-- Set as the leader key -- See `:help mapleader` -- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used) vim.g.mapleader = " " vim.g.maplocalleader = " " -- Disable mouse input vim.o.mouse = "" -- Minimal number of screen lines to keep above and below the cursor. vim.o.scrolloff = 10 -- Highlight the line where the cursor is on vim.o.cursorline = true -- Column at 80 characters vim.o.colorcolumn = "80" -- Set default tabstop and shiftwidth vim.o.tabstop = 4 vim.o.shiftwidth = 4 -- Show and trailing spaces vim.o.list = true vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" } -- Configure line wrap vim.o.linebreak = true vim.o.breakindent = true vim.o.showbreak = "↪ " -- Case-insensitive searching UNLESS \C or one or more capital letters in the search term vim.o.ignorecase = true vim.o.smartcase = true -- Use undofile to preserve actions over restarts vim.o.undofile = true -- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`), -- instead raise a dialog asking if you wish to save the current file(s) See `:help 'confirm'` vim.o.confirm = true vim.cmd.colorscheme("gruvbox") -- [[ Set up keymaps ]] See `:h vim.keymap.set()`, `:h mapping`, `:h keycodes` -- Use to exit terminal mode vim.keymap.set("t", "", "") -- Map , , , to navigate between windows in any modes vim.keymap.set({ "t", "i" }, "", "h") vim.keymap.set({ "t", "i" }, "", "j") vim.keymap.set({ "t", "i" }, "", "k") vim.keymap.set({ "t", "i" }, "", "l") vim.keymap.set({ "n" }, "", "h") vim.keymap.set({ "n" }, "", "j") vim.keymap.set({ "n" }, "", "k") vim.keymap.set({ "n" }, "", "l") -- [[ Basic Autocommands ]]. -- See `:h lua-guide-autocommands`, `:h autocmd`, `:h nvim_create_autocmd()` -- Highlight when yanking (copying) text. -- Try it with `yap` in normal mode. See `:h vim.hl.on_yank()` vim.api.nvim_create_autocmd("TextYankPost", { desc = "Highlight when yanking (copying) text", callback = function() vim.hl.on_yank() end, }) -- Sync clipboard between OS and Neovim. Schedule the setting after `UiEnter` because it can -- increase startup-time. Remove this option if you want your OS clipboard to remain independent. -- See `:help 'clipboard'` vim.api.nvim_create_autocmd("UIEnter", { callback = function() vim.o.clipboard = "unnamedplus" end, }) -- Print the line number in front of each line vim.o.number = true vim.o.relativenumber = true -- [[ Create user commands ]] -- See `:h nvim_create_user_command()` and `:h user-commands` -- Create a command `:GitBlameLine` that print the git blame for the current line vim.api.nvim_create_user_command("GitBlameLine", function() local line_number = vim.fn.line(".") -- Get the current line number. See `:h line()` local filename = vim.api.nvim_buf_get_name(0) print(vim.fn.system({ "git", "blame", "-L", line_number .. ",+1", filename })) end, { desc = "Print the git blame for the current line" }) -- [[ Add optional packages ]] -- Nvim comes bundled with a set of packages that are not enabled by -- default. You can enable any of them by using the `:packadd` command. -- For example, to add the "nohlsearch" package to automatically turn off search highlighting after -- 'updatetime' and when going to insert mode vim.cmd("packadd! nohlsearch") -- [[ Language Setup ]] -- Treat Ipe stylesheets as xml code vim.filetype.add({ extension = { isy = "xml", }, }) -- Install nvim-treesitter vim.pack.add({ "https://github.com/nvim-treesitter/nvim-treesitter" }) require("nvim-treesitter").setup() vim.api.nvim_create_autocmd('FileType', { pattern = {'', 'tex'}, callback = function() vim.treesitter.start() end, }) vim.pack.add({ "https://github.com/mason-org/mason.nvim" }) require("mason").setup() vim.lsp.enable({ 'lua_ls', 'texlab', 'clangd', 'jdtls', 'fish_lsp', 'html', 'cssls', 'lemminx' }) vim.keymap.set('n', 'lf', vim.lsp.buf.format, { desc = 'Formats a buffer using the attached language server clients' }) vim.keymap.set('n', 'lh', vim.lsp.buf.hover, { desc = 'Displays hover information about the symbol' }) vim.keymap.set('n', 'lr', vim.lsp.buf.rename, { desc = 'Renames all references to the symbol' }) vim.keymap.set('n', 'ld', vim.lsp.buf.definition, { desc = 'Jumps to the definition of the symbol' }) vim.diagnostic.config({ signs = { text = { [vim.diagnostic.severity.ERROR] = "W ", [vim.diagnostic.severity.WARN] = "w ", [vim.diagnostic.severity.INFO] = "I ", [vim.diagnostic.severity.HINT] = "H ", }, }, virtual_text = true, -- Show inline diagnostics }) vim.keymap.set("n", "dn", "]d", { desc = "Jump to next diagnostic" }) vim.keymap.set("n", "dp", "[d", { desc = "Jump to previous diagnostic" }) vim.keymap.set("n", "dN", "]D", { desc = "Jump to last diagnostic" }) vim.keymap.set("n", "dP", "[D", { desc = "Jump to first diagnostic" }) vim.keymap.set("n", "ds", "d", { desc = "Display diagnostic on current line" }) vim.api.nvim_create_user_command("DapInit", function() vim.pack.add({ "https://github.com/mfussenegger/nvim-dap" }) local dap = require("dap") local dap_widgets = require("dap.ui.widgets") local dap_sidebar_s = dap_widgets.sidebar(dap_widgets.scopes) local dap_sidebar_f = dap_widgets.sidebar(dap_widgets.frames) vim.keymap.set("n", "bb", dap.toggle_breakpoint, { desc = "Toggle breakpoint" }) vim.keymap.set("n", "bc", dap.continue, { desc = "Continue execution" }) dap.listeners.on_session["debug"] = function() vim.keymap.set("n", "bs", dap_sidebar_s.toggle, { desc = "Show scopes" }) vim.keymap.set("n", "bf", dap_sidebar_f.toggle, { desc = "Show frames" }) vim.keymap.set("n", "", dap.step_out, { desc = "Step out" }) vim.keymap.set("n", "", dap.step_into, { desc = "Step into" }) vim.keymap.set("n", "", dap.step_over, { desc = "Step over" }) vim.keymap.set("n", "", dap.restart_frame, { desc = "Restart frame" }) end dap.adapters.gdb = { type = "executable", command = "gdb", args = { "--interpreter=dap", "--eval-command", "set print pretty on" } } dap.configurations.c = { { name = "Launch", type = "gdb", request = "launch", program = function() return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') end, args = {}, -- provide arguments if needed cwd = "${workspaceFolder}", stopAtBeginningOfMainSubprogram = false, }, { name = "Select and attach to process", type = "gdb", request = "attach", program = function() return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') end, pid = function() local name = vim.fn.input('Executable name (filter): ') return require("dap.utils").pick_process({ filter = name }) end, cwd = '${workspaceFolder}' }, { name = 'Attach to gdbserver :1234', type = 'gdb', request = 'attach', target = 'localhost:1234', program = function() return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') end, cwd = '${workspaceFolder}' } } dap.configurations.cpp = dap.configurations.c dap.configurations.rust = dap.configurations.c end, { desc = "Initialize Debug Adater Protocol support" }) -- [[ UI Configuration ]] vim.pack.add({ "https://github.com/nvim-mini/mini.nvim" }) vim.o.winborder = "none" -- Use mini.completion require("mini.completion").setup() local imap_expr = function(lhs, rhs) vim.keymap.set('i', lhs, rhs, { expr = true }) end imap_expr('', [[pumvisible() ? "\" : "\"]]) imap_expr('', [[pumvisible() ? "\" : "\"]]) -- Snippet integration for mini.completion require("mini.snippets").setup() -- Icons for statusline and completion require("mini.icons").setup() -- Use mini.statusline instead of native showmode require("mini.statusline").setup() vim.o.showmode = false -- Git integration for statusline and Command mode require("mini.git").setup() -- Show git diff in linenumbers require("mini.diff").setup() -- Use and configure mini.clue local clue = require("mini.clue") clue.setup({ triggers = { -- Leader triggers { mode = { "n", "x" }, keys = "" }, -- `[` and `]` keys { mode = "n", keys = "[" }, { mode = "n", keys = "]" }, -- Built-in completion { mode = "i", keys = "" }, -- `g` key { mode = { "n", "x" }, keys = "g" }, -- Marks { mode = { "n", "x" }, keys = "'" }, { mode = { "n", "x" }, keys = "`" }, -- Registers { mode = { "n", "x" }, keys = '"' }, { mode = { "i", "c" }, keys = "" }, -- Window commands { mode = "n", keys = "" }, -- `z` key { mode = { "n", "x" }, keys = "z" }, -- `i/a` key { mode = { "n", "x" }, keys = "i" }, }, clues = { -- Enhance this by adding descriptions for mapping groups clue.gen_clues.square_brackets(), clue.gen_clues.builtin_completion(), clue.gen_clues.g(), clue.gen_clues.marks(), clue.gen_clues.registers(), clue.gen_clues.windows(), clue.gen_clues.z(), }, window = { delay = 200, config = { width = 'auto', } } }) -- Use and configure mini.hipatterns local hipatterns = require('mini.hipatterns') hipatterns.setup({ highlighters = { -- Highlight standalone 'FIXME', 'HACK', 'TODO', 'NOTE' fixme = { pattern = '%f[%w]()FIXME()%f[%W]', group = 'MiniHipatternsFixme' }, hack = { pattern = '%f[%w]()HACK()%f[%W]', group = 'MiniHipatternsHack' }, todo = { pattern = '%f[%w]()TODO()%f[%W]', group = 'MiniHipatternsTodo' }, note = { pattern = '%f[%w]()NOTE()%f[%W]', group = 'MiniHipatternsNote' }, -- Highlight hex color strings (`#rrggbb`) using that color hex_color = hipatterns.gen_highlighter.hex_color(), }, }) -- Use mini.notify require("mini.notify").setup()