From 1b314768f16f2465e6c0182b15c5712908732a5a Mon Sep 17 00:00:00 2001 From: Cian Hughes Date: Tue, 14 Jul 2026 12:36:11 +0100 Subject: [PATCH] Moved keys.lua into fennel prefix trie --- devenv.nix | 8 +- fnl/config/keys.fnl | 259 ++++++++++++++++++ init.lua | 2 +- lua/config/keys.lua | 553 -------------------------------------- lua/keybindings.lua | 10 +- lua/plugins/telescope.lua | 2 +- lua/plugins/ui.lua | 2 - 7 files changed, 274 insertions(+), 562 deletions(-) create mode 100644 fnl/config/keys.fnl delete mode 100644 lua/config/keys.lua diff --git a/devenv.nix b/devenv.nix index dbcf1bf..2fbcb80 100644 --- a/devenv.nix +++ b/devenv.nix @@ -30,8 +30,9 @@ smoketest.exec = '' PROFILE_DIR="$PWD/.devenv/test-profile" + rm -rf "$PROFILE_DIR/nvim" mkdir -p "$PROFILE_DIR/nvim" "$PROFILE_DIR/data" "$PROFILE_DIR/state" "$PROFILE_DIR/cache" - find "$PWD" -maxdepth 1 ! -name ".git" ! -name ".devenv" ! -name ".direnv" ! -name "devenv.lock" ! -name "devenv.nix" ! -name "devenv.yaml" ! -name ".envrc" -exec ln -sfn {} "$PROFILE_DIR/nvim/" \; + find "$PWD" -maxdepth 1 ! -name ".git" ! -name ".devenv" ! -name ".direnv" ! -name "devenv.lock" ! -name "devenv.nix" ! -name "devenv.yaml" ! -name ".envrc" -exec cp -r {} "$PROFILE_DIR/nvim/" \; XDG_CONFIG_HOME="$PROFILE_DIR" \ XDG_DATA_HOME="$PROFILE_DIR/data" \ @@ -42,10 +43,11 @@ test-drive.exec = '' PROFILE_DIR="$PWD/.devenv/test-profile" + rm -rf "$PROFILE_DIR/nvim" mkdir -p "$PROFILE_DIR/nvim" "$PROFILE_DIR/data" "$PROFILE_DIR/state" "$PROFILE_DIR/cache" - # Symlink config files and folders to local sandbox config path - find "$PWD" -maxdepth 1 ! -name ".git" ! -name ".devenv" ! -name ".direnv" ! -name "devenv.lock" ! -name "devenv.nix" ! -name "devenv.yaml" ! -name ".envrc" -exec ln -sfn {} "$PROFILE_DIR/nvim/" \; + # Copy config files and folders to local sandbox config path + find "$PWD" -maxdepth 1 ! -name ".git" ! -name ".devenv" ! -name ".direnv" ! -name "devenv.lock" ! -name "devenv.nix" ! -name "devenv.yaml" ! -name ".envrc" -exec cp -r {} "$PROFILE_DIR/nvim/" \; echo "Starting test-drive of Neovim configuration in isolated sandbox..." echo "Caches, plugins, and state will be saved to: $PROFILE_DIR" diff --git a/fnl/config/keys.fnl b/fnl/config/keys.fnl new file mode 100644 index 0000000..3951059 --- /dev/null +++ b/fnl/config/keys.fnl @@ -0,0 +1,259 @@ +;; Helper functions for keybindings + +(fn require-and-run [module func] + (let [m (require module)] + ((. m func)))) + +(fn gitsigns-nav [chord dir] + (if vim.wo.diff + (vim.cmd.normal {1 chord :bang true}) + (let [gs (require :gitsigns)] + (gs.nav_hunk dir)))) + +(fn harpoon-select [idx] + (let [hp (require :harpoon)] + (: (hp:list) :select idx))) + +(fn trouble-nav [dir fallback-cmd] + (let [tr (require :trouble)] + (if (tr.is_open) + ((. tr dir) {:skip_groups true :jump true}) + (let [(ok err) (pcall vim.cmd fallback-cmd)] + (when (not ok) + (vim.notify err vim.log.levels.ERROR)))))) + +(fn toggle-lisp-tooling [] + (let [rm (require :rainbow-delimiters)] + (rm.toggle 0) + (let [active (rm.is_enabled 0) + buf (vim.api.nvim_get_current_buf) + lisp-fts ["clojure" "fennel" "scheme" "lisp" "janet" "racket" "hy" "elisp"] + filetype (vim.api.nvim_get_option_value :filetype {:buf buf})] + (if (vim.tbl_contains lisp-fts filetype) + (let [(has-paredit paredit-config) (pcall require :nvim-paredit.config)] + (if has-paredit + (let [keys paredit-config.config.keys] + (if active + (let [(has-kb keybindings) (pcall require :nvim-paredit.utils.keybindings)] + (if has-kb + (keybindings.setup_keybindings {:keys keys :buf buf}))) + (each [keymap action (pairs keys)] + (when action + (let [mode (or action.mode [:n :x]) + modes (if (= (type mode) :string) [mode] mode)] + (each [_ m (ipairs modes)] + (pcall vim.keymap.del m keymap {:buffer buf})))))))) + (vim.notify (.. "Lisp Tooling: " (if active "ON" "OFF")) vim.log.levels.INFO)) + (vim.notify (.. "Rainbow Delimiters: " (if active "ON" "OFF")) vim.log.levels.INFO))))) + +;; Define the keybindings prefix trie +(local trie + { + ;; Globals (No leader) + "" ["h" "Window Left" :globals] + "" ["j" "Window Down" :globals] + "" ["k" "Window Up" :globals] + "" ["l" "Window Right" :globals] + + "" ["+" "Resize Increase Height" :globals] + "" ["-" "Resize Decrease Height" :globals] + "" [">" "Resize Increase Width" :globals] + "" ["<" "Resize Decrease Width" :globals] + + "" ["s" "Split Window Horizontal" :globals] + "" ["x" "Swap Window" :globals] + "" [":q" "Close Window" :globals] + + "" ["nohlsearch" "Clear Highlight" :globals] + + ;; Atone + "U" [#(let [atone (require :atone.core)] (atone.toggle)) "[U]ndotree" :atone] + + ;; Gitsigns (no-leader) + "]c" [#(gitsigns-nav "]c" :next) "Next Hunk" :gitsigns {:expr true :mode :n}] + "[c" [#(gitsigns-nav "[c" :prev) "Previous Hunk" :gitsigns {:expr true :mode :n}] + + ;; Harpoon (no-leader Alt keys) + "" [#(harpoon-select 1) "Harpoon file 1" :harpoon] + "" [#(harpoon-select 2) "Harpoon file 2" :harpoon] + "" [#(harpoon-select 3) "Harpoon file 3" :harpoon] + "" [#(harpoon-select 4) "Harpoon file 4" :harpoon] + + ;; LSP (no-leader) + "K" [#(vim.lsp.buf.hover) "[K] Hover Documentation" :lsp] + "gd" [#(let [tb (require :telescope.builtin)] (tb.lsp_definitions)) "[G]oto [D]efinition" :lsp] + "ge" [#(vim.lsp.buf.declaration) "[G]oto D[e]claration" :lsp] + "gi" [#(let [tb (require :telescope.builtin)] (tb.lsp_implementations)) "[G]oto [I]mplementation" :lsp] + "gr" [#(let [tb (require :telescope.builtin)] (tb.lsp_references)) "[G]oto [R]eferences" :lsp] + "gt" [#(let [tb (require :telescope.builtin)] (tb.lsp_type_definitions)) "[G]oto [T]ype" :lsp] + + ;; Todo comments (no-leader) + "]t" [#(let [tc (require :todo-comments)] (tc.jump_next)) "Next Todo Comment" :todo_comments] + "[t" [#(let [tc (require :todo-comments)] (tc.jump_prev)) "Previous Todo Comment" :todo_comments] + + ;; Trouble (no-leader) + "[q" [#(trouble-nav :prev :cprev) "Previous Trouble/Quickfix Item" :trouble] + "]q" [#(trouble-nav :next :cnext) "Next Trouble/Quickfix Item" :trouble] + + ;; Leader mappings + "" + {:name "Leader" + ;; Agenda / Org Mode Group + "a" {:name "[A]genda" :icon "󰕪"} + ;; Search Group + "s" {:name "[S]earch" :icon "" + "h" [#(let [tb (require :telescope.builtin)] (tb.help_tags)) "[S]earch [H]elp" :telescope] + "k" [#(let [tb (require :telescope.builtin)] (tb.keymaps)) "[S]earch [K]eymaps" :telescope] + "f" [#(let [tb (require :telescope.builtin)] (tb.find_files)) "[S]earch [F]iles" :telescope] + "b" [#(let [tb (require :telescope.builtin)] (tb.buffers)) "[S]earch [B]uffers" :telescope] + "s" [#(let [tb (require :telescope.builtin)] (tb.builtin)) "[S]earch [S]elect Telescope" :telescope] + "w" [#(let [tb (require :telescope.builtin)] (tb.grep_string)) "[S]earch current [W]ord" :telescope] + "g" [#(let [tb (require :telescope.builtin)] (tb.live_grep)) "[S]earch by [G]rep" :telescope] + "d" [#(let [tb (require :telescope.builtin)] (tb.diagnostics)) "[S]earch [D]iagnostics" :telescope] + "r" [#(let [tb (require :telescope.builtin)] (tb.resume)) "[S]earch [R]esume" :telescope] + "." [#(let [tb (require :telescope.builtin)] (tb.oldfiles)) "[S]earch Recent Files (\".\" for repeat)" :telescope] + "/" [#(let [tb (require :telescope.builtin)] + (tb.live_grep {:grep_open_files true :prompt_title "Live Grep in Open Files"})) + "[S]earch [/] in Open Files" :telescope] + "n" [#(let [tb (require :telescope.builtin)] + (tb.find_files {:cwd (vim.fn.stdpath :config)})) + "[S]earch [N]eovim files" :telescope] + "t" ["TodoTelescope" "Todo" :todo_comments] + "T" ["TodoTelescope keywords=TODO,FIX,FIXME" "Todo/Fix/Fixme" :todo_comments] + } + + ;; Search buffer (not in s group but starts with /) + "/" [#(let [tb (require :telescope.builtin)] + (tb.current_buffer_fuzzy_find + ((. (require :telescope.themes) :get_dropdown) + {:winblend 10 :previewer false}))) + "[/] Fuzzily search in current buffer" :telescope] + + ;; Code Group + "c" {:name "[C]ode" :icon "" + "s" [#(let [tb (require :telescope.builtin)] (tb.lsp_document_symbols)) "[C]ode [S]ymbols" :lsp] + "w" [#(let [tb (require :telescope.builtin)] (tb.lsp_dynamic_workspace_symbols)) "[C]ode [W]orkspace Symbols" :lsp] + "d" [":lua require('neogen').generate()" "[C]ode Add [D]ocumentation" :neogen] + "i" [#(vim.lsp.inlay_hint.enable (not (vim.lsp.inlay_hint.is_enabled))) "[I]nlay Hints" :lsp] + "a" [#(vim.lsp.buf.code_action) "[C]ode [A]ction" :lsp] + } + + ;; Rename (leaf, not group) + "r" [#(vim.lsp.buf.rename) "[R]ename" :lsp] + + ;; Format (leaf, not group) + "f" [#(vim.lsp.buf.format) "[F]ormat" :lsp] + + ;; Diagnostics Group + "d" {:name "[D]iagnostics" :icon "" + "d" [#(vim.diagnostic.open_float) "Show [D]iagnostics" :globals] + } + + ;; Git Group + "g" {:name "[G]it" :icon "󰊢" + "s" [#(let [gs (require :gitsigns)] (gs.stage_hunk)) "[G]it [S]tage Hunk" :gitsigns {:mode [:n :v]}] + "r" [#(let [gs (require :gitsigns)] (gs.reset_hunk)) "[G]it [R]eset Hunk" :gitsigns {:mode [:n :v]}] + "p" [#(let [gs (require :gitsigns)] (gs.preview_hunk)) "[G]it [P]review Hunk" :gitsigns {:mode :n}] + "b" [#(let [gs (require :gitsigns)] (gs.blame_line)) "[G]it [B]lame Line" :gitsigns {:mode :n}] + } + + ;; Workspace Group (empty group for which-key) + "w" {:name "[W]orkspace" :icon ""} + + ;; Tree Group + "t" {:name "[T]ree" :icon "󱏒" + "t" [#(vim.api.nvim_command "Neotree toggle") "[T]ree [T]oggle" :neotree] + "s" [#(vim.api.nvim_command "Neotree show") "[T]ree [S]how" :neotree] + "c" [#(vim.api.nvim_command "Neotree close") "[T]ree [C]lose" :neotree] + "f" [#(vim.api.nvim_command "Neotree focus") "[T]ree [F]ocus" :neotree] + "g" [#(vim.api.nvim_command "Neotree git_status") "[T]ree [G]it Status" :neotree] + "b" [#(vim.api.nvim_command "Neotree buffers") "[T]ree [B]uffers" :neotree] + "e" [#(vim.cmd.Oil) "[T]ree [E]dit" :oil] + } + + ;; LazyGit Group + "l" {:name "[L]azyGit" :icon "󰒲" + "g" [#(let [s (require :snacks)] (s.lazygit)) "[L]azy[G]it" :lazygit] + "l" [#(let [s (require :snacks)] (s.lazygit.log)) "[L]azyGit [L]og" :lazygit] + "f" [#(let [s (require :snacks)] (s.lazygit.log_file)) "[L]azyGit [F]ile Log" :lazygit] + } + + ;; Overseer Group + "o" {:name "[O]verseer" :icon "󰈈" + "b" [#(vim.cmd.OverseerBuild) "[O]verseer [B]uild" :overseer] + "c" [#(vim.cmd.OverseerRunCmd) "[O]verseer Run [C]ommand" :overseer] + "r" [#(vim.cmd.OverseerRun) "[O]verseer [R]un" :overseer] + "t" [#(vim.cmd.OverseerToggle) "[O]verseer [T]oggle" :overseer] + } + + ;; Harpoon Group + "h" {:name "[H]arpoon" :icon "󱡀" + "a" [#(let [hp (require :harpoon)] (: (hp:list) :add)) "[H]arpoon [A]dd file" :harpoon] + "q" [#(let [hp (require :harpoon)] (: hp.ui :toggle_quick_menu (hp:list))) "[H]arpoon [Q]uick menu" :harpoon] + } + + ;; Trouble Group + "x" {:name "[X] Trouble" :icon "󰋔" + "t" ["Trouble todo toggle" "Todo" :todo_comments] + "T" ["Trouble todo toggle filter = {tag = {TODO,FIX,FIXME}}" "Todo/Fix/Fixme" :todo_comments] + "x" ["Trouble diagnostics toggle" "Diagnostics" :trouble] + "X" ["Trouble diagnostics toggle filter.buf=0" "Buffer Diagnostics" :trouble] + "s" ["Trouble symbols toggle" "Symbols (Trouble)" :trouble] + "S" ["Trouble lsp toggle" "LSP references/definitions/... (Trouble)" :trouble] + "L" ["Trouble loclist toggle" "Location List" :trouble] + "Q" ["Trouble qflist toggle" "Quickfix List" :trouble] + } + + ;; Rainbow Delimiters / Lisp tooling + "(" [#(toggle-lisp-tooling) "Toggle Lisp Tooling (Rainbow & Paredit)" :rainbow_delimiters] + + ;; Precognition (empty group for which-key) + "p" {:name "[P]recognition" :icon "󰬯"} + + ;; Cheatsheet (empty group for which-key) + "?" {:name "[?] Cheatsheet" :icon "󰧹"} + } + + ;; Local Leader + "" + {:name "[L]ocal Leader (\\\\)" :icon "" + "x" {:name "Local [X] UV" :icon ""} + } + }) + +;; Flatten/parse the prefix trie into the flat representation for Neovim config +(local M {:groups []}) + +(fn traverse [node prefix] + (if (= (type node) :table) + (if (. node 1) + ;; Leaf node: [rhs description plugin-name opts] + (let [[rhs desc ?plugin ?opts] node + plugin (or ?plugin :globals) + opts (or ?opts {}) + entry (collect [k v (pairs opts)] (values k v))] + (tset entry 1 prefix) + (tset entry 2 rhs) + (tset entry :desc desc) + ;; Ensure the list for this plugin exists + (when (not (. M plugin)) + (tset M plugin [])) + (table.insert (. M plugin) entry)) + ;; Branch node + (do + ;; Check if it has group metadata + (when (and node.name (not= prefix "")) + (let [group-entry {1 prefix :group node.name}] + (when node.icon + (tset group-entry :icon node.icon)) + (table.insert M.groups group-entry))) + ;; Recursively traverse children + (each [k v (pairs node)] + (when (and (not= k :name) (not= k :icon)) + (traverse v (.. prefix k)))))))) + +;; Execute the traversal on the top-level trie +(traverse trie "") + +M + diff --git a/init.lua b/init.lua index a788f90..68d7923 100644 --- a/init.lua +++ b/init.lua @@ -5,7 +5,6 @@ vim.g.mapleader = "\\" vim.g.maplocalleader = "\\\\" require("config") -require("keybindings") -- Then, i want to load lazy as my plugin manager and have it load my plugins local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" @@ -37,6 +36,7 @@ vim.opt.rtp:prepend(lazypath) ---@diagnostic enable: undefined-field require("hotpot") +require("keybindings") require("lazy").setup("plugins") require("nvim-web-devicons").refresh() -- This fixes screwiness with the devicon colors diff --git a/lua/config/keys.lua b/lua/config/keys.lua deleted file mode 100644 index d94bdb1..0000000 --- a/lua/config/keys.lua +++ /dev/null @@ -1,553 +0,0 @@ ----@class Keymap ----@field [1] string LHS key ----@field [2] string|function RHS command or function ----@field desc string Description for which-key/vim.keymap ----@field mode? string|string[] Mode (n, v, i, etc.) ----@field expr? boolean Whether to use expression mapping - ----@class KeyConfig : table - ----@type KeyConfig -return { - groups = { - { "s", group = "[S]earch", icon = "" }, - { "c", group = "[C]ode", icon = "" }, - { "d", group = "[D]iagnostics", icon = "" }, - { "g", group = "[G]it", icon = "󰊢" }, - { "r", group = "[R]ename", icon = "󰑕" }, - { "w", group = "[W]orkspace", icon = "" }, - { "t", group = "[T]ree", icon = "󱏒" }, - { "l", group = "[L]azyGit", icon = "󰒲" }, - { "o", group = "[O]verseer", icon = "󰈈" }, - { "h", group = "[H]arpoon", icon = "󱡀" }, - { "x", group = "[X] Trouble", icon = "󰋔" }, - { "a", group = "[A]genda / [O]rg Mode", icon = "󰕪" }, - { "", group = "[L]ocal Leader (\\\\)", icon = "" }, - { "x", group = "Local [X] UV", icon = "" }, - }, - commands = { - { "f", group = "[F]ormat", icon = "󰗈" }, - { "p", group = "[P]recognition", icon = "󰬯" }, - { "?", group = "[?] Cheatsheet", icon = "󰧹" }, - }, - globals = { - -- Window Navigation - { "", "h", desc = "Window Left" }, - { "", "j", desc = "Window Down" }, - { "", "k", desc = "Window Up" }, - { "", "l", desc = "Window Right" }, - -- Window Resizing - { "", "+", desc = "Resize Increase Height" }, - { "", "-", desc = "Resize Decrease Height" }, - { "", ">", desc = "Resize Increase Width" }, - { "", "<", desc = "Resize Decrease Width" }, - -- Splits - { "", "s", desc = "Split Window Horizontal" }, - { "", "x", desc = "Swap Window" }, - { "", ":q", desc = "Close Window" }, - -- Misc - { "", "nohlsearch", desc = "Clear Highlight" }, - { "dd", vim.diagnostic.open_float, desc = "Show [D]iagnostics" }, - }, - atone = { - { - "U", - function() - require("atone.core").toggle() - end, - desc = "[U]ndotree", - }, - }, - gitsigns = { - { - "gs", - function() - require("gitsigns").stage_hunk() - end, - desc = "[G]it [S]tage Hunk", - mode = { "n", "v" }, - }, - { - "gr", - function() - require("gitsigns").reset_hunk() - end, - desc = "[G]it [R]eset Hunk", - mode = { "n", "v" }, - }, - { - "gp", - function() - require("gitsigns").preview_hunk() - end, - desc = "[G]it [P]review Hunk", - mode = "n", - }, - { - "gb", - function() - require("gitsigns").blame_line() - end, - desc = "[G]it [B]lame Line", - mode = "n", - }, - { - "]c", - function() - if vim.wo.diff then - vim.cmd.normal({ "]c", bang = true }) - else - ---@diagnostic disable-next-line: param-type-mismatch - require("gitsigns").nav_hunk("next") - end - end, - desc = "Next Hunk", - mode = "n", - expr = true, - }, - { - "[c", - function() - if vim.wo.diff then - vim.cmd.normal({ "[c", bang = true }) - else - ---@diagnostic disable-next-line: param-type-mismatch - require("gitsigns").nav_hunk("prev") - end - end, - desc = "Previous Hunk", - mode = "n", - expr = true, - }, - }, - - harpoon = { - { - "ha", - function() - require("harpoon"):list():add() - end, - desc = "[H]arpoon [A]dd file", - mode = "n", - }, - { - "hq", - function() - local harpoon = require("harpoon") - harpoon.ui:toggle_quick_menu(harpoon:list()) - end, - desc = "[H]arpoon [Q]uick menu", - mode = "n", - }, - { - "", - function() - require("harpoon"):list():select(1) - end, - desc = "Harpoon file 1", - mode = "n", - }, - { - "", - function() - require("harpoon"):list():select(2) - end, - desc = "Harpoon file 2", - mode = "n", - }, - { - "", - function() - require("harpoon"):list():select(3) - end, - desc = "Harpoon file 3", - mode = "n", - }, - { - "", - function() - require("harpoon"):list():select(4) - end, - desc = "Harpoon file 4", - mode = "n", - }, - }, - lazygit = { - { - "lg", - function() - Snacks.lazygit() - end, - desc = "[L]azy[G]it", - mode = "n", - }, - { - "ll", - function() - Snacks.lazygit.log() - end, - desc = "[L]azyGit [L]og", - mode = "n", - }, - { - "lf", - function() - Snacks.lazygit.log_file() - end, - desc = "[L]azyGit [F]ile Log", - mode = "n", - }, - }, - lsp = { - { "K", vim.lsp.buf.hover, desc = "[K] Hover Documentation" }, - { - "gd", - function() - require("telescope.builtin").lsp_definitions() - end, - desc = "[G]oto [D]efinition", - }, - { "ge", vim.lsp.buf.declaration, desc = "[G]oto D[e]claration" }, - { - "gi", - function() - require("telescope.builtin").lsp_implementations() - end, - desc = "[G]oto [I]mplementation", - }, - { - "gr", - function() - require("telescope.builtin").lsp_references() - end, - desc = "[G]oto [R]eferences", - }, - { - "gt", - function() - require("telescope.builtin").lsp_type_definitions() - end, - desc = "[G]oto [T]ype", - }, - { - "cs", - function() - require("telescope.builtin").lsp_document_symbols() - end, - desc = "[C]ode [S]ymbols", - }, - { - "cw", - function() - require("telescope.builtin").lsp_dynamic_workspace_symbols() - end, - desc = "[C]ode [W]orkspace Symbols", - }, - { "r", vim.lsp.buf.rename, desc = "[R]ename" }, - { "ca", vim.lsp.buf.code_action, desc = "[C]ode [A]ction" }, - { "f", vim.lsp.buf.format, desc = "[F]ormat" }, - { - "ci", - function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) - end, - desc = "[I]nlay Hints", - }, - }, - neogen = { - { - "cd", - ":lua require('neogen').generate()", - desc = "[C]ode Add [D]ocumentation", - mode = "n", - }, - }, - neotree = { - { - "tt", - function() - vim.api.nvim_command("Neotree toggle") - end, - desc = "[T]ree [T]oggle", - mode = "n", - }, - { - "ts", - function() - vim.api.nvim_command("Neotree show") - end, - desc = "[T]ree [S]how", - mode = "n", - }, - { - "tc", - function() - vim.api.nvim_command("Neotree close") - end, - desc = "[T]ree [C]lose", - mode = "n", - }, - { - "tf", - function() - vim.api.nvim_command("Neotree focus") - end, - desc = "[T]ree [F]ocus", - mode = "n", - }, - { - "tg", - function() - vim.api.nvim_command("Neotree git_status") - end, - desc = "[T]ree [G]it Status", - mode = "n", - }, - { - "tb", - function() - vim.api.nvim_command("Neotree buffers") - end, - desc = "[T]ree [B]uffers", - mode = "n", - }, - }, - oil = { - { "te", vim.cmd.Oil, desc = "[T]ree [E]dit", mode = "n" }, - }, - overseer = { - { "ob", vim.cmd.OverseerBuild, desc = "[O]verseer [B]uild", mode = "n" }, - { "oc", vim.cmd.OverseerRunCmd, desc = "[O]verseer Run [C]ommand", mode = "n" }, - { "or", vim.cmd.OverseerRun, desc = "[O]verseer [R]un", mode = "n" }, - { "ot", vim.cmd.OverseerToggle, desc = "[O]verseer [T]oggle", mode = "n" }, - }, - ---@param telescope_builtin table - telescope = function(telescope_builtin) - return { - { - "sh", - telescope_builtin.help_tags, - desc = "[S]earch [H]elp", - mode = "n", - }, - { - "sk", - telescope_builtin.keymaps, - desc = "[S]earch [K]eymaps", - mode = "n", - }, - { - "sf", - telescope_builtin.find_files, - desc = "[S]earch [F]iles", - mode = "n", - }, - { - "sb", - telescope_builtin.buffers, - desc = "[S]earch [B]uffers", - mode = "n", - }, - { - "ss", - telescope_builtin.builtin, - desc = "[S]earch [S]elect Telescope", - mode = "n", - }, - { - "sw", - telescope_builtin.grep_string, - desc = "[S]earch current [W]ord", - mode = "n", - }, - { - "sg", - telescope_builtin.live_grep, - desc = "[S]earch by [G]rep", - mode = "n", - }, - { - "sd", - telescope_builtin.diagnostics, - desc = "[S]earch [D]iagnostics", - mode = "n", - }, - { - "sr", - telescope_builtin.resume, - desc = "[S]earch [R]esume", - mode = "n", - }, - { - "s.", - telescope_builtin.oldfiles, - desc = '[S]earch Recent Files ("." for repeat)', - mode = "n", - }, - - -- Slightly advanced example of overriding default behavior and theme - { - "/", - function() - -- You can pass additional configuration to telescope to change theme, layout, etc. - telescope_builtin.current_buffer_fuzzy_find( - require("telescope.themes").get_dropdown({ - winblend = 10, - previewer = false, - }) - ) - end, - desc = "[/] Fuzzily search in current buffer", - mode = "n", - }, - -- Also possible to pass additional configuration options. - -- See `:help telescope.builtin.live_grep()` for information about particular keys - { - "s/", - function() - telescope_builtin.live_grep({ - grep_open_files = true, - prompt_title = "Live Grep in Open Files", - }) - end, - desc = "[S]earch [/] in Open Files", - mode = "n", - }, - -- Shortcut for searching your neovim configuration files - { - "sn", - function() - telescope_builtin.find_files({ cwd = vim.fn.stdpath("config") }) - end, - desc = "[S]earch [N]eovim files", - mode = "n", - }, - } - end, - todo_comments = { - { - "]t", - function() - require("todo-comments").jump_next() - end, - desc = "Next Todo Comment", - }, - { - "[t", - function() - require("todo-comments").jump_prev() - end, - desc = "Previous Todo Comment", - }, - { "xt", "Trouble todo toggle", desc = "Todo" }, - { - "xT", - "Trouble todo toggle filter = {tag = {TODO,FIX,FIXME}}", - desc = "Todo/Fix/Fixme", - }, - { "st", "TodoTelescope", desc = "Todo" }, - { - "sT", - "TodoTelescope keywords=TODO,FIX,FIXME", - desc = "Todo/Fix/Fixme", - }, - }, - trouble = { - { "xx", "Trouble diagnostics toggle", desc = "Diagnostics" }, - { - "xX", - "Trouble diagnostics toggle filter.buf=0", - desc = "Buffer Diagnostics", - }, - { "xs", "Trouble symbols toggle", desc = "Symbols (Trouble)" }, - { - "xS", - "Trouble lsp toggle", - desc = "LSP references/definitions/... (Trouble)", - }, - { "xL", "Trouble loclist toggle", desc = "Location List" }, - { "xQ", "Trouble qflist toggle", desc = "Quickfix List" }, - { - "[q", - function() - if require("trouble").is_open() then - require("trouble").prev({ skip_groups = true, jump = true }) - else - local ok, err = pcall(vim.cmd.cprev) - if not ok then - vim.notify(err, vim.log.levels.ERROR) - end - end - end, - desc = "Previous Trouble/Quickfix Item", - }, - { - "]q", - function() - if require("trouble").is_open() then - require("trouble").next({ skip_groups = true, jump = true }) - else - local ok, err = pcall(vim.cmd.cnext) - if not ok then - if err then - vim.notify(err, vim.log.levels.ERROR) - else - vim.notify("An error occured but returned nil!", vim.log.levels.ERROR) - end - end - end - end, - desc = "Next Trouble/Quickfix Item", - }, - }, - rainbow_delimiters = { - { - "(", - function() - local rm_module = require("rainbow-delimiters") - rm_module.toggle(0) - - local active = rm_module.is_enabled(0) - local buf = vim.api.nvim_get_current_buf() - local lisp_filetypes = - { "clojure", "fennel", "scheme", "lisp", "janet", "racket", "hy", "elisp" } - - if vim.tbl_contains(lisp_filetypes, vim.bo[buf].filetype) then - local has_paredit, paredit_config = pcall(require, "nvim-paredit.config") - if has_paredit then - local keys = paredit_config.config.keys - if active then - local has_kb, keybindings = - pcall(require, "nvim-paredit.utils.keybindings") - if has_kb then - keybindings.setup_keybindings({ - keys = keys, - buf = buf, - }) - end - else - for keymap, action in pairs(keys) do - if action then - local mode = action.mode or { "n", "x" } - if type(mode) == "string" then - mode = { mode } - end - for _, m in ipairs(mode) do - pcall(vim.keymap.del, m, keymap, { buffer = buf }) - end - end - end - end - end - vim.notify("Lisp Tooling: " .. (active and "ON" or "OFF"), vim.log.levels.INFO) - else - vim.notify( - "Rainbow Delimiters: " .. (active and "ON" or "OFF"), - vim.log.levels.INFO - ) - end - end, - desc = "Toggle Lisp Tooling (Rainbow & Paredit)", - }, - }, -} diff --git a/lua/keybindings.lua b/lua/keybindings.lua index 71525fa..bb5fc3b 100644 --- a/lua/keybindings.lua +++ b/lua/keybindings.lua @@ -2,9 +2,15 @@ local keys = require("config.keys").globals for _, map in ipairs(keys) do - vim.keymap.set("n", map[1], map[2], { + local opts = { noremap = true, silent = true, desc = map.desc, - }) + } + for k, v in pairs(map) do + if k ~= 1 and k ~= 2 and k ~= "desc" and k ~= "mode" then + opts[k] = v + end + end + vim.keymap.set(map.mode or "n", map[1], map[2], opts) end diff --git a/lua/plugins/telescope.lua b/lua/plugins/telescope.lua index e5a43ed..22a79fc 100644 --- a/lua/plugins/telescope.lua +++ b/lua/plugins/telescope.lua @@ -69,6 +69,6 @@ return { -- Telescope is so core to nvim that it gets its own module pcall(require("telescope").load_extension, "file-browser") end, -- See `:help telescope.builtin` - keys = require("config.keys").telescope(require("telescope.builtin")), + keys = require("config.keys").telescope, }, } diff --git a/lua/plugins/ui.lua b/lua/plugins/ui.lua index 8e25adc..a011992 100644 --- a/lua/plugins/ui.lua +++ b/lua/plugins/ui.lua @@ -24,9 +24,7 @@ return { -- UI components and other visual elements are declared here local wk = require("which-key") wk.setup({ preset = "modern" }) local groups = require("config.keys").groups - local commands = require("config.keys").commands wk.add(groups) - wk.add(commands) end, }, {