diff --git a/AmazonQ.md b/AmazonQ.md new file mode 100644 index 0000000..8d9ac84 --- /dev/null +++ b/AmazonQ.md @@ -0,0 +1,35 @@ +# Neovim Configuration Debugging + +## Issues Fixed + +1. **Noice.nvim Plugin Error** + - Problem: Error in `noice.nvim/lua/noice/util/lazy.lua:13: attempt to index field 'loaded' (a nil value)` + - Solution: Created a custom configuration for noice.nvim with proper error handling and dependencies + +2. **CSS Language Server Errors** + - Problem: Multiple "MethodNotFound" errors for "workspace/diagnostic/refresh" + - Solution: Added a custom handler to the cssls configuration to properly handle this method + +3. **LSP Configuration Error** + - Problem: "Setup `require(\"neoconf\").setup()` should be run **BEFORE** setting up any lsp server with lspconfig" + - Solution: Added neoconf.nvim and neodev.nvim as dependencies with proper configuration + +## Configuration Changes + +1. Created `/Users/iforster/myenv/neovim/.config/nvim/lua/iforster/plugins/noice.lua` with proper initialization and error handling +2. Modified `/Users/iforster/myenv/neovim/.config/nvim/lua/iforster/plugins/lsp/lspconfig.lua` to add a handler for the CSS language server +3. Updated `/Users/iforster/myenv/neovim/.config/nvim/lua/iforster/plugins/lsp/init.lua` to ensure proper loading order +4. Added neoconf.nvim and neodev.nvim as dependencies to lspconfig.lua with proper configuration + +## Next Steps + +1. Restart Neovim to test the changes +2. Run `:checkhealth` to verify all plugins are working correctly +3. If issues persist, check the logs again at `~/.local/state/nvim/log` and `~/.local/state/nvim/lsp.log` + +## Additional Recommendations + +1. Consider updating plugins with `:Lazy update` to ensure you have the latest versions +2. If you encounter issues with specific language servers, try reinstalling them with `:Mason` +3. For persistent issues with noice.nvim, consider temporarily disabling it to isolate other problems +4. Consider installing the Python neovim module with `pip install neovim` to resolve Python provider warnings diff --git a/lua/iforster/core/init.lua b/lua/iforster/core/init.lua index 5bba394..867e387 100644 --- a/lua/iforster/core/init.lua +++ b/lua/iforster/core/init.lua @@ -1,4 +1,4 @@ -require("iforster.core.fonts") require("iforster.core.options") +require("iforster.core.fonts") require("iforster.core.keymaps") --require("iforster.core.colorscheme") diff --git a/lua/iforster/core/keymaps.lua b/lua/iforster/core/keymaps.lua index 7b7520c..576bf5c 100644 --- a/lua/iforster/core/keymaps.lua +++ b/lua/iforster/core/keymaps.lua @@ -5,7 +5,7 @@ local keymap = vim.keymap -- for consiceness -- general keymaps -keymap.set("i", "jk", "") +keymap.set("i", "jk", "", { desc = "Exit insert mode with jk" }) keymap.set("n", "nh", ":nohl") diff --git a/lua/iforster/core/options.lua b/lua/iforster/core/options.lua index 1c89c42..49a7179 100644 --- a/lua/iforster/core/options.lua +++ b/lua/iforster/core/options.lua @@ -1,38 +1,41 @@ -local opt = vim.opt -- for conciseness +vim.cmd("let g:netrw_liststyle = 3") + +local opt = vim.opt + +vim.cmd("let g:netrw_liststyle = 3") --- line numbers opt.relativenumber = true opt.number = true --- tabs & indentation -opt.tabstop = 2 -opt.shiftwidth = 2 -opt.expandtab = true -opt.autoindent = true +-- tab & indentation +opt.tabstop = 2 -- 2 spaces for tabs (prettier default) +opt.shiftwidth = 2 -- 2 spaces for shiftwidth +opt.expandtab = true -- expand tab to spaces +opt.autoindent = true -- copy indent from current line when starting a new one --- line wrapping opt.wrap = false -- search settings -opt.ignorecase = true -opt.smartcase = true +opt.ignorecase = true --ignore case when searching +opt.smartcase = true -- if you use mixed case in search, assumes you want case insensitive search --- cursor line opt.cursorline = true --- appearance +-- turn on termguicolors for tokyonight colorscheme to work +-- (have to use iterm2 or any other true color terminal) opt.termguicolors = true -opt.background = "dark" -opt.signcolumn = "yes" +opt.background = "dark" -- colorschemes that can be light or dark will be made dark +opt.signcolumn = "yes" -- show sign column so that text doesn't shift -- backspace -opt.backspace = "indent,eol,start" +opt.backspace = "indent,eol,start" -- allow backspace on indent, end of line or insert mode start position -- clipboard -opt.clipboard:append("unnamedplus") +opt.clipboard:append("unnamedplus") -- use system clipboard as default register -- split windows -opt.splitright = true -opt.splitbelow = true +opt.splitright = true -- split vertical window to the right +opt.splitbelow = true -- split horizontal window to the bottom -opt.iskeyword:append("-") +-- turn off swapfile +opt.swapfile = false diff --git a/lua/iforster/lazy.lua b/lua/iforster/lazy.lua index 1b5ebfe..947790c 100644 --- a/lua/iforster/lazy.lua +++ b/lua/iforster/lazy.lua @@ -1,35 +1,21 @@ 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, - }) + 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("lazy").setup({ - spec = { - -- add LazyVim and import its plugins - { "LazyVim/LazyVim", import = "lazyvim.plugins" }, - { import = "iforster.plugins" }, - { import = "iforster.plugins.lsp" }, - }, - - -- import any extras modules here - -- { import = "lazyvim.plugins.extras.lang.typescript" }, - -- { import = "lazyvim.plugins.extras.lang.json" }, - -- { import = "lazyvim.plugins.extras.ui.mini-animate" }, - -- import/override with your plugins -}, { - checker = { - enabled = true, - notify = false, - }, - change_detection = { - notify = false, - }, +require("lazy").setup({ { import = "iforster.plugins" }, { import = "iforster.plugins.lsp" } }, { checker = { + enabled = true, + notify = false, + }, + change_detection = { + notify = false, + }, }) diff --git a/lua/iforster/plugins/alpha.lua b/lua/iforster/plugins/alpha.lua new file mode 100644 index 0000000..eaf1dba --- /dev/null +++ b/lua/iforster/plugins/alpha.lua @@ -0,0 +1,54 @@ +return { + "goolord/alpha-nvim", + lazy = false, + dependencies = { "nvim-tree/nvim-web-devicons" }, + opts = function() + local dashboard = require("alpha.themes.dashboard") + + -- Custom header (ASCII art) + dashboard.section.header.val = { + " ██╗ █████╗ ███████╗██╗ ██╗██╗ ██╗██╗███╗ ███╗ Z", + " ██║ ██╔══██╗╚══███╔╝╚██╗ ██╔╝██║ ██║██║████╗ ████║ Z ", + " ██║ ███████║ ███╔╝ ╚████╔╝ ██║ ██║██║██╔████╔██║ z ", + " ██║ ██╔══██║ ███╔╝ ╚██╔╝ ╚██╗ ██╔╝██║██║╚██╔╝██║ z ", + " ███████╗██║ ██║███████╗ ██║ ╚████╔╝ ██║██║ ╚═╝ ██║ ", + " ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ ", + " Customized by Ian Forster", + } + + -- Buttons (center actions) + dashboard.section.buttons.val = { + dashboard.button("SPC ff", "󰱼 Find File", "Telescope find_files"), + dashboard.button("n", " New File", ":ene | startinsert "), + dashboard.button("r", " Recent Files", ":Telescope oldfiles "), + dashboard.button("g", " Find Text", ":Telescope live_grep "), + dashboard.button("s", " Restore Session", ":lua require('persistence').load()"), + dashboard.button("x", " Lazy Extras", ":LazyExtras "), + dashboard.button("l", "󰒲 Lazy", ":Lazy "), + dashboard.button("q", " Quit", ":qa"), + } + + -- Footer with plugin stats + dashboard.section.footer.val = function() + local stats = require("lazy").stats() + local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100) + return { "⚡ Neovim loaded " .. stats.loaded .. "/" .. stats.count .. " plugins in " .. ms .. "ms" } + end + + dashboard.opts.layout[1].val = 8 -- Top padding (similar to `string.rep("\n", 8)`) + + vim.api.nvim_create_autocmd("User", { + pattern = "AlphaReady", + callback = function() + if vim.o.filetype == "lazy" then + vim.cmd.close() + vim.schedule(function() + require("lazy").show() + end) + end + end, + }) + + return dashboard.opts + end, +} diff --git a/lua/iforster/plugins/auto-session.lua b/lua/iforster/plugins/auto-session.lua new file mode 100644 index 0000000..adeff79 --- /dev/null +++ b/lua/iforster/plugins/auto-session.lua @@ -0,0 +1,16 @@ +return { + "rmagatti/auto-session", + config = function() + local auto_session = require("auto-session") + + auto_session.setup({ + auto_restore_enabled = false, + auto_session_suppress_dirs = { "~/", "~/Dev/", "~/Downloads", "~/Documents", "~/Desktop/" }, + }) + + local keymap = vim.keymap + + keymap.set("n", "wr", "SessionRestore", { desc = "Restore session for cwd" }) -- restore last workspace session for current directory + keymap.set("n", "ws", "SessionSave", { desc = "Save session for auto session root dir" }) -- save workspace session for current working directory + end, +} diff --git a/lua/iforster/plugins/autopairs.lua b/lua/iforster/plugins/autopairs.lua index 58429aa..e22b7db 100644 --- a/lua/iforster/plugins/autopairs.lua +++ b/lua/iforster/plugins/autopairs.lua @@ -1,31 +1,31 @@ return { - "windwp/nvim-autopairs", - "hrsh7th/nvim-cmp", - event = { "InsertEnter" }, - dependencies = { - "hrsh7th/nvim-cmp", - }, - config = function() - --import nvim-autopairs - local autopairs = require("nvim-autopairs") + "windwp/nvim-autopairs", + event = { "InsertEnter" }, + dependencies = { + "hrsh7th/nvim-cmp", + }, + config = function() + -- import nvim-autopairs + local autopairs = require("nvim-autopairs") - -- configure autopairs - autopairs.setup({ - check_ts = true, -- enable treesitter - ts_config = { - lua = { "string" }, -- don't add pairs in lua string treesitter nodes - javascript = { "template_string" }, -- don't add pairs in javscript template_string treesitter nodes - java = false, -- don't check treesitter on java - }, - }) + -- configure autopairs + autopairs.setup({ + check_ts = true, -- enable treesitter + ts_config = { + lua = { "string" }, -- don't add pairs in lua string treesitter nodes + javascript = { "template_string" }, -- don't add pairs in javscript template_string treesitter nodes + java = false, -- don't check treesitter on java + }, + }) - -- import nvim-autopairs completion functionality - local cmp_autopairs = require("nvim-autopairs.completion.cmp") + -- import nvim-autopairs completion functionality + local cmp_autopairs = require("nvim-autopairs.completion.cmp") - -- import nvim-cmp plugin (completions plugin) - local cmp = require("cmp") + -- import nvim-cmp plugin (completions plugin) + local cmp = require("cmp") - -- make autopairs and completion work together - cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done()) - end, + -- make autopairs and completion work together + cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done()) + end, } + diff --git a/lua/iforster/plugins/bufferline.lua b/lua/iforster/plugins/bufferline.lua new file mode 100644 index 0000000..7e1a826 --- /dev/null +++ b/lua/iforster/plugins/bufferline.lua @@ -0,0 +1,10 @@ +return { + "akinsho/bufferline.nvim", + dependencies = { "nvim-tree/nvim-web-devicons" }, + version = "*", + opts = { + options = { + mode = "tabs", + }, + }, +} diff --git a/lua/iforster/plugins/colorscheme.lua b/lua/iforster/plugins/colorscheme.lua new file mode 100644 index 0000000..21d6c48 --- /dev/null +++ b/lua/iforster/plugins/colorscheme.lua @@ -0,0 +1,45 @@ +return { + "folke/tokyonight.nvim", + priority = 1000, + config = function() + local transparent = false -- set to true if you would like to enable transparency + + local bg = "#011628" + local bg_dark = "#011423" + local bg_highlight = "#143652" + local bg_search = "#0A64AC" + local bg_visual = "#275378" + local fg = "#CBE0F0" + local fg_dark = "#B4D0E9" + local fg_gutter = "#627E97" + local border = "#547998" + + require("tokyonight").setup({ + style = "night", + transparent = transparent, + styles = { + sidebars = transparent and "transparent" or "dark", + floats = transparent and "transparent" or "dark", + }, + on_colors = function(colors) + colors.bg = bg + colors.bg_dark = transparent and colors.none or bg_dark + colors.bg_float = transparent and colors.none or bg_dark + colors.bg_highlight = bg_highlight + colors.bg_popup = bg_dark + colors.bg_search = bg_search + colors.bg_sidebar = transparent and colors.none or bg_dark + colors.bg_statusline = transparent and colors.none or bg_dark + colors.bg_visual = bg_visual + colors.border = border + colors.fg = fg + colors.fg_dark = fg_dark + colors.fg_float = fg + colors.fg_gutter = fg_gutter + colors.fg_sidebar = fg_dark + end, + }) + + vim.cmd("colorscheme tokyonight") + end, +} diff --git a/lua/iforster/plugins/comment.lua b/lua/iforster/plugins/comment.lua new file mode 100644 index 0000000..ecc93c4 --- /dev/null +++ b/lua/iforster/plugins/comment.lua @@ -0,0 +1,19 @@ +return { + "numToStr/Comment.nvim", + event = { "BufReadPre", "BufNewFile" }, + dependencies = { + "JoosepAlviste/nvim-ts-context-commentstring", + }, + config = function() + -- import comment plugin safely + local comment = require("Comment") + + local ts_context_commentstring = require("ts_context_commentstring.integrations.comment_nvim") + + -- enable comment + comment.setup({ + -- for commenting tsx, jsx, svelte, html files + pre_hook = ts_context_commentstring.create_pre_hook(), + }) + end, +} diff --git a/lua/iforster/plugins/core.lua b/lua/iforster/plugins/core.lua index 19d97fa..1658f53 100644 --- a/lua/iforster/plugins/core.lua +++ b/lua/iforster/plugins/core.lua @@ -1,4 +1,4 @@ return { - { "folke/lazy.nvim", version = false }, - { "LazyVim/LazyVim", version = false }, + { "folke/lazy.nvim", version = false }, + { "LazyVim/LazyVim", version = false }, } diff --git a/lua/iforster/plugins/dressing.lua b/lua/iforster/plugins/dressing.lua new file mode 100644 index 0000000..105f7e5 --- /dev/null +++ b/lua/iforster/plugins/dressing.lua @@ -0,0 +1,4 @@ +return { + "stevearc/dressing.nvim", + event = "VeryLazy", +} diff --git a/lua/iforster/plugins/formatting.lua b/lua/iforster/plugins/formatting.lua new file mode 100644 index 0000000..711abc4 --- /dev/null +++ b/lua/iforster/plugins/formatting.lua @@ -0,0 +1,41 @@ +return { + "stevearc/conform.nvim", + event = { "BufReadPre", "BufNewFile" }, + config = function() + local conform = require("conform") + + conform.setup({ + formatters_by_ft = { + javascript = { "prettier" }, + typescript = { "prettier" }, + javascriptreact = { "prettier" }, + typescriptreact = { "prettier" }, + svelte = { "prettier" }, + css = { "prettier" }, + go = { "goimports", "gofmt" }, + html = { "prettier" }, + java = { "google-java-format" }, + json = { "prettier" }, + yaml = { "prettier" }, + markdown = { "prettier" }, + graphql = { "prettier" }, + liquid = { "prettier" }, + lua = { "stylua" }, + python = { "isort", "black" }, + }, + format_on_save = { + lsp_fallback = true, + async = false, + timeout_ms = 1000, + }, + }) + + vim.keymap.set({ "n", "v" }, "mp", function() + conform.format({ + lsp_fallback = true, + async = false, + timeout_ms = 1000, + }) + end, { desc = "Format file or range (in visual mode)" }) + end, +} diff --git a/lua/iforster/plugins/gitsigns.lua b/lua/iforster/plugins/gitsigns.lua index 9d99114..7daca01 100644 --- a/lua/iforster/plugins/gitsigns.lua +++ b/lua/iforster/plugins/gitsigns.lua @@ -1,39 +1,47 @@ return { - { - "lewis6991/gitsigns.nvim", - event = "LazyFile", - opts = { - signs = { - add = { text = "+" }, - change = { text = "~" }, - delete = { text = "_" }, - topdelete = { text = "‾" }, - changedelete = { text = "~" }, - untracked = { text = "▎" }, - }, - on_attach = function(buffer) - local gs = package.loaded.gitsigns - - local function map(mode, l, r, desc) - vim.keymap.set(mode, l, r, { buffer = buffer, desc = desc }) - end - - -- stylua: ignore start - map("n", "]h", function() gs.nav_hunk("next") end, "Next Hunk") - map("n", "[h", function() gs.nav_hunk("prev") end, "Prev Hunk") - map("n", "]H", function() gs.nav_hunk("last") end, "Last Hunk") - map("n", "[H", function() gs.nav_hunk("first") end, "First Hunk") - map({ "n", "v" }, "ghs", ":Gitsigns stage_hunk", "Stage Hunk") - map({ "n", "v" }, "ghr", ":Gitsigns reset_hunk", "Reset Hunk") - map("n", "ghS", gs.stage_buffer, "Stage Buffer") - map("n", "ghu", gs.undo_stage_hunk, "Undo Stage Hunk") - map("n", "ghR", gs.reset_buffer, "Reset Buffer") - map("n", "ghp", gs.preview_hunk_inline, "Preview Hunk Inline") - map("n", "ghb", function() gs.blame_line({ full = true }) end, "Blame Line") - map("n", "ghd", gs.diffthis, "Diff This") - map("n", "ghD", function() gs.diffthis("~") end, "Diff This ~") - map({ "o", "x" }, "ih", ":Gitsigns select_hunk", "GitSigns Select Hunk") - end, - }, - }, + "lewis6991/gitsigns.nvim", + event = { "BufReadPre", "BufNewFile" }, + opts = { + on_attach = function(bufnr) + local gs = package.loaded.gitsigns + + local function map(mode, l, r, desc) + vim.keymap.set(mode, l, r, { buffer = bufnr, desc = desc }) + end + + -- Navigation + map("n", "]h", gs.next_hunk, "Next Hunk") + map("n", "[h", gs.prev_hunk, "Prev Hunk") + + -- Actions + map("n", "hs", gs.stage_hunk, "Stage hunk") + map("n", "hr", gs.reset_hunk, "Reset hunk") + map("v", "hs", function() + gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) + end, "Stage hunk") + map("v", "hr", function() + gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) + end, "Reset hunk") + + map("n", "hS", gs.stage_buffer, "Stage buffer") + map("n", "hR", gs.reset_buffer, "Reset buffer") + + map("n", "hu", gs.undo_stage_hunk, "Undo stage hunk") + + map("n", "hp", gs.preview_hunk, "Preview hunk") + + map("n", "hb", function() + gs.blame_line({ full = true }) + end, "Blame line") + map("n", "hB", gs.toggle_current_line_blame, "Toggle line blame") + + map("n", "hd", gs.diffthis, "Diff this") + map("n", "hD", function() + gs.diffthis("~") + end, "Diff this ~") + + -- Text object + map({ "o", "x" }, "ih", ":Gitsigns select_hunk", "Gitsigns select hunk") + end, + }, } diff --git a/lua/iforster/plugins/indent-blankline.lua b/lua/iforster/plugins/indent-blankline.lua new file mode 100644 index 0000000..572e0bd --- /dev/null +++ b/lua/iforster/plugins/indent-blankline.lua @@ -0,0 +1,8 @@ +return { + "lukas-reineke/indent-blankline.nvim", + event = { "BufReadPre", "BufNewFile" }, + main = "ibl", + opts = { + indent = { char = "┊" }, + }, +} diff --git a/lua/iforster/plugins/init.lua b/lua/iforster/plugins/init.lua index b22f6fb..a885d95 100644 --- a/lua/iforster/plugins/init.lua +++ b/lua/iforster/plugins/init.lua @@ -1,4 +1,4 @@ return { - "nvim-lua/plenary.nvim", -- lua functions that many plugins use - "christoomey/vim-tmux-navigator", -- tmux & split window navigation + "nvim-lua/plenary.nvim", -- lua functions that many plugins use + "christoomey/vim-tmux-navigator", -- tmux & split window navigation } diff --git a/lua/iforster/plugins/linting.lua b/lua/iforster/plugins/linting.lua new file mode 100644 index 0000000..e9fea9b --- /dev/null +++ b/lua/iforster/plugins/linting.lua @@ -0,0 +1,29 @@ +return { + "mfussenegger/nvim-lint", + event = { "BufReadPre", "BufNewFile" }, + config = function() + local lint = require("lint") + + lint.linters_by_ft = { + javascript = { "eslint_d" }, + typescript = { "eslint_d" }, + javascriptreact = { "eslint_d" }, + typescriptreact = { "eslint_d" }, + svelte = { "eslint_d" }, + python = { "pylint" }, + } + + local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true }) + + vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, { + group = lint_augroup, + callback = function() + lint.try_lint() + end, + }) + + vim.keymap.set("n", "l", function() + lint.try_lint() + end, { desc = "Trigger linting for current file" }) + end, +} diff --git a/lua/iforster/plugins/lsp/lspconfig.lua b/lua/iforster/plugins/lsp/lspconfig.lua index ff9b96b..145dc93 100644 --- a/lua/iforster/plugins/lsp/lspconfig.lua +++ b/lua/iforster/plugins/lsp/lspconfig.lua @@ -1,160 +1,146 @@ return { - "neovim/nvim-lspconfig", - event = { "BufReadPre", "BufNewFile" }, - dependencies = { - "hrsh7th/cmp-nvim-lsp", - { "antosha417/nvim-lsp-file-operations", config = true }, - }, - config = function() - -- import lspconfig plugin - local lspconfig = require("lspconfig") - - -- import cmp-nvim-lsp plugin - local cmp_nvim_lsp = require("cmp_nvim_lsp") - - local keymap = vim.keymap -- for conciseness - - local opts = { noremap = true, silent = true } - local on_attach = function(client, bufnr) - opts.buffer = bufnr - - -- set keybinds - opts.desc = "Show LSP references" - keymap.set("n", "gR", "Telescope lsp_references", opts) -- show definition, references - - opts.desc = "Go to declaration" - keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- go to declaration - - opts.desc = "Show LSP definitions" - keymap.set("n", "gd", "Telescope lsp_definitions", opts) -- show lsp definitions - - opts.desc = "Show LSP implementations" - keymap.set("n", "gi", "Telescope lsp_implementations", opts) -- show lsp implementations - - opts.desc = "Show LSP type definitions" - keymap.set("n", "gt", "Telescope lsp_type_definitions", opts) -- show lsp type definitions - - opts.desc = "See available code actions" - keymap.set({ "n", "v" }, "ca", vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection - - opts.desc = "Smart rename" - keymap.set("n", "rn", vim.lsp.buf.rename, opts) -- smart rename - - opts.desc = "Show buffer diagnostics" - keymap.set("n", "D", "Telescope diagnostics bufnr=0", opts) -- show diagnostics for file - - opts.desc = "Show line diagnostics" - keymap.set("n", "d", vim.diagnostic.open_float, opts) -- show diagnostics for line - - opts.desc = "Go to previous diagnostic" - keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer - - opts.desc = "Go to next diagnostic" - keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer - - opts.desc = "Show documentation for what is under cursor" - keymap.set("n", "K", vim.lsp.buf.hover, opts) -- show documentation for what is under cursor - - opts.desc = "Restart LSP" - keymap.set("n", "rs", ":LspRestart", opts) -- mapping to restart lsp if necessary - end - - -- used to enable autocompletion (assign to every lsp server config) - local capabilities = cmp_nvim_lsp.default_capabilities() - - -- Change the Diagnostic symbols in the sign column (gutter) - local signs = { Error = " ", Warn = " ", Hint = "󰠠 ", Info = " " } - for type, icon in pairs(signs) do - local hl = "DiagnosticSign" .. type - vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" }) - end - - -- configure html server - lspconfig["html"].setup({ - capabilities = capabilities, - on_attach = on_attach, - }) - - -- configure typescript server with plugin - lspconfig["tsserver"].setup({ - capabilities = capabilities, - on_attach = on_attach, - }) - - -- configure css server - lspconfig["cssls"].setup({ - capabilities = capabilities, - on_attach = on_attach, - }) - - -- configure tailwindcss server - lspconfig["tailwindcss"].setup({ - capabilities = capabilities, - on_attach = on_attach, - }) - - -- configure svelte server - lspconfig["svelte"].setup({ - capabilities = capabilities, - on_attach = function(client, bufnr) - on_attach(client, bufnr) - - vim.api.nvim_create_autocmd("BufWritePost", { - pattern = { "*.js", "*.ts" }, - callback = function(ctx) - if client.name == "svelte" then - client.notify("$/onDidChangeTsOrJsFile", { uri = ctx.file }) - end - end, - }) - end, - }) - - -- configure prisma orm server - lspconfig["prismals"].setup({ - capabilities = capabilities, - on_attach = on_attach, - }) - - -- configure graphql language server - lspconfig["graphql"].setup({ - capabilities = capabilities, - on_attach = on_attach, - filetypes = { "graphql", "gql", "svelte", "typescriptreact", "javascriptreact" }, - }) - - -- configure emmet language server - lspconfig["emmet_ls"].setup({ - capabilities = capabilities, - on_attach = on_attach, - filetypes = { "html", "typescriptreact", "javascriptreact", "css", "sass", "scss", "less", "svelte" }, - }) - - -- configure python server - lspconfig["pyright"].setup({ - capabilities = capabilities, - on_attach = on_attach, - }) - - -- configure lua server (with special settings) - lspconfig["lua_ls"].setup({ - capabilities = capabilities, - on_attach = on_attach, - settings = { -- custom settings for lua - Lua = { - -- make the language server recognize "vim" global - diagnostics = { - globals = { "vim" }, - }, - workspace = { - -- make language server aware of runtime files - library = { - [vim.fn.expand("$VIMRUNTIME/lua")] = true, - [vim.fn.stdpath("config") .. "/lua"] = true, - }, - }, - }, - }, - }) - end, + "neovim/nvim-lspconfig", + event = { "BufReadPre", "BufNewFile" }, + dependencies = { + "hrsh7th/cmp-nvim-lsp", + { "antosha417/nvim-lsp-file-operations", config = true }, + { "folke/neodev.nvim", opts = {} }, + }, + config = function() + -- import lspconfig plugin + local lspconfig = require("lspconfig") + + -- import mason_lspconfig plugin + local mason_lspconfig = require("mason-lspconfig") + + -- import cmp-nvim-lsp plugin + local cmp_nvim_lsp = require("cmp_nvim_lsp") + + local keymap = vim.keymap -- for conciseness + + vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup("UserLspConfig", {}), + callback = function(ev) + -- Buffer local mappings. + -- See `:help vim.lsp.*` for documentation on any of the below functions + local opts = { buffer = ev.buf, silent = true } + + -- set keybinds + opts.desc = "Show LSP references" + keymap.set("n", "gR", "Telescope lsp_references", opts) -- show definition, references + + opts.desc = "Go to declaration" + keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- go to declaration + + opts.desc = "Show LSP definitions" + keymap.set("n", "gd", "Telescope lsp_definitions", opts) -- show lsp definitions + + opts.desc = "Show LSP implementations" + keymap.set("n", "gi", "Telescope lsp_implementations", opts) -- show lsp implementations + + opts.desc = "Show LSP type definitions" + keymap.set("n", "gt", "Telescope lsp_type_definitions", opts) -- show lsp type definitions + + opts.desc = "See available code actions" + keymap.set({ "n", "v" }, "ca", vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection + + opts.desc = "Smart rename" + keymap.set("n", "rn", vim.lsp.buf.rename, opts) -- smart rename + + opts.desc = "Show buffer diagnostics" + keymap.set("n", "D", "Telescope diagnostics bufnr=0", opts) -- show diagnostics for file + + opts.desc = "Show line diagnostics" + keymap.set("n", "d", vim.diagnostic.open_float, opts) -- show diagnostics for line + + opts.desc = "Go to previous diagnostic" + keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer + + opts.desc = "Go to next diagnostic" + keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer + + opts.desc = "Show documentation for what is under cursor" + keymap.set("n", "K", vim.lsp.buf.hover, opts) -- show documentation for what is under cursor + + opts.desc = "Restart LSP" + keymap.set("n", "rs", ":LspRestart", opts) -- mapping to restart lsp if necessary + end, + }) + + -- used to enable autocompletion (assign to every lsp server config) + local capabilities = cmp_nvim_lsp.default_capabilities() + + -- Change the Diagnostic symbols in the sign column (gutter) + -- (not in youtube nvim video) + local signs = { Error = " ", Warn = " ", Hint = "󰠠 ", Info = " " } + for type, icon in pairs(signs) do + local hl = "DiagnosticSign" .. type + vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" }) + end + + mason_lspconfig.setup_handlers({ + -- default handler for installed servers + function(server_name) + lspconfig[server_name].setup({ + capabilities = capabilities, + }) + end, + ["svelte"] = function() + -- configure svelte server + lspconfig["svelte"].setup({ + capabilities = capabilities, + on_attach = function(client, bufnr) + vim.api.nvim_create_autocmd("BufWritePost", { + pattern = { "*.js", "*.ts" }, + callback = function(ctx) + -- Here use ctx.match instead of ctx.file + client.notify("$/onDidChangeTsOrJsFile", { uri = ctx.match }) + end, + }) + end, + }) + end, + ["graphql"] = function() + -- configure graphql language server + lspconfig["graphql"].setup({ + capabilities = capabilities, + filetypes = { "graphql", "gql", "svelte", "typescriptreact", "javascriptreact" }, + }) + end, + ["emmet_ls"] = function() + -- configure emmet language server + lspconfig["emmet_ls"].setup({ + capabilities = capabilities, + filetypes = { + "html", + "typescriptreact", + "javascriptreact", + "gopls", + "css", + "sass", + "scss", + "less", + "svelte", + }, + }) + end, + ["lua_ls"] = function() + -- configure lua server (with special settings) + lspconfig["lua_ls"].setup({ + capabilities = capabilities, + settings = { + Lua = { + -- make the language server recognize "vim" global + diagnostics = { + globals = { "vim" }, + }, + completion = { + callSnippet = "Replace", + }, + }, + }, + }) + end, + }) + end, } diff --git a/lua/iforster/plugins/lsp/mason.lua b/lua/iforster/plugins/lsp/mason.lua index a6a8a82..75fef4b 100644 --- a/lua/iforster/plugins/lsp/mason.lua +++ b/lua/iforster/plugins/lsp/mason.lua @@ -3,13 +3,14 @@ return { dependencies = { "williamboman/mason-lspconfig.nvim", "WhoIsSethDaniel/mason-tool-installer.nvim", - "neovim/nvim-lspconfig", }, config = function() -- import mason local mason = require("mason") + + -- import mason-lspconfig local mason_lspconfig = require("mason-lspconfig") - local lspconfig = require("lspconfig") + local mason_tool_installer = require("mason-tool-installer") -- enable mason and configure icons @@ -26,10 +27,13 @@ return { mason_lspconfig.setup({ -- list of servers for mason to install ensure_installed = { - -- "tsserver", + "tsserver", "html", "cssls", "tailwindcss", + "java_language_server", + "go", + "python", "svelte", "lua_ls", "graphql", @@ -37,18 +41,8 @@ return { "prismals", "pyright", }, - -- auto-setup configured servers (with lspconfig) - automatic_installation = true, }) - -- This is the important part that was missing - -- After mason_lspconfig sets up the servers, we need to configure them - -- Using a simple setup without the automatic_enable feature - local servers = mason_lspconfig.get_installed_servers() - for _, server_name in ipairs(servers) do - lspconfig[server_name].setup({}) - end - mason_tool_installer.setup({ ensure_installed = { "prettier", -- prettier formatter diff --git a/lua/iforster/plugins/lualine.lua b/lua/iforster/plugins/lualine.lua index a2f42d1..3698644 100644 --- a/lua/iforster/plugins/lualine.lua +++ b/lua/iforster/plugins/lualine.lua @@ -1,49 +1,71 @@ return { - "nvim-lualine/lualine.nvim", - dependencies = { "nvim-tree/nvim-web-devicons" }, - config = function() - local lualine = require("lualine") - local lazy_status = require("lazy.status") -- to configure lazy pending updates count - -- - ---- get lualine nightfly theme - local lualine_nightfly = require("lualine.themes.nightfly") + "nvim-lualine/lualine.nvim", + dependencies = { "nvim-tree/nvim-web-devicons" }, + config = function() + local lualine = require("lualine") + local lazy_status = require("lazy.status") -- to configure lazy pending updates count - -- new colors for theme - local new_colors = { - blue = "#65D1FF", - green = "#3EFFDC", - violet = "#FF61EF", - yellow = "#FFDA7B", - black = "#000000", - } - -- change nightlfy theme colors - lualine_nightfly.normal.a.bg = new_colors.blue - lualine_nightfly.insert.a.bg = new_colors.green - lualine_nightfly.visual.a.bg = new_colors.violet - lualine_nightfly.command = { - a = { - gui = "bold", - bg = new_colors.yellow, - fg = new_colors.black, -- black - }, - } - -- configure lualine with modified theme - lualine.setup({ - options = { - theme = lualine_nightfly, - }, - sections = { - lualine_x = { - { - lazy_status.updates, - cond = lazy_status.has_updates, - color = { fg = "#ff9e64" }, - }, - { "encoding" }, - { "fileformat" }, - { "filetype" }, - }, - }, - }) - end, + local colors = { + blue = "#65D1FF", + green = "#3EFFDC", + violet = "#FF61EF", + yellow = "#FFDA7B", + red = "#FF4A4A", + fg = "#c3ccdc", + bg = "#112638", + inactive_bg = "#2c3043", + } + + local my_lualine_theme = { + normal = { + a = { bg = colors.blue, fg = colors.bg, gui = "bold" }, + b = { bg = colors.bg, fg = colors.fg }, + c = { bg = colors.bg, fg = colors.fg }, + }, + insert = { + a = { bg = colors.green, fg = colors.bg, gui = "bold" }, + b = { bg = colors.bg, fg = colors.fg }, + c = { bg = colors.bg, fg = colors.fg }, + }, + visual = { + a = { bg = colors.violet, fg = colors.bg, gui = "bold" }, + b = { bg = colors.bg, fg = colors.fg }, + c = { bg = colors.bg, fg = colors.fg }, + }, + command = { + a = { bg = colors.yellow, fg = colors.bg, gui = "bold" }, + b = { bg = colors.bg, fg = colors.fg }, + c = { bg = colors.bg, fg = colors.fg }, + }, + replace = { + a = { bg = colors.red, fg = colors.bg, gui = "bold" }, + b = { bg = colors.bg, fg = colors.fg }, + c = { bg = colors.bg, fg = colors.fg }, + }, + inactive = { + a = { bg = colors.inactive_bg, fg = colors.semilightgray, gui = "bold" }, + b = { bg = colors.inactive_bg, fg = colors.semilightgray }, + c = { bg = colors.inactive_bg, fg = colors.semilightgray }, + }, + } + + -- configure lualine with modified theme + lualine.setup({ + options = { + theme = my_lualine_theme, + }, + sections = { + lualine_x = { + { + lazy_status.updates, + cond = lazy_status.has_updates, + color = { fg = "#ff9e64" }, + }, + { "encoding" }, + { "fileformat" }, + { "filetype" }, + }, + }, + }) + end, } diff --git a/lua/iforster/plugins/nvim-cmp.lua b/lua/iforster/plugins/nvim-cmp.lua index 25908e7..0947011 100644 --- a/lua/iforster/plugins/nvim-cmp.lua +++ b/lua/iforster/plugins/nvim-cmp.lua @@ -1,68 +1,63 @@ return { - "hrsh7th/nvim-cmp", - event = "InsertEnter", - dependencies = { - "hrsh7th/cmp-buffer", -- source for text in buffer - "hrsh7th/cmp-path", -- source for file system paths - { - "L3MON4D3/LuaSnip", - -- follow latest release. - version = "v2.*", -- Replace by the latest released major (first number of latest release) - -- install jsregexp (optional!). - build = "make install_jsregexp", - }, - "saadparwaiz1/cmp_luasnip", -- for autocompletion - "rafamadriz/friendly-snippets", -- useful snippets - "onsails/lspkind.nvim", -- vs-code like pictograms - }, - config = function() - local cmp = require("cmp") - local luasnip = require("luasnip") - local lspkind = require("lspkind") + "hrsh7th/nvim-cmp", + event = "InsertEnter", + dependencies = { + "hrsh7th/cmp-buffer", -- source for text in buffer + "hrsh7th/cmp-path", -- source for file system paths + { + "L3MON4D3/LuaSnip", + -- follow latest release. + version = "v2.*", -- Replace by the latest released major (first number of latest release) + -- install jsregexp (optional!). + build = "make install_jsregexp", + }, + "saadparwaiz1/cmp_luasnip", -- for autocompletion + "rafamadriz/friendly-snippets", -- useful snippets + "onsails/lspkind.nvim", -- vs-code like pictograms + }, + config = function() + local cmp = require("cmp") - -- loads vscode style snippets from installed plugins (e.g. friendly-snippets) - require("luasnip.loaders.from_vscode").lazy_load() + local luasnip = require("luasnip") - cmp.setup({ - completion = { - completeopt = "menu,menuone,preview,noselect", - }, - snippet = { -- configure how nvim-cmp interacts with snippet engine - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - 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(), -- show completion suggestions - [""] = cmp.mapping.abort(), -- close completion window - [""] = cmp.mapping.confirm({ select = false }), - }), - -- sources for autocompletion - sources = cmp.config.sources({ - { name = "nvim_lsp" }, - { name = "luasnip" }, -- snippets - { name = "buffer" }, -- text within current buffer - { name = "path" }, -- file system paths - }), - -- Setup up vim-dadbod - cmp.setup.filetype({ "sql" }, { - sources = { - { name = "vim-dadbod-completion" }, - { name = "buffer" }, - }, - }), + local lspkind = require("lspkind") - -- configure lspkind for vs-code like pictograms in completion menu - formatting = { - format = lspkind.cmp_format({ - maxwidth = 50, - ellipsis_char = "...", - }), - }, - }) - end, + -- loads vscode style snippets from installed plugins (e.g. friendly-snippets) + require("luasnip.loaders.from_vscode").lazy_load() + + cmp.setup({ + completion = { + completeopt = "menu,menuone,preview,noselect", + }, + snippet = { -- configure how nvim-cmp interacts with snippet engine + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + 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(), -- show completion suggestions + [""] = cmp.mapping.abort(), -- close completion window + [""] = cmp.mapping.confirm({ select = false }), + }), + -- sources for autocompletion + sources = cmp.config.sources({ + { name = "nvim_lsp"}, + { name = "luasnip" }, -- snippets + { name = "buffer" }, -- text within current buffer + { name = "path" }, -- file system paths + }), + + -- configure lspkind for vs-code like pictograms in completion menu + formatting = { + format = lspkind.cmp_format({ + maxwidth = 50, + ellipsis_char = "...", + }), + }, + }) + end, } diff --git a/lua/iforster/plugins/nvim-tree.lua b/lua/iforster/plugins/nvim-tree.lua new file mode 100644 index 0000000..b2b9cc9 --- /dev/null +++ b/lua/iforster/plugins/nvim-tree.lua @@ -0,0 +1,56 @@ +return { + "nvim-tree/nvim-tree.lua", + dependencies = "nvim-tree/nvim-web-devicons", + config = function() + local nvimtree = require("nvim-tree") + + -- recommended settings from nvim-tree documentation + vim.g.loaded_netrw = 1 + vim.g.loaded_netrwPlugin = 1 + + nvimtree.setup({ + view = { + width = 35, + relativenumber = true, + }, + -- change folder arrow icons + renderer = { + indent_markers = { + enable = true, + }, + icons = { + glyphs = { + folder = { + arrow_closed = "", -- arrow when folder is closed + arrow_open = "", -- arrow when folder is open + }, + }, + }, + }, + -- disable window_picker for + -- explorer to work well with + -- window splits + actions = { + open_file = { + window_picker = { + enable = false, + }, + }, + }, + filters = { + custom = { ".DS_Store" }, + }, + git = { + ignore = false, + }, + }) + + -- set keymaps + local keymap = vim.keymap -- for conciseness + + keymap.set("n", "e", "NvimTreeToggle", { desc = "Toggle file explorer" }) -- toggle file explorer + keymap.set("n", "ef", "NvimTreeFindFileToggle", { desc = "Toggle file explorer on current file" }) -- toggle file explorer on current file + keymap.set("n", "ec", "NvimTreeCollapse", { desc = "Collapse file explorer" }) -- collapse file explorer + keymap.set("n", "er", "NvimTreeRefresh", { desc = "Refresh file explorer" }) -- refresh file explorer + end +} diff --git a/lua/iforster/plugins/substitute.lua b/lua/iforster/plugins/substitute.lua new file mode 100644 index 0000000..b5ff1b6 --- /dev/null +++ b/lua/iforster/plugins/substitute.lua @@ -0,0 +1,17 @@ +return { + "gbprod/substitute.nvim", + event = { "BufReadPre", "BufNewFile" }, + config = function() + local substitute = require("substitute") + + substitute.setup() + + -- set keymaps + local keymap = vim.keymap -- for conciseness + + keymap.set("n", "s", substitute.operator, { desc = "Substitute with motion" }) + keymap.set("n", "ss", substitute.line, { desc = "Substitute line" }) + keymap.set("n", "S", substitute.eol, { desc = "Substitute to end of line" }) + keymap.set("x", "s", substitute.visual, { desc = "Substitute in visual mode" }) + end, +} diff --git a/lua/iforster/plugins/surround.lua b/lua/iforster/plugins/surround.lua new file mode 100644 index 0000000..77f5073 --- /dev/null +++ b/lua/iforster/plugins/surround.lua @@ -0,0 +1,6 @@ +return { + "kylechui/nvim-surround", + event = { "BufReadPre", "BufNewFile" }, + version = "*", -- Use for stability; omit to use `main` branch for the latest features + config = true, +} diff --git a/lua/iforster/plugins/todo-comments.lua b/lua/iforster/plugins/todo-comments.lua new file mode 100644 index 0000000..f74baa9 --- /dev/null +++ b/lua/iforster/plugins/todo-comments.lua @@ -0,0 +1,21 @@ +return { + "folke/todo-comments.nvim", + event = { "BufReadPre", "BufNewFile" }, + dependencies = { "nvim-lua/plenary.nvim" }, + config = function() + local todo_comments = require("todo-comments") + + -- set keymaps + local keymap = vim.keymap -- for conciseness + + keymap.set("n", "]t", function() + todo_comments.jump_next() + end, { desc = "Next todo comment" }) + + keymap.set("n", "[t", function() + todo_comments.jump_prev() + end, { desc = "Previous todo comment" }) + + todo_comments.setup() + end, +} diff --git a/lua/iforster/plugins/toggerterm.lua b/lua/iforster/plugins/toggerterm.lua new file mode 100644 index 0000000..6f3f6f6 --- /dev/null +++ b/lua/iforster/plugins/toggerterm.lua @@ -0,0 +1,4 @@ +return { + -- {'akinsho/toggleterm.nvim', version = "*", config = true} + { "akinsho/toggleterm.nvim", version = "*", opts = {} }, +} diff --git a/lua/iforster/plugins/treesitter-context.lua b/lua/iforster/plugins/treesitter-context.lua deleted file mode 100644 index 35e565d..0000000 --- a/lua/iforster/plugins/treesitter-context.lua +++ /dev/null @@ -1,23 +0,0 @@ -return { - "nvim-treesitter/nvim-treesitter-context", - event = "BufReadPost", - config = function() - require("treesitter-context").setup({ - enable = true, - max_lines = 3, - trim_scope = "outer", - patterns = { - default = { - "class", - "function", - "method", - "for", - "while", - "if", - "switch", - "case", - }, - }, - }) - end, -} diff --git a/lua/iforster/plugins/treesitter.lua b/lua/iforster/plugins/treesitter.lua new file mode 100644 index 0000000..fbd5ed1 --- /dev/null +++ b/lua/iforster/plugins/treesitter.lua @@ -0,0 +1,59 @@ +return { + "nvim-treesitter/nvim-treesitter", + event = { "BufReadPre", "BufNewFile" }, + build = ":TSUpdate", + dependencies = { + "windwp/nvim-ts-autotag", + }, + config = function() + -- import nvim-treesitter plugin + local treesitter = require("nvim-treesitter.configs") + + -- configure treesitter + treesitter.setup({ -- enable syntax highlighting + highlight = { + enable = true, + }, + -- enable indentation + indent = { enable = true }, + -- enable autotagging (w/ nvim-ts-autotag plugin) + autotag = { + enable = true, + }, + -- ensure these language parsers are installed + ensure_installed = { + "json", + "javascript", + "typescript", + "tsx", + "yaml", + "html", + "css", + "java", + "go", + "prisma", + "markdown", + "markdown_inline", + "svelte", + "graphql", + "bash", + "lua", + "vim", + "dockerfile", + "gitignore", + "query", + "vimdoc", + "c", + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + scope_incremental = false, + node_decremental = "", + }, + }, + }) + end, +} diff --git a/lua/iforster/plugins/vim-maximizer.lua b/lua/iforster/plugins/vim-maximizer.lua new file mode 100644 index 0000000..869b8d7 --- /dev/null +++ b/lua/iforster/plugins/vim-maximizer.lua @@ -0,0 +1,6 @@ +return { + "szw/vim-maximizer", + keys = { + { "sm", "MaximizerToggle", desc = "Maximize/minimize a split" }, + }, +} diff --git a/lua/iforster/plugins/whichkey.lua b/lua/iforster/plugins/which-key.lua similarity index 100% rename from lua/iforster/plugins/whichkey.lua rename to lua/iforster/plugins/which-key.lua