finally, after 3 months of intense Vimscript programming and Vim-fu learning, I've finished my Neovim config

This commit is contained in:
Dmytro Meleshko 2019-04-21 14:42:15 +03:00
parent 1c4d4d52d5
commit 4088de0f21
27 changed files with 1171 additions and 25 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/custom
/cache
*.pyc

View file

@ -1,17 +0,0 @@
#!/usr/bin/env bash
for zsh_file_name in zshrc; do
zsh_file="$HOME/.$zsh_file_name"
if [[ -f "$zsh_file" ]]; then
zsh_file_backup="$zsh_file.dmitmel-dotfiles-backup"
echo "Backing up $zsh_file to $zsh_file_backup"
mv -vi "$zsh_file" "$zsh_file_backup"
fi
cat > "$zsh_file" <<EOF
#!/usr/bin/env zsh
source "$PWD/$zsh_file_name"
EOF
done

29
install.zsh Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env zsh
install_dotfile() {
local dest="$1"
if [[ -f "$dest" ]]; then
mv -vi "$dest" "$dest.dmitmel-dotfiles-backup"
fi
mkdir -p "${dest:h}"
cat > "$dest"
}
# ZSH
for zsh_file_name in zshrc; do
install_dotfile "$HOME/.$zsh_file_name" <<EOF
#!/usr/bin/env zsh
source "$PWD/$zsh_file_name"
EOF
done
unset zsh_file_name
# Neovim
install_dotfile ~/.config/nvim/init.vim <<EOF
source $PWD/nvim/init.vim
EOF
install_dotfile ~/.config/nvim/ginit.vim <<EOF
source $PWD/nvim/ginit.vim
EOF

View file

@ -7,11 +7,10 @@ if [[ -z "$USER" && -n "$USERNAME" ]]; then
export USER="$USERNAME"
fi
if [[ -n "$SSH_CONNECTION" ]]; then
export EDITOR="rmate"
else
export EDITOR="code --wait"
fi
# find editor
export EDITOR="nvim"
export VISUAL="$EDITOR"
alias edit="$EDITOR"
alias e="$EDITOR"
export CLICOLOR="1"

8
nvim/ginit.vim Normal file
View file

@ -0,0 +1,8 @@
" nvim-qt settings {{{
if exists('g:GuiLoaded')
GuiFont Ubuntu Mono derivative Powerline:h14
GuiTabline 0
endif
" }}}

9
nvim/init.vim Normal file
View file

@ -0,0 +1,9 @@
let s:my_config_dir = expand('<sfile>:p:h')
for s:name in ['plugins', 'editing', 'interface', 'colorscheme', 'files', 'completion', 'terminal', 'git']
execute 'source' fnameescape(s:my_config_dir.'/lib/'.s:name.'.vim')
endfor
for s:path in globpath(s:my_config_dir.'/lib/languages', '*', 0, 1)
execute 'source' fnameescape(s:path)
endfor

354
nvim/lib/colorscheme.vim Normal file
View file

