-- TODO: replace to everywhere in AstroNvim v4 to match vimdoc local utils = require "astronvim.utils" local get_icon = utils.get_icon local is_available = utils.is_available local ui = require "astronvim.utils.ui" local maps = require("astronvim.utils").empty_map_table() local sections = { f = { desc = get_icon("Search", 1, true) .. "Find" }, p = { desc = get_icon("Package", 1, true) .. "Packages" }, l = { desc = get_icon("ActiveLSP", 1, true) .. "LSP" }, u = { desc = get_icon("Window", 1, true) .. "UI/UX" }, b = { desc = get_icon("Tab", 1, true) .. "Buffers" }, bs = { desc = get_icon("Sort", 1, true) .. "Sort Buffers" }, d = { desc = get_icon("Debugger", 1, true) .. "Debugger" }, g = { desc = get_icon("Git", 1, true) .. "Git" }, S = { desc = get_icon("Session", 1, true) .. "Session" }, t = { desc = get_icon("Terminal", 1, true) .. "Terminal" }, } -- Normal -- -- Standard Operations maps.n["j"] = { "v:count == 0 ? 'gj' : 'j'", expr = true, desc = "Move cursor down" } maps.n["k"] = { "v:count == 0 ? 'gk' : 'k'", expr = true, desc = "Move cursor up" } maps.n["w"] = { "w", desc = "Save" } maps.n["q"] = { "confirm q", desc = "Quit" } maps.n["n"] = { "enew", desc = "New File" } maps.n[""] = { "w!", desc = "Force write" } maps.n[""] = { "q!", desc = "Force quit" } maps.n["|"] = { "vsplit", desc = "Vertical Split" } maps.n["\\"] = { "split", desc = "Horizontal Split" } -- TODO: Remove when dropping support for p"] = sections.p maps.n["pi"] = { function() require("lazy").install() end, desc = "Plugins Install" } maps.n["ps"] = { function() require("lazy").home() end, desc = "Plugins Status" } maps.n["pS"] = { function() require("lazy").sync() end, desc = "Plugins Sync" } maps.n["pu"] = { function() require("lazy").check() end, desc = "Plugins Check Updates" } maps.n["pU"] = { function() require("lazy").update() end, desc = "Plugins Update" } -- AstroNvim maps.n["pa"] = { "AstroUpdatePackages", desc = "Update Plugins and Mason Packages" } maps.n["pA"] = { "AstroUpdate", desc = "AstroNvim Update" } maps.n["pv"] = { "AstroVersion", desc = "AstroNvim Version" } maps.n["pl"] = { "AstroChangelog", desc = "AstroNvim Changelog" } -- Manage Buffers maps.n["c"] = { function() require("astronvim.utils.buffer").close() end, desc = "Close buffer" } maps.n["C"] = { function() require("astronvim.utils.buffer").close(0, true) end, desc = "Force close buffer" } maps.n["]b"] = { function() require("astronvim.utils.buffer").nav(vim.v.count > 0 and vim.v.count or 1) end, desc = "Next buffer" } maps.n["[b"] = { function() require("astronvim.utils.buffer").nav(-(vim.v.count > 0 and vim.v.count or 1)) end, desc = "Previous buffer", } maps.n[">b"] = { function() require("astronvim.utils.buffer").move(vim.v.count > 0 and vim.v.count or 1) end, desc = "Move buffer tab right", } maps.n[" 0 and vim.v.count or 1)) end, desc = "Move buffer tab left", } maps.n["b"] = sections.b maps.n["bc"] = { function() require("astronvim.utils.buffer").close_all(true) end, desc = "Close all buffers except current" } maps.n["bC"] = { function() require("astronvim.utils.buffer").close_all() end, desc = "Close all buffers" } maps.n["bb"] = { function() require("astronvim.utils.status.heirline").buffer_picker(function(bufnr) vim.api.nvim_win_set_buf(0, bufnr) end) end, desc = "Select buffer from tabline", } maps.n["bd"] = { function() require("astronvim.utils.status.heirline").buffer_picker( function(bufnr) require("astronvim.utils.buffer").close(bufnr) end ) end, desc = "Close buffer from tabline", } maps.n["bl"] = { function() require("astronvim.utils.buffer").close_left() end, desc = "Close all buffers to the left" } maps.n["bp"] = { function() require("astronvim.utils.buffer").prev() end, desc = "Previous buffer" } maps.n["br"] = { function() require("astronvim.utils.buffer").close_right() end, desc = "Close all buffers to the right" } maps.n["bs"] = sections.bs maps.n["bse"] = { function() require("astronvim.utils.buffer").sort "extension" end, desc = "By extension" } maps.n["bsr"] = { function() require("astronvim.utils.buffer").sort "unique_path" end, desc = "By relative path" } maps.n["bsp"] = { function() require("astronvim.utils.buffer").sort "full_path" end, desc = "By full path" } maps.n["bsi"] = { function() require("astronvim.utils.buffer").sort "bufnr" end, desc = "By buffer number" } maps.n["bsm"] = { function() require("astronvim.utils.buffer").sort "modified" end, desc = "By modification" } maps.n["b\\"] = { function() require("astronvim.utils.status.heirline").buffer_picker(function(bufnr) vim.cmd.split() vim.api.nvim_win_set_buf(0, bufnr) end) end, desc = "Horizontal split buffer from tabline", } maps.n["b|"] = { function() require("astronvim.utils.status.heirline").buffer_picker(function(bufnr) vim.cmd.vsplit() vim.api.nvim_win_set_buf(0, bufnr) end) end, desc = "Vertical split buffer from tabline", } -- Navigate tabs maps.n["]t"] = { function() vim.cmd.tabnext() end, desc = "Next tab" } maps.n["[t"] = { function() vim.cmd.tabprevious() end, desc = "Previous tab" } -- Alpha if is_available "alpha-nvim" then maps.n["h"] = { function() local wins = vim.api.nvim_tabpage_list_wins(0) if #wins > 1 and vim.api.nvim_get_option_value("filetype", { win = wins[1] }) == "neo-tree" then vim.fn.win_gotoid(wins[2]) -- go to non-neo-tree window to toggle alpha end require("alpha").start(false, require("alpha").default_config) end, desc = "Home Screen", } end -- Comment if is_available "Comment.nvim" then maps.n["/"] = { function() require("Comment.api").toggle.linewise.count(vim.v.count > 0 and vim.v.count or 1) end, desc = "Toggle comment line", } maps.v["/"] = { "lua require('Comment.api').toggle.linewise(vim.fn.visualmode())", desc = "Toggle comment for selection", } end -- GitSigns if is_available "gitsigns.nvim" then maps.n["g"] = sections.g maps.n["]g"] = { function() require("gitsigns").next_hunk() end, desc = "Next Git hunk" } maps.n["[g"] = { function() require("gitsigns").prev_hunk() end, desc = "Previous Git hunk" } maps.n["gl"] = { function() require("gitsigns").blame_line() end, desc = "View Git blame" } maps.n["gL"] = { function() require("gitsigns").blame_line { full = true } end, desc = "View full Git blame" } maps.n["gp"] = { function() require("gitsigns").preview_hunk() end, desc = "Preview Git hunk" } maps.n["gh"] = { function() require("gitsigns").reset_hunk() end, desc = "Reset Git hunk" } maps.n["gr"] = { function() require("gitsigns").reset_buffer() end, desc = "Reset Git buffer" } maps.n["gs"] = { function() require("gitsigns").stage_hunk() end, desc = "Stage Git hunk" } maps.n["gS"] = { function() require("gitsigns").stage_buffer() end, desc = "Stage Git buffer" } maps.n["gu"] = { function() require("gitsigns").undo_stage_hunk() end, desc = "Unstage Git hunk" } maps.n["gd"] = { function() require("gitsigns").diffthis() end, desc = "View Git diff" } end -- NeoTree if is_available "neo-tree.nvim" then maps.n["e"] = { "Neotree toggle", desc = "Toggle Explorer" } maps.n["o"] = { function() if vim.bo.filetype == "neo-tree" then vim.cmd.wincmd "p" else vim.cmd.Neotree "focus" end end, desc = "Toggle Explorer Focus", } end -- Session Manager if is_available "neovim-session-manager" then maps.n["S"] = sections.S maps.n["Sl"] = { "SessionManager! load_last_session", desc = "Load last session" } maps.n["Ss"] = { "SessionManager! save_current_session", desc = "Save this session" } maps.n["Sd"] = { "SessionManager! delete_session", desc = "Delete session" } maps.n["Sf"] = { "SessionManager! load_session", desc = "Search sessions" } maps.n["S."] = { "SessionManager! load_current_dir_session", desc = "Load current directory session" } end if is_available "resession.nvim" then maps.n["S"] = sections.S maps.n["Sl"] = { function() require("resession").load "Last Session" end, desc = "Load last session" } maps.n["Ss"] = { function() require("resession").save() end, desc = "Save this session" } maps.n["St"] = { function() require("resession").save_tab() end, desc = "Save this tab's session" } maps.n["Sd"] = { function() require("resession").delete() end, desc = "Delete a session" } maps.n["Sf"] = { function() require("resession").load() end, desc = "Load a session" } maps.n["S."] = { function() require("resession").load(vim.fn.getcwd(), { dir = "dirsession" }) end, desc = "Load current directory session", } end -- Package Manager if is_available "mason.nvim" then maps.n["pm"] = { "Mason", desc = "Mason Installer" } maps.n["pM"] = { "MasonUpdateAll", desc = "Mason Update" } end -- Smart Splits if is_available "smart-splits.nvim" then maps.n[""] = { function() require("smart-splits").move_cursor_left() end, desc = "Move to left split" } maps.n[""] = { function() require("smart-splits").move_cursor_down() end, desc = "Move to below split" } maps.n[""] = { function() require("smart-splits").move_cursor_up() end, desc = "Move to above split" } maps.n[""] = { function() require("smart-splits").move_cursor_right() end, desc = "Move to right split" } maps.n[""] = { function() require("smart-splits").resize_up() end, desc = "Resize split up" } maps.n[""] = { function() require("smart-splits").resize_down() end, desc = "Resize split down" } maps.n[""] = { function() require("smart-splits").resize_left() end, desc = "Resize split left" } maps.n[""] = { function() require("smart-splits").resize_right() end, desc = "Resize split right" } else maps.n[""] = { "h", desc = "Move to left split" } maps.n[""] = { "j", desc = "Move to below split" } maps.n[""] = { "k", desc = "Move to above split" } maps.n[""] = { "l", desc = "Move to right split" } maps.n[""] = { "resize -2", desc = "Resize split up" } maps.n[""] = { "resize +2", desc = "Resize split down" } maps.n[""] = { "vertical resize -2", desc = "Resize split left" } maps.n[""] = { "vertical resize +2", desc = "Resize split right" } end -- SymbolsOutline if is_available "aerial.nvim" then maps.n["l"] = sections.l maps.n["lS"] = { function() require("aerial").toggle() end, desc = "Symbols outline" } end -- Telescope if is_available "telescope.nvim" then maps.n["f"] = sections.f maps.n["g"] = sections.g maps.n["gb"] = { function() require("telescope.builtin").git_branches { use_file_path = true } end, desc = "Git branches" } maps.n["gc"] = { function() require("telescope.builtin").git_commits { use_file_path = true } end, desc = "Git commits (repository)", } maps.n["gC"] = { function() require("telescope.builtin").git_bcommits { use_file_path = true } end, desc = "Git commits (current file)", } maps.n["gt"] = { function() require("telescope.builtin").git_status { use_file_path = true } end, desc = "Git status" } maps.n["f"] = { function() require("telescope.builtin").resume() end, desc = "Resume previous search" } maps.n["f'"] = { function() require("telescope.builtin").marks() end, desc = "Find marks" } maps.n["f/"] = { function() require("telescope.builtin").current_buffer_fuzzy_find() end, desc = "Find words in current buffer" } maps.n["fa"] = { function() local cwd = vim.fn.stdpath "config" .. "/.." local search_dirs = {} for _, dir in ipairs(astronvim.supported_configs) do -- search all supported config locations if dir == astronvim.install.home then dir = dir .. "/lua/user" end -- don't search the astronvim core files if vim.fn.isdirectory(dir) == 1 then table.insert(search_dirs, dir) end -- add directory to search if exists end if vim.tbl_isempty(search_dirs) then -- if no config folders found, show warning utils.notify("No user configuration files found", vim.log.levels.WARN) else if #search_dirs == 1 then cwd = search_dirs[1] end -- if only one directory, focus cwd require("telescope.builtin").find_files { prompt_title = "Config Files", search_dirs = search_dirs, cwd = cwd, } -- call telescope end end, desc = "Find AstroNvim config files", } maps.n["fb"] = { function() require("telescope.builtin").buffers() end, desc = "Find buffers" } maps.n["fc"] = { function() require("telescope.builtin").grep_string() end, desc = "Find word under cursor" } maps.n["fC"] = { function() require("telescope.builtin").commands() end, desc = "Find commands" } maps.n["ff"] = { function() require("telescope.builtin").find_files() end, desc = "Find files" } maps.n["fF"] = { function() require("telescope.builtin").find_files { hidden = true, no_ignore = true } end, desc = "Find all files", } maps.n["fh"] = { function() require("telescope.builtin").help_tags() end, desc = "Find help" } maps.n["fk"] = { function() require("telescope.builtin").keymaps() end, desc = "Find keymaps" } maps.n["fm"] = { function() require("telescope.builtin").man_pages() end, desc = "Find man" } if is_available "nvim-notify" then maps.n["fn"] = { function() require("telescope").extensions.notify.notify() end, desc = "Find notifications" } end maps.n["fo"] = { function() require("telescope.builtin").oldfiles() end, desc = "Find history" } maps.n["fr"] = { function() require("telescope.builtin").registers() end, desc = "Find registers" } maps.n["ft"] = { function() require("telescope.builtin").colorscheme { enable_preview = true } end, desc = "Find themes" } maps.n["fw"] = { function() require("telescope.builtin").live_grep() end, desc = "Find words" } maps.n["fW"] = { function() require("telescope.builtin").live_grep { additional_args = function(args) return vim.list_extend(args, { "--hidden", "--no-ignore" }) end, } end, desc = "Find words in all files", } maps.n["l"] = sections.l maps.n["ls"] = { function() local aerial_avail, _ = pcall(require, "aerial") if aerial_avail then require("telescope").extensions.aerial.aerial() else require("telescope.builtin").lsp_document_symbols() end end, desc = "Search symbols", } end -- Terminal if is_available "toggleterm.nvim" then maps.n["t"] = sections.t if vim.fn.executable "lazygit" == 1 then maps.n["g"] = sections.g maps.n["gg"] = { function() local worktree = require("astronvim.utils.git").file_worktree() local flags = worktree and (" --work-tree=%s --git-dir=%s"):format(worktree.toplevel, worktree.gitdir) or "" utils.toggle_term_cmd("lazygit " .. flags) end, desc = "ToggleTerm lazygit", } maps.n["tl"] = maps.n["gg"] end if vim.fn.executable "node" == 1 then maps.n["tn"] = { function() utils.toggle_term_cmd "node" end, desc = "ToggleTerm node" } end if vim.fn.executable "gdu" == 1 then maps.n["tu"] = { function() utils.toggle_term_cmd "gdu" end, desc = "ToggleTerm gdu" } end if vim.fn.executable "btm" == 1 then maps.n["tt"] = { function() utils.toggle_term_cmd "btm" end, desc = "ToggleTerm btm" } end local python = vim.fn.executable "python" == 1 and "python" or vim.fn.executable "python3" == 1 and "python3" if python then maps.n["tp"] = { function() utils.toggle_term_cmd(python) end, desc = "ToggleTerm python" } end maps.n["tf"] = { "ToggleTerm direction=float", desc = "ToggleTerm float" } maps.n["th"] = { "ToggleTerm size=10 direction=horizontal", desc = "ToggleTerm horizontal split" } maps.n["tv"] = { "ToggleTerm size=80 direction=vertical", desc = "ToggleTerm vertical split" } maps.n[""] = { "ToggleTerm", desc = "Toggle terminal" } maps.t[""] = maps.n[""] maps.n[""] = maps.n[""] -- requires terminal that supports binding maps.t[""] = maps.n[""] -- requires terminal that supports binding end if is_available "nvim-dap" then maps.n["d"] = sections.d maps.v["d"] = sections.d -- modified function keys found with `showkey -a` in the terminal to get key code -- run `nvim -V3log +quit` and search through the "Terminal info" in the `log` file for the correct keyname maps.n[""] = { function() require("dap").continue() end, desc = "Debugger: Start" } maps.n[""] = { function() require("dap").terminate() end, desc = "Debugger: Stop" } -- Shift+F5 maps.n[""] = { -- Shift+F9 function() vim.ui.input({ prompt = "Condition: " }, function(condition) if condition then require("dap").set_breakpoint(condition) end end) end, desc = "Debugger: Conditional Breakpoint", } maps.n[""] = { function() require("dap").restart_frame() end, desc = "Debugger: Restart" } -- Control+F5 maps.n[""] = { function() require("dap").pause() end, desc = "Debugger: Pause" } maps.n[""] = { function() require("dap").toggle_breakpoint() end, desc = "Debugger: Toggle Breakpoint" } maps.n[""] = { function() require("dap").step_over() end, desc = "Debugger: Step Over" } maps.n[""] = { function() require("dap").step_into() end, desc = "Debugger: Step Into" } maps.n[""] = { function() require("dap").step_out() end, desc = "Debugger: Step Out" } -- Shift+F11 maps.n["db"] = { function() require("dap").toggle_breakpoint() end, desc = "Toggle Breakpoint (F9)" } maps.n["dB"] = { function() require("dap").clear_breakpoints() end, desc = "Clear Breakpoints" } maps.n["dc"] = { function() require("dap").continue() end, desc = "Start/Continue (F5)" } maps.n["dC"] = { function() vim.ui.input({ prompt = "Condition: " }, function(condition) if condition then require("dap").set_breakpoint(condition) end end) end, desc = "Conditional Breakpoint (S-F9)", } maps.n["di"] = { function() require("dap").step_into() end, desc = "Step Into (F11)" } maps.n["do"] = { function() require("dap").step_over() end, desc = "Step Over (F10)" } maps.n["dO"] = { function() require("dap").step_out() end, desc = "Step Out (S-F11)" } maps.n["dq"] = { function() require("dap").close() end, desc = "Close Session" } maps.n["dQ"] = { function() require("dap").terminate() end, desc = "Terminate Session (S-F5)" } maps.n["dp"] = { function() require("dap").pause() end, desc = "Pause (F6)" } maps.n["dr"] = { function() require("dap").restart_frame() end, desc = "Restart (C-F5)" } maps.n["dR"] = { function() require("dap").repl.toggle() end, desc = "Toggle REPL" } maps.n["ds"] = { function() require("dap").run_to_cursor() end, desc = "Run To Cursor" } if is_available "nvim-dap-ui" then maps.n["dE"] = { function() vim.ui.input({ prompt = "Expression: " }, function(expr) if expr then require("dapui").eval(expr) end end) end, desc = "Evaluate Input", } maps.v["dE"] = { function() require("dapui").eval() end, desc = "Evaluate Input" } maps.n["du"] = { function() require("dapui").toggle() end, desc = "Toggle Debugger UI" } maps.n["dh"] = { function() require("dap.ui.widgets").hover() end, desc = "Debugger Hover" } end end -- Improved Code Folding if is_available "nvim-ufo" then maps.n["zR"] = { function() require("ufo").openAllFolds() end, desc = "Open all folds" } maps.n["zM"] = { function() require("ufo").closeAllFolds() end, desc = "Close all folds" } maps.n["zr"] = { function() require("ufo").openFoldsExceptKinds() end, desc = "Fold less" } maps.n["zm"] = { function() require("ufo").closeFoldsWith() end, desc = "Fold more" } maps.n["zp"] = { function() require("ufo").peekFoldedLinesUnderCursor() end, desc = "Peek fold" } end -- Stay in indent mode maps.v[""] = { ""] = { ">gv", desc = "Indent line" } -- Improved Terminal Navigation maps.t[""] = { "wincmd h", desc = "Terminal left window navigation" } maps.t[""] = { "wincmd j", desc = "Terminal down window navigation" } maps.t[""] = { "wincmd k", desc = "Terminal up window navigation" } maps.t[""] = { "wincmd l", desc = "Terminal right window navigation" } maps.n["u"] = sections.u -- Custom menu for modification of the user experience if is_available "nvim-autopairs" then maps.n["ua"] = { ui.toggle_autopairs, desc = "Toggle autopairs" } end maps.n["ub"] = { ui.toggle_background, desc = "Toggle background" } if is_available "nvim-cmp" then maps.n["uc"] = { ui.toggle_cmp, desc = "Toggle autocompletion" } end if is_available "nvim-colorizer.lua" then maps.n["uC"] = { "ColorizerToggle", desc = "Toggle color highlight" } end maps.n["ud"] = { ui.toggle_diagnostics, desc = "Toggle diagnostics" } maps.n["ug"] = { ui.toggle_signcolumn, desc = "Toggle signcolumn" } maps.n["ui"] = { ui.set_indent, desc = "Change indent setting" } maps.n["ul"] = { ui.toggle_statusline, desc = "Toggle statusline" } maps.n["uL"] = { ui.toggle_codelens, desc = "Toggle CodeLens" } maps.n["un"] = { ui.change_number, desc = "Change line numbering" } maps.n["uN"] = { ui.toggle_ui_notifications, desc = "Toggle Notifications" } maps.n["up"] = { ui.toggle_paste, desc = "Toggle paste mode" } maps.n["us"] = { ui.toggle_spell, desc = "Toggle spellcheck" } maps.n["uS"] = { ui.toggle_conceal, desc = "Toggle conceal" } maps.n["ut"] = { ui.toggle_tabline, desc = "Toggle tabline" } maps.n["uu"] = { ui.toggle_url_match, desc = "Toggle URL highlight" } maps.n["uw"] = { ui.toggle_wrap, desc = "Toggle wrap" } maps.n["uy"] = { ui.toggle_syntax, desc = "Toggle syntax highlight" } maps.n["uh"] = { ui.toggle_foldcolumn, desc = "Toggle foldcolumn" } utils.set_mappings(astronvim.user_opts("mappings", maps))