vim.opt.termguicolors = true vim.g.mapleader = vim.keycode("") vim.g.maplocalleader = vim.keycode("") -- ---------------------------------------- -- SETTINGS -- ---------------------------------------- -- system vim.o.shell = "/usr/bin/bash" vim.o.fileencodings = "utf-8,ucs-bom,gb18030,gbk,gb2312,cp936" vim.o.fileformats = "unix" vim.o.swapfile = false vim.g.BASH_Ctrl_j = "off" vim.g.BASH_Ctrl_l = "off" -- TODO remove in commands -- undo vim.o.undolevels = 100000 vim.o.undoreload = 100000 -- buffer vim.o.hidden = true -- Enable background buffers vim.o.number = false vim.o.relativenumber = false vim.o.cursorline = false vim.o.switchbuf = "useopen" -- Use existing window if buffer is already open -- diffs vim.o.diffopt = "internal,filler,closeoff,hiddenoff,vertical,algorithm:patience" -- tabs vim.o.expandtab = true -- Use spaces instead of tabs vim.o.shiftround = true -- Round indent vim.o.tabstop = 4 -- Number of spaces tabs count for vim.o.shiftwidth = 4 -- Size of an indent vim.o.listchars = "tab:→ ,trail:·,extends:↷,precedes:↶,nbsp:+" vim.o.list = true -- Show listchars -- search vim.opt.smartcase = false vim.opt.ignorecase = false vim.opt.wildmode = { "full" } -- Command-line completion mode vim.opt.wildignore = vim.opt.wildignore + { "*swp", "*.class", "*.pyc", "*.png", "*.jpg", "*.gif", "*.zip", "*/tmp/*", "*.o", ".obj", "*.so" } -- folding vim.o.foldenable = true -- enable fold vim.o.foldlevel = 99 -- start editing with all folds opened vim.o.foldmethod = "expr" -- use tree-sitter for folding method vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()" -- cursor vim.o.scrolloff = 5 -- Lines of context vim.o.scrolljump = 1 -- Lines to scroll when cursor leaves screen vim.o.sidescrolloff = 4 -- Columns of context vim.o.showmatch = true -- Show matching brackets / parentheses -- editing vim.o.langmap = "å(,¨),ø:,æ^,+$" vim.opt.clipboard = vim.opt.clipboard + { "unnamedplus" } vim.opt.formatoptions = vim.opt.formatoptions - { "c", "r", "o" } vim.opt.iskeyword = vim.opt.iskeyword - { "." } vim.api.nvim_create_autocmd({ "BufReadPost" }, { pattern = { "quickfix" }, callback = function() vim.keymap.set("n", "", "", { buffer = true }) end, }) -- ---------------------------------------- -- MAPS -- ---------------------------------------- local map = vim.keymap.set map("n", "Q", "", { noremap = true }) map("n", "q:", "", { noremap = true }) map({ "n", "v" }, "", "", { silent = true }) map("n", "e", [[:vnew ~/dotfiles/nvim/init.lua]], { noremap = true }) map("n", "ww", [[:cd %:p:h]], { noremap = true }) map("n", "", "noh", { silent = true, noremap = true }) map("", "", "", { silent = true, noremap = true }) -- to navigate the completion menu map("i", "", [[pumvisible() ? "\" : "\"]], { expr = true, noremap = true }) map("i", "", [[pumvisible() ? "\" : "\"]], { expr = true, noremap = true }) vim.opt.pumheight = 0 -- CURSOR -- stay visual when indenting map({ "n", "v" }, "-", "_", { noremap = true }) map("v", "v", "", { noremap = true }) map("v", "", ">gv", { noremap = true }) map("v", "", "o", "m`o``", { noremap = true }) -- Insert a newline in normal mode -- better indenting map("v", "<", "", ">gv") -- repeat and next map("n", "\\", "n.", { noremap = true, silent = true }) -- WINDOWS / BUFFERS -- make splits and tabs map("n", "", "vnew", { noremap = true }) map("n", "", "new", { noremap = true }) map("n", "", "vsplit", { noremap = true }) map("n", "", "split", { noremap = true }) map("n", "", "tabe %", { noremap = true }) map("n", "", "tabnew", { noremap = true }) -- buffers and tabs map("n", "", "bprev", { noremap = true }) map("n", "", "bnext", { noremap = true }) map("n", "", "tabprev", { noremap = true }) map("n", "", "tabnext", { noremap = true }) -- resize windows with hjkl map("n", "", "5<", { noremap = true }) map("n", "", "5-", { noremap = true }) map("n", "", "5+", { noremap = true }) map("n", "", "5>", { noremap = true }) -- Move Lines map("v", "J", ":m '>+1gv=gv", { desc = "Move Down" }) map("v", "K", ":m '<-2gv=gv", { desc = "Move Up" }) -- quickfix window map("n", "", "lprev", { noremap = true }) map("n", "", "lnext", { noremap = true }) --- F keys map("n", "", "Lazy", { noremap = true }) map("n", "", "checkt", { noremap = true }) -- VISUALS vim.o.guicursor = "n-v-c:block-CustomCursor,i:ver100-CustomICursor,n-v-c:blinkon0,i:blinkwait10" -- https://codeyarns.com/tech/2011-07-29-vim-chart-of-color-names.html vim.api.nvim_create_autocmd("ColorScheme", { pattern = { "*" }, callback = function() vim.api.nvim_set_hl(0, "CustomCursor", { fg = "salmon1", bg = "cyan" }) vim.api.nvim_set_hl(0, "CustomICursor", { fg = "salmon1", bg = "cyan" }) vim.api.nvim_set_hl(0, "ColorColumn", { bg = "salmon4" }) end, }) -- ---------------------------------------- -- LSP -- ---------------------------------------- -- vim.lsp.set_log_level(1) vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("UserLspAttach", { clear = true }), callback = function(ev) vim.lsp.completion.enable(true, ev.data.client_id, ev.buf) local bmap = function(mode, keys, func) vim.keymap.set(mode, keys, func, { buffer = ev.buf, noremap = true }) end local diag = vim.diagnostic local severity = diag.severity.HINT -- workspaces bmap("n", "wa", vim.lsp.buf.add_workspace_folder) bmap("n", "wr", vim.lsp.buf.remove_workspace_folder) bmap("n", "wl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end) -- jump bmap("n", "", function() diag.open_float({ source = true }) end) bmap("n", "", function() diag.jump({ severity = { min = severity }, float = true, count = 1 }) end) bmap("n", "", function() diag.jump({ severity = { min = severity }, float = true, count = -1 }) end) bmap("n", "gd", vim.lsp.buf.definition) bmap("n", "gD", vim.lsp.buf.type_definition) bmap("n", "gi", vim.lsp.buf.declaration) bmap("n", "gI", vim.lsp.buf.implementation) -- quickfix bmap("n", "gl", diag.setloclist) bmap("n", "gr", vim.lsp.buf.references) -- popups bmap({ "n", "i" }, "", vim.lsp.buf.signature_help) -- other bmap("n", "K", vim.lsp.buf.hover) bmap("n", "", vim.lsp.buf.rename) bmap("n", "ca", vim.lsp.buf.code_action) -- NOTE: Using `assert` bypasses needing to do a nil check before accessing a member that could be nil local client = assert(vim.lsp.get_client_by_id(ev.data.client_id)) end, }) vim.api.nvim_create_user_command("LspStop", function(kwargs) local name = kwargs.fargs[1] for _, client in ipairs(vim.lsp.get_clients({ name = name })) do client:stop() end end, { nargs = "?", complete = function() return vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients()) end, }) vim.api.nvim_create_user_command("LspRestart", function(kwargs) local name = kwargs.fargs[1] for _, client in ipairs(vim.lsp.get_clients({ name = name })) do local bufs = vim.lsp.get_buffers_by_client_id(client.id) client:stop() vim.wait(30000, function() return vim.lsp.get_client_by_id(client.id) == nil end) local client_id = vim.lsp.start(client.config, { attach = nil }) if client_id then for _, buf in ipairs(bufs) do vim.lsp.buf_attach_client(buf, client_id) end end end end, { nargs = "?", complete = function() return vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients()) end, }) vim.lsp.config("*", { root_markers = { ".git" } }) vim.lsp.config["lua_ls"] = { cmd = { "lua-language-server" }, filetypes = { "lua" }, root_markers = { ".luarc.json", ".luarc.jsonc", ".stylua.toml", "stylua.toml", ".git", }, settings = { Lua = { workspace = { checkThirdParty = false, library = { vim.env.VIMRUNTIME }, }, telemetry = { enable = false }, diagnostics = { globals = { "vim" } }, format = { enable = false }, runtime = { version = "LuaJIT" }, }, }, } vim.lsp.enable("lua_ls") vim.lsp.config["basedpyright"] = { cmd = { "basedpyright-langserver", "--stdio" }, filetypes = { "python" }, root_markers = { "pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "pyrightconfig.json", ".git", }, settings = { python = { analysis = { autoImportCompletions = false, diagnosticMode = "workspace", useLibraryCodeForTypes = false }, }, }, } vim.lsp.enable("basedpyright") vim.lsp.config["html"] = { cmd = { "vscode-html-language-server", "--stdio" }, filetypes = { "html" }, settings = { html = { format = { templating = true, wrapLineLength = 120, wrapAttributes = "auto", }, hover = { documentation = true, references = true, }, }, }, } vim.lsp.enable("html") vim.lsp.config["yaml"] = { cmd = { "yaml-language-server", "--stdio" }, filetypes = { "yaml" }, settings = { yaml = { schemas = { kubernetes = "/home/hjalmarlucius/src/hjarl/system/manifests/*.yaml" }, -- schemaStore = { enable = false, url = "" }, }, }, } vim.lsp.enable("yaml") vim.lsp.config["typst"] = { cmd = { "tinymist" }, filetypes = { "typst" }, settings = {}, } vim.lsp.enable("typst") vim.lsp.config["bash"] = { cmd = { "bash-language-server", "start" }, filetypes = { "bash", "sh" }, } vim.lsp.enable("bash") vim.lsp.config["js"] = { cmd = { "vtsls", "--stdio" }, root_markers = { ".git", "package.json", "tsconfig.json", "jsconfig.json" }, filetypes = { "javascript", "javascriptreact", "javascript.jsx", "typescript", "typescriptreact", "typescript.tsx" }, settings = { complete_function_calls = true, vtsls = { enableMoveToFileCodeAction = true, autoUseWorkspaceTsdk = true, experimental = { maxInlayHintLength = 30, completion = { enableServerSideFuzzyMatch = true, }, }, }, javascript = { updateImportsOnFileMove = { enabled = "always" }, suggest = { completeFunctionCalls = true, }, inlayHints = { enumMemberValues = { enabled = true }, functionLikeReturnTypes = { enabled = true }, parameterNames = { enabled = "literals" }, parameterTypes = { enabled = true }, propertyDeclarationTypes = { enabled = true }, variableTypes = { enabled = false }, }, }, typescript = { updateImportsOnFileMove = { enabled = "always" }, suggest = { completeFunctionCalls = true, }, inlayHints = { enumMemberValues = { enabled = true }, functionLikeReturnTypes = { enabled = true }, parameterNames = { enabled = "literals" }, parameterTypes = { enabled = true }, propertyDeclarationTypes = { enabled = true }, variableTypes = { enabled = false }, }, }, }, } vim.lsp.enable("js") -- ---------------------------------------- -- PLUGINS -- ---------------------------------------- local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or vim.loop).fs_stat(lazypath) then vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", "https://github.com/folke/lazy.nvim.git", lazypath, }) end vim.opt.rtp:prepend(lazypath) require("lazy").setup({ spec = { -- mini { "echasnovski/mini.basics", opts = { options = { basic = true, extra_ui = true }, mappings = { move_with_alt = true }, }, }, { "smoka7/hop.nvim", opts = {}, cmd = { "HopWord", "HopCamelCase", "HopChar1", "HopChar2", "HopPattern", "HopLine", "HopLineStart", "HopAnywhere", "HopNodes", "HopPaste", "HopYankChar1", }, keys = { { "", "HopWord", mode = { "n", "v" }, silent = true, noremap = true }, { "", "HopAnywhere", mode = { "n", "v" }, silent = true, noremap = true }, { "f", function() require("hop").hint_char1({ direction = require("hop.hint").HintDirection.AFTER_CURSOR, current_line_only = true, }) end, mode = { "n", "v", "o" }, remap = true, }, { "F", function() require("hop").hint_char1({ direction = require("hop.hint").HintDirection.BEFORE_CURSOR, current_line_only = true, }) end, mode = { "n", "v", "o" }, remap = true, }, { "t", function() require("hop").hint_char1({ direction = require("hop.hint").HintDirection.AFTER_CURSOR, current_line_only = true, hint_offset = -1, }) end, mode = { "n", "v", "o" }, remap = true, }, { "T", function() require("hop").hint_char1({ direction = require("hop.hint").HintDirection.BEFORE_CURSOR, current_line_only = true, hint_offset = 1, }) end, mode = { "n", "v", "o" }, remap = true, }, }, }, { "echasnovski/mini.icons", opts = {}, }, { "echasnovski/mini.surround", version = false, opts = {}, }, { "echasnovski/mini.bufremove", version = false, opts = {}, keys = { { "", function() require("mini.bufremove").wipeout() end, noremap = true }, { "", function() require("mini.bufremove").wipeout(nil, true) end, noremap = true }, }, }, -- snacks { "folke/snacks.nvim", priority = 1000, lazy = false, ---@type snacks.Config opts = { bigfile = { enabled = true, notify = true, -- show notification when big file detected size = 1.5 * 1024 * 1024, -- 1.5MB line_length = 1000, -- average line length (useful for minified files) -- Enable or disable features when big file detected ---@param ctx {buf: number, ft:string} setup = function(ctx) if vim.fn.exists(":NoMatchParen") ~= 0 then vim.cmd([[NoMatchParen]]) end Snacks.util.wo(0, { foldmethod = "manual", statuscolumn = "", conceallevel = 0 }) vim.schedule(function() if vim.api.nvim_buf_is_valid(ctx.buf) then vim.bo[ctx.buf].syntax = ctx.ft end end) end, }, notifier = { enabled = true }, indent = { enabled = true }, quickfile = { enabled = true }, image = { enabled = true }, rename = { enabled = true }, }, }, -- file management { "nvim-neo-tree/neo-tree.nvim", version = false, cmd = { "Neotree" }, dependencies = { "nvim-lua/plenary.nvim", "mini.icons", "MunifTanjim/nui.nvim" }, opts = { hijack_netrw_behavior = "disabled" }, keys = { { "", "Neotree", noremap = true } }, }, { "stevearc/oil.nvim", dependencies = { "mini.icons" }, cmd = { "Oil" }, opts = { watch_for_changes = true, view_options = { show_hidden = true }, }, keys = { { "b", "Oil .", noremap = true }, { "B", "Oil --float .", noremap = true }, }, config = function() vim.api.nvim_create_autocmd("User", { pattern = "OilActionsPost", callback = function(event) if event.data.actions.type == "move" then Snacks.rename.on_rename_file(event.data.actions.src_url, event.data.actions.dest_url) end end, }) end, }, -- div utils "tpope/vim-eunuch", -- Move, Rename etc "tpope/vim-sleuth", -- do the right thing with tabstop and softtabstop "dhruvasagar/vim-table-mode", -- tables "itchyny/vim-qfedit", -- editable quickfix list { -- keep location upon reopening "ethanholz/nvim-lastplace", opts = {}, }, { -- tmux / vim interop "alexghergh/nvim-tmux-navigation", config = function() require("nvim-tmux-navigation").setup({ disable_when_zoomed = true, -- defaults to false keybindings = { left = "", down = "", up = "", right = "", last_active = "", }, }) end, }, { "chomosuke/typst-preview.nvim", lazy = false, -- or ft = 'typst' version = "1.*", opts = { debug = true, port = 10010, dependencies_bin = { ["tinymist"] = "tinymist" }, follow_cursor = false, invert_colors = "auto", get_root = function(filename) local root = os.getenv("TYPST_ROOT") if root then return root end local dir0 = vim.fn.fnamemodify(filename, ":p:h") local dir = dir0 for _ = 1, 10 do if vim.fn.isdirectory(dir .. "/.git/") ~= 0 or vim.fn.filereadable(dir .. "/.git") ~= 0 then print("root dir: " .. dir) return dir end dir = vim.fn.fnamemodify(dir, ":p:h:h") end return dir0 end, }, }, { -- live preview of markdown files "iamcco/markdown-preview.nvim", -- requires yarn cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, ft = { "markdown" }, build = function() vim.fn["mkdp#util#install"]() end, init = function() vim.g.mkdp_auto_start = 0 -- auto start on moving into vim.g.mkdp_auto_close = 0 -- auto close on moving away vim.g.mkdp_open_to_the_world = 1 -- available to others vim.g.mkdp_port = 10010 vim.g.mkdp_echo_preview_url = 1 vim.g.mkdp_preview_options = { disable_sync_scroll = 1 } end, }, { -- search count > 99 "kevinhwang91/nvim-hlslens", dependencies = { "haya14busa/vim-asterisk" }, cmd = { "HlSearchLensDisable", "HlSearchLensEnable", "HlSearchLensToggle" }, opts = { nearest_only = true }, keys = { { "*", [[(asterisk-z*)lua require('hlslens').start()]], mode = { "n", "x" }, {} }, { "#", [[(asterisk-z#)lua require('hlslens').start()]], mode = { "n", "x" }, {} }, { "g*", [[(asterisk-gz*)lua require('hlslens').start()]], mode = { "n", "x" }, {} }, { "g#", [[(asterisk-gz#)lua require('hlslens').start()]], mode = { "n", "x" }, {} }, { "n", [[nlua require('hlslens').start()]], mode = { "n", "x" }, noremap = true, silent = true, }, { "N", [[Nlua require('hlslens').start()]], mode = { "n", "x" }, noremap = true, silent = true, }, }, init = function() vim.g["asterisk#keeppos"] = 1 end, }, { "catgoose/nvim-colorizer.lua", event = "BufReadPre", opts = { user_default_options = { mode = "virtualtext" } }, }, -- theme dark and light "NLKNguyen/papercolor-theme", "junegunn/seoul256.vim", { "mhartington/oceanic-next", config = function() local customthemegroup = vim.api.nvim_create_augroup("customthemegroup", {}) vim.api.nvim_create_autocmd("ColorScheme", { pattern = { "OceanicNext" }, group = customthemegroup, callback = function() vim.api.nvim_set_hl(0, "DiffAdded", { default = false, link = "DiffAdd" }) vim.api.nvim_set_hl(0, "DiffRemoved", { default = false, link = "DiffDelete" }) vim.api.nvim_set_hl(0, "Normal", {}) vim.api.nvim_set_hl(0, "LineNr", {}) vim.api.nvim_set_hl(0, "SignColumn", {}) vim.api.nvim_set_hl(0, "EndOfBuffer", {}) end, }) end, }, "morhetz/gruvbox", { "sonph/onehalf", lazy = false, config = function(plugin) vim.opt.rtp:append(plugin.dir .. "/vim") end, }, { "catppuccin/nvim", lazy = false, name = "catppuccin", priority = 1000, config = function() vim.cmd([[colorscheme catppuccin-mocha]]) end, }, { "Shatur/neovim-ayu", init = function() vim.g.ayu_extended_palette = 1 end, }, -- theme dark only "tomasr/molokai", "jnurmine/Zenburn", -- status + buffer lines { "nvim-lualine/lualine.nvim", dependencies = { "echasnovski/mini.icons", "folke/noice.nvim" }, opts = { options = { theme = "auto", globalstatus = false }, extensions = { "fugitive" }, sections = { lualine_a = { { "mode", color = { bg = "goldenrod" } } }, lualine_b = { "branch" }, lualine_c = { { "filename", file_status = true, path = 1, shorting_target = 0, }, { "diff", colored = true }, }, lualine_x = { { "require('noice').api.status.command.get()" }, { "require('noice').api.status.mode.get()" }, }, lualine_y = { "filetype", "progress" }, lualine_z = { "location" }, }, inactive_sections = { lualine_a = {}, lualine_b = {}, lualine_c = { { "filename", file_status = true, path = 1, shorting_target = 0, }, { "diff", colored = true }, }, lualine_x = {}, lualine_y = { "filetype", "progress" }, lualine_z = { "location" }, }, tabline = { lualine_a = { { "buffers", symbols = { alternate_file = "" }, buffers_color = { active = { bg = "goldenrod" }, }, }, }, lualine_b = {}, lualine_c = {}, lualine_x = {}, lualine_y = {}, lualine_z = { { "tabs", mode = 2, tabs_color = { active = { bg = "goldenrod" }, }, }, }, }, }, }, -- git related plugins { "sindrets/diffview.nvim", cmd = { "DiffviewOpen", "DiffviewClose", "DiffviewToggleFiles", "DiffviewFocusFiles", "DiffviewRefresh", "DiffviewFileHistory", }, keys = { { "gd", "DiffviewOpen", noremap = true }, { "gh", "DiffviewFileHistory", noremap = true }, }, }, { "tpope/vim-fugitive", cmd = { "Git", "Gedit", "Gdiffsplit", "Gread", "Gwrite", "Ggrep", "Glgrep", "Gmove", "GRename", "GDelete", "GRemove", "Gdelete", "GUnlink", "GBrowse", }, config = function() vim.api.nvim_create_autocmd("User", { pattern = { "FugitiveCommit", "BufReadPost" }, callback = function() vim.opt.foldmethod = "syntax" vim.opt.foldlevel = 0 end, }) end, keys = { { "", "vertical Git" }, { "gB", "Git blame" }, { "gp", "Git! push" }, { "gP", "Git! push -f" }, }, }, { "rbong/vim-flog", dependencies = { "tpope/vim-fugitive" }, cmd = { "Flog", "Flogsplit", "Floggit" }, config = function() vim.g.flog_permanent_default_opts = { -- format = "%ad [%h] {%an}%d %s", format = "%ad [%h]%d %s", date = "short", } end, keys = { { "gl", "vertical Flogsplit -path=%" }, { "gL", "vertical Flogsplit" }, }, }, { "lewis6991/gitsigns.nvim", opts = { signcolumn = true, numhl = true, linehl = false, word_diff = false, signs_staged_enable = false, on_attach = function(bufnr) local gs = require("gitsigns") local function bmap(mode, l, r, opts) opts = opts or {} opts.buffer = bufnr vim.keymap.set(mode, l, r, opts) end -- Navigation bmap("n", "", function() if vim.wo.diff then return "]c" end vim.schedule(function() gs.next_hunk() end) return "" end, { expr = true }) bmap("n", "", function() if vim.wo.diff then return "[c" end vim.schedule(function() gs.prev_hunk() end) return "" end, { expr = true }) -- Actions bmap("v", "gs", function() gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) end) bmap("v", "gx", function() gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) end) bmap("n", "gs", gs.stage_hunk) bmap("n", "gx", gs.reset_hunk) bmap("n", "gu", gs.undo_stage_hunk) bmap("n", "gi", gs.preview_hunk) bmap("n", "gb", function() gs.blame_line({ full = true }) end) bmap("n", "gS", gs.stage_buffer) bmap("n", "gX", gs.reset_buffer) bmap("n", "td", gs.toggle_deleted) bmap("n", "tl", gs.toggle_linehl) bmap("n", "tb", gs.toggle_current_line_blame) bmap("n", "th", gs.toggle_word_diff) bmap("n", "tn", gs.toggle_numhl) -- Text object bmap({ "o", "x" }, "ih", "Gitsigns select_hunk") end, }, }, { -- helplists "folke/todo-comments.nvim", dependencies = { "nvim-lua/plenary.nvim" }, lazy = false, opts = { signs = true, -- show icons in the signs column sign_priority = 8, -- sign priority keywords = { MAYBE = { icon = " " }, PERF = { icon = " " }, FIX = { icon = " ", color = "error", alt = { "BUG" } }, TODO = { icon = " ", color = "info" }, HACK = { icon = " ", color = "warning" }, WARN = { icon = " ", color = "warning" }, NOTE = { icon = " ", color = "hint" }, TEST = { icon = "⏲ ", color = "test" }, }, merge_keywords = false, -- when true, custom keywords will be merged with the defaults highlight = { keyword = "bg", pattern = [[.*<(KEYWORDS)\s*:]] }, search = { pattern = [[\b(KEYWORDS)\b]] }, colors = { error = { "#ba1a1a" }, warning = { "#FFC107" }, info = { "#91BED0" }, hint = { "#10B981" }, default = { "#91D0C1" }, }, }, keys = { { "", "TodoQuickFix", noremap = true } }, }, { -- Fuzzy Finder (files, lsp, etc) "nvim-telescope/telescope.nvim", version = false, dependencies = { "sharkdp/fd", "nvim-lua/plenary.nvim", "nvim-telescope/telescope-live-grep-args.nvim", }, keys = { { "", function() require("telescope.builtin").find_files({ layout_config = { width = 0.99 } }) end, noremap = true, }, { "", function() local cwd = vim.fn.getcwd() vim.fn.system("git rev-parse --is-inside-work-tree") local is_inside_work_tree = vim.v.shell_error == 0 local opts = { layout_config = { width = 0.99 } } if is_inside_work_tree then require("telescope.builtin").git_files(opts) else require("telescope.builtin").find_files(opts) end end, noremap = true, }, { "", function() require("telescope.builtin").diagnostics({ layout_strategy = "vertical", layout_config = { width = 0.99 }, }) end, noremap = true, }, { "", function() require("telescope").extensions.live_grep_args.live_grep_args() end, noremap = true, }, { "", function() require("telescope.builtin").filetypes() end, noremap = true }, { "", function() require("telescope.builtin").search_history() end, noremap = true }, { "", function() require("telescope.builtin").colorscheme({ layout_config = { width = 0.5 }, enable_preview = true, ignore_builtins = true, }) end, noremap = true, }, }, config = function() -- TODO grep with regex local actions = require("telescope.actions") require("telescope").setup({ defaults = { layout_config = { horizontal = { width = 0.99 } }, mappings = { i = { [""] = "close", [""] = "select_default", [""] = "move_selection_next", [""] = "move_selection_previous", [""] = "preview_scrolling_up", [""] = "preview_scrolling_down", [""] = "select_horizontal", [""] = "select_vertical", [""] = "select_tab", [""] = actions.toggle_selection + actions.move_selection_worse, [""] = actions.toggle_selection + actions.move_selection_better, [""] = actions.send_to_loclist + actions.open_loclist, [""] = actions.send_selected_to_loclist + actions.open_loclist, [""] = require("telescope.actions.layout").toggle_preview, [""] = "results_scrolling_up", [""] = "results_scrolling_down", }, n = { [""] = require("telescope.actions.layout").toggle_preview }, }, file_ignore_patterns = {}, set_env = { ["COLORTERM"] = "truecolor" }, }, }) end, }, "mbbill/undotree", { "debugloop/telescope-undo.nvim", dependencies = { { "nvim-telescope/telescope.nvim", dependencies = { "nvim-lua/plenary.nvim" }, }, }, keys = { { "", function() require("telescope").extensions.undo.undo() end, desc = "undo history", }, }, opts = { extensions = { undo = { side_by_side = true, vim_diff_opts = { ctxlen = vim.o.scrolloff }, entry_format = "state #$ID, $STAT, $TIME", time_format = "%H:%M:%S %m/%d/%Y", saved_only = false, layout_strategy = "vertical", layout_config = { preview_height = 0.6, width = 0.99 }, }, }, }, config = function(_, opts) -- Calling telescope's setup from multiple specs does not hurt, it will happily merge the -- configs for us. We won't use data, as everything is in it's own namespace (telescope -- defaults, as well as each extension). require("telescope").setup(opts) require("telescope").load_extension("undo") end, }, { -- Highlight, edit, and navigate code "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", opts = { { ensure_installed = { "bash", "c", "cpp", "git_rebase", "gitcommit", "lua", "python", "regex", "vimdoc", }, auto_install = true, highlight = { enable = true }, indent = { enable = true, disable = { "python" }, additional_vim_regex_highlighting = { "python" } }, incremental_selection = { enable = true, keymaps = { init_selection = "gnn", node_decremental = "", node_incremental = "", scope_incremental = "", }, }, }, }, config = function() vim.opt.foldexpr = "nvim_treesitter#foldexpr()" end, }, { "windwp/nvim-ts-autotag", dependencies = { "nvim-treesitter/nvim-treesitter" }, opts = { filetypes = { "html", "xml" } }, }, -- package manager + lsp stuff { "williamboman/mason.nvim", lazy = false, opts = {}, keys = { { "", "Mason", noremap = true } }, }, { "mfussenegger/nvim-lint", config = function() require("lint").linters_by_ft = { javascript = { "eslint_d" }, typescript = { "eslint_d" }, html = { "tidy", "eslint_d" }, go = { "golangcilint" }, sh = { "shellcheck" }, } vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, { callback = function() require("lint").try_lint() end, }) end, }, { "mhartington/formatter.nvim", -- TODO move to conform -- Utilities for creating configurations, keys = { { "f", "Format", silent = true, noremap = true }, { "F", "FormatWrite", silent = true, noremap = true }, }, config = function() require("formatter").setup({ logging = true, log_level = vim.log.levels.DEBUG, filetype = { python = { function() return { exe = "ruff", args = { "check", "--select I,F,UP", "--fix-only", "-" }, stdin = true, } end, function() return { exe = "ruff", args = { "format", "-" }, stdin = true, } end, }, lua = { function() local util = require("formatter.util") return { exe = "stylua", args = { "--search-parent-directories", "--indent-type Spaces", "--collapse-simple-statement Always", "--stdin-filepath", util.escape_path(util.get_current_buffer_file_path()), "--", "-", }, stdin = true, } end, }, yaml = { function() return { exe = "yamlfmt", args = { "-formatter indentless_arrays=true,retain_line_breaks=true,line_ending=lf,max_line_length=100,pad_line_comments=2", "-in", }, stdin = true, } end, }, typst = { function() return { exe = "typstyle", stdin = true, } end, }, typescript = { function() local util = require("formatter.util") return { exe = "eslint_d", args = { "--stdin", "--debug", "--stdin-filename", util.escape_path(util.get_current_buffer_file_path()), "--fix-to-stdout", }, stdin = true, try_node_modules = true, ignore_exitcode = true, } end, }, go = { require("formatter.filetypes.go").gofumpt, require("formatter.filetypes.go").golines }, sh = { require("formatter.filetypes.sh").shfmt }, javascript = { require("formatter.filetypes.javascript").prettierd }, html = { require("formatter.filetypes.html").prettierd }, css = { require("formatter.filetypes.css").prettierd }, markdown = { require("formatter.filetypes.markdown").prettierd }, json = { require("formatter.filetypes.json").jq }, ["*"] = { require("formatter.filetypes.any").remove_trailing_whitespace }, }, }) end, }, { "folke/noice.nvim", event = "VeryLazy", dependencies = { "MunifTanjim/nui.nvim" }, opts = { cmdline = { enabled = true, view = "cmdline_popup" }, messages = { enabled = true, -- enables the Noice messages UI view = "mini", -- default view for messages view_error = "notify", -- view for errors view_warn = "mini", -- view for warnings view_history = "popup", -- view for :messages view_search = false, }, popupmenu = { enabled = true }, notify = { enabled = true, view = "mini" }, lsp = { override = { ["vim.lsp.util.convert_input_to_markdown_lines"] = true, ["vim.lsp.util.stylize_markdown"] = true, }, progress = { enabled = false }, hover = { enabled = true }, signature = { enabled = true, auto_open = { enabled = true, throttle = 0 } }, message = { enabled = true, view = "notify" }, documentation = { view = "hover" }, }, -- you can enable a preset for easier configuration presets = { command_palette = true, -- position the cmdline and popupmenu together long_message_to_split = true, -- long messages will be sent to a split }, routes = { { filter = { event = "msg_show", kind = "search_count" }, opts = { skip = true } }, { filter = { kind = "", min_height = 2 }, view = "split" }, }, }, }, }, install = { colorscheme = { "habamax" } }, checker = { enabled = true }, })