@ -0,0 +1,354 @@
set termguicolors
" modified version of base16-vim (https://github.com/chriskempson/base16-vim)
" by Chris Kempson (http://chriskempson.com)
" Color definitions {{{
" Eighties scheme by Chris Kempson (http://chriskempson.com)
let s:colors = [
\ {'gui': '#2d2d2d', 'cterm': '00'},
\ {'gui': '#393939', 'cterm': '10'},
\ {'gui': '#515151', 'cterm': '11'},
\ {'gui': '#747369', 'cterm': '08'},
\ {'gui': '#a09f93', 'cterm': '12'},
\ {'gui': '#d3d0c8', 'cterm': '07'},
\ {'gui': '#e8e6df', 'cterm': '13'},
\ {'gui': '#f2f0ec', 'cterm': '15'},
\ {'gui': '#f2777a', 'cterm': '01'},
\ {'gui': '#f99157', 'cterm': '09'},
\ {'gui': '#ffcc66', 'cterm': '03'},
\ {'gui': '#99cc99', 'cterm': '02'},
\ {'gui': '#66cccc', 'cterm': '06'},
\ {'gui': '#6699cc', 'cterm': '04'},
\ {'gui': '#cc99cc', 'cterm': '05'},
\ {'gui': '#d27b53', 'cterm': '14'}
\ ]
" }}}
" Neovim terminal colors {{{
let s:i = 0
for s:color in [0x0, 0x8, 0xB, 0xA, 0xD, 0xE, 0xC, 0x5, 0x3, 0x8, 0xB, 0xA, 0xD, 0xE, 0xC, 0x7]
let g:terminal_color_{s:i} = s:colors[s:color].gui
let s:i += 1
endfor
unlet s:i
let g:terminal_color_background = g:terminal_color_0
let g:terminal_color_foreground = g:terminal_color_5
" }}}
" Theme setup {{{
hi clear
syntax reset
let g:colors_name = "base16-eighties"
" }}}
" Highlighting function {{{
function s:is_number(value)
return type(a:value) == v:t_number
endfunction
function s:hi(group, fg, bg, attr, guisp)
let l:args = ''
if a:fg isnot ''
let l:fg = s:is_number(a:fg) ? s:colors[a:fg] : {'gui': a:fg, 'cterm': a:fg}
let l:args .= ' guifg=' . l:fg.gui . ' ctermfg=' . l:fg.cterm
endif
if a:bg isnot ''
let l:bg = s:is_number(a:bg) ? s:colors[a:bg] : {'gui': a:bg, 'cterm': a:bg}
let l:args .= ' guibg=' . l:bg.gui . ' ctermbg=' . l:bg.cterm
endif
if a:attr isnot ''
let l:args .= ' gui=' . a:attr . ' cterm=' . a:attr
endif
if a:guisp isnot ''
let l:guisp = s:is_number(a:guisp) ? s:colors[a:guisp].gui : a:guisp
let l:args .= ' guisp=' . l:guisp
endif
exec 'hi' a:group l:args
endfunction
" }}}
" General syntax highlighting {{{
call s:hi('Normal', 0x5, 0x0, '', '')
call s:hi('Italic', 0xE, '', 'italic', '')
call s:hi('Bold', 0xA, '', 'bold', '')
call s:hi('Underlined', 0x8, '', 'underline', '')
call s:hi('Title', 0xD, '', '', '')
hi! link Directory Title
call s:hi('Conceal', 0xC, 'NONE', '', '')
call s:hi('NonText', 0x3, '', '', '')
hi! link SpecialKey NonText
call s:hi('MatchParen', 'fg', 0x3, '', '')
call s:hi('Keyword', 0xE, '', '', '')
hi! link Statement Keyword
hi! link Repeat Keyword
hi! link StorageClass Keyword
hi! link Exception Keyword
hi! link Structure Keyword
hi! link Conditional Keyword
call s:hi('Constant', 0x9, '', '', '')
call s:hi('Boolean', 0x9, '', '', '')
call s:hi('Float', 0x9, '', '', '')
call s:hi('Number', 0x9, '', '', '')
call s:hi('String', 0xB, '', '', '')
hi! link Character String
hi! link Quote String
call s:hi('Comment', 0x3, '', '', '')
hi! link SpecialComment Comment
call s:hi('Todo', 'bg', 0xA, 'bold', '')
call s:hi('Function', 0xD, '', '', '')
call s:hi('Identifier', 0x8, '', '', '')
hi! link Variable Identifier
call s:hi('Include', 0xF, '', '', '')
call s:hi('PreProc', 0xA, '', '', '')
call s:hi('Label', 0xA, '', '', '')
hi! link Operator NONE
hi! link Delimiter NONE
call s:hi('Special', 0xC, '', '', '')
call s:hi('Tag', 0xA, '', '', '')
call s:hi('Type', 0xA, '', 'none', '')
hi! link Typedef Type
" }}}
" User interface {{{
call s:hi('Error', 'bg', 0x8, '', '')
call s:hi('ErrorMsg', 0x8, 'NONE', '', '')
call s:hi('WarningMsg', 0x9, 'NONE', '', '')
call s:hi('TooLong', 0x8, '', '', '')
call s:hi('Debug', 0x8, '', '', '')
hi! link ALEError Error
hi! link ALEErrorSign ALEError
hi! link ALEStyleErrorSign ALEErrorSign
hi! link ALEVirtualTextError ALEError
hi! link ALEVirtualTextStyleError ALEVirtualTextError
hi! link ALEWarning Todo
hi! link ALEWarningSign ALEWarning
hi! link ALEStyleWarningSign ALEWarningSign
hi! link ALEVirtualTextWarning ALEWarning
hi! link ALEVirtualTextStyleWarning ALEVirtualTextWarning
hi! link ALEInfo ALEWarning
hi! link ALEInfoSign ALEWarningSign
hi! link ALEVirtualTextInfo ALEVirtualTextWarning
hi! link ALESignColumnWithErrors ALEError
hi! link CocErrorSign ALEErrorSign
hi! link CocWarningSign ALEWarningSign
hi! link CocInfoSign ALEInfoSign
hi! link CocHintSign ALEInfoSign
call s:hi('FoldColumn', 0xC, 0x1, '', '')
call s:hi('Folded', 0x3, 0x1, '', '')
call s:hi('IncSearch', 0x1, 0x9, 'none', '')
call s:hi('Search', 0x1, 0xA, '', '')
hi! link Substitute Search
call s:hi('ModeMsg', 0xB, '', '', '')
call s:hi('Question', 0xB, '', '', '')
hi! link MoreMsg Question
call s:hi('Visual', '', 0x2, '', '')
call s:hi('WildMenu', 0x1, 'fg', '', '')
call s:hi('CursorLine', '', 0x1, '', '')
hi! link CursorColumn CursorLine
call s:hi('ColorColumn', '', 0x1, '', '')
call s:hi('LineNr', 0x3, 0x1, '', '')
call s:hi('CursorLineNr', 0x4, 0x1, '', '')
call s:hi('QuickFixLine', '', 0x2, '', '')
call s:hi('SignColumn', 0x3, 0x1, '', '')
call s:hi('StatusLine', 0x4, 0x1, 'none', '')
call s:hi('StatusLineNC', 0x3, 0x1, '', '')
call s:hi('VertSplit', 0x2, 0x2, '', '')
call s:hi('TabLine', 0x3, 0x1, '', '')
call s:hi('TabLineFill', 0x3, 0x1, '', '')
call s:hi('TabLineSel', 0xB, 0x1, '', '')
call s:hi('PMenu', 'fg', 0x1, '', '')
call s:hi('PMenuSel', 0x1, 'fg', '', '')
" }}}
" Diff {{{
" diff mode
call s:hi('DiffAdd', 0xB, 0x1, '', '')
call s:hi('DiffDelete', 0x8, 0x1, '', '')
call s:hi('DiffText', 0xE, 0x1, '', '')
call s:hi('DiffChange', 0x3, 0x1, '', '')
" diff file
call s:hi('diffAdded', 0xB, '', '', '')
call s:hi('diffRemoved', 0x8, '', '', '')
call s:hi('diffChanged', 0xE, '', '', '')
hi! link diffNewFile diffAdded
hi! link diffFile diffRemoved
hi! link diffIndexLine Bold
hi! link diffLine Title
hi! link diffSubname Include
" }}}
" XML {{{
call s:hi('xmlTagName', 0x8, '', '', '')
call s:hi('xmlAttrib', 0x9, '', '', '')
hi! link xmlTag NONE
hi! link xmlEndTag xmlTag
" }}}
" Git {{{
hi! link gitCommitOverflow TooLong
hi! link gitCommitSummary String
hi! link gitCommitComment Comment
hi! link gitcommitUntracked Comment
hi! link gitcommitDiscarded Comment
hi! link gitcommitSelected Comment
hi! link gitcommitHeader Keyword
call s:hi('gitcommitSelectedType', 0xD, '', '', '')
call s:hi('gitcommitUnmergedType', 0xD, '', '', '')
call s:hi('gitcommitDiscardedType', 0xD, '', '', '')
hi! link gitcommitBranch Function
call s:hi('gitcommitUntrackedFile', 0xA, '', 'bold', '')
call s:hi('gitcommitUnmergedFile', 0x8, '', 'bold', '')
call s:hi('gitcommitDiscardedFile', 0x8, '', 'bold', '')
call s:hi('gitcommitSelectedFile', 0xB, '', 'bold', '')
hi! link GitGutterAdd DiffAdd
hi! link GitGutterDelete DiffDelete
hi! link GitGutterChange DiffText
hi! link GitGutterChangeDelete GitGutterDelete
hi! link SignifySignAdd DiffAdd
hi! link SignifySignChange DiffText
hi! link SignifySignDelete DiffDelete
" }}}
" Vim scripts {{{
hi! link vimUserFunc vimFuncName
hi! link vimBracket vimMapModKey
hi! link vimFunction vimFuncName
hi! link vimParenSep Delimiter
hi! link vimSep Delimiter
hi! link vimVar Variable
hi! link vimFuncVar Variable
" }}}
" C {{{
hi! link cOperator Special
" }}}
" C# {{{
call s:hi('csClass', 0xA, '', '', '')
call s:hi('csAttribute', 0xA, '', '', '')
call s:hi('csModifier', 0xE, '', '', '')
hi! link csType Type
call s:hi('csUnspecifiedStatement', 0xD, '', '', '')
call s:hi('csContextualStatement', 0xE, '', '', '')
call s:hi('csNewDecleration', 0x8, '', '', '')
" }}}
" Rust {{{
hi! link rustEnumVariant rustType
hi! link rustSelf Variable
hi! link rustSigil rustOperator
hi! link rustMacroVariable Variable
" }}}
" HTML {{{
hi! link htmlBold Bold
hi! link htmlItalic Italic
hi! link htmlTag xmlTag
hi! link htmlTagName xmlTagName
hi! link htmlSpecialTagName xmlTagName
hi! link htmlEndTag xmlEndTag
hi! link htmlArg xmlAttrib
" }}}
" CSS {{{
hi! link cssBraces Delimiter
hi! link cssTagName htmlTagName
hi! link cssPseudoClassId Special
hi! link cssClassName Type
hi! link cssClassNameDot cssClassName
hi! link cssAtRule Keyword
hi! link cssProp Identifier
hi! link cssVendor Special
hi! link cssNoise Delimiter
hi! link cssAttr String
hi! link cssAttrComma Delimiter
hi! link cssAttrRegion cssAttr
" }}}
" JavaScript {{{
hi! link javaScriptBraces Delimiter
hi! link jsOperator Operator
hi! link jsThis Variable
hi! link jsSuper jsThis
hi! link jsClassDefinition Type
hi! link jsFunction Keyword
hi! link jsArrowFunction jsFunction
hi! link jsFuncName jsFuncCall
hi! link jsClassFuncName jsFuncCall
hi! link jsClassMethodType jsFunction
hi! link jsRegexpString Special
hi! link jsGlobalObjects Type
hi! link jsGlobalNodeObjects Type
hi! link jsExceptions Type
hi! link jsBuiltins jsFuncName
hi! link jsNull Constant
hi! link jsUndefined Constant
hi! link jsOperatorKeyword Keyword
hi! link jsObjectKey Identifier
" }}}
" Markdown {{{
hi! link mkdHeading Title
" }}}
" Mail {{{
call s:hi('mailQuoted1', 0x8, '', '', '')
call s:hi('mailQuoted2', 0x9, '', '', '')
call s:hi('mailQuoted3', 0xA, '', '', '')
call s:hi('mailQuoted4', 0xB, '', '', '')
call s:hi('mailQuoted5', 0xD, '', '', '')
call s:hi('mailQuoted6', 0xE, '', '', '')
hi! link mailURL Underlined
hi! link mailEmail Underlined
" }}}
" Python {{{
hi! link pythonBuiltinType Type
hi! link pythonBuiltinObj pythonFunction
hi! link pythonClassVar Variable
" }}}
" Ruby {{{
hi! link rubyPseudoVariable Variable
hi! link rubyClassName Type
hi! link rubyAttribute rubyFunction
hi! link rubyConstant Constant
call s:hi('rubyInterpolationDelimiter', 0xF, '', '', '')
hi! link rubySymbol String
hi! link rubyStringDelimiter rubyString
hi! link rubyRegexp Special
hi! link rubyRegexpDelimiter rubyRegexp
" }}}
" Lua {{{
hi! link luaFuncCall Function
hi! link luaBraces Delimiter
" }}}
" Zsh {{{
hi! link zshFunction Function
hi! link zshVariable Variable
" }}}
" Spelling {{{
call s:hi('SpellBad', '', '', 'undercurl', 0x8)
call s:hi('SpellLocal', '', '', 'undercurl', 0xC)
call s:hi('SpellCap', '', '', 'undercurl', 0xD)
call s:hi('SpellRare', '', '', 'undercurl', 0xE)
" }}}

