Switch vim config to lua (Full rewrite)

This commit is contained in:
ItsDrike 2021-11-30 20:22:51 +01:00
parent f0385c4961
commit bb7a2af9f9
No known key found for this signature in database
GPG key ID: FB8CA11A2CF3A843
25 changed files with 497 additions and 303 deletions

View file

@ -0,0 +1,45 @@
local vim = require("vim")
local cmd = vim.cmd
-- I'm not aware of abbreviations having direct lua support like mappings,
-- though I'm not certain on that and may be completely wrong, if there is
-- a better way, this is opened to pull requests.
-- TODO: Check direct abbrev lua support
-- Make these function definitions global as they could be reused
-- in plugin specific scripts or in other places.
function abbrev(mode, input, result, reabbrev)
-- Assume noreabbrev unless specified otherwise
reabbrev = reabbrev or false
local command
if reabbrev then
command = mode .. "abbrev"
else
command = mode .. "noreabbrev"
end
cmd(command .. " " .. input .. " " .. result)
end
function cabbrev(input, result, reabbrev)
abbrev("c", input, result, reabbrev)
end
-- Invalid case abbreviations
cabbrev("Wq", "wq")
cabbrev("wQ", "wq")
cabbrev("WQ", "wq")
cabbrev("Wa", "wa")
cabbrev("W", "w")
cabbrev("Q", "q")
cabbrev("Qall", "qall")
cabbrev("W!", "w!")
cabbrev("Q!", "q!")
cabbrev("Qall!", "qall!")
-- Save file with sudo
cabbrev("w!!", "w !sudo tee > /dev/null %")
-- Reload lua configuration
-- TODO: Get the path dynamically
cabbrev("reload", "luafile ~/.config/nvim/init.lua")

View file

