From faad6ae58b11c101a2a2e107f9d6719cb4b58dcb Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Fri, 29 Aug 2025 15:49:38 +0200 Subject: [PATCH] Better lsp support that checks wheter a needed binary is installed before installing the lsp with mason to avoid errors --- README.md | 23 +++++++ lua/conf.lua | 7 +++ lua/config/keymaps.lua | 119 +++++++++++++++++------------------ lua/plugins/lsp.lua | 137 +++++++++++++++++++++++++++++++---------- 4 files changed, 189 insertions(+), 97 deletions(-) create mode 100644 lua/conf.lua diff --git a/README.md b/README.md index 7a9b1ca..2183eaf 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,26 @@ You can configure the current semester that you are in for university integrations. There are certain things required like `make` and `npm` for various plugins. +## Dependencies + +To install proper snippets and get the basic lsp the following programs are needed in path. + +``` +make +curl +gcc +libc +bash +``` + +Optionally for more lsp servers. + +``` +go +npm +``` + +## General + +This configuration is based on the lazy plugin manager. + diff --git a/lua/conf.lua b/lua/conf.lua new file mode 100644 index 0000000..27a9336 --- /dev/null +++ b/lua/conf.lua @@ -0,0 +1,7 @@ +local config = {} + +config.season = "S3" +config.projects = vim.fn.expand("~/projects") +config.uni_dir = vim.fn.expand("~/projects/university/" .. config.season) + +return config diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index bbbc03a..c5cf720 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -3,8 +3,7 @@ require("utils.functions") require("custom.uni") --- TODO: move this to a config file -local season = "S3" +local conf = require("conf") local links = require("utils.linker") local user = vim.fn.system('whoami'):gsub('\n', '') @@ -23,13 +22,6 @@ end --------------------- KEYMAPS ------------------------- ------------------------------------------------------- --- Fast quitter -vim.keymap.set('n', 'q', function() - pcall(function() - vim.cmd('wa') - end) - vim.cmd('qa!') -end) -- Fast window switch vim.keymap.set("n", "w", "w") @@ -46,9 +38,6 @@ vim.keymap.set("n", "me", ":mes") vim.keymap.set("n", "snt", "set nu") vim.keymap.set("n", "snf", "set nonu") -vim.keymap.set("n", "nv", function() - select_course_directory() -end, { desc = "Open UniCourse menu" }) vim.keymap.set("n", "n", "nzz", { silent = true }) vim.keymap.set("n", "N", "Nzz", { silent = true }) @@ -58,26 +47,15 @@ vim.keymap.set("n", "", "zz", { silent = true }) vim.keymap.set("n", "", "zz", { silent = true }) vim.keymap.set('n', 'a', 'm9ggVG"+y`9') vim.keymap.set('n', 'va', 'ggVG') - - - --- Get a ready to use terminal vim.keymap.set('n', 'tr', ':tabnew:termi') --- This needs to be refined for quick access to a new file or a recently edited one -vim.keymap.set('n', 'ov', - function() - local uni_dir = vim.fn.expand("~/projects/university/" .. season) +-- Indent all will be replaced by the formatting of lsp where the lsp is installed +vim.keymap.set('n', 'ia', 'gg=Gzz') + +vim.keymap.set('n', 'ya', 'ggVG"+y') + +vim.keymap.set('n', 'ss', ':wa') - require('telescope.builtin').find_files { - prompt_title = "Select Vorlesung in " .. season, - cwd = uni_dir, - find_command = { - "eza", "-1", "-D" - }, - } - end -) -- new quick note file -- TODO: make this smarter vim.keymap.set("n", "nn", ":e ~/synced/brainstore/zettelkasten/quick", { silent = true }) @@ -119,30 +97,9 @@ vim.keymap.set('n', 'oho', ':e ~/configuration/nixos/hosts') vim.keymap.set('n', 'os', ':e ~/configuration/nixos/modules/server') vim.keymap.set('n', 'ot', ':e ~/synced/brainstore/todos/todo.txt`.zz') vim.keymap.set('n', 'od', ':e ~/synced/brainstore/todos/done.txt`.zz') -vim.keymap.set('n', 'ou', ':e ~/projects/university/' .. season .. '/input.txt`.zz') +vim.keymap.set('n', 'ou', ':e ~/projects/university/' .. conf.season .. '/input.txt`.zz') vim.keymap.set('n', 'oz', ':e ~/.zshrc`.zz') vim.keymap.set('n', 'oaa', ':e ~/.common_shell`.zz') -vim.keymap.set("n", "or", - function() - local last_file_path = vim.fn.stdpath('data') .. "/lastfile.txt" - local file = io.open(last_file_path, "r") - if file then - local last_file = file:read("*line") - file:close() - if last_file and vim.fn.filereadable(last_file) == 1 then - vim.cmd("edit " .. last_file) - pcall(function() - vim.cmd('normal! `.') -- Go to the last edit position - vim.cmd('normal! zz') -- Center the cursor on the screen - end) - else - print("Last file does not exist or is not readable") - end - else - print("No last file found") - end - end - , { noremap = true, silent = true }) vim.keymap.set('n', 'ok', open_cal) @@ -156,12 +113,6 @@ vim.keymap.set("n", "lc", links.insert_contact_link, { desc = "Link Cont vim.keymap.set("n", "ld", links.insert_date_link, { desc = "Link Contact" }) --- Indent all will be replaced by the formatting of lsp where the lsp is installed -vim.keymap.set('n', 'ia', 'gg=Gzz') - -vim.keymap.set('n', 'ya', 'ggVG"+y') - -vim.keymap.set('n', 'ss', ':wa') vim.keymap.set('n', 'sw', function() local word = vim.fn.expand("") local replacement = vim.fn.input("Replace '" .. word .. "' with: ") @@ -196,26 +147,24 @@ end, { desc = "Substitute selection in file" }) vim.keymap.set('n', 'pp', function() vim.api.nvim_command('normal! "+p') end, { desc = 'Paste from system clipboard' }) - vim.keymap.set('v', 'p', function() vim.cmd('normal! "+p') end, { desc = 'Yank to clipboard and keep the selection' }) - ------------------------- VISUAL ------------------ +vim.keymap.set("n", "nv", function() + select_course_directory() +end, { desc = "Open UniCourse menu" }) vim.keymap.set('v', 'p', function() local unnamed_content = vim.fn.getreg('""') vim.api.nvim_command('normal! p') vim.fn.setreg('""', unnamed_content) end, { desc = 'Paste from unnamed register (don\'t overwrite it) in visual mode' }) + vim.keymap.set('v', 'y', function() vim.cmd('normal! "+y') vim.cmd('normal! gv') end, { desc = 'Yank to clipboard and keep the selection' }) - ----------------------------- INSERT --------------------------- - vim.keymap.set('i', '', function() local col = vim.fn.col('.') local line = vim.fn.line('.') @@ -228,6 +177,7 @@ vim.keymap.set('i', '', function() end end end) + -- Move left with wrapping vim.keymap.set('i', '', function() local col = vim.fn.col('.') @@ -242,3 +192,46 @@ vim.keymap.set('i', '', function() end end end, { noremap = true, silent = true }) + +vim.keymap.set("n", "or", + function() + local last_file_path = vim.fn.stdpath('data') .. "/lastfile.txt" + local file = io.open(last_file_path, "r") + if file then + local last_file = file:read("*line") + file:close() + if last_file and vim.fn.filereadable(last_file) == 1 then + vim.cmd("edit " .. last_file) + pcall(function() + vim.cmd('normal! `.') -- Go to the last edit position + vim.cmd('normal! zz') -- Center the cursor on the screen + end) + else + print("Last file does not exist or is not readable") + end + else + print("No last file found") + end + end + , { noremap = true, silent = true }) + +-- Fast quitter +vim.keymap.set('n', 'q', function() + pcall(function() + vim.cmd('wa') + end) + vim.cmd('qa!') +end) + +-- This needs to be refined for quick access to a new file or a recently edited one +vim.keymap.set('n', 'ov', + function() + require('telescope.builtin').find_files({ + prompt_title = "Select lecture in " .. conf.season, + cwd = conf.uni_dir, + find_command = { + "eza", "-1", "-D" + } + }) + end +) diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index b860572..7ecc21e 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -1,5 +1,66 @@ +-- Prefilled with lsp that have no dependencies +local servers = { "lua_ls", "rust_analyzer", "denols" } + +local function populate_servers() + if vim.fn.executable("go") == 1 then + table.insert(servers, "gopls") + else + vim.notify("[mason] Skipping gopls (go not found)", vim.log.levels.WARN) + end + + if vim.fn.executable("npm") == 1 then + table.insert(servers, "pyright") + table.insert(servers, "clangd") + table.insert(servers, "bashls") + else + vim.notify("[mason] Skipping install of some lsp (npm not found)", vim.log.levels.WARN) + end + + if vim.fn.executable("cargo") == 1 then + table.insert(servers, "nil_ls") + else + vim.notify("[mason] Skipping nil (cargo not found)", vim.log.levels.WARN) + end +end +populate_servers() + return { - { "stevearc/aerial.nvim", config = true }, + { + "stevearc/aerial.nvim", + dependencies = { + "nvim-treesitter/nvim-treesitter", + "nvim-tree/nvim-web-devicons" + }, + config = true, + keys = { + { + "ae", + function() + require("aerial") + vim.cmd("AerialToggle") + end + + }, + { + "}", + function() + require("aerial") + vim.cmd("AerialNext") + end + + }, + { + "{", + function() + require("aerial") + vim.cmd("AerialPrev") + end + + }, + + + }, + }, { "nvimdev/lspsaga.nvim", opts = { @@ -12,36 +73,31 @@ return { }, }, { - "neovim/nvim-lspconfig", + "williamboman/mason.nvim", dependencies = { - "williamboman/mason.nvim", - "williamboman/mason-lspconfig.nvim", + "williamboman/mason-lspconfig.nvim" + }, + priority = -10; + config = function() + require("mason").setup() - "hrsh7th/nvim-cmp", + + require("mason-lspconfig").setup({ + ensure_installed = servers, + automatic_installation = true, + }) + end, + + }, + { + "hrsh7th/nvim-cmp", + dependencies = { + "hrsh7th/cmp-path", + "saadparwaiz1/cmp_luasnip", "hrsh7th/cmp-nvim-lsp", "hrsh7th/cmp-buffer", - "nvimdev/lspsaga.nvim", - "hrsh7th/cmp-path", - "L3MON4D3/LuaSnip", - "saadparwaiz1/cmp_luasnip", }, config = function() - local lspconfig = require("lspconfig") - - -- Declarative important have npm and other tools installed - local servers = { "gopls", "pyright", "lua_ls", "rust_analyzer", "clangd" } - - -- Custom overwrites for servers - local server_settings = { - lua_ls = { - settings = { - Lua = { - diagnostics = { globals = { "vim" } }, - }, - }, - }, - } - local cmp = require("cmp") cmp.setup({ snippet = { @@ -61,6 +117,28 @@ return { { name = "path" }, }), }) + end + }, + { + "neovim/nvim-lspconfig", + dependencies = { + "hrsh7th/cmp-nvim-lsp", + "L3MON4D3/LuaSnip", + }, + config = function() + local lspconfig = require("lspconfig") + + -- Custom overwrites for servers + local server_settings = { + lua_ls = { + settings = { + Lua = { + diagnostics = { globals = { "vim" } }, + }, + }, + }, + } + local capabilities = require("cmp_nvim_lsp").default_capabilities() @@ -93,8 +171,6 @@ return { end, opts) end - - -- Setup servers manually for _, server in ipairs(servers) do local config = { @@ -107,13 +183,6 @@ return { lspconfig[server].setup(config) end - -- Mason for autoinstall of servers - require("mason").setup() - require("mason-lspconfig").setup({ - ensure_installed = servers, - automatic_installation = true, - }) - -- Add text in diagnostics vim.diagnostic.config({ virtual_text = true,