72
nvim/lib/completion.vim Normal file
View file

@ -0,0 +1,72 @@
" pop-up (completion) menu mappings {{{
imap <silent><expr> <CR> pumvisible() ? "\<C-y>" : "\<Plug>delimitMateCR"
imap <silent><expr> <Esc> pumvisible() ? "\<C-e>" : "\<Esc>"
imap <silent><expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
imap <silent><expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
" }}}
" coc.nvim {{{
" list of filetypes (that are added in language-specific scripts) for which
" coc mappings are enabled
let g:coc_filetypes = []
function IsCocEnabled()
return index(g:coc_filetypes, &filetype) >= 0
endfunction
augroup vimrc-coc
autocmd!
autocmd FileType * if IsCocEnabled()
\|let &l:formatexpr = "CocAction('formatSelected')"
\|let &l:keywordprg = ":call CocAction('doHover')"
\|endif
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end
" mappings {{{
let g:coc_snippet_next = '<Tab>'
let g:coc_snippet_prev = '<S-Tab>'
inoremap <silent><expr> <C-Space> coc#refresh()
nmap <silent> [c <Plug>(coc-diagnostic-prev)
nmap <silent> ]c <Plug>(coc-diagnostic-next)
nmap <silent> <leader>jd <Plug>(coc-definition)
nmap <silent> <leader>jt <Plug>(coc-type-definition)
nmap <silent> <leader>ji <Plug>(coc-implementation)
nmap <silent> <leader>jr <Plug>(coc-references)
nmap <silent> <F2> <Plug>(coc-rename)
nmap <silent> <A-CR> <Plug>(coc-codeaction)
vmap <silent> <A-CR> <Plug>(coc-codeaction-selected)
" nmap <silent> <leader>qf <Plug>(coc-fix-current)
nnoremap <silent> <space>l :CocList<CR>
nnoremap <silent> <space>d :CocList --auto-preview diagnostics<CR>
nnoremap <silent> <space>c :CocList commands<CR>
nnoremap <silent> <space>o :CocList --auto-preview outline<CR>
nnoremap <silent> <space>s :CocList --interactive symbols<CR>
nnoremap <silent> <space>h :CocPrev<CR>
nnoremap <silent> <space>k :CocPrev<CR>
nnoremap <silent> <space>l :CocNext<CR>
nnoremap <silent> <space>j :CocNext<CR>
nnoremap <silent> <space>p :CocListResume<CR>
" }}}
" CocFormat {{{
function s:CocFormat(range, line1, line2) abort
if a:range == 0
call CocAction('format')
else
call cursor(a:line1, 1)
normal! V
call cursor(a:line2, 1)
call CocAction('formatSelected', 'V')
endif
endfunction
command! -nargs=0 -range -bar CocFormat call s:CocFormat(<range>, <line1>, <line2>)
" }}}
call coc#add_extension('coc-snippets')
call coc#config('diagnostic', { 'virtualText': v:true, 'enableMessage': 'jump' })
" }}}

