-- ============================================================================ -- Key Mappings -- ============================================================================ local map = function(mode, l, r, opts) if r == nil then vim.notify("Attempted to map key '" .. l .. "' but RHS is nil", vim.log.levels.WARN) return end opts = vim.tbl_extend('force', { silent = true, noremap = true }, opts or {}) vim.keymap.set(mode, l, r, opts) end -- Leader key vim.g.mapleader = ";" vim.g.maplocalleader = "\\" -- Tmux/Vim navigation local function smart_move(direction, tmux_cmd) local curwin = vim.api.nvim_get_current_win() vim.cmd('wincmd ' .. direction) if curwin == vim.api.nvim_get_current_win() then vim.fn.system('tmux select-pane ' .. tmux_cmd) end end -- Window Navigation map('n', '', function() smart_move('h', '-L') end) map('n', '', function() smart_move('j', '-D') end) map('n', '', function() smart_move('k', '-U') end) map('n', '', function() smart_move('l', '-R') end) -- Buffer Navigation map('n', 'bn', 'bnext') map('n', 'bp', 'bprevious') --map('n', 'bd', 'bdelete') map('n', 'ba', '%bdelete') -- Get list of loaded buffers in order local function get_buffers() local bufs = {} for _, buf in ipairs(vim.api.nvim_list_bufs()) do if vim.api.nvim_buf_is_loaded(buf) then table.insert(bufs, buf) end end return bufs end -- Swap two buffers by index in the buffer list local function swap_buffers(idx1, idx2) local bufs = get_buffers() local buf1 = bufs[idx1] local buf2 = bufs[idx2] if not buf1 or not buf2 then return end local name1 = vim.api.nvim_buf_get_name(buf1) local name2 = vim.api.nvim_buf_get_name(buf2) vim.cmd("b " .. buf1) vim.cmd("file " .. name2) vim.cmd("b " .. buf2) vim.cmd("file " .. name1) end -- Move current buffer left vim.keymap.set("n", "bh", function() local bufs = get_buffers() local curr = vim.api.nvim_get_current_buf() local idx for i, b in ipairs(bufs) do if b == curr then idx = i break end end if idx and idx > 1 then swap_buffers(idx, idx-1) end end, { noremap = true, silent = true }) -- Move current buffer right vim.keymap.set("n", "bl", function() local bufs = get_buffers() local curr = vim.api.nvim_get_current_buf() local idx for i, b in ipairs(bufs) do if b == curr then idx = i break end end if idx and idx < #bufs then swap_buffers(idx, idx+1) end end, { noremap = true, silent = true }) -- Save and Quit map('n', 'w', 'w') map('n', 'q', 'q') map('n', 'wq', 'wq') map('n', 'Q', 'qa!') -- Resize Windows map('n', '', 'resize -2') map('n', '', 'resize +2') map('n', '', 'vertical resize -2') map('n', '', 'vertical resize +2') -- Quickfix and Location List map('n', ']q', 'cnextzz') map('n', '[q', 'cprevzz') map('n', ']l', 'lnextzz') map('n', '[l', 'lprevzz') -- Terminal Mode map('t', '', '') map('t', '', 'h') map('t', '', 'j') map('t', '', 'k') map('t', '', 'l') -- Insert mode escape map('i', 'jk', '') -- Tmux/(n)vim navigation local function smart_move(direction, tmux_cmd) local curwin = vim.api.nvim_get_current_win() vim.cmd('wincmd ' .. direction) if curwin == vim.api.nvim_get_current_win() then vim.fn.system('tmux select-pane ' .. tmux_cmd) end end map('n', '', function() smart_move('h', '-L') end, {silent = true}) map('n', '', function() smart_move('j', '-D') end, {silent = true}) map('n', '', function() smart_move('k', '-U') end, {silent = true}) map('n', '', function() smart_move('l', '-R') end, {silent = true}) -- Jump to next match on line using `.` instead of `;` NOTE: commented out in favour of "ggandor/flit.nvim" --map("n", ".", ";") -- Repeat last command using `` instead of `.` NOTE: commented out in favour of "ggandor/flit.nvim" --map("n", "", ".") -- Reload nvim config map("n", "", "luafile ~/.config/nvim/init.lua | :echom ('Nvim config loading...') | :sl! | echo ('')") vim.keymap.set("t", "", "", { desc = "Exit terminal mode" }) vim.keymap.set("t", "", "", { desc = "Exit terminal mode" }) --------------- Extended Operations --------------- -- Conditional 'q' to quit on floating/quickfix/help windows otherwise still use it for macros -- TODO: Have a list of if available on system/packages, example "Zen Mode" to not work on it (quit Zen Mode) map("n", "q", function() local config = vim.api.nvim_win_get_config(0) if config.relative ~= "" then -- is_floating_window? return ":silent! close!" elseif vim.o.buftype == "quickfix" then return ":quit" elseif vim.o.buftype == "help" then return ":close" else return "q" end end, { expr = true, replace_keycodes = true }) -- Minimalist Tab Completion map("i", "", function() local col = vim.fn.col('.') - 1 local line = vim.fn.getline('.') local prev_char = line:sub(col, col) if vim.fn.pumvisible() == 1 or prev_char:match("%w") then return vim.api.nvim_replace_termcodes("", true, true, true) else return vim.api.nvim_replace_termcodes("", true, true, true) end end, { expr = true }) -- Shift-Tab for reverse completion map("i", "", function() if vim.fn.pumvisible() == 1 then return vim.api.nvim_replace_termcodes("", true, true, true) else return vim.api.nvim_replace_termcodes("", true, true, true) end end, { expr = true }) -- Toggle completion map("n", "tc", ':lua require("user.mods").toggle_completion()') -- Minimalist Auto Completion map("i", "", function() -- Exit this keymap if nvim-cmp is present local cmp_is_present, _ = pcall(require, "cmp") if cmp_is_present and require("cmp").visible() then return vim.api.nvim_replace_termcodes("", true, true, true) elseif cmp_is_present then return vim.api.nvim_replace_termcodes("", true, true, true) end -- when cmp is NOT present if vim.fn.pumvisible() == 1 then return vim.api.nvim_replace_termcodes("", true, true, true) else return vim.api.nvim_replace_termcodes("", true, true, true) end end, { expr = true }) -- Closing compaction in insert mode map("i", "[", "[]") map("i", "(", "()") map("i", "{", "{}") map("i", "/*", "/**/") -- Edit new file map("n", "e", [[:e =expand("%:h")..'/']], { noremap = true, silent = true, desc = "New file" }) -- Write as sudo map("c", "W!", "exe 'w !sudo tee >/dev/null %:p:S' | setl nomod", { silent = true, desc = "Write as Sudo" }) -- Don't format on save map("c", "F!", ":noautocmd w") -- Combine buffers list with buffer name map("n", "b", ":buffers:buffer") -- Buffer confirmation map("n", "y", ":BufferPick") -- Map buffer next, prev and delete to +(n/p/d) respectively and tab/s-tab map("n", "n", ":bn") map("n", "p", ":bp") map("n", "d", ":bd") map("n", "", ":bnext") map("n", "", ":bprevious") -- Close all buffers and reopen last one map("n", "D", ":update | %bdelete | edit # | normal `") -- Delete file of current buffer map("n", "rm", "call delete(expand('%')) | bdelete!") -- List marks map("n", "M", ":marks") -- Messages map("n", "m", ":messages") --- Clear messages or just refresh/redraw the screen map("n", "i", function() local ok, notify = pcall(require, "notify") if ok then notify.dismiss() end end) -- Toggle set number map("n", "$", ":NumbersToggle") map("n", "%", ":NumbersOnOff") -- Easier split navigations, just ctrl-j instead of ctrl-w then j map("t", "", "") map("t", "", "") map("t", "", "") map("t", "", "") map("t", "", "") -- Split window map("n", "-", ":split") map("n", "\\", ":vsplit") -- Close window --map("n", "c", "c") map({ "n", "t", "c" }, "c", function() local winid = vim.api.nvim_get_current_win() local config = vim.api.nvim_win_get_config(winid) if config.relative ~= "" then -- This is a floating window vim.cmd("CloseFloatingWindows") else -- Not a float/close window vim.cmd("close") end end, { desc = "Close current float or all floating windows" }) -- Resize Panes map("n", "<", ":vertical resize +5") map("n", ">", ":vertical resize -5") map("n", "=", "=") -- Mapping for left and right arrow keys in command-line mode vim.api.nvim_set_keymap("c", "", "", { noremap = true, silent = false }) -- Left Arrow vim.api.nvim_set_keymap("c", "", "", { noremap = true, silent = false }) -- Right Arrow -- Map Alt+(h/j/k/l) in insert(include terminal/command) mode to move directional map({ "i", "t" }, "", "") map({ "i", "t" }, "", "") map({ "i", "t" }, "", "") map({ "i", "t" }, "", "") -- Create tab, edit and move between them map("n", "n", ":tabnew") map("n", "e", ":tabedit") map("n", "[", ":tabprev") map("n", "]", ":tabnext") -- Vim TABs map("n", "1", "1gt") map("n", "2", "2gt") map("n", "3", "3gt") map("n", "4", "4gt") map("n", "5", "5gt") map("n", "6", "6gt") map("n", "7", "7gt") map("n", "8", "8gt") map("n", "9", "9gt") map("n", "0", "10gt") -- Hitting ESC when inside a terminal to get into normal mode --map("t", "", [[]]) -- Move block (indentation) easily --map("n", "<", "<<", term_opts) --map("n", ">", ">>", term_opts) --map("x", "<", "", ">gv", term_opts) --map("v", "<", "", ">gv") --map("n", "<", "<change mode to normal") --map("n", ">", ">change mode to normal") -- Visual mode: Indent and reselect the visual area, like default behavior but explicit map("v", "<", "", ">gv", { desc = "Indent right and reselect" }) -- Normal mode: Indent current line and enter Visual Line mode to repeat easily map("n", "<", "v<<", { desc = "Indent left and select" }) map("n", ">", "v>>", { desc = "Indent right and select" }) ---- Visual mode: Indent and reselect the visual area, like default behavior but explicit --map("v", "<", "<", { desc = "Indent left" }) --map("v", ">", ">", { desc = "Indent right" }) -- ---- Normal mode: Indent current line and enter Visual Line mode to repeat easily --map("n", "<", "v<<", { desc = "Indent left and select" }) --map("n", ">", "v>>", { desc = "Indent right and select" }) -- Set alt+(j/k) to switch lines of texts or simply move them map("n", "", ':let save_a=@a"add"ap:let @a=save_a') map("n", "", ':let save_a=@a"add"ap:let @a=save_a') -- Toggle Diff map("n", "df", "call utils#ToggleDiff()") -- Toggle Verbose map("n", "uvt", "call utils#VerboseToggle()") -- Jump List map("n", "j", "call utils#GotoJump()") -- Rename file map("n", "rf", "call utils#RenameFile()") -- Map delete to Ctrl+l map("i", "", "") -- Clear screen map("n", "", "!clear") -- Change file to an executable map("n", "x", ":lua require('user.mods').Toggle_executable() | :echom ('Toggle executable') | :sl! | echo ('')") -- map("n", "x", ":!chmod +x %") vim.keymap.set("n", "cm", function() vim.cmd("redir @+") vim.cmd("silent messages") vim.cmd("redir END") vim.notify("Copied :messages to clipboard") end, { desc = "Copy :messages to clipboard" }) -- Paste without replace clipboard map("v", "p", '"_dP') map("n", "]p", 'm`o"+p``', opts) map("n", "[p", 'm`O"+p``', opts) -- Bind Ctrl-V to paste in insert/normal/command mode map("i", "", "u+", opts) map("n", "", '"+p', { noremap = true, silent = true }) vim.api.nvim_set_keymap("c", "", "=getreg('+')", { noremap = true, silent = false }) -- Change Working Directory to current project map("n", "cd", ":cd %:p:h:pwd") -- Search and replace map("v", "sr", 'y:%s/"//gc') -- Substitute globally and locally in the selected region. map("n", "s", ":%s//g") map("v", "s", ":s//g") -- Set line wrap map("n", "", function() local wrap_status = vim.api.nvim_exec("set wrap ?", true) if wrap_status == "nowrap" then vim.api.nvim_command("set wrap linebreak") print("Wrap enabled") else vim.api.nvim_command("set wrap nowrap") print("Wrap disabled") end end, { silent = true }) -- Toggle between folds map("n", "", "&foldlevel ? 'zM' : 'zR'", { expr = true }) -- Use space to toggle fold --map("n", "", "za") map("n", ".b", ":!cp % %.backup") -- Go to next window map("n", "wn", "w", { desc = "Next window" }) -- Go to previous window map("n", "wp", "W", { desc = "Previous window" }) -- Toggle transparency map("n", "tb", ":call utils#Toggle_transparent_background()") -- Toggle zoom map("n", "z", ":call utils#ZoomToggle()") map("n", "z", "|_") -- Toggle statusline map("n", "sl", ":call utils#ToggleHiddenAll()") -- Open last closed buffer map("n", "", ":call utils#OpenLastClosed()") -- Automatically set LSP keymaps when LSP attaches to a buffer --vim.api.nvim_create_autocmd("LspAttach", { -- callback = function(args) -- local bufnr = args.buf -- local opts = { buffer = bufnr } -- map("n", "K", vim.lsp.buf.hover) -- map("n", "gd", "lua require('goto-preview').goto_preview_definition()") -- map("n", "gi", "lua require('goto-preview').goto_preview_implementation()") -- map("n", "gr", "lua require('goto-preview').goto_preview_references()") -- map("n", "gD", vim.lsp.buf.declaration) -- map("n", "k", vim.lsp.buf.signature_help) -- map("n", "gt", "lua require('goto-preview').goto_preview_type_definition()") -- map("n", "gn", vim.lsp.buf.rename) -- map("n", "ga", vim.lsp.buf.code_action) -- map("n", "gf", function() vim.lsp.buf.format({ async = true }) end) -- map("n", "go", vim.diagnostic.open_float) -- map("n", "go", ":call utils#ToggleDiagnosticsOpenFloat() | :echom ('Toggle Diagnostics Float open/close...') | :sl! | echo ('')") -- map("n", "gq", vim.diagnostic.setloclist) -- map("n", "[d", vim.diagnostic.goto_prev) -- map("n", "]d", vim.diagnostic.goto_next) -- map("n", "gs", vim.lsp.buf.document_symbol) -- map("n", "gw", vim.lsp.buf.workspace_symbol) -- map("n", "wa", vim.lsp.buf.add_workspace_folder) -- map("n", "wr", vim.lsp.buf.remove_workspace_folder) -- map("n", "wl", function() -- print(vim.inspect(vim.lsp.buf.list_workspace_folders())) -- end) -- end, --}) ---- LSP Global Keymaps (available in all buffers) --map("n", "[d", vim.diagnostic.goto_prev, { desc = "LSP: Previous Diagnostic" }) --map("n", "]d", vim.diagnostic.goto_next, { desc = "LSP: Next Diagnostic" }) --map("n", "go", vim.diagnostic.open_float, { desc = "LSP: Open Diagnostic Float" }) -- ---- LSP Buffer-local keymaps function (to be called from LSP on_attach) --_G.setup_lsp_keymaps = function(bufnr) -- local bmap = function(mode, l, r, opts) -- opts = opts or {} -- opts.silent = true -- opts.noremap = true -- opts.buffer = bufnr -- vim.keymap.set(mode, l, r, opts) -- end -- -- bmap("n", "K", vim.lsp.buf.hover, { desc = "LSP: Hover Documentation" }) -- bmap("n", "gd", vim.lsp.buf.definition, { desc = "LSP: Go to Definition" }) -- bmap("n", "gD", vim.lsp.buf.declaration, { desc = "LSP: Go to Declaration" }) -- bmap("n", "gi", vim.lsp.buf.implementation, { desc = "LSP: Go to Implementation" }) -- bmap("n", "gt", vim.lsp.buf.type_definition, { desc = "LSP: Go to Type Definition" }) -- bmap("n", "gr", vim.lsp.buf.references, { desc = "LSP: Go to References" }) -- bmap("n", "gn", vim.lsp.buf.rename, { desc = "LSP: Rename" }) -- bmap("n", "ga", vim.lsp.buf.code_action, { desc = "LSP: Code Action" }) -- bmap("n", "k", vim.lsp.buf.signature_help, { desc = "LSP: Signature Help" }) -- bmap("n", "gs", vim.lsp.buf.document_symbol, { desc = "LSP: Document Symbols" }) --end -- LSP Global Keymaps (available in all buffers) map("n", "[d", vim.diagnostic.goto_prev, { desc = "LSP: Previous Diagnostic" }) map("n", "]d", vim.diagnostic.goto_next, { desc = "LSP: Next Diagnostic" }) map("n", "go", vim.diagnostic.open_float, { desc = "LSP: Open Diagnostic Float" }) map("n", "go", ":call utils#ToggleDiagnosticsOpenFloat() | :echom ('Toggle Diagnostics Float open/close...') | :sl! | echo ('')") -- LSP Buffer-local keymaps function (to be called from LSP on_attach) _G.setup_lsp_keymaps = function(bufnr) local bmap = function(mode, l, r, opts) opts = opts or {} opts.silent = true opts.noremap = true opts.buffer = bufnr vim.keymap.set(mode, l, r, opts) end -- Your preferred keybindings bmap("n", "K", function() vim.lsp.buf.hover { border = "single", max_height = 25, max_width = 120 } end, { desc = "LSP: Hover Documentation" }) bmap("n", "gd", function() vim.lsp.buf.definition { on_list = function(options) -- Custom logic to avoid showing multiple definitions for Lua patterns like: -- `local M.my_fn_name = function() ... end` local unique_defs = {} local def_loc_hash = {} for _, def_location in pairs(options.items) do local hash_key = def_location.filename .. def_location.lnum if not def_loc_hash[hash_key] then def_loc_hash[hash_key] = true table.insert(unique_defs, def_location) end end options.items = unique_defs vim.fn.setloclist(0, {}, " ", options) -- Open location list if multiple definitions, otherwise jump directly if #options.items > 1 then vim.cmd.lopen() else vim.cmd([[silent! lfirst]]) end end, } end, { desc = "LSP: Go to Definition" }) bmap("n", "", vim.lsp.buf.definition, { desc = "LSP: Go to Definition (Alt)" }) bmap("n", "gD", vim.lsp.buf.declaration, { desc = "LSP: Go to Declaration" }) bmap("n", "gi", vim.lsp.buf.implementation, { desc = "LSP: Go to Implementation" }) bmap("n", "gt", vim.lsp.buf.type_definition, { desc = "LSP: Go to Type Definition" }) bmap("n", "gr", vim.lsp.buf.references, { desc = "LSP: Go to References" }) bmap("n", "gn", vim.lsp.buf.rename, { desc = "LSP: Rename" }) bmap("n", "rn", vim.lsp.buf.rename, { desc = "LSP: Rename (Alt)" }) bmap("n", "ga", vim.lsp.buf.code_action, { desc = "LSP: Code Action" }) bmap("n", "ca", vim.lsp.buf.code_action, { desc = "LSP: Code Action (Alt)" }) bmap("n", "k", vim.lsp.buf.signature_help, { desc = "LSP: Signature Help" }) bmap("n", "", vim.lsp.buf.signature_help, { desc = "LSP: Signature Help (Alt)" }) bmap("n", "gs", vim.lsp.buf.document_symbol, { desc = "LSP: Document Symbols" }) -- Workspace folder management bmap("n", "wa", vim.lsp.buf.add_workspace_folder, { desc = "LSP: Add Workspace Folder" }) bmap("n", "wr", vim.lsp.buf.remove_workspace_folder, { desc = "LSP: Remove Workspace Folder" }) bmap("n", "wl", function() vim.print(vim.lsp.buf.list_workspace_folders()) end, { desc = "LSP: List Workspace Folders" }) end ---------------- Plugin Operations ---------------- -- Packer map("n", "Pc", "PackerCompile") map("n", "Pi", "PackerInstall") map("n", "Ps", "PackerSync") map("n", "PS", "PackerStatus") map("n", "Pu", "PackerUpdate") -- ToggleTerm map({ "n", "t" }, "tt", "ToggleTerm") map({ "n", "t" }, "th", "lua Horizontal_term_toggle()") map({ "n", "t" }, "tv", "lua Vertical_term_toggle()") -- LazyGit map({ "n", "t" }, "gg", "lua Lazygit_toggle()") map("n", "tg", "lua Gh_dash()") -- Fugitive git bindings map("n", "gs", vim.cmd.Git) map("n", "ga", ":Git add %:p") --map("n", "gs", ":Gstatus") --map("n", "gc", ":Gcommit -v -q") map("n", "gt", ":Gcommit -v -q %:p") map("n", "gd", ":Gdiff") map("n", "ge", ":Gedit") --map("n", "gr", ":Gread") map("n", "gw", ":Gwrite") map("n", "gl", ":silent! Glog:bot copen") --map("n", "gp", ":Ggrep") --map("n", "gp", ":Git push") --map("n", "gb", ":Gblame") map("n", "gm", ":Gmove") --map("n", "gb", ":Git branch") --map("n", "go", ":Git checkout") --map("n", "gps", ":Dispatch! git push") --map("n", "gpl", ":Dispatch! git pull") -- Telescope -- Safe load of your custom Telescope module -- This initial pcall for "plugins.telescope" is fine because it just checks if YOUR module is there. -- The actual checks for Telescope's core modules happen *inside* your wrapper functions when called. local telescope_ok, telescope_module = pcall(require, "plugins.telescope") if telescope_ok and telescope_module then -- Direct function calls from your plugins.telescope module -- M.safe_find_files handles its own internal `builtin` check map("n", "ff", telescope_module.safe_find_files, { desc = "Find files" }) -- For `find all files`, use your `safe_telescope_builtin` wrapper -- You need to wrap it in a function to pass the options correctly. map("n", "f.", function() telescope_module.safe_telescope_builtin("find_files")({ hidden = true, no_ignore = true }) end, { desc = "Find all files" }) --- --- Built-in Telescope functions --- Note: safe_telescope_builtin returns a function, so you map directly to it. --- map("n", "fg", function() telescope_module.safe_telescope_builtin("live_grep")() end, { desc = "Live grep" }) map("n", "fb", function() telescope_module.safe_telescope_builtin("buffers")() end, { desc = "Find buffers" }) map("n", "fh", function() telescope_module.safe_telescope_builtin("help_tags")() end, { desc = "Help tags" }) map("n", "fc", function() telescope_module.safe_telescope_builtin("commands")() end, { desc = "Commands" }) map("n", "fd", function() telescope_module.safe_telescope_builtin("diagnostics")() end, { desc = "Diagnostics" }) map("n", "fk", function() telescope_module.safe_telescope_builtin("keymaps")() end, { desc = "Keymaps" }) map("n", "fr", function() telescope_module.safe_telescope_builtin("registers")() end, { desc = "Registers" }) map("n", "ffc", function() telescope_module.safe_telescope_builtin("current_buffer_fuzzy_find")() end, { desc = "Current buffer fuzzy find" }) -- Corrected the previous `fp` mapping that pointed to `pickers` map("n", "fp", function() telescope_module.safe_telescope_builtin("oldfiles")() end, { desc = "Recently opened files" }) --- --- Telescope Extension functions --- Note: safe_telescope_extension returns a function, so you map directly to it. --- map("n", "cf", function() telescope_module.safe_telescope_extension("changed_files", "changed_files")() end, { desc = "Changed files" }) map("n", "fm", function() telescope_module.safe_telescope_extension("media_files", "media_files")() end, { desc = "Media files" }) map("n", "fi", function() telescope_module.safe_telescope_extension("notify", "notify")() end, { desc = "Notifications" }) map("n", "fs", function() telescope_module.safe_telescope_extension("session-lens", "search_session")() end, { desc = "Search sessions" }) map("n", "frf", function() telescope_module.safe_telescope_extension("recent_files", "pick")() end, { desc = "Recent files" }) map("n", "f/", function() telescope_module.safe_telescope_extension("file_browser", "file_browser")() end, { desc = "File browser" }) --- --- Custom functions defined in plugins.telescope.lua --- Note: safe_telescope_call returns a function, so you map directly to it. --- (These were already correct as safe_telescope_call returns a callable function) --- map("n", "ffd", telescope_module.safe_telescope_call("plugins.telescope", "find_dirs"), { desc = "Find directories" }) map("n", "ff.", telescope_module.safe_telescope_call("plugins.telescope", "find_configs"), { desc = "Find configs" }) map("n", "ffs", telescope_module.safe_telescope_call("plugins.telescope", "find_scripts"), { desc = "Find scripts" }) map("n", "ffw", telescope_module.safe_telescope_call("plugins.telescope", "find_projects"), { desc = "Find projects" }) map("n", "ffB", telescope_module.safe_telescope_call("plugins.telescope", "find_books"), { desc = "Find books" }) map("n", "ffn", telescope_module.safe_telescope_call("plugins.telescope", "find_notes"), { desc = "Find notes" }) map("n", "fgn", telescope_module.safe_telescope_call("plugins.telescope", "grep_notes"), { desc = "Grep notes" }) map("n", "fpp", telescope_module.safe_telescope_call("plugins.telescope", "find_private"), { desc = "Find private notes" }) map("n", "fgc", telescope_module.safe_telescope_call("plugins.telescope", "grep_current_dir"), { desc = "Grep current directory" }) end ---- Fallback keymaps when telescope is not available --map("n", "ff", function() -- local file = vim.fn.input("Open file: ", "", "file") -- if file ~= "" then -- vim.cmd("edit " .. file) -- end --end, { desc = "Find files (fallback)" }) ---- You can add other basic fallbacks here --map("n", "fg", function() -- vim.notify("Live grep requires telescope plugin", vim.log.levels.WARN) --end, { desc = "Live grep (unavailable)" }) ----end map("n", "fF", ":cd %:p:h:pwdlua require('user.mods').findFilesInCwd()", { noremap = true, silent = true, desc = "Find files in cwd" }) -- FZF map("n", "fz", function() local ok, fzf_lua = pcall(require, "fzf-lua") if ok then fzf_lua.files() -- no config, just open else local handle = io.popen("find . -type f | fzf") if handle then local result = handle:read("*a") handle:close() result = result:gsub("\n", "") if result ~= "" then vim.cmd("edit " .. vim.fn.fnameescape(result)) end else vim.notify("fzf not found or failed to run", vim.log.levels.ERROR) end end end, { desc = "FZF file picker (fzf-lua or fallback)" }) map("n", "gA", ":FzfLua lsp_code_actions") -- Nvim-tree local function safe_nvim_tree_toggle() local ok_tree, tree_api = pcall(require, "nvim-tree.api") if ok_tree then pcall(vim.cmd, "Rooter") -- silently run Rooter if available tree_api.tree.toggle() else -- Fallback to netrw local cur_buf = vim.api.nvim_get_current_buf() local ft = vim.api.nvim_get_option_value("filetype", { buf = cur_buf }) if ft == "netrw" then vim.cmd("close") else vim.cmd("Lexplore") end end end map("n", "f", safe_nvim_tree_toggle, { desc = "Toggle file explorer" }) -- Undotree map("n", "u", vim.cmd.UndotreeToggle) -- Markdown-preview map("n", "md", "MarkdownPreviewToggle") map("n", "mg", "Glow") -- Autopairs map("n", "ww", "lua require('user.mods').Toggle_autopairs()") -- Zen-mode toggle map("n", "zm", "ZenMode | :echom ('Zen Mode') | :sl! | echo ('')") -- Vim-rooter local function safe_project_root() if vim.fn.exists(":Rooter") == 2 then vim.cmd("Rooter") else vim.cmd("cd %:p:h") end end vim.keymap.set("n", "ro", safe_project_root, { desc = "Project root" }) -- Trouble (UI to show diagnostics) local function safe_trouble_toggle(view, opts) local ok, _ = pcall(require, "trouble") if ok then local cmd = "Trouble" if view then cmd = cmd .. " " .. view .. " toggle" if opts then cmd = cmd .. " " .. opts end else cmd = cmd .. " diagnostics toggle" end vim.cmd(cmd) else vim.cmd("copen") end end -- Replace 'map' with 'vim.keymap.set' if not already a global alias vim.keymap.set("n", "t", function() safe_trouble_toggle() end, { desc = "Diagnostics (Workspace)" }) vim.keymap.set("n", "tw", function() vim.cmd("cd %:p:h | pwd") safe_trouble_toggle("diagnostics") end, { desc = "Diagnostics (Workspace)" }) vim.keymap.set("n", "td", function() vim.cmd("cd %:p:h | pwd") safe_trouble_toggle("diagnostics", "filter.buf=0") end, { desc = "Diagnostics (Buffer)" }) vim.keymap.set("n", "tq", function() vim.cmd("cd %:p:h | pwd") safe_trouble_toggle("qflist") end, { desc = "Quickfix List" }) vim.keymap.set("n", "tl", function() vim.cmd("cd %:p:h | pwd") safe_trouble_toggle("loclist") end, { desc = "Location List" }) vim.keymap.set("n", "gR", function() safe_trouble_toggle("lsp") end, { desc = "LSP References/Definitions" }) -- Null-ls map("n", "ls", ':lua require("null-ls").toggle({})') -- Replacer map("n", "qr", ':lua require("replacer").run()') -- Quickfix map("n", "q", function() if vim.fn.getqflist({ winid = 0 }).winid ~= 0 then require("plugins.quickfix").close() else require("plugins.quickfix").open() end end, { desc = "Toggle quickfix window" }) -- Move to the next and previous item in the quickfixlist map("n", "]c", "cnext") map("n", "[c", "cprevious") -- Location list map("n", "l", 'lua require("plugins.loclist").loclist_toggle()') -- Dap (debugging) local dap_ok, dap = pcall(require, "dap") local dap_ui_ok, ui = pcall(require, "dapui") if not (dap_ok and dap_ui_ok) then --require("notify")("nvim-dap or dap-ui not installed!", "warning") return end vim.fn.sign_define("DapBreakpoint", { text = "🐞" }) -- Start debugging session map("n", "ds", function() dap.continue() ui.toggle({}) vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("=", false, true, true), "n", false) -- Spaces buffers evenly end) -- Set breakpoints, get variable values, step into/out of functions, etc. map("n", "dC", dap.continue) -- map("n", "dC", dap.close) -- map("n", "dt", dap.terminate) map("n", "dt", ui.toggle) map("n", "dd", function() dap.disconnect({ terminateDebuggee = true }) end) map("n", "dn", dap.step_over) map("n", "di", dap.step_into) map("n", "do", dap.step_out) map("n", "db", dap.toggle_breakpoint) map("n", "dB", function() dap.clear_breakpoints() require("notify")("Breakpoints cleared", "warn") end) map("n", "dl", function() local ok, dap_widgets = pcall(require, "dap.ui.widgets") if ok then dap_widgets.hover() end end) map("n", "de", function() require("dapui").float_element() end, { desc = "Open Element" }) map("n", "dq", function() require("dapui").close() require("dap").repl.close() local session = require("dap").session() if session then require("dap").terminate() end require("nvim-dap-virtual-text").refresh() end, { desc = "Terminate Debug" }) map("n", "dc", function() require("telescope").extensions.dap.commands() end, { desc = "DAP-Telescope: Commands" }) --vim.keymap.set("n", "B", ":lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: '))") --vim.keymap.set("v", "B", ":lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: '))") --vim.keymap.set("n", "lp", ":lua require'dap'.set_breakpoint(nil, nil, vim.fn.input('Log point message: '))") --vim.keymap.set("n", "dr", ":lua require'dap'.repl.open()") -- Close debugger and clear breakpoints --map("n", "de", function() -- dap.clear_breakpoints() -- ui.toggle({}) -- dap.terminate() -- vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("=", false, true, true), "n", false) -- require("notify")("Debugger session ended", "warn") --end) -- Toggle Dashboard map("n", "", 'lua require("user.mods").toggle_dashboard()') -- Lsp Lines toggle map("", "ll", require("lsp_lines").toggle, { desc = "Toggle lsp_lines" }) -- SnipRun map({ "n", "v" }, "r", "SnipRun") -- Codi map("n", "co", 'lua require("user.mods").toggleCodi()') -- Scratch buffer map("n", "ss", 'lua require("user.mods").Scratch("float")') map("n", "sh", 'lua require("user.mods").Scratch("horizontal")') map("n", "sv", 'lua require("user.mods").Scratch("vertical")') -- Hardtime map("n", "H", 'lua require("plugins.hardtime").ToggleHardtime()') -- Code Run map("n", "rr", 'lua require("user.mods").toggleCodeRunner()') -- Run executable file map("n", "rx", ":lua require('user.mods').RunCurrentFile():echom 'Running executable file...':sl!:echo ''") -- Set Files to current location as dir map({ "n" }, "cf", "e %:h") -- Vimtex map("n", "lc", ":VimtexCompile") map("v", "ls", ":VimtexCompileSelected") map("n", "li", ":VimtexInfo") map("n", "lt", ":VimtexTocToggle") map("n", "lv", ":VimtexView")