aboutsummaryrefslogtreecommitdiff
path: root/fnl
diff options
context:
space:
mode:
authorsefidel <contact@sefidel.net>2022-02-10 00:24:03 +0900
committersefidel <contact@sefidel.net>2022-02-10 00:24:03 +0900
commit72d448e384249103748ee83b587c45924e4bc44d (patch)
tree2aa05a6aaf8c7aa37a8c278fd2fede6e62ff2218 /fnl
downloadnvimrc-72d448e384249103748ee83b587c45924e4bc44d.zip
Initial commit
Diffstat (limited to 'fnl')
-rw-r--r--fnl/nvrc/colors.fnl81
-rw-r--r--fnl/nvrc/events.fnl47
-rw-r--r--fnl/nvrc/ignite.fnl6
-rw-r--r--fnl/nvrc/keymaps.fnl45
-rw-r--r--fnl/nvrc/lib/io.fnl31
-rw-r--r--fnl/nvrc/macro/color.fnl9
-rw-r--r--fnl/nvrc/macro/event.fnl63
-rw-r--r--fnl/nvrc/macro/keymap.fnl46
-rw-r--r--fnl/nvrc/macro/misc.fnl1
-rw-r--r--fnl/nvrc/macro/pack.fnl80
-rw-r--r--fnl/nvrc/macro/set.fnl79
-rw-r--r--fnl/nvrc/macro/thread.fnl15
-rw-r--r--fnl/nvrc/macro/toolkit.fnl39
-rw-r--r--fnl/nvrc/options.fnl51
-rw-r--r--fnl/nvrc/pack.fnl34
-rw-r--r--fnl/nvrc/packs/blankline.fnl11
-rw-r--r--fnl/nvrc/packs/cmp.fnl56
-rw-r--r--fnl/nvrc/packs/feline.fnl144
-rw-r--r--fnl/nvrc/packs/gitsigns.fnl7
-rw-r--r--fnl/nvrc/packs/lsp_signature.fnl15
-rw-r--r--fnl/nvrc/packs/lspconfig.fnl50
-rw-r--r--fnl/nvrc/packs/nvimtree.fnl44
-rw-r--r--fnl/nvrc/packs/telescope.fnl49
-rw-r--r--fnl/nvrc/packs/treesitter.fnl29
-rw-r--r--fnl/nvrc/utils.fnl127
25 files changed, 1159 insertions, 0 deletions
diff --git a/fnl/nvrc/colors.fnl b/fnl/nvrc/colors.fnl
new file mode 100644
index 0000000..854b79f
--- /dev/null
+++ b/fnl/nvrc/colors.fnl
@@ -0,0 +1,81 @@
+(local colors {:bg "#202020"
+ :nvimbg "#151515"
+ :fg "#cbc0ab"
+ :white "#e8e8d3"
+ :black "#181818"
+ :black2 "#101010"
+ :bblack "#252525"
+ :grey "#888888"
+ :grey2 "#666666"
+ :bgrey "#999999"
+ :red "#cf6a4c"
+ :orange "#fabb6e"
+ :yellow "#fad07a"
+ :lyellow "#ffe2a9"
+ :green "#99ad6a"
+ :skyblue "#8fbfdc"
+ :blue "#8197bf"
+ :violet "#c6b6ee"
+ :magenta "#f0a0c0"
+ :sign "#333333"})
+
+(fn colors.apply []
+ (local {: highlight} (require :nvrc.macro.color))
+ (vim.cmd "colorscheme jellybeans")
+
+ ; Buffer
+ (highlight :EndOfBuffer {:fg (. colors :bg)})
+ (highlight :FloatBorder {:fg (. colors :blue)})
+ (highlight :NormalFloat {:bg (. colors :bblack)})
+
+ ; Pmenu
+ (highlight :Pmenu {:bg (. colors :bblack)})
+ (highlight :PmenuSbar {:bg (. colors :bblack)})
+ (highlight :PmenuSel {:fg (. colors :orange) :bg (. colors :sign)})
+ (highlight :PmenuThumb {:bg (. colors :skyblue)})
+ (highlight :CmpItemAbbr {:fg (. colors :fg)})
+ (highlight :CmpItemAbbrMatch {:fg (. colors :fg)})
+ (highlight :CmpItemKind {:fg (. colors :fg)})
+ (highlight :CmpItemMenu {:fg (. colors :fg)})
+
+ ; Misc
+ (highlight :StatusLine {:bg (. colors :black)})
+ (highlight :StatusLineNC {:fg (. colors :grey) :bg (. colors :black) :underline true})
+ (highlight :LineNr {:fg (. colors :grey)})
+ (highlight :NvimInternalError {:fg (. colors :red)})
+ (highlight :VertSplit {:fg (. colors :grey2)})
+
+ ; Gitsigns
+ (highlight :DiffAdd {:fg (. colors :green) :bg (. colors :sign)})
+ (highlight :DiffChange {:fg (. colors :yellow) :bg (. colors :sign)})
+ (highlight :DiffChangeDelete {:fg (. colors :red) :bg (. colors :sign)})
+ (highlight :DiffModified {:fg (. colors :red) :bg (. colors :sign)})
+ (highlight :DiffDelete {:fg (. colors :red) :bg (. colors :sign)})
+
+ ; Nvimtree
+ (highlight :NvimTreeNormal {:bg (. colors :black)})
+ (highlight :NvimTreeNormalNC {:bg (. colors :black)})
+ (highlight :NvimTreeStatuslineNC {:fg (. colors :black) :bg (. colors :black)})
+ (highlight :NvimTreeVertSplit {:fg (. colors :black) :bg (. colors :black)})
+ (highlight :NvimTreeWindowPicker {:fg (. colors :red) :bg (. colors :black2)})
+ (highlight :NvimTreeIndentMarker {:fg (. colors :grey)})
+ (highlight :NvimTreeGitDirty {:fg (. colors :red)})
+ (highlight :NvimTreeRootFolder {:fg (. colors :red) :underline true})
+ (highlight :NvimTreeEmptyFolderName {:fg (. colors :skyblue)})
+ (highlight :NvimTreeFolderIcon {:fg (. colors :skyblue)})
+ (highlight :NvimTreeFolderName {:fg (. colors :skyblue)})
+ (highlight :NvimTreeOpenedFolderName {:fg (. colors :magenta)})
+ (highlight :NvimTreeEndOfBuffer {:fg (. colors :black2)})
+
+ ; Telescope
+ (highlight :TelescopeBorder {:fg (. colors :fg)})
+ (highlight :TelescopePromptBorder {:fg (. colors :fg)})
+ (highlight :TelescopePromptNormal {:fg (. colors :fg)})
+ (highlight :TelescopePromptPrefix {:fg (. colors :red)})
+ (highlight :TelescopeNormal {:bg :NONE})
+ (highlight :TelescopePreviewTitle {:fg (. colors :nvimbg) :bg (. colors :green)})
+ (highlight :TelescopePromptTitle {:fg (. colors :nvimbg) :bg (. colors :red)})
+ (highlight :TelescopeResultsTitle {:fg (. colors :nvimbg) :bg (. colors :skyblue)})
+ (highlight :TelescopeSelection {:link :Search}))
+
+colors
diff --git a/fnl/nvrc/events.fnl b/fnl/nvrc/events.fnl
new file mode 100644
index 0000000..a798fcf
--- /dev/null
+++ b/fnl/nvrc/events.fnl
@@ -0,0 +1,47 @@
+(import-macros {: au!
+ : ac!} :nvrc.macro.event)
+(import-macros {: set!
+ : setl!} :nvrc.macro.set)
+(local {: echo!} (require :nvrc.lib.io))
+
+(local {: line
+ : mode} vim.fn)
+(fn cmd! [...] (vim.cmd ...))
+(fn bufexists? [...] (= (vim.fn.bufexists ...) 1))
+
+; Restore cursor style to beam on exit
+(au! restore-cursor
+ (ac! VimLeave * #(set! guicursor ["a:ver75-blinkon0"])))
+
+; Restore the last cursor line
+(au! restore-last-cursor-line
+ (ac! BufReadPost * #(if (and (> (line "'\"") 1)
+ (<= (line "'\"") (line "$")))
+ (cmd! "normal! g'\""))))
+
+; Resize splits on window resize
+(au! resize-splits-on-resize
+ (ac! VimResized * "wincmd ="))
+
+;; Read file when it changes on disk
+(au! read-file-on-disk-change
+ (ac! [FocusGained BufEnter CursorHold CursorHoldI] *
+ #(if (and (not= :c (mode))
+ (not (bufexists? "[Command Line]")))
+ (cmd! "checktime")))
+ (ac! FileChangedShellPost *
+ #(echo! "File changed on disk. Buffer reloaded.")))
+
+(au! terminal-options
+ ;; Enter Terminal-mode (insert) automatically
+ (ac! TermOpen * "startinsert")
+ ;; Disables line number on terminal buffers
+ (ac! TermOpen * #(do
+ (setl! nonumber)
+ (setl! norelativenumber)))
+ ;; Disables spell on terminal buffers
+ (ac! TermOpen * #(setl! nospell))
+ ;; Disables sign column on terminal buffers
+ (ac! TermOpen * #(setl! signcolumn :no))
+ ;; Disables colorcolumn on terminal buffers
+ (ac! TermOpen * #(setl! colorcolumn [])))
diff --git a/fnl/nvrc/ignite.fnl b/fnl/nvrc/ignite.fnl
new file mode 100644
index 0000000..04f416b
--- /dev/null
+++ b/fnl/nvrc/ignite.fnl
@@ -0,0 +1,6 @@
+; Get the rocket going
+
+(require :nvrc.options)
+(require :nvrc.pack)
+(require :nvrc.keymaps)
+(require :nvrc.events)
diff --git a/fnl/nvrc/keymaps.fnl b/fnl/nvrc/keymaps.fnl
new file mode 100644
index 0000000..67b0d70
--- /dev/null
+++ b/fnl/nvrc/keymaps.fnl
@@ -0,0 +1,45 @@
+(import-macros {: map!} :nvrc.macro.keymap)
+(import-macros {: setv!} :nvrc.macro.set)
+
+(map! [n] :<space> "" "")
+(setv! mapleader " ")
+
+(map! [n :silent] :<leader>fe ":NvimTreeToggle <cr>")
+(map! [n :silent] :<leader>ft ":NvimTreeFocus <cr>")
+
+(map! [n :silent] :<leader>/
+ ":lua require('Comment.api').toggle_current_linewise() <cr>")
+(map! [v :silent] :<leader>/
+ ":lua require('Comment.api').toggle_linewise_op(vim.fn.visualmode()) <cr>")
+
+(map! [n :silent] :<leader>ff ":Telescope find_files <cr>")
+(map! [n :silent] :<leader>fc ":Telescope grep_string <cr>")
+(map! [n :silent] :<leader>fs ":Telescope live_grep <cr>")
+(map! [n :silent] :<leader>fa
+ ":Telescope find_files follow=true no_ignore=true hidden=true <cr>")
+(map! [n :silent] :<leader>fb ":Telescope buffers <cr>")
+(map! [n :silent] :<leader>gc ":Telescope git_commits <cr>")
+(map! [n :silent] :<leader>gs ":Telescope git_status <cr>")
+
+(map! [n] :f :<plug>Lightspeed_f)
+(map! [n] :F :<plug>Lightspeed_F)
+(map! [n] :t :<plug>Lightspeed_t)
+(map! [n] :T :<plug>Lightspeed_T)
+
+(map! [n :silent] :<leader>rm ":TZMinimalist <cr>")
+(map! [n :silent] :<leader>rf ":TZFocus <cr>")
+(map! [n :silent] :<leader>ra ":TZAtaraxis <cr>")
+
+(map! [t] :jk "<C-\\><C-n>")
+(map! [t :silent] :JK "<C-\\><C-n> :lua require ('nvrc.utils').close_buf() <cr>")
+(map! [n :silent] :<leader>tl ":Telescope terms <cr>")
+; FIXME This opens on top of existing vertical/horizontal term
+(map! [n :silent] :<leader>th ":execute 15 .. 'new +terminal' | let b:term_type = 'hori' <cr>")
+(map! [n :silent] :<leader>tv ":execute 'vnew +terminal' | let b:term_type = 'vert' <cr>")
+(map! [n :silent] :<leader>tn ":execute 'terminal' | let b:term_type = 'wind' <cr>")
+
+(map! [n :silent] :<leader>q ":lua require('nvrc.utils').close_buf() <cr>")
+(map! [n :silent] :<leader>ya ":%y+ <cr>")
+(map! [n :silent] :<leader>bn ":enew <cr>")
+(map! [n :silent] :<leader>wn ":tabnew <cr>")
+(map! [n :silent] :<leader>lt ":set nu! <cr>")
diff --git a/fnl/nvrc/lib/io.fnl b/fnl/nvrc/lib/io.fnl
new file mode 100644
index 0000000..7d20ed7
--- /dev/null
+++ b/fnl/nvrc/lib/io.fnl
@@ -0,0 +1,31 @@
+(fn cmd! [...] (vim.cmd ...))
+(local {: format
+ : sub} string)
+
+(fn str? [x]
+ (= :string (type x)))
+
+(lambda double-quote [s]
+ "Add double quotes at the beginning and end of the string."
+ (assert (str? s) "expected string for s")
+ (format "\"%s\"" s))
+
+(lambda echo! [s]
+ "Print a vim message without any format."
+ (cmd! (format "echom %s" (double-quote s))))
+
+(lambda warn! [s]
+ "Print a vim message with a warning format."
+ (cmd! (format "echohl WarningMsg
+ echom %s
+ echohl None" (double-quote s))))
+
+(lambda err! [s]
+ "Print a vim message with an error format."
+ (cmd! (format "echohl ErrorMsg
+ echom %s
+ echohl None" (double-quote s))))
+
+{: echo!
+ : warn!
+ : err!}
diff --git a/fnl/nvrc/macro/color.fnl b/fnl/nvrc/macro/color.fnl
new file mode 100644
index 0000000..9636956
--- /dev/null
+++ b/fnl/nvrc/macro/color.fnl
@@ -0,0 +1,9 @@
+(fn tbl? [x]
+ (= :table (type x)))
+
+(fn highlight [group-arg colset]
+ "Add a highlighting group."
+ (each [_ group (ipairs (if (tbl? group-arg) group-arg [group-arg]))]
+ (vim.api.nvim_set_hl 0 group colset)))
+
+{: highlight}
diff --git a/fnl/nvrc/macro/event.fnl b/fnl/nvrc/macro/event.fnl
new file mode 100644
index 0000000..3453431
--- /dev/null
+++ b/fnl/nvrc/macro/event.fnl
@@ -0,0 +1,63 @@
+(import-macros {: as->} :nvrc.macro.thread)
+
+(local {: format} string)
+(local {: insert : concat} table)
+
+(local {: fn? : gensym-checksum : vlua} (require :nvrc.macro.toolkit))
+
+(fn last [xs]
+ (. xs (length xs)))
+
+(fn ->str [x]
+ (tostring x))
+
+(fn includes? [xs x]
+ (accumulate [is? false _ v (ipairs xs) :until is?]
+ (= v x)))
+
+(lambda au! [name ...]
+ "Defines an autocommand group using the vim API."
+ `(do
+ (vim.cmd ,(format "augroup %s" name))
+ (vim.cmd :autocmd!)
+ (do
+ ,...)
+ (vim.cmd "augroup END")))
+
+(lambda aub! [name ...]
+ "Defines a buffer-local autocommand group using the vim API."
+ `(do
+ (vim.cmd ,(format "augroup %s" name))
+ (vim.cmd "autocmd! * <buffer>")
+ (do
+ ,...)
+ (vim.cmd "augroup END")))
+
+(lambda ac! [events pattern ...]
+ "Defines an autocommand using the vim API."
+ (let [events (as-> [$ events] (if (sequence? $) $ [$])
+ (icollect [_ v (ipairs $)]
+ (->str v)) (concat $ ","))
+ pattern (as-> [$ pattern] (if (sequence? $) $ [$])
+ (icollect [_ v (ipairs $)]
+ (->str v)) (concat $ ","))
+ once? (or (includes? [...] `++once) (includes? [...] :++once))
+ nested? (or (includes? [...] `++nested) (includes? [...] :++nested))
+ command (last [...])]
+ (if (fn? command)
+ (let [fsym (gensym-checksum "__" command)]
+ `(do
+ (global ,fsym ,command)
+ (vim.cmd ,(format (if (and once? nested?)
+ "autocmd %s %s ++once ++nested call %s" once?
+ "autocmd %s %s ++once call %s" nested?
+ "autocmd %s %s ++nested call %s"
+ "autocmd %s %s call %s")
+ events pattern (vlua fsym)))))
+ `(vim.cmd ,(format (if (and once? nested?)
+ "autocmd %s %s ++once ++nested %s" once?
+ "autocmd %s %s ++once %s" nested?
+ "autocmd %s %s ++nested %s" "autocmd %s %s %s")
+ events pattern command)))))
+
+{: au! : aub! : ac!}
diff --git a/fnl/nvrc/macro/keymap.fnl b/fnl/nvrc/macro/keymap.fnl
new file mode 100644
index 0000000..7a784ab
--- /dev/null
+++ b/fnl/nvrc/macro/keymap.fnl
@@ -0,0 +1,46 @@
+(local {: gmatch} string)
+(local {: insert} table)
+
+(local {: fn?} (require :nvrc.macro.toolkit))
+
+(fn ->str [x]
+ (tostring x))
+
+(fn nil? [x]
+ (= nil x))
+
+(fn str? [x]
+ (= :string (type x)))
+
+(fn tbl? [x]
+ (= :table (type x)))
+
+(lambda map! [[modes & options] lhs rhs ?desc]
+ "Defines a new mapping using the lua API.
+ Supports all the options that the API supports."
+ (assert-compile (sym? modes) "expected symbol for modes" modes)
+ (assert-compile (tbl? options) "expected table for options" options)
+ (assert-compile (str? lhs) "expected string for lhs" lhs)
+ (assert-compile (or (str? rhs) (list? rhs) (fn? rhs) (sym? rhs))
+ "expected string or list or function or symbol for rhs" rhs)
+ (assert-compile (or (nil? ?desc) (str? ?desc))
+ "expected string or nil for description" ?desc)
+ (let [modes (icollect [char (gmatch (->str modes) ".")]
+ char)
+ options (collect [_ v (ipairs options)]
+ (->str v)
+ true)
+ rhs (if (and (not (fn? rhs)) (list? rhs)) `#,rhs rhs)
+ desc (if (and (not ?desc) (or (fn? rhs) (sym? rhs))) (view rhs) ?desc)
+ options (if desc (doto options (tset :desc desc)) options)]
+ `(vim.keymap.set ,modes ,lhs ,rhs ,options)))
+
+(lambda mapb! [[modes & options] lhs rhs ?description]
+ "Defines a new mapping using the lua API.
+ Supports all the options that the API supports.
+ Automatically sets the `:buffer` option."
+ (let [options (doto options
+ (insert :buffer))]
+ (map! [modes (unpack options)] lhs rhs ?description)))
+
+{: map! : mapb!}
diff --git a/fnl/nvrc/macro/misc.fnl b/fnl/nvrc/macro/misc.fnl
new file mode 100644
index 0000000..cde60ce
--- /dev/null
+++ b/fnl/nvrc/macro/misc.fnl
@@ -0,0 +1 @@
+{:disable-builtins! #(vim.tbl_map #(tset vim.g (.. :loaded_ $) 1) $)}
diff --git a/fnl/nvrc/macro/pack.fnl b/fnl/nvrc/macro/pack.fnl
new file mode 100644
index 0000000..5ba7896
--- /dev/null
+++ b/fnl/nvrc/macro/pack.fnl
@@ -0,0 +1,80 @@
+(fn str? [x]
+ (= :string (type x)))
+
+(fn nil? [x]
+ (= nil x))
+
+(fn tbl? [x]
+ (= :table (type x)))
+
+(local {: format} string)
+(local {: insert} table)
+
+(global nvrc/pack [])
+(global nvrc/rock [])
+
+(lambda pack [identifier ?options]
+ "Returns a mixed table with the identifier as the first sequential element
+ and options as hash-table items.
+ See https://github.com/wbthomason/packer.nvim for information about the
+ options."
+ (assert-compile (str? identifier) "expected string for identifier" identifier)
+ (assert-compile (or (nil? ?options) (tbl? ?options))
+ "expected table for options" ?options)
+ (let [options (or ?options {})
+ options (collect [k v (pairs options)]
+ (if
+ (= k :req) (values :config (format "require('nvrc.packs.%s')" v))
+ (= k :init) (values :config (format "require('%s').setup()" v))
+ (= k :defer) (values :setup (format "require('nvrc.utils').defer_unpack('%s', 5)" v))
+ (values k v)))]
+ (doto options
+ (tset 1 identifier))))
+
+(lambda pack! [identifier ?options]
+ "Declares a plugin with its options.
+ This is a mixed table saved on the global compile-time variable nvrc/pack.
+ See https://github.com/wbthomason/packer.nvim for information about the
+ options."
+ (assert-compile (str? identifier) "expected string for identifier" identifier)
+ (assert-compile (or (nil? ?options) (tbl? ?options))
+ "expected table for options" ?options)
+ (insert nvrc/pack (pack identifier ?options)))
+
+(lambda rock [identifier ?options]
+ "Returns a mixed table with the identifier as the first sequential element
+ and options as hash-table items.
+ See https://github.com/wbthomason/packer.nvim for information about the
+ options."
+ (assert-compile (str? identifier) "expected string for identifier" identifier)
+ (assert-compile (or (nil? ?options) (tbl? ?options))
+ "expected table for options" ?options)
+ (let [options (or ?options {})]
+ (doto options
+ (tset 1 identifier))))
+
+(lambda rock! [identifier ?options]
+ "Declares a plugin with its options.
+ This is a mixed table saved on the global compile-time variable nvrc/rock.
+ See https://github.com/wbthomason/packer.nvim for information about the
+ options."
+ (assert-compile (str? identifier) "expected string for identifier" identifier)
+ (assert-compile (or (nil? ?options) (tbl? ?options))
+ "expected table for options" ?options)
+ (insert nvrc/rock (rock identifier ?options)))
+
+(lambda unpack! []
+ "Initializes the plugin manager with the previously declared plugins and
+ their options."
+ (let [packs (icollect [_ v (ipairs nvrc/pack)]
+ `(use ,v))
+ rocks (icollect [_ v (ipairs nvrc/rock)]
+ `(use_rocks ,v))]
+ `((. (require :packer) :startup) #(do
+ ,(unpack (icollect [_ v (ipairs packs) :into rocks] v))))))
+
+{: pack
+ : pack!
+ : rock
+ : rock!
+ : unpack!}
diff --git a/fnl/nvrc/macro/set.fnl b/fnl/nvrc/macro/set.fnl
new file mode 100644
index 0000000..144bdef
--- /dev/null
+++ b/fnl/nvrc/macro/set.fnl
@@ -0,0 +1,79 @@
+(local {: fn? : gensym-checksum : vlua} (require :nvrc.macro.toolkit))
+
+(fn str? [x]
+ (= :string (type x)))
+
+(fn ->str [x]
+ (tostring x))
+
+(fn nil? [x]
+ (= nil x))
+
+(fn includes? [xs x]
+ (accumulate [is? false _ v (ipairs xs) :until is?]
+ (= v x)))
+
+(lambda set! [name ?value]
+ "Set a vim option via the lua API.
+ The name of the option must a symbol.
+ If no value is specified, if the name begins with 'no' the value
+ becomes false, true otherwise."
+ (assert-compile (sym? name) "expected symbol for name" name)
+ (let [name (->str name)
+ value (or ?value (not (name:match "^no")))
+ name (or (name:match "^no(.+)$") name)]
+ (if (fn? value)
+ (let [vsym (gensym-checksum "__" value)]
+ `(do
+ (global ,vsym ,value)
+ (tset vim.opt ,name ,(vlua vsym))))
+ (match (name:sub -1)
+ "+" `(: (. vim.opt ,(name:sub 1 -2)) :append ,value)
+ "-" `(: (. vim.opt ,(name:sub 1 -2)) :remove ,value)
+ "^" `(: (. vim.opt ,(name:sub 1 -2)) :prepend ,value)
+ _ `(tset vim.opt ,name ,value)))))
+
+(lambda setl! [name ?value]
+ "Set a vim local option via the lua API.
+ The name of the option must a symbol.
+ If no value is specified, if the name begins with 'no' the value
+ becomes false, true otherwise."
+ (assert-compile (sym? name) "expected symbol for name" name)
+ (let [name (->str name)
+ value (or ?value
+ (not (name:match "^no")))
+ name (or (name:match "^no(.+)$")
+ name)]
+ (if (fn? value)
+ (let [fsym (gensym-checksum "__" value)]
+ `(do
+ (global ,fsym ,value)
+ (tset vim.opt_local ,name ,(vlua fsym))))
+ (match (name:sub -1)
+ :+ `(: (. vim.opt_local ,(name:sub 1 -2)) :append ,value)
+ :- `(: (. vim.opt_local ,(name:sub 1 -2)) :remove ,value)
+ :^ `(: (. vim.opt_local ,(name:sub 1 -2)) :prepend ,value)
+ _ `(tset vim.opt_local ,name ,value)))))
+
+(lambda setv! [name value]
+ "Set a vim variable via the lua API.
+ The name can be either a symbol or a string.
+ If the name begins with [gbwt] followed by [/:.], the name
+ is scoped to the respective scope."
+ (assert-compile (or (str? name) (sym? name))
+ "expected string or symbol for name" name)
+ (let [name (->str name)
+ scope (when (includes? ["g/" "b/" "w/" "t/"
+ "g." "b." "w." "t."
+ "g:" "b:" "w:" "t:"] (name:sub 1 2))
+ (name:sub 1 1))
+ name (if
+ (nil? scope) name
+ (name:sub 3))]
+ `(tset ,(match scope
+ :b 'vim.b
+ :w 'vim.w
+ :t 'vim.t
+ _ 'vim.g) ,name ,value)))
+
+{: set! : setl! : setv!}
diff --git a/fnl/nvrc/macro/thread.fnl b/fnl/nvrc/macro/thread.fnl
new file mode 100644
index 0000000..9060b04
--- /dev/null
+++ b/fnl/nvrc/macro/thread.fnl
@@ -0,0 +1,15 @@
+(local {: insert} table)
+
+(lambda as-> [[binding expr] ...]
+ "A threading macro where the first argument is the value binded to the
+ second argument, which must be a symbol.
+ This binding is valid for the whole body of the threading macro."
+ (assert-compile (sym? binding) "expected symbol for binding" binding)
+ `(let [,binding ,expr
+ ,(unpack (accumulate [exprs [] _ expr (ipairs [...])]
+ (doto exprs
+ (insert binding)
+ (insert expr))))]
+ ,binding))
+
+{: as->}
diff --git a/fnl/nvrc/macro/toolkit.fnl b/fnl/nvrc/macro/toolkit.fnl
new file mode 100644
index 0000000..8a2bc50
--- /dev/null
+++ b/fnl/nvrc/macro/toolkit.fnl
@@ -0,0 +1,39 @@
+(local {: format} string)
+
+(fn ->str [x]
+ (tostring x))
+
+(fn head [xs]
+ (. xs 1))
+
+(fn fn? [x]
+ "Returns whether the parameter(s) is a function.
+ A function is defined as any list with 'fn or 'hashfn as
+ their first element."
+ (and (list? x) (or (= `fn (head x)) (= `hashfn (head x)))))
+
+(lambda gensym-checksum [...]
+ "Generates a new symbol from the checksum of the object
+ passed as a parameter.
+ The parameter first is casted into a string using the
+ function `fennel.view`.
+ If only one parameter is passed to the function the return
+ value is the checksum as a symbol.
+ If two parameters are passed, the first one is considered
+ the prefix.
+ If three parameters are passed, the first one is considered
+ the prefix and the last one is considered the suffix.
+ This function depends on the md5 library and the fennel library."
+ (match [...]
+ [prefix object suffix] (let [{: view} (require :fennel)
+ {:sumhexa md5} (require :md5)]
+ (sym (.. prefix (md5 (view object)) suffix)))
+ [prefix object] (gensym-checksum prefix object "")
+ [object] (gensym-checksum "" object "")))
+
+(lambda vlua [x]
+ "Return a symbol mapped to `v:lua.%s()`, where `%s` is the symbol."
+ (assert-compile (sym? x) "expected symbol for x" x)
+ (format "v:lua.%s()" (->str x)))
+
+{: fn? : gensym-checksum : vlua}
diff --git a/fnl/nvrc/options.fnl b/fnl/nvrc/options.fnl
new file mode 100644
index 0000000..b9a59bc
--- /dev/null
+++ b/fnl/nvrc/options.fnl
@@ -0,0 +1,51 @@
+(import-macros {: set! : setv!} :nvrc.macro.set)
+(local {: disable-builtins!} (require :nvrc.macro.misc))
+
+(set! clipboard :unnamedplus)
+
+; Interface
+(set! cul)
+(set! cmdheight 1)
+(set! number)
+(set! numberwidth 2)
+(set! shortmess+ :sI)
+(set! splitbelow)
+(set! splitright)
+(set! termguicolors)
+(set! lazyredraw)
+
+; Style
+(set! expandtab)
+(set! tabstop 8)
+(set! shiftwidth 2)
+(set! smartindent)
+(set! list)
+(set! listchars {:tab ">-" :extends ">" :precedes "<" :trail "*" :nbsp "+"})
+
+; Miscellaneous
+(set! ignorecase)
+(set! smartcase)
+(set! mouse :a)
+(set! timeoutlen 400)
+(set! updatetime 250)
+(set! undofile)
+(set! whichwrap+ "<>[]hl")
+
+(disable-builtins! [:2html_plugin
+ :getscript
+ :getscriptPlugin
+ :gzip
+ :logipat
+ :netrw
+ :netrwPlugin
+ :netrwSettings
+ :netrwFileHandlers
+ :matchit
+ :tar
+ :tarPlugin
+ :rrhelper
+ :spellfile_plugin
+ :vimball
+ :vimballPlugin
+ :zip
+ :zipPlugin])
diff --git a/fnl/nvrc/pack.fnl b/fnl/nvrc/pack.fnl
new file mode 100644
index 0000000..a1c611a
--- /dev/null
+++ b/fnl/nvrc/pack.fnl
@@ -0,0 +1,34 @@
+(import-macros {: pack! : unpack!} :nvrc.macro.pack)
+
+(pack! :wbthomason/packer.nvim)
+(pack! :rktjmp/hotpot.nvim)
+(pack! :lewis6991/impatient.nvim)
+(pack! :nvim-lua/plenary.nvim {:module :plenary})
+
+(pack! :nanotech/jellybeans.vim {:event :VimEnter :config "require('nvrc.colors').apply()"})
+(pack! :feline-nvim/feline.nvim {:req :feline :after :jellybeans.vim})
+(pack! :lukas-reineke/indent-blankline.nvim {:event :BufRead :req :blankline})
+(pack! :NvChad/nvim-colorizer.lua {:event :BufRead})
+(pack! :nvim-treesitter/nvim-treesitter {:req :treesitter :defer :nvim-treesitter :run ":TSUpdate"})
+(pack! :lewis6991/gitsigns.nvim {:req :gitsigns :defer :gitsigns.nvim})
+(pack! :Pocco81/TrueZen.nvim {:cmd [:TZMinimalist :TZFocus :TZAtaraxis]})
+(pack! :stefandtw/quickfix-reflector.vim {:ft :qf})
+
+(pack! :neovim/nvim-lspconfig {:req :lspconfig :module :lspconfig :setup (fn []
+ ((. (require :nvrc.utils) :defer_unpack) :nvim-lspconfig 100)
+ (vim.defer_fn #(vim.cmd "if &ft == 'packer' | echo '' | else | silent! e %") 150))})
+(pack! :ray-x/lsp_signature.nvim {:req :lsp_signature :after :nvim-lspconfig})
+(pack! :hrsh7th/nvim-cmp {:req :cmp :event :InsertEnter})
+(pack! :hrsh7th/cmp-nvim-lsp {:after :nvim-cmp})
+
+(pack! :luukvbaal/stabilize.nvim {:after :jellybeans.vim :init :stabilize})
+(pack! :numToStr/Comment.nvim {:module :Comment :init :Comment})
+; TODO: https://github.com/kyazdani42/nvim-tree.lua/issues/951
+(pack! :kyazdani42/nvim-tree.lua {:req :nvimtree :cmd [:NvimTreeToggle :NvimTreeFocus] :commit "d8bf1ad"})
+(pack! :ggandor/lightspeed.nvim {:keys [:s :S :x :X :f :F]})
+(pack! :nvim-telescope/telescope.nvim {:req :telescope :module :telescope :cmd :Telescope})
+(pack! :boppyt/nvrc-extra)
+
+(pack! :bakpakin/fennel.vim {:ft :fennel})
+
+(unpack!)
diff --git a/fnl/nvrc/packs/blankline.fnl b/fnl/nvrc/packs/blankline.fnl
new file mode 100644
index 0000000..3139174
--- /dev/null
+++ b/fnl/nvrc/packs/blankline.fnl
@@ -0,0 +1,11 @@
+(local {: setup} (require :indent_blankline))
+
+(setup {:indentLine_enabled 1
+ :char "▏"
+ :filetype_exclude {:help :terminal
+ :packer :lspinfo
+ :TelescopePrompt :TelescopeResults
+ :lsp-installer ""}
+ :buftype_exclude {1 :terminal}
+ :show_trailing_blankline_indent false
+ :show_first_indent_level false})
diff --git a/fnl/nvrc/packs/cmp.fnl b/fnl/nvrc/packs/cmp.fnl
new file mode 100644
index 0000000..3b70af5
--- /dev/null
+++ b/fnl/nvrc/packs/cmp.fnl
@@ -0,0 +1,56 @@
+(import-macros {: set!} :nvrc.macro.opt)
+(local cmp (require :cmp))
+
+(set! completeopt "menuone,noselect")
+
+(local icons {:Text "(t)"
+ :Method "(m)"
+ :Function "(f)"
+ :Constructor "(cs)"
+ :Field "(s)"
+ :Variable "(v)"
+ :Class "(c)"
+ :Interface "(i)"
+ :Module "(m)"
+ :Property "(p)"
+ :Unit "(u)"
+ :Value "(v)"
+ :Enum "(e)"
+ :Keyword "(k)"
+ :Snippet "(sn)"
+ :Color "(co)"
+ :File "(fi)"
+ :Reference "(r)"
+ :Folder "(fl)"
+ :EnumMember "(em)"
+ :Constant "(cn)"
+ :Struct "(s)"
+ :Event "(ev)"
+ :Operator "(op)"
+ :TypeParameter "(tp)"})
+
+(cmp.setup {
+ :formatting {:format (fn [entry vim-item]
+ (set vim-item.kind
+ (string.format "%s %s"
+ (. icons vim-item.kind)
+ vim-item.kind))
+ (set vim-item.menu
+ (. {:nvim_lsp "[LSP]"}
+ entry.source.name))
+ vim-item)}
+ :mapping {:<C-p> (cmp.mapping.select_prev_item)
+ :<C-n> (cmp.mapping.select_next_item)
+ :<C-d> (cmp.mapping.scroll_docs (- 4))
+ :<C-f> (cmp.mapping.scroll_docs 4)
+ :<C-Space> (cmp.mapping.complete)
+ :<C-e> (cmp.mapping.close)
+ :<CR> (cmp.mapping.confirm {:behavior cmp.ConfirmBehavior.Replace
+ :select true})
+ :Tab (fn [fallback]
+ (if (cmp.visible) (cmp.select_next_item)"")
+ (fallback))
+ :<S-Tab> (fn [fallback]
+ (if (cmp.visible) (cmp.select_next_item)"")
+ (fallback))}
+ :sources {1 {:name :nvim_lsp}}})
diff --git a/fnl/nvrc/packs/feline.fnl b/fnl/nvrc/packs/feline.fnl
new file mode 100644
index 0000000..4953a7d
--- /dev/null
+++ b/fnl/nvrc/packs/feline.fnl
@@ -0,0 +1,144 @@
+(local feline (require :feline))
+(local lsp (require :feline.providers.lsp))
+(local lsp_severity vim.diagnostic.severity)
+(local vi_mode (require :feline.providers.vi_mode))
+(local git (require :feline.providers.git))
+
+(local colors (require :nvrc.colors))
+(local utils (require :nvrc.utils))
+
+(local vi_mode_colors {:NORMAL (. colors :green)
+ :INSERT (. colors :red)
+ :VISUAL (. colors :yellow)
+ :OP (. colors :green)
+ :BLOCK (. colors :skyblue)
+ :REPLACE (. colors :violet)
+ :V-REPLACE (. colors :violet)
+ :ENTER (. colors :skyblue)
+ :MORE (. colors :skyblue)
+ :SELECT (. colors :orange)
+ :COMMAND (. colors :green)
+ :SHELL (. colors :green)
+ :TERM (. colors :green)
+ :NONE (. colors :yellow)})
+
+(local modules {:pad {:provider "▊ " :hl {:fg (. colors :skyblue)}}
+ :current_position {:provider :position
+ :left_sep " "
+ :right_sep {1 " "
+ 2 {:str :vertical_bar_thin
+ :hl {:fg :fg :bg :bg}}}}
+ :vi_mode {:provider :vi_mode
+ :icon ""
+ :right_sep " "
+ :hl (fn []
+ {:name (vi_mode.get_mode_highlight_name)
+ :fg (vi_mode.get_mode_color)})}
+ :file {:info {:provider {:name :file_info
+ :opts {:file_modified_icon "[+]"
+ :file_readonly_icon "!w "}}
+ :icon ""
+ :right_sep " "
+ :hl {:fg (. colors :orange) :style :bold}}
+ :encoding {:provider :file_encoding
+ :icon ""
+ :right_sep " "
+ :hl {:fg (. colors :magenta) :style :bold}}
+ :type {:provider :file_type
+ :icon ""
+ :right_sep " "
+ :hl {:fg (. colors :magenta) :style :bold}}
+ :size {:provider :file_size
+ :right_sep {1 " "
+ 2 {:str :vertical_bar_thin
+ :hl {:fg :fg :bg :bg}}}}}
+ :line_percentage {:provider :line_percentage
+ :right_sep " "
+ :hl {:style :bold}}
+ :scroll_bar {:provider :scroll_bar
+ :right_sep " "
+ :hl {:fg (. colors :skyblue) :style :bold}}
+ :lsp {:name {:provider :lsp_client-names
+ :icon ""
+ :right_sep " "
+ :hl {:fg (. colors :yellow)}}
+ :load_fidget {:provider #(utils.lsp_fidget)
+ :enabled #(utils.will_it_fit 80)
+ :hl {:fg (. colors :green)}}
+ :diag_err {:provider :diagnostic_errors
+ :enabled #(lsp.diagnostics_exist lsp_severity.ERROR)
+ :left_sep " "
+ :icon :E
+ :hl {:fg (. colors :red)}}
+ :diag_warn {:provider :diagnostic_warnings
+ :enabled #(lsp.diagnostics_exist lsp_severity.WARN)
+ :left_sep " "
+ :icon :W
+ :hl {:fg (. colors :yellow)}}
+ :diag_info {:provider :diagnostic_info
+ :enabled #(lsp.diagnostics_exist lsp_severity.INFO)
+ :left_sep " "
+ :icon :I
+ :hl {:fg (. colors :skyblue)}}
+ :diag_hint {:provider :diagnostic_hints
+ :enabled #(lsp.diagnostics_exist lsp_severity.HINT)
+ :left_sep " "
+ :icon :H
+ :hl {:fg (. colors :white)}}}
+ :git {:branch {:provider :git_branch
+ :enabled #(git.git_info_exists)
+ :icon "*"
+ :right_sep " "
+ :hl {:fg (. colors :violet) :style :bold}}
+ :add {:provider :git_diff_added
+ :enabled #(git.git_info_exists)
+ :icon "+"
+ :right_sep " "
+ :hl {:fg (. colors :green)}}
+ :change {:provider :git_diff_changed
+ :enabled #(git.git_info_exists)
+ :icon "~"
+ :right_sep " "
+ :hl {:fg (. colors :orange)}}
+ :remove {:provider :git_diff_removed
+ :enabled #(git.git_info_exists)
+ :icon "-"
+ :right_sep " "
+ :hl {:fg (. colors :red)}}}})
+
+(local comps {:left {:active [(. modules :pad)
+ (. modules :vi_mode)
+ (. modules :file :info)
+ (. modules :file :size)
+ (. modules :current_position)
+ (. modules :lsp :diag_err)
+ (. modules :lsp :diag_warn)
+ (. modules :lsp :diag_info)
+ (. modules :lsp :diag_hint)]
+ :inactive []}
+ :middle {:active [(. modules :lsp :load_fidget)]
+ :inactive []}
+ :right {:active [(. modules :git :branch)
+ (. modules :git :add)
+ (. modules :git :change)
+ (. modules :git :remove)
+ (. modules :file :encoding)
+ (. modules :file :type)
+ (. modules :line_percentage)
+ (. modules :scroll_bar)]
+ :inactive []}})
+
+(local components
+ {:active [comps.left.active comps.middle.active comps.right.active]
+ :inactive [comps.left.inactive comps.middle.inactive comps.right.inactive]})
+
+(local properties
+ {:force_inactive {:filetypes [:NvimTree :packer]
+ :buftypes [:terminal :packer]}})
+
+(feline.setup {:theme colors
+ :default_bg (. colors :bg)
+ :default_fg (. colors :fg)
+ : components
+ : properties
+ : vi_mode_colors})
diff --git a/fnl/nvrc/packs/gitsigns.fnl b/fnl/nvrc/packs/gitsigns.fnl
new file mode 100644
index 0000000..fe500a8
--- /dev/null
+++ b/fnl/nvrc/packs/gitsigns.fnl
@@ -0,0 +1,7 @@
+(local {: setup} (require :gitsigns))
+
+(setup {:signs {:add {:hl :DiffAdd :text "│" :numhl :GitSignsAddNr}
+ :change {:hl :DiffChange :text "│" :numhl :GitSignsChangeNr}
+ :delete {:hl :DiffDelete :text "_" :numhl :GitSignsDeleteNr}
+ :topdelete {:hl :DiffDelete :text "‾" :numhl :GitSignsDeleteNr}
+ :changedelete {:hl :DiffChangeDelete :text "~" :numhl :GitSignsChangeNr}}})
diff --git a/fnl/nvrc/packs/lsp_signature.fnl b/fnl/nvrc/packs/lsp_signature.fnl
new file mode 100644
index 0000000..b14a374
--- /dev/null
+++ b/fnl/nvrc/packs/lsp_signature.fnl
@@ -0,0 +1,15 @@
+(local {: setup} (require :lsp_signature))
+
+(setup {:bind true
+ :doc_lines 0
+ :floating_window true
+ :fix_pos true
+ :hint_enable true
+ :hint_scheme :String
+ :hint_prefix "(i) "
+ :hi_parameter :Search
+ :max_height 22
+ :max_width 120
+ :handler_opts {:border :single}
+ :zindex 200
+ :padding ""})
diff --git a/fnl/nvrc/packs/lspconfig.fnl b/fnl/nvrc/packs/lspconfig.fnl
new file mode 100644
index 0000000..83a4146
--- /dev/null
+++ b/fnl/nvrc/packs/lspconfig.fnl
@@ -0,0 +1,50 @@
+(local lsp (require :lspconfig))
+(local {: highlight} (require :nvrc.macro.color))
+(local {: merge} (require :nvrc.utils))
+(local colors (require :nvrc.colors))
+
+(fn on_attach [client bufnr]
+ (highlight :DiagnosticError {:fg (. colors :red)})
+ (highlight :DiagnosticWarn {:fg (. colors :yellow)})
+ (highlight :DiagnosticInformation {:fg (. colors :green)})
+ (highlight :DiagnosticHint {:fg (. colors :grey)})
+ (if client.resolved_capabilities.document_highlight
+ (do
+ (highlight :LspReferenceRead {:underline true})
+ (highlight :LspReferenceText {:underline true})
+ (highlight :LspReferenceWrite {:underline true})
+ (vim.api.nvim_exec "augroup lsp_document_highlight
+ autocmd! * <buffer>
+ autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
+ augroup END" false))))
+
+(fn better_root_pattern [patterns except-patterns]
+ "match path if one of the given patterns is matched, EXCEPT if one of the except-patterns is matched"
+ (fn [path]
+ (when (not ((lsp.util.root_pattern except-patterns) path))
+ ((lsp.util.root_pattern patterns) path))))
+
+(local default_capabilities (vim.lsp.protocol.make_client_capabilities))
+
+(fn init_lsp [lsp-name ?opts]
+ "initialize a language server with defaults"
+ (let [merged-opts (merge {: on_attach
+ :capabilities default_capabilities}
+ (or ?opts {}))]
+ ((. lsp lsp-name :setup) merged-opts)))
+
+(tset vim.lsp.handlers :textDocument/publishDiagnostics
+ (vim.lsp.with vim.lsp.diagnostic.on_publish_diagnostics
+ {:update_in_insert false
+ :virtual_text {:prefix "-"}
+ :signs false}))
+
+(init_lsp :ccls)
+(init_lsp :hls)
+(init_lsp :rust_analyzer)
+
+(vim.cmd "highlight link LspSemantic_type Include")
+(vim.cmd "highlight link LspSemantic_function Identifier")
+(vim.cmd "highlight link LspSemantic_struct Number")
+(vim.cmd "highlight LspSemantic_variable guifg=gray")
+(vim.cmd "highlight link LspSemantic_keyword Structure")
diff --git a/fnl/nvrc/packs/nvimtree.fnl b/fnl/nvrc/packs/nvimtree.fnl
new file mode 100644
index 0000000..83326ea
--- /dev/null
+++ b/fnl/nvrc/packs/nvimtree.fnl
@@ -0,0 +1,44 @@
+(import-macros {: setv!} :nvrc.macro.set)
+(local {: setup} (require :nvim-tree))
+
+(setv! nvim_tree_add_trailing 0)
+(setv! nvim_tree_git_hl 1)
+(setv! nvim_tree_highlight_opened_files 0)
+(setv! nvim_tree_indent_markers 1)
+(setv! nvim_tree_quit_on_open 0)
+(setv! nvim_tree_root_folder_modifier
+ (table.concat {1 ":t:gs?$?/.." 2 (string.rep " " 1000) 3 "?:gs?^??"}))
+(setv! nvim_tree_window_picker_exclude
+ {:filetype {1 :notify 2 :packer 3 :qf} :buftype {1 :terminal}})
+
+(setv! nvim_tree_show_icons {:folders 0 :files 0 :git 0 :folder_arrows 0})
+
+; Nvimtree still shows folder icon despite folders being disabled
+; Maybe the nvim_tree_show_icons option isn't really working?
+(setv! nvim_tree_symlink_arrow " -> ")
+(setv! nvim_tree_icons {:default ""
+ :symlink "~"
+ :git {:deleted :x
+ :ignored "?"
+ :renamed "->"
+ :staged "*"
+ :unmerged "!"
+ :unstaged "!"
+ :untracked "!"}
+ :folder {:default "+"
+ :empty "?"
+ :empty_open "-"
+ :open "-"
+ :symlink "~"
+ :symlink_open "~-"}})
+
+(setup {:filters {:dotfiles false}
+ :disable_netrw true
+ :hijack_netrw true
+ :auto_close false
+ :open_on_tab false
+ :hijack_cursor true
+ :update_cwd true
+ :update_focused_file {:enable true :update_cwd false}
+ :view {:allow_resize true :side :left :width 25 :hide_root_folder true}
+ :git {:enable false :ignore false}})
diff --git a/fnl/nvrc/packs/telescope.fnl b/fnl/nvrc/packs/telescope.fnl
new file mode 100644
index 0000000..9f9eb0f
--- /dev/null
+++ b/fnl/nvrc/packs/telescope.fnl
@@ -0,0 +1,49 @@
+(local telescope (require :telescope))
+
+(telescope.setup {:defaults {:vimgrep_arguments {1 :rg
+ 2 :--color=never
+ 3 :--no-heading
+ 4 :--with-filename
+ 5 :--line-number
+ 6 :--column
+ 7 :--smart-case}
+ :prompt_prefix "Search: "
+ :selection_caret " "
+ :entry_prefix " "
+ :initial_mode :insert
+ :selection_strategy :reset
+ :sorting_strategy :ascending
+ :layout_strategy :horizontal
+ :layout_config {:horizontal {:prompt_position :top
+ :preview_width 0.55
+ :results_width 0.8}
+ :vertical {:mirror false}
+ :width 0.87
+ :height 0.8
+ :preview_cutoff 120}
+ :file_sorter (. (require :telescope.sorters)
+ :get_fuzzy_file)
+ :file_ignore_patterns {1 :node_modules}
+ :generic_sorter (. (require :telescope.sorters)
+ :get_generic_fuzzy_sorter)
+ :path_display {1 :truncate}
+ :winblend 0
+ :border {}
+ :borderchars {1 "─"
+ 2 "│"
+ 3 "─"
+ 4 "│"
+ 5 "╭"
+ 6 "╮"
+ 7 "╯"
+ 8 "╰"}
+ :use_less false
+ :set_env {:COLORTERM :truecolor}
+ :file_previewer (. (require :telescope.previewers)
+ :vim_buffer_cat.new)
+ :grep_previewer (. (require :telescope.previewers)
+ :vim_buffer_vimgrep.new)
+ :qflist_previewer (. (require :telescope.previewers)
+ :vim_buffer_qflist.new)}})
+
+(telescope.load_extension :terms)
diff --git a/fnl/nvrc/packs/treesitter.fnl b/fnl/nvrc/packs/treesitter.fnl
new file mode 100644
index 0000000..6e02ae5
--- /dev/null
+++ b/fnl/nvrc/packs/treesitter.fnl
@@ -0,0 +1,29 @@
+(local {: setup} (require :nvim-treesitter.configs))
+
+(local colors (require :nvrc.colors))
+
+(setup {:ensure_installed [:fennel :lua]
+ :highlight {:enable true}
+ :indent {:enable true}
+ :refactor {:highlight_definitions {:enable true}
+ :highlight_current_scope {:enable false}
+ :smart_rename {:enable true
+ :keymaps {:smart_rename :<localleader>rn}}
+ :navigation {:enable true
+ :keymaps {:goto_definition :<localleader>gd
+ :list_definitions :<localleader>ld
+ :list_definitions_toc :<localleader>td
+ :goto_next_usage :<a-*>
+ :goto_previous_usage "<a-#>"}}}
+ :textobjects {:select {:enable true
+ :lookahead true
+ :keymaps {:if "@function.inner"
+ :af "@function.outer"
+ :ic "@class.inner"
+ :ac "@class.outer"
+ :ia "@parameter.inner"
+ :aa "@parameter.outer"}}
+ :swap {:enable true
+ :swap_next {:<localleader>> "@parameter.inner"}
+ :swap_previous {:<localleader>< "@parameter.inner"}}}
+ :matchup {:enable true}})
diff --git a/fnl/nvrc/utils.fnl b/fnl/nvrc/utils.fnl
new file mode 100644
index 0000000..6812c0c
--- /dev/null
+++ b/fnl/nvrc/utils.fnl
@@ -0,0 +1,127 @@
+(fn tbl? [x]
+ (= :table (type x)))
+
+(fn count [xs]
+ (if (tbl? xs) (table.maxn xs)
+ (not xs) 0
+ (length xs)))
+
+(fn run! [f xs]
+ "Execute the function (for side effects) for every xs."
+ (when xs
+ (let [nxs (count xs)]
+ (when (> nxs 0)
+ (for [i 1 nxs]
+ (f (. xs i)))))))
+
+(fn reduce [f init xs]
+ "Reduce xs into a result by passing each subsequent value into the fn with
+ the previous value as the first arg. Starting with init."
+ (var result init)
+ (run! (fn [x]
+ (set result (f result x))) xs)
+ result)
+
+(fn merge! [base ...]
+ (reduce (fn [acc m]
+ (when m
+ (each [k v (pairs m)]
+ (tset acc k v)))
+ acc) (or base {}) [...]))
+
+(fn merge [...]
+ (merge! {} ...))
+
+(fn lsp_fidget []
+ "Simple implementation of LSP fidget. Returns current LSP status with a spinner"
+ (let [lsp (. (vim.lsp.util.get_progress_messages) 1)]
+ (when lsp
+ (let [msg (or lsp.message "")
+ percentage (or lsp.percentage 0)
+ title (or lsp.title "")
+ spinners {1"⠋" 2 "⠙" 3 "⠹" 4 "⠸" 5 "⠼" 6 "⠴" 7 "⠦" 8 "⠧" 9 "⠇" 10 "⠏"}
+ success-icon "^.^!"
+ ms (/ (vim.loop.hrtime) 1000000)
+ frame (% (math.floor (/ ms 120)) (length spinners))]
+ (when (>= percentage 70)
+ (let [ertn [(string.format " %%<%s %s %s (%s%%%%) "
+ success-icon
+ title msg
+ percentage)]]
+ (lua "return (table.unpack or _G.unpack)(ertn)")))
+ (let [ertn [(string.format " %%<%s %s %s (%s%%%%) "
+ (. spinners
+ (+ frame 1))
+ title msg
+ percentage)]]
+ (lua "return (table.unpack or _G.unpack)(ertn)"))))) "")
+
+(fn will_it_fit [width winid]
+ "Returns whether this module will fit in the given width"
+ (> (vim.api.nvim_win_get_width (or (tonumber winid) 0)) width))
+
+(fn close_buf [force]
+ "ojroques/nvim-bufdel 'BSD-2'"
+ (let [opts {:next :cycle :quit false}]
+ (fn switch-buffer [windows buf]
+ (let [cur-win (vim.fn.winnr)]
+ (each [_ winid (ipairs windows)]
+ (set-forcibly! winid (or (tonumber winid) 0))
+ (vim.cmd (string.format "%d wincmd w" (vim.fn.win_id2win winid)))
+ (vim.cmd (string.format "buffer %d" buf)))
+ (vim.cmd (string.format "%d wincmd w" cur-win))))
+
+ (fn get-next-buf [buf]
+ (var next (vim.fn.bufnr "#"))
+ (when (and (= opts.next :alternate) (= (vim.fn.buflisted next) 1))
+ (lua "return next"))
+ (for [i 0 (- (vim.fn.bufnr "$") 1) 1]
+ (set next (+ (% (+ buf i) (vim.fn.bufnr "$")) 1))
+ (when (= (vim.fn.buflisted next) 1)
+ (lua "return next"))))
+
+ (local buf (vim.fn.bufnr))
+ (when (= (vim.fn.buflisted buf) 0)
+ (vim.cmd :close)
+ (lua "return "))
+ (when (< (length (vim.fn.getbufinfo {:buflisted 1})) 2)
+ (when opts.quit
+ (if force (vim.cmd :qall!) (vim.cmd "confirm qall"))
+ (lua "return "))
+ (local (term _)
+ (pcall (fn []
+ (vim.api.nvim_buf_get_var buf :term_type))))
+ (when term
+ (vim.cmd (string.format "setlocal nobl" buf))
+ (vim.cmd :enew)
+ (lua "return "))
+ (vim.cmd :enew)
+ (vim.cmd :bp))
+ (local next-buf (get-next-buf buf))
+ (local windows (. (. (vim.fn.getbufinfo buf) 1) :windows))
+ (if (or force (= (vim.fn.getbufvar buf :&buftype) :terminal))
+ (let [(term type) (pcall (fn []
+ (vim.api.nvim_buf_get_var buf :term_type)))]
+ (if term
+ (if (= type :wind)
+ (do
+ (vim.cmd (string.format "%d bufdo setlocal nobl" buf))
+ (vim.cmd :BufferLineCycleNext))
+ (let [cur-win (vim.fn.winnr)]
+ (vim.cmd (string.format "%d wincmd c" cur-win))
+ (lua "return ")))
+ (do
+ (switch-buffer windows next-buf)
+ (vim.cmd (string.format "bd! %d" buf)))))
+ (do
+ (switch-buffer windows next-buf)
+ (vim.cmd (string.format "silent! confirm bd %d" buf))))
+ (when (= (vim.fn.buflisted buf) 1)
+ (switch-buffer windows buf))))
+
+(fn defer_unpack [pack after]
+ (when pack
+ (set-forcibly! after (or after 0))
+ (vim.defer_fn (fn [] ((. (require :packer) :loader) pack)) after)))
+
+{: merge : lsp_fidget : will_it_fit : close_buf : defer_unpack}