From d320577772588ae87ce4b3e3e79cda21f48c876e Mon Sep 17 00:00:00 2001 From: Squibid Date: Sun, 10 Aug 2025 13:10:05 -0400 Subject: [PATCH] I'm not gonna bother --- after/ftplugin/java.lua | 15 ++--- after/ftplugin/openscad.vim | 3 + init.lua | 6 +- lua/conf/binds.lua | 26 ++++++-- lua/conf/opts.lua | 8 ++- lua/conf/plugins/lsp.lua | 28 +------- lua/conf/plugins/luasnip.lua | 4 ++ lua/conf/plugins/telescope.lua | 2 + lua/conf/plugins/treesitter.lua | 2 +- lua/core/color.lua | 18 ----- lua/core/init.lua | 39 +++++++++++ lua/core/lsp/binds.lua | 5 +- lua/core/lsp/completion.lua | 38 +++++++---- lua/core/lsp/init.lua | 7 +- lua/core/lsp/servers.lua | 11 +++ lua/core/lsp/wtf.lua | 29 ++++++++ lua/core/misc.lua | 114 ++------------------------------ lua/snippets/lua.lua | 19 ++++++ 18 files changed, 182 insertions(+), 192 deletions(-) create mode 100644 after/ftplugin/openscad.vim create mode 100644 lua/core/lsp/servers.lua create mode 100644 lua/core/lsp/wtf.lua create mode 100644 lua/snippets/lua.lua diff --git a/after/ftplugin/java.lua b/after/ftplugin/java.lua index 272a593..82540d8 100644 --- a/after/ftplugin/java.lua +++ b/after/ftplugin/java.lua @@ -12,8 +12,8 @@ local java_dap_install = core.mason.get_pkg_path("java-debug-adapter") -- make sure to check if things with 💀 need updating local config = { cmd = { - "/usr/lib/jvm/openjdk21/bin/java", -- 💀 - "-jar", -- 💀 + "java", -- 💀 + "-jar", vim.fn.glob(vim.fs.joinpath(jdtls_install, "plugins/org.eclipse.equinox.launcher_*.jar")), "-configuration", jdtls_install.."config_linux", "-data", vim.fn.stdpath("cache").."/nvim-jdtls", @@ -71,12 +71,6 @@ local config = { dap.adapters.java = nil -- remove any old java adapters jdtls.setup_dap({ hotcodereplace = "auto" }) end, - - -- don't print out status messages - handlers = { - ["language/status"] = function() end - }, - init_options = { bundles = { vim.fs.joinpath(java_dap_install, @@ -84,6 +78,10 @@ local config = { true) ) } + }, + -- don't print out status messages + handlers = { + ["language/status"] = function() end } } @@ -157,7 +155,6 @@ local function version_check() return true end - -- start the jdtls with dap! if not version_check() then return diff --git a/after/ftplugin/openscad.vim b/after/ftplugin/openscad.vim new file mode 100644 index 0000000..5bd35bf --- /dev/null +++ b/after/ftplugin/openscad.vim @@ -0,0 +1,3 @@ +" will remove when my pr gets into neovim +" https://github.com/vim/vim/pull/17902 +setl commentstring=//\ %s diff --git a/init.lua b/init.lua index 0840136..85fd7cb 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,3 @@ --- TODO: after switching to dep with lazy loading check out vim-startuptime --- again - -- load core utilities _G.core = require("core") @@ -10,6 +7,9 @@ vim.loader.enable() -- load user config require("conf") +-- setup lsp stuff +core.lsp.setup() + -- bootstrap plugin manager local path = vim.fn.stdpath("data").."/site/pack/deps/opt/dep" if not vim.uv.fs_stat(path) then diff --git a/lua/conf/binds.lua b/lua/conf/binds.lua index dd4a88b..3c47c11 100644 --- a/lua/conf/binds.lua +++ b/lua/conf/binds.lua @@ -1,4 +1,7 @@ local map, lz = core.misc.map, core.misc.lz + +--- feed keys as userinput +---@param keys string keys local function feedkeys(keys) vim.api.nvim_feedkeys( vim.api.nvim_replace_termcodes(keys, true, false, true), @@ -9,7 +12,8 @@ end vim.g.mapleader = " " -- set leader key map("x", "p", [["_dP]], { desc = "Greatest remap of all time." }) -map("n", "", ":nohlsearch:echo", { desc = "Clear search." }) +map("n", "", "noh:ec", { desc = "Clear search." }) +map("n", "a", lz "e #zz", { desc = "swap to alt file" }) -- the cursor STAYS IN THE MIDDLE map("n", "", lz "mzJ`zdelm z") -- when combining lines @@ -17,6 +21,8 @@ map("n", "n", lz "nzzzv") -- when searching map("n", "N", lz "Nzzzv") map("n", "", lz "zz") -- half page jumping map("n", "", lz "zz") +map("n", "", lz "zz") -- jump history +map("n", "", lz "zz") -- trigger completion menu -- (stolen from https://gist.github.com/MariaSolOs/2e44a86f569323c478e5a078d0cf98cc) @@ -40,10 +46,20 @@ map("i", "", "", { desc = "Trigger spell completion" }) map("n", "", lz "se spellease nospell", { desc = "Trigger spell completion" }) -- quickfix -map("n", "", "cnext") -map("n", "", "cprev") -map("n", "", "cclose") -map("n", "", "cope") +map("n", "", "cnext", { desc = "qf next" }) +map("n", "", "cprev", { desc = "qf prev" }) +map("n", "", "cclose", { desc = "qf close" }) +map("n", "", "cope", { desc = "qf open" }) -- man pages map("n", "", "Man") + +-- okay this is gonna sound crazy, but I like emacs binds for editing when I'm +-- stuck without modal editing like in command mode. +map("c", "", function() feedkeys("") end) +map("c", "", function() feedkeys("") end) +map("c", "", function() feedkeys("") end) + +-- execute line/block +map("n", "x", ":.lua") +map("x", "x", ":lua") diff --git a/lua/conf/opts.lua b/lua/conf/opts.lua index b35ca4c..ea6e4e9 100644 --- a/lua/conf/opts.lua +++ b/lua/conf/opts.lua @@ -29,6 +29,9 @@ vim.o.udf = true -- searching vim.o.ic = true +-- make windows look nice +vim.o.winborder = "solid" + -- wild menus vim.o.ph = 20 vim.o.wic = true @@ -37,9 +40,8 @@ vim.o.wop = "fuzzy,pum,tagfile" -- completion vim.o.cot = "menu,menuone,noinsert,fuzzy,popup" vim.o.cia = "kind,abbr,menu" - --- make windows look nice -vim.o.winborder = "solid" +-- waiting for https://github.com/neovim/neovim/pull/25541 to land +-- vim.o.completepopup = "border:"..vim.o.winborder do -- statusline ---@return string out formatted status line diff --git a/lua/conf/plugins/lsp.lua b/lua/conf/plugins/lsp.lua index 630d7a6..c250047 100644 --- a/lua/conf/plugins/lsp.lua +++ b/lua/conf/plugins/lsp.lua @@ -1,32 +1,8 @@ local nonels_augroup = core.misc.augroup("nullls formatting") return { - { "neovim/nvim-lspconfig", - reqs = { - "mason-org/mason.nvim", - "mason-org/mason-lspconfig.nvim" - }, - load = function() - core.lsp.setup() - require("mason-lspconfig").setup { - ensure_added = { - "clangd", - "mesonlsp", - - "bashls", - "jdtls", - "lua_ls", - - -- python - "basedpyright", - "black", - "debugpy" - } - } - end - }, - { "mason-org/mason.nvim", + reqs = "neovim/nvim-lspconfig", load = function() require("mason").setup { ui = { @@ -38,6 +14,8 @@ return { } } } + + core.mason.ensure_installed() end }, diff --git a/lua/conf/plugins/luasnip.lua b/lua/conf/plugins/luasnip.lua index f66a105..56491c7 100644 --- a/lua/conf/plugins/luasnip.lua +++ b/lua/conf/plugins/luasnip.lua @@ -10,9 +10,13 @@ return { "L3MON4D3/LuaSnip", load:keymap({"i", "s"}, "") load:keymap({"i", "s"}, "") load:keymap({"i", "s"}, "") + load:auto("InsertEnter") end, load = function() local ls = require("luasnip") + + -- replace the builtin snippet handler with luasnip so I get all my fancy + -- stuff vim.snippet.expand = ls.lsp_expand ls.config.setup { diff --git a/lua/conf/plugins/telescope.lua b/lua/conf/plugins/telescope.lua index 4d732bc..75925e0 100644 --- a/lua/conf/plugins/telescope.lua +++ b/lua/conf/plugins/telescope.lua @@ -151,5 +151,7 @@ return { "nvim-telescope/telescope.nvim", cwd = vim.fs.joinpath(vim.fn.stdpath("data"), "site/pack/deps/opt") } end, { desc = "find files in plugin directory" }) + + map("n", "tt", "Telescope") end } diff --git a/lua/conf/plugins/treesitter.lua b/lua/conf/plugins/treesitter.lua index 335c914..7043f84 100644 --- a/lua/conf/plugins/treesitter.lua +++ b/lua/conf/plugins/treesitter.lua @@ -71,7 +71,7 @@ return { { "windwp/nvim-ts-autotag", reqs = "nvim-treesitter/nvim-treesitter", - disable = not vim.fn.has("nvim-0.9.5"), + disable = true, -- lazy = dep_short.auto({ "BufReadPre", "BufNewFile" }), load = function() require("nvim-ts-autotag").setup {} diff --git a/lua/core/color.lua b/lua/core/color.lua index 5d846ce..c5a0251 100644 --- a/lua/core/color.lua +++ b/lua/core/color.lua @@ -29,24 +29,6 @@ function M.copyhl(hlgroup, namespace) return res end ---- Taken from https://github.com/rachartier/tiny-inline-diagnostic.nvim ----@param hex string ----@return table rgb -function M.hex_to_rgb(hex) - if hex == nil or hex == 'None' then - return {0, 0, 0} - end - - hex = hex:gsub('#', '') - hex = string.lower(hex) - - return { - tonumber(hex:sub(1, 2), 16), - tonumber(hex:sub(3, 4), 16), - tonumber(hex:sub(5, 6), 16) - } -end - -- Source: 'runtime/lua/vim/_defaults.lua' in Neovim source local function parse_osc11(x) local r, g, b = x:match('^\027%]11;rgb:(%x+)/(%x+)/(%x+)$') diff --git a/lua/core/init.lua b/lua/core/init.lua index 2f47744..5325cab 100644 --- a/lua/core/init.lua +++ b/lua/core/init.lua @@ -35,6 +35,45 @@ local M = { } M.mason = { + packages = { + formatters = { "black" }, + daps = { "debugpy" }, + lsps = { + "clangd", + "mesonlsp", + "bashls", + "lua_ls", + "jdtls", + "basedpyright" + } + }, + + --- Attempt to install all desired packages. This only really works on first + --- install as mason seems to not remove the paths of the things we uninstall + --- and instead just removes the code, leaving behind it's metadata. + ensure_installed = function() + local to_install = {} + + for _, type in pairs(M.mason.packages) do + for _, pkg in ipairs(type) do + -- HACK: some servers don't have the same name in mason as they do in + -- the vim lsp, we use the vim lsp names, and therefore need to + -- convert them in here when they're incorrect for mason + if pkg == "bashls" then pkg = "bash-language-server" + elseif pkg == "lua_ls" then pkg = "lua-language-server" + end + + if vim.fn.isdirectory(M.mason.get_pkg_path(pkg)) == 0 then + table.insert(to_install, pkg) + end + end + end + + if #to_install > 0 then + vim.cmd.MasonInstall(to_install) + end + end, + --- Gets a path to a package in the Mason registry. --- Prefer this to `get_package`, since the package might not always be --- available yet and trigger errors. diff --git a/lua/core/lsp/binds.lua b/lua/core/lsp/binds.lua index 2cdc6ca..831f4ab 100644 --- a/lua/core/lsp/binds.lua +++ b/lua/core/lsp/binds.lua @@ -48,8 +48,8 @@ auto("LspAttach", { map("n", "gy", function() vim.lsp.buf.type_definition(list_opts) end, opts) map("n", "gr", function() vim.lsp.buf.references(nil, list_opts) end, opts) map("n", "", vim.lsp.buf.signature_help, opts) - map("n", { "r", "" }, vim.lsp.buf.rename, opts) - map("n", { "gA", "" }, vim.lsp.buf.code_action, opts) + map("n", "r", vim.lsp.buf.rename, opts) + map("n", "gA", vim.lsp.buf.code_action, opts) -- Diagnostics map("n", "[d", function() @@ -58,6 +58,7 @@ auto("LspAttach", { map("n", "]d", function() vim.diagnostic.jump({ count = 1 }) end, opts) + map("n", "gb", vim.diagnostic.setqflist, opts) -- formatting map("n", "c", vim.lsp.buf.format) diff --git a/lua/core/lsp/completion.lua b/lua/core/lsp/completion.lua index 22eaed0..cc4db9a 100644 --- a/lua/core/lsp/completion.lua +++ b/lua/core/lsp/completion.lua @@ -1,4 +1,9 @@ --- stolen from https://github.com/glepnir/nvim with some modifications by me +-- My neovim autocomplete setup. +-- partially stolen from https://github.com/glepnir/nvim +-- +-- To make this work nicely you're gonna want a solid snippet setup, for me this +-- is luasnip. If you too would like to use luasnip just set vim.snippet.expand +-- to luasnip.lsp_expand --- add char to list of triggerable chars ---@param list table list of chars @@ -16,14 +21,15 @@ local function add_to_client(list, char) end end +-- make sure we can add autos local misc = require("core.misc") local auto = misc.auto +local completion_group = misc.augroup("lsp.completion") -local competion_group = misc.augroup("lsp.completion") - --- configure the lsp completion menu +-- Configure the lsp completion menu. In addition to setting up lsp completion +-- this also styles it to look nice. auto("LspAttach", { - group = competion_group, + group = completion_group, callback = function(ctx) local client = vim.lsp.get_client_by_id(ctx.data.client_id) if not client or not client:supports_method("textDocument/completion") then @@ -43,6 +49,9 @@ auto("LspAttach", { convert = function(item) local kind = vim.lsp.protocol.CompletionItemKind[item.kind] or 'u' return { + -- in the future if we ever get the ability to highlight specific + -- entries in the pummenu I'd like to add treesitter highlighting to + -- the entries abbr = item.label:gsub('%b()', ''), kind = kind:sub(1, 1):lower(), menu = '' @@ -54,7 +63,7 @@ auto("LspAttach", { -- attempt to style the completion documentation popup auto("CompleteChanged", { - group = competion_group, + group = completion_group, callback = function() local info = vim.fn.complete_info({ "selected" }) if info.preview_bufnr and vim.bo[info.preview_bufnr].filetype == "" then @@ -69,9 +78,10 @@ auto("CompleteChanged", { -- only supports function calls. -- -- there's a very good chance this will give us problems for languages who do --- not follow the c-style function call style +-- not follow the c-style function call style. I've only gotten this working in +-- lua thus far. auto("CompleteDonePre", { - group = competion_group, + group = completion_group, callback = function() local item = vim.tbl_get( vim.v.completed_item, @@ -138,6 +148,7 @@ auto("CompleteDonePre", { n_complete_item.user_data.nvim.lsp.completion_item.insertText = text n_complete_item.user_data.nvim.lsp.completion_item.insertTextFormat = 2 + n_complete_item.user_data.nvim.lsp.completion_item.kind = 3 vim.v.completed_item = n_complete_item end end @@ -146,12 +157,12 @@ auto("CompleteDonePre", { -- show the signature help when inside a function call auto("CompleteDone", { - group = competion_group, + group = completion_group, callback = function(ctx) -- make sure there's an lsp client, and make sure the lsp client supports -- textDocument/signatureHelp - local client = vim.lsp.get_clients({ bufnr = ctx.buf })[0] - if not client or not client[0]:supports_method("textDocument/signatureHelp") then + local client = vim.lsp.get_clients({ bufnr = ctx.buf })[1] + if not client or not client:supports_method("textDocument/signatureHelp") then return end @@ -169,9 +180,8 @@ auto("CompleteDone", { -- show signature help when the completion is a function if item.kind == 3 and (item.textEdit ~= nil or item.insertText ~= nil) then - vim.schedule(function() - vim.lsp.buf.signature_help() - end) + -- for some reason calling vim.schedule didn't work for me + vim.defer_fn(vim.lsp.buf.signature_help, 100) end end, desc = "Auto show signature help when completion is done" diff --git a/lua/core/lsp/init.lua b/lua/core/lsp/init.lua index 5e0b1e9..15ef9c6 100644 --- a/lua/core/lsp/init.lua +++ b/lua/core/lsp/init.lua @@ -2,14 +2,14 @@ local M = {} --- setup vim lsp options function M.setup() + -- ensure the severs are setup + require("core.lsp.servers") + -- confgiure lsp vim.diagnostic.config { - virtual_text = false, virtual_lines = { current_line = true }, - update_in_insert = false, - underline = true, severity_sort = true, signs = { text = { @@ -28,6 +28,7 @@ function M.setup() require("core.lsp.binds") require("core.lsp.completion") + require("core.lsp.wtf") end return M diff --git a/lua/core/lsp/servers.lua b/lua/core/lsp/servers.lua new file mode 100644 index 0000000..e4a0bb2 --- /dev/null +++ b/lua/core/lsp/servers.lua @@ -0,0 +1,11 @@ +local servers = require("core").mason.packages.lsps + +-- enable the servers I want +for _, server in ipairs(servers) do + -- skip jdtls, we start this on our own + if servers == "jdtls" then + goto continue + end + vim.lsp.enable(server) + ::continue:: +end diff --git a/lua/core/lsp/wtf.lua b/lua/core/lsp/wtf.lua new file mode 100644 index 0000000..daf0d7a --- /dev/null +++ b/lua/core/lsp/wtf.lua @@ -0,0 +1,29 @@ +-- wtf why does the language server protocol have these features? +-- partially stolen from https://github.com/glepnir/nvim + +local misc = require("core.misc") +local auto = misc.auto +local wtf_group = misc.augroup("lsp.wtf") + +auto('LspAttach', { + group = wtf_group, + callback = function(ctx) + local client = vim.lsp.get_client_by_id(ctx.data.client_id) + if not client then + return + end + + -- highlight color codes via lsp (supported by cssls) + -- #ff0000 + if client:supports_method('textDocument/documentColor') then + vim.lsp.document_color.enable(true, ctx.buf) + end + + -- enable linked editing this allows lsps to modify things like html tags + -- for example when you change

