diff --git a/init.vim b/init.vim new file mode 100644 index 0000000..5c1608e --- /dev/null +++ b/init.vim @@ -0,0 +1,811 @@ +" FIRST TIME SETUP NOTES: + " Windows: + " Add the following environmental variables: + " USER + " Install git + " Neomake: + " Installation config for LaTeX: Add 'ignorechktex' to VerbEnvir in the chktex + " files. + " fyz: (Linux only! TODO: Find a windows method) + " Install fzy systemwide, or configure a custom install location below + " (search for 'g:picker_selector_executable') + " Vimtex: + " Add the following to ~/.latexmkrc, to improve the cleanup of junk + " files: + " push @generated_exts, "synctex.gz"; + " push @generated_exts, "run.xml"; + " push @generated_exts, "bbl"; + " Linux: Install zathura + " Windows: Install sumatrapdf + +" if !(has('win32') || has('win64')) + " let $BASH_ENV = "~/.bash_aliases" +" endif + +" Automatically reload vimrc on changes {{{ + augroup autosource + autocmd! + autocmd bufwritepost init.vim source $MYVIMRC + augroup END +" }}} +" vim-plug {{{ + " Install vim-plug if it isn't already installed + if has('win32') || has('win64') + if empty(glob(stdpath('config') . '\autoload\plug.vim')) + execute '!curl -fLo ' . stdpath('config') . '\autoload\plug.vim' . ' --create-dirs ' . + \ 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' + autocmd VimEnter * PlugInstall | source $MYVIMRC + endif + else + if empty(glob(stdpath('data') . '/site/autoload/plug.vim')) + silent execute '!curl -fLo ' . stdpath('data') . '/site/autoload/plug.vim' . ' --create-dirs ' . + \ 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' + autocmd VimEnter * PlugInstall | source $MYVIMRC + endif + endif + + if has('win32') || has('win64') + let g:plugged_home = stdpath('data') . '\plugged' " neovim path + else + let g:plugged_home = stdpath('data') . '/plugged' " neovim path +" let g:plugged_home = '~/.vim/plugged' " vim path + endif + + call plug#begin(g:plugged_home) + " vim-plug bundles {{{ + + " UI related + Plug 'chriskempson/base16-vim' + Plug 'itchyny/lightline.vim' + Plug 'dracula/vim' " alternate theme + Plug 'jnurmine/Zenburn' " alternate theme + Plug 'romainl/Apprentice' " alternate theme + Plug 'connorholyday/vim-snazzy' " alternate theme + Plug 'morhetz/gruvbox' " alternate theme + Plug 'sonph/onehalf', {'rtp': 'vim/'} " altenate theme + Plug 'romainl/vim-dichromatic' " colorblind theme + + " Linting + Plug 'neomake/neomake' + Plug 'fsharp/vim-fsharp', { + \ 'for': 'fsharp', + \ 'do': 'make fsautocomplete', + \} + Plug 'JuliaEditorSupport/julia-vim' + Plug 'rust-lang/rust.vim' + + " Fuzzy finding +" Plug 'jhawthorn/fzy' " Install this systemwide (or configure a manual +" location. See below) + Plug 'srstevenson/vim-picker' + + " line indentation guides + Plug 'Yggdroot/indentLine' + + " commenting code + Plug 'tpope/vim-commentary' + + " shell commands without having to leave vim (eg. rename) + Plug 'tpope/vim-eunuch' + + " open file at linenumber via : + Plug 'wsdjeg/vim-fetch' + + " Todo lists + Plug 'vuciv/vim-bujo' + + " Autocompletion {{{ + " Deep TabNine {{{ +" Plug 'zxqfl/tabnine-vim' + " }}} + + " ncm2 {{{ + Plug 'ncm2/ncm2' + Plug 'roxma/nvim-yarp' + + Plug 'ncm2/ncm2-bufword' " adds words from current buffer + Plug 'ncm2/ncm2-path' " adds paths for current buffer, working directory, and root + Plug 'ncm2/ncm2-jedi' " adds python completion + Plug 'ncm2/ncm2-pyclang' " add C/C++ completion + Plug 'ncm2/ncm2-tern', {'do': 'npm install'} " add javascript completion + Plug 'ncm2/ncm2-html-subscope' " detect javascript/css subscope from html code + Plug 'ncm2/float-preview' " improves the completion preview window + " }}} + + " VimTex + Plug 'lervag/vimtex' + + " vim-instant-markdown + Plug 'suan/vim-instant-markdown', {'for': 'markdown'} + + " Git {{{ + + " git diff in vim + Plug 'mhinz/vim-signify' + + " Git CLI integration + Plug 'tpope/vim-fugitive' + " See http://vimcasts.org/blog/2011/05/the-fugitive-series/ + + " Git commit browser + Plug 'junegunn/gv.vim' + + " }}} + + " vim-test - run perl-tests from inside the editor + Plug 'janko-m/vim-test' + + " Syntax highlighting {{{ + + " Bedre perl-highlighting + Plug 'vim-perl/vim-perl', { 'for': 'perl', 'do': 'make clean carp highlight-all-pragmas moose test-more try-tiny method-signatures' } + + " LESS (CSS) syntax highlighting + Plug 'groenewege/vim-less' + + " Mojolicious syntax highlighting + Plug 'yko/mojo.vim' + + " Haskell syntax highlighting + Plug 'neovimhaskell/haskell-vim' + + " }}} + + " Custom JIX modules + if $USER =~ "^jry$" + let g:loaded_jix_jump = 1 " don't load + " let g:loaded_jix_neomake = 1 " load + let g:loaded_jix_open_url = 1 " don't load + let g:loaded_jix_perltidy = 1 " don't load + let g:loaded_jix_skeletons = 1 " don't load + let g:loaded_jix_vimtest = 1 " don't load + + Plug '~/dev-utils/conf/vim' + end + + " }}} + call plug#end() +" }}} + +" enable plugins and indentation based on the filetype +filetype plugin indent on +" custom file extensions {{{ + au BufRead,BufNewFile *.html+itjdk.ep set filetype=html.epl + au BufRead,BufNewFile *.html+stedk.ep set filetype=html.epl + au BufRead,BufNewFile *.html+isbdk.ep set filetype=html.epl +" }}} +" escape terminal on +tnoremap + +" UI config {{{ + " Enable syntax highlighting + syntax on + syntax enable + set conceallevel=0 + + " Highlight unwanted whitespaces + function! HighlightWhitespaces() + if &ft == 'markdown' + " don't match on exactly two trailing whitespaces + match ExtraWhitespace /\S\@<=\s\%#\@ will hit indentation levels instead of always -4/+4 + set shiftround +"}}} + +" highlight tabs and trailing whitespace {{{ + set listchars=tab:>-,trail:·,nbsp:¬,extends:…,precedes:… + set list +" }}} + +" save folds in files {{{ + augroup autofolding + autocmd! + autocmd BufWinLeave,BufLeave,BufWritePost * nested if filereadable(expand('%')) | silent mkview! + autocmd BufWinEnter,BufEnter,BufReadPost * silent! loadview + augroup END +" }}} + +" Retain undo-history between sessions +if has('persistent_undo') + let myUndoDir = stdpath('data') . '/undodir' + call system('mkdir ' . myUndoDir) + let &undodir = myUndoDir + set undofile +endif + +" Todo config {{{ + let g:bujo#todo_file_path = stdpath('data') . '/bujo' + command! TODO execute "botright Todo g" + let g:bujo#window_width = 60 + + function BujoSearchCustom(pattern) + return (search(a:pattern, 'nc', line('.')) || search(a:pattern, 'nbc', line('.'))) + endfunction + + function BujoSearchCheck() + if BujoSearchCustom('\[ \]') + execute ':s/\[ \]/\[\x\]/' + elseif BujoSearchCustom('\[x\]') + execute ':s/\[x\]/\[ \]/' + else + return + endif + "move cursor back to previous position + execute 'normal!``' + " if BujoSearchCustom('\[ \]') + " execute ':s/\[ \]/\[\/\]/' + " elseif BujoSearchCustom('\[/\]') + " execute ':s/\[\/\]/\[x\]/' + " elseif BujoSearchCustom('\[x\]') + " execute ':s/\[x\]/\[ \]/' + " endif + endfunction + + augroup BujoKeybinds + autocmd! + " autocmd FileType markdown nmap BujoAddnormal + " autocmd FileType markdown imap BujoAddinsert + + " " autocmd FileType markdown nmap BujoChecknormal :nohl + " " autocmd FileType markdown imap BujoCheckinsert :nohl + autocmd FileType markdown nmap :call BujoSearchCheck() + autocmd FileType markdown imap :call BujoSearchCheck()i + " + autocmd Filetype markdown nmap i- [ ] + autocmd Filetype markdown imap - [ ] + " autocmd Filetype markdown nnoremap BujoSearchCustom('\[ \]') ? ':s/\[ \]/\[x\]' : ':s/\[x\]/\[ \]' + " autocmd Filetype markdown inoremap BujoSearchCustom('\[ \]') ? ':s/\[ \]/\[x\]' : ':s/\[x\]/\[ \]' + " autocmd Filetype markdown nnoremap BujoSearchCustom('\[ \]') ? ':s/\[ \]/\[x\]' : ':s/\[x\]/\[ \]' + " autocmd Filetype markdown inoremap BujoSearchCustom('\[ \]') ? ':s/\[ \]/\[x\]' : ':s/\[x\]/\[ \]' + augroup END +" }}} + +" Fuzzy finding +" TODO: Figure out fuzzy finding on windows +if !(has('win32') || has('win64')) + " TODO: Check if the below works, so this note can be erased + if $USER =~ "^jry$" + let g:picker_selector_executable = '/home/jry/.fzy/fzy' + " let g:picker_custom_find_executable = 'find' + " nnoremap ¬ :PickerEdit ~/jobxx/ + endif + + function! CallPickerEdit() + let l:IsInGitRepo = system('git rev-parse --is-inside-work-tree') + if l:IsInGitRepo =~ 'true' + let l:GitRepoDir = system('git rev-parse --show-toplevel') + execute 'PickerEdit ' . l:GitRepoDir + else + execute 'PickerEdit ' . glob('~/') + " TODO: Verify if this works +" if $USER =~ '^knyff$' +" " TODO: Make PickerEdit work on windows +" execute 'PickerEdit C:\User\' . $USER + " PickerEdit C:\User\knyff\ +" else +" PickerEdit ~/ +" endif + endif + endfunction + + function! CallPickerPDF() + let l:IsInGitRepo = system('git rev-parse --is-inside-work-tree') + if l:IsInGitRepo =~ 'true' + " TODO: Make this work +" let l:CurrBufNr = bufnr('%') + let l:GitRepoDir = system('git rev-parse --show-toplevel') + call picker#File('git ls-files --cached --exclude-standard --others', 'te zathura', l:GitRepoDir) +" execute 'b '.l:CurrBufNr + else +" let l:OldBufNr = bufnr('%') +" echo bufnr('%') + execute 'tabedit' + call picker#File('find ' . glob('~/') . ' -type f', 'te zathura') +" let l:CurrBufNr = bufnr('%') +" echo bufnr('%') +" execute 'tabclose' +" execute 'b '.l:CurrBufNr + endif + endfunction + + nnoremap ¬ :call CallPickerEdit() + nnoremap ¿ :call CallPickerPDF() +endif + +" NeoMake {{{ + " Note: Additional neomake configuration (for JIX) is done in + " ~/dev-utils/conf/vim/plugin/neomake.vim + + " Full config: when writing or reading a buffer, and on changes in insert and + " normal mode (after 1s; no delay when writing). + call neomake#configure#automake('nrwi', 500) + + " Autoopen error list + let g:neomake_open_list = 2 + + " Configure for C + let g:c_syntax_for_h=1 + let g:neomake_c_enabled_makers = ['gcc'] + let g:neomake_gcc_args = [ + \ '-fsyntax-only', + \ '-Wall', + \ '-Wextra', + \ '-Wfloat-equal', + \ '-std=c99', + \ '-I.', + \ '-fopenmp' + \ ] + + " Configure for C++ + let g:cpp_syntax_for_h=1 + let g:neomake_cpp_enabled_makers = ['clang'] ", 'clangtidy', 'clangcheck'] - clangtidy and/or clangcheck requires a compilation database + let g:neomake_clang_args = [ + \ '-fsyntax-only', + \ '-Wall', + \ '-Wextra', + \ '-Wfloat-equal', + \ '-std=c++17', + \ '-I.', + \ '-fopenmp' + \ ] + + " Configure for Rust + let g:neomake_rust_enabled_makers = ['rustc', 'cargo'] + + " Configure for Haskell + let g:neomake_haskell_enabled_makers = ['hlint'] + " let g:neomake_haskell_enabled_makers = ['hlint', 'ghcmod', 'hdevtools', 'liquid'] + + " " Configure HTML at JI + " if $USER =~ '^jry$' + " let g:neomake_html_enabled_makers = [] " disable because at work different html files are stiched together + " endif + + " " Configure javascript at JI + " if $USER =~ "^jry$" + " let g:neomake_eslint_args = [ + " \ '--rulesdir=/home/jry/jobxx/t/lib/ESLint' + " \ ] + " endif + + " let g:neomake_perl_perlcritic_postprocess = { + " \ entry -> entry.text =~# 'Private subroutine/method used (Use published APIs)' + " \ ? extend(entry, {'valid': -1}) + " \ : entry} + + " \ || (expand('%:t') =~# 'Test.pm') + + " Configure for latex + let g:neomake_tex_enabled_makers = ['chktex'] + augroup NeomakeTex + autocmd! + autocmd BufReadPre *.sty let b:neomake_tex_enabled_makers = ['chktex'] + autocmd BufEnter *.sty let b:neomake_tex_enabled_makers = ['chktex'] + augroup END + + function! Configure_perlcritic_for_test(fname) + let is_test = a:fname =~ 't/lib/' + for arg in ["--exclude Modules::RequireExplicitInclusion", "--exclude Subroutines::ProtectPrivateSubs", "--exclude Subroutines::ProhibitUnusedPrivateSubroutines", "--exclude Variables::ProtectPrivateVars"] + " Clean up perlcritic arguments to prevent duplicates + call Find_index_and_remove(g:neomake_perl_perlcritic_args, arg) + if is_test + " Add perlcritic argument + call add(g:neomake_perl_perlcritic_args, arg) + endif + endfor + endfunction + + " augroup perlcritic_config + " au! + " au FileType perl call Configure_perlcritic_for_test(expand(":p")) + " au BufEnter * if &ft == 'perl' | call Configure_perlcritic_for_test(expand("%:p")) | endif + " augroup END + + " Goto next linting error + nnoremap ]d :call LocationNext() + function! LocationNext() + try + lnext + catch + try | lfirst | catch | endtry + endtry + endfunction + + " Goto previous linting error + nnoremap [d :lprev +" }}} + +" add a proper delete line command {{{ + nnoremap x "_dl + nnoremap "_dd + nnoremap + nnoremap +" }}} + +" haskell-vim {{{ + " let g:haskell_classic_highlighting = 1 + " let g:haskell_indent_disable = 1 + let g:haskell_indent_if = 4 " 3 + let g:haskell_indent_case = 4 " 2 + let g:haskell_indent_let = 4 " 4 + let g:haskell_indent_where = 8 " 6 + let g:haskell_indent_before_where = 4 " 2 + let g:haskell_indent_after_bare_where = 4 " 2 + let g:haskell_indent_do = 4 " 3 + let g:haskell_indent_in = 4 " 1 + let g:haskell_indent_guard = 4 " 2 +" }}} + +" TODO: +" disable copying when pasting in visual mode {{{ + "vnoremap p

