From 457674c5b25b9f4be84f0f0ddf0cea7c1811174a Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Sun, 18 Oct 2026 15:54:35 -0600 Subject: Redesign my vim config. Now uses Lua primarily Breaks apart the configuration into rc-service style configuration files. Deletes a ton of the cruft with old LSP settings. --- lua/config/00-options.lua | 42 ++++ lua/config/01-plugins.lua | 56 ++++++ lua/config/02-mappings.lua | 148 ++++++++++++++ lua/config/03-commands.lua | 85 ++++++++ lua/config/04-autocmds.lua | 67 +++++++ lua/config/05-lsp.lua | 141 +++++++++++++ lua/config/99-extregs-config.lua | 17 ++ lua/config/99-gitsigns-config.lua | 27 +++ lua/config/99-hop-config.lua | 2 + lua/config/99-lualine-config.lua | 32 +++ lua/config/99-nvim-surround-config.lua | 2 + lua/config/99-nvim-treesitter-config.lua | 86 ++++++++ lua/config/99-nvim-web-devicons-config.lua | 2 + lua/config/99-telescope-config.lua | 19 ++ lua/config/99-treesitter-config.lua | 87 ++++++++ lua/diagnostics.lua | 55 ------ lua/lsp.lua | 308 ----------------------------- lua/lualinesetup.lua | 47 ----- lua/tabby.lua | 32 --- lua/treesitter-textobjects-setup.lua | 52 ----- lua/treesitter.lua | 45 ----- lua/windownav.lua | 76 ------- 22 files changed, 813 insertions(+), 615 deletions(-) create mode 100644 lua/config/00-options.lua create mode 100644 lua/config/01-plugins.lua create mode 100644 lua/config/02-mappings.lua create mode 100644 lua/config/03-commands.lua create mode 100644 lua/config/04-autocmds.lua create mode 100644 lua/config/05-lsp.lua create mode 100644 lua/config/99-extregs-config.lua create mode 100644 lua/config/99-gitsigns-config.lua create mode 100644 lua/config/99-hop-config.lua create mode 100644 lua/config/99-lualine-config.lua create mode 100644 lua/config/99-nvim-surround-config.lua create mode 100644 lua/config/99-nvim-treesitter-config.lua create mode 100644 lua/config/99-nvim-web-devicons-config.lua create mode 100644 lua/config/99-telescope-config.lua create mode 100644 lua/config/99-treesitter-config.lua delete mode 100644 lua/diagnostics.lua delete mode 100644 lua/lsp.lua delete mode 100644 lua/lualinesetup.lua delete mode 100644 lua/tabby.lua delete mode 100644 lua/treesitter-textobjects-setup.lua delete mode 100644 lua/treesitter.lua delete mode 100644 lua/windownav.lua (limited to 'lua') diff --git a/lua/config/00-options.lua b/lua/config/00-options.lua new file mode 100644 index 0000000..629c14d --- /dev/null +++ b/lua/config/00-options.lua @@ -0,0 +1,42 @@ +-- Editor options extracted from the original init.vim. +-- Load before plugin setup where possible (especially netrw and mapleader). + +local opt = vim.opt +local g = vim.g + +g.loaded_netrw = 1 +g.loaded_netrwPlugin = 1 +g.mapleader = ' ' + + +-- Display and navigation. +opt.termguicolors = true +opt.number = true +opt.relativenumber = true +opt.wrap = false +opt.scrolloff = 8 +opt.title = true +opt.colorcolumn = '+1' + +-- Indentation and text layout. +opt.shiftwidth = 2 +opt.tabstop = 2 +opt.expandtab = true +opt.textwidth = 80 + +-- Splits and completion. +opt.splitright = true +opt.splitbelow = true +opt.wildmode = { 'longest', 'list', 'full' } +opt.pumheight = 20 +opt.completeopt = { 'menu', 'menuone', 'noselect' } + +-- Performance, responsiveness, and matching pairs. +opt.updatetime = 1000 +opt.matchpairs:append('<:>') + +-- Global configuration for plugins. +g.vsnip_snippet_dir = vim.fn.expand('~/.config/nvim/snippets') +g.vsnip_snippet_dirs = { vim.fn.expand('~/.config/nvim/local/snippets') } +g.jq_highlight_objects = 1 +g.jq_highlight_function_calls = 1 diff --git a/lua/config/01-plugins.lua b/lua/config/01-plugins.lua new file mode 100644 index 0000000..e0acdd0 --- /dev/null +++ b/lua/config/01-plugins.lua @@ -0,0 +1,56 @@ +-- Core plugin list: Neovim 0.12+ built-in package manager. +-- GitHub shorthand (owner/repo) is not supported by vim.pack. +local github = function(repo) + return 'https://github.com/' .. repo .. '.git' +end + +-- Josher projects: local working checkout takes precedence over Git. +-- Change the root on each machine or override this helper locally. +local projects = vim.fn.expand('~/Projects') +local function josher(repo) + local path = projects .. '/' .. repo + if vim.fn.isdirectory(path) == 1 then + -- Place local checkout on runtimepath instead of downloading it. + vim.opt.rtp:prepend(path) + return nil + end + return 'git@git.josher.dev:' .. repo .. '.git' +end + +local plugins = { + -- Searching + github('nvim-lua/plenary.nvim'), + github('nvim-telescope/telescope.nvim'), + + -- Syntax / structural editing + github('nvim-treesitter/nvim-treesitter'), + github('nvim-treesitter/nvim-treesitter-textobjects'), + + -- Editing and navigation + github('lewis6991/gitsigns.nvim'), + github('kylechui/nvim-surround'), + github('smoka7/hop.nvim'), + + -- UI + github('nvim-lualine/lualine.nvim'), + github('nvim-tree/nvim-web-devicons'), + + -- LSP server presets only; native vim.lsp.enable/config is used elsewhere. + github('neovim/nvim-lspconfig'), + + -- Existing personal plugins; delete entries you no longer want. + josher('bulletjava.vim'), + josher('fieldmarshal.vim'), + josher('nvim-color-picker'), + josher('nvim-warp'), + josher('meltdown'), + josher('extregs.nvim'), + -- josher('rneovim-userregs'), -- Optional experimental branch/plugin. +} + +-- Local projects return nil; remove holes before calling vim.pack. +local install = {} +for _, plugin in pairs(plugins) do + if plugin then install[#install + 1] = plugin end +end +vim.pack.add(install) diff --git a/lua/config/02-mappings.lua b/lua/config/02-mappings.lua new file mode 100644 index 0000000..8c4f6e3 --- /dev/null +++ b/lua/config/02-mappings.lua @@ -0,0 +1,148 @@ +-- Global mappings migrated from the original init.vim. +-- Load after setting vim.g.mapleader = " " and after defining required commands. +-- Plugin-owned mappings (LSP, Gitsigns, Tree-sitter, Trouble) remain in their setup files. + +vim.g.mapleader = vim.g.mapleader or " " + +local map = vim.keymap.set +local all = { "n", "x", "s", "o" } -- Vimscript :noremap modes + +local function find_in_dir() + local dir = vim.fn.resolve(vim.fn.expand("%:p:h")) + require("telescope.builtin").find_files({ + search_dirs = { dir }, + path_display = { "shorten" }, + hidden = true, + }) +end + +local function shift_char(delta) + local pos = vim.api.nvim_win_get_cursor(0) + local line = vim.api.nvim_get_current_line() + local col = pos[2] + 1 + local char_index = vim.fn.strchars(line:sub(1, col - 1)) + local char = vim.fn.strcharpart(line, char_index, 1) + if char == "" then return end + local code = vim.fn.char2nr(char) + local replacement = vim.fn.nr2char(code + delta) + vim.api.nvim_set_current_line(line:sub(1, col - 1) .. replacement .. line:sub(col + #char)) +end + +vim.go.operatorfunc = "v:lua.JumpToLastChange" +_G.JumpToLastChange = function() + vim.cmd.normal({ "`[", bang = true }) +end + +map(all, "g.", "set operatorfunc=v:lua.JumpToLastChangeg@", { silent = true }) +map(all, "%", "v") +map(all, "\"", "s") +map(all, "", "sterm") +map(all, "", "sTERM") +map(all, "Y", "y$") +map("x", "ú", ":FormatLines") +map(all, "ú", "lua run_format_code()") +map(all, "p", "(SynStack)") +map(all, "ff", "Telescope find_files") +map(all, "", "Telescope find_files") +map(all, "", "Telescope find_files") +map(all, "", find_in_dir) +map("i", "", "(vsnip-expand)") +map(all, "^", "^zH") +map(all, "to", "Telescope oldfiles") +map(all, "ta", "Telescope autocommands") +map(all, "tbu", "Telescope buffers") +map(all, "T", "Telescope builtin") +map(all, "tcs", "Telescope colorscheme") +map(all, "tch", "Telescope command_history") +map(all, "tco", "Telescope commands") +map(all, "t/", "Telescope current_buffer_fuzzy_find") +map(all, "tcbt", "Telescope current_buffer_tags") +map(all, "td", "Telescope diagnostics") +map(all, "tf", "Telescope find_files") +map(all, "tgb", "Telescope git_branches") +map(all, "tgc", "Telescope git_commits") +map(all, "tgf", "Telescope git_files") +map(all, "tgs", "Telescope git_stash") +map(all, "tgr", "Telescope grep_string") +map(all, "thi", "Telescope highlights") +map(all, "tjl", "Telescope jumplist") +map(all, "tlg", "Telescope live_grep") +map(all, "tll", "Telescope loclist") +map(all, "t[d", "Telescope lsp_definitions") +map(all, "t[s", "Telescope lsp_document_symbols") +map(all, "t[w", "Telescope lsp_dynamic_workspace_symbols") +map(all, "t[i", "Telescope lsp_implementations") +map(all, "t[r", "Telescope lsp_incoming_calls") +map(all, "t[n", "Telescope lsp_outgoing_calls") +map(all, "t[e", "Telescope lsp_references") +map(all, "t[t", "Telescope lsp_type_definitions") +map(all, "t?", "Telescope man_pages") +map(all, "t'", "Telescope marks") +map(all, "tp", "Telescope pickers") +map(all, "tqf", "Telescope quickfix") +map(all, "tqh", "Telescope quickfixhistory") +map(all, "t\"", "Telescope registers") +map(all, "th/", "Telescope search_history") +map(all, "tz", "Telescope spell_suggest") +map(all, "ty", "Telescope symbols") +map(all, "tt", "Telescope tags") +map(all, "tst", "Telescope tagstack") +map(all, "tsit", "Telescope treesitter") +map(all, "tv", "Telescope vim_options") +map("n", "n", "set hlsearchn", { silent = true }) +map("n", "N", "set hlsearchN", { silent = true }) +map(all, "nt", "NvimTreeToggle") +map(all, "", [[:e =escape(expand('%:h'), ' \')/]]) +map(all, ".", "lua require('windownav').goto_terminal()") +map(all, "I", "lua require('windownav').goto_initvim()") +map(all, "'", "lua require('windownav').goto_lastwin()") +map("n", "", "termstartinsert") +map("n", "", "TERMstartinsert") +map("n", "", "") +map("n", "", "Telescope buffers") +map("n", "", "bnext") +map("n", "", "bprev") +map(all, "", "lua vim.diagnostic.open_float()") +map(all, "", "WarpFull") +map(all, "", "WarpGrid") +map("o", "", "vWarpGrid") +map(all, "w", "WarpWords") +map("o", "w", "vWarpWords") +map(all, "", [[/\%V]]) -- Original mapping (encoded as Ctrl-_) +map("n", "œ", "k", { remap = true }) +map("n", "ï", "j", { remap = true }) +map("o", "œ", "k", { remap = true }) +map("o", "ï", "j", { remap = true }) +map("o", "aœ", "ak", { remap = true }) +map("o", "aï", "aj", { remap = true }) +map("o", "iœ", "ik", { remap = true }) +map("o", "iï", "ij", { remap = true }) +map("x", "œ", "k", { remap = true }) +map("x", "ï", "j", { remap = true }) +map(all, "", "TSNodeUnderCursor") +map(all, "", "TSCaptureUnderCursor") +map(all, "Τ", "Inspect") +map(all, "g[r", "Telescope lsp_references path_display={\"shorten\"}") +map(all, "g[d", "Telescope lsp_definitions path_display={\"shorten\"}") +map(all, "g[i", "Telescope lsp_implementations path_display={\"shorten\"}") +map(all, "g[td", "Telescope lsp_type_definitions path_display={\"shorten\"}") +map(all, "g[ci", "Telescope lsp_incoming_calls path_display={\"shorten\"}") +map(all, "g[co", "Telescope lsp_outgoing_calls path_display={\"shorten\"}") +map(all, "g[sd", "Telescope lsp_document_symbols path_display={\"shorten\"}") +map(all, "g[sw", "Telescope lsp_workspace_symbols path_display={\"shorten\"}") +map(all, "g[sdw", "Telescope lsp_dynamic_workspace_symbols path_display={\"shorten\"}") +map(all, "[e", "lua vim.diagnostic.jump({count=-1, severity=vim.diagnostic.severity.ERROR})") +map(all, "]e", "lua vim.diagnostic.jump({count=1, severity=vim.diagnostic.severity.ERROR})") +map(all, "α", function() shift_char(1) end) +map(all, "Α", function() shift_char(-1) end) +map(all, "€", "viba)") +map(all, "", "") +map(all, "<2-X2Mouse>", "") +map(all, "<3-X2Mouse>", "") +map(all, "", "") +map(all, "<2-X1Mouse>", "") +map(all, "<3-X1Mouse>", "") +map(all, "", "") +map(all, "", "Telescope tags") +map(all, "gh", "HopCamelCase") + diff --git a/lua/config/03-commands.lua b/lua/config/03-commands.lua new file mode 100644 index 0000000..f8b0d47 --- /dev/null +++ b/lua/config/03-commands.lua @@ -0,0 +1,85 @@ +-- Commands and command-line abbreviations migrated from the original init.vim. +-- This file intentionally does not register autocommands or keymaps. + +local api = vim.api +local config_dir = vim.fn.stdpath('config') + +-- Edit the new configuration (original commands opened init.vim/local.vim). +api.nvim_create_user_command('Config', function() + vim.cmd.edit(vim.fn.fnameescape(config_dir .. '/init.lua')) +end, { desc = 'Edit Neovim init.lua' }) + +api.nvim_create_user_command('Configl', function() + vim.cmd.edit(vim.fn.fnameescape(config_dir .. '/lua/config/local/00-machine.lua')) +end, { desc = 'Edit machine-local configuration' }) + +-- :W is an easy-to-type alias for :w. Pass through arguments and !. +api.nvim_create_user_command('W', function(opts) + vim.cmd('write' .. (opts.bang and '!' or '') .. (opts.args ~= '' and ' ' .. opts.args or '')) +end, { bang = true, nargs = '*', complete = 'file', desc = 'Write buffer' }) + +-- Open a terminal in the specified directory, defaulting to the current +-- buffer's directory. The original function required a directory argument or +-- a buffer whose name was itself a directory; the default is more useful here. +_G.open_terminal_on_directory = function(dirname) + dirname = dirname or vim.fn.expand('%:p:h') + if vim.fn.isdirectory(dirname) ~= 1 then + vim.notify('Not a directory: ' .. dirname, vim.log.levels.WARN) + return + end + + local shell_cmd = string.format('cd %s && exec "$SHELL"', vim.fn.shellescape(dirname)) + vim.cmd('terminal sh -c ' .. vim.fn.shellescape(shell_cmd)) + vim.cmd.startinsert() + vim.cmd('silent! keepalt file ' .. vim.fn.fnameescape('TERM ' .. dirname)) +end + +api.nvim_create_user_command('TERM', function(opts) + _G.open_terminal_on_directory(opts.args ~= '' and vim.fn.expand(opts.args) or nil) +end, { nargs = '?', complete = 'dir', desc = 'Terminal in current file directory' }) + +-- Kept global because 01-mappings.lua invokes it with :lua run_format_code(). +_G.run_format_code = function() + local clients = vim.lsp.get_clients({ bufnr = 0, method = 'textDocument/formatting' }) + if #clients > 0 then + vim.lsp.buf.format({ async = false }) + elseif vim.fn.exists(':FormatCode') == 2 then + vim.cmd('FormatCode') + else + vim.notify('No LSP formatter or :FormatCode command available', vim.log.levels.WARN) + end +end + +-- Developer conveniences from the original config. +_G.remove_package = function(prefix) + for name in pairs(package.loaded) do + if name:sub(1, #prefix) == prefix then + package.loaded[name] = nil + end + end +end + +_G.reload_package = function(name) + _G.remove_package(name) + return require(name) +end + +-- Original command-line abbreviations. Limit them to a leading command-line +-- token, so they don't unexpectedly expand inside commands or search patterns. +local abbreviations = { + _config = config_dir, + _plugged = vim.fn.stdpath('data') .. '/plugged', -- legacy vim-plug path + _fm = vim.fn.stdpath('data') .. '/plugged/fieldmarshal.vim', -- legacy path + _home = vim.fn.stdpath('data'), + _projects = vim.fn.expand('~/Projects'), +} + +for word, replacement in pairs(abbreviations) do + vim.cmd('cnoreabbrev ' .. word .. ' (getcmdtype() ==# ":" && getcmdline() ==# "' .. word .. '") ? ' .. vim.fn.string(replacement) .. ' : "' .. word .. '"') +end + +vim.cmd([[cnoreabbrev _ (getcmdtype() ==# ':' && getcmdline() ==# '_') ? fnameescape(expand('%:h')) : '_']]) + +-- The old :UpdateInitVimHook belonged to vim-plug and is intentionally omitted. +-- Move the old InitVim/UseTerminal autocommands to a separate 04-autocmds.lua. + diff --git a/lua/config/04-autocmds.lua b/lua/config/04-autocmds.lua new file mode 100644 index 0000000..aff6d27 --- /dev/null +++ b/lua/config/04-autocmds.lua @@ -0,0 +1,67 @@ +-- Autocommands migrated from the original init.vim. +-- Plugin-specific autocommands (LSP, windownav, etc.) stay in their modules. + +local api = vim.api + +local init_group = api.nvim_create_augroup('InitVim', { clear = true }) + +-- Turn search highlighting off when leaving Insert mode; mappings for n/N +-- in 01-mappings.lua re-enable highlighting when navigating results. +api.nvim_create_autocmd('InsertLeave', { + group = init_group, + callback = function() + vim.opt.hlsearch = false + end, + desc = 'Clear search highlighting after insert mode', +}) + +-- Highlight matches whenever entering the / or ? search command line. +api.nvim_create_autocmd('CmdlineEnter', { + group = init_group, + pattern = { '/', '?' }, + callback = function() + vim.opt.hlsearch = true + end, + desc = 'Enable search highlighting on search', +}) + +vim.api.nvim_create_autocmd('TextYankPost', { + group = vim.api.nvim_create_augroup('HighlightYank', { clear = true }), + callback = function() + vim.hl.hl_op({ higroup = 'IncSearch', timeout = 100 }) + end, +}) + +vim.api.nvim_create_autocmd('TextPutPost', { + group = vim.api.nvim_create_augroup('HighlightPut', { clear = true }), + callback = function() + vim.hl.hl_op({ higroup = 'IncSearch', timeout = 100 }) + end, +}) + +api.nvim_create_autocmd({ 'FocusGained', 'BufEnter' }, { + group = init_group, + command = 'checktime', + desc = 'Check for changes to files on disk', +}) + +-- The original UseTerminal group only opened a terminal if the entered buffer +-- *itself* was named after a directory. Guard that explicitly: the new +-- open_terminal_on_directory() helper defaults to the file's parent directory, +-- which would otherwise open a terminal whenever you entered any file. +local terminal_group = api.nvim_create_augroup('UseTerminal', { clear = true }) +api.nvim_create_autocmd({ 'BufNewFile', 'BufEnter' }, { + group = terminal_group, + callback = function(args) + local dirname = api.nvim_buf_get_name(args.buf) + if dirname ~= '' and vim.fn.isdirectory(dirname) == 1 then + -- Defined by 03-commands.lua. Resolve at callback time so our + -- numbered config loader may source this file independently. + if type(_G.open_terminal_on_directory) == 'function' then + _G.open_terminal_on_directory(dirname) + end + end + end, + desc = 'Open a terminal when editing a directory buffer', +}) + diff --git a/lua/config/05-lsp.lua b/lua/config/05-lsp.lua new file mode 100644 index 0000000..64328a9 --- /dev/null +++ b/lua/config/05-lsp.lua @@ -0,0 +1,141 @@ +-- Native LSP and automatic completion for Neovim 0.12/0.13. +-- Requires nvim-lspconfig only for its server presets in runtimepath. +-- No nvim-cmp, cmp-nvim-lsp, lspkind, or vsnip required. + +vim.opt.autocomplete = true +vim.opt.complete = 'o' +vim.opt.completeopt = { 'menu', 'menuone', 'noselect', 'popup' } +vim.opt.shortmess:append('c') + +-- Keep the old LSP bindings; all are buffer-local. +local function map(buf, lhs, rhs, desc) + vim.keymap.set('n', lhs, rhs, { buffer = buf, silent = true, desc = desc }) +end + +local group = vim.api.nvim_create_augroup('UserNativeLsp', { clear = true }) + +vim.api.nvim_create_autocmd('LspAttach', { + group = group, + callback = function(args) + local bufnr = args.buf + local client = vim.lsp.get_client_by_id(args.data.client_id) + if not client then return end + + -- Completion requests are sent automatically while typing, without cmp. + -- C-n/C-p move through suggestions; C-y accepts one; C-e dismisses. + if client:supports_method('textDocument/completion') then + vim.lsp.completion.enable(true, client.id, bufnr, { autotrigger = true }) + end + + map(bufnr, 'rn', vim.lsp.buf.rename, 'LSP rename') + map(bufnr, 'ca', vim.lsp.buf.code_action, 'LSP code action') + map(bufnr, '', vim.lsp.buf.hover, 'LSP hover') + map(bufnr, 'g0', vim.lsp.buf.document_symbol, 'Document symbols') + map(bufnr, 'gW', vim.lsp.buf.workspace_symbol, 'Workspace symbols') + map(bufnr, 'gd', vim.lsp.buf.definition, 'Go to definition') + map(bufnr, 'gD', vim.lsp.buf.declaration, 'Go to declaration') + map(bufnr, 'gi', vim.lsp.buf.implementation, 'Go to implementation') + map(bufnr, 'gr', vim.lsp.buf.references, 'Find references') + map(bufnr, '', vim.lsp.buf.signature_help, 'Signature help') + map(bufnr, 'g', vim.lsp.buf.type_definition, 'Type definition') + map(bufnr, '[d', function() vim.diagnostic.jump({ count = -1 }) end, 'Previous diagnostic') + map(bufnr, ']d', function() vim.diagnostic.jump({ count = 1 }) end, 'Next diagnostic') + + vim.bo[bufnr].omnifunc = 'v:lua.vim.lsp.omnifunc' + vim.opt_local.signcolumn = 'yes' + + if client:supports_method('textDocument/documentHighlight') then + -- Per-buffer autocommands, shared across clients to avoid duplicates. + local hlgroup = vim.api.nvim_create_augroup('UserLspHighlight' .. bufnr, { clear = true }) + vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { + group = hlgroup, buffer = bufnr, callback = vim.lsp.buf.document_highlight, + }) + vim.api.nvim_create_autocmd({ 'CursorMoved', 'InsertLeave' }, { + group = hlgroup, buffer = bufnr, callback = vim.lsp.buf.clear_references, + }) + end + end, +}) + +vim.diagnostic.config({ + signs = { + text = { + [vim.diagnostic.severity.ERROR] = '✘', + [vim.diagnostic.severity.WARN] = '▲', + [vim.diagnostic.severity.INFO] = '●', + [vim.diagnostic.severity.HINT] = '◆' + } + }, + underline = true, + severity_sort = true, +}) + +-- nvim-lspconfig's modern lsp/*.lua presets supply cmd, filetypes and root detection. +-- Only list your desired servers and their overrides here. +local servers = { + bashls = { filetypes = { 'bash', 'sh' } }, + clangd = { filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' } }, + mlir = {}, + jqls = {}, + lua_ls = { + settings = { + Lua = { + runtime = { version = 'LuaJIT' }, + workspace = { checkThirdParty = false, library = { vim.env.VIMRUNTIME } }, + }, + }, + }, + ocamllsp = {}, + perlpls = {}, + rust_analyzer = {}, + verible = {}, + vimls = {}, + zls = {}, + texlab = {}, + hls = { settings = { haskell = { plugin = { semanticTokens = { globalOn = true } } } } }, + pylsp = { settings = { pylsp = { plugins = { pycodestyle = { enabled = false } } } } }, +} + +for name, overrides in pairs(servers) do + vim.lsp.config(name, overrides) + vim.lsp.enable(name) +end + +vim.keymap.set('i', '', function() + if vim.fn.pumvisible() == 1 then + return '' + end + return '' +end, { expr = true, desc = 'Accept completion or insert Tab' }) + +local fallbacks = { + Pmenu = 'NormalFloat', + PmenuSel = 'Visual', + PmenuKind = 'Type', + PmenuKindSel = 'Type', + PmenuExtra = 'Comment', + PmenuExtraSel = 'Comment', + PmenuMatch = 'Identifier', + PmenuMatchSel = 'Identifier', + PmenuBorder = 'FloatBorder', +} + +local function apply_fallbacks() + for group, target in pairs(fallbacks) do + local hl = vim.api.nvim_get_hl(0, { name = group, link = true }) + + if vim.tbl_isempty(hl) or hl.link == 'Pmenu' then + vim.api.nvim_set_hl(0, group, { link = target }) + end + end +end + +vim.api.nvim_create_autocmd('ColorScheme', { + callback = apply_fallbacks, +}) + +apply_fallbacks() + +vim.opt.pumheight = 12 +vim.opt.pummaxwidth = 70 +vim.opt.pumblend = 0 diff --git a/lua/config/99-extregs-config.lua b/lua/config/99-extregs-config.lua new file mode 100644 index 0000000..2827091 --- /dev/null +++ b/lua/config/99-extregs-config.lua @@ -0,0 +1,17 @@ +if vim.fn.has('extregs') ~= 1 or not (vim._extregs and vim._extregs.register) then + return false +end + +require('extregs').setup({ + ssh = { + host = "rahm@josher.dev", + } +}) + +vim._extregs.bind('$', 'file.stem') +vim._extregs.bind('&', 'file.backed') +vim._extregs.bind('\\', 'ssh.backed') +vim._extregs.bind('|', 'buffer') +vim._extregs.bind('τ', 'timestamp') +vim._extregs.bind('θ', 'uuid') +vim._extregs.bind(']', 'tmux') diff --git a/lua/config/99-gitsigns-config.lua b/lua/config/99-gitsigns-config.lua new file mode 100644 index 0000000..4687668 --- /dev/null +++ b/lua/config/99-gitsigns-config.lua @@ -0,0 +1,27 @@ +-- Adapted from the original init.vim; mappings are buffer-local. +local gs = require('gitsigns') +gs.setup({ + on_attach = function(bufnr) + local function map(mode, lhs, rhs) + vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, silent = true }) + end + + map({ 'o', 'x' }, 'ih', ':Gitsigns select_hunk') + map('n', ']h', function() + if vim.wo.diff then vim.cmd.normal({ ']c', bang = true }) + else gs.nav_hunk('next') end + end) + map('n', '[h', function() + if vim.wo.diff then vim.cmd.normal({ '[c', bang = true }) + else gs.nav_hunk('prev') end + end) + map('n', 'hs', gs.stage_hunk) + map('n', 'hr', gs.reset_hunk) + map('v', 'hs', function() gs.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') }) end) + map('v', 'hr', function() gs.reset_hunk({ vim.fn.line('.'), vim.fn.line('v') }) end) + map('n', 'hS', gs.stage_buffer) + map('n', 'hR', gs.reset_buffer) + map('n', 'hp', gs.preview_hunk) + map('n', 'hi', gs.preview_hunk_inline) + end, +}) diff --git a/lua/config/99-hop-config.lua b/lua/config/99-hop-config.lua new file mode 100644 index 0000000..91a15f8 --- /dev/null +++ b/lua/config/99-hop-config.lua @@ -0,0 +1,2 @@ +-- Keep Hop's defaults. Your existing Hop mappings live in 01-mappings.lua. +require('hop').setup({}) diff --git a/lua/config/99-lualine-config.lua b/lua/config/99-lualine-config.lua new file mode 100644 index 0000000..37b8821 --- /dev/null +++ b/lua/config/99-lualine-config.lua @@ -0,0 +1,32 @@ +-- Based on the original lua/lualinesetup.lua. +local function clients_lsp() + local clients = vim.lsp.get_clients({ bufnr = 0 }) + if #clients == 0 then return '' end + local names = {} + for _, client in ipairs(clients) do names[#names + 1] = client.name end + return '\u{f085} ' .. table.concat(names, ',') +end + +require('lualine').setup({ + options = { + -- The old 'meltdown' theme needs a lualine/themes/meltdown.lua file. + -- 'auto' works even if that theme is absent. + theme = 'auto', + component_separators = '', + section_separators = { left = '', right = '' }, + }, + sections = { + lualine_a = { 'mode' }, + lualine_b = { 'branch', 'diff', 'diagnostics' }, + lualine_c = { 'filename' }, + lualine_x = {}, + lualine_y = { + { clients_lsp, color = { fg = '#80a0ff' } }, + { 'encoding', color = { fg = '#80a0ff' } }, + { 'fileformat', color = { fg = '#ffb700' } }, + { 'filetype', color = { fg = '#80a0ff' } }, + 'progress', + }, + lualine_z = { 'location' }, + }, +}) diff --git a/lua/config/99-nvim-surround-config.lua b/lua/config/99-nvim-surround-config.lua new file mode 100644 index 0000000..839da9c --- /dev/null +++ b/lua/config/99-nvim-surround-config.lua @@ -0,0 +1,2 @@ +-- Keep nvim-surround defaults as in the original configuration. +require('nvim-surround').setup({}) diff --git a/lua/config/99-nvim-treesitter-config.lua b/lua/config/99-nvim-treesitter-config.lua new file mode 100644 index 0000000..57d84a9 --- /dev/null +++ b/lua/config/99-nvim-treesitter-config.lua @@ -0,0 +1,86 @@ +-- Current nvim-treesitter main branch + nvim-treesitter-textobjects main branch. +-- Requires Neovim >= 0.12, tree-sitter CLI, a C compiler, and both plugins. +-- The old nvim-treesitter.configs module no longer exists on main. + +local ts = require('nvim-treesitter') +local textobjects = require('nvim-treesitter-textobjects') + +-- Install parsers explicitly with :TSInstall or +-- :lua require('nvim-treesitter').install({ 'lua', 'vim', 'c' }) +-- Update installed parsers after plugin updates with :TSUpdate. +-- Unlike the old API, there is no auto_install/sync_install option. + +-- Enable highlighting for buffers with installed parsers, except for large +-- files. Core Neovim supplies highlighting; nvim-treesitter supplies parsers. +local max_filesize = 100 * 1024 +local group = vim.api.nvim_create_augroup('UserTreesitterHighlight', { clear = true }) +vim.api.nvim_create_autocmd('FileType', { + group = group, + callback = function(args) + local buf = args.buf + local name = vim.api.nvim_buf_get_name(buf) + if name ~= '' then + local stat = vim.uv.fs_stat(name) + if stat and stat.size > max_filesize then + return + end + end + -- Don't error for filetypes without an installed parser. + pcall(vim.treesitter.start, buf) + end, +}) + +textobjects.setup({ + select = { + lookahead = true, + selection_modes = { + ['@parameter.outer'] = 'v', + ['@function.outer'] = 'V', + ['@function.inner'] = 'V', + ['@block.inner'] = 'V', + ['@block.outer'] = 'V', + }, + -- Corrected from the original pattern '^function', which could never + -- match a capture name beginning with '@'. + include_surrounding_whitespace = function(q) + return q.query_string:match('%.inner$') == nil + and q.query_string:match('^@function') ~= nil + end, + }, + move = { set_jumps = true }, +}) + +local select = require('nvim-treesitter-textobjects.select') +local move = require('nvim-treesitter-textobjects.move') +local selections = { + am = '@function.outer', im = '@function.inner', + af = '@function.outer', ['if'] = '@function.inner', + aC = '@class.outer', iC = '@class.inner', + aa = '@parameter.outer', ia = '@parameter.inner', + iq = '@block.inner', aq = '@block.outer', + ['a;'] = '@statement.outer', ['i;'] = '@statement.inner', +} +for lhs, query in pairs(selections) do + vim.keymap.set({ 'x', 'o' }, lhs, function() + select.select_textobject(query, 'textobjects') + end, { desc = 'Tree-sitter select ' .. query }) +end + +-- The original mapping references a custom capture; it only works when +-- you provide a matching textobjects query for the current language. +for lhs, query in pairs({ + [']C'] = '@injectable_constructor.params.inner', + [']c'] = '@class.outer', +}) do + vim.keymap.set({ 'n', 'x', 'o' }, lhs, function() + move.goto_next_start(query, 'textobjects') + end) +end +for lhs, query in pairs({ + ['[C'] = '@injectable_constructor.params.inner', + ['[c'] = '@class.outer', +}) do + vim.keymap.set({ 'n', 'x', 'o' }, lhs, function() + move.goto_previous_start(query, 'textobjects') + end) +end diff --git a/lua/config/99-nvim-web-devicons-config.lua b/lua/config/99-nvim-web-devicons-config.lua new file mode 100644 index 0000000..6450096 --- /dev/null +++ b/lua/config/99-nvim-web-devicons-config.lua @@ -0,0 +1,2 @@ +-- Optional: setup isn't required for default devicons behavior. +require('nvim-web-devicons').setup({ default = true }) diff --git a/lua/config/99-telescope-config.lua b/lua/config/99-telescope-config.lua new file mode 100644 index 0000000..054c701 --- /dev/null +++ b/lua/config/99-telescope-config.lua @@ -0,0 +1,19 @@ +-- Telescope configuration migrated from init.vim. +-- Keybindings remain in 01-mappings.lua. +require('telescope').setup({ + defaults = { + title = '', + borderchars = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, + prompt_prefix = '🞂 ', + selection_caret = '🞂 ', + layout_strategy = 'horizontal', + results_title = false, + sorting_strategy = 'ascending', + layout_config = { + horizontal = { width = 0.66, height = 0.66 }, + }, + }, + pickers = { + find_files = { hidden = true }, + }, +}) diff --git a/lua/config/99-treesitter-config.lua b/lua/config/99-treesitter-config.lua new file mode 100644 index 0000000..5b81c7e --- /dev/null +++ b/lua/config/99-treesitter-config.lua @@ -0,0 +1,87 @@ +-- Current nvim-treesitter main branch + nvim-treesitter-textobjects main branch. +-- Requires Neovim >= 0.12, tree-sitter CLI, a C compiler, and both plugins. +-- The old nvim-treesitter.configs module no longer exists on main. + +local ts = require('nvim-treesitter') +local textobjects = require('nvim-treesitter-textobjects') + +-- Install parsers explicitly with :TSInstall or +-- :lua require('nvim-treesitter').install({ 'lua', 'vim', 'c' }) +-- Update installed parsers after plugin updates with :TSUpdate. +-- Unlike the old API, there is no auto_install/sync_install option. + +-- Enable highlighting for buffers with installed parsers, except for large +-- files. Core Neovim supplies highlighting; nvim-treesitter supplies parsers. +local max_filesize = 100 * 1024 +local group = vim.api.nvim_create_augroup('UserTreesitterHighlight', { clear = true }) +vim.api.nvim_create_autocmd('FileType', { + group = group, + callback = function(args) + local buf = args.buf + local name = vim.api.nvim_buf_get_name(buf) + if name ~= '' then + local stat = vim.uv.fs_stat(name) + if stat and stat.size > max_filesize then + return + end + end + -- Don't error for filetypes without an installed parser. + pcall(vim.treesitter.start, buf) + end, +}) + +textobjects.setup({ + select = { + lookahead = true, + selection_modes = { + ['@parameter.outer'] = 'v', + ['@function.outer'] = 'V', + ['@function.inner'] = 'V', + ['@block.inner'] = 'V', + ['@block.outer'] = 'V', + }, + -- Corrected from the original pattern '^function', which could never + -- match a capture name beginning with '@'. + include_surrounding_whitespace = function(q) + return q.query_string:match('%.inner$') == nil + and q.query_string:match('^@function') ~= nil + end, + }, + move = { set_jumps = true }, +}) + +local select = require('nvim-treesitter-textobjects.select') +local move = require('nvim-treesitter-textobjects.move') +local selections = { + am = '@function.outer', im = '@function.inner', + af = '@function.outer', ['if'] = '@function.inner', + aC = '@class.outer', iC = '@class.inner', + aa = '@parameter.outer', ia = '@parameter.inner', + iq = '@block.inner', aq = '@block.outer', + ['a;'] = '@statement.outer', ['i;'] = '@statement.inner', +} +for lhs, query in pairs(selections) do + vim.keymap.set({ 'x', 'o' }, lhs, function() + select.select_textobject(query, 'textobjects') + end, { desc = 'Tree-sitter select ' .. query }) +end + +-- The original mapping references a custom capture; it only works when +-- you provide a matching textobjects query for the current language. +for lhs, query in pairs({ + [']C'] = '@injectable_constructor.params.inner', + [']c'] = '@class.outer', +}) do + vim.keymap.set({ 'n', 'x', 'o' }, lhs, function() + move.goto_next_start(query, 'textobjects') + end) +end +for lhs, query in pairs({ + ['[C'] = '@injectable_constructor.params.inner', + ['[c'] = '@class.outer', +}) do + vim.keymap.set({ 'n', 'x', 'o' }, lhs, function() + move.goto_previous_start(query, 'textobjects') + end) +end + diff --git a/lua/diagnostics.lua b/lua/diagnostics.lua deleted file mode 100644 index f5f7b9d..0000000 --- a/lua/diagnostics.lua +++ /dev/null @@ -1,55 +0,0 @@ --- Diagnostics -require("trouble").setup({ - position = "bottom", -- position of the list can be: bottom, top, left, right - height = 10, -- height of the trouble list when position is top or bottom - width = 50, -- width of the list when position is left or right - icons = true, -- use devicons for filenames - mode = "workspace_diagnostics", -- "workspace_diagnostics", "document_diagnostics", "quickfix", "lsp_references", "loclist" - fold_open = "", -- icon used for open folds - fold_closed = "", -- icon used for closed folds - group = true, -- group results by file - padding = true, -- add an extra new line on top of the list - action_keys = { -- key mappings for actions in the trouble list - -- map to {} to remove a mapping, for example: - -- close = {}, - close = "q", -- close the list - cancel = "", -- cancel the preview and get back to your last window / buffer / cursor - refresh = "r", -- manually refresh - jump = { "", "" }, -- jump to the diagnostic or open / close folds - open_split = { "" }, -- open buffer in new split - open_vsplit = { "" }, -- open buffer in new vsplit - open_tab = { "" }, -- open buffer in new tab - jump_close = { "o" }, -- jump to the diagnostic and close the list - toggle_mode = "m", -- toggle between "workspace" and "document" diagnostics mode - toggle_preview = "P", -- toggle auto_preview - hover = "K", -- opens a small popup with the full multiline message - preview = "p", -- preview the diagnostic location - close_folds = { "zM", "zm" }, -- close all folds - open_folds = { "zR", "zr" }, -- open all folds - toggle_fold = { "zA", "za" }, -- toggle fold of current file - previous = "k", -- preview item - next = "j", -- next item - }, - indent_lines = true, -- add an indent guide below the fold icons - auto_open = false, -- automatically open the list when you have diagnostics - auto_close = false, -- automatically close the list when you have no diagnostics - auto_preview = true, -- automatically preview the location of the diagnostic. to close preview and go back to last window - auto_fold = false, -- automatically fold a file trouble list at creation - auto_jump = { "lsp_definitions" }, -- for the given modes, automatically jump if there is only a single result - signs = { - -- icons / text used for a diagnostic - error = "", - warning = "", - hint = "", - information = "", - other = "", - }, - use_diagnostic_signs = false, -- enabling this will use the signs defined in your lsp client -}) - --- Mappings -vim.api.nvim_set_keymap("n", "xx", "Trouble", { silent = true, noremap = true }) -vim.api.nvim_set_keymap("n", "xw", "Trouble workspace_diagnostics", { silent = true, noremap = true }) -vim.api.nvim_set_keymap("n", "xd", "Trouble document_diagnostics", { silent = true, noremap = true }) -vim.api.nvim_set_keymap("n", "xl", "Trouble loclist", { silent = true, noremap = true }) -vim.api.nvim_set_keymap("n", "xq", "Trouble quickfix", { silent = true, noremap = true }) diff --git a/lua/lsp.lua b/lua/lsp.lua deleted file mode 100644 index 1d2cb37..0000000 --- a/lua/lsp.lua +++ /dev/null @@ -1,308 +0,0 @@ --- my_lsp.lua -local ok_cmp, cmp = pcall(require, "cmp") -local ok_kind, lspkind = pcall(require, "lspkind") -local ok_cmp_caps, cmp_caps = pcall(require, "cmp_nvim_lsp") -local has_lspconfig, lspconfig = pcall(require, "lspconfig") - --- ── completion (cmp) ─────────────────────────────────────────────────────────── -vim.opt.completeopt = { "menu", "menuone", "noselect" } -vim.opt.shortmess:append("c") - -if ok_kind then - lspkind.init({ - symbol_map = { - Text = "󰉿", - Method = "󰊕", - Function = "λ", - Constructor = "", - Field = "󰜢", - Variable = "󰀫", - Class = "󰠱", - Interface = "", - Module = "󰆧", - Property = "󰜢", - Unit = "󰑭", - Value = "󰎠", - Enum = "", - Keyword = "󰌋", - Snippet = "", - Color = "󰏘", - File = "󰈙", - Reference = "󰈇", - Folder = "󰉋", - EnumMember = "", - Constant = "󰏿", - Struct = "󰙅", - Event = "", - Operator = "󰆕", - TypeParameter = "τ", - }, - }) -end - -local function has_words_before() - local unpack = unpack or table.unpack - local line, col = unpack(vim.api.nvim_win_get_cursor(0)) - if col == 0 then return false end - local l = vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1] or "" - return l:sub(col, col):match("%s") == nil -end - -local function feedkey(key, mode) - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) -end - -if ok_cmp then - cmp.setup({ - mapping = { - [""] = cmp.mapping.scroll_docs(-4, { "i", "s" }), - [""] = cmp.mapping.scroll_docs(4, { "i", "s" }), - [""] = cmp.mapping.close(), - [""] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }), - [""] = cmp.mapping(function() - cmp.select_next_item() - pcall(vim.fn["vsnip#deactivate"]) - end, { "i", "s" }), - [""] = cmp.mapping(function() - cmp.select_prev_item() - pcall(vim.fn["vsnip#deactivate"]) - end, { "i", "s" }), - [""] = cmp.mapping(function(fallback) - if vim.fn == 1 then - feedkey("(vsnip-expand-or-jump)", "") - elseif cmp.visible() then - cmp.mapping.confirm({ select = true })() - elseif has_words_before() then - cmp.complete() - else - fallback() - end - end, { "i", "s" }), - [""] = cmp.mapping(function() - if cmp.visible() then - cmp.select_prev_item() - elseif vim.fn["vsnip#jumpable"](-1) == 1 then - feedkey("(vsnip-jump-prev)", "") - end - end, { "i", "s" }), - }, - formatting = ok_kind and { - format = lspkind.cmp_format({ - mode = "symbol_text", - maxwidth = 50, - ellipsis_char = "...", - show_labelDetails = true, - before = function(_, item) - local function split_args(s) - if #s == 0 or not s:find("%(") then return s, "" end - local i = s:find("%(") - 1 - return s:sub(1, i), s:sub(i + 1) - end - local verbosity = (vim.bo.filetype == "java") and 2 or 1 - if vim.bo.filetype == "java" and item.kind == "Method" then - local name, args = split_args(item.abbr) - item.abbr = name - item.menu = (args or "") .. (item.menu or "") - end - item.abbr = item.abbr:sub(1, 20 * verbosity) - item.menu = (item.menu or ""):sub(1, 20 * verbosity) - return item - end, - }), - } or nil, - sources = { - { name = "nvim_lsp" }, - { name = "path" }, - { name = "vim_vsnip" }, - { name = "buffer", keyword_length = 5 }, - }, - sorting = { comparators = {} }, -- let LSP decide - snippet = { - expand = function(args) vim.fn["vsnip#anonymous"](args.body) end, - }, - experimental = { native_menu = false, ghost_text = true }, - }) - - -- zsh source on zsh buffers - vim.api.nvim_create_augroup("CmpZsh", { clear = true }) - vim.api.nvim_create_autocmd("FileType", { - group = "CmpZsh", - pattern = "zsh", - callback = function() - require("cmp").setup.buffer { sources = { { name = "zsh" } } } - end, - }) -end - --- ── LSP shared on_attach & capabilities ─────────────────────────────────────── -local M = {} - -M.on_attach = function(client, bufnr) - -- omnifunc, tagfunc, formatexpr - vim.bo[bufnr].omnifunc = "v:lua.vim.lsp.omnifunc" - if vim.lsp.formatexpr then vim.bo[bufnr].formatexpr = "v:lua.vim.lsp.formatexpr" end - if vim.lsp.tagfunc then vim.bo[bufnr].tagfunc = "v:lua.vim.lsp.tagfunc" end - - local map = function(mode, lhs, rhs) - vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, silent = true, noremap = true }) - end - map("n", "rn", vim.lsp.buf.rename) - map("n", "ca", vim.lsp.buf.code_action) - map("n", "", vim.lsp.buf.hover) - map("n", "g0", vim.lsp.buf.document_symbol) - map("n", "gW", vim.lsp.buf.workspace_symbol) - map("n", "gd", vim.lsp.buf.definition) - map("n", "gD", vim.lsp.buf.declaration) - map("n", "gi", vim.lsp.buf.implementation) - map("n", "gr", vim.lsp.buf.references) - map("n", "", vim.lsp.buf.signature_help) - map("n", "g", vim.lsp.buf.type_definition) - map("n", "[d", vim.diagnostic.goto_prev) - map("n", "]d", vim.diagnostic.goto_next) - - -- document highlight (only if server supports it) - if client.server_capabilities.documentHighlightProvider then - local gid = vim.api.nvim_create_augroup("LspDocumentHighlight" .. bufnr, { clear = true }) - vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { - group = gid, buffer = bufnr, callback = vim.lsp.buf.document_highlight, - }) - vim.api.nvim_create_autocmd("CursorMoved", { - group = gid, buffer = bufnr, callback = vim.lsp.buf.clear_references, - }) - end - - vim.opt_local.signcolumn = "yes" -end - -local capabilities = vim.lsp.protocol.make_client_capabilities() -if ok_cmp_caps then - capabilities = cmp_caps.default_capabilities(capabilities) -end - --- nice diagnostics styling -vim.cmd [[hi DiagnosticUnderlineError gui=undercurl guisp=salmon]] -vim.cmd [[hi DiagnosticUnderlineWarn gui=undercurl guisp=gold]] -for type, icon in pairs({ Error = " ", Warn = " ", Hint = " ", Info = " " }) do - local hl = "DiagnosticSign" .. type - vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" }) -end - --- ── Servers (one table to rule them all) ────────────────────────────────────── -local servers = { - bashls = { filetypes = { "bash", "sh" } }, - clangd = { filetypes = { "c", "cpp", "objc", "objcpp", "cuda" } }, - mlir = { filetypes = { "mlir" } }, - jqls = { filetypes = { "jq" } }, - lua_ls = { - filetypes = { "lua" }, - settings = { - Lua = { - runtime = { - version = "LuaJIT", - }, - workspace = { - checkThirdParty = false, - library = { - vim.env.VIMRUNTIME, - }, - } - } - } - }, - ocamllsp = {}, - perlpls = {}, - rust_analyzer = { - settings = { - semantic_tokens = { - modifiers = { - disabled = { "dead" }, - }, - }, - } - }, - verible = {}, - vimls = {}, - zls = {}, - texlab = {}, - hls = { - settings = { haskell = { plugin = { semanticTokens = { globalOn = true } } } } - }, - pylsp = { - settings = { pylsp = { plugins = { pycodestyle = { enabled = false } } } } - }, -} - --- Fallback command guesses for native start (used only if lspconfig is absent) -local default_cmd = { - bashls = { "bash-language-server", "start" }, - clangd = { "clangd" }, - mlir = { "mlir-lsp-server" }, - jqls = { "jq-lsp" }, - lua_ls = { "lua-language-server" }, - ocamllsp = { "ocamllsp" }, - perlpls = { "perlpls" }, - rust_analyzer = { "rust-analyzer" }, - verible = { "verible-verilog-ls" }, - vimls = { "vim-language-server", "--stdio" }, - zls = { "zls" }, - texlab = { "texlab" }, - hls = { "haskell-language-server-wrapper", "--lsp" }, - pylsp = { "pylsp" }, -} - --- ── Setup: prefer native vim.lsp.config, fallback to lspconfig ─────────────── -local has_native = (vim.lsp and vim.lsp.config and vim.lsp.start) - -local function setup_with_native(name, opts) - -- Build a vim.lsp.config() object and start per-filetype - local cfg = vim.lsp.config(name, { - name = name, - cmd = opts.cmd or default_cmd[name], - root_dir = opts.root_dir, -- optional; can rely on server defaults - filetypes = opts.filetypes, - settings = opts.settings, - capabilities = capabilities, - on_attach = M.on_attach, - }) - - vim.lsp.enable(name); - - -- if cfg.cmd == nil then - -- vim.notify(("LSP %s: no cmd found; skipping native start."):format(name), vim.log.levels.WARN) - -- return - -- end - - -- Start when a matching buffer opens - -- local pat = opts.filetypes or "*" - -- vim.api.nvim_create_autocmd("FileType", { - -- pattern = pat, - -- callback = function(args) - -- -- Only start if ft matches the server's filetypes (or none specified) - -- if not cfg.filetypes or vim.tbl_contains(cfg.filetypes, vim.bo[args.buf].filetype) then - -- vim.lsp.start(cfg, { bufnr = args.buf }) - -- end - -- end, - -- }) -end - -local function setup_with_lspconfig(name, opts) - if not has_lspconfig then - vim.notify(("lspconfig not found; cannot setup %s"):format(name), vim.log.levels.WARN) - return - end - local final = vim.tbl_deep_extend("force", { - capabilities = capabilities, - on_attach = M.on_attach, - }, opts or {}) - lspconfig[name].setup(final) -end - -for name, opts in pairs(servers) do - if has_native then - setup_with_native(name, opts) - else - setup_with_lspconfig(name, opts) - end -end - -return M diff --git a/lua/lualinesetup.lua b/lua/lualinesetup.lua deleted file mode 100644 index b324f39..0000000 --- a/lua/lualinesetup.lua +++ /dev/null @@ -1,47 +0,0 @@ -local vim = assert(vim) - --- LSP clients attached to buffer -local clients_lsp = function() - local bufnr = vim.api.nvim_get_current_buf() - - local clients = vim.lsp.buf_get_clients(bufnr) - if next(clients) == nil then - return '' - end - - local c = {} - for _, client in pairs(clients) do - table.insert(c, client.name) - end - return '\u{f085} ' .. table.concat(c, ',') -end - -local config = { - options = { - theme = 'meltdown', - component_separators = '', -- '┃' - section_separators = {left = '', right = ''}, - }, - sections = { - lualine_a = { 'mode' }, - lualine_b = { 'branch', 'diff', 'diagnostics' }, - lualine_c = { 'filename' }, - - -- right - lualine_x = { - -- { clients_lsp, color = { fg = '#80a0ff' } }, - -- { 'encoding', color = { fg = '#80a0ff' } }, - -- { 'fileformat', color = { fg = '#ffb700' } }, - -- { 'filetype', color = { fg = '#80a0ff' } }, - }, - lualine_y = { - { clients_lsp, color = { fg = '#80a0ff' } }, - { 'encoding', color = { fg = '#80a0ff' } }, - { 'fileformat', color = { fg = '#ffb700' } }, - { 'filetype', color = { fg = '#80a0ff' } }, - 'progress' }, - lualine_z = { 'location' } - }, -} - -require("lualine").setup(config) diff --git a/lua/tabby.lua b/lua/tabby.lua deleted file mode 100644 index c2a1475..0000000 --- a/lua/tabby.lua +++ /dev/null @@ -1,32 +0,0 @@ -local theme = { - fill = 'TabLineFill', - -- Also you can do this: fill = { fg='#f2e9de', bg='#907aa9', style='italic' } - head = 'TabLine', - current_tab = 'TabLineSel', - tab = 'TabLine', - win = 'TabLine', - tail = 'TabLineTail', - close_sel = 'TabLineCloseSel', - close = 'TabLineClose', -} -require('tabby.tabline').use_preset('active_wins_at_tail', { - theme = { - fill = 'TabLineFill', -- tabline background - head = 'TabLine', -- head element highlight - current_tab = 'TabLineSel', -- current tab label highlight - tab = 'TabLine', -- other tab label highlight - win = 'TabLine', -- window highlight - tail = 'TabLine', -- tail element highlight - }, - nerdfont = true, -- whether use nerdfont - lualine_theme = nil, -- lualine theme name - -- tab_name = { - -- name_fallback = function(tabid) - -- return tabid - -- end, - -- }, - buf_name = { - mode = 'tail', - }, - -}) diff --git a/lua/treesitter-textobjects-setup.lua b/lua/treesitter-textobjects-setup.lua deleted file mode 100644 index 4296857..0000000 --- a/lua/treesitter-textobjects-setup.lua +++ /dev/null @@ -1,52 +0,0 @@ -require'nvim-treesitter.configs'.setup { - textobjects = { - select = { - enable = true, - - -- Automatically jump forward to textobj, similar to targets.vim - lookahead = true, - - keymaps = { - -- You can use the capture groups defined in textobjects.scm - ["am"] = "@function.outer", - ["im"] = "@function.inner", - ["af"] = "@function.outer", - ["if"] = "@function.inner", - ["aC"] = "@class.outer", - ["aa"] = "@parameter.outer", - ["ia"] = "@parameter.inner", - ["iq"] = "@block.inner", - ["aq"] = "@block.outer", - -- You can optionally set descriptions to the mappings (used in the desc parameter of - -- nvim_buf_set_keymap) which plugins like which-key display - ["iC"] = { query = "@class.inner", desc = "Select inner part of a class region" }, - }, - -- You can choose the select mode (default is charwise 'v') - -- - -- Can also be a function which gets passed a table with the keys - -- * query_string: eg '@function.inner' - -- * method: eg 'v' or 'o' - -- and should return the mode ('v', 'V', or '') or a table - -- mapping query_strings to modes. - selection_modes = { - ['@parameter.outer'] = 'v', -- charwise - ['@function.outer'] = 'V', -- linewise - ['@function.inner'] = 'V', -- linewise - }, - -- If you set this to `true` (default is `false`) then any textobject is - -- extended to include preceding or succeeding whitespace. Succeeding - -- whitespace has priority in order to act similarly to eg the built-in - -- `ap`. - -- - -- Can also be a function which gets passed a table with the keys - -- * query_string: eg '@function.inner' - -- * selection_mode: eg 'v' - -- and should return true of false - include_surrounding_whitespace = function (q) - return string.match(q.query_string, '.inner$') == nil and - string.match(q.query_string, '^function') - end, - }, - }, -} - diff --git a/lua/treesitter.lua b/lua/treesitter.lua deleted file mode 100644 index e10e7c6..0000000 --- a/lua/treesitter.lua +++ /dev/null @@ -1,45 +0,0 @@ -require'nvim-treesitter.configs'.setup { - -- A list of parser names, or "all" (the four listed parsers should always be installed) - -- ensure_installed = { "all" }, - - -- Install parsers synchronously (only applied to `ensure_installed`) - sync_install = false, - - -- Automatically install missing parsers when entering buffer - -- Recommendation: set to false if you don't have `tree-sitter` CLI installed locally - auto_install = true, - - -- List of parsers to ignore installing (for "all") - ignore_install = { "javascript" }, - - ---- If you need to change the installation directory of the parsers (see -> Advanced Setup) - -- parser_install_dir = "/some/path/to/store/parsers", -- Remember to run vim.opt.runtimepath:append("/some/path/to/store/parsers")! - - highlight = { - -- `false` will disable the whole extension - enable = true, - - -- NOTE: these are the names of the parsers and not the filetype. (for example if you want to - -- disable highlighting for the `tex` filetype, you need to include `latex` in this list as this is - -- the name of the parser) - -- list of language that will be disabled - -- disable = { "c", "rust" }, - -- Or use a function for more flexibility, e.g. to disable slow treesitter highlight for large files - disable = function(lang, buf) - -- if lang == "vim" or lang == "lua" then - -- return true - -- end - local max_filesize = 100 * 1024 -- 100 KB - local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) - if ok and stats and stats.size > max_filesize then - return true - end - end, - - -- Setting this to true will run `:h syntax` and tree-sitter at the same time. - -- Set this to `true` if you depend on 'syntax' being enabled (like for indentation). - -- Using this option may slow down your editor, and you may see some duplicate highlights. - -- Instead of true it can also be a list of languages - additional_vim_regex_highlighting = false, - }, -} diff --git a/lua/windownav.lua b/lua/windownav.lua deleted file mode 100644 index 9ac83e3..0000000 --- a/lua/windownav.lua +++ /dev/null @@ -1,76 +0,0 @@ -local vim = assert(vim) -local augroup = vim.api.nvim_create_augroup -- Create/get autocommand group -local autocmd = vim.api.nvim_create_autocmd -- Create autocommand - -M = {} - -local function get_buffers(options) - local buffers = {} - local len = 0 - local options_listed = options.listed - local vim_fn = vim.fn - local buflisted = vim_fn.buflisted - - for buffer = 1, vim_fn.bufnr('$') do - if not options_listed or buflisted(buffer) ~= 1 then - len = len + 1 - buffers[len] = buffer - end - end - - return buffers -end - -function M.goto_terminal() - for _, buf in pairs(vim.fn.tabpagebuflist()) do - if string.match(vim.fn.bufname(buf), "^term://.*") then - local win = vim.fn.bufwinnr(buf) - vim.api.nvim_exec(win .. "wincmd w", 0) - return - end - end -end - -local function contains(needle, haystack) - for _, h in pairs(haystack) do - if h == needle then - return true - end - end - return false -end - -local function navigate_to(buffer) - local wid = vim.fn.win_findbuf(buffer) - if #wid > 0 then - vim.fn.win_gotoid(wid[1]) - end -end - -function M.goto_lastwin() - if M.lastwin then - vim.fn.win_gotoid(M.lastwin) - end -end - -function M.goto_initvim() - local buffers = get_buffers({}) - for _, buf in pairs(buffers) do - if string.match(vim.fn.bufname(buf), "nvim/init.vim$") then - navigate_to(buf) - return - end - end - - vim.api.nvim_exec("tabedit ~/.config/nvim/init.vim", 0) -end - -augroup('WindowNav', { clear = true }) -autocmd('WinLeave', { - group = 'WindowNav', - callback = function () - M.lastwin = vim.fn.win_getid() - end -}) - -return M -- cgit