423 lines
17 KiB
Fennel
423 lines
17 KiB
Fennel
;;; init.fnl - primary init file
|
|
|
|
;; 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)))
|
|
|
|
;; Make space leader
|
|
(set vim.g.mapleader " ")
|
|
(bind! :n :<space> :<nop>)
|
|
|
|
;; Enable lua filetype
|
|
(set vim.g.do_filetype_lua true)
|
|
|
|
;; Some options
|
|
; Make the mouse work
|
|
(set vim.opt.mouse :a)
|
|
(set vim.opt.mousemodel :extend)
|
|
; Ignore case when a query is all lower case
|
|
(set vim.opt.ignorecase true)
|
|
(set vim.opt.smartcase true)
|
|
; Enable line numbering
|
|
(set vim.opt.number true)
|
|
; Make <tab> insert 4 spaces
|
|
(set vim.opt.expandtab true)
|
|
(set vim.opt.tabstop 4)
|
|
(set vim.opt.shiftwidth 4)
|
|
(set vim.opt.shiftround true)
|
|
; Auto-indent
|
|
(set vim.opt.autoindent true)
|
|
(set vim.opt.smartindent true)
|
|
; Give context while scrolling
|
|
(set vim.opt.scrolloff 4)
|
|
(set vim.opt.sidescrolloff 8)
|
|
; Make splitting better
|
|
(set vim.opt.splitbelow true)
|
|
(set vim.opt.splitright true)
|
|
; 24 bit color support
|
|
(set vim.opt.termguicolors true)
|
|
; Shell like completions
|
|
(set vim.opt.wildmode [ :list :longest ])
|
|
; Set completion options
|
|
(set vim.opt.completeopt [ :menu :menuone :noselect ])
|
|
; Make buffers hide when abandoned
|
|
(set vim.opt.hidden true)
|
|
; Save undo data
|
|
(set vim.opt.undofile true)
|
|
; Text width
|
|
(set vim.opt.textwidth 80)
|
|
; Spell options
|
|
(set vim.opt.spelllang :en_us)
|
|
(set vim.opt.spelloptions :camel)
|
|
; Allow more freedom with the cursor
|
|
(set vim.opt.virtualedit :block)
|
|
|
|
;; Disable netrw
|
|
(set vim.g.loaded_netrw 1)
|
|
(set vim.g.loaded_netrwPlugin 1)
|
|
|
|
;; Remove trailing whitespace
|
|
(fn remove_trailing_whitespace []
|
|
"Remove trailing whitespace from the whole file."
|
|
(let [res (pcall vim.cmd "%s/ \\+$//gc")]
|
|
(vim.cmd.nohlsearch)
|
|
(when (not res)
|
|
(print "File is clean"))))
|
|
(vim.api.nvim_create_user_command :RemoveTrailingWhitespace
|
|
remove_trailing_whitespace {})
|
|
(bind! :n :<leader>ws remove_trailing_whitespace)
|
|
|
|
;; Spell keybindings
|
|
(bind! :n :<leader>l (fn []
|
|
(let [new_spell (not (vim.opt_local.spell:get))]
|
|
(set vim.opt_local.spell new_spell)
|
|
(print (if new_spell
|
|
"Enabled Spellcheck"
|
|
"Disabled Spellcheck")))))
|
|
|
|
(fn jump_or_open_terminal []
|
|
"If no terminal buffer exists, create one. Otherwise, open new one."
|
|
(var term_count 0)
|
|
(var last_id 0)
|
|
(var terms [ ])
|
|
(each [_ id (pairs (vim.api.nvim_list_bufs))]
|
|
(let [name (vim.api.nvim_buf_get_name id)]
|
|
(when (vim.startswith name "term://")
|
|
(table.insert terms name)
|
|
(set term_count (+ term_count 1))
|
|
(set last_id id))))
|
|
(if (= term_count 0)
|
|
(vim.cmd.terminal)
|
|
(= term_count 1)
|
|
(vim.cmd.buffer last_id)
|
|
(vim.ui.select terms
|
|
{ :prompt "Terminal Buffers" }
|
|
(fn [choice]
|
|
(when choice
|
|
(vim.cmd.buffer choice))))))
|
|
(bind! :n :<leader>t jump_or_open_terminal)
|
|
|
|
;; Some keybindings for diagnostics
|
|
(bind! :n :<leader>e vim.diagnostic.open_float)
|
|
(bind! :n "[d" vim.diagnostic.goto_prev)
|
|
(bind! :n "]d" vim.diagnostic.goto_next)
|
|
(bind! :n :<leader>q vim.diagnostic.setloclist)
|
|
|
|
;; 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")
|
|
|
|
;; 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 (fn []
|
|
(.. "recording @" (vim.fn.reg_recording)))
|
|
:cond (fn []
|
|
(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"
|
|
:config (fn []
|
|
(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 {
|
|
:<esc> :close
|
|
:<C-j> :move_selection_next
|
|
:<C-k> :move_selection_previous }
|
|
:n {
|
|
:<C-j> :move_selection_next
|
|
:<C-k> :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 :<leader>fq builtin.quickfix)
|
|
(bind! :n :<leader>fr builtin.registers)
|
|
(bind! :n :<leader>fj builtin.jumplist)
|
|
(bind! :n :<leader>fa builtin.marks)
|
|
(bind! :n :<leader>fh builtin.help_tags)
|
|
(bind! :n :<leader>g builtin.live_grep)
|
|
(bind! :n :<leader>fg builtin.live_grep)
|
|
(bind! :n :<leader>G builtin.grep_string)
|
|
(bind! :n :<leader>fG builtin.grep_string)
|
|
(bind! :n :<leader>b builtin.buffers)
|
|
(bind! :n :gb builtin.buffers)
|
|
(bind! :n :<leader>fu builtin.git_status)
|
|
(bind! :n :<leader>fm builtin.man_pages)
|
|
(bind! :n :<leader>fe builtin.diagnostics)
|
|
(bind! :n :<leader>fp builtin.spell_suggest)
|
|
(bind! :n :<leader>i builtin.find_files)
|
|
(bind! :n :z= builtin.spell_suggest)
|
|
(local repo_check_cmd
|
|
"git rev-parse --is-inside-work-tree >/dev/null 2>&1")
|
|
(bind! :n :<leader>ff (fn []
|
|
(let [code (os.execute repo_check_cmd)]
|
|
(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 "<plug>(leap-forward-to)")
|
|
(bind! :o :Z "<plug>(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))
|
|
|
|
;; Snippy
|
|
(use! "dcampos/nvim-snippy"
|
|
:config (fn []
|
|
(let [map (require :snippy.mapping)]
|
|
(bind! [ :i :s ] :<tab> ((. map :next) :<tab>))
|
|
(bind! [ :i :s ] :<s-tab> (map.previous :<tab>)))))
|
|
|
|
;; nvim-cmp (autocomplete)
|
|
(use! "hrsh7th/nvim-cmp"
|
|
:requires [ "hrsh7th/cmp-buffer"
|
|
"hrsh7th/cmp-path"
|
|
"hrsh7th/cmp-cmdline" ]
|
|
:after [ "nvim-snippy"
|
|
"telescope.nvim" ]
|
|
:config (fn []
|
|
(let [cmp (require :cmp)
|
|
compare (require :cmp.config.compare)]
|
|
(cmp.setup
|
|
{ :snippet {
|
|
:expand
|
|
#((. (require :snippy) :expand_snippet) $1.body) }
|
|
:mapping {
|
|
:<C-b> (cmp.mapping (cmp.mapping.scroll_docs -4)
|
|
[ :i :c ])
|
|
:<C-f> (cmp.mapping (cmp.mapping.scroll_docs 4)
|
|
[ :i :c ])
|
|
:<C-space> (cmp.mapping (cmp.mapping.complete)
|
|
[ :i :c ])
|
|
:<C-e> (cmp.mapping (cmp.mapping.abort)
|
|
[ :i :c ])
|
|
:<CR> (cmp.mapping
|
|
(cmp.mapping.confirm { :select false })
|
|
[ :i :c ])
|
|
:<C-j> (cmp.mapping
|
|
(cmp.mapping.select_next_item
|
|
{ :behavior cmp.SelectBehavior.Select })
|
|
[ :i :c ])
|
|
:<C-k> (cmp.mapping
|
|
(cmp.mapping.select_prev_item
|
|
{ :behavior cmp.SelectBehavior.Select })
|
|
[ :i :c ])
|
|
:<C-n> (cmp.mapping
|
|
(cmp.mapping.select_next_item
|
|
{ :behavior cmp.SelectBehavior.Select })
|
|
[ :i :c ])
|
|
:<C-p> (cmp.mapping
|
|
(cmp.mapping.select_prev_item
|
|
{ :behavior cmp.SelectBehavior.Select })
|
|
[ :i :c ])
|
|
:<down> (cmp.mapping
|
|
(cmp.mapping.select_next_item
|
|
{ :behavior cmp.SelectBehavior.Select })
|
|
[ :i :c ])
|
|
:<up> (cmp.mapping
|
|
(cmp.mapping.select_prev_item
|
|
{ :behavior cmp.SelectBehavior.Select })
|
|
[ :i :c ]) }
|
|
:sources (cmp.config.sources
|
|
{{ :name :nivm_lsp :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 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)))
|
|
(fn 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 :<C-k> vim.lsp.buf.signature_help buf)
|
|
(bind! :n :<leader>wa vim.lsp.buf.add_workspace_folder buf)
|
|
(bind! :n :<leader>wr vim.lsp.buf.remove_workspace_folder buf)
|
|
(bind! :n :<leader>wl #(print (vim.inspect
|
|
(vim.lsp.buf.list_workspace_folders))) buf)
|
|
(bind! :n :<leader>D vim.lsp.buf.type_definition buf)
|
|
(bind! :n :<leader>rn vim.lsp.buf.rename buf)
|
|
(bind! :n :<leader>cn vim.lsp.buf.code_action buf)
|
|
; (bind! :n :gr vim.lsp.buf.references buf)
|
|
(bind! :n :<leader>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 :<leader>s builtin.lsp_dynamic_workspace_symbols buf)
|
|
(bind! :n :<leader>fs builtin.lsp_dynamic_workspace_symbols buf)
|
|
(bind! :n :<leader>fS builtin.lsp_workspace_symbols buf)
|
|
(bind! :n :<leader>d builtin.lsp_document_symbols buf)
|
|
(bind! :n :<leader>fd builtin.lsp_document_symbols buf)))
|
|
(let [lsp (require :lspconfig)
|
|
lsp_cap ((. (require :cmp_nvim_lsp) :default_capabilities))
|
|
default_config { :on_attach on_attach
|
|
:capabilities lsp_cap }]
|
|
nil))
|
|
(use! "neovim/nvim-lspconfig"
|
|
:requires "hrsh7th/cmp-nvim-lsp"
|
|
:after "nvim-cmp"
|
|
:config lsp_config_callback))
|
|
|
|
(vim.cmd.packadd "packer.nvim")
|
|
(let [packer (require :packer)]
|
|
(packer.startup packer_init_callback))
|