@ -0,0 +1,21 @@
local vim = require("vim")
local cmd = vim.cmd
-- Disable automatic commenting on newlines
cmd[[autocmd FileType * setlocal formatoptions-=cro]]
-- Have vim jump to last position when reopening a file
cmd[[autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif]]
-- Automatically delete all trailing whitespace on save
cmd[[autocmd BufWritePre * %s/\s\+$//e]]
-- Enable spellcheck for certain file types
cmd[[autocmd FileType tex,latex,markdown,gitcommit setlocal spell spelllang=en_us]]
-- Use auto-wrap for certain file types at 119 chars
cmd[[autocmd FileType markdown setlocal textwidth=119]]
-- Don't show line numbers in terminal
cmd[[autocmd BufEnter term://* setlocal nonumber | setlocal norelativenumber]]

View file

@ -0,0 +1,44 @@
local vim = require("vim")
local cmd = vim.cmd
local o = vim.opt
cmd[[filetype plugin on]]
-- Tab settings
o.expandtab = true -- Expand tabs to spaces
o.tabstop = 4 -- Tab size
o.shiftwidth = 4 -- Indentation size
o.softtabstop = 4 -- Tabs/Spaces interlop
o.tabpagemax = 50 -- More tabs
-- Folding
o.foldmethod = "indent" -- Use indent to determine the fold levels
o.foldnestmax = 8 -- Only fold up to given amount of levels
o.foldlevel = 2 -- Set initial fold level
o.foldenable = false -- Hide all folds by default
-- Split order
o.splitbelow = true -- Put new windows below current
o.splitright = true -- Put new vertical splits to right
-- In-file search (/)
o.ignorecase = true -- Use case insensitive matching
o.incsearch = true -- Show partial matches for search phrase
o.hlsearch = true -- Highlight search matches
-- Show trailing whitespace
o.list = true -- Enable showing characters like <Tab>, <EOL>, ...
o.listchars = "trail:·" -- Only show trailing whitespaces
-- Command-mode search
o.wildmode = {"longest", "list", "full"} -- Enable autocompletion
o.wildmenu = true -- Display all matching files when we tab complete
table.insert(o.path, "**") -- Search down into subfolders with tab completion
-- Misc
o.mouse = "a" -- Enable mouse mode
o.encoding = "utf-8" -- Use UTF-8 encoding
o.autoindent = true -- Enable autoindent
o.autoread = true -- Automatically reload files on change
o.undolevels = 999 -- Lots of these
o.history = 1000 -- More history

View file

@ -0,0 +1,112 @@
local vim = require("vim")
-- Make these function definitions global as they could be reused
-- in plugin specific scripts or in other places.
function keymap(mode, shortcut, command, options)
-- Assume silent, noremap unless specified otherwise
local opts = {noremap=true, silent=true}
if options then opts = vim.tbl_extend("force", opts, options) end
-- Perform the actual remap
vim.api.nvim_set_keymap(mode, shortcut, command, opts)
end
-- This is a bit silly, but I don't like passing the mode argument
-- to every keymap definition and this makes things a lot easier
-- and a bit more vimscript-like
function nmap(shortcut, command, options)
keymap("n", shortcut, command, options)
end
function imap(shortcut, command, options)
keymap("i", shortcut, command, options)
end
function vmap(shortcut, command, options)
keymap("v", shortcut, command, options)
end
function tmap(shortcut, command, options)
keymap("t", shortcut, command, options)
end
-- Unmap arrow keys in normal mode to remove bad habits
nmap("<Down>", "<nop>")
nmap("<Left>", "<nop>")
nmap("<Right>", "<nop>")
nmap("<Up>", "<nop>")
-- Tab navigation
nmap("<Tab>", "gt")
nmap("<S-Tab>", "gT")
nmap("<A-t>", ":tabnew<CR>")
nmap("<A-2>", ":tabmove +<CR>")
nmap("<A-1>", ":tabmove -<CR>")
nmap("<A-p>", ":tabp<CR>")
nmap("<A-n>", ":tabn<CR>")
-- Set splits navigation to just ALT + hjkl
nmap("<C-h>", "<C-w>h")
nmap("<C-j>", "<C-w>j")
nmap("<C-k>", "<C-w>k")
nmap("<C-l>", "<C-w>l")
-- Split size adjusting
nmap("<C-Right>", ":verical resize +3<CR>")
nmap("<C-Left>", ":vertical resize -3<CR>")
nmap("<C-Up>", ":resize +3<CR>")
nmap("<C-Down>", ":resize -3<CR>")
-- Define some common shortcuts
nmap("<C-s>", ":w<CR>")
nmap("<C-z>", ":undo<CR>")
nmap("<C-y>", ":redo<CR>")
-- Terminal
nmap("<C-t>", ":split term://zsh<CR>i")
nmap("<C-A-t>", ":vnew term://zsh<CR>i")
nmap("<A-T>", ":tabnew term://zsh<CR>i")
tmap("<Esc>", "<C-\\><C-n>")
-- Use space for folding/unfolding sections
nmap("<space>", "za")
vmap("<space>", "zf")
-- Use shift to quickly move 10 lines up/down
nmap("K", "10k")
nmap("J", "10j")
-- Enable/Disable auto commenting
nmap("<leader>c", ":setlocal formatoptions-=cro<CR>")
nmap("<leader>C", ":setlocal formatoptions+=cro<CR>")
-- Don't leave visual mode after indenting
vmap("<", "<gv")
vmap(">", ">gv")
-- System clipboard copying
vmap("<C-c>", '"+y')
-- Alias replace all
nmap("<A-s>", ":%s//gI<Left><Left><Left>", {silent=false})
-- Stop search highlight with Esc
nmap("<esc>", ":noh<CR>")
-- Start spell-check
nmap("<leader>s", ":setlocal spell! spelllang=en_us<CR>")
-- Run shell check
nmap("<leader>p", ":!shellckeck %<CR>")
-- Compile opened file (using custom script)
nmap("<A-c>", ":w | !comp <c-r>%<CR>")
-- Close all opened buffers
nmap("<leader>Q", ":bufdo bdelete<CR>")
-- Don't set the incredibely annoying mappings that trigger dynamic SQL
-- completion with dbext and keeps on freezing vim whenever pressed with
-- a message saying that dbext plugin isn't installed
-- See :h ft-sql.txt
vim.g.omni_sql_no_default_maps = 1

View file

@ -0,0 +1,42 @@
local vim = require("vim")
local g = vim.g
local cmd = vim.cmd
cmd[[
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
]]
-- Airline specific theming settings
g.airline_theme = 'codedark' -- Use codedark theme from vim-airline-themes
g.airline_right_sep = "" -- Don't use special separators (<)
g.airline_left_sep = "" -- Don't use special separators (>)
-- Tabline setup
-- TODO: Figure out how to set # separated variables in lua (open for PRs)
cmd[[let g:airline#extensions#tabline#enabled = 1]] -- Enable tabline (top line)
cmd[[let g:airline#tabline#formatter = 'unique_tail']] -- Tabline filename formatter
-- Special symbols
g.webdevicons_enable_airline_statusline = 0 -- Use special icons from vim-devicons (requires nerdfonts)
g.airline_powerline_fonts = 1 -- Use special symbols from poweline fonts (line no, col no)
if not os.getenv("DISPLAY") then -- Use ASCII-only if we're in TTY
g.airline_symbols_ascii = 1
end
-- Disable airline in nerdtree buffer
-- TODO; For some reason, this fails even though it works in regular vimscript
--[[
cmd[[
augroup filetype_nerdtree
au!
au FileType nerdtree call s:disable_airline_on_nerdtree()
au WinEnter,BufWinEnter,TabEnter * call s:disable_airline_on_nerdtree()
augroup END
fu s:disable_airline_on_nerdtree() abort
let nerdtree_winnr = index(map(range(1, winnr('$')), {_,v -> getbufvar(winbufnr(v), '&ft')}), 'nerdtree') + 1
call timer_start(0, {-> nerdtree_winnr && setwinvar(nerdtree_winnr, '&stl', '%#Normal#')})
endfu
]]
--]]

View file

@ -0,0 +1,99 @@
" Converting these settings into lua isn't easy since we utilize
" <SID> which needs to be in a vim script context, making it impossible
" to replicate with simple vim.cmd call. It also contains a lot of function
" definitions taken from the coc github page without provided lua alternatives
" this makes it quite complicated to replicate this in pure lua,
" however if anyone knows how to completely reproduce everything here in lua,
" this is open to pull requests
Plug 'neoclide/coc.nvim', {'branch': 'release'}
let g:coc_global_extensions = [
\ 'coc-pyright', 'coc-json', 'coc-git', 'coc-html', 'coc-css',
\ 'coc-clangd', 'coc-cmake', 'coc-java', 'coc-sh', 'coc-toml',
\ 'coc-yaml', 'coc-omnisharp', 'coc-markdownlint', 'coc-pairs',
\ 'coc-lua'
\ ]
" Use tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()
" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current position.
" Coc only does snippet and additional edit on confirm.
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
" Or use `complete_info` if your vim support it, like:
" inoremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"
" Use `[g` and `]g` to navigate diagnostics
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('<cword>')
else
call CocAction('doHover')
endif
endfunction
" Remap for rename current word
nmap <leader>rn <Plug>(coc-rename)
" Remap for format selected region
xmap <leader>f <Plug>(coc-format-selected)
nmap <leader>f <Plug>(coc-format-selected)
augroup mygroup
autocmd!
" Setup formatexpr specified filetype(s).
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
" Update signature help on jump placeholder
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end
" Remap for do codeAction of selected region, ex: `<leader>aap` for current paragraph
xmap <leader>a <Plug>(coc-codeaction-selected)
nmap <leader>a <Plug>(coc-codeaction-selected)
" Remap for do codeAction of current line
nmap <leader>ac <Plug>(coc-codeaction)
" Fix autofix problem of current line
nmap <leader>qf <Plug>(coc-fix-current)
" Create mappings for function text object, requires document symbols feature of languageserver.
xmap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap if <Plug>(coc-funcobj-i)
omap af <Plug>(coc-funcobj-a)
" Use `:Format` to format current buffer
command! -nargs=0 Format :call CocAction('format')
" Use `:Fold` to fold current buffer
command! -nargs=? Fold :call CocAction('fold', <f-args>)
" use `:OR` for organize import of current buffer
command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
" Add status line support, for integration with other plugin, checkout `:h coc-status`
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

View file

@ -0,0 +1,9 @@
local vim = require("vim")
local cmd = vim.cmd
cmd[[Plug 'tpope/vim-commentary']]
nmap("<A-/>", ":Commentary<CR>")
vmap("<A-/>", ":Commentary<CR>")
cmd[[autocmd FileType apache setlocal commentstring=#\ %s]]

View file

@ -0,0 +1,22 @@
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'stsewd/fzf-checkout.vim'
let g:fzf_layout = { 'up': '~90%', 'window': { 'width': 0.8, 'height': 0.8, 'yoffset':0.5, 'xoffset': 0.5 } }
let $FZF_DEFAULT_OPTS = '--layout=reverse --info=inline'
" Customise the Files command to use ripgrep which respects .gitignore files
command! -bang -nargs=? -complete=dir Files
\ call fzf#run(fzf#wrap('files', fzf#vim#with_preview({ 'dir': <q-args>, 'sink': 'e', 'source': 'rg --files --hidden' }), <bang>0))
" Add an AllFiles variation that shows ignored files too
command! -bang -nargs=? -complete=dir AllFiles
\ call fzf#run(fzf#wrap('allfiles', fzf#vim#with_preview({ 'dir': <q-args>, 'sink': 'e', 'source': 'rg --files --hidden --no-ignore' }), <bang>0))
nmap <leader>f :Files<cr>
nmap <leader>F :AllFiles<cr>
nmap <leader>b :Buffers<cr>
nmap <leader>h :History<cr>
nmap <leader>r :Rg<cr>
nmap <leader>R :Rg<space>
nmap <leader>gb :GBranches<cr>

View file

@ -0,0 +1,65 @@
local vim = require("vim")
local g = vim.g
local fn = vim.fn
local cmd = vim.cmd
cmd[[
Plug 'preservim/nerdtree'
Plug 'Xuyuanp/nerdtree-git-plugin'
Plug 'tiagofumo/vim-nerdtree-syntax-highlight'
]]
-- Implement manual NERDTreeToggle, but use NERDTreeFind for openning.
-- This makes NERDTree open with the current file pre-selected
nmap("<C-n>", "g:NERDTree.IsOpen() ? ':NERDTreeClose<CR>' : @% == '' ? ':NERDTree<CR>' : ':NERDTreeFind<CR>'", {expr=true})
g.NERDTreeShowHidden = 1
g.NERDTreeMinimalUI = 1
g.NERDTreeShowLineNumbers = 0
g.NERDTreeWinSize = 25
g.NERDTreeDirArrowExpandable = ''
g.NERDTreeDirArrowCollapsible = ''
-- Disable devicons for nerdtree in TTY
if not os.getenv("DISPLAY") then
g.webdevicons_enable_nerdtree = 0
else
g.DevIconsEnableFoldersOpenClose = 1
end
-- If a directory is specified, start NERDTree
cmd[[
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in') |
\ execute 'NERDTree' argv()[0] | wincmd p | enew | execute 'cd '.argv()[0] |
\ endif
]]
-- Exit Vim if NERDTree is the only window left.
cmd[[
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() |
\ quit | endif
]]
-- If another buffer tries to replace NerdTree, put it in another window, and bring back NerdTree.
cmd[[
autocmd BufEnter * if bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 |
\ let buf=bufnr() | buffer# | execute "normal! \<C-W>w" | execute 'buffer'.buf | endif
]]
-- Use $NERDTREE_BOOKMARKS environment variable for the location of .NERDTreeBookmarks file
local bookmark_loc = os.getenv("NERDTREE_BOOKMARKS")
if bookmark_loc then
-- Check if file exists (lua doesn't have a built-in function for this)
local file_exists = os.rename(bookmark_loc, bookmark_loc) and true or false
if not file_exists then
-- While this is possible with os.execute in lua, we would need to do some hacky
-- things to capture output from os.execute and it's simpler to just use vimscript
local dir = fn.system("dirname $NERDTREE_BOOKMARKS")
fn.system({"mkdir", "-p", dir})
fn.system("touch $NERDTREE_BOOKMARKS")
end
g.NERDTreeBookmarksFile = bookmark_loc
end

View file

@ -0,0 +1,12 @@
local vim = require("vim")
local cmd = vim.cmd
cmd[[Plug 'tomasiser/vim-code-dark']]
-- Set vim-code-dark as colortheme after plugin loading was finished
cmd[[
augroup VimCodeDark
autocmd!
autocmd User PlugLoaded ++nested colorscheme codedark
augroup end
]]

View file

@ -0,0 +1,14 @@
local vim = require("vim")
local cmd = vim.cmd
local g = vim.g
cmd[[Plug 'vimwiki/vimwiki']]
local wiki_conf = {}
wiki_conf["path"] = "~/Personal/vimwiki"
wiki_conf["path_html"] = "~/Personal/vimwiki-html"
wiki_conf["html_template"] = "~/Personal/vimwiki-html/template.tpl"
wiki_conf["syntax"] = "markdown"
wiki_conf["ext"] = ".md"
g.vimwiki_list = {wiki_conf}

View file

@ -0,0 +1,56 @@
local vim = require("vim")
local cmd = vim.cmd
local fn = vim.fn
local config_dir = fn.stdpath("config") -- Config directory (usually: ~/.config/nvim)
local plugvim_plugins_dir = config_dir .. "/plugged" -- Dir with all plugins installed by Plug.vim
local plugin_files_dir = config_dir .. "/lua/plugins.d" -- Dir with plugin config files including Plug call(s)
-- Automatically download vimplug and run PlugInstall
local autoload_dir = config_dir .. "/autoload"
local plug_install_path = autoload_dir .. "/plug.vim"
local plug_download_url = "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
if fn.empty(fn.glob(plug_install_path)) > 0 then
print("Downloading vim-plug, there may be initial errors...")
fn.system({"mkdir", "-p", autoload_dir})
fn.system("curl " .. plug_download_url .. " > " .. plug_install_path)
cmd[[autocmd VimEnter * PlugInstall]]
end
-- Load a .vim or .lua file containing Plug call(s) and plugin settings
local function load_plugin_file(plugin_file)
local extension = plugin_file:match("^.+(%..+)$")
local plugin_path = plugin_files_dir .. "/" .. plugin_file
local run_cmd
if (extension == ".vim") then run_cmd = "source" else run_cmd = "luafile" end
fn.execute(run_cmd .. " " .. plugin_path)
end
-- Load a single given plugin using a Plug call
local function load_plugin(plugin)
cmd("Plug '" .. plugin .. "'")
end
-- Begin Plug.vim loading process
cmd("call plug#begin('" .. plugvim_plugins_dir .. "')")
load_plugin('airblade/vim-gitgutter')
load_plugin('dhruvasagar/vim-table-mode')
load_plugin('tmhedberg/SimpylFold')
load_plugin('wakatime/vim-wakatime')
load_plugin('mhinz/vim-startify')
load_plugin('ryanoasis/vim-devicons')
load_plugin_file("vim-code-dark.lua")
load_plugin_file("commentary.lua")
load_plugin_file("coc.vim")
load_plugin_file("vimwiki.lua")
load_plugin_file("nerdtree.lua")
load_plugin_file("airline.lua")
load_plugin_file("fzf.vim")
-- End Plug.vim loading process
cmd[[call plug#end()]]
-- Run autocmds defined in the plugin files after plugin loading has finished
cmd[[doautocmd User PlugLoaded]]

View file

@ -0,0 +1,27 @@
local vim = require("vim")
local cmd = vim.cmd
local o = vim.opt
cmd[[syntax on]] -- Turn on syntax highlighting
o.cursorline = true -- Highlight cursor line
o.laststatus = 2 -- Always show status line
o.number = true -- Show line numbers
o.relativenumber = true -- Use relative line numbers
o.showmatch = true -- Show matching bracket
o.scrolloff = 5 -- Keep 5 lines horizontal scrolloff
o.sidescrolloff = 5 -- Keep 5 chars vertical scrolloff
-- I wasn't able to find a way to set guioptions directly in lua
cmd[[
set guioptions-=m " Remove menubar
set guioptions-=T " Remove toolbar
set guioptions-=r " Remove right-hand scrollbar
set guioptions-=L " Remove left-hand scrollbar
]]
-- Use more noticable cursor line color
cmd[[highlight CursorLine guibg=#2b2b2b]]
-- Don't use true colors in TTY
o.termguicolors = os.getenv("DISPLAY") and true or false

View file

@ -0,0 +1,7 @@
-- This file is here to allow running `local vim = require("vim")`, which
-- avoids the hassle of having to ignore vim as undefined-global for lua
-- language server diagnostics. Another advantage is that it actually allows
-- us to detect the attributes of vim so we will get suggestions.
---@diagnostic disable-next-line:undefined-global
return vim