;; Plugin specs in Fennel ;; This file is compiled to lua/plugins/init.lua by nfnl (local repo 1) ;; lazy.nvim spec index for the git repo (e.g., "folke/plugin") (local lhs 1) ;; lazy.nvim/which-key spec index for key sequence (local rhs 2) ;; lazy.nvim keys spec index for command/action [;; Tokyonight - Colorscheme {repo "folke/tokyonight.nvim" :lazy false :priority 1000 :config (fn [] (let [tokyonight (require :tokyonight)] (tokyonight.setup {:style "night" ; storm, moon, night, or day :transparent false :terminal_colors true})) (vim.cmd.colorscheme "tokyonight"))} ;; Conjure - Interactive REPL for Fennel, Clojure, Lisp, etc. {repo "Olical/conjure" :ft ["fennel" "clojure" "lisp" "scheme" "racket" "lua"] :config (fn [] ;; Enable HUD floating window (set vim.g.conjure#log#hud#enabled true))} ;; nvim-parinfer - Automatic parenthesis balancing ;; Works alongside paredit: parinfer handles passive balancing, ;; paredit provides explicit structural commands {repo "gpanders/nvim-parinfer" :ft ["fennel" "clojure" "lisp" "scheme" "racket" "carp" "timl"] :keys [{lhs "tpi" rhs "ParinferToggle" :desc "Toggle Parinfer"}]} ;; nvim-paredit - Structural editing for Lisp ;; Configured with vim-sexp + vim-sexp-mappings-for-regular-people compatible bindings ;; ;; Default paredit bindings (from nvim-paredit): ;; >)/<) slurp/barf forwards <(/>( slurp/barf backwards ;; >e/f/p/

@ splice ;; o/O raise form/element ;; ;; Additional bindings added below for vim-sexp compatibility {repo "julienvincent/nvim-paredit" :ft ["fennel" "clojure" "lisp" "scheme" "racket"] :config (fn [] (local paredit (require :nvim-paredit)) (local api paredit.api) (local wrap paredit.wrap) (local cursor paredit.cursor) (local keymap vim.keymap.set) ;; Use default keybindings (paredit.setup {}) ;; ============================================================ ;; vim-sexp-mappings-for-regular-people (tpope) style bindings ;; ============================================================ ;; dsf - Splice (delete surrounding form) - alias for @ (keymap :n "dsf" api.unwrap_form_under_cursor {:desc "Splice (delete surrounding form)"}) ;; cse* - Surround element (no insert mode, surround.vim style) (keymap :n "cseb" #(api.wrap_element_under_cursor "(" ")") {:desc "Wrap element in ()"}) (keymap :n "cse(" #(api.wrap_element_under_cursor "(" ")") {:desc "Wrap element in ()"}) (keymap :n "cse)" #(api.wrap_element_under_cursor "(" ")") {:desc "Wrap element in ()"}) (keymap :n "cse[" #(api.wrap_element_under_cursor "[" "]") {:desc "Wrap element in []"}) (keymap :n "cse]" #(api.wrap_element_under_cursor "[" "]") {:desc "Wrap element in []"}) (keymap :n "cse{" #(api.wrap_element_under_cursor "{" "}") {:desc "Wrap element in {}"}) (keymap :n "cse}" #(api.wrap_element_under_cursor "{" "}") {:desc "Wrap element in {}"}) ;; I - Insert at form head/tail (tpope style) (keymap :n "I" (fn [] (api.move_to_parent_form_end) (vim.cmd "startinsert")) {:desc "Insert at form tail"}) ;; W/B/E/gE - Element-wise motions (override WORD motions) (each [_ mode (ipairs [:n :x :o])] (keymap mode "W" api.move_to_next_element_head {:desc "Next element head"}) (keymap mode "B" api.move_to_prev_element_head {:desc "Previous element head"}) (keymap mode "E" api.move_to_next_element_tail {:desc "Next element tail"}) (keymap mode "gE" api.move_to_prev_element_tail {:desc "Previous element tail"})) ;; ============================================================ ;; vim-sexp (guns) style LocalLeader bindings ;; ============================================================ ;; w/W - Wrap element + insert at head/tail (keymap :n "w" (fn [] (cursor.place_cursor (wrap.wrap_element_under_cursor "( " ")") {:placement "inner_start" :mode "insert"})) {:desc "Wrap element, insert head"}) (keymap :n "W" (fn [] (cursor.place_cursor (wrap.wrap_element_under_cursor "(" ")") {:placement "inner_end" :mode "insert"})) {:desc "Wrap element, insert tail"}) ;; i/I - Wrap form + insert at head/tail (keymap :n "i" (fn [] (cursor.place_cursor (wrap.wrap_enclosing_form_under_cursor "( " ")") {:placement "inner_start" :mode "insert"})) {:desc "Wrap form, insert head"}) (keymap :n "I" (fn [] (cursor.place_cursor (wrap.wrap_enclosing_form_under_cursor "(" ")") {:placement "inner_end" :mode "insert"})) {:desc "Wrap form, insert tail"}) ;; [ ] { } - Wrap form in brackets/braces + insert (keymap :n "[" (fn [] (cursor.place_cursor (wrap.wrap_enclosing_form_under_cursor "[ " "]") {:placement "inner_start" :mode "insert"})) {:desc "Wrap form in [], insert head"}) (keymap :n "]" (fn [] (cursor.place_cursor (wrap.wrap_enclosing_form_under_cursor "[" "]") {:placement "inner_end" :mode "insert"})) {:desc "Wrap form in [], insert tail"}) (keymap :n "{" (fn [] (cursor.place_cursor (wrap.wrap_enclosing_form_under_cursor "{ " "}") {:placement "inner_start" :mode "insert"})) {:desc "Wrap form in {}, insert head"}) (keymap :n "}" (fn [] (cursor.place_cursor (wrap.wrap_enclosing_form_under_cursor "{" "}") {:placement "inner_end" :mode "insert"})) {:desc "Wrap form in {}, insert tail"}) ;; e[ e] e{ e} - Wrap element in brackets/braces + insert (keymap :n "e[" (fn [] (cursor.place_cursor (wrap.wrap_element_under_cursor "[ " "]") {:placement "inner_start" :mode "insert"})) {:desc "Wrap element in [], insert head"}) (keymap :n "e]" (fn [] (cursor.place_cursor (wrap.wrap_element_under_cursor "[" "]") {:placement "inner_end" :mode "insert"})) {:desc "Wrap element in [], insert tail"}) (keymap :n "e{" (fn [] (cursor.place_cursor (wrap.wrap_element_under_cursor "{ " "}") {:placement "inner_start" :mode "insert"})) {:desc "Wrap element in {}, insert head"}) (keymap :n "e}" (fn [] (cursor.place_cursor (wrap.wrap_element_under_cursor "{" "}") {:placement "inner_end" :mode "insert"})) {:desc "Wrap element in {}, insert tail"}) ;; h/l - Insert at list head/tail (vim-sexp originals) ;; Same as I but with localleader (keymap :n "h" (fn [] (api.move_to_parent_form_start) (vim.cmd "normal! l") (vim.cmd "startinsert")) {:desc "Insert at list head"}) (keymap :n "l" (fn [] (api.move_to_parent_form_end) (vim.cmd "startinsert")) {:desc "Insert at list tail"}) ;; [[ / ]] - Move to prev/next top-level form (each [_ mode (ipairs [:n :x :o])] (keymap mode "]]" (fn [] ;; Go to current top-level, then find next (api.move_to_parent_form_end) (api.move_to_next_element_head)) {:desc "Next top-level form"}) (keymap mode "[[" (fn [] ;; Go to current top-level start, then find prev (api.move_to_parent_form_start) (api.move_to_prev_element_head)) {:desc "Previous top-level form"})))} ;; Clojure-Typst - Syntax highlighting for #t"" Typst literals in Clojure ;; Injects Typst highlighting into tagged literals, ~() switches back to Clojure {:dir "/home/ajet/repos/clojure-typst/editors/nvim" :ft ["clojure"]} ;; Mason - Package manager for LSP servers, DAP servers, linters, formatters ;; Run :MasonInstall clojure_lsp lua_ls to install servers {repo "williamboman/mason.nvim" :cmd ["Mason" "MasonInstall" "MasonUpdate"] :build ":MasonUpdate" :opts {:ui {:border "rounded"}}} ;; which-key - Shows keybinding hints ;; lhs constant defined at top - which-key specs use index [1] for the key sequence {repo "folke/which-key.nvim" :event "VeryLazy" :opts {} :config (fn [_ opts] (local wk (require :which-key)) (wk.setup opts) (wk.add [{lhs "f" :group "find"} {lhs "b" :group "buffer"} {lhs "r" :group "refactor"} {lhs "c" :group "code"} {lhs "t" :group "toggle"}]))}]