commit 38bddf66fb688abb28a68ae6cd44d0923b9887ba Author: konsthol Date: Sun Jun 8 21:04:14 2025 +0300 Hiding API key hahaha diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..ceeb6cc --- /dev/null +++ b/init.lua @@ -0,0 +1 @@ +require("konsthol.lazy") -- Plugins diff --git a/lua/konsthol/lazy.lua b/lua/konsthol/lazy.lua new file mode 100644 index 0000000..eb0c672 --- /dev/null +++ b/lua/konsthol/lazy.lua @@ -0,0 +1,31 @@ +--> Run Lazy sync every time plugins.lua is updated +-- vim.cmd [[autocmd BufWritePost plugins.lua source | Lazy sync]] + +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not vim.loop.fs_stat(lazypath) then + vim.fn.system({ + "git", + "clone", + "--filter=blob:none", + "https://github.com/folke/lazy.nvim.git", + "--branch=stable", -- latest stable release + lazypath, + }) +end +vim.opt.rtp:prepend(lazypath) + +local plugins = { + { import = 'konsthol.plugins.lsp' }, +} + +local opts = { + checker = { + enabled = true, + notify = false, + }, + change_detection = { + notify = false, + }, +} + +require('lazy').setup(plugins, opts) diff --git a/lua/konsthol/plugins/lsp/cmp.lua b/lua/konsthol/plugins/lsp/cmp.lua new file mode 100644 index 0000000..029eec6 --- /dev/null +++ b/lua/konsthol/plugins/lsp/cmp.lua @@ -0,0 +1,181 @@ +return { + 'hrsh7th/nvim-cmp', --> Autocompletion plugin + event = 'InsertEnter', + dependencies = { + 'hrsh7th/cmp-buffer', --> source for text in buffer + 'hrsh7th/cmp-path', --> source for file system paths + 'onsails/lspkind.nvim', --> VS Code like icons + 'L3MON4D3/LuaSnip', --> Snippets plugin for custom snippets + 'saadparwaiz1/cmp_luasnip', --> Snippets source for nvim-cmp (for autocompletion) + 'rafamadriz/friendly-snippets', --> useful snippets + 'hrsh7th/cmp-copilot', + 'hrsh7th/cmp-nvim-lsp', --> LSP source for nvim-cmp + 'hrsh7th/cmp-nvim-lua', --> LSP source for nvim-cmp + 'hrsh7th/cmp-nvim-lsp-signature-help', --> Signature help for nvim-cmp + 'kdheepak/cmp-latex-symbols', --> Latex symbols for nvim-cmp + }, + config = function() + -- Set up nvim-cmp + local cmp = require'cmp' + -- Set up luasnip + local lspkind = require('lspkind') + local luasnip = require('luasnip') + -- loads vscode style snippets from installed plugins (e.g. friendly-snippets) + require("luasnip.loaders.from_vscode").lazy_load() + -- Custom snippets for latex + require("luasnip.loaders.from_snipmate").load({ paths = "~/.config/nvim/snippets/" }) + cmp.setup({ + completion = { + completeopt = 'menu,menuone,preview,noselect', + }, + snippet = { + -- REQUIRED - you must specify a snippet engine + expand = function(args) + -- vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users. + luasnip.lsp_expand(args.body) -- For `luasnip` users. + -- require('snippy').expand_snippet(args.body) -- For `snippy` users. + -- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users. + end, + }, + window = { + completion = cmp.config.window.bordered(), -- unfortunately changes selected item highlighting color + -- documentation = cmp.config.window.bordered(), + documentation = { + border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, + }, + }, + mapping = cmp.mapping.preset.insert({ + -- [''] = cmp.mapping.select_prev_item(), -- previous suggestion + -- [''] = cmp.mapping.select_next_item(), -- next suggestion + -- [''] = cmp.mapping.scroll_docs(-4), + -- [''] = cmp.mapping.scroll_docs(4), + -- [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), -- closes the popup + [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + -- [''] = cmp.mapping.confirm { + -- behavior = cmp.ConfirmBehavior.Replace, + -- select = true, + -- }, + + -- When in a snippet, will jump to the next + -- snipper segment without accidentally + -- expanding another snippet. + [''] = cmp.mapping(function(fallback) + if luasnip.jumpable(1) then + luasnip.jump(1) + else + fallback() + end + end, { 'i', 's' }), + + -- [''] = cmp.mapping(function(fallback) + -- if cmp.visible() then + -- cmp.select_next_item() + -- elseif luasnip.expand_or_jumpable() then + -- luasnip.expand_or_jump() + -- else + -- fallback() + -- end + -- end, { 'i', 's' }), + -- [''] = cmp.mapping(function(fallback) + -- if cmp.visible() then + -- cmp.select_prev_item() + -- elseif luasnip.jumpable(-1) then + -- luasnip.jump(-1) + -- else + -- fallback() + -- end + -- end, { 'i', 's' }), + }), + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + -- { name = 'vsnip' }, -- For vsnip users. + { name = 'luasnip' }, -- For luasnip users. + { name = 'nvim_lua' }, + { name = 'nvim_lsp_signature_help' }, + -- { name = 'ultisnips' }, -- For ultisnips users. + -- { name = 'snippy' }, -- For snippy users. + }, { + { name = 'buffer' }, + { name = 'path' }, + -- { name = 'copilot' }, + -- order matters here + }), + formatting = { + format = lspkind.cmp_format({ + with_text = true, + mode = 'symbol', -- show only symbol annotations + -- mode = 'symbol_text', -- show symbol annotations and text + maxwidth = 80, -- prevent the popup from showing more than provided characters (e.g 50 will not show more than 50 characters) + ellipsis_char = '...', -- when popup menu exceed maxwidth, the truncated part would show ellipsis_char instead (must define maxwidth first) + + -- The function below will be called before any actual modifications from lspkind + -- so that you can provide more controls on popup customization. (See [#30](https://github.com/onsails/lspkind-nvim/pull/30)) + before = function (entry, vim_item) + vim_item.menu = ({ + nvim_lsp = "[LSP]", + nvim_lua = "[NVIM_LUA]", + luasnip = "[Snippet]", + buffer = "[Buffer]", + path = "[Path]", + nvim_lsp_signature_help = "[Signature]", + latex_symbols = "[Latex Symbols]", + })[entry.source.name] + return vim_item + end + }) + }, + + }) + + -- Set configuration for specific filetype. + -- cmp.setup.filetype('gitcommit', { + -- sources = cmp.config.sources({ + -- { name = 'cmp_git' }, -- You can specify the `cmp_git` source if you were installed it. + -- }, + -- { + -- { name = 'buffer' }, + -- }) + -- }) + + cmp.setup.filetype('tex', { + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + -- { name = 'vsnip' }, -- For vsnip users. + { name = 'luasnip' }, -- For luasnip users. + { name = 'nvim_lua' }, + { name = 'nvim_lsp_signature_help' }, + -- { name = 'ultisnips' }, -- For ultisnips users. + -- { name = 'snippy' }, -- For snippy users. + }, { + { name = 'buffer' }, + { name = 'path' }, + { -- will probably never load being this low in the list + name = 'latex_symbols', + option = { + strategy = 0, -- mixed + }, + } + }) + }) + + + -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). + -- cmp.setup.cmdline({ '/', '?' }, { + -- mapping = cmp.mapping.preset.cmdline(), + -- sources = { + -- { name = 'buffer' } + -- } + -- }) + + -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). + -- cmp.setup.cmdline(':', { + -- mapping = cmp.mapping.preset.cmdline(), + -- sources = cmp.config.sources({ + -- { name = 'path' } + -- }, { + -- { name = 'cmdline' } + -- }) + -- }) + end +} diff --git a/lua/konsthol/plugins/lsp/lsp.lua b/lua/konsthol/plugins/lsp/lsp.lua new file mode 100644 index 0000000..6163de8 --- /dev/null +++ b/lua/konsthol/plugins/lsp/lsp.lua @@ -0,0 +1,163 @@ +return { + --> LSP/cmp Plugins + 'neovim/nvim-lspconfig', + event = { 'BufReadPre', 'BufNewFile' }, + dependencies = { + 'hrsh7th/cmp-nvim-lsp', + 'lewis6991/hover.nvim', + }, + config = function() + -- Import lspconfig plugin + local lspconfig = require('lspconfig') + -- Import cmp_nvim_lsp plugin + local cmp_nvim_lsp = require('cmp_nvim_lsp') + -- Set options + local opts = { noremap = true, silent = true } + + -- Diagnostics + -- Set diagnostic keymaps + local map = vim.keymap.set + opts.desc = "Open diagnostics" + map("n", "ld", ":lua vim.diagnostic.open_float()", opts) + opts.desc = "Diagnostic prev" + map("n", "[d", ":lua vim.diagnostic.goto_prev()", opts) + opts.desc = "Diagnostic next" + map("n", "]d", ":lua vim.diagnostic.goto_next()", opts) + opts.desc = "Diagnostic list" + map("n", "lq", ":lua vim.diagnostic.setloclist()", opts) + + -- Set diagnostic signs + local signs = { + { name = "DiagnosticSignError", text = "" }, + { name = "DiagnosticSignWarn", text = "" }, + { name = "DiagnosticSignHint", text = "" }, + { name = "DiagnosticSignInfo", text = "" }, + } + + for _, sign in ipairs(signs) do + vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = "" }) + end + + -- Set diagnostic config + local diagnostic_config = { + virtual_text = true, -- false disables virtual text + signs = { + active = signs, -- show signs + }, + update_in_insert = true, + underline = true, + severity_sort = true, + float = { + focusable = true, + style = "minimal", + border = "rounded", + source = "always", + header = "", + prefix = "", + }, + } + + vim.diagnostic.config(diagnostic_config) + + -- Add border to hover window + local border = { + {"╭", "FloatBorder"}, + {"─", "FloatBorder"}, + {"╮", "FloatBorder"}, + {"│", "FloatBorder"}, + {"╯", "FloatBorder"}, + {"─", "FloatBorder"}, + {"╰", "FloatBorder"}, + {"│", "FloatBorder"}, + } + + local hover = require('hover') + hover.setup({ + init = function() + require('hover.providers.lsp') + end, + preview_opts = { + border = border, + }, + preview_window = false, + title = true + }) + vim.keymap.set("n", "K", require("hover").hover, {desc = "Hover info"}) + + -- LSP keymaps + local function lsp_keymaps(bufnr) + local keymap = function(mode, keys, func, desc) + if desc then + opts.desc = 'LSP: ' .. desc + end + vim.api.nvim_buf_set_keymap(bufnr, mode, keys, func, opts) + end + keymap('n', 'gd', 'Telescope lsp_definitions', "Go to definition") -- Ctrl+o to go back + keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', "Go to declaration") + -- keymap('n', 'K', require('hover').hover(), "Hover info") + keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', "Go to type implementation") + keymap('n', 'gr', "Telescope lsp_references", "Go to references") + keymap('n', 'rn', 'lua vim.lsp.buf.rename()', "Rename") -- may need saving with :wa after + keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', "Code actions") + keymap('n', 'F', 'Format', "Format") + keymap('n', 'di', 'Telescope diagnostics', "Telescope Diagnostics") + keymap('n', 'dss', 'Telescope lsp_document_symbols', "Telescope LSP Document Symbols") + keymap('n', 'dsw', 'Telescope lsp_workspace_symbols', "Telescope LSP Workspace Symbols") + keymap('n', 'gld', 'lua vim.diagnostic.open_float()', "Get Line Diagnostics") + -- buf_set_keymap("n", "lf", ":lua vim.lsp.buf.format({ async = true })", opts) --> formats the current buffer + end + + local handlers = { + ["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, {border = border}), + -- ["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, {border = border }), -- seems to happen automatically + } + + + local on_attach = function(_, bufnr) + lsp_keymaps(bufnr) + -- vim.api.nvim_set_option_value(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') -- happens automatically + end + + ---@diagnostic disable-next-line: undefined-global + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities.textDocument.completion.completionItem.snippetSupport = true + capabilities = cmp_nvim_lsp.default_capabilities(capabilities) + local lsp_flags = { + debounce_text_changes = 150, + capabilities = capabilities, + virtual_text = true, + } + + local lspsetup = function(server, config) + lspconfig[server].setup({ + handlers = handlers, + on_attach = on_attach, + flags = lsp_flags, + settings = config, + }) + end + + -- Configure bash language server + lspsetup("bashls") + + local lua_config = { + Lua = { + -- make the language server recognize "vim" global + diagnostics = { + globals = { "vim" }, -- Preferred than using a .luacheckrc file like nvim-lint requires + }, + workspace = { + -- make language server aware of runtime files + library = { + [vim.fn.expand("$VIMRUNTIME/lua")] = true, + [vim.fn.stdpath("config") .. "/lua"] = true, + }, + }, + }, + } + + -- Configure lua language server (with special settings) + lspsetup("lua_ls", lua_config) + + end +} diff --git a/lua/konsthol/plugins/lsp/mason.lua b/lua/konsthol/plugins/lsp/mason.lua new file mode 100644 index 0000000..541f7aa --- /dev/null +++ b/lua/konsthol/plugins/lsp/mason.lua @@ -0,0 +1,46 @@ +return { + --> Mason Plugins + 'williamboman/mason.nvim', + event = { 'BufReadPre', 'BufNewFile' }, + dependencies = { + 'williamboman/mason-lspconfig.nvim', + 'WhoIsSethDaniel/mason-tool-installer.nvim', + -- 'mason-org/mason-registry', + }, + config = function() + -- Import Mason + local mason = require('mason') + -- Import mason-lspconfig + local mason_lsp = require('mason-lspconfig') + local mason_tool_installer = require('mason-tool-installer') + -- Enable mason and configure icons + mason.setup({ + ui = { + icons = { + package_installed = "✓", + package_pending = "➜", + package_uninstalled = "✗", + }, + }, + providers = { + "mason.providers.client", + -- "mason.providers.registry-api" -- This is the default provider. You can still include it here if you want, as a fallback to the client provider. + } + }) + mason_lsp.setup({ + -- List of servers for mason to install + ensure_installed = { + "bashls", + "lua_ls", + }, + -- Auto-install configured servers (with lspconfig) + automatic_installation = true, + }) + mason_tool_installer.setup({ + ensure_installed = { + "shellcheck", + "shfmt", + }, + }) + end +}