diff --git a/home/.config/nvim/README.adoc b/home/.config/nvim/README.adoc new file mode 100644 index 00000000..caabc08f --- /dev/null +++ b/home/.config/nvim/README.adoc @@ -0,0 +1,16 @@ += FunctionalHacker's NeoVim configuration + +This is my personal NeoVim configuration I use for all text editing in my free +time and at my day job. I mostly code in Java, TypeScript and ReactJS, with +a bit of Rust and Python once in a blue moon. + +The configuration is quite minimal but still fully featured. Some highlights +include + +* LSP support with neovim's built in LSP client +** LSP servers are easily installed and auto-configured with Mason +* Treesitter +** Code folding +** Code highlighting +** Text objects +* Lazy plugin manager for fast startup times diff --git a/home/.config/nvim/ftplugin/java.lua b/home/.config/nvim/ftplugin/java.lua new file mode 100644 index 00000000..58e0b620 --- /dev/null +++ b/home/.config/nvim/ftplugin/java.lua @@ -0,0 +1,111 @@ +local nvim_local_dir = vim.fn.expand("~/.local/share/nvim") +local mason_packages = nvim_local_dir .. "/mason/packages" +local lombok_jar = mason_packages .. "/jdtls/lombok.jar" +local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":p:h:t") +local workspace_dir = nvim_local_dir .. "/jdtls-workspaces/" .. project_name +local lsp_utils = require("lsp_utils") +local jvm = "/usr/lib/jvm" +local java_version = 21 + +require("jdtls").start_or_attach({ + cmd = { + jvm .. "/java-" .. java_version .. "-openjdk-amd64/bin/java", + "-Declipse.application=org.eclipse.jdt.ls.core.id1", + "-Dosgi.bundles.defaultStartLevel=4", + "-Declipse.product=org.eclipse.jdt.ls.core.product", + "-Dlog.protocol=true", + "-Dlog.level=ALL", + "-Xms1g", + "--add-modules=ALL-SYSTEM", + "--add-opens", + "java.base/java.util=ALL-UNNAMED", + "--add-opens", + "java.base/java.lang=ALL-UNNAMED", + "-javaagent:" .. lombok_jar, + "-jar", + vim.fn.glob(mason_packages .. "/jdtls/plugins/org.eclipse.equinox.launcher_*.jar"), + "-configuration", + nvim_local_dir .. "/mason/packages/jdtls/config_linux", + "-data", + workspace_dir, + }, + settings = { + java = { + signatureHelp = { enabled = true }, + autobuild = { enabled = false }, + configuration = { + runtimes = { + { + name = "JavaSE-1.8", + path = jvm .. "/java-8-openjdk-amd64/", + }, + { + name = "JavaSE-11", + path = jvm .. "/java-11-openjdk-amd64/", + }, + { + name = "JavaSE-17", + path = jvm .. "/java-17-openjdk-amd64/", + }, + { + name = "JavaSE-21", + path = jvm .. "/java-21-openjdk-amd64/", + }, + }, + }, + }, + }, + completion = { favoriteStaticMembers = { "java.text.MessageFormat.format" } }, + handlers = { + ["language/status"] = function() end, + }, + init_options = { + bundles = { + vim.fn.glob(mason_packages .. "/java-debug-adapter/extension/server/com.microsoft.java.debug.plugin-*.jar"), + }, + }, + capabilities = lsp_utils.get_capabilities(), + on_attach = lsp_utils.map_keys, +}) + +function RunJava() + local function show_output(output) + vim.cmd("split") + vim.cmd("enew") + vim.fn.append(0, output) + --vim.cmd("1d") -- Remove the empty first line + vim.bo[0].modifiable = false + end + + local filename = vim.fn.expand("%") -- Get the current file name + local class_name = vim.fn.fnamemodify(filename, ":r") -- Extract the class name + local compile_cmd = "javac " .. filename + local run_cmd = "java " .. class_name + + -- Create a temporary file to capture the compile output + local temp_file = vim.fn.tempname() + + -- Run the compilation command and save the output to the temporary file + local compile_exit_code = vim.fn.system(compile_cmd .. " > " .. temp_file .. " 2>&1") + + -- Check the exit code of the compile command + if compile_exit_code == 0 then + -- Compilation was successful, run the Java program + show_output(vim.fn.systemlist(run_cmd)) + else + -- Compilation failed, display the error output from the temporary file + show_output(vim.fn.readfile(temp_file)) + end + + -- Clean up the temporary file and class file + vim.fn.delete(temp_file) + vim.fn.delete(vim.fn.expand("%:p:h") .. "/" .. class_name .. ".class") +end + +-- Define a VimScript command to execute the Lua function +vim.api.nvim_exec( + [[ + command! RunJava lua RunJava() +]], + false +) diff --git a/home/.config/nvim/init.lua b/home/.config/nvim/init.lua new file mode 100644 index 00000000..a23743b8 --- /dev/null +++ b/home/.config/nvim/init.lua @@ -0,0 +1,28 @@ +-- Install lazy if it's not yet installed +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) + +require("settings") +require("keybinds") +require("neovide") +require("highlight_yank") +require("lazy").setup({ + spec = { import = "plugins" }, + lockfile = "~/git/dotfiles/home/.config/nvim/lazy-lock.json", + performance = { + disabled_plugins = { "netrwPlugin" }, + }, + defaults = { + -- version = "*", -- Disabled for now + }, +}) diff --git a/home/.config/nvim/lazy-lock.json b/home/.config/nvim/lazy-lock.json new file mode 100644 index 00000000..2fd9a9b5 --- /dev/null +++ b/home/.config/nvim/lazy-lock.json @@ -0,0 +1,69 @@ +{ + "LuaSnip": { "branch": "master", "commit": "b84eeb3641b08324287587b426ec974b888390d9" }, + "alpha-nvim": { "branch": "main", "commit": "b6f4129302db197a7249e67a90de3f2b676de13e" }, + "auto-dark-mode.nvim": { "branch": "master", "commit": "14cad96b80a07e9e92a0dcbe235092ed14113fb2" }, + "bufferline.nvim": { "branch": "main", "commit": "0b2fd861eee7595015b6561dade52fb060be10c4" }, + "cder.nvim": { "branch": "main", "commit": "0a071389bb52544ac9cf9557378aa1212dff6982" }, + "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" }, + "cmp-cmdline": { "branch": "main", "commit": "d250c63aa13ead745e3a40f61fdd3470efde3923" }, + "cmp-git": { "branch": "main", "commit": "50d526dff0f6bc441b51fc269d9fdc99a50c76af" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "39e2eda76828d88b773cc27a3f61d2ad782c922d" }, + "cmp-nvim-lua": { "branch": "main", "commit": "f12408bdb54c39c23e67cab726264c10db33ada8" }, + "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" }, + "cmp-spell": { "branch": "master", "commit": "694a4e50809d6d645c1ea29015dad0c293f019d6" }, + "cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" }, + "confirm-quit.nvim": { "branch": "main", "commit": "f15f6d728d385a3d2efa22098e9a45b8a2b20144" }, + "copilot-cmp": { "branch": "master", "commit": "b6e5286b3d74b04256d0a7e3bd2908eabec34b44" }, + "copilot.lua": { "branch": "master", "commit": "86537b286f18783f8b67bccd78a4ef4345679625" }, + "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" }, + "dropbar.nvim": { "branch": "master", "commit": "d26bf92161cd70e049dc138b44ffa0246dbf7178" }, + "firenvim": { "branch": "master", "commit": "bb70728c13c305ff35193586d5f6ce68668af063" }, + "friendly-snippets": { "branch": "main", "commit": "00ebcaa159e817150bd83bfe2d51fa3b3377d5c4" }, + "fugitive-gitea": { "branch": "master", "commit": "d93176028d13820f941c165c14039a6019744a5a" }, + "gitsigns.nvim": { "branch": "main", "commit": "562dc47189ad3c8696dbf460d38603a74d544849" }, + "indent-blankline.nvim": { "branch": "master", "commit": "dddb5d21811c319eb6e51a993d8fb44b193aae3f" }, + "kanagawa.nvim": { "branch": "master", "commit": "e5f7b8a804360f0a48e40d0083a97193ee4fcc87" }, + "lazy.nvim": { "branch": "main", "commit": "077102c5bfc578693f12377846d427f49bc50076" }, + "lazydev.nvim": { "branch": "main", "commit": "491452cf1ca6f029e90ad0d0368848fac717c6d2" }, + "lualine.nvim": { "branch": "master", "commit": "b431d228b7bbcdaea818bdc3e25b8cdbe861f056" }, + "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, + "mason-extra-cmds": { "branch": "main", "commit": "1bf94d631a9d35061e694ab49dbdea83172a8e51" }, + "mason-lock.nvim": { "branch": "main", "commit": "86614f76c3442fba1c5c8d79aa1efcb3ad69de1c" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "1c55991321d1a861537e32446affc5de5d9a6eaf" }, + "mason.nvim": { "branch": "main", "commit": "e2f7f9044ec30067bc11800a9e266664b88cda22" }, + "mini.nvim": { "branch": "main", "commit": "fe573c7fb74252076d6c6d40837a92a7138dbb00" }, + "neoformat": { "branch": "master", "commit": "b3b38589b39038dc12c2f5a59a828ed43439363a" }, + "noice.nvim": { "branch": "main", "commit": "448bb9c524a7601035449210838e374a30153172" }, + "nui.nvim": { "branch": "main", "commit": "61574ce6e60c815b0a0c4b5655b8486ba58089a1" }, + "nvim-asciidoc-preview": { "branch": "main", "commit": "50708bea09cead374bf0b4b9c50686de68951d5c" }, + "nvim-autopairs": { "branch": "master", "commit": "19606af7c039271d5aa96bceff101e7523af3136" }, + "nvim-cmp": { "branch": "main", "commit": "ae644feb7b67bf1ce4260c231d1d4300b19c6f30" }, + "nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" }, + "nvim-dap": { "branch": "master", "commit": "281a2e4cd1e7a17cea7ecb1745d84a8ab1249925" }, + "nvim-dap-ui": { "branch": "master", "commit": "a5606bc5958db86f8d92803bea7400ee26a8d7e4" }, + "nvim-jdtls": { "branch": "master", "commit": "99e4b2081de1d9162666cc7b563cbeb01c26b66b" }, + "nvim-lsp-file-operations": { "branch": "master", "commit": "92a673de7ecaa157dd230d0128def10beb56d103" }, + "nvim-lspconfig": { "branch": "master", "commit": "43200fb3a820ed1b6c526e0eb0f3e6e6edd9fd64" }, + "nvim-nio": { "branch": "master", "commit": "a428f309119086dc78dd4b19306d2d67be884eee" }, + "nvim-notify": { "branch": "master", "commit": "d333b6f167900f6d9d42a59005d82919830626bf" }, + "nvim-tree.lua": { "branch": "master", "commit": "ad0b95dee55955817af635fa121f6e2486b10583" }, + "nvim-treesitter": { "branch": "master", "commit": "cfd2095e66e49ea0dfbef6b41be2efd0ba6cc4ee" }, + "nvim-treesitter-textobjects": { "branch": "master", "commit": "41e3abf6bfd9a9a681eb1f788bdeba91c9004b2b" }, + "nvim-ts-autotag": { "branch": "main", "commit": "0cb76eea80e9c73b88880f0ca78fbd04c5bdcac7" }, + "nvim-ufo": { "branch": "main", "commit": "7dcb8fea3e7b3ccdb50f2c3ae7c248cdf6fe1ae1" }, + "nvim-web-devicons": { "branch": "master", "commit": "3722e3d1fb5fe1896a104eb489e8f8651260b520" }, + "password-store": { "branch": "master", "commit": "b5e965a838bb68c1227caa2cdd874ba496f10149" }, + "plenary.nvim": { "branch": "master", "commit": "ec289423a1693aeae6cd0d503bac2856af74edaa" }, + "promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" }, + "statuscol.nvim": { "branch": "main", "commit": "93d8bcda516fc86e11c03f9ef577bae9a72fba0e" }, + "suda.vim": { "branch": "master", "commit": "b97fab52f9cdeabe2bbb5eb98d82356899f30829" }, + "telescope-fzf-native.nvim": { "branch": "main", "commit": "cf48d4dfce44e0b9a2e19a008d6ec6ea6f01a83b" }, + "telescope-project.nvim": { "branch": "master", "commit": "1aaf16580a614601a7f7077d9639aeb457dc5559" }, + "telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" }, + "telescope.nvim": { "branch": "master", "commit": "5972437de807c3bc101565175da66a1aa4f8707a" }, + "vim-asciidoctor": { "branch": "master", "commit": "f553311b5db03440eb8d7035434d0405e4a2c559" }, + "vim-caddyfile": { "branch": "master", "commit": "24fe0720551883e407cb70ae1d7c03f162d1d5a0" }, + "vim-fugitive": { "branch": "master", "commit": "0444df68cd1cdabc7453d6bd84099458327e5513" }, + "vim-gnupg": { "branch": "main", "commit": "f9b608f29003dfde6450931dc0f495a912973a88" }, + "which-key.nvim": { "branch": "main", "commit": "6c1584eb76b55629702716995cca4ae2798a9cca" } +} diff --git a/home/.config/nvim/lua/highlight_yank.lua b/home/.config/nvim/lua/highlight_yank.lua new file mode 100644 index 00000000..649506bb --- /dev/null +++ b/home/.config/nvim/lua/highlight_yank.lua @@ -0,0 +1,12 @@ +-- Highlight yanked text + +local ag = vim.api.nvim_create_augroup +local au = vim.api.nvim_create_autocmd + +au('TextYankPost', { + group = ag('yank_highlight', {}), + pattern = '*', + callback = function() + vim.highlight.on_yank { higroup='IncSearch', timeout=300 } + end, +}) diff --git a/home/.config/nvim/lua/keybinds.lua b/home/.config/nvim/lua/keybinds.lua new file mode 100644 index 00000000..6676d121 --- /dev/null +++ b/home/.config/nvim/lua/keybinds.lua @@ -0,0 +1,15 @@ +vim.keymap.set("n", "b", function() + local current_theme = vim.fn.eval("&background") + if current_theme == "dark" then + vim.cmd("set background=light") + else + vim.cmd("set background=dark") + end +end, { desc = "Toggle background between dark and light" }) + +vim.keymap.set("n", "h", "nohlsearch", { desc = "Turn off search highlight" }) +vim.keymap.set("n", "co", 'silent! execute "%bd|e#|bd#"', { desc = "Close other buffers" }) +vim.keymap.set("n", "a", "e#", { desc = "Edit alternate file" }) +vim.keymap.set("n", "", "bnext", { desc = "Next buffer" }) +vim.keymap.set("n", "", "bprevious", { desc = "Previous buffer" }) +vim.keymap.set("t", "", "", { desc = "Exit terminal insert mode with esc" }) diff --git a/home/.config/nvim/lua/lsp_utils.lua b/home/.config/nvim/lua/lsp_utils.lua new file mode 100644 index 00000000..8851c307 --- /dev/null +++ b/home/.config/nvim/lua/lsp_utils.lua @@ -0,0 +1,56 @@ +-- This module contains lsp related +-- reusable functions +local m = {} + +local lsp = vim.lsp +local diagnostic = vim.diagnostic +local k = vim.keymap.set + +-- Maps LSP specific keybinds. +-- This makes them only available when LSP is running +function m.map_keys() + local builtin = require("telescope.builtin") + + require("which-key").add({ + { "w", group = "Workspace" }, + }) + + k("n", "F", lsp.buf.format, { desc = "Format with LSP" }) + k("n", "ca", lsp.buf.code_action, { desc = "Code action" }) + k("n", "e", diagnostic.open_float, { desc = "Open diagnostics" }) + k("n", "k", lsp.buf.signature_help, { desc = "Signature help" }) + k("n", "rn", lsp.buf.rename, { desc = "Rename symbol" }) + k("n", "wa", lsp.buf.add_workspace_folder, { desc = "Add folder" }) + k("n", "wl", function() + print(vim.inspect(lsp.buf.list_workspace_folders())) + end, { desc = "List folders" }) + k("n", "wr", lsp.buf.remove_workspace_folder, { desc = "Remove folder" }) + k("n", "K", lsp.buf.hover, { desc = "Hover" }) + k("n", "[d", diagnostic.goto_prev, { desc = "Previous diagnostic" }) + k("n", "]d", diagnostic.goto_next, { desc = "Next diagnostic" }) + k("n", "gD", lsp.buf.declaration, { desc = "Declaration" }) + k("n", "gd", builtin.lsp_definitions, { desc = "Definition" }) + k("n", "gi", builtin.lsp_implementations, { desc = "Implementation" }) + k("n", "gr", builtin.lsp_references, { desc = "References" }) + k("n", "gs", builtin.lsp_document_symbols, { desc = "Symbols" }) + k("n", "gt", lsp.buf.type_definition, { desc = "Type definition" }) +end + +-- Combine built-in LSP and cmp cabaibilities +-- and additional capabilities from other plugins +function m.get_capabilities() + local capabilities = vim.tbl_deep_extend( + "force", + lsp.protocol.make_client_capabilities(), + require("cmp_nvim_lsp").default_capabilities() + ) + + -- Neovim hasn't added foldingRange to default capabilities, users must add it manually for ufo + capabilities.textDocument.foldingRange = { + dynamicRegistration = false, + lineFoldingOnly = true, + } + return capabilities +end + +return m diff --git a/home/.config/nvim/lua/neovide.lua b/home/.config/nvim/lua/neovide.lua new file mode 100644 index 00000000..c6b62c02 --- /dev/null +++ b/home/.config/nvim/lua/neovide.lua @@ -0,0 +1,29 @@ +local g = vim.g +local o = vim.o + +-- Change scale factor with C+ and C- +g.neovide_scale_factor = 1.0 +local change_scale_factor = function(delta) + g.neovide_scale_factor = g.neovide_scale_factor * delta +end +vim.keymap.set("n", "", function() + change_scale_factor(1.25) +end) +vim.keymap.set("n", "", function() + change_scale_factor(1 / 1.25) +end) + +-- Hide mouse when typing in neovide (disabled) +g.neovide_hide_mouse_when_typing = false + +-- Enable cursor particles in neovide +g.neovide_cursor_vfx_mode = "railgun" + +-- Enable dark/light theme detection +g.neovide_theme = "auto" + +-- Confirm quit +g.neovide_confirm_quit = true + +-- Set font +--o.guifont = "Hack Nerd Font Mono:h15" diff --git a/home/.config/nvim/lua/pager.lua b/home/.config/nvim/lua/pager.lua new file mode 100644 index 00000000..aea0b8d7 --- /dev/null +++ b/home/.config/nvim/lua/pager.lua @@ -0,0 +1,2 @@ +-- Settings for pager mode +vim.keymap.set("n", "q", vim.cmd.q) diff --git a/home/.config/nvim/lua/plugins/alpha.lua b/home/.config/nvim/lua/plugins/alpha.lua new file mode 100644 index 00000000..792ea76d --- /dev/null +++ b/home/.config/nvim/lua/plugins/alpha.lua @@ -0,0 +1,39 @@ +-- Startup dashboard +--- @type LazyPluginSpec +return { + "goolord/alpha-nvim", + config = function() + local alpha = require("alpha") + local dashboard = require("alpha.themes.dashboard") + dashboard.section.header.val = { + [[ __ ]], + [[ ___ ___ ___ __ __ /\_\ ___ ___ ]], + [[ / _ `\ / __`\ / __`\/\ \/\ \\/\ \ / __` __`\ ]], + [[/\ \/\ \/\ __//\ \_\ \ \ \_/ |\ \ \/\ \/\ \/\ \ ]], + [[\ \_\ \_\ \____\ \____/\ \___/ \ \_\ \_\ \_\ \_\]], + [[ \/_/\/_/\/____/\/___/ \/__/ \/_/\/_/\/_/\/_/]], + } + dashboard.section.buttons.val = { + dashboard.button( + "p", + "📽 Open a project", + ":lua require('telescope').extensions.project.project()" + ), + dashboard.button("e", " New file", ":ene startinsert "), + dashboard.button("", "🔍 Find file", "Telescope find_files"), + dashboard.button("", "𑪢 Grep files", "Telescope live_grep"), + dashboard.button("l", "🛋 Lazy", ":Lazy"), + dashboard.button("m", "📦 Mason", ":Mason"), + dashboard.button("q", "ꭙ Quit NeoVim", ":qa"), + } + + -- Fortune in footer + dashboard.section.footer.val = require("alpha.fortune")() + + dashboard.config.opts.noautocmd = true + + vim.cmd([[autocmd User AlphaReady echo 'ready']]) + + alpha.setup(dashboard.config) + end, +} diff --git a/home/.config/nvim/lua/plugins/asciidoc.lua b/home/.config/nvim/lua/plugins/asciidoc.lua new file mode 100644 index 00000000..d723b3fc --- /dev/null +++ b/home/.config/nvim/lua/plugins/asciidoc.lua @@ -0,0 +1,15 @@ +-- AsciiDoc plugins are grouped together here +return { + -- Vim ♥️ Asciidoctor + --- @type LazyPluginSpec + { + "habamax/vim-asciidoctor", + ft = { "asciidoctor", "asciidoc" }, + }, + -- AsciiDoc preview + --- @type LazyPluginSpec + { + "tigion/nvim-asciidoc-preview", + ft = { "asciidoctor", "asciidoc" }, + }, +} diff --git a/home/.config/nvim/lua/plugins/autopairs.lua b/home/.config/nvim/lua/plugins/autopairs.lua new file mode 100644 index 00000000..cde6d85c --- /dev/null +++ b/home/.config/nvim/lua/plugins/autopairs.lua @@ -0,0 +1,6 @@ +-- Automatic brackets +--- @type LazyPluginSpec +return { + "windwp/nvim-autopairs", + config = true +} diff --git a/home/.config/nvim/lua/plugins/bufferline.lua b/home/.config/nvim/lua/plugins/bufferline.lua new file mode 100644 index 00000000..e4c85983 --- /dev/null +++ b/home/.config/nvim/lua/plugins/bufferline.lua @@ -0,0 +1,16 @@ +-- Bufferline +--- @type LazyPluginSpec +return { + "akinsho/bufferline.nvim", + dependencies = { "kyazdani42/nvim-web-devicons" }, + --- @type BufferlineConfig + opts = { + options = { + diagnostics = "nvim_lsp", + diagnostics_indicator = function(count, level) + local icon = level:match("error") and " " or " " + return " " .. icon .. count + end, + }, + }, +} diff --git a/home/.config/nvim/lua/plugins/caddyfile.lua b/home/.config/nvim/lua/plugins/caddyfile.lua new file mode 100644 index 00000000..ec4c5273 --- /dev/null +++ b/home/.config/nvim/lua/plugins/caddyfile.lua @@ -0,0 +1,6 @@ +-- Caddyfile syntax support +--- @type LazyPluginSpec +return { + "isobit/vim-caddyfile", + ft = "caddyfile", +} diff --git a/home/.config/nvim/lua/plugins/cmp.lua b/home/.config/nvim/lua/plugins/cmp.lua new file mode 100644 index 00000000..9f6537d5 --- /dev/null +++ b/home/.config/nvim/lua/plugins/cmp.lua @@ -0,0 +1,150 @@ +-- Auto completion +--- @type LazyPluginSpec +return { + "hrsh7th/nvim-cmp", + dependencies = { + "hrsh7th/cmp-buffer", -- Buffer source + -- Git source + { + "petertriho/cmp-git", + dependencies = { "nvim-lua/plenary.nvim" }, + config = true, + }, + "hrsh7th/cmp-nvim-lsp", -- LSP source + "hrsh7th/cmp-nvim-lua", -- Neovim Lua API documentation source + "hrsh7th/cmp-path", -- Path source + "hrsh7th/cmp-cmdline", -- cmdline source + "saadparwaiz1/cmp_luasnip", -- Snippets source + "f3fora/cmp-spell", -- Spell check source + "petertriho/cmp-git", -- Git source + -- Copilot source + { + "zbirenbaum/copilot-cmp", + opts = { fix_pairs = true }, + }, + }, + config = function() + local cmp = require("cmp") + local luasnip = require("luasnip") + + local has_words_before = function() + unpack = unpack or table.unpack + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil + end + + -- Set completeopt to have a better completion experience + vim.o.completeopt = "menuone,noselect" + + local bordered = cmp.config.window.bordered() + + cmp.setup({ + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + window = { + completion = bordered, + documentation = bordered, + }, + mapping = { + [""] = cmp.mapping.select_prev_item(), + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.close(), + [""] = cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }), + -- Snippet placeholder forward + [""] = cmp.mapping(function(fallback) + if luasnip.jumpable(1) then + luasnip.jump(1) + else + fallback() + end + end, { "i", "s" }), + -- Snippet placeholder backward + [""] = cmp.mapping(function(fallback) + if luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + -- Completion menu forward + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + -- If only one entry, select it + if #cmp.get_entries() == 1 then + cmp.confirm({ select = true }) + else + cmp.select_next_item() + end + elseif has_words_before() then + cmp.complete() + if #cmp.get_entries() == 1 then + cmp.confirm({ select = true }) + end + else + fallback() + end + end, { "i", "s" }), + -- Completion menu backward + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + else + fallback() + end + end, { "i", "s" }), + }, + sources = { + { name = "luasnip" }, + { name = "nvim_lsp" }, + { name = "nvim_lua" }, + { name = "git" }, + { name = "copilot" }, + { name = "buffer" }, + { name = "spell" }, + { name = "path" }, + { + name = "lazydev", + group_index = 0, -- set group index to 0 to skip loading LuaLS completions + }, + }, + }) + + require("cmp_git").setup() + + -- Enable autopairs when enter is processed + -- on completion + local cmp_autopairs = require("nvim-autopairs.completion.cmp") + cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done()) + + -- search cmdline setup. + cmp.setup.cmdline({ "/", "?" }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = "buffer" }, + }, + }) + -- `:` cmdline setup. + cmp.setup.cmdline(":", { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = "path" }, + }, { + { + name = "cmdline", + option = { + ignore_cmds = { "Man", "!" }, + }, + }, + }), + }) + end, +} diff --git a/home/.config/nvim/lua/plugins/confirm-quit.lua b/home/.config/nvim/lua/plugins/confirm-quit.lua new file mode 100644 index 00000000..f140e7af --- /dev/null +++ b/home/.config/nvim/lua/plugins/confirm-quit.lua @@ -0,0 +1,10 @@ +-- Confirm before quit +--- @type LazyPluginSpec +return { + cond = vim.g.neovide == not nil, + "yutkat/confirm-quit.nvim", + event = "CmdlineEnter", + opts = { + quit_message = "You are in Neovide, are you sure you want to quit?", + }, +} diff --git a/home/.config/nvim/lua/plugins/copilot.lua b/home/.config/nvim/lua/plugins/copilot.lua new file mode 100644 index 00000000..c1b6a3ed --- /dev/null +++ b/home/.config/nvim/lua/plugins/copilot.lua @@ -0,0 +1,9 @@ +-- GitHub Copilot +--- @type LazyPluginSpec +return { + "zbirenbaum/copilot.lua", + opts = { + suggestion = { enabled = false }, + panel = { enabled = false }, + }, +} diff --git a/home/.config/nvim/lua/plugins/diffview.lua b/home/.config/nvim/lua/plugins/diffview.lua new file mode 100644 index 00000000..aa17c163 --- /dev/null +++ b/home/.config/nvim/lua/plugins/diffview.lua @@ -0,0 +1,3 @@ +-- Improved diffs +--- @type LazyPluginSpec +return { "sindrets/diffview.nvim" } diff --git a/home/.config/nvim/lua/plugins/dropbar.lua b/home/.config/nvim/lua/plugins/dropbar.lua new file mode 100644 index 00000000..30ef6fff --- /dev/null +++ b/home/.config/nvim/lua/plugins/dropbar.lua @@ -0,0 +1,6 @@ +-- Show the current LSP context in winbar +--- @type LazyPluginSpec +return { + enabled = vim.fn.has("nvim-0.10") == 1, + "Bekaboo/dropbar.nvim", +} diff --git a/home/.config/nvim/lua/plugins/firenvim.lua b/home/.config/nvim/lua/plugins/firenvim.lua new file mode 100644 index 00000000..dba55753 --- /dev/null +++ b/home/.config/nvim/lua/plugins/firenvim.lua @@ -0,0 +1,17 @@ +-- Neovim inside Firefox +--- @type LazyPluginSpec +return { + "glacambre/firenvim", + build = function() + vim.fn["firenvim#install"](0) + end, + config = function() + vim.g.firenvim_config = { + localSettings = { + [".*"] = { + takeOver = "never", + }, + }, + } + end, +} diff --git a/home/.config/nvim/lua/plugins/fugitive.lua b/home/.config/nvim/lua/plugins/fugitive.lua new file mode 100644 index 00000000..f6282331 --- /dev/null +++ b/home/.config/nvim/lua/plugins/fugitive.lua @@ -0,0 +1,12 @@ +-- Git commands +--- @type LazyPluginSpec +return { + "tpope/vim-fugitive", + dependencies = { "borissov/fugitive-gitea" }, + config = function() + vim.g.fugitive_gitea_domains = { + "https://git.korhonen.cc", + "https://git.rossum.fi", + } + end, +} diff --git a/home/.config/nvim/lua/plugins/gitsigns.lua b/home/.config/nvim/lua/plugins/gitsigns.lua new file mode 100644 index 00000000..000ef9d5 --- /dev/null +++ b/home/.config/nvim/lua/plugins/gitsigns.lua @@ -0,0 +1,34 @@ +local k = vim.keymap.set + +--- @type LazyPluginSpec +return { + "lewis6991/gitsigns.nvim", + config = function() + local gs = require("gitsigns") + gs.setup() + + -- Add groups for which-key + require("which-key").add({ + { "g", group = "Git" }, + { "gr", group = "Reset" }, + { "ga", group = "Add" }, + }) + + -- Keybinds + local opts + + -- Hunk navigation + k("n", "[h", gs.prev_hunk, { desc = "Previous hunk" }) + k("n", "]h", gs.next_hunk, { desc = "Next hunk" }) + + -- Hunk actions + opts = { desc = "Hunk" } + k("n", "grh", gs.reset_hunk, opts) + k("n", "gah", gs.stage_hunk, opts) + + -- Buffer actions + opts = { desc = "Buffer" } + k("n", "gab", gs.stage_buffer, opts) + k("n", "grb", gs.reset_buffer, opts) + end, +} diff --git a/home/.config/nvim/lua/plugins/gnupg.lua b/home/.config/nvim/lua/plugins/gnupg.lua new file mode 100644 index 00000000..4da3d9d8 --- /dev/null +++ b/home/.config/nvim/lua/plugins/gnupg.lua @@ -0,0 +1,6 @@ +-- Edit GPG encrypted files transparently +--- @type LazyPluginSpec +return { + "jamessan/vim-gnupg", + ft = { "gpg" }, +} diff --git a/home/.config/nvim/lua/plugins/indent-blankline.lua b/home/.config/nvim/lua/plugins/indent-blankline.lua new file mode 100644 index 00000000..8ddab8c7 --- /dev/null +++ b/home/.config/nvim/lua/plugins/indent-blankline.lua @@ -0,0 +1,24 @@ +-- Indent characters +--- @type LazyPluginSpec +return { + "lukas-reineke/indent-blankline.nvim", + --- @type ibl.config + opts = { + exclude = { + filetypes = { + "", + "checkhealth", + "alpha", + "git", + "gitcommit", + "TelescopePrompt", + "TelescopeResults", + "help", + "lazy", + "lspinfo", + "man", + }, + }, + }, + main = "ibl", +} diff --git a/home/.config/nvim/lua/plugins/kanagawa.lua b/home/.config/nvim/lua/plugins/kanagawa.lua new file mode 100644 index 00000000..3cd3beac --- /dev/null +++ b/home/.config/nvim/lua/plugins/kanagawa.lua @@ -0,0 +1,56 @@ +-- Colorscheme +--- @type LazyPluginSpec +return { + "rebelot/kanagawa.nvim", + dependencies = { { "f-person/auto-dark-mode.nvim", config = true } }, + --- @type KanagawaConfig + opts = { + compile = true, + dimInactive = true, + colors = { + theme = { + all = { + ui = { + bg_gutter = "none", -- Hide gutter background + }, + }, + }, + }, + background = { + dark = "wave", + light = "lotus", + }, + overrides = function(colors) + local theme = colors.theme + return { + -- Transparent floating windows + NormalFloat = { bg = "none" }, + FloatBorder = { bg = "none" }, + FloatTitle = { bg = "none" }, + NormalDark = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m3 }, + LazyNormal = { bg = theme.ui.bg_m3, fg = theme.ui.fg_dim }, + MasonNormal = { bg = theme.ui.bg_m3, fg = theme.ui.fg_dim }, + + -- Block-like modern Telescope UI + TelescopeTitle = { fg = theme.ui.special, bold = true }, + TelescopePromptNormal = { bg = theme.ui.bg_p1 }, + TelescopePromptBorder = { fg = theme.ui.bg_p1, bg = theme.ui.bg_p1 }, + TelescopeResultsNormal = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m1 }, + TelescopeResultsBorder = { fg = theme.ui.bg_m1, bg = theme.ui.bg_m1 }, + TelescopePreviewNormal = { bg = theme.ui.bg_dim }, + TelescopePreviewBorder = { bg = theme.ui.bg_dim, fg = theme.ui.bg_dim }, + + -- More uniform look for the popup menu + Pmenu = { fg = theme.ui.shade0, bg = theme.ui.bg_p1, blend = vim.o.pumblend }, + PmenuSel = { fg = "NONE", bg = theme.ui.bg_p2 }, + PmenuSbar = { bg = theme.ui.bg_m1 }, + PmenuThumb = { bg = theme.ui.bg_p2 }, + } + end, + }, + --- @param opts KanagawaConfig + config = function(_, opts) + require("kanagawa").setup(opts) + vim.cmd("colorscheme kanagawa") + end, +} diff --git a/home/.config/nvim/lua/plugins/lazydev.lua b/home/.config/nvim/lua/plugins/lazydev.lua new file mode 100644 index 00000000..4e9b1b54 --- /dev/null +++ b/home/.config/nvim/lua/plugins/lazydev.lua @@ -0,0 +1,15 @@ +-- Neovim setup for init.lua and plugin development with full signature help, docs and completion for the nvim lua API. +--- @type LazyPluginSpec +return { + { + "folke/lazydev.nvim", + ft = "lua", -- only load on lua files + opts = { + library = { + -- See the configuration section for more details + -- Load luvit types when the `vim.uv` word is found + { path = "luvit-meta/library", words = { "vim%.uv" } }, + }, + }, + }, +} diff --git a/home/.config/nvim/lua/plugins/lualine.lua b/home/.config/nvim/lua/plugins/lualine.lua new file mode 100644 index 00000000..1aaba3e7 --- /dev/null +++ b/home/.config/nvim/lua/plugins/lualine.lua @@ -0,0 +1,38 @@ +local noice_mode = require("noice").api.statusline.mode +-- Statusline +--- @type LazyPluginSpec +return { + "nvim-lualine/lualine.nvim", + dependencies = { "kyazdani42/nvim-web-devicons" }, + opts = { + sections = { + lualine_x = { + "encoding", + "fileformat", + "filetype", + { + noice_mode.get, + cond = noice_mode.has, + color = { fg = "#ff9e64" }, + }, + }, + lualine_z = { + { + "selectioncount", + cond = function() + local mode = vim.fn.mode() + return mode == "v" or mode == "V" or mode == "\22" + end, + }, + { + "location", + cond = function() + local mode = vim.fn.mode() + return mode ~= "v" and mode ~= "V" and mode ~= "\22" + end, + }, + }, + }, + }, + config = true, +} diff --git a/home/.config/nvim/lua/plugins/luasnip.lua b/home/.config/nvim/lua/plugins/luasnip.lua new file mode 100644 index 00000000..1364a570 --- /dev/null +++ b/home/.config/nvim/lua/plugins/luasnip.lua @@ -0,0 +1,19 @@ +-- Snippets plugin +--- @type LazyPluginSpec +return { + "L3MON4D3/LuaSnip", + -- Snippets collection + dependencies = { "rafamadriz/friendly-snippets" }, + config = function() + local vsCodeLoader = require("luasnip/loaders/from_vscode") + + -- Load friendly-snippets + vsCodeLoader.lazy_load() + + -- Load my custom snippets + vsCodeLoader.lazy_load({ + paths = { "./snippets" }, + }) + end, + run = "make install_jsregexp", +} diff --git a/home/.config/nvim/lua/plugins/markdown-preview.lua b/home/.config/nvim/lua/plugins/markdown-preview.lua new file mode 100644 index 00000000..731496ab --- /dev/null +++ b/home/.config/nvim/lua/plugins/markdown-preview.lua @@ -0,0 +1,10 @@ +-- Markdown preview +--- @type LazyPluginSpec +return { + "iamcco/markdown-preview.nvim", + build = "cd app && yarn install", + config = function() + vim.g.mkdp_filetypes = { "markdown" } + end, + ft = { "markdown" }, +} diff --git a/home/.config/nvim/lua/plugins/mason.lua b/home/.config/nvim/lua/plugins/mason.lua new file mode 100644 index 00000000..b357e5d4 --- /dev/null +++ b/home/.config/nvim/lua/plugins/mason.lua @@ -0,0 +1,60 @@ +-- Package manager for LSP servers, DAP adapters etc. +-- It also handles starting all of my LSP servers +--- @type LazyPluginSpec +return { + "williamboman/mason.nvim", + dependencies = { + "neovim/nvim-lspconfig", + "williamboman/mason-lspconfig.nvim", + -- Add MasonUpdateAll + { "Zeioth/mason-extra-cmds", opts = {} }, + -- Add lockfile support + { + "zapling/mason-lock.nvim", + opts = { + lockfile_path = vim.fn.expand("~/git/dotfiles/home/.config/nvim/mason-lock.json"), + }, + }, + -- Extended functionality for jdtls + "mfussenegger/nvim-jdtls", + -- Add support for LSP file operations + { "antosha417/nvim-lsp-file-operations", opts = {} }, + }, + config = function() + require("mason").setup() + + local mlspc = require("mason-lspconfig") + local lsp_utils = require("lsp_utils") + + local commonLspConfigArgs = { + on_attach = lsp_utils.map_keys, + capabilities = lsp_utils.get_capabilities(), + } + + mlspc.setup() + mlspc.setup_handlers({ + -- Default handler + function(server_name) + require("lspconfig")[server_name].setup(commonLspConfigArgs) + end, + + -- Disable tsserver diagnostics diagnostics + -- that come from ESLint + ["tsserver"] = function() + require("lspconfig").tsserver.setup(vim.tbl_extend("force", commonLspConfigArgs, { + settings = { + diagnostics = { + ignoredCodes = { + 6133, -- Unused variable + 6192, -- Unused import + }, + }, + }, + })) + end, + + -- Don't set up jdtls, it is set up by nvim-jdtls + ["jdtls"] = function() end, + }) + end, +} diff --git a/home/.config/nvim/lua/plugins/mini.lua b/home/.config/nvim/lua/plugins/mini.lua new file mode 100644 index 00000000..1c2c25a9 --- /dev/null +++ b/home/.config/nvim/lua/plugins/mini.lua @@ -0,0 +1,12 @@ +-- Library of 30+ independent Lua modules improving overall Neovim +--- @type LazyPluginSpec +return { + "echasnovski/mini.nvim", + config = function() + require("mini.surround").setup() + require("mini.comment").setup() + + -- Recommended for which-key + require("mini.icons").setup() + end, +} diff --git a/home/.config/nvim/lua/plugins/neoformat.lua b/home/.config/nvim/lua/plugins/neoformat.lua new file mode 100644 index 00000000..1bdc479a --- /dev/null +++ b/home/.config/nvim/lua/plugins/neoformat.lua @@ -0,0 +1,12 @@ +-- Formatter plugin +--- @type LazyPluginSpec +return { + "sbdchd/neoformat", + keys = { + { + desc = "Format with Neoformat", + "f", + "Neoformat", + }, + }, +} diff --git a/home/.config/nvim/lua/plugins/noice.lua b/home/.config/nvim/lua/plugins/noice.lua new file mode 100644 index 00000000..1de8aae2 --- /dev/null +++ b/home/.config/nvim/lua/plugins/noice.lua @@ -0,0 +1,30 @@ +-- Replace much of neovim's default UI +-- with a modern replacement +--- @type LazyPluginSpec +return { + "folke/noice.nvim", + event = "VeryLazy", + dependencies = { "MunifTanjim/nui.nvim", "rcarriga/nvim-notify" }, + --- @type NoiceConfig + opts = { + lsp = { + -- override markdown rendering so that **cmp** and other plugins use **Treesitter** + override = { + ["vim.lsp.util.convert_input_to_markdown_lines"] = true, + ["vim.lsp.util.stylize_markdown"] = true, + ["cmp.entry.get_documentation"] = true, + }, + }, + presets = { + -- add a border to hover docs and signature help + lsp_doc_border = true, + }, + }, + keys = { + { + desc = "Dismiss notifications", + "d", + "NoiceDismiss", + }, + }, +} diff --git a/home/.config/nvim/lua/plugins/nvim-colorizer.lua b/home/.config/nvim/lua/plugins/nvim-colorizer.lua new file mode 100644 index 00000000..ce3131d5 --- /dev/null +++ b/home/.config/nvim/lua/plugins/nvim-colorizer.lua @@ -0,0 +1,6 @@ +-- High performance color highlighter +--- @type LazyPluginSpec +return { + "norcalli/nvim-colorizer.lua", + config = true, +} diff --git a/home/.config/nvim/lua/plugins/nvim-dap.lua b/home/.config/nvim/lua/plugins/nvim-dap.lua new file mode 100644 index 00000000..7eb63a51 --- /dev/null +++ b/home/.config/nvim/lua/plugins/nvim-dap.lua @@ -0,0 +1,123 @@ +-- Debug adapter for NeoVim + +local masonPkg = vim.fn.stdpath("data") .. "/mason/packages" +--- @type LazyPluginSpec +return { + "mfussenegger/nvim-dap", + dependencies = { + { + "rcarriga/nvim-dap-ui", + dependencies = { "nvim-neotest/nvim-nio" }, + config = true, + }, + }, + config = function() + local dap = require("dap") + local configurations = dap.configurations + local adapters = dap.adapters + local pick_process = require("dap.utils").pick_process + + -- Applies all given configurations to the given filetypes + --- @param filetypes string[] + --- @param configs Configuration[] + local function dapConfigure(filetypes, configs) + for _, ft in ipairs(filetypes) do + configurations[ft] = configs + end + end + + -- Bash/sh + local bashAdapter = masonPkg .. "/bash-debug-adapter" + local bashExtension = bashAdapter .. "/extension" + adapters.bashdb = { + type = "executable", + command = bashAdapter .. "/bash-debug-adapter", + name = "bashdb", + } + configurations.sh = { + name = "Debug with bashdb", + type = "bashdb", + request = "launch", + showDebugOutput = true, + trace = true, + pathBashdbLib = bashExtension .. "/bashdb_dir", + pathBashdb = bashExtension .. "/bashdb_dir/bashdb", + file = "${file}", + program = "${file}", + cwd = "${workspaceFolder}", + pathCat = "cat", + pathBash = "/bin/bash", + pathMkfifo = "mkfifo", + pathPkill = "pkill", + args = {}, + env = {}, + terminalKind = "integrated", + } + + -- JavaScript/TypeScript in Firefox/Chrome/Node + adapters.libreWolf = { + type = "executable", + command = "node", + args = { masonPkg .. "/firefox-debug-adapter/dist/adapter.bundle.js" }, + } + adapters["pwa-node"] = { + type = "server", + host = "localhost", + port = "${port}", + executable = { + command = "node", + args = { masonPkg .. "/js-debug-adapter/js-debug/src/dapDebugServer.js", "8123" }, + }, + } + + --- @type Configuration[] + local browserConfigs = { + { + name = "LibreWolf attach", + type = "libreWolf", + request = "attach", + url = "http://localhost:4000", + webRoot = "${workspaceFolder}", + }, + { + name = "Chrome attach", + type = "pwa-chrome", + request = "attach", + cwd = "${workspaceFolder}", + }, + } + + --- @type Configuration[] + local nodeConfigs = { + { + name = "Node attach", + type = "pwa-node", + request = "attach", + processId = pick_process, + cwd = "${workspaceFolder}", + }, + { + name = "Node launch", + type = "pwa-node", + request = "launch", + program = "${file}", + cwd = "${workspaceFolder}", + port = "8123", + }, + } + + dapConfigure({ "typescriptreact", "javascriptreact" }, browserConfigs) + dapConfigure({ "typescript", "javascript" }, vim.tbl_extend("force", browserConfigs, nodeConfigs)) + + -- Java + configurations.java = { + { + name = "Debug (Attach) - Remote", + type = "java", + request = "attach", + hostName = "127.0.0.1", + port = 9009, + }, + } + end, +} diff --git a/home/.config/nvim/lua/plugins/nvim-tree.lua b/home/.config/nvim/lua/plugins/nvim-tree.lua new file mode 100644 index 00000000..fb185398 --- /dev/null +++ b/home/.config/nvim/lua/plugins/nvim-tree.lua @@ -0,0 +1,25 @@ +-- Tree explorer +--- @type LazyPluginSpec +return { + "kyazdani42/nvim-tree.lua", + dependencies = { "kyazdani42/nvim-web-devicons" }, + opts = { + diagnostics = { + enable = true, + show_on_dirs = true, + }, + renderer = { + highlight_git = true, + }, + update_focused_file = { + enable = true, + }, + }, + keys = { + { + desc = "Open/close nvim-tree", + "o", + "NvimTreeToggle", + }, + }, +} diff --git a/home/.config/nvim/lua/plugins/redact_pass.lua b/home/.config/nvim/lua/plugins/redact_pass.lua new file mode 100644 index 00000000..984de136 --- /dev/null +++ b/home/.config/nvim/lua/plugins/redact_pass.lua @@ -0,0 +1,8 @@ +-- Make editing passwords safer +--- @type LazyPluginSpec +return { + "https://git.zx2c4.com/password-store", + config = function(plugin) + vim.opt.rtp:append(plugin.dir .. "contrib/vim/redact_pass.vim") + end, +} diff --git a/home/.config/nvim/lua/plugins/statuscol.lua b/home/.config/nvim/lua/plugins/statuscol.lua new file mode 100644 index 00000000..c8890013 --- /dev/null +++ b/home/.config/nvim/lua/plugins/statuscol.lua @@ -0,0 +1,16 @@ +-- Customize statuscolumn +--- @type LazyPluginSpec +return { + "luukvbaal/statuscol.nvim", + config = function() + local builtin = require("statuscol.builtin") + require("statuscol").setup({ + relculright = true, + segments = { + { text = { builtin.foldfunc }, click = "v:lua.ScFa" }, + { text = { "%s" }, click = "v:lua.ScSa" }, + { text = { builtin.lnumfunc, " " }, click = "v:lua.ScLa" }, + }, + }) + end, +} diff --git a/home/.config/nvim/lua/plugins/suda.lua b/home/.config/nvim/lua/plugins/suda.lua new file mode 100644 index 00000000..e02bd3ae --- /dev/null +++ b/home/.config/nvim/lua/plugins/suda.lua @@ -0,0 +1,3 @@ +-- Do stuff as sudo +--- @type LazyPluginSpec +return { "lambdalisue/suda.vim" } diff --git a/home/.config/nvim/lua/plugins/telescope.lua b/home/.config/nvim/lua/plugins/telescope.lua new file mode 100644 index 00000000..0a8435a9 --- /dev/null +++ b/home/.config/nvim/lua/plugins/telescope.lua @@ -0,0 +1,107 @@ +--- @type LazyPluginSpec +return { + "nvim-telescope/telescope.nvim", + dependencies = { + -- Internal dependency for telescope + "nvim-lua/plenary.nvim", + + -- Use fzf for fuzzy finder + { + "nvim-telescope/telescope-fzf-native.nvim", + build = "make", + }, + + -- Replace vim built in select with telescope + "nvim-telescope/telescope-ui-select.nvim", + + -- cd plugin for telescope + "zane-/cder.nvim", + + -- project plugin for telescope + "nvim-telescope/telescope-project.nvim", + }, + opts = { + -- Set layout to vertical + defaults = { + layout_strategy = "flex", + layout_config = { + flex = { + flip_columns = 200, + }, + }, + }, + pickers = { + find_files = { find_command = { "fd", "-Ht", "f" } }, + lsp_references = { show_line = false }, + live_grep = { + additional_args = function() + return { "--hidden" } + end, + }, + }, + extensions = { + cder = { + previewer_command = "eza " + .. "-a " + .. "--color=always " + .. "-T " + .. "--level=3 " + .. "--icons " + .. "--git-ignore " + .. "--long " + .. "--no-permissions " + .. "--no-user " + .. "--no-filesize " + .. "--git " + .. "--ignore-glob=.git", + dir_command = { "fd", "-Ht", "d", ".", os.getenv("HOME") }, + }, + }, + }, + keys = function() + local telescope = require("telescope") + local builtin = require("telescope.builtin") + local extensions = telescope.extensions + + return { + { + desc = "Open Telescope", + "t", + function() + builtin.builtin({ include_extensions = true }) + end, + }, + { + desc = "Change directories", + "cd", + extensions.cder.cder, + }, + { + desc = "Find files", + "", + builtin.find_files, + }, + { + desc = "Grep files", + "", + builtin.live_grep, + }, + { + desc = "Open a project", + "p", + extensions.project.project, + }, + } + end, + config = function(_, opts) + local telescope = require("telescope") + telescope.setup(opts) + + -- Load extensions + telescope.load_extension("fzf") + telescope.load_extension("ui-select") + telescope.load_extension("cder") + telescope.load_extension("project") + telescope.load_extension("notify") + end, +} diff --git a/home/.config/nvim/lua/plugins/treesitter.lua b/home/.config/nvim/lua/plugins/treesitter.lua new file mode 100644 index 00000000..1c8d78c9 --- /dev/null +++ b/home/.config/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,153 @@ +return { + -- Improved syntax highlighting, text objects and more + --- @type LazyPluginSpec + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + init = function() + require("nvim-treesitter.install").update({ + with_sync = true, + }) + end, + --- @type TSConfig + opts = { + highlight = { enable = true }, + indent = { enable = true }, + ensure_installed = { + "bash", + "css", + "diff", + "dockerfile", + "git_config", + "git_rebase", + "gitattributes", + "gitcommit", + "gitignore", + "html", + "http", + "java", + "javascript", + "jsdoc", + "json", + "json5", + "jsonc", + "latex", + "lua", + "luadoc", + "luap", + "make", + "markdown", + "markdown_inline", + "php", + "python", + "query", + "rasi", + "regex", + "rst", + "scss", + "toml", + "tsx", + "typescript", + "vim", + "vimdoc", + "yaml", + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + scope_incremental = false, + node_decremental = "", + }, + }, + textobjects = { + move = { + enable = true, + goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer" }, + goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer" }, + goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer" }, + goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer" }, + }, + select = { + enable = true, + lookahead = true, + keymaps = { + ["af"] = { + query = "@function.outer", + desc = "Select outer part of a function", + }, + ["if"] = { + query = "@function.inner", + desc = "Select inner part of a function", + }, + ["ac"] = { + query = "@class.outer", + desc = "Select outer part of a class", + }, + ["ic"] = { + query = "@class.inner", + desc = "Select inner part of a class", + }, + ["as"] = { + query = "@scope", + query_group = "locals", + desc = "Select language scope", + }, + }, + }, + }, + }, + --- @param opts TSConfig + config = function(_, opts) + if type(opts.ensure_installed) == "table" then + --- @type table + local added = {} + opts.ensure_installed = vim.tbl_filter(function(lang) + if added[lang] then + return false + end + added[lang] = true + return true + end, opts.ensure_installed) + end + require("nvim-treesitter.configs").setup(opts) + end, + dependencies = { + { + "nvim-treesitter/nvim-treesitter-textobjects", + config = function() + -- When in diff mode, we want to use the default + -- vim text objects c & C instead of the treesitter ones. + --- @type table + local move = require("nvim-treesitter.textobjects.move") + local configs = require("nvim-treesitter.configs") + for name, fn in pairs(move) do + if name:find("goto") == 1 then + move[name] = function(q, ...) + if vim.wo.diff then + --- @type table + local config = configs.get_module("textobjects.move")[name] + for key, query in pairs(config or {}) do + if q == query and key:find("[%]%[][cC]") then + vim.cmd("normal! " .. key) + return + end + end + end + return fn(q, ...) + end + end + end + end, + }, + }, + }, + + -- Automatically add closing tags for HTML and JSX + --- @type LazyPluginSpec + { + "windwp/nvim-ts-autotag", + config = true, + }, +} diff --git a/home/.config/nvim/lua/plugins/ufo.lua b/home/.config/nvim/lua/plugins/ufo.lua new file mode 100644 index 00000000..9615f83c --- /dev/null +++ b/home/.config/nvim/lua/plugins/ufo.lua @@ -0,0 +1,28 @@ +-- Better folds +--- @type LazyPluginSpec +return { + "kevinhwang91/nvim-ufo", + dependencies = { "kevinhwang91/promise-async" }, + --- @type UfoConfig + opts = { + close_fold_kinds_for_ft = { + default = { "imports" }, + }, + }, + --- @param opts UfoConfig + config = function(_, opts) + local ufo = require("ufo") + ufo.setup(opts) + + -- Using ufo, we need to remap `zR` and `zM` + vim.keymap.set("n", "zR", ufo.openAllFolds) + vim.keymap.set("n", "zM", ufo.closeAllFolds) + + -- Fold settings + local o = vim.o + o.foldcolumn = "1" + o.foldlevel = 99 + o.foldlevelstart = 99 + o.foldenable = true + end, +} diff --git a/home/.config/nvim/lua/plugins/which-key.lua b/home/.config/nvim/lua/plugins/which-key.lua new file mode 100644 index 00000000..481adc15 --- /dev/null +++ b/home/.config/nvim/lua/plugins/which-key.lua @@ -0,0 +1,20 @@ +-- Display possible keybinds +--- @type LazyPluginSpec +return { + "folke/which-key.nvim", + config = function() + require("which-key").add({ + { "", group = "Leader" }, + { "g", group = "Go to" }, + }) + end, + keys = { + { + "?", + function() + require("which-key").show({ global = false }) + end, + desc = "Buffer Local Keymaps (which-key)", + }, + }, +} diff --git a/home/.config/nvim/lua/settings.lua b/home/.config/nvim/lua/settings.lua new file mode 100644 index 00000000..a02c5de0 --- /dev/null +++ b/home/.config/nvim/lua/settings.lua @@ -0,0 +1,53 @@ +local o = vim.o +local g = vim.g +o.pumblend = 10 + +-- Relative line numbers +o.number = true +o.relativenumber = true + +-- True colors +o.termguicolors = true + +-- Enable cursorline highlighting +o.cursorline = true + +-- Floating window transparency +o.winblend = 10 + +-- Set window title +o.title = true +o.titlestring = "NeoVim: " .. vim.fn.getcwd() + +-- Diff settings +o.diffopt = "filler,internal,algorithm:histogram,indent-heuristic" + +-- Allow switching buffers with unsaved changes +o.hidden = true + +o.guicursor = table.concat({ + "i:ver1", -- Vertical bar cursor in insert mode + "a:blinkon1", -- Blinking cursor in all modes +}, ",") + +-- Enable global statusline +o.laststatus = 3 + +-- Use suda by default +g.suda_smart_edit = 1 + +-- Case insensitive search +o.ignorecase = true +o.smartcase = true + +-- Set leader +g.mapleader = " " + +-- Indentation settings +o.tabstop = 4 +o.softtabstop = -1 +o.expandtab = true +o.shiftwidth = 4 +o.smartindent = true + +o.showmode = false diff --git a/home/.config/nvim/mason-lock.json b/home/.config/nvim/mason-lock.json new file mode 100644 index 00000000..18047f30 --- /dev/null +++ b/home/.config/nvim/mason-lock.json @@ -0,0 +1,21 @@ +{ + "bash-language-server": "5.4.0", + "css-lsp": "4.10.0", + "docker-compose-language-service": "0.2.0", + "dockerfile-language-server": "0.13.0", + "eslint-lsp": "4.10.0", + "google-java-format": "v1.23.0", + "html-lsp": "4.10.0", + "java-debug-adapter": "0.58.0", + "jdtls": "v1.38.0", + "json-lsp": "4.10.0", + "lemminx": "0.27.1", + "lua-language-server": "3.10.5", + "prettier": "3.3.3", + "prettierd": "0.25.3", + "stylua": "v0.20.0", + "taplo": "0.9.3", + "tree-sitter-cli": "v0.22.6", + "typescript-language-server": "4.3.3", + "yaml-language-server": "1.15.0" +} diff --git a/home/.config/nvim/snippets/java.json b/home/.config/nvim/snippets/java.json new file mode 100644 index 00000000..6ab73774 --- /dev/null +++ b/home/.config/nvim/snippets/java.json @@ -0,0 +1,14 @@ +{ + "queryListFromModel": { + "scope": "java", + "description": "Create a method to get a List from the database (Rossum JpaBaseDAO)", + "prefix": "queryListFromModel", + "body": [ + "public List<$1> $2($3) {", + " return queryFromModelObject()", + " .where((cb, root) -> $0)", + " .results();", + "}" + ] + } +} diff --git a/home/.config/nvim/snippets/package.json b/home/.config/nvim/snippets/package.json new file mode 100644 index 00000000..70b1949d --- /dev/null +++ b/home/.config/nvim/snippets/package.json @@ -0,0 +1,14 @@ +{ + "name": "functionalhacker-snippets", + "engines": { + "vscode": "^1.11.0" + }, + "contributes": { + "snippets": [ + { + "language": "java", + "path": "./java.json" + } + ] + } +} diff --git a/users/functionalhacker/home.nix b/users/functionalhacker/home.nix index 5934169a..a0d6310c 100644 --- a/users/functionalhacker/home.nix +++ b/users/functionalhacker/home.nix @@ -1,14 +1,28 @@ -{ lib, pkgs, ... }: +{ config, lib, pkgs, ... }: { + programs.neovim = { + enable = true; + defaultEditor = true; + }; + home = { username = "functionalhacker"; homeDirectory = "/home/functionalhacker"; stateVersion = "24.05"; + file.".config/nvim".source = + config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/git/dotfiles/home/.config/nvim"; + packages = with pkgs; [ - neofetch + cargo + fzf + gcc + nerdfonts + nodejs pass + tree-sitter + yarn zsh ]; };