diff --git a/.vimrc b/.vimrc new file mode 100644 index 0000000..3763955 --- /dev/null +++ b/.vimrc @@ -0,0 +1,585 @@ +" vim: set foldmethod=marker: +" {{{1 Global Variables + +let g:skip_defaults_vim = 1 +let g:mapleader = " " +let g:vimsyn_embed = "lpP" +let g:python_indent = {} +let g:python_indent.open_paren = 'shiftwidth()' +let g:python_indent.continue = 'shiftwidth()' +let g:netrw_banner = 0 +let g:netrw_liststyle = 1 +let g:netrw_list_hide = '\.venv/,\.git/' +let g:netrw_maxfilenamelen = 47 +let g:netrw_mousemaps = 0 +let g:netrw_sizestyle = 'H' +let g:netrw_sort_by = 'name' +let g:netrw_sort_options = 'i' +let g:netrw_sort_sequence = '[\/]\s*,*' +let g:netrw_special_syntax = v:true +let g:netrw_timefmt = '%d-%m-%Y %H:%M' +let &t_8f = "\[38;2;%lu;%lu;%lum" +let &t_8b = "\[48;2;%lu;%lu;%lum" +let &t_SI = "\e[6 q" +let &t_EI = "\e[2 q" +let &t_SR = "\e[4 q" + +" {{{1 Options + +set cursorline +set number +set relativenumber +set mouse=a +set mousemodel=popup +set fillchars= +set fillchars+=vert:┃ +set fillchars+=diff:\ +set splitbelow +set splitright +set tabstop=4 +set softtabstop=4 +set expandtab +set shiftwidth=4 +set nosmarttab +set foldlevelstart=99 +set foldmethod=indent +set foldignore= +set guifont=Iosevka\ Custom\ 12 +set completeopt=menu,menuone,preview,noinsert,noselect +set matchpairs=(:),{:},[:],<:> +set linebreak +set breakindent +set showbreak=↪\ +set scrolloff=3 +set visualbell +set noerrorbells +set undofile +set shiftround +set virtualedit=block +set termguicolors +set diffopt= +set diffopt+=vertical +set diffopt+=filler +set diffopt+=closeoff +set diffopt+=internal +set diffopt+=indent-heuristic +set diffopt+=algorithm:histogram +set hlsearch +set laststatus=2 +set textwidth=0 +set colorcolumn=81 +set shortmess=atToOCF +set autoread +set timeout timeoutlen=1000 ttimeoutlen=0 +set nocompatible +set updatetime=100 +set hidden +set incsearch +set jumpoptions=stack + +syntax on +filetype plugin indent on + +" {{{1 Mappings + +if !empty($TMUX) && executable('tmux') + map y "+y:call system('tmux load-buffer -w -', @+) +else + map y "+y +endif + +map + :call setreg('+', @") +map p "+p +map P "+P + +map dp :diffput +map do :diffget +nmap gd :Gdiffsplit +nmap gc :G commit +nmap ga :G commit --amend +nmap gp :G push +nmap gg :tabnew \| leftabove vert G \| vert resize 50 \| set wfw +nmap ]g (GitGutterNextHunk) +nmap [g (GitGutterPrevHunk) +map gs (GitGutterStageHunk) +map gr (GitGutterUndoHunk) +map g? (GitGutterPreviewHunk) +xmap < >gv +map +imap +imap +imap ^ +imap $ +imap C +imap x +execute "set =\ef" +execute "set =\eb" +execute "set =\ed" +imap w +imap b +imap dw +cmap +cmap +cmap +cmap +cmap +cmap +cmap +cmap +cmap +cmap +inoremap +noremap :nohlsearch:diffupdate +nmap tn :tabnew +nmap tq :tabclose +nmap ff :Files +nmap fr :CwdHistory +nmap fb :Buffers +nmap fg :Rg "" +nmap fe &filetype ==# 'netrw' ? ':Rex' : ':Ex' +nmap q :bn \| bd# + +" {{{2 Default Mappings + +" - Exit insert mode in terminal +" insert mode: +" - indent, see :h i_CTRL-T +" - un-indent, see :h i_CTRL-D +" normal mode: +" - scroll window down lines, see :h CTRL-E +" - scroll window up lines, see :h CTRL-Y +" commands: +" :make - execute makeprg with given args +" :copen - open quickfix list +" :cdo {cmd} - execute {cmd} in each valid entry in the quickfix list. +" works like this: +" :cfirst +" :{cmd} +" :cnext +" :{cmd} +" etc. +" :cn - go to the next error in quickfix list that includes a file name +" :cp - go to the previous error in quickfix list that includes a file name +" :cc [num] - go to the specified error in quickfix list +" @: - repeat last command +" :s/foo/bar/ - substitute the first match of foo with bar in the current line +" :s/foo/bar/g - same as above but for all matches in the current line +" :%s/foo/bar/g - same as above, but for all lines in buffer +" :%s/foo/bar/gc - same as above but asking for confirmation on each match +" :lua << EOF - run a lua snippet using lua-heredoc syntax +" local tbl = {1, 2, 3} +" for k, v in ipairs(tbl) do +" print(v) +" end +" EOF + +" {{{1 Autocommands + +" Return cursor to last position in buffer +autocmd BufReadPost * silent! normal! g`"zv + +" Filetype specific config +autocmd FileType go setlocal noexpandtab +autocmd FileType c,cpp + \ setlocal tabstop=2 | + \ setlocal softtabstop=2 | + \ setlocal shiftwidth=2 +autocmd FileType netrw nmap - +autocmd FileType netrw nmap +autocmd VimEnter * :clearjumps + +" {{{1 Custom commands +command! W write + +" {{{1 Plugins +" {{{2 Plugin variables +" {{{3 Moonfly + +let g:moonflyNormalFloat = v:true +let g:moonflyCursorColor = v:true +let g:moonflyWinSeparator = 2 +let g:moonflyVirtualTextColor = v:true + +" {{{2 GitGutter + +let g:gitgutter_sign_added = '┃' +let g:gitgutter_sign_modified = '┃' +let g:gitgutter_sign_removed = '┃' + +" {{{2 Colorizer + +let g:colorizer_colornames = 0 + +" {{{2 Install +let s:plug_file = expand('$HOME/.vim/autoload/plug.vim') +if !filereadable(s:plug_file) + silent execute '!curl -fkLo ' . s:plug_file ' --create-dirs' + \ ' https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' + autocmd VimEnter * PlugInstall --sync | source $MYVIMRC +endif + +let s:plug_dir = expand('$HOME/.vim/plugged') +call plug#begin(s:plug_dir) + Plug 'bluz71/vim-moonfly-colors', { 'as': 'moonfly' } + Plug 'tpope/vim-commentary' + Plug 'tpope/vim-fugitive' + Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } + Plug 'junegunn/fzf.vim' + Plug 'airblade/vim-gitgutter' + Plug 'markonm/traces.vim' + Plug 'rbong/vim-flog' + Plug 'chrisbra/Colorizer' + Plug 'jceb/vim-orgmode' + + " Plug 'prabirshrestha/vim-lsp' + " Plug 'dense-analysis/ale' + " Plug 'prabirshrestha/asyncomplete.vim' + " Plug 'prabirshrestha/asyncomplete-lsp.vim' + + " Plug 'neoclide/coc.nvim', {'branch': 'release'} + + " Plug 'https://github.com/yegappan/lsp' + + " Some notes: + " * ALE doesn't support semantic highlighting + " * vim-lsp doesn't support clangd switch to header/source or request document + " highlight on cursor or request diagnostic float on cursor + " * CoC flickers in C++/clangd when semanticTokens is enabled + " * lsp slow loading new buffers + " * YouCompleteMe ??? haven't tried but supports semantic highlighting + " + " To conclude, vim-lsp + asynccomplete + ALE seems to be the best stack. + " Disabling LSP stuff for now. +call plug#end() + +" {{{2 Colorscheme + +augroup CustomHighlight + autocmd! + autocmd ColorScheme moonfly highlight VertSplit term=none cterm=none +augroup END + +silent! colorscheme moonfly + +" {{{2 Fzf + +function! s:build_quickfix_list(lines) + echo "lines" + echo lines + call setqflist(map(copy(a:lines), '{ "filename": v:val, "lnum": 1 }')) + copen + cc +endfunction + +autocmd! FileType fzf tnoremap +autocmd! FileType fzf tnoremap +autocmd! FileType fzf tnoremap + +" To match exact, prefix word with `'` +command! -bang -nargs=* Rg call fzf#vim#grep( + \ "rg" + \ . " --column" + \ . " --line-number" + \ . " --no-heading" + \ . " --color=always" + \ . " --smart-case" + \ . " --iglob=!.git" + \ . " --hidden" + \ . " --no-ignore-vcs " ., 1, 0) + +command! -bang CwdHistory call fzf#run(fzf#wrap({ + \ 'source': filter( + \ fzf#vim#_recent_files(), + \ 'v:val !~ "^\\~\\?/"' + \ ), + \ 'options': [ + \ '-m', + \ '--header-lines', !empty(expand('%')), + \ '--prompt', 'CwdHist> ' + \ ]}, + \ 0)) + +" {{{2 flog + +nmap gl :Flog + +" {{{2 vim-lsp + +" let g:lsp_use_native_client = 1 +" let g:lsp_semantic_enabled = 1 +" let g:lsp_format_sync_timeout = 1000 +" let g:lsp_document_code_action_signs_enabled = 0 +" let g:lsp_document_highlight_enabled = 0 +" let g:lsp_diagnostics_virtual_text_enabled = 1 +" let g:lsp_diagnostics_virtual_text_align = 'after' +" let g:lsp_diagnostics_virtual_text_padding_left = 5 +" let g:lsp_diagnostics_virtual_text_wrap = 'truncate' + +" highlight! link lspReference Visual + +" if executable('pyright') +" au User lsp_setup call lsp#register_server({ +" \ 'name': 'pyright', +" \ 'cmd': {server_info->['pyright-langserver', '--stdio']}, +" \ 'allowlist': ['python'], +" \ 'workspace_config': { +" \ 'python': { +" \ 'analysis': { +" \ 'autoSearchPaths': v:true, +" \ 'diagnosticMode': 'openFilesOnly', +" \ 'useLibraryCodeForTypes': v:true, +" \ 'typeCheckingMode': 'off' +" \ } +" \ } +" \ }}) +" endif + +" if executable('clangd') +" au User lsp_setup call lsp#register_server({ +" \ 'name': 'clangd', +" \ 'cmd': {server_info->[ +" \ 'clangd', +" \ '--clang-tidy', +" \ '--enable-config', +" \ '--compile-commands-dir=build' +" \ ]}, +" \ 'allowlist': ['c', 'cpp'], +" \ }) +" endif + +" function! s:on_lsp_buffer_enabled() abort +" setlocal omnifunc=lsp#complete +" setlocal signcolumn=yes +" if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif +" nmap gd (lsp-definition) +" nmap gs (lsp-document-symbol-search) +" nmap gS (lsp-workspace-symbol-search) +" nmap gr (lsp-references) +" nmap gi (lsp-implementation) +" nmap gD (lsp-type-definition) +" nmap lr (lsp-rename) +" nmap [d (lsp-previous-diagnostic) +" nmap ]d (lsp-next-diagnostic) +" nmap (lsp-hover-float) +" imap (lsp-hover-float) +" nmap (lsp-signature-help) +" imap (lsp-signature-help) +" nmap (lsp-document-symbol) +" nmap ld (lsp-document-diagnostics) + +" inoremap pumvisible() ? "\" : "\" +" inoremap pumvisible() ? "\" : "\" +" inoremap pumvisible() ? asyncomplete#close_popup() : "\" + +" nmap la (lsp-code-action-float) + +" " function! s:check_back_space() abort +" " let col = col('.') - 1 +" " return !col || getline('.')[col - 1] =~ '\s' +" " endfunction + +" " inoremap +" " \ pumvisible() ? "\" : +" " \ check_back_space() ? "\" : +" " \ asyncomplete#force_refresh() +" " inoremap pumvisible() ? "\" : "\" + +" " let g:lsp_format_sync_timeout = 1000 +" " autocmd! BufWritePre *.rs,*.go call execute('LspDocumentFormatSync') + +" augroup lsp_float_colours +" autocmd! +" autocmd User lsp_float_opened +" \ call popup_setoptions(lsp#document_hover_preview_winid(), +" \ #{borderchars: [ +" \ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +" \ ], +" \ border: [0, 1, 0 ,1] +" \ }) +" augroup end +" endfunction + +" augroup lsp_install +" au! +" " call s:on_lsp_buffer_enabled only for languages that has the server registered. +" autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled() +" augroup END + +" {{{2 CoC + +" inoremap +" \ coc#pum#visible() ? coc#pum#next(1) : +" \ CheckBackspace() ? "\" : +" \ coc#refresh() +" inoremap coc#pum#visible() ? coc#pum#prev(1) : "\" + +" " Make to accept selected completion item or notify coc.nvim to format +" " u breaks current undo, please make your own choice +" inoremap coc#pum#visible() ? coc#pum#confirm() +" \: "\u\\=coc#on_enter()\" + +" function! CheckBackspace() abort +" let col = col('.') - 1 +" return !col || getline('.')[col - 1] =~# '\s' +" endfunction + +" " Use to trigger completion +" if has('nvim') +" inoremap coc#refresh() +" else +" inoremap coc#refresh() +" endif + +" " Use `[d` and `]d` to navigate diagnostics +" " Use `:CocDiagnostics` to get all diagnostics of current buffer in location list +" nmap [d (coc-diagnostic-prev) +" nmap ]d (coc-diagnostic-next) + +" " GoTo code navigation +" nmap gd (coc-definition) +" nmap gD (coc-type-definition) +" nmap gi (coc-implementation) +" nmap gr (coc-references) + +" " Use K to show documentation in preview window +" nmap :call ShowDocumentation() +" imap :call CocActionAsync('showSignatureHelp') + +" function! ShowDocumentation() +" if CocAction('hasProvider', 'hover') +" call CocActionAsync('doHover') +" endif +" endfunction + +" " Highlight the symbol and its references +" nmap :call CocActionAsync('highlight') + +" " Symbol renaming +" nmap rn (coc-rename) + +" " Formatting selected code +" xmap lf (coc-format-selected) +" nmap lf :call CocActionAsync('format') + +" " Applying code actions to the selected code block +" xmap la (coc-codeaction-selected) +" nmap la (coc-codeaction-selected) + +" {{{2 lsp + +" autocmd User LspSetup call LspOptionsSet(#{ +" \ aleSupport: v:false, +" \ autoComplete: v:true, +" \ autoHighlight: v:false, +" \ autoHighlightDiags: v:true, +" \ autoPopulateDiags: v:false, +" \ completionMatcher: 'case', +" \ completionMatcherValue: 1, +" \ diagSignErrorText: 'E', +" \ diagSignHintText: 'H', +" \ diagSignInfoText: 'I', +" \ diagSignWarningText: 'W', +" \ echoSignature: v:false, +" \ hideDisabledCodeActions: v:false, +" \ highlightDiagInline: v:true, +" \ hoverInPreview: v:false, +" \ ignoreMissingServer: v:false, +" \ keepFocusInDiags: v:true, +" \ keepFocusInReferences: v:true, +" \ completionTextEdit: v:true, +" \ diagVirtualTextAlign: 'above', +" \ diagVirtualTextWrap: 'default', +" \ noNewlineInCompletion: v:false, +" \ omniComplete: v:null, +" \ outlineOnRight: v:false, +" \ outlineWinSize: 20, +" \ semanticHighlight: v:false, +" \ showDiagInBalloon: v:true, +" \ showDiagInPopup: v:true, +" \ showDiagOnStatusLine: v:true, +" \ showDiagWithSign: v:true, +" \ showDiagWithVirtualText: v:false, +" \ showInlayHints: v:true, +" \ showSignature: v:true, +" \ snippetSupport: v:false, +" \ ultisnipsSupport: v:false, +" \ useBufferCompletion: v:false, +" \ usePopupInCodeAction: v:false, +" \ useQuickfixForLocations: v:false, +" \ vsnipSupport: v:false, +" \ bufferCompletionTimeout: 100, +" \ customCompletionKinds: v:false, +" \ completionKinds: {}, +" \ filterCompletionDuplicates: v:false, +" \ }) + +" autocmd User LspSetup call LspAddServer([#{ +" \ name: 'clangd', +" \ filetype: ['c', 'cpp'], +" \ path: 'clangd', +" \ args: [ +" \ '--background-index', +" \ '--clang-tidy', +" \ '--enable-config', +" \ "--compile-commands-dir=build", +" \ ] +" \ }]) + +" {{{2 ALE + +" let g:ale_linters_explicit = 1 +" let g:ale_linters = #{ +" \ python: ['flake8'], +" \ } +" let g:ale_python_flake8_options = '--max-line-length=80 --max-doc-length=80' + +" let g:ale_fixers = #{ +" \ python: ['black', 'isort', 'remove_trailing_lines', 'trim_whitespace'], +" \ } +" let g:ale_python_black_options = '--line-length 80' + +" {{{1 Statusline + +execute 'highlight default GitStatusAdd guifg=' + \ . synIDattr(synIDtrans(hlID('GitGutterAdd')), 'fg') + \ . ' guibg=' + \ . synIDattr(synIDtrans(hlID('StatusLine')), 'bg') +execute 'highlight GitStatusChange guifg=' + \ . synIDattr(synIDtrans(hlID('GitGutterChange')), 'fg') + \ . ' guibg=' + \ . synIDattr(synIDtrans(hlID('StatusLine')), 'bg') +execute 'highlight GitStatusDelete guifg=' + \ . synIDattr(synIDtrans(hlID('GitGutterDelete')), 'fg') + \ . ' guibg=' + \ . synIDattr(synIDtrans(hlID('StatusLine')), 'bg') + +function! GitStatus() + let [a,m,r] = GitGutterGetHunkSummary() + let parts = [] + + if a > 0 + let parts += ['%#GitStatusAdd#' . printf('+%d', a) . '%*'] + endif + + if m > 0 + let parts += ['%#GitStatusChange#' . printf('~%d', m) . '%*'] + endif + + if r > 0 + let parts += ['%#GitStatusDelete#' . printf('-%d', r) . '%*'] + endif + + if empty(parts) + return '' + endif + + return ' ' . join(parts, ' ') +endfunction + + " \%{coc#status()}%{get(b:,'coc_current_function','')} +set statusline=\ %f%{%GitStatus()%}\ %m + \%= + \%-5.5{&filetype}\ %-6.6{&fileencoding}\ %-4.4{&fileformat} + \\ %4.4(%p%%%)%5.5l:%-3.3v + diff --git a/setup.sh b/setup.sh index 6b7a49b..d401d4c 100755 --- a/setup.sh +++ b/setup.sh @@ -56,6 +56,7 @@ SYMLINKS=( ".local/bin" ".local/share/fonts" ".local/share/konsole" + ".vimrc" ".xinit-scripts" ".xinitrc" ".Xresources"