""---------------------------------------------------------------------------// "MAPPINGS ""---------------------------------------------------------------------------// ""---------------------------------------------------------------------------// "Terminal {{{ ""---------------------------------------------------------------------------// " Terminal settings if has('nvim') "Add neovim terminal escape with ESC mapping tmap tmap jk tmap tmap tmap tmap tmap x bp! bd! # tmap . bprev tmap , bnext else tmap h tmap j tmap k tmap l tmap q! endif nnoremap to term "Opening splits with terminal in all directions nnoremap h leftabove 30vnewterminal nnoremap l rightbelow 30vnewterminal nnoremap k leftabove 10newterminal nnoremap j rightbelow 10newterminal nnoremap te tabnewte "}}} ""---------------------------------------------------------------------------// " MACROS {{{ ""---------------------------------------------------------------------------// "-------------------------------------------- "Absolutely fantastic function from stoeffel/.dotfiles which allows you to "repeat macros across a visual range "-------------------------------------------- xnoremap @ call ExecuteMacroOverVisualRange() function! ExecuteMacroOverVisualRange() echo "@".getcmdline() execute ":'<,'>normal @".nr2char(getchar()) endfunction "-------------------------------------------- " Focus marked text by highlighting everything else as a comment xnoremap :call Focus() nnoremap q :call Unfocus() function! s:Focus() let start = line("'<") let end = line("'>") call matchadd('Comment', '.*\%<'.start.'l') call matchadd('Comment', '.*\%>'.end.'l') syntax sync fromstart redraw endfunction function! s:Unfocus() call clearmatches() endfunction "}}} " ---------------------------------------------------------------------------- " Credit: JGunn Choi ?il | inner line " ---------------------------------------------------------------------------- " includes newline xnoremap al $o0 onoremap al :normal val " No Spaces or CR xnoremap il ^vg_ onoremap il :normal! ^vg_ ""---------------------------------------------------------------------------// " Word transposition. Lifted from: " http://superuser.com/questions/290360/how-to-switch-words-in-an-easy-manner-in-vim/290449#290449 ""---------------------------------------------------------------------------// " exchange word under cursor with the next word without moving the cursor nnoremap gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/ " move the current word to the right and keep the cursor on it nnoremap [w "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1//\w\+\_W\+ " move the current word to the left and keep the cursor on it nnoremap ]w "_yiw?\w\+\_W\+\%#:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/ " Replace the current work with the last yanked word; " Save word and exchange it under cursor nnoremap ciy ciw0:let@/=@1:noh nnoremap cy ce0:let@/=@1:noh ""---------------------------------------------------------------------------// " Add Empty space above and below ""---------------------------------------------------------------------------// nnoremap [ :put! =repeat(nr2char(10), v:count1)'[ nnoremap ] :put =repeat(nr2char(10), v:count1) "Use enter to create new lines w/o entering insert mode " nnoremap o nnoremap :call lib#jump() "Below is to fix issues with the ABOVE mappings in quickfix window augroup EnterMapping au! autocmd BufReadPost quickfix nnoremap augroup END ""---------------------------------------------------------------------------// " Make the given command repeatable using repeat.vim command! -nargs=* Repeatable call s:Repeatable() function! s:Repeatable(command) exe a:command call repeat#set(':Repeatable '.a:command."\") endfunction ""---------------------------------------------------------------------------// "Tab completion ""---------------------------------------------------------------------------// inoremap pumvisible() ? "\" : "\" inoremap pumvisible()?"\":"\" " , : close popup and delete backword char. inoremap deoplete#smart_close_popup()."\" " To open a new empty buffer nnoremap n :enew " nnoremap q :bd! " Paste in visual mode multiple times xnoremap p pgvy " search visual selection vnoremap // y/" "Displays the name of the highlight group of the selected word nnoremap E :call SynStack() function! SynStack() if !exists("*synstack") return endif echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') endfunc nnoremap W :%s/\s\+$//:let @/='' " nnoremap empty(&buftype) ? '@@' : '' "Evaluates whether there is a fold on the current line if so unfold it else return a normal space nnoremap @=(foldlevel('.')?'za':"\") ""---------------------------------------------------------------------------// " => Command mode related ""---------------------------------------------------------------------------// " Commands {{{1 command! -bang -range -nargs=1 -complete=file MoveWrite ,write | ,delete _ command! -bang -range -nargs=1 -complete=file MoveAppend ,write >> | ,delete _ " smooth searching cnoremap getcmdtype() == "/" \|\| getcmdtype() == "?" ? "//" : "" cnoremap getcmdtype() == "/" \|\| getcmdtype() == "?" ? "?/" : "" " Smart mappings on the command line cno $d e ~/Desktop/ cmap cwd lcd %:p:h cmap cd. lcd %:p:h cmap w!! w !sudo tee % >/dev/null " insert path of current file into a command cnoremap %% =fnameescape(expand('%')) cnoremap :: =fnameescape(expand('%:p:h'))/ " Loop cnext / cprev / lnext / lprev {{{1 command! Cnext try | cnext | catch | cfirst | catch | endtry command! Cprev try | cprev | catch | clast | catch | endtry command! Lnext try | lnext | catch | lfirst | catch | endtry command! Lprev try | lprev | catch | llast | catch | endtry cabbrev cnext Cnext cabbrev cprev CPrev cabbrev lnext Lnext cabbrev lprev Lprev command! AutoResize call lib#auto_resize() nnoremap ar :AutoResize nnoremap * lib#star_search('*') vnoremap * lib#star_search('*') nno [of lib#open_folds('enable') nno ]of lib#open_folds('disable') nno cof lib#open_folds(open_folds('is_active') ? 'disable' : 'enable') ""---------------------------------------------------------------------------// " => VISUAL MODE RELATED ""---------------------------------------------------------------------------// " Store relative line number jumps in the jumplist. nnoremap j (v:count > 1 ? 'm`' . v:count : '') . 'gj' nnoremap k (v:count > 1 ? 'm`' . v:count : '') . 'gk' " c-a / c-e everywhere - RSI.vim provides these cnoremap cnoremap " Scroll command history cnoremap cnoremap "Save nnoremap :update inoremap s :update "Save all files nnoremap qa :wqa " Quit inoremap :q vnoremap " ---------------------------------------------------------------------------- " Quickfix " ---------------------------------------------------------------------------- nnoremap ]q :cnextzz nnoremap [q :cprevzz nnoremap ]l :lnextzz nnoremap [l :lprevzz " ---------------------------------------------------------------------------- " Tabs " ---------------------------------------------------------------------------- " Tab navigation nnoremap th :tabprev nnoremap tl :tabnext " Useful mappings for managing tabs nnoremap tn :tab split nnoremap to :tabonly nnoremap tc :tabclose nnoremap tm :tabmove " Switch between tabs nnoremap 1 1gt nnoremap 2 2gt nnoremap 3 3gt nnoremap 4 4gt nnoremap 5 5gt nnoremap 6 6gt nnoremap 7 7gt nnoremap 8 8gt nnoremap 9 9gt " ========== Multiple Cursor Replacement ======== " http://www.kevinli.co/posts/2017-01-19-multiple-cursors-in-500-bytes-of-vimscript/ let g:mc = "y/\\V\=escape(@\", '/')\\" nnoremap cn *``cgn nnoremap cN *``cgN vnoremap cn g:mc . "``cgn" vnoremap cN g:mc . "``cgN" function! SetupCR() nnoremap :nnoremap Enter> n@zq:let @z=strpart(@z,0,strlen(@z)-1)n@z endfunction nnoremap cq :call SetupCR()*``qz nnoremap cQ :call SetupCR()#``qz vnoremap cq ":\call SetupCR()\" . "gv" . g:mc . "``qz" vnoremap cQ ":\call SetupCR()\" . "gv" . substitute(g:mc, '/', '?', 'g') . "``qz" " This rewires n and N to do the highlighing... nnoremap n n:call lib#HLNext(0.4) nnoremap N N:call lib#HLNext(0.4) "---------------------------------------------------------------------------- "Buffers "---------------------------------------------------------------------------- nnoremap on :w %bd e# "File completion made a little less painful inoremap f "Tab and Shift + Tab Circular buffer navigation if has('nvim') nnoremap bnext nnoremap bprevious else nnoremap :bnext nnoremap :bprevious endif " Switch between the last two files nnoremap " use ,gf to go to file in a vertical split nnoremap gf :vertical botright wincmd F nnoremap cf :let @*=expand("%:p") " Mnemonic: Copy File path nnoremap yf :let @"=expand("%:p") " Mnemonic: Yank File path " force Vim to always present the relative path - fnamemodify(expand("%"), ":~:.") nnoremap fn :let @"=fnamemodify(expand("%"), ":~:.") " Mnemonic: yank File Name ""---------------------------------------------------------------------------// nnoremap gg "Change operator arguments to a character representing the desired motion nnoremap ; : nnoremap : ; " Allow using alt in macOS without enabling “Use Option as Meta key” nmap ¬ nmap ˙ nmap ∆ nmap ˚ ""---------------------------------------------------------------------------// " Last Inserted ""---------------------------------------------------------------------------// " select last paste in visual mode nnoremap gb '`[' . strpart(getregtype(), 0, 1) . '`]' ""---------------------------------------------------------------------------// " Capitalize ""---------------------------------------------------------------------------// " Capitalize. nnoremap ,U gUiw`] inoremap gUiw`]a ""---------------------------------------------------------------------------// " Insert Mode Bindings ""---------------------------------------------------------------------------// inoremap ddi " ---------------------------------------------------------------------------- " Moving lines " ---------------------------------------------------------------------------- " Move visual block nnoremap ∆ :move+ nnoremap ˚ :move-2 vnoremap ˚ :m '<-2gv=gv vnoremap ∆ :m '>+1gv=gv ""---------------------------------------------------------------------------// " Paragrapgh Wise navigation ""---------------------------------------------------------------------------// " Smart }." nnoremap } :call ForwardParagraph() onoremap } :call ForwardParagraph() xnoremap } :call ForwardParagraph()mzgv`z function! ForwardParagraph() let cnt = v:count ? v:count : 1 let i = 0 while i < cnt if !search('^\s*\n.*\S','W') normal! G$ return endif let i = i + 1 endwhile endfunction " Select block. xnoremap r " Made mappings recursize to work with targets plugin " 'quote' omap aq a' xmap aq a' omap iq i' xmap iq i' " \"double quote" omap ad a" xmap ad a" omap id i" xmap id i" "Change two horizontally split windows to vertical splits nnoremap h t K "Change two vertically split windows to horizontal splits nnoremap v t H "Select txt that has just been read or pasted in nnoremap gV `[V`] " find visually selected text vnoremap * y/" xnoremap * :call lib#search_all()// " make . work with visually selected lines vnoremap . :norm. xnoremap nu :call lib#Numbers() onoremap nu :normal vin "---------------------------------------------------------------------------// " Inner Indent Text Object - Courtesty of http://vim.wikia.com/wiki/Indent_text_object "---------------------------------------------------------------------------// " Changes to allow blank lines in blocks, and " Top level blocks (zero indent) separated by two or more blank lines. " Usage: source in pythonmode and " Press: vai, vii to select outer/inner python blocks by indetation. " Press: vii, yii, dii, cii to select/yank/delete/change an indented block. onoremap ai :call IndTxtObj(0) onoremap ii :call IndTxtObj(1) vnoremap ai :call IndTxtObj(0)gv vnoremap ii :call IndTxtObj(1)gv function! IndTxtObj(inner) let curcol = col(".") let curline = line(".") let lastline = line("$") let i = indent(line(".")) if getline(".") !~ "^\\s*$" let p = line(".") - 1 let pp = line(".") - 2 let nextblank = getline(p) =~ "^\\s*$" let nextnextblank = getline(pp) =~ "^\\s*$" while p > 0 && ((i == 0 && (!nextblank || (pp > 0 && !nextnextblank))) \ || (i > 0 && ((indent(p) >= i && !(nextblank && a:inner)) \ || (nextblank && !a:inner)))) - let p = line(".") - 1 let pp = line(".") - 2 let nextblank = getline(p) =~ "^\\s*$" let nextnextblank = getline(pp) =~ "^\\s*$" endwhile normal! 0V call cursor(curline, curcol) let p = line(".") + 1 let pp = line(".") + 2 let nextblank = getline(p) =~ "^\\s*$" let nextnextblank = getline(pp) =~ "^\\s*$" while p <= lastline && ((i == 0 && (!nextblank || pp < lastline && !nextnextblank)) \ || (i > 0 && ((indent(p) >= i && !(nextblank && a:inner)) \ || (nextblank && !a:inner)))) + let p = line(".") + 1 let pp = line(".") + 2 let nextblank = getline(p) =~ "^\\s*$" let nextnextblank = getline(pp) =~ "^\\s*$" endwhile normal! $ endif endfunction nnoremap :! open % " Remap jumping to the last spot you were editing previously to bk as this is easier form me to remember nnoremap bk `. " Yank from the cursor to the end of the line, to be consistent with C and D. " nnoremap Y y$ ""---------------------------------------------------------------------------// " Quick find/replace ""---------------------------------------------------------------------------// nnoremap [ :%s/\<=expand("")\>/ nnoremap [ :'{,'}s/\<=expand("")\>/ vnoremap [ "zy:%s/"/ ""---------------------------------------------------------------------------// " Find and Replace Using Abolish Plugin %S - Subvert ""---------------------------------------------------------------------------// nnoremap { :%S///c vnoremap { "zy:%S/"//c " Visual shifting (does not exit Visual mode) vnoremap < >gv "Remap back tick for jumping to marks more quickly back nnoremap ' ` nnoremap ` ' ""---------------------------------------------------------------------------// "Sort a visual selection vnoremap s :sort "open a new file in the same directory nnoremap nf :e =expand("%:p:h") . "/" "Open command line window nnoremap C : nnoremap l :nohlsearch:diffupdate:syntax sync fromstart ""---------------------------------------------------------------------------// " Window resizing bindings ""---------------------------------------------------------------------------// "Create a horizontal split nnoremap - :sp "Create a vertical split nnoremap \| :vsp " Resize window vertically - shrink nnoremap 15- " Resize window vertically - grow nnoremap 15+ " Increase window size horizontally nnoremap 15> " Decrease window size horizontally nnoremap 15< "Normalize all split sizes, which is very handy when resizing terminal nnoremap = = "Close every window in the current tabview but the current one nnoremap q o "Swap top/bottom or left/right split nnoremap sw R ""---------------------------------------------------------------------------// "Open Common files ""---------------------------------------------------------------------------// nnoremap a :argadd =fnameescape(expand('%:p:h'))/* nnoremap ez :e ~/.zshrc nnoremap et :e ~/.tmux.conf "close loclist or qflist nnoremap x :cclose lclose "Indent a page nnoremap f gg=G inoremap inoremap inoremap inoremap " Repeat last substitute with flags nnoremap & :&& xnoremap & :&& ""---------------------------------------------------------------------------// " Insert & Commandline mode Paste ""---------------------------------------------------------------------------// inoremap pa cnoremap " " ---------------------------------------------------------------------------- "Credit: JGunn :Count " ---------------------------------------------------------------------------- command! -nargs=1 Count execute printf('%%s/%s//gn', escape(, '/')) | normal! `` " ---------------------------------------------------------------------------- " Todo - Check the repo for Todos and add to the qf list " ---------------------------------------------------------------------------- command! Todo noautocmd vimgrep /TODO\|FIXME/j ** | cw " ---------------------------------------------------------------------------- " Open FILENAME:LINE:COL " ---------------------------------------------------------------------------- function! s:goto_line() let tokens = split(expand('%'), ':') if len(tokens) <= 1 || !filereadable(tokens[0]) return endif let file = tokens[0] let rest = map(tokens[1:], 'str2nr(v:val)') let line = get(rest, 0, 1) let col = get(rest, 1, 1) bd! silent execute 'e' file execute printf('normal! %dG%d|', line, col) endfunction augroup GoToLine autocmd! BufRead * nested call s:goto_line() augroup END " ---------------------------------------------------------------------------- " Credit: June Gunn ?/! | Google it / Feeling lucky " ---------------------------------------------------------------------------- function! s:goog(pat, lucky) let q = '"'.substitute(a:pat, '["\n]', ' ', 'g').'"' let q = substitute(q, '[[:punct:] ]', \ '\=printf("%%%02X", char2nr(submatch(0)))', 'g') call system(printf('open "https://www.google.com/search?%sq=%s"', \ a:lucky ? 'btnI&' : '', q)) endfunction nnoremap ? :call goog(expand(""), 0) nnoremap ! :call goog(expand(""), 1) xnoremap ? "gy:call goog(@g, 0)gv xnoremap ! "gy:call goog(@g, 1)gv " ---------------------------------------------------------------------------- " Credit: June Gunn == ConnectChrome " ---------------------------------------------------------------------------- if has('mac') function! s:connect_chrome(bang) augroup connect-chrome autocmd! if !a:bang autocmd BufWritePost call system(join([ \ "osascript -e 'tell application \"Google Chrome\"". \ "to tell the active tab of its first window\n", \ " reload", \ "end tell'"], "\n")) endif augroup END endfunction command! -bang ConnectChrome call s:connect_chrome(0) endif " ---------------------------------------------------------------------------- " ?ie | entire object " ---------------------------------------------------------------------------- xnoremap ie gg0oG$ onoremap ie :execute "normal! m`"keepjumps normal! ggVG ""---------------------------------------------------------------------------// " Navigation (CORE) ""---------------------------------------------------------------------------// nnoremap 0 ^ " jk is escape, THEN move to the right to preserve the cursor position, unless " at the first column. will continue to work the default way. inoremap jk col('.') == 1 ? '' : 'l' imap JK jk imap Jk jk xnoremap jk cnoremap jk " Note: These mappings MUST be recursive i.e. `nmap` since `j` and `k` are mapped to be added to the " jump list aka this recursively calls the mappings for j and k making sure these movements " are added nmap J 10j nmap K 10k " Toggle top/center/bottom noremap zz (winline() == (winheight(0)+1)/ 2) ? 'zt' : (winline() == 1)? 'zb' : 'zz' "This line opens the vimrc in a vertical split nnoremap ev :vsplit $MYVIMRC nnoremap ev :tabnew $MYVIMRC command! Vimrc :e $MYVIMRC "This line allows the current file to source the vimrc allowing me use bindings as they're added nnoremap sv :source $MYVIMRC " Surround word with quotes or braces nnoremap " viwa"bi"lel nnoremap ' viwa'bi'lel nnoremap ( viwa)bi(lel nnoremap ) viwa)bi(lel nnoremap { viwa}bi{lel nnoremap } viwa}bi{lel " To the leftmost non-blank character of the current line nnoremap H g^ " To the rightmost character of the current line nnoremap L g$ nnoremap ll :vertical resize +10 nnoremap hh :vertical resize -10 nnoremap jj :res +10 nnoremap kk :res -10 " source : https://blog.petrzemek.net/2016/04/06/things-about-vim-i-wish-i-knew-earlier/ "Move to beginning of a line in insert mode inoremap 0 inoremap $ " Quick macro invocation with q register nnoremap q @q "Map Q to remove a CR nnoremap Q J "Replace word under cursor nnoremap S "_diwP "}}} " Shortcut to jump to next conflict marker" nnoremap co /^\(<\\|=\\|>\)\{7\}\([^=].\+\)\?$ " Zoom - This function uses a tab to zoom the current split nnoremap z :call lib#tab_zoom() " Zoom / Restore window. - Zooms by increasing window with smooshing the " Other window nnoremap z :call lib#buf_zoom() command! PU PlugUpdate | PlugUpgrade command! -nargs=0 Reg call lib#reg() nnoremap r :Reg ""---------------------------------------------------------------------------// " Map key to toggle opt ""---------------------------------------------------------------------------// function! MapToggle(key, opt) let cmd = ':set '.a:opt.'! \| set '.a:opt."?\" exec 'nnoremap '.a:key.' '.cmd exec 'inoremap '.a:key." \".cmd endfunction command! -nargs=+ MapToggle call MapToggle() ""---------------------------------------------------------------------------// " Display-altering option toggles ""---------------------------------------------------------------------------// MapToggle wrap MapToggle list ""---------------------------------------------------------------------------// " Behavior-altering option toggles ""---------------------------------------------------------------------------// MapToggle scrollbind set pastetoggle= fu! ToggleColorColumn() if &colorcolumn set colorcolumn="" else set colorcolumn=80 endif endfunction nnoremap :call ToggleColorColumn() "Re-indent pasted text nnoremap p p=`] nnoremap P P=`] " ---------------------------------------------------------------------------- " Profile " ---------------------------------------------------------------------------- function! s:profile(bang) if a:bang profile pause noautocmd qall else profile start /tmp/profile.log profile func * profile file * endif endfunction command! -bang Profile call s:profile(0) ""---------------------------------------------------------------------------// " GREPPING ""---------------------------------------------------------------------------// nnoremap g* :silent! :grep! -w " Show last search in quickfix - http://travisjeffery.com/b/2011/10/m-x-occur-for-vim/ nnoremap gl/ :vimgrep ///j %\|:cw nnoremap g/ :silent! :grep! " cnoremap lib#CCR() " Conditionally modify character at end of line nnoremap , :call lib#ModifyLineEndDelimiter(',') nnoremap ; :call lib#ModifyLineEndDelimiter(';')