local M = {} local wk = require('which-key') local api, notify = vim.api, vim.notify local opts = {noremap = true, silent = true} ------------------------------- -- Globally defined mappings -- ------------------------------- local normal_mappings = { -- Easier start and end of line H = {'^', 'Start of the line'}, L = {'$', 'End of the line'}, -- Close a window [''] = {'q', 'Quit current window'}, -- Close current buffer [''] = {':bdelete', 'Close current buffer'}, -- Copy the whole buffer [''] = {':%y+', 'Copy whole buffer'}, -- Remove trailing whitespace [''] = {':%s/\\s\\+$//e', 'Remove trailing'}, -- Resize buffer [''] = {':resize -2', 'Resize vertical -2'}, [''] = {':resize +2', 'Resize vertical +2'}, [''] = {':vertical resize -2', 'Resize horizontal -2'}, [''] = {':vertical resize +2', 'Resize horizontal +2'}, -- Switch between tabs and spaces [''] = { function() if vim.opt.expandtab:get() then vim.opt.expandtab = false vim.opt.smarttab = false vim.opt.softtabstop = 0 -- reset to default notify('Indent with Tabs.', vim.log.levels.INFO) else vim.opt.expandtab = true vim.opt.smarttab = true vim.opt.softtabstop = -1 -- fallback to shiftwidth notify('Indent with Spaces.', vim.log.levels.INFO) end end, 'Switch indent style' }, -- Naming common keys ['['] = { name = 'Block motions (previous)', g = 'Previous git hunk' }, [']'] = { name = 'Block motions (next)', g = 'Next git hunk' }, g = { name = 'Goto motions', t = {':TodoTrouble', 'Todo list'} }, z = {name = 'Misc utils'}, -- Move between tabs [''] = {':BufferLineCycleNext', 'Next buffer'}, [''] = {':BufferLineCyclePrev', 'Previous buffer'}, -- ToggleTerm [''] = {':ToggleTerm', 'Toggle terminal'}, [''] = {':ToggleTerm direction=float', 'Toggle float terminal'}, -- hop.nvim S = {':HopWord', 'Hop to word'}, [''] = {':HopChar1', 'Hop to character'}, [''] = {':HopPattern', 'Hop to pattern'} } local normal_leader_mappings = { d = { name = 'DAP', b = 'Toggle breakpoint', B = 'Set breakpoint with condition', c = 'Run to cursor', d = 'Disconnect adapter', e = 'Hover under cursor (UI)', f = 'Open float window (UI)', i = 'Step into function/method', l = 'List breakpoints', n = 'Resume the execution', o = 'Step out of function/method', r = 'Inspect in REPL', t = 'Toggle UI', v = 'Run again 1 step', z = 'Re-run the last adapter' }, e = { name = 'Editor', a = {':EasyAlign', 'Align elements'}, g = 'Generate annotations', h = {':TSHighlightCapturesUnderCursor', 'Syntax under cursor'}, s = {':ISwapWith', 'Swap elements'}, t = {':TableModeToggle', 'Toggle table mode'}, v = { function() local venn_enabled = vim.inspect(vim.b.venn_enabled) if venn_enabled == 'nil' then vim.b.venn_enabled = true api.nvim_command('setlocal virtualedit=all') -- Draw lines with WASD keystroke api.nvim_buf_set_keymap(0, 'n', 'A', 'h:VBox', opts) api.nvim_buf_set_keymap(0, 'n', 'S', 'j:VBox', opts) api.nvim_buf_set_keymap(0, 'n', 'W', 'k:VBox', opts) api.nvim_buf_set_keymap(0, 'n', 'D', 'l:VBox', opts) -- Draw boxes by pressing 'f' with visual selection api.nvim_buf_set_keymap(0, 'v', 'f', ':VBox', opts) notify('Virtual box edit enabled.', vim.log.levels.INFO) else vim.b.venn_enabled = nil api.nvim_command('setlocal virtualedit=block') api.nvim_buf_del_keymap(0, 'v', 'f') api.nvim_buf_del_keymap(0, 'n', 'A') api.nvim_buf_del_keymap(0, 'n', 'S') api.nvim_buf_del_keymap(0, 'n', 'W') api.nvim_buf_del_keymap(0, 'n', 'D') notify('Virtual box edit disabled.', vim.log.levels.INFO) end end, 'Toggle virtual box edit' }, z = {':ZenMode', 'Zen mode'}, Z = {':Twilight', 'Twilight mode'} }, f = { name = 'Telescope', a = {':Telescope autocommands', 'Autocommands'}, b = {':Telescope buffers', 'Buffers'}, c = {':Telescope commands', 'Commands'}, d = {':Telescope projects', 'Recent directories'}, e = {':Telescope file_browser', 'File browser'}, f = {':Telescope find_files', 'Find files'}, g = {':Telescope live_grep', 'Live grep'}, h = {':Telescope help_tags', 'Help tags'}, i = {':Telescope highlights', 'Highlight groups'}, j = { name = 'Symbols', g = 'Gitmoji', h = {':Telescope symbols', 'All symbols'}, j = 'Emoji', k = 'Kaomoji', l = 'Julia', m = 'Math symbols', n = 'Nerd-fonts symbols', t = 'Latex symbols' }, k = {':Telescope keymaps', 'Normal keymaps'}, l = {':Telescope notify', 'Notification history'}, m = {':Telescope marks', 'Bookmarks'}, n = {':Telescope man_pages', 'Man pages'}, o = {':Telescope oldfiles', 'Recent files'}, p = {':Telescope project display_type=full', 'Projects'}, r = {':Telescope reloader', 'Reload lua modules'}, s = {':Telescope treesitter', 'Treesitter'}, t = {':TodoTelescope', 'Todo list'}, u = {':Telescope current_buffer_fuzzy_find', 'Search current buffer'}, v = {':Telescope vim_options', 'Vim options'}, x = { name = 'Tasks', a = {':Telescope yabs tasks', 'All tasks'}, g = {':Telescope yabs global_tasks', 'Global tasks'}, l = {':Telescope yabs current_language_tasks', 'Tasks for current filetype'}, t = {':YabsDefaultTask', 'Run default task'} }, y = {':Telescope filetypes', 'Filetypes'}, z = {':Telescope registers', 'Vim registers'} }, g = { name = 'Git', a = {':Telescope git_stash', 'Stash'}, b = 'Blame current line', c = {':Telescope git_bcommits', 'Buffer commits'}, C = {':Telescope git_commits', 'Commits'}, m = {':Telescope git_branches', 'Branches'}, n = {':Neogit', 'Neogit'}, p = 'Preview hunk', r = 'Reset hunk', R = 'Reset all hunks in buffer', s = 'Stage hunk', S = 'Stage buffer', t = {':Telescope git_status', 'Status'}, u = 'Undo hunk', U = 'Reset buffer index', y = 'Get remote url for cursorline', Y = 'Get remote url' }, j = { name = 'Translate', t = {':Trans', 'Translate'}, d = {':TransSelectDirection', 'Translate with direction'}, r = {'cw=system(\'trans -brief -no-ansi\', getreg(""))[:-2]', 'Translate and replace'}, c = {'cw=system(\'trans -brief -no-ansi :\', getreg(""))[:-2]', 'Translate and replace with direction'} }, n = {':NvimTreeToggle', 'NvimTree'}, p = { name = 'Find/Replace', o = 'Open spectre', p = 'Search in current file', w = 'Find/Replace cursorword' }, r = { name = 'REST', c = {'RestNvim', 'Run request under cursor'}, p = {'RestNvimPreview', 'Preview request cURL command'}, l = {'RestNvimLast', 'Re-run last request'} }, s = { name = 'Session', s = 'Save session for current directory', d = 'Stop automatically saving', l = 'Load last session', r = 'Load session for current directory' }, w = {':WindowPick', 'Pick window'} } local visual_leader_mappings = { e = { name = 'Editor', a = {':EasyAlign', 'Range align'} }, d = { name = 'DAP', e = 'Hover on range (UI)' }, g = { name = 'Git', r = 'Reset hunk', s = 'Stage hunk', y = 'Get remote url for range' }, j = { name = 'Translate', t = {':Trans', 'Translate'}, d = {':TransSelectDirection', 'Translate with direction'}, r = {'c=system(\'trans -brief -no-ansi\', getreg(""))[:-2]', 'Translate and replace'}, c = {'c=system(\'trans -brief -no-ansi :\', getreg(""))[:-2]', 'Translate and replace with direction'} }, p = 'Find/Replace' } local function undefined_mappings() -- Escape to normal mode in terminal buffer api.nvim_set_keymap('t', '', '', opts) -- Continuous indent api.nvim_set_keymap('v', '<', '', '>gv', opts) -- Also move up/down virtual lines (:set wrap) api.nvim_set_keymap('n', 'j', 'v:count == 0 ? "gj" : "j"', {noremap = true, expr = true, silent = true}) api.nvim_set_keymap('n', 'k', 'v:count == 0 ? "gk" : "k"', {noremap = true, expr = true, silent = true}) -- winshift.nvim api.nvim_set_keymap('n', '', ':WinShift', opts) api.nvim_set_keymap('n', 'm', ':WinShift', opts) api.nvim_set_keymap('n', '', ':WinShift left', opts) api.nvim_set_keymap('n', '', ':WinShift down', opts) api.nvim_set_keymap('n', '', ':WinShift up', opts) api.nvim_set_keymap('n', '', ':WinShift right', opts) end function M.setup() undefined_mappings() wk.register(normal_mappings) wk.register(normal_leader_mappings, {prefix = ''}) wk.register(visual_leader_mappings, {mode = 'v', prefix = ''}) end -------------------- -- Local mappings -- -------------------- function WhichkeyLocal() local bufnr = api.nvim_get_current_buf() wk.register({ c = {':ColorizerToggle', 'Colorizer'}, d = { name = 'Delete', a = {':BDelete all', 'All buffers'}, d = {':BDelete this', 'Current buffer'}, h = {':BDelete hidden', 'Hidden buffers'}, n = {':BDelete nameless', 'Buffers without name'}, o = {':BDelete other', 'Other buffers'} }, j = {':BufferLineCyclePrev', 'Previous buffer'}, k = {':BufferLineCycleNext', 'Next buffer'}, n = {':enew', 'New buffer'}, u = {':UndotreeToggle', 'Undotree'} }, {buffer = bufnr, prefix = ''}) end function WhichkeyMarkdown() wk.register({ p = {':MarkdownPreviewToggle', 'Preview markdown'} }, {buffer = api.nvim_get_current_buf(), prefix = ''}) end function WhichkeyHtml() wk.register({ p = {':Bracey', 'Preview html'} }, {buffer = api.nvim_get_current_buf(), prefix = ''}) end function WhichkeyOrg() wk.register({ ['o'] = { name = 'Org', a = 'Agenda', A = 'Toggle ARCHIVE', c = 'Capture', e = 'Export', i = { name = 'Insert', h = 'Add headline', t = 'Add TODO heading and content', T = 'Add TODO heading' }, J = 'Move subtree down', K = 'Move subtree up', o = 'Open at point', r = 'Refile', t = 'Set tags', ['$'] = 'Archive current headline' }, [''] = 'Org meta return', [''] = 'Org increase date', [''] = 'Org decrease date', ['cid'] = 'Org change date', ['cit'] = 'Org TODO', ['ciT'] = 'Org TODO prev', [''] = 'Org toggle checkbox', [''] = 'Org cycle folding', [''] = 'Org cycle global folding', ['<<'] = 'Org promote headline', ['>>'] = 'Org demote headline', ['s'] = 'Org demote subtree', ['}'] = 'Org next visible heading', ['{'] = 'Org previous visible heading', [']]'] = 'Org forward heading', ['[['] = 'Org backward heading', ['g{'] = 'Org parent heading', ['?'] = 'Org help' }, {buffer = api.nvim_get_current_buf()}) end ----------------------- -- Plugins' mappings -- ----------------------- function M.treesitter() local mappings = { ['['] = { m = 'Previous start of outer class', M = 'Previous end of outer class', ['['] = 'Previous start of outer function', [']'] = 'Previous end of outer function' }, [']'] = { m = 'Next start of outer class', M = 'Next end of outer class', ['['] = 'Next start of outer function', [']'] = 'Next end of outer function' }, g = { n = { name = 'Treesitter', d = 'Goto definition', D = 'List definitions', i = 'Initialize selection', j = 'Goto previous usage', k = 'Goto next usage', o = 'List definitions TOC', r = 'Rename within scope' } } } local visual_mappings = { a = { c = 'Outer class', f = 'Outer function' }, i = { c = 'Inner class', f = 'Inner function' }, g = { n = { name = 'Treesitter', n = 'Increment node', s = 'Increment scope', m = 'Decrement node' } } } wk.register(mappings) wk.register(visual_mappings, {mode = 'v'}) end function M.eft() api.nvim_set_keymap('n', 'f', '(eft-f)', {silent = true}) api.nvim_set_keymap('x', 'f', '(eft-f)', {silent = true}) api.nvim_set_keymap('n', 'F', '(eft-F)', {silent = true}) api.nvim_set_keymap('x', 'F', '(eft-F)', {silent = true}) api.nvim_set_keymap('n', 't', '(eft-t)', {silent = true}) api.nvim_set_keymap('x', 't', '(eft-t)', {silent = true}) api.nvim_set_keymap('n', 'T', '(eft-T)', {silent = true}) api.nvim_set_keymap('x', 'T', '(eft-T)', {silent = true}) api.nvim_set_keymap('n', ';', '(eft-repeat)', {silent = true}) api.nvim_set_keymap('x', ';', '(eft-repeat)', {silent = true}) end function M.dial() api.nvim_set_keymap('n', '', '(dial-increment)', {silent = true}) api.nvim_set_keymap('v', '', '(dial-increment)', {silent = true}) api.nvim_set_keymap('n', '', '(dial-decrement)', {silent = true}) api.nvim_set_keymap('v', '', '(dial-decrement)', {silent = true}) api.nvim_set_keymap('v', 'g', '(dial-increment-additional)', {silent = true}) api.nvim_set_keymap('v', 'g', '(dial-decrement-additional)', {silent = true}) end function M.neogen() api.nvim_set_keymap('n', 'eg', ':lua require("neogen").generate()', opts) api.nvim_set_keymap('n', '', ':lua require("neogen").jump_next()', opts) end function M.gitlinker() api.nvim_set_keymap('n', 'gY', ':lua require("gitlinker").get_repo_url()', opts) end function M.dap() api.nvim_set_keymap('n', 'dn', ':lua require("dap").continue()', opts) api.nvim_set_keymap('n', 'dd', ':lua require("dap").disconnect()', opts) api.nvim_set_keymap('n', 'db', ':lua require("dap").toggle_breakpoint()', opts) api.nvim_set_keymap('n', 'dB', ':lua require("dap").set_breakpoint(vim.fn.input("Breakpoint condition: "))', opts) api.nvim_set_keymap('n', 'dl', ':lua require("dap").list_breakpoints()', opts) api.nvim_set_keymap('n', 'dc', ':lua require("dap").run_to_cursor()', opts) api.nvim_set_keymap('n', 'dz', ':lua require("dap").run_last()', opts) api.nvim_set_keymap('n', '', ':lua require("dap").step_over()', opts) api.nvim_set_keymap('n', 'dv', ':lua require("dap").step_over()', opts) api.nvim_set_keymap('n', '', ':lua require("dap").step_into()', opts) api.nvim_set_keymap('n', 'di', ':lua require("dap").step_into()', opts) api.nvim_set_keymap('n', '', ':lua require("dap").step_out()', opts) api.nvim_set_keymap('n', 'do', ':lua require("dap").step_out()', opts) api.nvim_set_keymap('n', 'dr', ':lua require("dap").repl.open()', opts) end function M.dapui() api.nvim_set_keymap('n', 'de', ':lua require("dapui").eval()', opts) api.nvim_set_keymap('v', 'de', ':lua require("dapui").eval()', opts) api.nvim_set_keymap('n', 'df', ':lua require("dapui").float_element()', opts) api.nvim_set_keymap('n', 'dt', ':lua require("dapui").toggle()', opts) end function M.telescope_symbols() api.nvim_set_keymap('n', 'fjg', ':lua require("telescope.builtin").symbols{sources = {"gitmoji"}, prompt_title = "Gitmoji"}', opts) api.nvim_set_keymap('n', 'fjj', ':lua require("telescope.builtin").symbols{sources = {"emoji"}, prompt_title = "Emoji"}', opts) api.nvim_set_keymap('n', 'fjk', ':lua require("telescope.builtin").symbols{sources = {"kaomoji"}, prompt_title = "Kaomoji"}', opts) api.nvim_set_keymap('n', 'fjl', ':lua require("telescope.builtin").symbols{sources = {"julia"}, prompt_title = "Julia symbols"}', opts) api.nvim_set_keymap('n', 'fjm', ':lua require("telescope.builtin").symbols{sources = {"math"}, prompt_title = "Math symbols"}', opts) api.nvim_set_keymap('n', 'fjn', ':lua require("telescope.builtin").symbols{sources = {"nerd"}, prompt_title = "Nerd-fonts symbols"}', opts) api.nvim_set_keymap('n', 'fjt', ':lua require("telescope.builtin").symbols{sources = {"latex"}, prompt_title = "Latex symbols"}', opts) end function M.spectre() api.nvim_set_keymap('n', 'po', ':lua require("spectre").open()', opts) api.nvim_set_keymap('n', 'pp', 'viw:lua require("spectre").open_file_search()', opts) api.nvim_set_keymap('n', 'pw', ':lua require("spectre").open_visual({select_word = true})', opts) api.nvim_set_keymap('v', 'p', ':lua require("spectre").open_visual()', opts) end function M.persistence() api.nvim_set_keymap('n', 'ss', ':lua require("persistence").save()', opts) api.nvim_set_keymap('n', 'sd', ':lua require("persistence").stop()', opts) api.nvim_set_keymap('n', 'sl', ':lua require("persistence").load({last = true})', opts) api.nvim_set_keymap('n', 'sr', ':lua require("persistence").load()', opts) end return M