to

will be changed by the lsp + -- to + if client:supports_method('textDocument/linkedEditingRange') then + vim.lsp.linked_editing_range.enable(true, { client_id = client.id }) + end + end +}) diff --git a/lua/core/misc.lua b/lua/core/misc.lua index 7e419f3..2936c6c 100644 --- a/lua/core/misc.lua +++ b/lua/core/misc.lua @@ -3,20 +3,9 @@ local M = {} --- vim.notify title M.appid = "Nvim Config" ---- loop through files in directory ----@param path string absolute path of directory to be looped through ----@param body function function to use on every recursion of the loop ----@param ext string? desired file extension of files to be returned from directory -function M.loopf(path, body, ext) - ext = ext and [[v:val =~ '\.]]..ext..[[$']] or nil - for _, file in ipairs(vim.fn.readdir(path, ext)) do - body(file) - end -end - --- extend vim.kemap.set ---@param mode string|table mode for the keymap ----@param bind string|table keymap +---@param bind string keymap ---@param cmd function|string command to run ---@param opts vim.keymap.set.Opts? keymap options function M.map(mode, bind, cmd, opts) @@ -35,19 +24,12 @@ function M.map(mode, bind, cmd, opts) end end - -- define the keybinds - if type(bind) == "table" then - for i in pairs(bind) do - vim.keymap.set(mode, bind[i], cmd, opts) - end - elseif type(bind) == "string" then - vim.keymap.set(mode, bind, cmd, opts) - end + vim.keymap.set(mode, bind, cmd, opts) end --- a small map wrapper to easily create local buffer mappings ---@param mode string|table mode for the keymap ----@param bind string|table keymap +---@param bind string keymap ---@param cmd function|string command to run ---@param opts table? keymap options function M.map_local(mode, bind, cmd, opts) @@ -56,13 +38,8 @@ function M.map_local(mode, bind, cmd, opts) M.map(mode, bind, cmd, opts) end ---- extend vim.api.nvim_create_autocmd ----@param event string|table event or events ----@param opts vim.api.keyset.create_autocmd options ----@return integer -function M.auto(event, opts) - return vim.api.nvim_create_autocmd(event, opts) -end +--- shorten vim.api.nvim_create_autocmd call +M.auto = vim.api.nvim_create_autocmd --- extend auto group ---@param name string name of the autogroup @@ -82,85 +59,4 @@ function M.lz(txt) return "se lz"..txt.."se lz!" end ---- extend vim.api.nvim_set_hl ----@param group string|table highlight group ----@param opts table highlight options ----@param namespace? number highlight space -function M.highlight(group, opts, namespace) - namespace = namespace or 0 - - if type(group) == "table" then - for i in pairs(group) do - vim.api.nvim_set_hl(namespace, group[i], opts) - end - elseif type(group) == "string" then - vim.api.nvim_set_hl(namespace, group, opts) - end -end - ---- highlight something with some highlight group for a certain amount of time ---- example: ---- ```lua ---- { ---- -- highlight group to use ---- hl = "IncSearch", ---- ---- -- # of ms to stay highlighted for ---- timeout = 250, ---- ---- -- line to highlight ---- line = vim.api.nvim_win_get_cursor(0)[1], ---- ---- -- range to highlight if this is used line will be ignored ---- range = { ---- { 0, 0 }, ---- { 0, 0 } ---- } ---- } ---- ``` ---- opts is optional and if empty will simply highlight the current line for ---- 250ms using IncSearch as the highlight group ----@param opts table? options -function M.timeout_highlight(opts) - opts = opts or {} - opts.hl = opts.hl or "IncSearch" - opts.timeout = opts.timeout or 250 - if type(opts.range) ~= "table" or type(opts.range[1]) ~= "table" or - type(opts.range[2]) ~= "table" then - local curline = opts.line or vim.api.nvim_win_get_cursor(0)[1] - opts.range = { - { curline - 1, 0 }, - { curline, 0 } - } - end - - local namespaceid = vim.api.nvim_create_namespace("timeout_highlight") - - -- timer code was happily stolen from neovim/runtime/lua/vim/highlight.lua :) - local timer, timer_cancel - if not vim.fn.has("nvim-0.11") then - if timer then - timer:close() - assert(timer_cancel) - timer_cancel() - end - end - - -- set the highlight - vim.highlight.range(0, namespaceid, opts.hl, opts.range[1], opts.range[2], { - opts.timeout, - }) - - if not vim.fn.has("nvim-0.11") then - timer_cancel = function() - timer = nil - timer_cancel = nil - pcall(vim.api.nvim_buf_clear_namespace, 0, namespaceid, 0, -1) - pcall(vim.api.nvim_win_remove_ns, 0, namespaceid) - end - - timer = vim.defer_fn(timer_cancel, opts.timeout) - end -end - return M diff --git a/lua/snippets/lua.lua b/lua/snippets/lua.lua new file mode 100644 index 0000000..0aa0e4e --- /dev/null +++ b/lua/snippets/lua.lua @@ -0,0 +1,19 @@ +dofile(core.snippets) + +return { + -- print inspect text + s("inspect", { + t("print(vim.inspect("), + i(0), + t("))") + }), + + -- print inspect text + s("M", { + i(1, "M"); + t({ " = {}", "" }), + i(0), + t({ "", "return " }), + r(1) + }) +}