+4
.stylua.toml
+4
.stylua.toml
+1
after/ftplugin/go.vim
+1
after/ftplugin/go.vim
···
1
+
setlocal noexpandtab
+1
after/ftplugin/http.vim
+1
after/ftplugin/http.vim
···
1
+
nnoremap <buffer> <cr> <cmd>Rest run<cr>
+11
after/ftplugin/norg.vim
+11
after/ftplugin/norg.vim
+8
init.lua
+8
init.lua
+111
lua/core/autocmds.lua
+111
lua/core/autocmds.lua
···
1
+
local aug = function(group_name, clear)
2
+
clear = vim.F.if_nil(clear, true)
3
+
return vim.api.nvim_create_augroup(group_name, { clear = clear })
4
+
end
5
+
6
+
local au = vim.api.nvim_create_autocmd
7
+
8
+
au({ "FocusGained", "TermClose", "TermLeave" }, {
9
+
group = aug("checktime"),
10
+
command = "checktime",
11
+
})
12
+
13
+
-- Highlight on yank
14
+
au("TextYankPost", {
15
+
group = aug("highlight_yank"),
16
+
callback = function()
17
+
vim.highlight.on_yank()
18
+
end,
19
+
})
20
+
21
+
-- Resize splits if window got resized
22
+
au("VimResized", {
23
+
group = aug("resize_splits"),
24
+
command = "tabdo wincmd =",
25
+
})
26
+
27
+
-- Go to last location when opening a buffer
28
+
au("BufReadPost", {
29
+
group = aug("last_loc"),
30
+
callback = function()
31
+
local mark = vim.api.nvim_buf_get_mark(0, '"')
32
+
local lcount = vim.api.nvim_buf_line_count(0)
33
+
if mark[1] > 0 and mark[1] <= lcount then
34
+
pcall(vim.api.nvim_win_set_cursor, 0, mark)
35
+
end
36
+
end,
37
+
})
38
+
39
+
-- Auto create dir when saving a file, in case some intermediate directory does not exists
40
+
au("BufWritePre", {
41
+
group = aug("auto_create_dir"),
42
+
callback = function(event)
43
+
if event.match:match("^%w%w+://") then
44
+
return
45
+
end
46
+
local file = vim.uv.fs_realpath(event.match) or event.match
47
+
vim.fn.mkdir(vim.fn.fnamemodify(file, ":p:h"), "p")
48
+
end,
49
+
})
50
+
51
+
-- Set options for terminal buffer
52
+
-- Use `BufWinEnter term://*` instead of just `TermOpen`
53
+
-- just `TermOpen` isn't enough when terminal buffer is created in background
54
+
au({ "TermOpen", "BufWinEnter" }, {
55
+
group = aug("terminal_options"),
56
+
pattern = "term://*",
57
+
callback = function()
58
+
-- I should use `setlocal` than `vim.wo` or `vim.bo`
59
+
-- vim.wo[winid] only works with specific window id
60
+
vim.cmd([[
61
+
setlocal nonu
62
+
setlocal nornu
63
+
setlocal nolist
64
+
setlocal signcolumn=no
65
+
setlocal foldcolumn=0
66
+
setlocal statuscolumn=
67
+
setlocal nocursorline
68
+
setlocal scrolloff=0
69
+
setlocal sidescrolloff=0
70
+
]])
71
+
end,
72
+
})
73
+
74
+
local ftplugins = aug("ftplugins")
75
+
76
+
au("FileType", {
77
+
group = ftplugins,
78
+
pattern = { "json", "jsonc" },
79
+
callback = function()
80
+
vim.wo.conceallevel = 0
81
+
end,
82
+
})
83
+
84
+
-- HACK: umm... is this right way..?
85
+
au("BufWinEnter", {
86
+
group = ftplugins,
87
+
pattern = "NeogitStatus",
88
+
callback = function()
89
+
vim.wo.foldcolumn = "0"
90
+
vim.wo.statuscolumn = ""
91
+
end,
92
+
})
93
+
94
+
-- prevent editing module files
95
+
au("BufNew", {
96
+
group = ftplugins,
97
+
pattern = {
98
+
"node_modules/**",
99
+
vim.fs.joinpath(vim.env.CARGO_HOME or "~/.cargo", "register/**"),
100
+
},
101
+
callback = function(event)
102
+
vim.bo[event.buf].modifiable = false
103
+
end,
104
+
})
105
+
106
+
au("CmdlineEnter", {
107
+
group = aug("auto_hlsearch"),
108
+
callback = vim.schedule_wrap(function()
109
+
vim.cmd.nohlsearch()
110
+
end),
111
+
})
+17
lua/core/highlights.lua
+17
lua/core/highlights.lua
···
1
+
local util_hl = require("utils.highlights")
2
+
3
+
vim.cmd.colorscheme("github_dark_default")
4
+
5
+
util_hl.set("StatusLineNC", { reverse = true, inherit = "StatusLine" })
6
+
-- util_hl.set("StatusLine", { bold = true })
7
+
-- local sep = util_hl.tint(util_hl.get("WinBar", "fg"), -0.25)
8
+
-- util_hl.set("WinBar", { reverse = true })
9
+
-- util_hl.set("WinBarNC", { fg = sep, reverse = true })
10
+
-- util_hl.set("WinSeparator", { fg = sep })
11
+
12
+
--[[
13
+
some good-looking colorscheems
14
+
15
+
# light-theme
16
+
- https://github.com/yorickpeterse/nvim-grey
17
+
]]
+159
lua/core/keymaps.lua
+159
lua/core/keymaps.lua
···
1
+
local Util = require("utils")
2
+
3
+
-- Fix default keymap errors
4
+
vim.keymap.set("x", "<c-c>", "<esc>")
5
+
-- Add undo break-points
6
+
vim.keymap.set("i", ",", ",<c-g>u")
7
+
vim.keymap.set("i", ".", ".<c-g>u")
8
+
vim.keymap.set("i", ";", ";<c-g>u")
9
+
10
+
-- Native-like keymaps
11
+
-- keymaps that follows native keymap and make it more consistent
12
+
vim.keymap.set("n", "-", "<cmd>e %:h<cr>", { desc = "open dir" })
13
+
14
+
-- Breaking remaps on native keymaps
15
+
vim.keymap.set("n", "g/", "gcc", { remap = true })
16
+
vim.keymap.set("x", "g/", "gc", { remap = true })
17
+
vim.keymap.set("n", "Q", "q")
18
+
vim.keymap.set("n", "q", "<cmd>close<cr>")
19
+
-- fast indent/dedenting
20
+
vim.keymap.set("n", "<", "<<")
21
+
vim.keymap.set("x", "<", "<gv")
22
+
vim.keymap.set("n", ">", ">>")
23
+
vim.keymap.set("x", ">", ">gv")
24
+
-- https://github.com/mhinz/vim-galore#saner-behavior-of-n-and-n
25
+
-- vim.keymap.set({ "n", "x", "o" }, "n", "'Nn'[v:searchforward]", { expr = true, desc = "Next search result" })
26
+
-- vim.keymap.set({ "n", "x", "o" }, "N", "'nN'[v:searchforward]", { expr = true, desc = "Prev search result" })
27
+
28
+
-- quickfix list
29
+
vim.keymap.set("n", "<c-j>", "<cmd>cnext<cr>")
30
+
vim.keymap.set("n", "<c-k>", "<cmd>cprev<cr>")
31
+
32
+
vim.keymap.set("n", "<cs-tab>", "<cmd>tabprev<cr>", { desc = "Prev tab" })
33
+
vim.keymap.set("n", "<c-tab>", "<cmd>tabnext<cr>", { desc = "Next tab" })
34
+
35
+
-- ways to exit select mode without substituting
36
+
vim.keymap.set("s", "<left>", "<c-g><c-v>I")
37
+
vim.keymap.set("s", "<right>", "<c-g><c-v>A")
38
+
39
+
-- other useful mappings
40
+
vim.keymap.set("x", "J", ":m '>+1<cr>gv=gv", { silent = true, desc = "Move down" })
41
+
vim.keymap.set("x", "K", ":m '<-2<cr>gv=gv", { silent = true, desc = "Move up" })
42
+
43
+
-- diagnostics
44
+
vim.keymap.set("n", "<leader>cd", vim.diagnostic.open_float, { desc = "Line Diagnostics" })
45
+
vim.keymap.set({ "n", "x" }, "]d", vim.diagnostic.goto_next, { desc = "Next Diagnostic" })
46
+
vim.keymap.set({ "n", "x" }, "[d", vim.diagnostic.goto_prev, { desc = "Prev Diagnostic" })
47
+
-- stylua: ignore start
48
+
vim.keymap.set({ "n", "x" }, "]e", function() vim.diagnostic.goto_next({ severity = vim.diagnostic.severity.ERROR }) end, { desc = "Next Error" })
49
+
vim.keymap.set({ "n", "x" }, "[e", function() vim.diagnostic.goto_prev({ severity = vim.diagnostic.severity.ERROR }) end, { desc = "Prev Error" })
50
+
vim.keymap.set({ "n", "x" }, "]w", function() vim.diagnostic.goto_next({ severity = vim.diagnostic.severity.WARN }) end, { desc = "Next Warning" })
51
+
vim.keymap.set({ "n", "x" }, "[w", function() vim.diagnostic.goto_prev({ severity = vim.diagnostic.severity.WARN }) end, { desc = "Prev Warning" })
52
+
-- stylua: ignore end
53
+
54
+
-- format
55
+
vim.keymap.set("n", "<leader>cf", "<cmd>Format<cr>", { desc = "Format" })
56
+
57
+
-- snippets
58
+
vim.keymap.set({ "i", "s" }, "<c-l>", function()
59
+
return vim.snippet.active({ direction = 1 }) and vim.snippet.jump(1)
60
+
end, { silent = true })
61
+
vim.keymap.set({ "i", "s" }, "<c-h>", function()
62
+
return vim.snippet.active({ direction = -1 }) and vim.snippet.jump(-1)
63
+
end, { silent = true })
64
+
vim.keymap.set({ "i", "s" }, "<tab>", function()
65
+
return vim.snippet.active({ direction = 1 }) and vim.snippet.jump(1)
66
+
end, { silent = true })
67
+
vim.keymap.set({ "i", "s" }, "<s-tab>", function()
68
+
return vim.snippet.active({ direction = -1 }) and vim.snippet.jump(-1)
69
+
end, { silent = true })
70
+
71
+
-- TODO: automate this
72
+
local function lsp_not_attached(_command)
73
+
return function()
74
+
Util.notify.warn("lsp not attached")
75
+
end
76
+
end
77
+
vim.keymap.set("n", "<leader>ca", lsp_not_attached("code_action"))
78
+
vim.keymap.set("n", "<leader>cr", lsp_not_attached("rename"))
79
+
vim.keymap.set("n", "gd", lsp_not_attached("definition"))
80
+
vim.keymap.set("n", "gr", lsp_not_attached("references"))
81
+
vim.keymap.set("n", "gy", lsp_not_attached("type_definition"))
82
+
vim.keymap.set("n", "gI", lsp_not_attached("implementation"))
83
+
vim.keymap.set("n", "gD", lsp_not_attached("declaration"))
84
+
vim.keymap.set("i", "<c-k>", lsp_not_attached("signature_help"))
85
+
vim.keymap.set("i", "<c-s>", lsp_not_attached("signature_help"))
86
+
87
+
-- lsp
88
+
vim.api.nvim_create_autocmd("LspAttach", {
89
+
group = vim.api.nvim_create_augroup("UserLspAttach", { clear = false }),
90
+
callback = function(ev)
91
+
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, { buffer = ev.buf })
92
+
vim.keymap.set("n", "<leader>cr", vim.lsp.buf.rename, { buffer = ev.buf })
93
+
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { buffer = ev.buf })
94
+
vim.keymap.set("n", "gr", vim.lsp.buf.references, { buffer = ev.buf })
95
+
vim.keymap.set("n", "gy", vim.lsp.buf.type_definition, { buffer = ev.buf })
96
+
vim.keymap.set("n", "gI", vim.lsp.buf.implementation, { buffer = ev.buf })
97
+
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, { buffer = ev.buf })
98
+
vim.keymap.set("i", "<c-k>", vim.lsp.buf.signature_help, { buffer = ev.buf })
99
+
vim.keymap.set("i", "<c-s>", vim.lsp.buf.signature_help, { buffer = ev.buf })
100
+
end,
101
+
})
102
+
103
+
vim.api.nvim_create_autocmd("User", {
104
+
pattern = "GitAttach",
105
+
callback = function(ev)
106
+
vim.keymap.set({ "x", "o" }, "ih", ":<c-u>Gitsigns select_hunk<cr>", { desc = "Select Hunk", buffer = ev.buf })
107
+
vim.keymap.set({ "x", "o" }, "ah", ":<c-u>Gitsigns select_hunk<cr>", { desc = "Select Hunk", buffer = ev.buf })
108
+
vim.keymap.set({ "n", "x" }, "]h", "<cmd>Gitsigns next_hunk<cr>", { desc = "Next Hunk", buffer = ev.buf })
109
+
vim.keymap.set({ "n", "x" }, "[h", "<cmd>Gitsigns prev_hunk<cr>", { desc = "Prev Hunk", buffer = ev.buf })
110
+
vim.keymap.set("n", "<leader>gu", "<cmd>Gitsigns undo_stage_hunk<cr>", { desc = "Undo Stage Hunk", buffer = ev.buf })
111
+
vim.keymap.set("n", "<leader>gA", "<cmd>Gitsigns stage_buffer<cr>", { desc = "Stage Buffer", buffer = ev.buf })
112
+
vim.keymap.set("n", "<leader>gR", "<cmd>Gitsigns reset_buffer<cr>", { desc = "Reset Buffer", buffer = ev.buf })
113
+
vim.keymap.set("n", "<leader>gp", "<cmd>Gitsigns preview_hunk_inline<cr>", { desc = "Preview Inline", buffer = ev.buf })
114
+
vim.keymap.set("n", "<leader>gP", "<cmd>Gitsigns preview_hunk<cr>", { desc = "Preview Hunk", buffer = ev.buf })
115
+
vim.keymap.set("n", "<leader>gb", "<cmd>Gitsigns blame_line<cr>", { desc = "Blame Line", buffer = ev.buf })
116
+
vim.keymap.set({ "n", "x" }, "<leader>ga", "<cmd>Gitsigns stage_hunk<cr>", { desc = "Stage Hunk", buffer = ev.buf })
117
+
vim.keymap.set({ "n", "x" }, "<leader>gr", "<cmd>Gitsigns reset_hunk<cr>", { desc = "Reset Hunk", buffer = ev.buf })
118
+
end,
119
+
})
120
+
--[[
121
+
./?.so;/usr/local/lib/lua/5.1/?.so
122
+
/home/ubuntu/repo/neovim/.deps/usr/lib/lua/5.1/?.so
123
+
/usr/local/lib/lua/5.1/loadall.so
124
+
/home/ubuntu/.local/share/nvim_rocks/rocks/lib/lua/5.1/?.so
125
+
/home/ubuntu/.local/share/nvim_rocks/rocks/lib64/lua/5.1/?.so
126
+
127
+
/home/ubuntu/.local/share/nvim_rocks/site/pack/luarocks/opt/tree-sitter-css/parser/css.so
128
+
129
+
./?.lua
130
+
/home/ubuntu/repo/neovim/.deps/usr/share/luajit-2.1/?.lua
131
+
/usr/local/share/lua/5.1/?.lua
132
+
/usr/local/share/lua/5.1/?/init.lua
133
+
/home/ubuntu/repo/neovim/.deps/usr/share/lua/5.1
134
+
/?.lua
135
+
/home/ubuntu/repo/neovim/.deps/usr/share/lua/5.1/?/init.lua
136
+
/home/ubuntu/.local/share/nvim_rocks/rocks/share/lua/5.1/?.lua
137
+
/home/ubuntu/.local/share/nvim_rocks/rocks/share/lu
138
+
a/5.1/?/init.lua
139
+
/run/user/1001/luarocks-E5B7D6D75851B0/share/lua/5.1/?.lua
140
+
/run/user/1001/luarocks-E5B7D6D75851B0/share/lua/5.1/init.lua
141
+
142
+
set packpath?
143
+
/home/ubuntu/.config/nvim_rocks
144
+
/etc/xdg/nvim_rocks
145
+
/home/ubuntu/.local/share/nvim_rocks/site
146
+
/usr/local/share/nvim_rocks/site
147
+
/usr/share/nvim_rocks/site
148
+
/var/lib/snapd/desktop/nvim_rocks/site
149
+
/usr/local/share/nvim/runtime
150
+
/usr/local/lib/nvim
151
+
/var/lib/snapd/desktop/nvim_rocks/site/after
152
+
/usr/share/nvim_rocks/site/after
153
+
/usr/local/share/nvim_rocks/site/after
154
+
/home/ubuntu/.local/share/nvim_rocks/site/after
155
+
/etc/xdg/nvim_rocks/after
156
+
/home/ubuntu/.config/nvim_rocks/after
157
+
158
+
/home/ubuntu/.local/share/nvim_rocks/site/pack/luarocks/opt/tree-sitter-css/parser/css.so
159
+
--]]
+45
lua/core/lsp/init.lua
+45
lua/core/lsp/init.lua
···
1
+
vim.diagnostic.config({
2
+
underline = true,
3
+
-- virtual_text
4
+
-- signs
5
+
-- float
6
+
-- update_in_insert
7
+
servirty_sort = true,
8
+
})
9
+
10
+
do
11
+
local ok, mason = pcall(require, "mason")
12
+
if ok then
13
+
mason.setup()
14
+
end
15
+
end
16
+
-- do
17
+
-- local ok, neodev = pcall(require, "neodev")
18
+
-- if ok then
19
+
-- neodev.setup()
20
+
-- end
21
+
-- end
22
+
23
+
vim.api.nvim_create_autocmd("LspAttach", {
24
+
group = vim.api.nvim_create_augroup("UserLspAttach", { clear = false }),
25
+
callback = function(ev)
26
+
vim.lsp.completion.enable(true, ev.data.client_id, ev.buf, { autotrigger = false })
27
+
end,
28
+
})
29
+
30
+
local ok, lspconfig = pcall(require, "lspconfig")
31
+
if not ok then return end
32
+
33
+
local function setup(server, opts)
34
+
-- NOTE: This isn't perfect, but it should work for 99% of uninstalled servers
35
+
local cmd = lspconfig[server].document_config.default_config.cmd[1]
36
+
if vim.fn.executable(cmd) == 0 then
37
+
return
38
+
end
39
+
opts = opts or {}
40
+
lspconfig[server].setup(opts)
41
+
end
42
+
43
+
for name, opts in pairs(require("core.lsp.servers")) do
44
+
setup(name, opts)
45
+
end
+108
lua/core/lsp/servers.lua
+108
lua/core/lsp/servers.lua
···
1
+
---@diagnostic disable: missing-fields
2
+
---@type lspconfig.options
3
+
return {
4
+
clangd = {},
5
+
cssls = {},
6
+
dartls = {},
7
+
emmet_language_server = {},
8
+
gopls = {},
9
+
hls = {
10
+
settings = {
11
+
haskell = {
12
+
formattingProvider = "ormolu",
13
+
checkProject = true,
14
+
},
15
+
},
16
+
},
17
+
html = {},
18
+
lua_ls = {
19
+
settings = {
20
+
Lua = {
21
+
hint = {
22
+
enable = true,
23
+
arrayIndex = "Disable",
24
+
paramType = false,
25
+
setType = true,
26
+
},
27
+
completion = {
28
+
callSnippet = "Replace",
29
+
},
30
+
diagnostics = {
31
+
unusedLocalExclude = { "_*" },
32
+
globals = { "vim" },
33
+
},
34
+
format = {
35
+
enable = false, -- use stylua istead
36
+
},
37
+
workspace = {
38
+
checkThirdParty = "Disable",
39
+
},
40
+
},
41
+
},
42
+
},
43
+
tsserver = {
44
+
settings = {
45
+
typescript = {
46
+
inlayHints = {
47
+
includeInlayParameterNameHints = "all",
48
+
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
49
+
includeInlayVariableTypeHintsWhenTypeMatchesName = false,
50
+
includeInlayFunctionParameterTypeHints = true,
51
+
includeInlayVariableTypeHints = false,
52
+
includeInlayPropertyDeclarationTypeHints = true,
53
+
includeInlayFunctionLikeReturnTypeHints = true,
54
+
includeInlayEnumMemberValueHints = true,
55
+
},
56
+
},
57
+
javascript = {
58
+
inlayHints = {
59
+
includeInlayParameterNameHints = "all",
60
+
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
61
+
includeInlayVariableTypeHintsWhenTypeMatchesName = false,
62
+
includeInlayFunctionParameterTypeHints = true,
63
+
includeInlayVariableTypeHints = false,
64
+
includeInlayPropertyDeclarationTypeHints = true,
65
+
includeInlayFunctionLikeReturnTypeHints = true,
66
+
includeInlayEnumMemberValueHints = true,
67
+
},
68
+
},
69
+
},
70
+
},
71
+
svelte = {},
72
+
ruff_lsp = {},
73
+
rust_analyzer = {
74
+
cargo = {
75
+
buildScripts = {
76
+
-- enable = true,
77
+
},
78
+
},
79
+
},
80
+
-- volar = {
81
+
-- filetypes = {
82
+
-- "javascript",
83
+
-- "typescript",
84
+
-- "javascriptreact",
85
+
-- "typescriptreact",
86
+
-- "vue",
87
+
-- "json",
88
+
-- },
89
+
-- -- on_new_config = function(new_config, new_root_dir)
90
+
-- -- new_config.init_options.typescript.tsdk = "/path/to/tsserver"
91
+
-- -- end
92
+
-- },
93
+
-- yamlls = {
94
+
-- settings = {
95
+
-- yaml = {
96
+
-- on_new_config = function(new_config)
97
+
-- if require("utils").plugin.has("SchemaStore.nvim") then
98
+
-- new_config.settings.yaml.schemas = new_config.settings.yaml.schemas or {}
99
+
-- vim.list_extend(new_config.settings.yaml.schemas, require("schemastore").yaml.schemas())
100
+
-- end
101
+
-- end,
102
+
-- schemaStore = {
103
+
-- enable = false,
104
+
-- },
105
+
-- },
106
+
-- },
107
+
-- },
108
+
}
+106
lua/core/options.lua
+106
lua/core/options.lua
···
1
+
vim.cmd([[let $LANG='en_US.UTF-8']])
2
+
3
+
vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()"
4
+
vim.opt.diffopt:append("linematch:60")
5
+
vim.o.clipboard = "unnamedplus"
6
+
vim.o.cmdheight = 1
7
+
vim.o.cmdwinheight = 10
8
+
vim.o.colorcolumn = "80"
9
+
vim.o.completeopt = "menu,menuone,noselect,fuzzy"
10
+
vim.o.conceallevel = 0
11
+
vim.o.confirm = true
12
+
vim.o.cursorline = true
13
+
vim.o.expandtab = true
14
+
-- stylua: ignore
15
+
vim.opt.fillchars = {
16
+
foldopen = "v",
17
+
foldclose = ">",
18
+
fold = " ",
19
+
foldsep = " ",
20
+
21
+
diff = "╱",
22
+
eob = "~",
23
+
24
+
horiz = ' ', -- '▁',
25
+
-- horiz = '▁',
26
+
horizup = '│',
27
+
horizdown = ' ', -- '▁',
28
+
-- horizdown = '▁',
29
+
vert = '│',
30
+
vertleft = '│',
31
+
vertright = '│',
32
+
verthoriz = '│',
33
+
}
34
+
vim.o.foldcolumn = "0"
35
+
vim.o.foldenable = true
36
+
vim.o.foldlevel = 99
37
+
vim.o.foldlevelstart = 99
38
+
vim.o.formatoptions = "jcrqlnt"
39
+
if vim.fn.executable("rg") ~= 0 then
40
+
vim.o.grepprg = "rg --vimgrep"
41
+
end
42
+
vim.o.inccommand = "split"
43
+
vim.o.ignorecase = true
44
+
vim.o.laststatus = 2
45
+
vim.o.list = true
46
+
vim.opt.listchars = {
47
+
-- eol = "¬",
48
+
tab = "▏ ",
49
+
trail = "·", -- Dot Operator (U+22C5)
50
+
extends = "»", -- RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (U+00BB, UTF-8: C2 BB)
51
+
precedes = "«", -- LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (U+00AB, UTF-8: C2 AB)
52
+
}
53
+
vim.o.mouse = "nv"
54
+
vim.o.number = true
55
+
vim.o.pumblend = 0
56
+
vim.o.pumheight = 10
57
+
vim.o.relativenumber = true
58
+
vim.o.scrolloff = 5
59
+
vim.opt.sessionoptions = { "buffers", "curdir", "folds", "help", "tabpages", "winsize" }
60
+
vim.o.shiftround = true
61
+
vim.o.shiftwidth = 4
62
+
vim.opt.shortmess:append({
63
+
W = true, -- Don't print "written" when editing
64
+
I = false, -- No splash screen
65
+
c = true, -- Don't show ins-completion-menu messages (match 1 of 2)
66
+
C = true, -- Don't show messages while scannign ins-completion items (scanning tags)
67
+
s = true, -- Don't show "Search hit BOTTOM" message
68
+
})
69
+
-- vim.o.showbreak = "↳ "
70
+
vim.o.showmode = true
71
+
vim.o.sidescrolloff = 6
72
+
vim.o.signcolumn = "yes"
73
+
vim.o.smartcase = true
74
+
vim.o.smartindent = true
75
+
vim.o.spelllang = "en,cjk"
76
+
vim.o.splitkeep = "cursor"
77
+
vim.o.splitbelow = true
78
+
vim.o.splitright = true
79
+
vim.o.tabstop = 4
80
+
vim.o.termguicolors = true
81
+
vim.o.timeoutlen = 500
82
+
vim.o.undofile = true
83
+
vim.o.undolevels = 10000
84
+
vim.o.updatetime = 200
85
+
-- vim.o.winbar = [[%f %h%w%m%r%=%-14.(%l,%c%V%) %P]]
86
+
vim.o.winminwidth = 10
87
+
vim.o.wrap = false
88
+
89
+
vim.g.mapleader = " "
90
+
-- vim.cmd[[let mapleader = "\<tab>"]]
91
+
92
+
vim.g.editorconfig = true
93
+
94
+
-- disable providers (see :h provider)
95
+
vim.g.loaded_python3_provider = 0
96
+
vim.g.loaded_ruby_provider = 0
97
+
vim.g.loaded_node_provider = 0
98
+
vim.g.loaded_perl_provider = 0
99
+
100
+
if vim.g.neovide then
101
+
vim.o.guifont = "Fira Code:h16"
102
+
vim.g.neovide_profiler = true
103
+
end
104
+
105
+
-- Fix markdown indentation settings
106
+
vim.g.markdown_recommended_style = 0
lua/core/ui/statusline.lua
lua/core/ui/statusline.lua
This is a binary file and will not be displayed.
+129
lua/core/ui/winbar.lua
+129
lua/core/ui/winbar.lua
···
1
+
local Util = require("utils")
2
+
local util_hl = require("utils.highlights")
3
+
4
+
local function is_win_current()
5
+
local winid = vim.api.nvim_get_current_win()
6
+
local curwin = tonumber(vim.g.actual_curwin)
7
+
return winid == curwin
8
+
end
9
+
10
+
local hls = {
11
+
}
12
+
13
+
local hl_text = util_hl.hl_text
14
+
15
+
local function file_name()
16
+
local path = vim.fn.expand("%:p:h")--[[@as string]]
17
+
path = path:gsub("oil://", "")
18
+
-- stylua: ignore
19
+
path = vim.fs.joinpath(path, "")
20
+
:gsub(vim.pesc(vim.fs.joinpath(Util.root(), "")), "")
21
+
22
+
local name = vim.fn.expand("%:p:t")--[[@as string]]
23
+
if vim.bo.filetype == "oil" then
24
+
name = path == "" and "." or path
25
+
path = "oil://"
26
+
elseif name == "" then
27
+
name = "[No Name]"
28
+
end
29
+
30
+
local hi = is_win_current() and hls.bold or hls.nc_bold
31
+
return hl_text(path, hls.nc_base) .. hl_text(name, hi)
32
+
end
33
+
34
+
local function sg_name()
35
+
local path = vim.fn.expand("%:p:h")
36
+
path = path .. "/"
37
+
local name = vim.fn.expand("%:p:t")
38
+
local hi = is_win_current() and hls.bold or hls.nc_bold
39
+
return hl_text(path, hls.nc_base) .. hl_text(name, hi)
40
+
end
41
+
42
+
local function sg_status()
43
+
-- TODO:
44
+
-- on github.com
45
+
-- on crates.io
46
+
return ""
47
+
end
48
+
49
+
function _G.winbar()
50
+
local modules = {}
51
+
local buftype = vim.bo.buftype
52
+
local filetype = vim.bo.filetype
53
+
local filename = vim.api.nvim_buf_get_name(0)
54
+
local function center(title)
55
+
return {
56
+
vi_mode(),
57
+
"%=" .. title .. "%=",
58
+
vi_mode_placer,
59
+
}
60
+
end
61
+
if buftype == "" or filename:match('^suda://') then
62
+
modules = {
63
+
vi_mode(),
64
+
" ",
65
+
file_name(),
66
+
file_modi(),
67
+
" ",
68
+
git_status(),
69
+
"%=",
70
+
"%<",
71
+
"%-14.(" .. lsp_status() .. "%)",
72
+
" ",
73
+
"%P ",
74
+
}
75
+
elseif buftype == "help" then
76
+
modules = center(help_file())
77
+
elseif buftype == "terminal" then
78
+
modules = {
79
+
vi_mode(),
80
+
"%=Terminal%=",
81
+
-- TODO: add terminal id too
82
+
vi_mode_placer,
83
+
}
84
+
elseif buftype == "nofile" and filetype == "query" and vim.bo.modifiable and not vim.bo.readonly then
85
+
modules = center("Edit Query")
86
+
elseif filetype == "qf" then
87
+
modules = center("Quickfix List")
88
+
elseif filetype == "checkhealth" then
89
+
modules = center("checkhealth")
90
+
elseif filetype == "oil" then
91
+
modules = {
92
+
vi_mode(),
93
+
" ",
94
+
file_name(),
95
+
file_modi(),
96
+
" ",
97
+
git_status(),
98
+
"%=",
99
+
" ",
100
+
"%P ",
101
+
}
102
+
elseif filetype:match("^Neogit.*") then
103
+
modules = center("Neogit")
104
+
elseif filetype == "neotest-summary" then
105
+
modules = center("Test Summary")
106
+
elseif filetype == "tsplayground" then
107
+
modules = center("TSPlayground")
108
+
elseif vim.fn.win_gettype(vim.api.nvim_get_current_win()) == "command" then
109
+
modules = center("Command Window")
110
+
elseif filename:match("^sg://") then
111
+
modules = {
112
+
vi_mode(),
113
+
" ",
114
+
sg_name(),
115
+
file_modi(),
116
+
" ",
117
+
sg_status(), -- TODO: sg_status instead of git_status
118
+
"%=",
119
+
"%<",
120
+
" ",
121
+
"%P ",
122
+
}
123
+
else
124
+
modules = center(filetype)
125
+
end
126
+
return table.concat(vim.tbl_filter(function(i)
127
+
return i ~= nil
128
+
end, modules))
129
+
end
+37
lua/plugins/conform.lua
+37
lua/plugins/conform.lua
···
1
+
require("conform").setup({
2
+
format = {
3
+
timeout_ms = 3000,
4
+
async = false,
5
+
quiet = false,
6
+
},
7
+
formatters_by_ft = {
8
+
["lua"] = { "stylua" },
9
+
["fish"] = { "fish_indent" },
10
+
["sh"] = { "shfmt" },
11
+
["javascript"] = { "prettierd" },
12
+
["javascriptreact"] = { "prettierd" },
13
+
["typescript"] = { "prettierd" },
14
+
["typescriptreact"] = { "prettierd" },
15
+
["vue"] = { "prettierd" },
16
+
["css"] = { "prettierd" },
17
+
["scss"] = { "prettierd" },
18
+
["less"] = { "prettierd" },
19
+
["html"] = { "prettierd" },
20
+
["json"] = { "prettierd" },
21
+
["jsonc"] = { "prettierd" },
22
+
["yaml"] = { "prettierd" },
23
+
["markdown"] = { "prettierd" },
24
+
["markdown.mdx"] = { "prettierd" },
25
+
["graphql"] = { "prettierd" },
26
+
["handlebars"] = { "prettierd" },
27
+
},
28
+
formatters = {
29
+
injected = { options = { ignore_errors = true } },
30
+
prettierd = {
31
+
env = {
32
+
-- FIXME: this doesn't work for some reason
33
+
PRETTIERD_DEFAULT_CONFIG = vim.fn.expand("~/.config/nvim/utils/linter-config/.prettierrc.json"),
34
+
},
35
+
},
36
+
},
37
+
})
+14
lua/plugins/crates.lua
+14
lua/plugins/crates.lua
···
1
+
local crates = require("crates")
2
+
3
+
crates.setup()
4
+
5
+
vim.api.nvim_create_autocmd("BufRead", {
6
+
pattern = "Cargo.toml",
7
+
callback = function(ev)
8
+
vim.keymap.set("n", "K", function()
9
+
if crates.popup_available() then
10
+
crates.show_popup()
11
+
end
12
+
end, { silent = true, buffer = ev.buf })
13
+
end,
14
+
})
+8
lua/plugins/fidget.lua
+8
lua/plugins/fidget.lua
+56
lua/plugins/fzf-lua.lua
+56
lua/plugins/fzf-lua.lua
···
1
+
local fzf_lua = require("fzf-lua")
2
+
3
+
fzf_lua.setup({
4
+
winopts = {
5
+
fullscreen = true,
6
+
preview = {
7
+
layout = "vertical",
8
+
vertical = "up:75%",
9
+
scrollbar = false,
10
+
},
11
+
},
12
+
keymap = {},
13
+
})
14
+
15
+
local function find_dirs(opts)
16
+
opts = opts or {}
17
+
opts.prompt = "Directories> "
18
+
opts.fn_transform = function(x)
19
+
return fzf_lua.utils.ansi_codes.magenta(x)
20
+
end
21
+
opts.actions = {
22
+
["default"] = function(selected)
23
+
vim.cmd.edit(selected[1])
24
+
end,
25
+
}
26
+
fzf_lua.fzf_exec("fd --type d", opts)
27
+
end
28
+
29
+
vim.keymap.set("n", "<f1>", "<cmd>FzfLua helptags<cr>")
30
+
vim.keymap.set("n", "<leader>,", "<cmd>FzfLua buffers<cr>")
31
+
vim.keymap.set("n", "<leader>e", "<cmd>FzfLua files<cr>")
32
+
vim.keymap.set("n", "<leader>ff", "<cmd>FzfLua files<cr>")
33
+
vim.keymap.set("n", "<leader>fo", "<cmd>FzfLua oldfiles<cr>")
34
+
vim.keymap.set("n", "<leader>fd", find_dirs)
35
+
vim.keymap.set("n", "<leader>sf", "<cmd>FzfLua files<cr>")
36
+
vim.keymap.set("n", "<leader>sg", "<cmd>FzfLua live_grep<cr>")
37
+
vim.keymap.set("n", "<leader>sk", "<cmd>FzfLua keymaps<cr>")
38
+
vim.keymap.set("n", "<leader>sh", "<cmd>FzfLua highlights<cr>")
39
+
vim.keymap.set("n", "<leader>gs", "<cmd>FzfLua git_status<cr>")
40
+
vim.keymap.set("n", "<leader>gl", "<cmd>FzfLua git_commits<cr>")
41
+
-- { "<plug>(lsp_definitions)", "<cmd>Telescope lsp_definitions<cr>" },
42
+
-- { "<plug>(lsp_type_definitions)", "<cmd>Telescope lsp_type_definitions<cr>" },
43
+
-- { "<plug>(lsp_references)", "<cmd>Telescope lsp_references<cr>" },
44
+
-- { "<plug>(lsp_implementations)", "<cmd>Telescope lsp_implementations<cr>" },
45
+
--
46
+
--
47
+
--
48
+
--
49
+
-- ["top"] = "gg",
50
+
-- ["bottom"] = "G",
51
+
-- ["half-page-up"] = ("%c"):format(0x15), -- [[]]
52
+
-- ["half-page-down"] = ("%c"):format(0x04), -- [[]]
53
+
-- ["page-up"] = ("%c"):format(0x02), -- [[]]
54
+
-- ["page-down"] = ("%c"):format(0x06), -- [[]]
55
+
-- ["line-up"] = "Mgk", -- ^Y doesn't seem to work
56
+
-- ["line-down"] = "Mgj", -- ^E doesn't seem to work
+7
lua/plugins/gitsigns.lua
+7
lua/plugins/gitsigns.lua
+58
lua/plugins/harpoon.lua
+58
lua/plugins/harpoon.lua
···
1
+
local harpoon = require("harpoon")
2
+
3
+
harpoon:setup()
4
+
5
+
vim.keymap.set("n", "<leader>h", function()
6
+
harpoon:list():add()
7
+
end)
8
+
vim.keymap.set("n", "<leader><leader>", function()
9
+
harpoon.ui:toggle_quick_menu(harpoon:list())
10
+
end)
11
+
12
+
vim.keymap.set("n", "<m-1>", function()
13
+
harpoon:list():select(1)
14
+
end)
15
+
vim.keymap.set("n", "<m-2>", function()
16
+
harpoon:list():select(2)
17
+
end)
18
+
vim.keymap.set("n", "<m-3>", function()
19
+
harpoon:list():select(3)
20
+
end)
21
+
vim.keymap.set("n", "<m-4>", function()
22
+
harpoon:list():select(4)
23
+
end)
24
+
vim.keymap.set("n", "<F4>", function()
25
+
harpoon:list():select(1)
26
+
end)
27
+
vim.keymap.set("n", "<F5>", function()
28
+
harpoon:list():select(2)
29
+
end)
30
+
vim.keymap.set("n", "<F6>", function()
31
+
harpoon:list():select(3)
32
+
end)
33
+
vim.keymap.set("n", "<F7>", function()
34
+
harpoon:list():select(4)
35
+
end)
36
+
vim.keymap.set("n", "<leader>1", function()
37
+
harpoon:list():select(1)
38
+
end)
39
+
vim.keymap.set("n", "<leader>2", function()
40
+
harpoon:list():select(2)
41
+
end)
42
+
vim.keymap.set("n", "<leader>3", function()
43
+
harpoon:list():select(3)
44
+
end)
45
+
vim.keymap.set("n", "<leader>4", function()
46
+
harpoon:list():select(4)
47
+
end)
48
+
49
+
-- Toggle previous & next buffers stored within Harpoon list
50
+
-- vim.keymap.set("n", "<C-S-P>", function() harpoon:list():prev() end)
51
+
-- vim.keymap.set("n", "<C-S-N>", function() harpoon:list():next() end)
52
+
53
+
vim.api.nvim_create_autocmd("FileType", {
54
+
pattern = "harpoon",
55
+
callback = function(ev)
56
+
vim.keymap.set("n", "<c-c>", "<cmd>q<cr>", { buffer = ev.buf })
57
+
end,
58
+
})
+5
lua/plugins/indent-blankline.lua
+5
lua/plugins/indent-blankline.lua
+10
lua/plugins/leap.lua
+10
lua/plugins/leap.lua
···
1
+
-- local leap = require("leap")
2
+
-- leap.add_default_mappings(true)
3
+
vim.keymap.set('n', 's', '<Plug>(leap-forward)')
4
+
vim.keymap.set('n', 'S', '<Plug>(leap-backward)')
5
+
vim.keymap.set('n', 'gs', '<Plug>(leap-from-window)')
6
+
-- vim.keymap.del({ "x", "o" }, "x")
7
+
-- vim.keymap.del({ "x", "o" }, "X")
8
+
-- vim.keymap.del({ "x" }, "s")
9
+
-- vim.keymap.del({ "x" }, "S")
10
+
-- vim.keymap.del({ "x", "o" }, "gs")
+104
lua/plugins/luasnip.lua
+104
lua/plugins/luasnip.lua
···
1
+
local Util = require("utils")
2
+
local ls = require("luasnip")
3
+
4
+
vim.snippet.expand = ls.lsp_expand
5
+
6
+
---@diagnostic disable-next-line: duplicate-set-field
7
+
vim.snippet.active = function(filter)
8
+
filter = filter or {}
9
+
filter.direction = filter.direction or 1
10
+
11
+
-- if filter.direction == 1 then
12
+
-- return ls.expand_or_locally_jumpable()
13
+
-- else
14
+
-- return ls.locally_jumpable(filter.direction)
15
+
-- end
16
+
return ls.locally_jumpable(filter.direction)
17
+
end
18
+
19
+
-- ---@diagnostic disable-next-line: duplicate-set-field
20
+
-- vim.snippet.jump = function(direction)
21
+
-- if direction == 1 then
22
+
-- if ls.expandable() then
23
+
-- return ls.expand_or_jump()
24
+
-- else
25
+
-- return ls.locally_jumpable(1) and ls.jump(1)
26
+
-- end
27
+
-- else
28
+
-- return ls.locally_jumpable(-1) and ls.jump(-1)
29
+
-- end
30
+
-- end
31
+
---@diagnostic disable-next-line: duplicate-set-field
32
+
vim.snippet.jump = ls.jump
33
+
34
+
vim.snippet.stop = ls.unlink_current
35
+
36
+
ls.config.set_config({
37
+
update_events = "TextChanged,TextChangedI",
38
+
history = true,
39
+
delete_check_events = "InsertLeave",
40
+
ext_opts = {},
41
+
})
42
+
43
+
vim.g.ls_next_choice_map = "<c-j>"
44
+
45
+
vim.keymap.set({ "i", "s" }, "<c-y>", function()
46
+
if vim.fn.pumvisible() ~= 0 then
47
+
return "<c-y>"
48
+
elseif ls.expandable() then
49
+
vim.schedule(function()
50
+
ls.expand()
51
+
end)
52
+
end
53
+
end, { silent = true, expr = true })
54
+
vim.keymap.set({ "i", "s" }, vim.g.ls_next_choice_map, function()
55
+
if ls.choice_active() then
56
+
ls.change_choice(1)
57
+
end
58
+
end)
59
+
-- vim.keymap.set({ "i", "s" }, "<c-k>", function()
60
+
-- if ls.choice_active() then
61
+
-- ls.change_choice(-1)
62
+
-- end
63
+
-- end)
64
+
65
+
local group = vim.api.nvim_create_augroup("UserLuasnip", { clear = true })
66
+
local ns = vim.api.nvim_create_namespace("UserLuasnip")
67
+
vim.api.nvim_create_autocmd("User", {
68
+
group = group,
69
+
pattern = "LuasnipChoiceNodeEnter",
70
+
callback = function()
71
+
local node = ls.session.event_node
72
+
local line = node:get_buf_position()[1]
73
+
vim.api.nvim_buf_set_extmark(0, ns, line, -1, {
74
+
end_line = line,
75
+
end_right_gravity = true,
76
+
right_gravity = false,
77
+
virt_text = { { " " .. vim.g.ls_next_choice_map .. " to toggle ", "LspInfoTip" } },
78
+
})
79
+
end,
80
+
})
81
+
local function delete_extmarks()
82
+
local extmarks = vim.api.nvim_buf_get_extmarks(0, ns, 0, -1, {})
83
+
for _, extmark in ipairs(extmarks) do
84
+
vim.api.nvim_buf_del_extmark(0, ns, extmark[1])
85
+
end
86
+
end
87
+
vim.api.nvim_create_autocmd("User", {
88
+
group = group,
89
+
pattern = "LuasnipChoiceNodeLeave",
90
+
callback = delete_extmarks,
91
+
})
92
+
vim.api.nvim_create_autocmd("ModeChanged", {
93
+
group = group,
94
+
pattern = "*[isS\19]*:*[^isS\19]*",
95
+
callback = Util.debounce(50, function()
96
+
if vim.fn.mode():match("[^isS\19]") then
97
+
delete_extmarks()
98
+
end
99
+
end),
100
+
})
101
+
102
+
for _, ft_path in ipairs(vim.api.nvim_get_runtime_file("lua/snippets/*.lua", true)) do
103
+
loadfile(ft_path)()
104
+
end
+25
lua/plugins/mini-ai.lua
+25
lua/plugins/mini-ai.lua
···
1
+
local ai = require("mini.ai")
2
+
local ts_gen = ai.gen_spec.treesitter
3
+
ai.setup({
4
+
custom_textobjects = {
5
+
-- remove unused default mappings
6
+
["?"] = false,
7
+
-- override default mappings
8
+
["f"] = ts_gen({ a = "@function.outer", i = "@function.inner" }, { use_nvim_treesitter = false }),
9
+
-- custom mappings
10
+
-- ["o"] = ts_gen({
11
+
-- a = { "@block.outer", "@conditional.outer", "@loop.outer" },
12
+
-- i = { "@block.inner", "@conditional.inner", "@loop.inner" },
13
+
-- }, {}),
14
+
-- ["c"] = ts_gen({ a = "@class.outer", i = "@class.inner" }),
15
+
-- ["/"] = ts_gen({ a = "@comment.outer", i = "@comment.inner" }),
16
+
["u"] = ai.gen_spec.function_call(),
17
+
["U"] = ai.gen_spec.function_call({ name_pattern = "[%w_]" }),
18
+
},
19
+
mappings = {
20
+
goto_left = '',
21
+
goto_right = '',
22
+
},
23
+
n_lines = 500,
24
+
silent = false,
25
+
})
+1
lua/plugins/neogit.lua
+1
lua/plugins/neogit.lua
···
1
+
require("neogit").setup()
+85
lua/plugins/nvim-cmp.lua
+85
lua/plugins/nvim-cmp.lua
···
1
+
--[[
2
+
local cmp = require("cmp")
3
+
4
+
cmp.setup({
5
+
snippet = {
6
+
expand = function(args)
7
+
vim.snippet.expand(args.body)
8
+
end,
9
+
},
10
+
mapping = cmp.mapping.preset.insert({
11
+
["<C-n>"] = cmp.mapping(function ()
12
+
if not cmp.visible() then
13
+
cmp.complete()
14
+
else
15
+
cmp.select_next_item()
16
+
end
17
+
end),
18
+
["<C-p>"] = cmp.mapping.select_prev_item(),
19
+
["<C-d>"] = cmp.mapping.scroll_docs(4),
20
+
["<C-u>"] = cmp.mapping.scroll_docs(-4),
21
+
["<C-e>"] = cmp.mapping.abort(),
22
+
["<C-c>"] = cmp.mapping.close(),
23
+
["<c-y>"] = cmp.mapping.confirm({ select = true }),
24
+
}),
25
+
completion = {
26
+
-- https://github.com/hrsh7th/nvim-cmp/blob/v0.0.1/lua/cmp/config/default.lua#L38
27
+
autocomplete = false,
28
+
-- keyword_pattern = "",
29
+
-- keyword_length = 2,
30
+
},
31
+
sources = cmp.config.sources({
32
+
{ name = "nvim_lsp" },
33
+
-- { name = "luasnip" },
34
+
{ name = "neorg" },
35
+
{ name = "path" },
36
+
{ name = "crates" },
37
+
{ name = "buffer" },
38
+
}),
39
+
-- sorting = {
40
+
-- comparators = {
41
+
-- cmp.config.compare.offset,
42
+
-- cmp.config.compare.exact,
43
+
-- cmp.config.compare.score,
44
+
-- cmp.config.compare.recently_used,
45
+
-- -- require("cmp-under-comparator").under,
46
+
-- cmp.config.compare.kind,
47
+
-- cmp.config.compare.sort_text,
48
+
-- cmp.config.compare.length,
49
+
-- cmp.config.compare.order,
50
+
-- },
51
+
-- },
52
+
formatting = {
53
+
fields = { "abbr", "kind", "menu" },
54
+
format = function(entry, item)
55
+
-- local icons = require("config.icons").kinds
56
+
-- if icons[item.kind] then
57
+
-- item.kind = icons[item.kind] .. item.kind
58
+
-- end
59
+
local label = item.abbr
60
+
local truncated_label = vim.fn.strcharpart(label, 0, 30)
61
+
if truncated_label ~= label then
62
+
item.abbr = truncated_label .. "…"
63
+
end
64
+
-- stylua: ignore
65
+
item.menu = ({
66
+
nvim_lsp = "[LSP]",
67
+
luasnip = "[SNIP]",
68
+
luasnip_choice = "[SNIP]",
69
+
buffer = "[BUF]",
70
+
path = "[PATH]",
71
+
emoji = "[EMOJI]",
72
+
crates = "[CRATES]",
73
+
npm = "[NPM]",
74
+
neorg = "[NEORG]",
75
+
orgmode = "[ORG]",
76
+
git = "[GIT]",
77
+
})[entry.source.name]
78
+
return item
79
+
end,
80
+
},
81
+
experimental = {
82
+
ghost_text = false,
83
+
},
84
+
})
85
+
]]
+17
lua/plugins/nvim-lint.lua
+17
lua/plugins/nvim-lint.lua
···
1
+
local Util = require("utils")
2
+
3
+
local lint = require("lint")
4
+
5
+
lint.linters_by_ft = {
6
+
dockerfile = { "hadolint" },
7
+
editorconfig = { "editorconfig-checker" },
8
+
fish = { "fish" },
9
+
-- lua = { "luacheck" },
10
+
}
11
+
12
+
vim.api.nvim_create_autocmd({ "BufWritePost", "BufReadPost", "InsertLeave" }, {
13
+
group = vim.api.nvim_create_augroup("nvim-lint", { clear = true }),
14
+
callback = Util.debounce(100, function ()
15
+
lint.try_lint()
16
+
end),
17
+
})
+15
lua/plugins/nvim-surround.lua
+15
lua/plugins/nvim-surround.lua
···
1
+
require("nvim-surround").setup({
2
+
-- stylua: ignore
3
+
keymaps = {
4
+
insert = false,
5
+
insert_line = false,
6
+
normal = "ys",
7
+
normal_cur = false,
8
+
normal_line = false,
9
+
normal_cur_line = false,
10
+
visual = "s",
11
+
visual_line = false,
12
+
change = "cs",
13
+
delete = "ds",
14
+
},
15
+
})
+5
lua/plugins/nvim-treesitter.lua
+5
lua/plugins/nvim-treesitter.lua
+8
lua/plugins/nvim-ufo.lua
+8
lua/plugins/nvim-ufo.lua
+22
lua/plugins/oil.lua
+22
lua/plugins/oil.lua
···
1
+
require("oil").setup({
2
+
keymaps = {
3
+
-- TODO: put a small note that I can use `g?` for help
4
+
-- TODO: change `_` opens Oil in util.root()
5
+
-- and make it global keymap
6
+
["<C-/>"] = "actions.show_help",
7
+
["<C-s>"] = "actions.select_split",
8
+
["<C-v>"] = "actions.select_vsplit",
9
+
["K"] = "actions.preview",
10
+
["<C-l>"] = "actions.refresh",
11
+
["<C-.>"] = "actions.toggle_hidden",
12
+
["-"] = "actions.parent",
13
+
["_"] = false,
14
+
["<c-h>"] = false,
15
+
["<c-p>"] = false,
16
+
["%"] = function()
17
+
vim.ui.input({ prompt = "Enter filename: " }, function(input)
18
+
vim.cmd.edit(vim.fn.expand("%") .. input)
19
+
end)
20
+
end,
21
+
},
22
+
})
+1
lua/plugins/rest.lua
+1
lua/plugins/rest.lua
···
1
+
require("rest-nvim").setup()
+77
lua/rocks-setup.lua
+77
lua/rocks-setup.lua
···
1
+
-- local rocks_config = {
2
+
-- rocks_path = vim.env.HOME .. "/.local/share/nvim_rocks/rocks",
3
+
-- luarocks_binary = vim.env.HOME .. "/.local/share/nvim_rocks/rocks/bin/luarocks",
4
+
-- }
5
+
--
6
+
-- vim.g.rocks_nvim = rocks_config
7
+
--
8
+
-- local luarocks_path = {
9
+
-- vim.fs.joinpath(rocks_config.rocks_path, "share", "lua", "5.1", "?.lua"),
10
+
-- vim.fs.joinpath(rocks_config.rocks_path, "share", "lua", "5.1", "?", "init.lua"),
11
+
-- }
12
+
-- package.path = package.path .. ";" .. table.concat(luarocks_path, ";")
13
+
--
14
+
-- local luarocks_cpath = {
15
+
-- vim.fs.joinpath(rocks_config.rocks_path, "lib", "lua", "5.1", "?.so"),
16
+
-- vim.fs.joinpath(rocks_config.rocks_path, "lib64", "lua", "5.1", "?.so"),
17
+
-- -- Remove the dylib and dll paths if you do not need macos or windows support
18
+
-- vim.fs.joinpath(rocks_config.rocks_path, "lib", "lua", "5.1", "?.dylib"),
19
+
-- vim.fs.joinpath(rocks_config.rocks_path, "lib64", "lua", "5.1", "?.dylib"),
20
+
-- vim.fs.joinpath(rocks_config.rocks_path, "lib", "lua", "5.1", "?.dll"),
21
+
-- vim.fs.joinpath(rocks_config.rocks_path, "lib64", "lua", "5.1", "?.dll"),
22
+
-- }
23
+
-- package.cpath = package.cpath .. ";" .. table.concat(luarocks_cpath, ";")
24
+
--
25
+
-- vim.opt.runtimepath:append(vim.fs.joinpath(rocks_config.rocks_path, "lib", "luarocks", "rocks-5.1", "*", "*"))
26
+
do
27
+
-- Specifies where to install/use rocks.nvim
28
+
local install_location = vim.fs.joinpath(vim.fn.stdpath("data"), "rocks")
29
+
30
+
-- Set up configuration options related to rocks.nvim (recommended to leave as default)
31
+
local rocks_config = {
32
+
rocks_path = vim.fs.normalize(install_location),
33
+
luarocks_binary = vim.fs.joinpath(install_location, "bin", "luarocks"),
34
+
}
35
+
36
+
vim.g.rocks_nvim = rocks_config
37
+
38
+
-- Configure the package path (so that plugin code can be found)
39
+
local luarocks_path = {
40
+
vim.fs.joinpath(rocks_config.rocks_path, "share", "lua", "5.1", "?.lua"),
41
+
vim.fs.joinpath(rocks_config.rocks_path, "share", "lua", "5.1", "?", "init.lua"),
42
+
}
43
+
package.path = package.path .. ";" .. table.concat(luarocks_path, ";")
44
+
45
+
-- Configure the C path (so that e.g. tree-sitter parsers can be found)
46
+
local luarocks_cpath = {
47
+
vim.fs.joinpath(rocks_config.rocks_path, "lib", "lua", "5.1", "?.so"),
48
+
vim.fs.joinpath(rocks_config.rocks_path, "lib64", "lua", "5.1", "?.so"),
49
+
}
50
+
package.cpath = package.cpath .. ";" .. table.concat(luarocks_cpath, ";")
51
+
52
+
-- Load all installed plugins, including rocks.nvim itself
53
+
vim.opt.runtimepath:append(vim.fs.joinpath(rocks_config.rocks_path, "lib", "luarocks", "rocks-5.1", "rocks.nvim", "*"))
54
+
end
55
+
56
+
-- If rocks.nvim is not installed then install it!
57
+
if not pcall(require, "rocks") then
58
+
local rocks_location = vim.fs.joinpath(vim.fn.stdpath("cache"), "rocks.nvim")
59
+
60
+
if not vim.uv.fs_stat(rocks_location) then
61
+
-- Pull down rocks.nvim
62
+
vim.fn.system({
63
+
"git",
64
+
"clone",
65
+
"--filter=blob:none",
66
+
"https://github.com/nvim-neorocks/rocks.nvim",
67
+
rocks_location,
68
+
})
69
+
end
70
+
71
+
-- If the clone was successful then source the bootstrapping script
72
+
assert(vim.v.shell_error == 0, "rocks.nvim installation failed. Try exiting and re-entering Neovim!")
73
+
74
+
vim.cmd.source(vim.fs.joinpath(rocks_location, "bootstrap.lua"))
75
+
76
+
vim.fn.delete(rocks_location, "rf")
77
+
end
+127
lua/snippets/all.lua
+127
lua/snippets/all.lua
···
1
+
require("luasnip.session.snippet_collection").clear_snippets("all")
2
+
3
+
local ls = require("luasnip")
4
+
local s = ls.snippet
5
+
local sn = ls.snippet_node
6
+
local i = ls.insert_node
7
+
local t = ls.text_node
8
+
local c = ls.choice_node
9
+
local r = ls.restore_node
10
+
local fmt = require("luasnip.extras.fmt").fmt
11
+
12
+
local function prevent_reexpand(_line_to_cursor, matched_trigger)
13
+
local current_node = ls.session.current_nodes[vim.api.nvim_get_current_buf()]
14
+
if not current_node then
15
+
return true
16
+
end
17
+
local is_same_trigger = current_node.parent.snippet.trigger == matched_trigger
18
+
local current_is_0 = current_node.pos == 0
19
+
if not (is_same_trigger and current_is_0) then
20
+
return true
21
+
end
22
+
local node_pos = current_node:get_buf_position()
23
+
local cur_pos = vim.api.nvim_win_get_cursor(0)
24
+
local same_pos = node_pos[1] + 1 == cur_pos[1] and node_pos[2] == cur_pos[2]
25
+
return not same_pos
26
+
end
27
+
28
+
local function create_autopair(open, close)
29
+
return s({
30
+
trig = open .. close,
31
+
wordTrig = false,
32
+
}, {
33
+
t(open),
34
+
c(1, {
35
+
r(1, "content", i(1)),
36
+
sn(nil, { t({ "", "\t" }), r(1, "content", i(1)), t({ "", "" }) }),
37
+
}),
38
+
t(close),
39
+
}, { condition = prevent_reexpand })
40
+
end
41
+
42
+
-- stylua: ignore
43
+
ls.add_snippets(nil, {
44
+
create_autopair("(", ")"),
45
+
create_autopair("[", "]"),
46
+
create_autopair("{", "}"),
47
+
create_autopair("(", "),"),
48
+
create_autopair("[", "],"),
49
+
create_autopair("{", "},"),
50
+
s({ trig = '""', wordTrig = false }, { t('"'), i(1), t('"') }, { condition = prevent_reexpand }),
51
+
s({ trig = "''", wordTrig = false }, { t("'"), i(1), t("'") }, { condition = prevent_reexpand }),
52
+
s({ trig = "``", wordTrig = false }, { t("`"), i(1), t("`") }, { condition = prevent_reexpand }),
53
+
})
54
+
55
+
-- autopair code from Luasnip's wiki
56
+
57
+
local function char_count_same(c1, c2)
58
+
local line = vim.api.nvim_get_current_line()
59
+
-- '%'-escape chars to force explicit match (gsub accepts patterns).
60
+
-- second return value is number of substitutions.
61
+
local _, ct1 = string.gsub(line, "%" .. c1, "")
62
+
local _, ct2 = string.gsub(line, "%" .. c2, "")
63
+
return ct1 == ct2
64
+
end
65
+
66
+
local function even_count(ch)
67
+
local line = vim.api.nvim_get_current_line()
68
+
local _, ct = string.gsub(line, ch, "")
69
+
return ct % 2 == 0
70
+
end
71
+
72
+
local function neg(fn, ...)
73
+
return not fn(...)
74
+
end
75
+
76
+
local function posi()
77
+
return true
78
+
end
79
+
80
+
local function part(fn, ...)
81
+
local args = { ... }
82
+
return function()
83
+
return fn(unpack(args))
84
+
end
85
+
end
86
+
87
+
-- This makes creation of pair-type snippets easier.
88
+
local function pair(pair_begin, pair_end, expand_func, ...)
89
+
-- triggerd by opening part of pair, wordTrig=false to trigger anywhere.
90
+
-- ... is used to pass any args following the expand_func to it.
91
+
return s({ trig = pair_begin, wordTrig = false }, {
92
+
t({ pair_begin }),
93
+
c(1, {
94
+
r(1, "content", i(1)),
95
+
sn(nil, { t({ "", "\t" }), r(1, "content", i(1)), t({ "", "" }) }),
96
+
}),
97
+
t({ pair_end }),
98
+
}, {
99
+
condition = expand_func and part(expand_func, part(..., pair_begin, pair_end)),
100
+
})
101
+
end
102
+
103
+
-- FIXME: pair() also doesn't work bc of this case:
104
+
-- ```
105
+
-- vim.schedule(function (|)
106
+
-- end)
107
+
-- ```
108
+
-- here, I get unwanted autopair (|))
109
+
ls.add_snippets(nil, {
110
+
pair("(", ")", neg, char_count_same),
111
+
pair("{", "}", neg, char_count_same),
112
+
pair("[", "]", neg, char_count_same),
113
+
pair("<", ">", neg, char_count_same),
114
+
pair("'", "'", neg, even_count),
115
+
pair('"', '"', neg, even_count),
116
+
pair("`", "`", neg, even_count),
117
+
})
118
+
119
+
ls.add_snippets("all", {
120
+
pair("(", ")"),
121
+
pair("{", "}"),
122
+
pair("[", "]"),
123
+
pair("<", ">"),
124
+
pair("'", "'"),
125
+
pair('"', '"'),
126
+
pair("`", "`"),
127
+
})
+21
lua/snippets/go.lua
+21
lua/snippets/go.lua
···
1
+
require("luasnip.session.snippet_collection").clear_snippets("go")
2
+
3
+
local ls = require("luasnip")
4
+
local s = ls.snippet
5
+
local sn = ls.snippet_node
6
+
local i = ls.insert_node
7
+
local t = ls.text_node
8
+
local c = ls.choice_node
9
+
local fmt = require("luasnip.extras.fmt").fmt
10
+
11
+
-- stylua: ignore
12
+
ls.add_snippets("go", {
13
+
s("ife", {
14
+
t{"if err != nil {", ""},
15
+
t"\t", c(1, {
16
+
sn(nil, { t"return ", i(1), t"err" }),
17
+
t"log.Fatalln(err)",
18
+
}),
19
+
t{"", "}"}, i(0),
20
+
}),
21
+
})
+39
lua/snippets/lua.lua
+39
lua/snippets/lua.lua
···
1
+
require("luasnip.session.snippet_collection").clear_snippets("lua")
2
+
3
+
local ls = require("luasnip")
4
+
local s = ls.snippet
5
+
local sn = ls.snippet_node
6
+
local i = ls.insert_node
7
+
local t = ls.text_node
8
+
local fmt = require("luasnip.extras.fmt").fmt
9
+
local c = ls.choice_node
10
+
11
+
-- stylua: ignore
12
+
ls.add_snippets("lua", {
13
+
s("fn", fmt([[
14
+
function {}({})
15
+
{}{}
16
+
end
17
+
]], { i(1), i(2), t("\t"), i(3) })),
18
+
s("lfn", fmt([[
19
+
local function {}({})
20
+
{}{}
21
+
end
22
+
]], { i(1, "name"), i(2), t("\t"), i(3) })),
23
+
s("if", fmt([[
24
+
if {} then
25
+
{}{}
26
+
end
27
+
]], { i(1), t"\t", i(2) })),
28
+
s("for", {
29
+
t"for ",
30
+
c(1, {
31
+
sn(nil, { i(1, "i"), t" = ", i(2, "1"), t", ", i(3, "10, 1") }),
32
+
sn(nil, { i(1, "key"), t", ", i(2, "value"), t" in pairs(", i(3, "t"), t")" }),
33
+
sn(nil, { i(1, "index"), t", ", i(2, "value"), t" in ipairs(", i(3, "t"), t")" }),
34
+
}),
35
+
t{" do", "\t"},
36
+
i(2),
37
+
t{"", "end"},
38
+
}),
39
+
})
+16
lua/snippets/rust.lua
+16
lua/snippets/rust.lua
···
1
+
require("luasnip.session.snippet_collection").clear_snippets("rust")
2
+
3
+
local ls = require("luasnip")
4
+
local s = ls.snippet
5
+
local sn = ls.snippet_node
6
+
local i = ls.insert_node
7
+
local t = ls.text_node
8
+
local c = ls.choice_node
9
+
local fmt = require("luasnip.extras.fmt").fmt
10
+
11
+
-- stylua: ignore
12
+
ls.add_snippets("rust", {
13
+
s("cl", {
14
+
t"|", i(1), t"|", t" {", i(2), t"}",
15
+
}),
16
+
})
+103
lua/snippets/tsx.lua
+103
lua/snippets/tsx.lua
···
1
+
require("luasnip.session.snippet_collection").clear_snippets("typescriptreact")
2
+
3
+
local ls = require("luasnip")
4
+
local s = ls.snippet
5
+
local i = ls.insert_node
6
+
local t = ls.text_node
7
+
local c = ls.choice_node
8
+
local fn = ls.function_node
9
+
local dn = ls.dynamic_node
10
+
local sn = ls.snippet_node
11
+
local rep = require("luasnip.extras").rep
12
+
local fmt = require("luasnip.extras.fmt").fmt
13
+
local fmta = require("luasnip.extras.fmt").fmta
14
+
15
+
-- Get a list of the property names given an `interface_declaration`
16
+
-- treesitter *tsx* node.
17
+
-- Ie, if the treesitter node represents:
18
+
-- interface {
19
+
-- prop1: string;
20
+
-- prop2: number;
21
+
-- }
22
+
-- Then this function would return `{"prop1", "prop2"}
23
+
---@param node TSNode interface declaration node
24
+
---@return string[]
25
+
local function get_prop_names(node)
26
+
local interface_body = node:field("body")[1]
27
+
if not interface_body then
28
+
return {}
29
+
end
30
+
31
+
local prop_names = {}
32
+
33
+
for prop_signature in interface_body:iter_children() do
34
+
if prop_signature:type() == "property_signature" then
35
+
local prop_iden = prop_signature:child(0)
36
+
local prop_name = vim.treesitter.get_node_text(prop_iden, 0)
37
+
prop_names[#prop_names + 1] = prop_name
38
+
end
39
+
end
40
+
41
+
return prop_names
42
+
end
43
+
44
+
-- original: https://gist.github.com/davidatsurge/9873d9cb1781f1a37c0f25d24cb1b3ab
45
+
-- https://www.reddit.com/r/neovim/comments/uuhk1t/feedback_on_luasniptreesitter_snippet_that_fills/
46
+
local componentWithProps = fmta(
47
+
[[
48
+
<>interface <>Props {
49
+
<><>
50
+
}
51
+
52
+
export function <>({ <> }: <>Props) {
53
+
<>return <>;
54
+
};
55
+
]],
56
+
{
57
+
c(1, { t "export ", t "" }),
58
+
-- Initialize component name to file name
59
+
rep(3),
60
+
t "\t",
61
+
i(2, "// Props"),
62
+
dn(3, function(_, snip)
63
+
local filename = vim.fn.expand("%:t:r")
64
+
local comp_name
65
+
-- TODO: rewrite this with `vim.fs` lua api
66
+
if filename == "index" then
67
+
comp_name = vim.fn.expand("%"):match("([^/]+)/[^/]+$")
68
+
else
69
+
comp_name = vim.fn.substitute(snip.env.TM_FILENAME, "\\..*$", "", "g")
70
+
end
71
+
return sn(nil, { i(1, comp_name) })
72
+
end, { 1 }),
73
+
fn(function(_, snip, _)
74
+
local pos_begin = snip.nodes[4].mark:pos_begin()
75
+
local pos_end = snip.nodes[4].mark:pos_end()
76
+
local parser = vim.treesitter.get_parser(0, "tsx")
77
+
local tstree = parser:parse()
78
+
79
+
local node = tstree[1]:root():named_descendant_for_range(pos_begin[1], pos_begin[2], pos_end[1], pos_end[2])
80
+
81
+
while node ~= nil and node:type() ~= "interface_declaration" do
82
+
node = node:parent()
83
+
end
84
+
85
+
if node == nil then
86
+
return ""
87
+
end
88
+
89
+
-- `node` is now surely of type "interface_declaration"
90
+
local prop_names = get_prop_names(node)
91
+
92
+
return vim.fn.join(prop_names, ", ")
93
+
end, { 2 }),
94
+
rep(3),
95
+
t "\t",
96
+
i(4, "null"),
97
+
}
98
+
)
99
+
100
+
-- stylua: ignore
101
+
ls.add_snippets("typescriptreact", {
102
+
s("cp", componentWithProps),
103
+
})
+90
lua/utils/format.lua
+90
lua/utils/format.lua
···
1
+
local Util = require("utils")
2
+
3
+
---@class bt.util.format
4
+
local M = {}
5
+
6
+
---@param buf? number
7
+
---@return boolean
8
+
function M.enabled(buf)
9
+
buf = (buf == nil or buf == 0) and vim.api.nvim_get_current_buf() or buf
10
+
11
+
-- autoformat options fallback. buffer > editorconfig > global
12
+
-- stylua: ignore
13
+
return vim.F.if_nil(
14
+
vim.b[buf].autoformat,
15
+
vim.b[buf].editorconfig_autoformat,
16
+
vim.g.autoformat
17
+
)
18
+
end
19
+
20
+
function M.toggle()
21
+
-- TODO: if editorconfig says autoformat in that buffer is enabled,
22
+
-- disable it with buffer-local variable
23
+
if vim.b.editorconfig_autoformat ~= nil or vim.b.autoformat ~= nil then
24
+
vim.b.autoformat = not M.enabled()
25
+
else
26
+
vim.g.autoformat = not M.enabled()
27
+
vim.b.autoformat = nil
28
+
end
29
+
M.info()
30
+
end
31
+
32
+
---@param buf? number
33
+
function M.info(buf)
34
+
buf = buf or vim.api.nvim_get_current_buf()
35
+
Util.notify.info({
36
+
("* Status *%s*"):format(M.enabled(buf) and "enabled" or "disabled"),
37
+
("- (%s) global"):format(vim.g.autoformat and "x" or " "),
38
+
("- (%s) editorconfig"):format(vim.b[buf].editorconfig_autoformat and "x" or " "),
39
+
("- (%s) buffer"):format(vim.b[buf].autoformat and "x" or " "),
40
+
})
41
+
end
42
+
43
+
function M.setup()
44
+
vim.g.autoformat = false
45
+
-- Autoformat autocmd
46
+
vim.api.nvim_create_autocmd("BufWritePre", {
47
+
group = vim.api.nvim_create_augroup("AutoFormat", {}),
48
+
callback = function(event)
49
+
if M.enabled(event.buf) then
50
+
require("conform").format({
51
+
lsp_fallback = true,
52
+
async = false,
53
+
})
54
+
end
55
+
end,
56
+
})
57
+
58
+
vim.api.nvim_create_user_command("Format", function(args)
59
+
local range = nil
60
+
if args.count ~= -1 then
61
+
local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1]
62
+
range = {
63
+
start = { args.line1, 0 },
64
+
["end"] = { args.line2, end_line:len() },
65
+
}
66
+
end
67
+
68
+
local ok = require("conform").format({
69
+
lsp_fallback = true,
70
+
async = true,
71
+
range = range,
72
+
})
73
+
-- TODO: check that ranged-format failed
74
+
if not ok then
75
+
Util.notify.warn("No formatter available", { title = "Formatter" })
76
+
end
77
+
end, {
78
+
desc = "Format selection or buffer",
79
+
range = true,
80
+
})
81
+
82
+
vim.api.nvim_create_user_command("FormatInfo", function()
83
+
M.info()
84
+
end, { desc = "Show info about the formatters for the current buffer" })
85
+
86
+
vim.api.nvim_create_user_command("FormatToggle", function()
87
+
M.toggle()
88
+
end, { desc = "Toggle autoformat option" })
89
+
end
90
+
return M
+215
lua/utils/highlights.lua
+215
lua/utils/highlights.lua
···
1
+
---@class bt.util.highlights
2
+
local M = {}
3
+
4
+
-- TODO: fuck. rewrite this sometime
5
+
-- dealing with types is way hard then I thought
6
+
7
+
---@alias HLAttr {from: string, attr: "fg" | "bg", alter: integer}
8
+
9
+
---@class HLData
10
+
---@field fg? string foreground
11
+
---@field bg? string background
12
+
---@field sp? string special
13
+
---@field blend? integer between 0 and 100
14
+
---@field bold? boolean
15
+
---@field standout? boolean
16
+
---@field underline? boolean
17
+
---@field undercurl? boolean
18
+
---@field underdouble? boolean
19
+
---@field underdotted? boolean
20
+
---@field underdashed? boolean
21
+
---@field strikethrough? boolean
22
+
---@field italic? boolean
23
+
---@field reverse? boolean
24
+
---@field nocombine? boolean
25
+
---@field link? string
26
+
---@field default? boolean
27
+
28
+
---@alias HLAttrName
29
+
---| '"fg"'
30
+
---| '"bg"'
31
+
---| '"sp"'
32
+
---| '"blend"'
33
+
---| '"bold"'
34
+
---| '"standout"'
35
+
---| '"underline"'
36
+
---| '"undercurl"'
37
+
---| '"underdouble"'
38
+
---| '"underdotted"'
39
+
---| '"underdashed"'
40
+
---| '"strikethrough"'
41
+
---| '"italic"'
42
+
---| '"reverse"'
43
+
---| '"nocombine"'
44
+
---| '"link"'
45
+
---| '"default"'
46
+
47
+
---@class HLArgs: HLData
48
+
---@field fg? string | HLAttr
49
+
---@field bg? string | HLAttr
50
+
---@field sp? string | HLAttr
51
+
---@field clear? boolean clear existing highlight
52
+
---@field inherit? string inherit other highlight
53
+
54
+
---@private
55
+
---@param opts? {name?: string, link?: boolean}
56
+
---@param ns? integer
57
+
---@return vim.api.keyset.hl_info|nil
58
+
local function get_hl_as_hex(opts, ns)
59
+
opts = opts or {}
60
+
ns = ns or 0
61
+
opts.link = opts.link ~= nil and opts.link or false
62
+
local hl = vim.api.nvim_get_hl(ns, opts)
63
+
if vim.tbl_isempty(hl) then
64
+
return nil
65
+
end
66
+
hl.fg = hl.fg and ("#%06x"):format(hl.fg)
67
+
hl.bg = hl.bg and ("#%06x"):format(hl.bg)
68
+
return hl
69
+
end
70
+
71
+
---Change the brightness of a color, negative numbers darken and positive ones brighten
72
+
---see:
73
+
---1. https://stackoverflow.com/q/5560248
74
+
---2. https://stackoverflow.com/a/37797380
75
+
---@param color string A hex color
76
+
---@param percent float a negative number darkens and a positive one brightens
77
+
---@return string
78
+
function M.tint(color, percent)
79
+
assert(color and percent, "cannot alter a color without specifying a color and percentage")
80
+
local r = tonumber(color:sub(2, 3), 16)
81
+
local g = tonumber(color:sub(4, 5), 16)
82
+
local b = tonumber(color:sub(6), 16)
83
+
if not r or not g or not b then
84
+
return "NONE"
85
+
end
86
+
local blend = function(component)
87
+
component = math.floor(component * (1 + percent))
88
+
return math.min(math.max(component, 0), 255)
89
+
end
90
+
return string.format("#%02x%02x%02x", blend(r), blend(g), blend(b))
91
+
end
92
+
93
+
---Get the value a highlight group whilst handling errors and fallbacks as well as returning a gui value
94
+
---If no attribute is specified return the entire highlight table
95
+
---in the right format
96
+
---@param group string
97
+
---@param attribute HLAttrName
98
+
---@param fallback string?
99
+
---@return string
100
+
function M.get(group, attribute, fallback)
101
+
local data = get_hl_as_hex({ name = group })
102
+
local color = (data and data[attribute]) or fallback or "NONE"
103
+
if not color then
104
+
local error_msg =
105
+
string.format("failed to get highlight %s for attribute %s\n%s", group, attribute, debug.traceback())
106
+
local error_title = string.format("Highlight - get(%s)", group)
107
+
vim.schedule(function()
108
+
vim.notify(error_msg, vim.log.levels.ERROR, { title = error_title })
109
+
end)
110
+
return "NONE"
111
+
end
112
+
return color
113
+
end
114
+
115
+
---resolve fg/bg/sp attribute type
116
+
---@param hl string | HLAttr
117
+
---@param attr string
118
+
---@return string
119
+
local function resolve_from_attr(hl, attr)
120
+
if type(hl) ~= "table" then
121
+
return hl
122
+
end
123
+
local color = M.get(hl.from, hl.attr or attr)
124
+
color = color == "NONE" and M.get("Normal", hl.attr or attr) or color
125
+
-- TODO: tint color
126
+
return color
127
+
end
128
+
129
+
--- Sets a neovim highlight with some syntactic sugar. It takes a highlight table and converts
130
+
--- any highlights specified as `GroupName = {fg = { from = 'group'}}` into the underlying colour
131
+
--- by querying the highlight property of the from group so it can be used when specifying highlights
132
+
--- as a shorthand to derive the right colour.
133
+
--- For example:
134
+
--- ```lua
135
+
--- M.set({ MatchParen = {fg = {from = 'ErrorMsg'}}})
136
+
--- ```
137
+
--- This will take the foreground colour from ErrorMsg and set it to the foreground of MatchParen.
138
+
--- NOTE: this function must NOT mutate the options table as these are re-used when the colorscheme is updated
139
+
---
140
+
---@param ns integer
141
+
---@param name string
142
+
---@param opts HLArgs
143
+
---@overload fun(name: string, opts: HLArgs)
144
+
function M.set(ns, name, opts)
145
+
if type(ns) == "string" and type(name) == "table" then
146
+
opts, name, ns = name, ns, 0
147
+
end
148
+
149
+
local hl = opts.clear and {} or get_hl_as_hex({ name = opts.inherit or name }) or {}
150
+
for attribute, data in pairs(opts) do
151
+
if attribute ~= "clear" and attribute ~= "inherit" then
152
+
local new_data = resolve_from_attr(data, attribute)
153
+
hl[attribute] = new_data
154
+
end
155
+
end
156
+
157
+
-- FIXME: this part
158
+
vim.api.nvim_set_hl(ns, name, hl --[[@as vim.api.keyset.highlight]])
159
+
end
160
+
161
+
---Apply a list of highlights
162
+
---@param hls table<string, HLArgs>
163
+
---@param namespace integer?
164
+
function M.all(hls, namespace)
165
+
for name, args in pairs(hls) do
166
+
M.set(namespace or 0, name, args)
167
+
end
168
+
end
169
+
170
+
---Set window local highlights
171
+
---@param name string
172
+
---@param win_id number
173
+
---@param hls table<string, HLArgs>
174
+
function M.set_winhl(name, win_id, hls)
175
+
local namespace = vim.api.nvim_create_namespace(name)
176
+
M.all(hls, namespace)
177
+
vim.api.nvim_win_set_hl_ns(win_id, namespace)
178
+
end
179
+
180
+
---Run `cb()` on `ColorScheme` event.
181
+
---This is useful when *color override* code is quite complicate
182
+
---@param name string
183
+
---@param cb function
184
+
function M.plugin_wrap(name, cb)
185
+
cb()
186
+
local augroup_name = name:gsub("^%l", string.upper) .. "HighlightOverrides"
187
+
vim.api.nvim_create_autocmd({ "ColorScheme", "UIEnter" }, {
188
+
group = vim.api.nvim_create_augroup(augroup_name, { clear = true }),
189
+
callback = function()
190
+
-- Defer resetting these highlights to ensure they apply *after* other overrides
191
+
vim.defer_fn(function()
192
+
cb()
193
+
end, 1)
194
+
end,
195
+
})
196
+
end
197
+
198
+
---Apply highlights for a plugin and refresh on colorscheme change
199
+
---@param name string plugin name
200
+
---@param hls table<string, HLArgs>
201
+
function M.plugin(name, hls)
202
+
M.plugin_wrap(name, function()
203
+
M.all(hls)
204
+
end)
205
+
end
206
+
207
+
---Apply highlight to given text
208
+
---@param content any
209
+
---@param hlgroup string
210
+
---@return string
211
+
function M.hl_text(content, hlgroup)
212
+
return string.format("%%#%s#%s%%*", hlgroup, content)
213
+
end
214
+
215
+
return M
+27
lua/utils/init.lua
+27
lua/utils/init.lua
···
1
+
---@class bt.util
2
+
---@field notify bt.util.notify
3
+
---@field highlights bt.util.highlights
4
+
---@field format bt.util.format
5
+
local M = {}
6
+
setmetatable(M, {
7
+
__index = function(t, k)
8
+
t[k] = require("utils." .. k)
9
+
return t[k]
10
+
end,
11
+
})
12
+
13
+
---@param ms number
14
+
---@param fn function
15
+
---@return function
16
+
function M.debounce(ms, fn)
17
+
local timer = vim.uv.new_timer()
18
+
return function(...)
19
+
local argv = {...}
20
+
timer:start(ms, 0, function()
21
+
timer:stop()
22
+
vim.schedule_wrap(fn)(unpack(argv))
23
+
end)
24
+
end
25
+
end
26
+
27
+
return M
+53
lua/utils/notify.lua
+53
lua/utils/notify.lua
···
1
+
---@class bt.util.notify
2
+
local M = {}
3
+
4
+
---@alias BtNotifyOpts {lang?:string, title?:string, level?:number, once?:boolean}
5
+
6
+
---@param msg string|string[]
7
+
---@param opts? BtNotifyOpts
8
+
function M.notify(msg, opts)
9
+
if vim.in_fast_event() then
10
+
return vim.schedule(function()
11
+
M.notify(msg, opts)
12
+
end)
13
+
end
14
+
15
+
opts = opts or {}
16
+
if type(msg) == "table" then
17
+
msg = table.concat(
18
+
vim.tbl_filter(function(line)
19
+
return line or false
20
+
end, msg),
21
+
"\n"
22
+
)
23
+
end
24
+
vim.notify(msg, opts.level or vim.log.levels.INFO, {
25
+
title = opts.title or "config",
26
+
})
27
+
end
28
+
29
+
---@param msg string|string[]
30
+
---@param opts? BtNotifyOpts
31
+
function M.error(msg, opts)
32
+
opts = opts or {}
33
+
opts.level = vim.log.levels.ERROR
34
+
M.notify(msg, opts)
35
+
end
36
+
37
+
---@param msg string|string[]
38
+
---@param opts? BtNotifyOpts
39
+
function M.info(msg, opts)
40
+
opts = opts or {}
41
+
opts.level = vim.log.levels.INFO
42
+
M.notify(msg, opts)
43
+
end
44
+
45
+
---@param msg string|string[]
46
+
---@param opts? BtNotifyOpts
47
+
function M.warn(msg, opts)
48
+
opts = opts or {}
49
+
opts.level = vim.log.levels.WARN
50
+
M.notify(msg, opts)
51
+
end
52
+
53
+
return M
+82
rocks.toml
+82
rocks.toml
···
1
+
# This is your rocks.nvim plugins declaration file.
2
+
# Here is a small yet pretty detailed example on how to use it:
3
+
#
4
+
# [plugins]
5
+
# nvim-treesitter = "semver_version" # e.g. "1.0.0"
6
+
7
+
# List of non-Neovim rocks.
8
+
# This includes things like `toml` or other lua packages.
9
+
[rocks]
10
+
11
+
# List of Neovim plugins to install alongside their versions.
12
+
# If the plugin name contains a dot then you must add quotes to the key name!
13
+
[plugins]
14
+
"rocks.nvim" = "2.35.0"
15
+
"rocks-git.nvim" = "1.5.1"
16
+
"rocks-dev.nvim" = "1.2.3"
17
+
"rocks-config.nvim" = "2.1.3"
18
+
"rocks-edit.nvim" = "scm"
19
+
"rocks-treesitter.nvim" = "scm"
20
+
# harpoon uses plenary.nvim
21
+
"plenary.nvim" = "scm"
22
+
github-nvim-theme = "1.0.2"
23
+
nvim-lspconfig = "0.1.8"
24
+
"mason.nvim" = "1.10.0"
25
+
"indent-blankline.nvim" = "3.7.1"
26
+
"conform.nvim" = "6.0.0"
27
+
"fidget.nvim" = "1.4.1"
28
+
nvim-ufo = "1.4.0"
29
+
luasnip = "2.3.0"
30
+
neogit = "scm"
31
+
"kanagawa.nvim" = "scm"
32
+
"rest.nvim" = "2.0.1"
33
+
"mini.ai" = "scm"
34
+
nvim-surround = "2.1.5"
35
+
nvim-treesitter-legacy-api = "0.9.2"
36
+
fzf-lua = "0.0.1363"
37
+
38
+
tree-sitter-css = "scm"
39
+
tree-sitter-ecma = "scm"
40
+
tree-sitter-go = "scm"
41
+
tree-sitter-html = "scm"
42
+
tree-sitter-http = "scm"
43
+
tree-sitter-javascript = "scm"
44
+
tree-sitter-json = "scm"
45
+
tree-sitter-jsx = "scm"
46
+
tree-sitter-lua = "scm"
47
+
tree-sitter-make = "scm"
48
+
tree-sitter-query = "scm"
49
+
tree-sitter-rust = "scm"
50
+
tree-sitter-templ = "scm"
51
+
tree-sitter-toml = "scm"
52
+
tree-sitter-tsx = "scm"
53
+
tree-sitter-typescript = "scm"
54
+
tree-sitter-yaml = "scm"
55
+
56
+
"oil.nvim" = { git = "stevearc/oil.nvim", rev = "v2.9.0" }
57
+
nvim-cmp = { git = "hrsh7th/nvim-cmp" }
58
+
cmp-nvim-lsp = { git = "hrsh7th/cmp-nvim-lsp" }
59
+
"leap.nvim" = { git = "ggandor/leap.nvim" }
60
+
harpoon = { git = "ThePrimeagen/harpoon", branch = "harpoon2" }
61
+
# for some plugins that needs legacy api (e.g. nvim-surround)
62
+
nvim-treesitter-textobjects = { dir = "~/repo/nvim-treesitter-textobjects" }
63
+
# neodev doesn't work when installed from luarocks
64
+
# "neodev.nvim" = { git = "folke/neodev.nvim", rev = "v3.0.0" }
65
+
nvim-lint = "scm"
66
+
tree-sitter-gomod = "scm"
67
+
tree-sitter-dockerfile = "scm"
68
+
tree-sitter-regex = "scm"
69
+
70
+
[plugins."crates.nvim" ]
71
+
git = "Saecki/crates.nvim"
72
+
rev = "v0.5.1"
73
+
74
+
[plugins."gitsigns.nvim" ]
75
+
git = "lewis6991/gitsigns.nvim"
76
+
rev = "v0.9.0"
77
+
78
+
[config]
79
+
auto_setup = false
80
+
81
+
[treesitter]
82
+
auto_highlight = "all"