160
nvim/lib/editing.vim Normal file
View file

@ -0,0 +1,160 @@
" <leader> is comma
let mapleader = ','
" allow moving cursor just after the last chraracter of the line
set virtualedit=onemore
set foldmethod=marker
" Indentination {{{
function SetIndent(expandtab, shiftwidth)
let &l:expandtab = a:expandtab
let &l:shiftwidth = str2nr(a:shiftwidth)
let &l:tabstop = &shiftwidth
let &l:softtabstop = &shiftwidth
endfunction
command -nargs=1 Indent call SetIndent(1, <q-args>)
command -nargs=1 IndentTabs call SetIndent(0, <q-args>)
" use 2 spaces for indentination
set expandtab shiftwidth=2 tabstop=2 softtabstop=2
" round indents to multiple of shiftwidth when using shift (< and >) commands
set shiftround
let g:indentLine_char = "\u2502"
let g:indentLine_first_char = g:indentLine_char
let g:indentLine_showFirstIndentLevel = 1
let g:indentLine_fileTypeExclude = ['text', 'help', 'tutor']
" }}}
" Invisible characters {{{
set list
let &listchars = "tab:\u2192 ,extends:>,precedes:<,eol:\u00ac,trail:\u00b7"
let &showbreak = '>'
" }}}
" Cursor and Scrolling {{{
set number
set relativenumber
set cursorline
" remember cursor position
augroup vimrc-editing-remember-cursor-position
autocmd!
autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exec "normal! g`\"" | endif
augroup END
" }}}
" Wrapping {{{
set nowrap
set colorcolumn=80,100,120
" }}}
" Mappings {{{
" arguably one of the most useful mappings
nnoremap <silent><expr> <CR> empty(&buftype) ? ":w\<CR>" : "\<CR>"
" stay in the Visual mode when using shift commands
xnoremap < <gv
xnoremap > >gv
" 2 mappings for quick prototyping: duplicate this line and comment it out
nmap <silent> <leader>] m'yygccp`'j
nmap <silent> <leader>[ m'yygccP`'k
command! -nargs=+ -complete=command PutOutput execute 'put =execute(' . escape(string(<q-args>), '|"') . ')'
" Clipboard {{{
" ,c is easier to type than "+ because it doesn't require pressing Shift
noremap <leader>c "+
" these 3 mappings are equivalent to Ctrl+C, Ctrl+V, and Ctrl+X in GUI
" editors (hence the names)
" noremap <leader>cc "+y
" noremap <leader>cv "+gP
" noremap <leader>cV "+gp
" noremap <leader>cx "+d
" }}}
" }}}
" Search {{{
" ignore case if the pattern doesn't contain uppercase characters (use '\C'
" anywhere in pattern to override these two settings)
set ignorecase smartcase
nnoremap \ :nohlsearch<CR>
let g:indexed_search_center = 1
" search inside a visual selection
vnoremap / <Esc>/\%><C-R>=line("'<")-1<CR>l\%<<C-R>=line("'>")+1<CR>l
vnoremap ? <Esc>?\%><C-R>=line("'<")-1<CR>l\%<<C-R>=line("'>")+1<CR>l
" * and # in the Visual mode will search the selected text
function! s:VisualStarSearch(search_cmd)
let l:tmp = @"
normal! gvy
let @/ = '\V' . substitute(escape(@", a:search_cmd . '\'), '\n', '\\n', 'g')
let @" = l:tmp
endfunction
" HACK: my mappings are added on VimEnter to override mappings from the
" vim-indexed-search plugin
augroup vimrc-editing-visual-star-search
autocmd!
autocmd VimEnter *
\ xmap * :<C-u>call <SID>VisualStarSearch('/')<CR>n
\|xmap # :<C-u>call <SID>VisualStarSearch('?')<CR>N
augroup END
" }}}
" Replace {{{
" show the effects of the :substitute command incrementally, as you type
" (works similar to 'incsearch')
set inccommand=nosplit
" quick insertion of the substitution command
nnoremap gs :%s///g<Left><Left><Left>
xnoremap gs :s///g<Left><Left><Left>
nnoremap gss :%s///g<Left><Left>
xnoremap gss :s///g<Left><Left>
" }}}
" Formatting {{{
" don't insert a comment after hitting 'o' or 'O' in the Normal mode
augroup vimrc-editing-formatting
autocmd!
autocmd FileType * set formatoptions-=o
augroup END
" }}}
" plugins {{{
let g:delimitMate_expand_space = 1
let g:delimitMate_expand_cr = 1
let g:pencil#wrapModeDefault = 'soft'
let g:pencil#conceallevel = 0
let g:pencil#cursorwrap = 0
xmap ga <Plug>(LiveEasyAlign)
nmap ga <Plug>(LiveEasyAlign)
" }}}

136
nvim/lib/files.vim Normal file
View file

@ -0,0 +1,136 @@
" order of EOL detection
set fileformats=unix,dos,mac
set wildignore+=.git,.svn,.hg,.DS_Store,*~
" ripgrep (rg) {{{
if executable('rg')
let s:rg_cmd = "rg --hidden --follow"
let s:rg_ignore = split(&wildignore, ',') + [
\ 'node_modules', 'target', 'build', 'dist', '.stack-work'
\ ]
let s:rg_cmd .= " --glob '!{'" . shellescape(join(s:rg_ignore, ',')) . "'}'"
let &grepprg = s:rg_cmd . ' --vimgrep'
let $FZF_DEFAULT_COMMAND = s:rg_cmd . ' --files'
command! -bang -nargs=* Rg call fzf#vim#grep(s:rg_cmd . ' --column --line-number --no-heading --fixed-strings --smart-case --color always ' . shellescape(<q-args>), 1, <bang>0)
command! -bang -nargs=* Find Rg<bang> <args>
endif
" }}}
" Netrw {{{
" disable most of the Netrw functionality (because I use Ranger) except its
" helper functions (which I use in my dotfiles)
let g:loaded_netrwPlugin = 1
" re-add Netrw's gx mappings since we've disabled them
nnoremap <silent> gx :call netrw#BrowseX(expand('<cfile>'),netrw#CheckIfRemote())<CR>
vnoremap <silent> gx :<C-u>call netrw#BrowseXVis()<CR>
" }}}
" Ranger {{{
let g:ranger_replace_netrw = 1
let g:ranger_map_keys = 0
nnoremap <silent> <Leader>o :Ranger<CR>
" ranger.vim relies on the Bclose.vim plugin, but I use Bbye.vim, so this
" command is here just for compatitabilty
command! -bang -complete=buffer -nargs=? Bclose Bdelete<bang> <args>
" }}}
" Commands {{{
" DiffWithSaved {{{
" Compare current buffer with the actual (saved) file on disk
function s:DiffWithSaved()
let l:filetype = &filetype
diffthis
vnew | read # | normal! ggdd
diffthis
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile readonly nomodifiable
let &filetype = l:filetype
endfunction
command DiffWithSaved call s:DiffWithSaved()
" }}}
" Reveal {{{
" Reveal file in the system file explorer
function s:Reveal(path)
if has('macunix')
" only macOS has functionality to really 'reveal' a file, that is, to open
" its parent directory in Finder and select this file
call system('open -R ' . fnamemodify(a:path, ':S'))
else
" for other systems let's not reinvent the bicycle, instead we open file's
" parent directory using netrw's builtin function (don't worry, netrw is
" always bundled with Nvim)
call s:Open(a:path)
endif
endfunction
command Reveal call s:Reveal(expand('%'))
" }}}
" Open {{{
" opens file with a system program
function s:Open(path)
" HACK: 2nd parameter of this function is called 'remote', it tells
" whether to open a remote (1) or local (0) file. However, it doesn't work
" as expected in this context, because it uses the 'gf' command if it's
" opening a local file (because this function was designed to be called
" from the 'gx' command). BUT, because this function only compares the
" value of the 'remote' parameter to 1, I can pass any other value, which
" will tell it to open a local file and ALSO this will ignore an
" if-statement which contains the 'gf' command.
call netrw#BrowseX(a:path, 2)
endfunction
command Open call s:Open(expand('%'))
" }}}
" }}}
" on save (BufWritePre) {{{
" create directory {{{
" Creates the parent directory of the file if it doesn't exist
function s:CreateDirOnSave()
" <afile> is the filename of the buffer where the autocommand is executed
let l:file = expand('<afile>')
" check if this is a regular file and its path is not a URL
if empty(&buftype) && l:file !~# '\v^\w+://'
let l:dir = fnamemodify(l:file, ':h')
if !isdirectory(l:dir) | call mkdir(l:dir, 'p') | endif
endif
endfunction
" }}}
" fix whitespace {{{
function s:FixWhitespaceOnSave()
let l:pos = getpos('.')
" remove trailing whitespace
%s/\s\+$//e
" remove trailing newlines
%s/\($\n\s*\)\+\%$//e
call setpos('.', l:pos)
endfunction
" }}}
function s:OnSave()
call s:FixWhitespaceOnSave()
if IsCocEnabled() | silent CocFormat | endif
call s:CreateDirOnSave()
endfunction
augroup vimrc-on-save
autocmd!
autocmd BufWritePre * call s:OnSave()
augroup END
" }}}
" CtrlSF {{{
nmap <leader>/ <Plug>CtrlSFPrompt
nmap <leader>* <Plug>CtrlSFCwordPath
xmap <leader>* <Plug>CtrlSFVwordPath
" }}}

12
nvim/lib/git.vim Normal file
View file

@ -0,0 +1,12 @@
" mappings {{{
let g:gitgutter_map_keys = 0
nnoremap <leader>gg :G
nnoremap <leader>g :Git<space>
nnoremap <leader>gs :Gstatus<CR>
nnoremap <leader>gd :Gdiff
nnoremap <leader>gb :Gblame<CR>
nnoremap <leader>gw :Gbrowse<CR>
nnoremap <leader>gc :Gcommit %
nnoremap <leader>gl :Glog<CR>
nnoremap <leader>gp :Gpush
" }}}

166
nvim/lib/interface.vim Normal file
View file

@ -0,0 +1,166 @@
" configure behaviour of wildmenu when I press <Tab> in the Vim command prompt
" 1. on the 1st <Tab>, complete the longest common prefix
" 2. on the 2nd <Tab>, list all available completions and open wildmenu
" this basically emulates Tab-completion behaviour in Zsh
set wildmode=list:longest,list:full
" always show the sign column
set signcolumn=yes
" enable bell everywhere
set belloff=
" title {{{
set title
let &titlestring = '%F%{&modified ? g:airline_symbols.modified : ""} (nvim)'
" }}}
" Yes, I occasionally use mouse. Sometimes it is handy for switching windows/buffers
set mouse=a
" <RightMouse> pops up a context menu
" <S-LeftMouse> extends a visual selection
set mousemodel=popup
" Maybe someday I'll use a Neovim GUI
if has('guifont')
let &guifont = 'Ubuntu Mono derivative Powerline:h14'
endif
" Buffers {{{
set hidden
" open diffs in vertical splits by default
set diffopt+=vertical
" buffer navigation {{{
noremap <silent> <Tab> :bnext<CR>
noremap <silent> <S-Tab> :bprev<CR>
noremap <silent> gb :buffer #<CR>
" }}}
" ask for confirmation when closing unsaved buffers
set confirm
" Bbye with confirmation, or fancy buffer closer {{{
function s:CloseBuffer(cmd) abort
let l:cmd = a:cmd
if &modified
let l:answer = confirm("Save changes?", "&Yes\n&No\n&Cancel")
if l:answer is 1 " Yes
write
elseif l:answer is 2 " No
let l:cmd .= '!'
else " Cancel/Other
return
endif
endif
execute l:cmd
endfunction
" }}}
" closing buffers {{{
nnoremap <silent> <BS> :<C-u>call <SID>CloseBuffer('Bdelete')<CR>
nnoremap <silent> <Del> :<C-u>quit <bar> call <SID>CloseBuffer('Bdelete')<CR>
" }}}
" }}}
" Windows {{{
" window navigation {{{
noremap <C-j> <C-w>j
noremap <C-k> <C-w>k
noremap <C-l> <C-w>l
noremap <C-h> <C-w>h
" }}}
" switch to previous window
noremap <C-\> <C-w>p
" don't automatically make all windows the same size
set noequalalways
" splitting {{{
noremap <silent> <leader>h :split<CR>
noremap <silent> <leader>v :vsplit<CR>
" }}}
" closing windows {{{
nnoremap <silent> <A-BS> :quit<CR>
" }}}
" }}}
" Airline (statusline) {{{
let g:airline_symbols = {
\ 'readonly': 'RO',
\ 'whitespace': "\u21e5 ",
\ 'linenr': '',
\ 'maxlinenr': ' ',
\ 'branch': '',
\ 'notexists': " [?]",
\ }
let g:airline#extensions#branch#enabled = 1
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#ale#enabled = 1
call airline#parts#define_function('coc#status', 'coc#status')
function StatusLine_filesize()
let l:bytes = getfsize(expand('%'))
if l:bytes < 0 | return '' | endif
let l:factor = 1
for l:unit in ['B', 'K', 'M', 'G']
let l:next_factor = l:factor * 1024
if l:bytes < l:next_factor
let l:number_str = printf('%.2f', (l:bytes * 1.0) / l:factor)
" remove trailing zeros
let l:number_str = substitute(l:number_str, '\v\.?0+$', '', '')
return l:number_str . l:unit
endif
let l:factor = l:next_factor
endfor
endfunction
call airline#parts#define_function('filesize', 'StatusLine_filesize')
function s:airline_section_prepend(section, items)
let g:airline_section_{a:section} = airline#section#create_right(a:items + ['']) . g:airline_section_{a:section}
endfunction
function s:airline_section_append(section, items)
let g:airline_section_{a:section} = g:airline_section_{a:section} . airline#section#create_left([''] + a:items)
endfunction
function s:tweak_airline()
call s:airline_section_prepend('x', ['coc#status'])
call s:airline_section_append('y', ['filesize'])
call s:airline_section_prepend('error', ['coc_error_count'])
call s:airline_section_prepend('warning', ['coc_warning_count'])
endfunction
augroup vimrc-interface-airline
autocmd!
autocmd user AirlineAfterInit call s:tweak_airline()
augroup END
" }}}
" FZF {{{
nnoremap <silent> <F1> :Helptags<CR>
nnoremap <silent> <leader>f :Files<CR>
nnoremap <silent> <leader>b :Buffers<CR>
" }}}
" quickfix/location list {{{
nmap [q <Plug>(qf_qf_previous)
nmap ]q <Plug>(qf_qf_next)
nmap [l <Plug>(qf_loc_previous)
nmap ]l <Plug>(qf_loc_next)
let g:qf_mapping_ack_style = 1
" }}}

19
nvim/lib/languages/c.vim Normal file
View file

@ -0,0 +1,19 @@
let s:filetypes = ['c', 'cpp', 'objc', 'objcpp']
let g:coc_filetypes += s:filetypes
call coc#config('languageserver.ccls', {
\ 'filetypes': s:filetypes,
\ 'command': 'ccls',
\ 'rootPatterns': ['.ccls', 'compile_commands.json', '.vim/', '.git/', '.hg/'],
\ 'initializationOptions': {
\ 'cache': {
\ 'directory': '/tmp/ccls',
\ },
\ },
\ })
" call coc#config('languageserver.clangd', {
" \ 'filetypes': s:filetypes,
" \ 'command': 'clangd',
" \ 'rootPatterns': ['compile_flags.txt', 'compile_commands.json', '.vim/', '.git/', '.hg/'],
" \ })

View file

@ -0,0 +1,2 @@
call coc#add_extension('coc-css')
let g:coc_filetypes += ['css']

View file

@ -0,0 +1,12 @@
let s:filetypes = ['haskell', 'lhaskell', 'chaskell']
let g:coc_filetypes += s:filetypes
call coc#config('languageserver.haskell', {
\ 'filetypes': s:filetypes,
\ 'command': 'hie-wrapper',
\ 'rootPatterns': ['.stack.yaml', 'cabal.config', 'package.yaml'],
\ 'initializationOptions': {},
\ })
let g:haskell_conceal = 0
let g:haskell_conceal_enumerations = 0
let g:haskell_multiline_strings = 1

