-- Set leader key as Space vim.g.mapleader = " " local function map(mode, left, right, opts) local default_opts = { noremap = true, silent = true, } opts = opts or {} -- "keep" mode preserves the values from the leftmost table, -- so prioritize any options provided over the defaults local full_opts = vim.tbl_extend("keep", opts, default_opts) vim.keymap.set(mode, left, right, full_opts) end -- Clear any highlighted searches when pressing Esc -- This lets me leave hlsearch on by default while having an easy way to clear -- it again. map({ "i", "n" }, "", "noh", { desc = "Escape and clear hlsearch" }) -- Move lines while in visual mode with J and K map("v", "J", ":m '>+1gv=gv") map("v", "K", ":m '<-2gv=gv") -- Easier execution of Lua code map("n", "x", ".lua", { desc = "Execute the current line" }) map("n", "x", "source %", { desc = "Execute the current file" }) -- Keep cursor in the same place when using J to join lines map("n", "J", "mzJ`z") -- Center the screen when jumping around with C-d and C-u map("n", "", "zz") map("n", "", "zz") -- Center the screen when jumping to next / previous search terms map("n", "n", "nzzzv") map("n", "N", "Nzzzv") -- Quick maps to paste/delete without overwriting the current buffer map("x", "p", '"_dP') map({ "n", "v" }, "d", '"_dP') -- Easier quickfix naviagion map("n", "", "cprev", { desc = "Quickfix previous item" }) map("n", "", "cnext", { desc = "Quickfix next item" }) -- System clipboard map({ "n", "v" }, "cd", '"+d', { desc = "Clipboard delete" }) map({ "n", "v" }, "cp", '"+p', { desc = "Clipboard paste" }) map({ "n", "v" }, "cy", '"+y', { desc = "Clipboard yank" }) -- Map g- to netrw (temporary placeholder for oil) -- map("n", "g-", vim.cmd.Ex, { desc = "Open netrw" }) map("n", "gx", function() local command = "go run " .. vim.fn.expand("%") local f = assert(io.popen(command, "r")) local s = assert(f:read("*a")) f:close() s = string.gsub(s, "^%s+", "") s = string.gsub(s, "%s+$", "") s = string.gsub(s, "[\n\r]+", " ") print(s) end, { desc = "Execute current go file" }) -- Create a GitHub URL for the current file and line number, and copy it -- to the clipboard. map("n", "yfg", function() local remote_url = vim.fn.system("git config --get remote.origin.url") if not remote_url:find("github.com") then vim.notify("This is not a GitHub repository") return end local trimmed_remote_url = remote_url:gsub("%.git", ""):gsub("%s+", ""):gsub("\n", "") local branch_name = vim.fn.system("git rev-parse --abbrev-ref HEAD"):gsub("\n", "") -- Now construct the link in this format: -- /blob//#L local filepath = vim.fn.expand("%:."):gsub("\\", "/") local line = vim.fn.line(".") local result = trimmed_remote_url .. "/blob/" .. branch_name .. "/" .. filepath .. "#L" .. line vim.fn.setreg("+", result) vim.notify("Copied GitHub URL to clipboard: " .. result) end, { desc = "Yank GitHub URL to clipboard", expr = true }) -- LSP specific keybindings vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("IbrahimLspConfig", {}), callback = function(evt) local function lsp_map(mode, lhs, rhs, desc) local opts = { buffer = evt.buf, desc = "LSP: " .. (desc or "") } map(mode, lhs, rhs, opts) end local has_telescope, _ = pcall(require, "telescope") local function lsp_telescope_map(mode, lhs, with_telescope_rhs, no_telescope_rhs, desc) if has_telescope then desc = desc .. " (Telescope)" lsp_map(mode, lhs, with_telescope_rhs, desc) else lsp_map(mode, lhs, no_telescope_rhs, desc) end end local function tele_builtin(name, opts) return function() require("telescope.builtin")[name](opts) end end -- Navigation lsp_map("n", "gd", vim.lsp.buf.definition, "[G]oto [D]efinition") lsp_map("n", "gt", vim.lsp.buf.type_definition, "[G]oto [t]ype Definition") lsp_map("n", "gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") lsp_map("n", "gr", vim.lsp.buf.references, "[G]oto [R]eferences") lsp_map("n", "gI", vim.lsp.buf.implementation, "[G]oto [I]mplementation") lsp_telescope_map("n", "gr", tele_builtin("lsp_references"), vim.lsp.buf.references, "Go to references") lsp_telescope_map( "n", "sn", tele_builtin("lsp_document_symbols"), vim.lsp.buf.document_symbol, "Search document symbols" ) lsp_telescope_map( "n", "sN", tele_builtin("lsp_dynamic_workspace_symbols"), vim.lsp.buf.workspace_symbol, "Search workspace symbols" ) -- Code changes lsp_map("n", "cr", vim.lsp.buf.rename, "Rename") -- ca is being overwritten by the 'actions-preview' plugin -- lsp_map("n", "ca", vim.lsp.buf.code_action, "Code actions") -- Diagnostics lsp_map("n", "ds", vim.diagnostic.open_float, "[s]how [d]iagnostic window") lsp_map("n", "dn", function() vim.diagnostic.goto_next({ float = true }) end, "Go to [n]ext [d]iagnostic") lsp_map("n", "dp", function() vim.diagnostic.goto_prev({ float = true }) end, "Go to [p]revious [d]iagnostic") -- See `:help K` for why this keymap lsp_map("n", "K", vim.lsp.buf.hover, "Hover Documentation") lsp_map("n", "", vim.lsp.buf.signature_help, "Signature Documentation") -- Workspace lsp_map("n", "wa", vim.lsp.buf.add_workspace_folder, "[W]orkspace [A]dd Folder") lsp_map("n", "wr", vim.lsp.buf.remove_workspace_folder, "[W]orkspace [R]emove Folder") lsp_map("n", "wl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, "[W]orkspace [L]ist Folders") end, })