:let @"=@0 + "vnoremap p :put:let @"=@0 + "vnoremap P

+" }}} + +" vim-perl configuration {{{ + " highlight advanced perl vars inside strings + let perl_extended_vars = 1 + + " do highlighting on POD comments + let perl_include_pod = 1 + + " increase number of lines used when syntax highlighting + let perl_sync_dist = 1000 + + autocmd BufEnter * :syntax sync minlines=300 + + " allow subroutine signatures + let perl_sub_signatures = 1 +" }}} + +" Configure Signify {{{ + let g:signify_vcs_list = [ 'git' ] + let g:signify_realtime = 1 + + " highlight lines in Sy and vimdiff etc. + highlight DiffAdd cterm=bold ctermbg=none ctermfg=119 + highlight DiffDelete cterm=bold ctermbg=none ctermfg=167 + highlight DiffChange cterm=bold ctermbg=none ctermfg=227 + + " highlight signs in Sy + highlight SignifySignAdd cterm=bold ctermbg=none ctermfg=119 + highlight SignifySignDelete cterm=bold ctermbg=none ctermfg=167 + highlight SignifySignChange cterm=bold ctermbg=none ctermfg=227 + + " highlight signs column + highlight SignColumn ctermbg=none +" }}} + +" Configure Vim-Commentary +autocmd FileType matlab setlocal commentstring=%\ %s +autocmd FileType julia setlocal commentstring=#\ %s + +" NCM2 +augroup NCM2 + autocmd! + " Enable ncm2 for all buffers + autocmd BufEnter * call ncm2#enable_for_buffer() + " :help Ncm2PopupOpen for more information + set completeopt=noinsert,menuone,noselect + " When the key is pressed while the popup menu is visible, it only + " hides the menu. Use this mapping to close the menu and also start a new line. + inoremap (pumvisible() ? "\\" : "\") + " Suppress the annoying 'match x of y', 'The only match' and 'Pattern not + " found' messages + set shortmess+=c + " Use to select the popup menu: + inoremap pumvisible() ? "\" : "\" + inoremap pumvisible() ? "\" : "\" + + " Configure float-preview + let g:float_preview#docked = 1 + + " LaTeX + autocmd Filetype tex call ncm2#register_source({ + \ 'name': 'vimtex', + \ 'priority': 8, + \ 'scope': ['tex'], + \ 'mark': 'tex', + \ 'word_pattern': '\w+', + \ 'complete_pattern': g:vimtex#re#ncm2, + \ 'on_complete': ['ncm2#on_complete#omni', 'vimtex#complete#omnifunc'], + \ }) + + " C/C++ + let g:ncm2_pyclang#library_path = 'usr/lib' + " goto declaration (TODO: is the ¬ on purpose???) + autocmd FileType c,cpp nnoremap gd :call ncm2_pyclang#goto_declaration()¬ +augroup END + +" VimTex {{ + let g:tex_flavor = 'latex' + let g:vimtex_syntax_conceal_default = 0 + let g:vimtex_fold_manual = 1 + let g:vimtex_compiler_enabled = 1 " continuous compilation + if has('nvim') + let g:vimtex_compiler_progname = 'nvr' " nvr = neovim remote + endif + if has('win32') || has('win64') + let g:vimtex_view_general_viewer = 'SumatraPDF' + let g:vimtex_view_general_options='-reuse-instance -forward-search @tex @line @pdf' + let g:vimtex_view_general_options_latexmk='-reuse-instance' + else + let g:vimtex_view_general_viewer = 'zathura' + let g:vimtex_view_method = 'zathura' + endif + + " Cleanup junk files automatically + augroup MyVimtex + autocmd! + autocmd User VimtexEventQuit call vimtex#compiler#clean(0) + augroup END + + let g:vimtex_syntax_packages = { + \ 'biblatex' : {'load' : 2}, + \ 'tikz' : {'load' : 2}, + \ 'amsmath' : {'load' : 2}, + \ 'listings' : {'load' : 2}, + \ 'hyperref' : {'load' : 2}, + \ 'cleveref' : {'load' : 2}, + \ 'booktabs' : {'load' : 2} + \ } + + " Add 'gather' as a math zone + " au FileType tex :call TexNewMathZone("M","gather",1) + " au FileType tex :call TexNewMathZone("M","gather*",1) + " au FileType tex :call TexNewMathZone("N","align",1) + " au FileType tex :call TexNewMathZone("N","align*",1) +" }} + +" vim-instant-markdown {{ + au FileType markdown setlocal conceallevel=0 + "Uncomment to override defaults: + let g:instant_markdown_slow = 1 + let g:instant_markdown_autostart = 0 + au FileType markdown nnoremap ll :InstantMarkdownPreview + " stop it with :InstantMarkdownStop + "let g:instant_markdown_open_to_the_world = 1 + "let g:instant_markdown_allow_unsafe_content = 1 + "let g:instant_markdown_allow_external_content = 0 + "let g:instant_markdown_logfile = '/tmp/instant_markdown.log' + let g:instant_markdown_mathjax = 1 + let g:instant_markdown_browser = "firefox --new-window" + "let g:instant_markdown_port = 8888 + "let g:instant_markdown_autoscroll = 0 + "let g:instant_markdown_python = 1 +" }} + +" Add spell checking to LaTeX documents {{ + augroup LaTeXSpelling + au! + au FileType tex setlocal spell spelllang=en_gb + " As a reminder: + " ]s [s jumps between spelling mistakes + " zg adds the word to the dictionary + " z= shows the suggestions + " in insert mode Ctrl-X s shows the suggestions + + " We only want the 10 best suggestions - not over 50 + au FileType tex setlocal spellsuggest+=10 + + " Add a file for custom suggestions + au FileType tex setlocal spellsuggest+=file:~/.config/nvim/spell/suggestions + + " Add the default spelling file + au FileType tex setlocal spellfile+=~/.config/nvim/spell/en.utf-8.add + " zg or 1zg adds a word to the dictionary + + " Add a file specific wordlist for one-off words that shouldn't be part of + " the dictionary + au FileType tex setlocal spellfile+=oneoff.utf-8.add + " 2zg adds a word to the dictionary + + " Add a LaTeX specific wordlist for e.g. chktex + au FileType tex setlocal spellfile+=~/.config/nvim/spell/LaTeX.utf-8.add + " 3zg adds a word to the dictionary + augroup END +" }} + +" Change window directory to the same as the open buffer +command! LCDCurrDir lcd %:p:h + +function! FindAll() + call inputsave() + let p = input('Enter pattern:') + call inputrestore() + execute 'vimgrep "'.p.'" % |copen' +endfunction + +nnoremap :call FindAll() + +au FileType perl setlocal keywordprg=perldoc\ -T\ -f + +function! LoadPerlModule() + set iskeyword+=: + let currentIdent = expand('') + set iskeyword-=: + e `=system("perlopen -f " . currentIdent)` +endfunction + +nnoremap pm :call LoadPerlModule() + +nnoremap "_dh + +" Enable vim-test with our perl test naming scheme +let g:test#perl#prove#file_pattern = 'Test.pm$' + +" autoreload lightline config +command! LightlineReload call LightlineReload() + +function! LightlineReload() + call lightline#init() + call lightline#colorscheme() + call lightline#update() +endfunction + +:call LightlineReload() + +" Gdiff method: +" :Gdiff +" dp " diffput: add change from this window to the other window (below cursor) +" do " diffget: add change from the other window to this window (below cursor) + +" Center cursor when searching +nnoremap n nzz +nnoremap N Nzz +nnoremap * *zz +nnoremap # #zz +nnoremap g* g*zz +nnoremap g# g#zz + function! ZZWrap(...) + exec ':set so=999' + exec join(a:000, ' ') + exec ':set so=0' + endfunction +command! -nargs=* ZZ call ZZWrap() + +function! InsertSnip(snip_name) + " Find the template + if a:snip_name =~ '^JIX/' + let l:fname = stdpath('config') . '/snippets/' . a:snip_name . '.pm' + else + let l:fname = stdpath('config') . '/snippets/' . a:snip_name . '.snip' + endif + + execute "r ". l:fname + + " Autoindent + let l:lines = execute("!wc -l " . expand(l:fname)) + let l:lines = matchstr(l:lines, '\d\+') + execute "norm!" "=" . (l:lines-1) . "j" + + " Goto the tag + if execute("!cat " . expand(l:fname)) =~ '' + execute "normal! gg/\\"_8x" + endif +endfunction + +command! -nargs=1 R call InsertSnip()