View file

@ -0,0 +1,2 @@
call coc#add_extension('coc-html', 'coc-emmet')
let g:coc_filetypes += ['html']

View file

@ -0,0 +1,12 @@
call coc#add_extension('coc-tsserver', 'coc-eslint', 'coc-prettier')
let g:coc_filetypes += ['javascript', 'javascript.jsx', 'typescript', 'typescript.jsx']
call coc#config('eslint', {
\ 'filetypes': ['javascript', 'javascriptreact', 'typescript', 'typescriptreact'],
\ 'autoFixOnSave': v:true,
\ })
call coc#config('prettier', {
\ 'singleQuote': v:true,
\ 'trailingComma': 'all',
\ 'jsxBracketSameLine': v:true,
\ 'eslintIntegration': v:true,
\ })

View file

@ -0,0 +1,7 @@
call coc#add_extension('coc-json')
let g:coc_filetypes += ['json']
augroup vimrc-languages-json
autocmd!
autocmd FileType json syntax match Comment +\/\/.\+$+
augroup END

View file

@ -0,0 +1,9 @@
let g:coc_filetypes += ['markdown']
let g:vim_markdown_conceal = 0
let g:vim_markdown_conceal_code_blocks = 0
augroup vimrc-languages-markdown
autocmd!
autocmd FileType markdown call pencil#init()
augroup END

