neovim configuration using rocks.nvim plugin manager

Initial Commit

Seongmin Lee 3dc5defd

+4
.stylua.toml
··· 1 + indent_type = "Spaces" 2 + indent_width = 4 3 + column_width = 120 4 + call_parentheses = "Input"
+1
after/ftplugin/go.vim
··· 1 + setlocal noexpandtab
+1
after/ftplugin/http.vim
··· 1 + nnoremap <buffer> <cr> <cmd>Rest run<cr>
+2
after/ftplugin/markdown.vim
··· 1 + setlocal wrap 2 + setlocal colorcolumn=
+11
after/ftplugin/norg.vim
··· 1 + nnoremap <buffer> j gj 2 + nnoremap <buffer> k gk 3 + nnoremap <buffer> 0 g0 4 + nnoremap <buffer> ^ g^ 5 + nnoremap <buffer> $ g$ 6 + 7 + setlocal breakindent 8 + setlocal formatoptions-=r 9 + setlocal linebreak 10 + setlocal shiftwidth=1 11 + setlocal wrap
+5
ftdetect/http.lua
··· 1 + vim.filetype.add({ 2 + extension = { 3 + http = "http", 4 + }, 5 + })
+8
init.lua
··· 1 + require("rocks-setup") 2 + require("core.keymaps") 3 + require("core.options") 4 + require("core.autocmds") 5 + require("core.highlights") 6 + require("core.lsp") 7 + 8 + require("utils.format").setup()
+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
··· 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
··· 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
··· 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
··· 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
··· 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

This is a binary file and will not be displayed.

+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
··· 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
··· 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
··· 1 + require("fidget").setup({ 2 + progress = { 3 + display = { 4 + -- see https://github.com/j-hui/fidget.nvim/blob/main/lua/fidget/spinner/patterns.lua 5 + progress_icon = { "arc" }, 6 + }, 7 + }, 8 + })
+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
··· 1 + require("gitsigns").setup({ 2 + on_attach = function() 3 + vim.api.nvim_exec_autocmds("User", { 4 + pattern = "GitAttach", 5 + }) 6 + end, 7 + })
+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
··· 1 + require("ibl").setup({ 2 + scope = { 3 + enabled = false, 4 + }, 5 + })
+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
··· 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
··· 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 + require("neogit").setup()
+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
··· 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
··· 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
··· 1 + -- require("nvim-treesitter.configs").setup({ 2 + -- highlight = { 3 + -- enable = false, 4 + -- }, 5 + -- })
+8
lua/plugins/nvim-ufo.lua
··· 1 + require("ufo").setup({ 2 + provider_selector = function(_bufnr, _filetype, _buftype) 3 + return { "treesitter" } 4 + end, 5 + }) 6 + 7 + vim.keymap.set("n", "zR", require("ufo").openAllFolds) 8 + vim.keymap.set("n", "zM", require("ufo").closeAllFolds)
+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 + require("rest-nvim").setup()
+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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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"
+4
todo.norg
··· 1 + - (x) `ds'` to delete surrounding `'` 2 + - ( ) `ds%` to delete any surrounding under cursor 3 + - ( ) `:h 'matchpairs'` 4 + - ( ) statusbar