aboutsummaryrefslogtreecommitdiff
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
downloadnvimrc-72d448e384249103748ee83b587c45924e4bc44d.zip
Initial commit
-rw-r--r--.gitignore1
-rw-r--r--LICENSES/aniseed.md24
-rw-r--r--LICENSES/zest.md9
-rw-r--r--README.md16
-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
-rw-r--r--init.lua35
-rw-r--r--lua/md5.lua397
31 files changed, 1641 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8cb205e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+plugin
diff --git a/LICENSES/aniseed.md b/LICENSES/aniseed.md
new file mode 100644
index 0000000..cf1ab25
--- /dev/null
+++ b/LICENSES/aniseed.md
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org>
diff --git a/LICENSES/zest.md b/LICENSES/zest.md
new file mode 100644
index 0000000..b1e62e7
--- /dev/null
+++ b/LICENSES/zest.md
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2021 tsbohc
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..99180e7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+<div align="center">
+
+# .nvrc
+> *Elegant neovim config written in fennel, for more civilized age.*
+
+> Happy hacking!
+
+</div>
+
+# Shoutouts
+- [rktjmp/hotpot.nvim](https://github.com/rktjmp/hotpot.nvim)
+- [wbthomason/packer.nvim](https://github.com/wbthomason/packer.nvim)
+- [datwaft/nvim.conf](https://github.com/datwaft/nvim.conf)
+- [kolja/vimrc](https://github.com/kolja.vimrc)
+- [tsbohc/zest.nvim](https://github.com/tsbohc/zest.nvim)
+- [Olical/aniseed](https://github.com/Olical/aniseed)
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