View file

@ -0,0 +1,19 @@
call coc#add_extension('coc-python')
let g:coc_filetypes += ['python']
call coc#config('pyls.plugins.pycodestyle.ignore', ['E501'])
call coc#config('python', {
\ 'autocomplete': { 'showAdvancedMembers': v:false },
\ 'formatting': { 'provider': 'black' },
\ 'linting': {
\ 'pylintEnabled': v:false,
\ 'flake8Enabled': v:true,
\ 'flake8Args': ['--ignore', 'E501'],
\ },
\ })
augroup vimrc-language-python
autocmd!
autocmd FileType python Indent 4
augroup END
let g:python_highlight_all = 1

View file

@ -0,0 +1,9 @@
call coc#add_extension('coc-rls')
let g:coc_filetypes += ['rust']
call coc#config('rust', { 'clippy_preference': 'on' })
let g:rust_recommended_style = 0
augroup vimrc-rust
autocmd FileType rust setlocal matchpairs-=<:>
augroup END

View file

@ -0,0 +1,4 @@
augroup vimrc-languages-text
autocmd!
autocmd FileType text call pencil#init()
augroup END

View file

@ -0,0 +1 @@
let g:coc_filetypes += ['yaml']

116
nvim/lib/plugins.vim Normal file
View file

@ -0,0 +1,116 @@
let s:dein_plugins_dir = expand('~/.cache/dein')
let s:dein_dir = s:dein_plugins_dir . '/repos/github.com/Shougo/dein.vim'
if !isdirectory(s:dein_dir)
echo 'Installing Dein...'
call system('git clone https://github.com/Shougo/dein.vim ' . shellescape(s:dein_dir))
endif
let &runtimepath .= ',' . s:dein_dir
if dein#load_state(s:dein_plugins_dir)
call dein#begin(s:dein_plugins_dir)
command! -nargs=+ -bar Plugin call dein#add(<args>)
" Let dein manage itself
Plugin s:dein_dir
" Files {{{
Plugin 'tpope/vim-eunuch'
Plugin 'francoiscabrol/ranger.vim'
" }}}
" Editing {{{
Plugin 'easymotion/vim-easymotion'
Plugin 'junegunn/vim-easy-align'
Plugin 'Raimondi/delimitMate'
Plugin 'tpope/vim-repeat'
Plugin 'tpope/vim-commentary'
Plugin 'tpope/vim-surround'
Plugin 'Yggdroot/indentLine'
Plugin 'henrik/vim-indexed-search'
Plugin 'andymass/vim-matchup'
Plugin 'tommcdo/vim-exchange'
Plugin 'inkarkat/vim-ingo-library' " required by LineJuggler
Plugin 'inkarkat/vim-LineJuggler', { 'rev': 'stable' }
Plugin 'reedes/vim-pencil'
" }}}
" Text objects {{{
Plugin 'kana/vim-textobj-user'
Plugin 'kana/vim-textobj-entire'
Plugin 'kana/vim-textobj-line'
Plugin 'kana/vim-textobj-indent'
" Plugin 'kana/vim-textobj-fold'
" }}}
" UI {{{
Plugin 'moll/vim-bbye'
Plugin 'gerw/vim-HiLinkTrace'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'wincent/terminus'
Plugin 'tpope/vim-obsession'
Plugin 'romainl/vim-qf'
Plugin 'dyng/ctrlsf.vim'
" }}}
" Git {{{
Plugin 'tpope/vim-fugitive'
Plugin 'tpope/vim-rhubarb'
Plugin 'airblade/vim-gitgutter'
" }}}
" FZF {{{
Plugin 'junegunn/fzf', { 'build': './install --bin' }
Plugin 'junegunn/fzf.vim'
" }}}
" Programming {{{
Plugin 'sheerun/vim-polyglot'
Plugin 'neoclide/coc.nvim', { 'build': 'yarn install' }
Plugin 'dag/vim2hs'
" }}}
delcommand Plugin
call dein#end()
call dein#save_state()
endif
" enable full plugin support
filetype plugin indent on
syntax enable
" Automatically install/clean plugins (because I'm a programmer) {{{
" the following two lines were copied directly from dein's source code
let s:dein_cache_dir = get(g:, 'dein#cache_directory', g:dein#_base_path)
let s:dein_state_file = s:dein_cache_dir . '/state_' . g:dein#_progname . '.vim'
let s:current_file = expand('<sfile>')
" gettftime() returns the last modification time of a given file
let s:plugins_file_changed = getftime(s:current_file) > getftime(s:dein_state_file)
if s:plugins_file_changed
echo "plugins.vim was changed, clearing Dein state..."
call dein#clear_state()
let s:unused_plugins = dein#check_clean()
if !empty(s:unused_plugins)
echo "Cleaning up unused plugins..."
for s:plugin in s:unused_plugins
echo "deleting" s:plugin
call delete(s:plugin, 'rf')
endfor
endif
endif
if dein#check_install() || s:plugins_file_changed
echo "Installing plugins..."
call dein#install()
echo
endif
" }}}

6
nvim/lib/terminal.vim Normal file
View file

@ -0,0 +1,6 @@
nnoremap <silent> <leader>t :terminal<CR>
augroup vimrc-terminal
autocmd!
autocmd TermOpen * set nocursorline | IndentLinesDisable
augroup END

1
welcome/.gitignore vendored
View file

@ -1 +0,0 @@
*.pyc

View file

@ -2,7 +2,7 @@
import re
from colors import Style, COLORS
from colors import COLORS, Style
from system_info import get_system_info
print("")