this repo has no description
1(import-macros {: use : reuse} :relude)
2
3(use nvim {: map : fun : api : opt : cmd})
4
5(reuse plugins)
6
7(use picker)
8(import-macros {: augroup : defcommand} :nvim)
9
10(set opt.shell :fish)
11
12(do ; MatchIt must be unloaded for MatchPair to work correctly
13 (set vim.g.loaded_matchit true)
14 (set vim.g.matchup_surround_enabled true))
15
16(do ; Colors
17 (cmd.colorscheme :blame)
18 (opt {:termguicolors true
19 :guicursor ["n-v-c-sm:block-Cursor"
20 "i-ci-ve:ver25-Cursor"
21 "r-cr-o:hor20-Cursor"]}))
22
23(do ; Indentation
24 (opt {:shiftwidth 2
25 :expandtab true
26 :textwidth 80
27 :wrap false
28 :linebreak true
29 :formatoptions :tcqjl}))
30
31(do ; UI
32 (opt {:updatetime 500
33 :title true
34 :showmode true
35 :signcolumn "yes:1"}))
36
37(do ; Display tabs and trailing spaces visually
38 (opt {:fillchars ["vert:┃" "fold:·"]
39 :list true
40 :listchars ["tab:→ "
41 "trail:·"
42 "nbsp:␣"
43 "extends:↦"
44 "precedes:↤"]
45 :conceallevel 2
46 :concealcursor :nc}))
47
48(do ; Ignore case.
49 ; If your code uses different casing to differentiate files, then you need
50 ; mental help
51 (opt {:wildignorecase true
52 :wildmode :full
53 :fileignorecase true
54 :wildignore [:*.o
55 "*~"
56 :**/.git/**
57 :**/node_modules/**
58 :**/_build/**
59 :**/deps/**
60 :**/target/**
61 :**/uploads/**
62 :*.lock]}))
63
64(opt {:diffopt+ [:indent-heuristic "algorithm:patience"]
65 :iskeyword+ ["-"]})
66
67(do ; Autowrite file whenever possible
68 (opt {:hidden false :autowriteall true}))
69
70(do
71 (set opt.mousescroll ["ver:3" "hor:0"])
72 ; Keep cursor in the middle
73 (let [value 9999
74 enter (fn []
75 (set opt.window.signcolumn :no)
76 (set opt.window.scrolloff 0))
77 leave (fn []
78 (set opt.window.signcolumn "yes:1")
79 (set opt.window.scrolloff value))]
80 (set opt.scrolloff value)
81 (augroup terminal-scrolloff
82 (on TermOpen "*" (enter))
83 (on BufEnter "term://*" (enter))
84 (on BufLeave "term://*" (leave)))))
85
86(do ; XXI century - we have cursors now
87 (set opt.mouse :a))
88
89(do
90 (set opt.title true)
91 (augroup window-title
92 (on BufEnter "*"
93 (let [cwd (fun.getcwd)
94 project (fun.fnamemodify cwd ":p:~:h")]
95 (set opt.titlestring (.. "nvim " project))))))
96
97(do ; TreeSitter
98 (let [try-start (fn []
99 (let [(value _error) (vim.treesitter.get_parser nil nil {:error false})]
100 (if value (vim.treesitter.start))))]
101 (defcommand TSStart (try-start))
102 (defcommand TSStop (vim.treesitter.stop))
103 (augroup ts-start
104 (on FileType [:elixir :eex :heex :fennel :rust :nix :css] (try-start)))))
105
106
107(do ; Split in CORRECT places
108 (opt {:splitright true :splitbelow true}))
109
110(do ; Searching
111 (opt {:ignorecase true :smartcase true :inccommand :nosplit}))
112
113(do ; Permanent undo
114 (set opt.undofile true))
115
116(do ; Save only meaningful data to sessions
117 (set opt.sessionoptions [:blank
118 :buffers
119 :curdir
120 :folds
121 :tabpages
122 :winsize
123 :terminal]))
124
125(do ; Folding
126 (opt {:foldmethod :expr
127 :foldexpr "nvim_treesitter#foldexpr()"
128 :foldlevel 999})
129 (map :n :<CR> "foldlevel(\".\") ? \"za\" : \"\\<CR>\"" {:expr true}))
130
131(do ; Completion
132 (opt {:complete ["." :w :b :t :k :kspell]
133 :completeopt [:menuone :noselect :noinsert]}))
134
135(do ; Clap
136 (map :n :<Space><Space> #(picker.find-files)))
137
138(do ; Additional "Close" commands
139 (map :n :ZS ":wa")
140 (map :n :ZA ":qa")
141 (map :n :ZX ":cq"))
142
143(do ; Swap ; and : for easier command line mode
144 (let [swap (fn [a b]
145 (map :nx a b)
146 (map :nx b a))]
147 (swap ";" ":")
148 (map :n "q;" "q:")))
149
150(do ; Expand abbreviation when hit <CR>
151 (map :i :<CR> "<C-]><CR>"))
152
153(do ; Make Vim behaviour consistent
154 (map :n :Y :y$))
155
156(do ; Code formatting
157 (map :n :g= "=aGg``")
158 (map :nx :Q :gq)
159 (map :n :gQ "gqaG``"))
160
161(do ; Smart `0`
162 ; Goes to the beginning of the text at first and later goes to the beginning of
163 ; the line, alternates afterwards
164 (map :n :0 "virtcol('.') - 1 <= indent('.') && col('.') > 1 ? '0' : '_'"
165 {:expr true}))
166
167(do ; Help viewing and opening URLs
168 (defcommand Dash {:nargs "?"} (fun.dash#open (tostring args)))
169 (map :n :gK ":Dash")
170 (map :n :gq #(let [name (fun.expand :<cfile>)]
171 (fun.jobstart [:open name] {:detach true})
172 (print :Open name))))
173
174(do ; Text object for whole file
175 (map :o :aG ":normal! ggVG"))
176
177(do ; Quickly disable highlight
178 (map :n "<Space>," ":nohlsearch"))
179
180(do ; Frequently used unimpaired mappings
181 (let [unimpaired (fn [char left right]
182 (map :n (.. "[" char) left)
183 (map :n (.. "]" char) right))]
184 (unimpaired :w :gT :gt)))
185
186(do ; Terminal mappings
187 ; (map :n :<C-q>c ":term")
188 (map :n :<C-q>s ":Start")
189 (map :n :<C-q>v ":vert Start")
190 (map :n :<C-q>t ":tab Start")
191 (map :t :<C-q> "<C-\\><C-n>")
192 (map :n :<C-q> :<ESC>)
193 (map :n :<C-q>q :<ESC>)
194 (map :n :<C-q><C-q> :<ESC>)
195 (map :i :<C-q><C-q> :<ESC>))
196 ; (when (fun.executable :nvr)
197 ; (set vim.env.EDITOR "nvr -cc split -c 'set bufhidden=delete' --remote-wait")))
198
199(do ; Git mappings
200 (let [leader :U
201 git-map (fn [lhs cmd]
202 (map :n (.. leader lhs) (.. ":Git " cmd)))]
203 (map :n leader :<nop>)
204 (map :n (.. leader leader) (.. leader :u) {:noremap false})
205 (git-map :p :push)
206 (git-map :s "")
207 (git-map :d :diff)
208 (git-map :B :blame)
209 (git-map :c :commit)
210 (git-map :u :pull)
211 (git-map :g :log)))
212
213; (do ; Split management
214; (set vim.g.choosewin_label :QWERTASDF)
215; (map :n :<C-w><C-w> "<plug>(choosewin)")
216; (map :n :<C-_> "<plug>(choosewin)"))
217
218(do ; Search
219 (when (fun.executable :rg)
220 (opt {:grepprg "rg --vimgrep --no-heading --smart-case"
221 :grepformat "%f:%l:%c:%m,%f:%l%m,%f %l%m"})))
222
223(do ; Matchparen
224 (set vim.g.matchup_matchparen_offscreen {:method :popup})
225 (augroup matchparen-term
226 (let [term "term://*"]
227 (on BufEnter term (cmd.NoMatchParen))
228 (on BufLeave term (cmd.DoMatchParen)))))
229
230(do ; Autoreload Direnv after writing the .envrc
231 (when (fun.executable :direnv)
232 (augroup autoreload-envrc
233 (on BufWritePost :.envrc
234 (fun.system ["direnv" "allow" (fun.expand "%")])
235 (cmd.DirenvExport)))))
236
237(do ; Setup Lua extensions
238 (let [setup (fn [package config]
239 (let [lib (require package)
240 f (. lib :setup)
241 opts (match (type config)
242 :nil {}
243 :function (config lib)
244 :table config)]
245 (f opts)
246 lib))]
247 (setup :mini.ai)
248 (setup :mini.align
249 {:mappings {:start :gl
250 :start_with_preview :gL}})
251 ;(setup :mini.bracketed)
252 (setup :mini.bufremove
253 (fn [bufremove]
254 (defcommand Bd (bufremove.delete))
255 (defcommand BClean
256 (->> (fun.getbufinfo {:buflisted true})
257 (vim.tbl_filter #(= (next $1.windows) nil))
258 (#(each [_ v (ipairs $1)]
259 (bufremove.delete v.bufnr)))))
260 {:set_vim_settings false}))
261 (setup :mini.jump {:mappings {:repeat_jump ":"}})
262 (setup :mini.operators {
263 :multiply {:prefix ""}
264 :replace {:prefix ""}
265 :sort {:prefix ""}})
266 (setup :mini.sessions
267 (fn [sessions]
268 (let [complete (fn [with-current?]
269 #(icollect [_ spec (pairs sessions.detected)]
270 (when (not (and with-current?
271 (= spec.path vim.v.this_session)))
272 spec.name)))]
273 (defcommand SSave {:nargs "?" :bang true}
274 (print (sessions.write args {:force bang})))
275 (defcommand SDelete {:nargs "?" :bang true :complete (complete true)}
276 (print (sessions.delete args {:force bang})))
277 (defcommand SRead {:nargs 1 :bang true :complete (complete false)}
278 (print (sessions.read (tostring args) {:force bang}))))
279 {:directory (.. (fun.stdpath :data) "/site/sessions/")}))
280 (setup :mini.starter
281 (fn [starter]
282 {:items [(starter.sections.sessions 10 true)
283 (starter.sections.builtin_actions)]}))
284 (setup :mini.surround
285 {:mappings {:add :gsa
286 :delete :gsd
287 :find :gsf
288 :find_left :gsF
289 :highlight ""
290 :replace :gss
291 :update_n_lines ""}})
292 ; (setup :nvim-treesitter
293 ; {:highlight {:enable true
294 ; ; Currently disable as it do not work as expected
295 ; :disable [:erlang :make :diff]}
296 ; :matchup {:enable true}
297 ; :indent {:enable true}
298 ; :incremental_selection {:enable true}})
299 ; (setup :neorg
300 ; {:load {:core.defaults {}
301 ; :core.concealer {}}})
302 ))
303
304(defcommand Clean "keeppatterns %s/\\s\\+$//e | set nohlsearch")
305
306(do ; Async Make and Grep
307 (let [run (fn [args f-args]
308 (api.call-function "asyncdo#run" (vim.list_extend args f-args)))]
309 (defcommand Make {:bang true :nargs "*" :complete :file}
310 (run [bang opt.makeprg] args))
311 (defcommand Grep {:bang true :nargs "+" :complete :dir}
312 (run [bang {:job opt.grepprg :errorformat opt.grepformat}]
313 args))))
314
315(defcommand Ctags (cmd.AsyncDo "ctags -R ."))
316
317(defcommand Start {:nargs "*"}
318 (let [args (if (= (length args) 0) (fun.split opt.shell) args)
319 command (icollect [_ v (pairs args)] (fun.expand v))]
320 (cmd.new {:mods mods})
321 (fun.termopen command)
322 (cmd.startinsert)))
323
324(do ; TreeSJ
325 (map :n :gS #(let [lib (require "treesj")
326 toggle (. lib :toggle)]
327 (toggle))))
328
329(require :langclient)