diff --git a/fnl/macros.fnl b/fnl/macros.fnl new file mode 100644 index 0000000..5936d63 --- /dev/null +++ b/fnl/macros.fnl @@ -0,0 +1,70 @@ +;;; macros.fnl - useful macros + +;; Helpful keymaping functions +(lambda bind! [mode key cmd ?a1 ?a2] + (let [desc (or ?a2 ?a1) + buf (if (and ?a1 ?a2) ?a1 ?a2) + opts { :noremap true + :silent true + :buffer buf }] + (when desc + (tset opts :desc desc)) + `(vim.keymap.set ,mode ,key ,cmd ,opts))) + +;; Better autocommands +(lambda hook! [hooks ?patterns callback] + (let [hook_table (if (= (type hooks) :table) + hooks + [ hooks ]) + pattern_table (if (not ?patterns) + [] + (= (type ?patterns) :table) + ?patterns + [ ?patterns ])] + (var group "config-hook") + (each [_ hook (ipairs hook_table)] + (set group (.. group "-" hook))) + (each [_ pattern (ipairs pattern_table)] + (set group (.. group "-" pattern))) + `(vim.api.nvim_create_autocmd ,hook_table + { :group + (vim.api.nvim_create_augroup ,group + { :clear true }) + :pattern ,pattern_table + :callback ,callback }))) +;; Nicer macro for use +(lambda use! [repo ...] + (local output [ repo ]) + (var last_key nil) + (each [_ val (ipairs [...])] + (if last_key + (do (tset output last_key val) + (set last_key nil)) + (set last_key val))) + `(use ,output)) + +;; Can be passed to :config of `use!' +;; to call a plugin's `setup' function +(lambda setup! [pkg ...] (local output [ ]) + (var last_key nil) + (each [_ val (ipairs [...])] + (if last_key + (do (tset output last_key val) + (set last_key nil)) + (set last_key val))) + `((. (require ,pkg) :setup) ,output)) + +;; Call module function +(lambda module-call! [mod func ...] + `((. (require ,mod) ,func) ,...)) + +;; Return module function +(lambda module-fn! [mod func] + `(. (require ,mod) ,func)) + +{: bind! + : hook! + : use! + : setup! + : module-call! + : module-fn!} diff --git a/fnl/plugin.fnl b/fnl/plugin.fnl new file mode 100644 index 0000000..2eedebb --- /dev/null +++ b/fnl/plugin.fnl @@ -0,0 +1,174 @@ +;;; plugin.fnl - plugin configurations + +(import-macros {: bind! : hook! + : use! : setup! + : module-call! + : module-fn!} :macros) + +(fn [use] + ;; Packer + (use! :wbthomason/packer.nvim) + + ;; tangerine.nvim (auto fennel compile) + (use! :udayvir-singh/tangerine.nvim) + + ;; Treesitter + (use! :nvim-treesitter/nvim-treesitter + :config #(setup! "nvim-treesitter.configs" + :ensure_installed :all + :sync_install false + :auto_install true + :highlight { :enable true + :additional_vim_regex_highlighting false } + :indent { :enable true })) + + ;; nightfox.nvim (colorscheme) + (use! :EdenEast/nightfox.nvim + :after :nvim-treesitter + :config #(vim.cmd.colorscheme :carbonfox)) + + ;; Devicons + (use! :kyazdani42/nvim-web-devicons) + + ;; lualine.nvim + (use! :nvim-lualine/lualine.nvim + :after [ :nightfox.nvim :nvim-web-devicons ] + :config #(setup! :lualine + :options { :section_separators "" + :component_separators "│" } + :sections { :lualine_x [ + { 1 #(.. "recording @" (vim.fn.reg_recording)) + :cond #(not= (# (vim.fn.reg_recording)) 0) } + :encoding + :fileformat + :filetype ]})) + + ;; bufferline.nvim + (use! :akinsho/bufferline.nvim + :after [ :nvim-web-devicons :nightfox.nvim ] + :config #(setup! :bufferline + :options { + :always_show_bufferline false + :mode :tabs + :numbers :buffer-id + :show_buffer_close_icons false + :show_close_icon false })) + + ;; fzf (a fuzzy finder) + (use! :ibhagwan/fzf-lua + :config (fn [] + (let [fzf (require :fzf-lua)] + (fzf.register_ui_select) + (bind! :n :fq fzf.quickfix) + (bind! :n :fr fzf.registers) + (bind! :n :fj fzf.jumps) + (bind! :n :fa fzf.marks) + (bind! :n :fh fzf.help_tags) + (bind! :n :g fzf.live_grep) + (bind! :n :fg fzf.live_grep) + (bind! :n :G fzf.grep) + (bind! :n :fG fzf.grep) + (bind! :n :b fzf.buffers) + (bind! :n :gb fzf.buffers) + (bind! :n :fu fzf.git_status) + (bind! :n :fm fzf.man_pages) + (bind! :n :fe fzf.diagnostics_document) + (bind! :n :fE fzf.diagnostics_workspace) + (bind! :n :fp fzf.spell_suggest) + (bind! :n :i fzf.files) + (bind! :n :z= fzf.spell_suggest) + (bind! :n :ff (fn [] + (let [code (os.execute "git rev-parse --is-inside-work-tree >/dev/null 2>&1")] + (if (= code 0) + (fzf.git_files) + (fzf.files)))))))) + + ;; Nvim surround + (use! :kylechui/nvim-surround + :config #(setup! :nvim-surround)) + + ;; Leap + (use! :ggandor/leap.nvim + :after :nvim-treesitter + :config (fn [] + ((. (require :leap) :add_default_mappings)) + (bind! :o :z "(leap-forward-to)") + (bind! :o :Z "(leap-backward-to)") + (vim.api.nvim_set_hl 0 :LeapBackdrop { :link :Comment }))) + + ;; Leap spooky (remote operations) + (use! :ggandor/leap-spooky.nvim + :after :leap.nvim + :config #(setup! :leap-spooky)) + + ;; Flit (leap for 'till' and 'forward' motions) + (use! :ggandor/flit.nvim + :after :leap.nvim + :config #(setup! :flit)) + + ;; Comment.nvim + (use! :numToStr/Comment.nvim + :config #(setup! :Comment)) + + ;; nvim-find-other + (use! "https://git.zander.im/Zander671/nvim-find-other.git" + :config (fn [] (setup! :nvim-find-other + :c [ "h" "H" ] + :h [ "c" "C" "cpp" "cxx" "c++" "cc" ] + :cpp [ "hpp" "hxx" "h++" "hh" "h" "H" ] + :hpp [ "cpp" "cxx" "c++" "cc" ]) + (let [find_other (require :nvim-find-other)] + (vim.api.nvim_create_user_command + "FindOtherFile" + find_other.find_other_current_buffer + {}) + (bind! :n :go find_other.find_other_current_buffer)))) + + (use! :RRethy/vim-illuminate + :config (fn [] + (module-call! :illuminate :configure) + { :providers [ + "lsp" + "treesitter" + "ragex" ] + :modes_denylist [ + :markdown + :text + :gitconfig + :gitignore ] + :delay 0 } + (hook! :FileType :lua #(vim.api.nvim_set_hl 0 + :IlluminatedWordText + {})))) + + ;; Snippy + (use! :dcampos/nvim-snippy + :config #(let [map (require :snippy.mapping)] + (bind! [ :i :s ] : ((. map :next) :)) + (bind! [ :i :s ] : (map.previous :)))) + + ;; nvim-cmp (autocomplete) + (use! :hrsh7th/nvim-cmp + :requires [ :hrsh7th/cmp-buffer + :hrsh7th/cmp-path + :hrsh7th/cmp-cmdline + :hrsh7th/cmp-nvim-lsp + { 1 :ray-x/cmp-treesitter + :after :nvim-cmp } + :dcampos/cmp-snippy ] + :config (module-fn! :plugin.cmp :configure)) + + ;; lspconfig + (use! :neovim/nvim-lspconfig + :after [ :cmp-nvim-lsp + :fzf-lua ] + :config (module-fn! :plugin.lsp :configure)) + + ;; nvim-jdtls + (use! :mfussenegger/nvim-jdtls + :after :nvim-lspconfig + :config (module-fn! :plugin.jdtls :configure)) + + ;; Sync all packages on first launch + (if _G.first_launch + (module-call! :packer :sync))) diff --git a/init.fnl b/init.fnl index 06bc6db..db90e49 100644 --- a/init.fnl +++ b/init.fnl @@ -1,39 +1,6 @@ ;;; init.fnl - primary init file -;; Initialize global `zander' prefix -(set _G.zander {}) - -;; Helpful keymaping functions -(macro bind! [mode key cmd ?a1 ?a2] - (let [desc (or ?a2 ?a1) - buf (if (and ?a1 ?a2) ?a1 ?a2) - opts { :noremap true - :silent true - :buffer buf }] - (when desc - (tset opts :desc desc)) - `(vim.keymap.set ,mode ,key ,cmd ,opts))) -;; Better autocommands -(macro hook! [hooks ?patterns callback] - (let [hook_table (if (= (type hooks) :table) - hooks - [ hooks ]) - pattern_table (if (not ?patterns) - [] - (= (type ?patterns) :table) - ?patterns - [ ?patterns ])] - (var group "config-hook") - (each [_ hook (ipairs hook_table)] - (set group (.. group "-" hook))) - (each [_ pattern (ipairs pattern_table)] - (set group (.. group "-" pattern))) - `(vim.api.nvim_create_autocmd ,hook_table - { :group - (vim.api.nvim_create_augroup ,group - { :clear true }) - :pattern ,pattern_table - :callback ,callback }))) +(import-macros {: bind!} :macros) ;; Make space leader (set vim.g.mapleader " ") @@ -146,405 +113,5 @@ "h" :c "ui" :xml }}) - -;; Plugins (with packer.nvim) -(fn packer_init_callback [use] - ;; Nicer macro for use - (macro use! [repo ...] - (local output [ repo ]) - (var last_key nil) - (each [_ val (ipairs [...])] - (if last_key - (do (tset output last_key val) - (set last_key nil)) - (set last_key val))) - `(use ,output)) - ;; Can be passed to :config of `use!' - ;; to call a plugin's `setup' function - (macro setup! [pkg ...] - (local output [ ]) - (var last_key nil) - (each [_ val (ipairs [...])] - (if last_key - (do (tset output last_key val) - (set last_key nil)) - (set last_key val))) - (let [req_var (gensym)] - `((. (require ,pkg) :setup) ,output))) - - ;; Packer - (use! :wbthomason/packer.nvim) - - ;; tangerine.nvim (auto fennel compile) - (use! :udayvir-singh/tangerine.nvim) - - ;; Treesitter - (use! :nvim-treesitter/nvim-treesitter - :config #(setup! "nvim-treesitter.configs" - :ensure_installed :all - :sync_install false - :auto_install true - :highlight { :enable true - :additional_vim_regex_highlighting false } - :indent { :enable true })) - - ;; nightfox.nvim (colorscheme) - (use! :EdenEast/nightfox.nvim - :after :nvim-treesitter - :config #(vim.cmd.colorscheme :carbonfox)) - - ;; Devicons - (use! :kyazdani42/nvim-web-devicons) - - ;; lualine.nvim - (use! :nvim-lualine/lualine.nvim - :after [ :nightfox.nvim :nvim-web-devicons ] - :config #(setup! :lualine - :options { :section_separators "" - :component_separators "│" } - :sections { :lualine_x [ - { 1 #(.. "recording @" (vim.fn.reg_recording)) - :cond #(not= (# (vim.fn.reg_recording)) 0) } - :encoding - :fileformat - :filetype ]})) - - ;; bufferline.nvim - (use! :akinsho/bufferline.nvim - :after [ :nvim-web-devicons :nightfox.nvim ] - :config #(setup! :bufferline - :options { - :always_show_bufferline false - :mode :tabs - :numbers :buffer-id - :show_buffer_close_icons false - :show_close_icon false })) - - ;; noice.nvim (ui overhaul) - (use! :folke/noice.nvim - :requires :MunifTanjim/nui.nvim - :config #(setup! - :noice - :lsp { - :override { - "vim.lsp.util.convert_input_to_markdown_lines" true - "vim.lsp.util.stylize_markdown" true - "cmp.entry.get_documentation" true }} - :presets { - :bottom_search true - :command_palette false - :long_message_to_split true - :inc_rename false - :lsp_doc_border false } - :cmdline { - :view :cmdline })) - - ;; dressing.nvim (better prmpts) - (use! :stevearc/dressing.nvim - :after :telescope.nvim - :config #(setup! :dressing - :input { :insert_only true })) - - ;; Telescope - (use! :nvim-telescope/telescope.nvim - :requires :nvim-lua/plenary.nvim - :after :noice.nvim - :config (fn [] - (setup! :telescope - :defaults { - :mappings { - :i { - : :close - : :move_selection_next - : :move_selection_previous } - :n { - : :move_selection_next - : :move_selection_previous }}} - :pickers { - :buffers { - :sort_lastused true }} - :extensions { - :fzf { - :fuzzy true - :override_generic_sorter true - :override_file_sorter true - :case_mode :smart_case }}) - (let [builtin (require :telescope.builtin)] - (bind! :n :fq builtin.quickfix) - (bind! :n :fr builtin.registers) - (bind! :n :fj builtin.jumplist) - (bind! :n :fa builtin.marks) - (bind! :n :fh builtin.help_tags) - (bind! :n :g builtin.live_grep) - (bind! :n :fg builtin.live_grep) - (bind! :n :G builtin.grep_string) - (bind! :n :fG builtin.grep_string) - (bind! :n :b builtin.buffers) - (bind! :n :gb builtin.buffers) - (bind! :n :fu builtin.git_status) - (bind! :n :fm builtin.man_pages) - (bind! :n :fe builtin.diagnostics) - (bind! :n :fp builtin.spell_suggest) - (bind! :n :i builtin.find_files) - (bind! :n :z= builtin.spell_suggest) - (bind! :n :ff (fn [] - (let [code (os.execute "git rev-parse --is-inside-work-tree >/dev/null 2>&1")] - (if (= code 0) - (builtin.git_files) - (builtin.find_files)))))) - ((. (require :telescope) :load_extension) :noice))) - - ;; Telescope fzf - (use! :nvim-telescope/telescope-fzf-native.nvim - :after :telescope.nvim - :run "make" - :config #((. (require :telescope) :load_extension) :fzf)) - - ;; Nvim surround - (use! :kylechui/nvim-surround - :config #(setup! :nvim-surround)) - - ;; Leap - (use! :ggandor/leap.nvim - :after :nvim-treesitter - :config (fn [] - ((. (require :leap) :add_default_mappings)) - (bind! :o :z "(leap-forward-to)") - (bind! :o :Z "(leap-backward-to)") - (vim.api.nvim_set_hl 0 :LeapBackdrop { :link :Comment }))) - - ;; Leap spooky (remote operations) - (use! :ggandor/leap-spooky.nvim - :after :leap.nvim - :config #(setup! :leap-spooky)) - - ;; Flit (leap for 'till' and 'forward' motions) - (use! :ggandor/flit.nvim - :after :leap.nvim - :config #(setup! :flit)) - - ;; Comment.nvim - (use! :numToStr/Comment.nvim - :config #(setup! :Comment)) - - ;; nvim-find-other - (use! "https://git.zander.im/Zander671/nvim-find-other.git" - :config (fn [] (setup! :nvim-find-other - :c [ "h" "H" ] - :h [ "c" "C" "cpp" "cxx" "c++" "cc" ] - :cpp [ "hpp" "hxx" "h++" "hh" "h" "H" ] - :hpp [ "cpp" "cxx" "c++" "cc" ]) - (let [find_other (require :nvim-find-other)] - (vim.api.nvim_create_user_command - "FindOtherFile" - find_other.find_other_current_buffer - {}) - (bind! :n :go find_other.find_other_current_buffer)))) - - (use! :RRethy/vim-illuminate - :config (fn [] - ((. (require :illuminate) :configure) { :providers [ - "lsp" - "treesitter" - "ragex" ] - :modes_denylist [ - :markdown - :text - :gitconfig - :gitignore ] - :delay 0 } - (hook! :FileType :lua #(vim.api.nvim_set_hl 0 - :IlluminatedWordText - {}))))) - - ;; Snippy - (use! :dcampos/nvim-snippy - :config #(let [map (require :snippy.mapping)] - (bind! [ :i :s ] : ((. map :next) :)) - (bind! [ :i :s ] : (map.previous :)))) - - ;; nvim-cmp (autocomplete) - (use! :hrsh7th/nvim-cmp - :requires [ :hrsh7th/cmp-buffer - :hrsh7th/cmp-path - :hrsh7th/cmp-cmdline - :hrsh7th/cmp-nvim-lsp - { 1 :ray-x/cmp-treesitter - :after :nvim-cmp } - :dcampos/cmp-snippy ] - :config #(let [cmp (require :cmp) - compare (require :cmp.config.compare)] - (cmp.setup - { :snippet { - :expand #((. (require :snippy) :expand_snippet) $1.body) } - :mapping { - : (cmp.mapping (cmp.mapping.scroll_docs -4) - [ :i :c ]) - : (cmp.mapping (cmp.mapping.scroll_docs 4) - [ :i :c ]) - : (cmp.mapping (cmp.mapping.complete) - [ :i :c ]) - : (cmp.mapping (cmp.mapping.abort) - [ :i :c ]) - : (cmp.mapping - (cmp.mapping.confirm { :select false }) - [ :i :c ]) - : (cmp.mapping - (cmp.mapping.select_next_item - { :behavior cmp.SelectBehavior.Select }) - [ :i :c ]) - : (cmp.mapping - (cmp.mapping.select_prev_item - { :behavior cmp.SelectBehavior.Select }) - [ :i :c ]) - : (cmp.mapping - (cmp.mapping.select_next_item - { :behavior cmp.SelectBehavior.Select }) - [ :i :c ]) - : (cmp.mapping - (cmp.mapping.select_prev_item - { :behavior cmp.SelectBehavior.Select }) - [ :i :c ]) - : (cmp.mapping - (cmp.mapping.select_next_item - { :behavior cmp.SelectBehavior.Select }) - [ :i :c ]) - : (cmp.mapping - (cmp.mapping.select_prev_item - { :behavior cmp.SelectBehavior.Select }) - [ :i :c ]) } - :formatting { - :format (fn [entry vim_item] - (tset vim_item :menu - (. { :nvim_lsp "[LSP]" - :treesitter "[TS]" - :snippy "[Snippy]" - :buffer "[Buffer]" - :path "[Path]" } - entry.source.name)) - vim_item) - } - :sources (cmp.config.sources - [{ :name "nvim_lsp" :priority 2 } - { :name "snippy" :priority 1 } - { :name "buffer" :priority 0 } - { :name "path" :priority 0 }] - [{ :name "treesitter" :priority 2 } - { :name "snippy" :priority 1 } - { :name "buffer" :priority 0 } - { :name "path" :priority 0 }]) - :sorting { - :priority_weight 2 - :comparators [ - compare.score - compare.locality - compare.recently_used - compare.offset - compare.order - ; compare.scopes - ; compare.exact - ; compare.sort_text - ; compare.kind - ; compare.length - ]}}) - (cmp.setup.cmdline "/" - { :mapping (cmp.mapping.preset.cmdline) - :sources (cmp.config.sources - [{ :name "buffer" }])}) - (cmp.setup.cmdline ":" - { :mapping (cmp.mapping.preset.cmdline) - :sources (cmp.config.sources - [{ :name "cmdline" } - { :name "path" }])}))) - - ;; lspconfig - (fn lsp_config_callback [] - (fn _G.zander.lsp_on_attach [_ buf] - (bind! :n :gD vim.lsp.buf.declaration buf) - (bind! :n :gd vim.lsp.buf.definition buf) - (bind! :n :K vim.lsp.buf.hover buf) - (bind! :n :gI vim.lsp.buf.implementation buf) - (bind! :n : vim.lsp.buf.signature_help buf) - (bind! :n :wa vim.lsp.buf.add_workspace_folder buf) - (bind! :n :wr vim.lsp.buf.remove_workspace_folder buf) - (bind! :n :wl #(print (vim.inspect - (vim.lsp.buf.list_workspace_folders))) buf) - (bind! :n :D vim.lsp.buf.type_definition buf) - (bind! :n :rn vim.lsp.buf.rename buf) - (bind! :n :cn vim.lsp.buf.code_action buf) - ; (bind! :n :gr vim.lsp.buf.references buf) - (bind! :n :o #(vim.lsp.buf.format { :async true }) buf) - - ;; Some telescope commands - (let [builtin (require :telescope.builtin)] - (bind! :n :gr builtin.lsp_references buf) - (bind! :n :s builtin.lsp_dynamic_workspace_symbols buf) - (bind! :n :fs builtin.lsp_dynamic_workspace_symbols buf) - (bind! :n :fS builtin.lsp_workspace_symbols buf) - (bind! :n :d builtin.lsp_document_symbols buf) - (bind! :n :fd builtin.lsp_document_symbols buf))) - (fn _G.zander.lsp_get_data_dir [server root] - (let [resolved_path (vim.fn.resolve root) - joined_path (vim.fn.substitute resolved_path "\\/" "@" :g)] - (.. (vim.fn.fnamemodify (.. "~/.local/nvim/lsp-cache/" - server - "/") - ":p") joined_path))) - (let [lsp (require :lspconfig) - configs (require :lspconfig.configs) - lsp_cap ((. (require :cmp_nvim_lsp) :default_capabilities))] - (macro setup_server! [name ...] - (let [opts { :on_attach `_G.zander.lsp_on_attach - :capabilities `lsp_cap }] - (var last_key nil) - (each [_ val (ipairs [...])] - (if last_key - (do (tset opts last_key val) - (set last_key nil)) - (set last_key val))) - `((. (. lsp ,name) :setup) ,opts))) - (setup_server! :ccls) - (setup_server! :cmake) - (setup_server! :gopls) - (setup_server! :rust_analyzer) - (setup_server! :texlab) - (setup_server! :sumneko_lua - :settings { - :Lua { - :runtime { - :version "LuaJIT" } - :diagnostics { - :globals [ "vim" ] } - :workspace { - :checkThirdParty false - :library (vim.api.nvim_get_runtime_file "" true) } - :telemetry { - :enable false }}}))) - (use! :neovim/nvim-lspconfig - :after :cmp-nvim-lsp - :config lsp_config_callback) - - ;; nvim-jdtls - (fn jdtls_config_callback [] - (hook! :FileType :java - #(let [root_dir ((. (require :jdtls.setup) :find_root) - [ ".git" "mvnw" "gradlew" "build.gradle" ]) - lsp_cap ((. (require :cmp_nvim_lsp) :default_capabilities))] - ((. (require :jdtls) :start_or_attach) - { :capabilities lsp_cap - :on_attach _G.zander.lsp_on_attach - :root_dir root_dir - :cmd [ "jdtls" - "-data" - (_G.zander.lsp_get_data_dir - :jdtls root_dir) ]})))) - (use! :mfussenegger/nvim-jdtls - :after :nvim-lspconfig - :config jdtls_config_callback) - - ;; Sync all packages on first launch - (if _G.zander.first_launch - ((. (require :packer) :sync)))) - (let [packer (require :packer)] - (packer.startup packer_init_callback)) + (packer.startup (require :plugin))) diff --git a/init.lua b/init.lua index 2cd602a..78ce784 100644 --- a/init.lua +++ b/init.lua @@ -8,8 +8,7 @@ local function bootstrap(pkg, repo) return false end -_G.zander = {} -_G.zander.first_launch = bootstrap('packer.nvim', 'https://github.com/wbthomason/packer.nvim') +_G.first_launch = bootstrap('packer.nvim', 'https://github.com/wbthomason/packer.nvim') bootstrap('tangerine.nvim', 'https://github.com/udayvir-singh/tangerine.nvim') require('tangerine').setup({