" Author: Konstantin Bukley " License: WTFPL " Description: Personal vim configuration " ======================================================== " -> General " ======================================================== set fileencoding=utf-8 nnoremap let mapleader=' ' " ======================================================== " -> Plugins " ======================================================== " " curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim " call plug#begin('~/.vim/plugged') Plug 'scrooloose/nerdtree', { 'on': ['NERDTreeToggle', 'NERDTreeFind'] } Plug 'junegunn/vim-easy-align', { 'on': ['(EasyAlign)', 'EasyAlign'] } Plug 'gregsexton/MatchTag', { 'for': 'html' } Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } Plug 'junegunn/fzf.vim' Plug 'AndrewRadev/splitjoin.vim' Plug 'mattn/gist-vim' | Plug 'mattn/webapi-vim' Plug 'Raimondi/delimitMate' Plug 'nelstrom/vim-visual-star-search' Plug 'benmills/vimux' Plug 'vim-test/vim-test' Plug 'dyng/ctrlsf.vim' Plug 'terryma/vim-expand-region' Plug 'mg979/vim-visual-multi' Plug 'bogado/file-line' Plug 'vim-utils/vim-interruptless' Plug 'airblade/vim-gitgutter' Plug 'machakann/vim-highlightedyank' Plug 'arcticicestudio/nord-vim' Plug 'christoomey/vim-tmux-navigator' Plug 'tpope/vim-fugitive' Plug 'tpope/vim-rails', { 'for': 'ruby' } Plug 'tpope/vim-surround' Plug 'tpope/vim-commentary' Plug 'tpope/vim-repeat' Plug 'tpope/vim-git' Plug 'tpope/vim-vinegar' Plug 'tpope/vim-rhubarb' " Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' Plug 'L3MON4D3/LuaSnip' | Plug 'honza/vim-snippets' " ======== Experimental ================================= " Plug 'nvim-lua/popup.nvim' " Plug 'nvim-lua/plenary.nvim' " Plug 'nvim-telescope/telescope.nvim' Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'} Plug 'neovim/nvim-lspconfig' call plug#end() " ======================================================== " -> Functions " ======================================================== function! StripTrailingWhitespace() let _s=@/ let l = line(".") let c = col(".") %s/\s\+$//e let @/=_s silent! call cursor(l, c) endfunction function! Tabline() let s = '' for i in range(tabpagenr('$')) let tab = i + 1 let winnr = tabpagewinnr(tab) let buflist = tabpagebuflist(tab) let bufnr = buflist[winnr - 1] let bufname = bufname(bufnr) let bufmodified = getbufvar(bufnr, "&mod") let s .= (tab == tabpagenr() ? '%#TabLineSel#' : '%#TabLine#') if bufname == '' let s .= ' empty' elseif bufname =~ 'NERD_tree' let s .= ' tree' elseif bufname =~ 'ControlP' let s .= ' ctrlp' elseif bufname =~ 'FZF' let s .= ' fzf' elseif bufname =~ '__CtrlSF__' let s .= ' ctrlsf' else let s .= ' ' . fnamemodify(bufname, ':t') endif if bufmodified let s .= '(+)' endif endfor let s .= '%#TabLineFill#' return s endfunction function! CloseNERDTree() if exists("t:NERDTreeBufName") if bufwinnr(t:NERDTreeBufName) != -1 if winnr("$") == 1 q endif endif endif endfunction " ======================================================== " -> Plugin settings " ======================================================== " Enable matchit.vim runtime macros/matchit.vim " --- Netrw let g:netrw_banner = 0 let g:netrw_list_hide = '^\.$' let g:netrw_liststyle = 4 " --- test let test#strategy = "vimux" " --- NERDTree let NERDTreeWinPos = "right" let NERDTreeMinimalUI = 1 let NERDTreeDirArrows = 1 let NERDTreeAutoDeleteBuffer = 1 let NERDTreeHijackNetrw = 1 " --- highlightedyank let g:highlightedyank_highlight_duration = 400 " --- gitgutter let g:gitgutter_sign_added = '│' let g:gitgutter_sign_modified = '│' let g:gitgutter_sign_removed = '│' let g:gitgutter_sign_modified_removed = '│' let g:gitgutter_sign_removed_first_line = '│' " --- fzf if has('nvim') || has('gui_running') let $FZF_DEFAULT_OPTS .= ' --no-info --color=gutter:#2E3440' endif command! -nargs=? -complete=dir AF \ call fzf#run(fzf#wrap(fzf#vim#with_preview({ \ 'source': 'fd --type f --hidden --follow --exclude .git --no-ignore . '.expand() \ }))) let g:fzf_preview_window = '' let g:fzf_layout = { 'window': { 'width': 0.6, 'height': 0.6, 'border': 'sharp' } } let g:fzf_colors = \ { 'fg': ['fg', 'Normal'], \ 'bg': ['bg', 'Normal'], \ 'hl': ['fg', 'Comment'], \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], \ 'hl+': ['fg', 'Statement'], \ 'info': ['fg', 'PreProc'], \ 'border': ['fg', 'Ignore'], \ 'prompt': ['fg', 'Conditional'], \ 'pointer': ['fg', 'Exception'], \ 'marker': ['fg', 'Keyword'], \ 'spinner': ['fg', 'Label'], \ 'header': ['fg', 'Comment'] } " --- CtrlSF let g:ctrlsf_ackprg = 'rg' let g:ctrlsf_regex_pattern = 1 let g:ctrlsf_case_sensitive = 'smart' let g:ctrlsf_default_root = 'project' let g:ctrlsf_context = '-B 1 -A 1' let g:ctrlsf_position = 'bottom' let g:ctrlsf_winsize = '40%' let g:ctrlsf_mapping = \ { \ 'next': 'n', \ 'prev': 'N', \ } " --- gist-vim let g:gist_clip_command = 'pbcopy' let g:gist_detect_filetype = 1 let g:gist_post_private = 1 let g:gist_show_privates = 1 " ======================================================== " -> Autocommands " ======================================================== if has("autocmd") au filetype help nnoremap au filetype help nnoremap au filetype help set nonumber au BufNewFile,BufRead *.docker setl ft=Dockerfile au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null au FileType json setlocal equalprg=python\ -m\ json.tool au FileType markdown setlocal wrap " Hide statusline au! FileType fzf au FileType fzf set laststatus=0 noshowmode noruler \| autocmd BufLeave set laststatus=2 showmode ruler " Close tab if only NERDTree left au WinEnter * call CloseNERDTree() " Resize when the host window resized au VimResized * wincmd = endif " ======================================================== " -> Colors & Fonts " ======================================================== colorscheme nord set background=dark set guifont=Fira\ Code\ Medium:h18 if has('gui_running') set guioptions-=T " Remove toolbar set guioptions-=m " Remove menubar set guioptions+=LlRrb " Remove set guioptions-=LlRrb " Scrollbars set t_Co=256 else " Disable Background Color Erase (BCE) so that color schemes " work properly when Vim is used inside tmux and GNU screen. " See also http://snk.tuxfamily.org/log/vim-256color-bce.html set t_ut= set t_Co=16 endif " ======================================================== " -> User Interface " ======================================================== " Nicer separators set fillchars=diff:⣿,vert:│ " Don't try to highlight lines longer than 800 characters. set synmaxcol=200 " Do not redraw while running macros set lazyredraw " Tab label - requires vim-madundead set tabline=%!Tabline() " Number rows set number " Disable welcome message set shortmess+=I " Show matching braces set showmatch " Shows when you are in insert mode set showmode " Show title in console status bar set title " Dont wrap lines set nowrap " When I scroll up or down, there are 2 lines between the line I'm on and the bottom or top of the screen. set scrolloff=5 " How many tenths of a second to blink on matching brackets set mat=2 " Disable cursor blink set gcr=a:blinkon0 " Hide the mouse pointer while typing set mousehide " Conceal mostly for markdown set conceallevel=2 " Highlight VCS conflict markers match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$' " Statusline set statusline=%<%f " ======================================================== " -> Behavior & Different Tricks " ======================================================== " Shamelessly taken from YADR dotfile repo https://github.com/skwp/dotfiles " Stuff to ignore whent tab completing set wildignore=*.o,*.obj,*~ set wildignore+=*vim/backups* set wildignore+=*sass-cache* set wildignore+=*DS_Store* set wildignore+=vendor/rails/** set wildignore+=vendor/cache/** set wildignore+=*.gem set wildignore+=log/** set wildignore+=tmp/** set wildignore+=*.png,*.jpg,*.gif " Russian keymap support set langmap=ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯЖ;ABCDEFGHIJKLMNOPQRSTUVWXYZ:,фисвуапршолдьтщзйкыегмцчня;abcdefghijklmnopqrstuvwxyz " W invokes sudo command! W w !sudo tee % > /dev/null " Use the OS clipboard by default (requires `+clipboard`) set clipboard=unnamed " Tenths of a second to show the matching paren set matchtime=2 " Turn off visualbell set novisualbell " Fuck backups set nobackup set nowb set noswapfile " Doesn't select lines number in vim set mouse=a " Fancy whitespace characters set list listchars=tab:→\ ,trail:· " Abbrev. of messages (avoids 'hit enter') set shortmess+=filmnrxoOtT " Start scrolling when we're 8 lines away from margins set scrolloff=8 " The minimal number of screen columns to keep to the left and to the " right of the cursor if 'nowrap' is set. set sidescrolloff=15 " Vertical splits in diff mode set diffopt+=vertical " Reduce delay between modes set timeoutlen=1000 ttimeoutlen=0 " Use ripgrep if possible if executable('rg') set grepprg=rg\ -i\ --vimgrep endif " Enables aliases from .bashrc in :! commands set shellcmdflag=-ic " ======================================================== " -> Indentations " ======================================================== " Automatically inserts one extra level of indentation in some cases set smartindent " Tab counts as 2 columns set tabstop=2 " Numbers of spaces to (auto)indent set shiftwidth=2 " Spaces set expandtab " ======================================================== " -> Hotkeys & Bindings " ======================================================== nnoremap ; : nnoremap Q :q! nnoremap h nnoremap j nnoremap k nnoremap l nnoremap ,, nnoremap ff (expand('%') =~ 'NERD_tree' ? "\\" : '').":Files\" nnoremap b (expand('%') =~ 'NERD_tree' ? "\\" : '').":Buffers\" nnoremap gl (expand('%') =~ 'NERD_tree' ? "\\" : '').":Commits\" nnoremap a :A nnoremap x nnoremap n :NERDTreeToggle nnoremap N :NERDTreeFind nnoremap c /\v^[<=>]{7}( .*\|$) nnoremap t :tabnew nnoremap d orequire 'pry'; binding.pry nnoremap D oit { require 'pry'; binding.pry } nnoremap r :TestFile nnoremap R :TestSuite nnoremap J :%!python -m json.tool nnoremap w :w nnoremap q :q! nnoremap e :e! nnoremap = = nnoremap :nohlsearch nnoremap ga :Gwrite nnoremap gs :Git nnoremap gb :Git blame nnoremap :tabnext nnoremap :tabprevious " nnoremap vv v nnoremap vv :sp nnoremap :call StripTrailingWhitespace() nnoremap S :%s/\<\>//g nnoremap yy Y nnoremap Y y$ nnoremap N Nzz nnoremap n nzz nnoremap j gj nnoremap k gk nnoremap H ^ nnoremap L $ nnoremap J mzJ`z nnoremap K nnoremap gQ vnoremap . :normal . vnoremap J :m '>+1gv=gv vnoremap K :m '<-2gv=gv vnoremap < >gv inoremap vnoremap cnoremap inoremap vnoremap cnoremap nmap CtrlSFPrompt vmap CtrlSFVwordPath vmap (EasyAlign) xmap ga (EasyAlign) nmap ga (EasyAlign) nnoremap e (expand('%') =~ 'NERD_tree' ? "\\" : '').":Files ~/Tmp\" nnoremap E :e ~/Tmp/ " TODO Ignore .obsidian/ nnoremap o (expand('%') =~ 'NERD_tree' ? "\\" : '').":Files ~/Library/Mobile\ Documents/iCloud~md~obsidian/Documents/Personal\" nnoremap O :e ~/Library/Mobile\ Documents/iCloud~md~obsidian/Documents/Personal " EXPERIMENTAL STUFF nnoremap ft Telescope find_files " nmap ft Telescope live_grep " undo break points inoremap , ,u inoremap . .u inoremap ! !u inoremap ? ?u " Fix gx " https://github.com/vim/vim/issues/4738#issuecomment-856925080 nnoremap gx :execute 'silent! !open ' . shellescape(expand(''), 1) lua < buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') -- Mappings. local opts = { noremap=true, silent=true } -- See `:help vim.lsp.*` for documentation on any of the below functions buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts) buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) -- buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) -- buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) -- buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) -- buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) -- buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()', opts) buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', opts) buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', opts) buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) -- buf_set_keymap('n', 'e', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) buf_set_keymap('n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) buf_set_keymap('n', 'q', 'lua vim.lsp.diagnostic.set_loclist()', opts) -- buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', opts) end -- Use a loop to conveniently call 'setup' on multiple servers and -- map buffer local keybindings when the language server attaches local servers = { 'solargraph' } for _, lsp in ipairs(servers) do nvim_lsp[lsp].setup { on_attach = on_attach, flags = { debounce_text_changes = 150, } } end require("luasnip.loaders.from_snipmate").load() local function prequire(...) local status, lib = pcall(require, ...) if (status) then return lib end return nil end local luasnip = prequire('luasnip') local cmp = prequire("cmp") local t = function(str) return vim.api.nvim_replace_termcodes(str, true, true, true) end local check_back_space = function() local col = vim.fn.col('.') - 1 if col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then return true else return false end end _G.tab_complete = function() if cmp and cmp.visible() then cmp.select_next_item() elseif luasnip and luasnip.expand_or_jumpable() then return t("luasnip-expand-or-jump") elseif check_back_space() then return t "" else cmp.complete() end return "" end _G.s_tab_complete = function() if cmp and cmp.visible() then cmp.select_prev_item() elseif luasnip and luasnip.jumpable(-1) then return t("luasnip-jump-prev") else return t "" end return "" end vim.api.nvim_set_keymap("i", "", "v:lua.tab_complete()", {expr = true}) vim.api.nvim_set_keymap("s", "", "v:lua.tab_complete()", {expr = true}) vim.api.nvim_set_keymap("i", "", "v:lua.s_tab_complete()", {expr = true}) vim.api.nvim_set_keymap("s", "", "v:lua.s_tab_complete()", {expr = true}) vim.api.nvim_set_keymap("i", "", "luasnip-next-choice", {}) vim.api.nvim_set_keymap("s", "", "luasnip-next-choice", {}) EOF