" Description: vim keymap " Last Modified: 27 April 2016 " !::exe [So] " Recent mappings: " xmap sr (Visual-Split-VSResize) xmap ss (Visual-Split-VSSplit) xmap sk (Visual-Split-VSSplitAbove) xmap sj (Visual-Split-VSSplitBelow) nnoremap . :Clap blines nnoremap :Clap grep "=============================================================================== " Major maps {{{1 let mapleader = "\" " nnoremap ( \ exists('b:esc') ? b:esc : \ coc#float#has_float() ? (coc#float#close_all() . '')[1] : \ ':nohl' ) " "cnoremap g:space.parse_cmd_line() " V cycles visual modes nnoremap v v xnoremap v \ (mode() ==# 'v' ? "\" \ : mode() ==# 'V' ? 'v' : 'V') nnoremap Y y$ " nnoremap u u " nnoremap U nmap . (RepeatDot) " nmap u (RepeatUndo) nnoremap u u nnoremap U nmap (ignore-1) (RepeatDot) nmap (ignore-2) (RepeatUndo) nmap (ignore-3) (RepeatRedo) nmap (ignore-4) (RepeatUndoLine) " YankRing "if exists('*miniyank#on_yank') nmap p (miniyank-autoput) nmap P (miniyank-autoPut) nmap (miniyank-cycle) "end " G-commands: "nnoremap gp P`[ "nnoremap gp m`p`` "nnoremap gP m`P`` " Re-select last pasted text nnoremap gb '`[' . strpart(getregtype(), 0, 1) . '`]' nnoremap ge gel onoremap ge :normal! hvgel " go-lower/go-upper nnoremap gl gu nnoremap gu gU nnoremap gU ~ xnoremap gl gu xnoremap gu gU xnoremap gU ~ " go-replace nnoremap gR xnoremap rgR " Next/Previous Tab nnoremap g[ gT nnoremap g] gt " Open nnoremap go :OpenURLOrSearch xnoremap go y:OpenURLOrSearch " " Insert newline nnoremap o nnoremap O nnoremap g occ " Don't leave spaces when doing i, then nnoremap i empty(substitute(getline('.'), '^\s\+', '', '')) ? 'cc' : 'i' " Split line (as opposed to J) nnoremap i:silent -DeleteTrailingWS " Alt-M start MultiCursor-mode nnoremap viw:MultipleCursorsFind vnoremap :call multiple_cursors#new('v', 0) "vnoremap "\ visualmode() ==# 'V' "\ ? ":'<,'>MultipleCursorsFind \\S\\+ " "\ : ":call multiple_cursors#new('v', 0) " " Remove things we don't use vmap vmap " }}}1 "=============================================================================== " Semicolon quick commands {{{1 " Semicolon key nmap ; quick_cmd() imap ;w ;w let s:quick_cmd_map = { \ 'w': ":w\", \ "\": ':Files ', \ "\": 'q:":P', \} function! s:quick_cmd () if sneak#is_sneaking() return ":call sneak#rpt('', 0)\" end echo '' let char = GetChar('Info', ':') let qmap = get(s:quick_cmd_map, char, ':' . char) if !empty(qmap) return qmap else return ':' . char end endfunc " }}}1 "=============================================================================== " RC & Setup quick access {{{1 " @configuration " Local config nmap gslc :Edit .vimrc nmap gsln :execute 'Note ' . GetCurrentSession() " Files nnoremap gsrc :Edit $MYVIMRC nnoremap gsro :Edit $vim/coc-settings.json nnoremap gsm :Edit $vim/rc/keymap.vim nnoremap gsko :Edit $vim/plugin/options.vim nnoremap gsa :Edit $vim/rc/autocmd.vim nnoremap gse :Edit $vim/rc/events.vim nnoremap gsf :Edit $vim/rc/function.vim nnoremap gsd :Edit $vim/rc/commands.vim nnoremap gsc :Edit $vim/rc/colors.vim nnoremap gsh :Edit $vim/rc/highlight.vim nnoremap gso :Edit $vim/rc/settings.vim nnoremap gsjg :Edit $HOME/src/github-light.vim/colors/github-light.vim nnoremap gsjd :Edit $HOME/src/doom-one.vim/colors/doom-one.vim nnoremap gsp :Edit $vim/rc/plugins.vim nnoremap gsP :Clap files $vim/rc/plugins/ nnoremap gsv :Clap files $vim " New... nnoremap :UltiSnipsEdit nnoremap :EditFtplugin nnoremap :EditFtsyntax " Edit runtime syntax file nnoremap :EditSyntax " Notefile nnoremap :Edit $vim/plugin/notes.vim nnoremap :Note vim " }}}1 "=============================================================================== " Jumps & cursor movement {{{1 " j/k screen rows nnoremap j gj nnoremap k gk xnoremap j gj xnoremap k gk " SoL-EoL motion noremap $l noremap \ (col('.') - 1) && match(getline('.'),'\S') >= col('.') - 1 \ ? '0' : '^' xnoremap endOfLine() fu! s:endOfLine() if (visualmode() ==# "\") return '$' end if (&ve=~#'onemore' || &ve==#'all') return '$h' end return '$' endfu " wide move noremap 5 noremap 5 nnoremap 5gj nnoremap 5gk vnoremap 5gj vnoremap 5gk " scroll up/down nmap 12 nmap 12 vmap 12 vmap 12 " WORD moves nnoremap B nnoremap El onoremap B onoremap E xnoremap B xnoremap E " Column-edge nmap ColumnMoveDown nmap ColumnMoveUp vmap ColumnMoveDown vmap ColumnMoveUp nmap ColumnMoveDown nmap ColumnMoveUp vmap ColumnMoveDown vmap ColumnMoveUp " Jumps: nnoremap H zz nnoremap L zz " no noremap: remapped to matchit nmap % vmap % omap % " Character-wise jumps always nnoremap ' ` vnoremap ' ` nnoremap '' `' vnoremap '' `' nnoremap } } nnoremap { { " Close any preview window then jump nnoremap z " CamelCase motion " map: w, b, nmap: e, ge {{{ nmap w CamelCaseMotion_w nmap b CamelCaseMotion_b nmap e CamelCaseMotion_e xmap w CamelCaseMotion_w xmap b CamelCaseMotion_b xmap e CamelCaseMotion_e xmap ge CamelCaseMotion_ge omap w searchpos('\%#\s', '')[1] ? \ 'CamelCaseMotion_w' : 'CamelCaseMotion_e' omap CamelCaseMotion_e xmap b CamelCaseMotion_b xnoremap iw iw " }}} " GitGutter hunks nnoremap [h :GitGutterPrevHunkzvzz nnoremap ]h :GitGutterNextHunkzvzz " Git conflicts nnoremap ]c /^<<<:set nohls nnoremap [c ?^<<<:set nohls " QF window nnoremap ]q :cnext nnoremap [q :cprevious nnoremap ]l :lnext nnoremap [l :lprevious " 1}}} "=============================================================================== " Sneak {{{1 nmap Sneak_S nmap Sneak_s nmap gk Sneak_S nmap gj Sneak_s xmap ; SneakNext xmap SneakPrevious nmap sneak#is_sneaking() ? (sneak#state().reverse==1 \ ? "Sneak_s" \ : "Sneak_S") \ : "SneakNext" " find operator nmap f Sneak_f xmap f Sneak_f omap f Sneak_f nmap Sneak_F xmap Sneak_F omap Sneak_F nmap F Sneak_F xmap F Sneak_F omap F Sneak_F " until operator nmap t Sneak_t nmap T Sneak_T xmap u Sneak_t xmap U Sneak_T omap u Sneak_t omap U Sneak_T " 1}}} "=============================================================================== " Intellisense (coc.nvim) {{{1 nmap coc :Clap coc_commands nmap :call CocAction('rename') " xmap gme :execute 'CocCommand actions.open ' . visualmode() " nmap gme :CocCommand actions.open " Coc Diagnostics nnoremap [d (coc-diagnostic-previous) nnoremap ]d (coc-diagnostic-next) nnoremap [e (coc-diagnostic-previous-error) nnoremap ]e (coc-diagnostic-next-error) " Remap keys for gotos nmap gd (coc-definition)zz nmap gy (coc-type-definition)zz nmap gD (coc-implementation)zz nmap gR (coc-references) nmap g (coc-references-used) " Use K for show documentation in preview window nnoremap K :call show_documentation() inoremap :call coc#float#jump() inoremap :call coc#float#scroll(-1) inoremap :call coc#float#scroll(+1) function! s:show_documentation() if &filetype == 'vim' execute 'h '.expand('') return end if !empty(win#filter('getwinvar(v:val, "float")')) call coc#float#jump() call s:coc_popup_mappings() else call CocAction('doHover') end endfunction function! s:coc_popup_mappings () nnoremap :call coc#float#close_all() endfunc " Remap for rename current word nmap (coc-rename) " Remap for format selected region vmap gq (coc-format-selected) augroup CocEvents autocmd! " Setup formatexpr specified filetype(s). autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') " Update signature help on jump placeholder autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') augroup end " Remap for do codeAction of selected region, ex: `aap` for current paragraph " vmap a (coc-codeaction-selected) nmap a (coc-codeaction-selected) " Remap for do codeAction of current line nmap ac (coc-codeaction) " Fix autofix problem of current line nmap qf (coc-fix-current) " 1}}} "=============================================================================== " Commands & Space maps @space {{{1 nnoremap :NeomakeSh make build nmap j Sneak_s nmap k Sneak_S " OptionsWidget: nnoremap op :OptionsWidget nunmap ac nunmap a "=============================================================================== " File management nnoremap fr :Rename " Session management: nnoremap ss xolox#session#find_current_session() != 'default' ? \ ":wall! \ SaveSession\\" : ":wall! \ SaveSession\" nnoremap sS :SaveSession! nnoremap so :Clap session nnoremap sd :OpenSession! default nnoremap sc :wall! CloseSession nnoremap si :wall! CloseSession OpenSession! nnoremap sl :SourceLocalVimrc nnoremap sn :Note =xolox#session#find_current_session() nnoremap np :NewProject " Notes: nnoremap no :Clap note " Git: nnoremap gg :tabedit %:Gito nnoremap gaa :Git add --all nnoremap ga. :Git add % nnoremap gcm :Git commit -m "" nnoremap gcam :Git commit -am "" nnoremap gcaa :Git commit --amend nnoremap g. :Git commit % -m "" nnoremap gk :Git checkout nnoremap gK :Git checkout -b nnoremap gb :Clap git_branch nnoremap gl :Git pull nnoremap gp :EchoHL ErrorMsg Remaped to SPC g p p nnoremap gpp :Git push nnoremap gpf :Git push --force nnoremap gpu :Git push -u origin =trim(system('git rev-parse --abbrev-ref HEAD')) nnoremap gs :Gstatus nnoremap gu :GitOpenUnmergedFiles nnoremap gdo :DiffviewOpen nnoremap gda :GitDiff nnoremap gd. :GitDiff % nnoremap gdd :GitDiff nnoremap gr. :Git restore % nnoremap grA :Git restore . " GitMessenger: nnoremap gm :GitMessenger " GitGutter: nnoremap hh :GitGutter nnoremap hs :GitGutterStageHunk nnoremap hv :GitGutterPreviewHunk nnoremap hu :GitGutterUndoHunk " Open in Github: nnoremap gh :GH "=============================================================================== " Ack, Ag, Grep & File Searching " Files: nnoremap md :Mkdir! nnoremap mv :Move d/ nnoremap rn :Rename " Search: nnoremap rg :Rg nnoremap rw :Rg " nnoremap ag XXX implement search " nnoremap aa XXX implement search "=============================================================================== " Window things nnoremap ww :InteractiveWindow nnoremap w- :call SizeDown() nnoremap w+ :call SizeUp() "=============================================================================== " Various: nnoremap mp :MarkdownPreview nnoremap mP :MarkdownPreviewStop nnoremap cp :VCoolor nnoremap c- '"_ciw' . color#Darken(expand('')) . "\" nnoremap c= '"_ciw' . color#Lighten(expand('')) . "\" nnoremap gf :NERDTreeFind nnoremap ap vip:EasyAlign nnoremap ret :set et ret nnoremap dws :%DeleteTrailingWS nnoremap how :r !hors -e google --raw nnoremap syv :SynStack nnoremap sye :SynCurrentEdit nnoremap ti :Todoist nnoremap to :Clap todoist nnoremap td :TodoQuickFix nnoremap npm :Clap npm nnoremap qr :e! nnoremap qo expand('%:e') == 'vim' ? ':So' : ':luafile %' nmap qw :w nnoremap up :PlugUpdate CocUpdate nnoremap hh :Clap help_tags " Multi-Cursors: " (see: ./plugins/multiple-cursors.vim) nnoremap mw :.,.MultipleCursorsFind \S\+o nnoremap mW :.,.MultipleCursorsFind \w\+ nnoremap mf :MultipleCursorsFind " }}}1 "=============================================================================== " Panels, File navigation & Clap {{{1 nnoremap :TreeToggle nnoremap :NERDTreeFind nnoremap :TagbarToggle nnoremap :call ToggleWindows() nnoremap :Clap files =getcwd() nnoremap :Clap filer =escape(expand("%:p:h"), ' ') nnoremap :Clap recent_files " nnoremap :Clap buffers nnoremap :Clap tags " nnoremap :Clap generated_tags " nnoremap :Clap tagfiles nnoremap :Clap coc_symbols nnoremap :Clap command " Clap input " see ../syntax/clap_input.vim " }}}1 "=============================================================================== " Window & Tabs navigation {{{1 " @windows " Cycle between editor Windows nnoremap :GoNextListedWindow " Windows actions nnoremap v vl nnoremap s sj nnoremap ; :split terminal nnoremap : :vsplit terminal nnoremap :tabedit term://bin/zsh nnoremap y :WindowYank nnoremap g :WindowPaste nnoremap :WindowCopyView nnoremap \ :WindowFitText nnoremap q :BufferClose! wincmd c nnoremap :tabedit =bufname() " Terminal navigation mappings down here. }}}1 "=============================================================================== " Terminal @term {{{1 if has('nvim') " Panels/Navigation nnoremap g: :GoFirstTerminalWindow nnoremap g :OpenTerminalHere " nnoremap g :GoFirstTerminalWindow nnoremap :ToggleTerminalWindow nnoremap :wincmd s \| NextTerminalBuffer tnoremap w tmap :PreviousTerminalBuffer tmap :NextTerminalBuffer tmap :bp tmap :bn tnoremap " Paste tnoremap pi " Close tnoremap :bd! tnoremap tnoremap gt tnoremap " Navigation tnoremap ; : tnoremap ; tnoremap tnoremap w tmap " Arrows tnoremap j tnoremap k tnoremap h tnoremap l tnoremap ; end "of has('nvim') }}}1 "=============================================================================== " Buffer navigation {{{1 nnoremap :BufferPrevious nnoremap :BufferNext nnoremap :BufferMovePrevious nnoremap > :BufferMoveNext nnoremap :BufferGoto 1 nnoremap :BufferGoto 2 nnoremap :BufferGoto 3 nnoremap :BufferGoto 4 nnoremap :BufferGoto 5 nnoremap :BufferGoto 6 nnoremap :BufferGoto 7 nnoremap :BufferGoto 8 nnoremap :BufferLast nnoremap :BufferClose! nnoremap :BufferReopen nnoremap :BufferPick nnoremap bd :BufferOrderByDirectory nnoremap bl :BufferOrderByLanguage if exists('g:gui_oni') nnoremap :tabprev nnoremap :tabnext nnoremap :tabclose end if exists('g:fvim_loaded') nnoremap :BufferNext nnoremap :BufferPrevious end " }}}1 "=============================================================================== " Text manipulation {{{1 " Increase/decrease nmap - (CtrlXA-CtrlX) nmap _ (CtrlXA-CtrlA) nmap + (CtrlXA-CtrlA) nmap = (CtrlXA-CtrlA) " Exchange line x-up/down nnoremap j 'ddp' . col('.') . '' nnoremap k 'ddkP' . col('.') . '' " Exchange args left/right nnoremap h :SidewaysLeft nnoremap l :SidewaysRight " Yank & Paste * (yank-up, yank-down) nnoremap yu yyP nnoremap yd yyp " Indent nnoremap > V> nnoremap < V< vnoremap > >gv vnoremap < g< vii< nmap g> vii> " Targets: " b(), k{}, r[] {{{ let pairs = 'b()k{}r[]a<>' " self-added to local surround/ let targets_pairs = '()b {}k []r <>' let targets_quotes = '"d ''q `' let targets_separators = ', . ; : + - = ~ _ * # / | \ & $' let targets_tagTrigger = 't' let targets_argTrigger = 'a' let targets_argSeparator = ',' let targets_argOpening = '[({[]' let targets_argClosing = '[]})]' let targets_aiAI = 'aIAi' let targets_nlNL = 'npNF' let targets_seekRanges = \ 'cr cb cB lc ac Ac lr lb rr rb bb ll al aa ar ab' " Default "cr cb cB lc ac Ac lr rr ll lb ar ab lB Ar aB Ab" " "AB rb al rB Al bb aa bB Aa BB AA" "}}} " Surround: operator " + ysf, csf, dsf, cs', ds' {{{ " hack nmap csk csB nmap dsk dsB nmap dsq ds' nmap dsd ds" nmap Ysurround vmap VSurround " delete/change/surround func-call: (ysf) let surround_{char2nr("f")} = "\1func: \1(\r)" " }}} " Functioncall: Text-Object {{{ " change inside/all current/last/next fcall " function definitions & search patterns TODO move to autoload " function-call patterns let name_pattern = '\(\k\|\i\|\f\|<\|>\|:\|\\\)\+' let args_pattern = '\(\\)\|[^)]\)*' let fcall_pattern = name_pattern . '\s*\ze(' let fargs_pattern = name_pattern . '\s*(\zs' . args_pattern . '\ze\s*)' let func_pattern = name_pattern . '\s*(' . args_pattern . '\s*)' " Param {String} flags - same as search() (see vim help), " plus 'v' - visually select the function " Returns the [lnum, col] of the nearest function function! s:findFunc (flags, ...) let fc = a:flags =~# 'c' ? 'c' : '' let fb = a:flags =~# 'b' ? 'b' : '' let fn = a:flags =~# 'n' ? 'n' : '' let visual = a:flags =~# 'v' ? 1 : 0 let pattern = '\(\k\|\i\|\f\|<\|>\|:\|\\\)\+\s*\ze(' if (len(a:000) == 1) let pattern = a:000[0] | end if (visual) let start = searchpos(pattern, fc . fb) normal! v let end = searchpos(pattern, 'ce') return [ start, end ] else return searchpos(pattern, fc . fb . fn) end endfu fu! s:visualFunc(...) let which = get(a:, 1, 'c') let pattern = g:fcall_pattern " inside ... if which =~ 'i' let pattern = g:fargs_pattern | end " all ... if which =~ 'a' let pattern = g:func_pattern | end " Current if which =~ 'c' call s:findFunc ('vbc', pattern) | end " Next if which =~ 'n' call s:findFunc ('v', pattern) | end " Last if which =~ 'l' call s:findFunc ('vb', pattern) | end return endfu fu! s:changeFunc(...) let which = get(a:, 1, 'c') let pattern = g:fcall_pattern " inside ... if which =~ 'i' let pattern = g:fargs_pattern | end " all ... if which =~ 'a' let pattern = g:func_pattern | end " Current if which =~ 'c' call s:findFunc ('vbc', pattern) call feedkeys('c', '') | end " Next if which =~ 'n' call s:findFunc ('v', pattern) call feedkeys('c', '') | end " Last if which =~ 'l' call s:findFunc ('vb', pattern) call feedkeys('c', '') | end return '' endfu fu! s:deleteSurroundingFunc(flags) call s:findFunc(a:flags) normal ddsb endfu fu! s:changeSurroundingFunc () let saved_cursor = getcurpos() call s:findFunc ('vbc') | redraw let char = GetChar('Question', 'Change surrounding func with: ') if char != "\" call feedkeys('dcsb' . char, '') else Reset saved_cursor end endfu nmap cif :call changeFunc('c') nmap cIf :call changeFunc('ic') nmap caf :call changeFunc('ac') nmap cnf :call changeFunc('n') nmap cpf :call changeFunc('l') " nmap cinf :call changeFunc('in') " nmap cilf :call changeFunc('il') " nmap canf :call changeFunc('an') " nmap calf :call changeFunc('al') nmap dsf :call deleteSurroundingFunc('vbc') nmap dsF :call deleteSurroundingFunc('vb') nmap ds :call deleteSurroundingFunc('vb') nmap csf :call changeSurroundingFunc() " }}} " FindQuote: " mappings: {{{ " cs'' toggles surrounding quotes " ds' deletes surrounding quotes " f' is equivalent to f' and/or f" fu! s:findQuote(...) " ( forward=1, action='m' ) " action: m -> move cursor " p -> returns the character position [line, col] " c -> returns the matched character (' or ") if (a:0 > 0) && (a:1==1 || a:1==0) let dir = a:1 let which = (a:0 > 1 ? a:2 : 'm') let fb = (dir) ? '' : 'b' if which =~ 'm' call searchpos('\v["'']', fb) return | end if which =~ 'p' let pos = searchpos('\v["'']', fb . 'n') return pos | end if which =~ 'c' let pos = searchpos('\v["'']', fb . 'nc') let ch = CharAt( [pos[0], pos[1]-1] ) return ch | end return end let flags = a:0 ? a:1 : 'nc' let cw = getcurpos()[1:2] let fw = searchpos('\v["'']', flags) let fw[1] -= 1 let bw = searchpos('\v["'']', 'b' . flags) let bw[1] -= 1 if fw == cw let pos = fw else let df = (fw[0] - cw[0]) * 80 + (fw[1] - cw[1]) let db = (cw[0] - bw[0]) * 80 + (cw[1] - bw[1]) let pos = df < db ? fw : bw end return CharAt(pos) endfu fu! s:changeSurroundingQuotes() let qch = s:findQuote() let char = GetChar('Question', 'Change surrounding quotes with: ') if char == "'" let char = (qch ==# "\"" ? "'" : "\"") | end return "\Csurround" . qch . char endfu fu! s:deleteSurroundingQuotes() return "\Dsurround" . s:findQuote() endfu nmap f' "Sneak_f" . findQuote(1, 'c') nmap F' "Sneak_F" . findQuote(0, 'c') " delete/change surrounding quotes nmap cs' changeSurroundingQuotes() nmap ds' deleteSurroundingQuotes() " }}} " Substitute: operator (replace.vim) " normal: s,ss,S visual: s {{{ " unlet! m nmap s ReplaceOperator nmap ss Vs nmap S s$ xmap s ReplaceOperator " TODO assess usage nmap X ExchangeOperator vmap X ExchangeOperator " }}} " EasyAlign: " mappings: ga, {{{ " General nmap (EasyAlign) vmap (EasyAlign) xmap g (EasyAlign) nmap (EasyAlign)ip1 xmap ""(EasyAlign)ip1.\{-}\zs\s*\ze" " align semicolon nnoremap vip:EasyAlign *: xnoremap :EasyAlign *: " align bar nnoremap vip:EasyAlign * xnoremap :EasyAlign * " align equal nnoremap vip:EasyAlign *= xnoremap :EasyAlign *= nnoremap vip:EasyAlign *= xnoremap :EasyAlign *= nnoremap = vip:EasyAlign *= xnoremap = :EasyAlign *= " align word nnoremap vip:EasyAlign *\ xnoremap :EasyAlign *\ nnoremap w vip:EasyAlign *\ xnoremap w :EasyAlign *\ nnoremap vip:EasyAlign *\ xnoremap :EasyAlign *\ nnoremap vip:EasyAlign *\ xnoremap :EasyAlign *\ " align Last-Word nnoremap - vip:EasyAlign - xnoremap - :EasyAlign - " align commas nnoremap vip:EasyAlign *, xnoremap :EasyAlign *, nnoremap , vip:EasyAlign *, xnoremap , :EasyAlign *, " EasyAlign }}} " SplitJoin: " overrides 's' operator {{{ nmap sj :SplitjoinJoin nmap sk :SplitjoinSplit " }}} " Comment: " alt-' & alt-" {{{ nmap NERDCommenterToggle vmap NERDCommenterSexy " }}} " StringTransform: " Change Case {{{ nmap ccc (camel_case_operator) nmap ccC (upper_camel_case_operator) nmap cc_ (snake_case_operator) nmap cc- (kebab_case_operator) nmap ccs (start_case_operator) " xmap ccc (camel_case_operator) " xmap ccC (upper_camel_case_operator) " xmap cc_ (snake_case_operator) " xmap cc- (kebab_case_operator) " xmap ccs (start_case_operator) "}}} " }}}1 "=============================================================================== " Search & replace {{{1 " Search nnoremap g/ *zvzz nnoremap g? #zvzz " nnoremap g/ " nnoremap g? " IncSearch nmap / (incsearch-forward) nmap ? (incsearch-backward) nmap n (incsearch-nohl-n)zvzz nmap N (incsearch-nohl-N)zvzz nmap * (incsearch-nohl-*) nmap # (incsearch-nohl-#) " Yank selected text as an escaped search-pattern map (visual-yank-plaintext) \ :call setreg(v:register, '\C\V'.escape(visual#GetText(), '\/')) vmap "/(visual-yank-plaintext):set hlsearch vmap g/ "/(visual-yank-plaintext)n vmap g? "/(visual-yank-plaintext)N nmap g\ incsearch#go(incsearch_config()) function! s:incsearch_config() abort return {'converters': [{val -> '\V' . escape(val, '/\')}]} endfunction " Text Replace TODO implement a real replace-mode nnoremap r & nnoremap g& nmap :s/// nmap :%s/// nmap a :%s/// nmap :.,$s/// nmap j :.,$s/// nmap viw nmap w viw nmap m'viw'' xmap :s/// xmap r :s/// xmap xmap " SearchReplace nnoremap :Search nnoremap "cyiw:Search \bc\b nnoremap w "cyiw:Search \bc\b " }}}1 "=============================================================================== " Macro & Automation {{{1 " Replay macro nnoremap @q " Replay macro (visual) xnoremap @ :normal @q " Execute the next macro with current visual-range vnoremap q :call VisualRecord() function! VisualRecord () range " {{{ if exists('a:firstline') let g:range = [a:firstline, a:lastline] else let g:range = [getpos("'<")[1], getpos("'>")[1]] end noremap q :call VisualExecute() noremap :call VisualStop() call cursor(g:range[0], 1) normal! qv endfu function! VisualStop() normal! q let g:macro=getreg('v', 1) unmap q unmap endfu function! VisualExecute () call VisualStop() let g:macro = substitute(g:macro, 'q$', '', '') Pp g:range, g:macro "if empty(g:macro) | return | end for lnum in range(g:range[0]+1, g:range[1]) call cursor(lnum, 1) echom lnum . '/' . line('.') call feedkeys(g:macro, '') "exe g:range[0] . ',' g:range[1] . 'normal ' . g:macro endfor endfu " }}}1 "=============================================================================== " Debugger {{{1 nnoremap lua require'dap'.continue() nnoremap g lua require'dap'.run_to_cursor() nnoremap lua require'dap'.close() nnoremap lua require'dapui'.close() nnoremap lua require'dap'.step_over() nnoremap lua require'dap'.step_into() nnoremap lua require'dap'.step_out() nnoremap lua require'dap'.toggle_breakpoint() nnoremap lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: ')) nnoremap lua require'dap'.set_breakpoint(nil, nil, vim.fn.input('Log point message: ')) nnoremap lua require('dapui').eval() " nnoremap :lua require'dap'.continue() " nnoremap :lua require'dap'.step_over() " nnoremap :lua require'dap'.step_into() " nnoremap :lua require'dap'.step_out() " nnoremap b :lua require'dap'.toggle_breakpoint() " nnoremap B :lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: ')) " nnoremap lp :lua require'dap'.set_breakpoint(nil, nil, vim.fn.input('Log point message: ')) " nnoremap dr :lua require'dap'.repl.open() " nnoremap dl :lua require'dap'.run_last() " }}}1 "=============================================================================== " Quick Utils {{{1 " @utils " Foldmethod nmap z;m :setlocal fdm=marker nmap z;s :setlocal fdm=syntax nmap z;i :setlocal fdm=indent nmap z;I :setlocal fdm=expr:setlocal foldexpr=GetIndentFold(v:lnum) nmap z;e :setlocal fdm=expr nmap z;E :setlocal fdm=expr:setlocal foldexpr= nmap z;t :setlocal fdm=expr:setlocal foldexpr=nvim_treesitter#foldexpr() " Surround line with { and } nnoremap g{ m`o}kkA{`` nnoremap g, m`A,`` " Yank all nnoremap gya :%y+ nnoremap dya ggdG " Exchange lhs-rhs nmap gx= vihgxvilgx " File Explorer if has('win32') nnoremap :silent !explorer . else nnoremap :!nautilus . & end nnoremap :e! " Insert word of the line above inoremap :let @z = @"mz \:exec 'normal!' (col('.')==1 && col('$')==1 ? 'k' : 'kl') \:exec (col('.')==col('$') - 1 ? 'let @" = @_' : 'normal! yw') \`zp:let @" = @za " Copy current file path nmap ycf :let @+=expand("%:~") call Warn('Yanked: ' . @+) nmap ycd :let @+=expand("%:h") call Warn('Yanked: ' . @+) nmap ycF :let @+=expand("%:p") call Warn('Yanked: ' . @+) nmap ycD :let @+=expand("%:p:h") call Warn('Yanked: ' . @+) " Gtfo nnoremap ZZ :wqall! " }}}1 "=============================================================================== " Operator-pending maps {{{1 " for lazyness onoremap l $ onoremap h ^ " Paragraph: operator " all paragraph onoremap ap " in paragraph xnoremap ip " Remaps to targets omap ' i' omap " i" omap id i" omap iq i' omap ik i{ omap ir i[ omap ad a" omap aq a' omap ak a{ omap ar a[ " A/in onoremap a, a< onoremap i, i< " Until... onoremap ; t; onoremap : t: onoremap , t, onoremap . t. " Until space onoremap E onoremap B xnoremap E xnoremap B " Inside space onoremap i iW vnoremap i iW " LHS/RHS operators: {{{ "let property = value omap ih (operator-lhs) omap iH (operator-Lhs) omap ah (operator-Lhs) omap il (operator-rhs) omap al (operator-Rhs) omap iL (operator-Rhs) xmap ih (visual-lhs) xmap iH (visual-Lhs) xmap ah (visual-Lhs) xmap il (visual-rhs) xmap al (visual-Rhs) xmap iL (visual-Rhs) " end-of-LHS/RHS }}} " Treesitter operator: " ./rc/plugins/tree-sitter.after.lua " }}}1 "=============================================================================== " Visual-mode {{{1 " xn := visual-mode noremap, excluding select-mode " TODO use these to exchange text " Visual Marks: {{{ xmap m VisualMarksVisualMark nmap gm VisualMarksGetVisualMark "}}} " Niceblock: {{{ xmap I (niceblock-I) xmap gI (niceblock-gI) xmap gi (niceblock-gI) xmap A (niceblock-A) xmap ga (niceblock-A) ""}}} " VisualSelection Move: {{{ xnoremap J :m '>+1gv=gv xnoremap K :m '<-2gv=gv xnoremap H 'dhP`[' . visualmode() . '`]' xnoremap L 'dp`[' . visualmode() . '`]' "}}} " 1}}} "=============================================================================== " Lang & common maps {{{1 " Underspace map! _ map! _ " Paste @@ cnoremap + inoremap + " Section: Filename/path insertion {{{ " noremap! =expand('%:p:~') noremap! f =expand('%') noremap! =expand('%:~') noremap! F =expand('%:p') noremap! h =expand('%:h:.')/ noremap! =expand('%:h:~')/ noremap! H =expand('%:p:h')/ noremap! d =expand('%:h:.')/ noremap! =expand('%:h:~')/ noremap! D =expand('%:p:h')/ noremap! b =expand('%:t:r') noremap! n =expand('%:t') noremap! e =expand('%:e') noremap! t =expand('%:t') noremap! < =expand('%<') noremap! , =expand('%<') . '.' noremap! f =expand('#') noremap! =expand('#:~') noremap! F =expand('#:p') noremap! h =expand('#:h:.') noremap! =expand('#:h:~') noremap! H =expand('#:p:h') noremap! d =expand('#:h:.') noremap! =expand('#:h:~') noremap! D =expand('#:p:h') noremap! b =expand('#:t:r') noremap! n =expand('#:t') noremap! e =expand('#:e') noremap! t =expand('#:t') noremap! < =expand('#<') noremap! , =expand('#<') noremap! c =fnamemodify(getcwd(), ':~') noremap! C =getcwd() "}}} " Section: Move {{{ noremap! noremap! noremap! noremap! " }}} " FIXME move the functions to some autoload folder " Section: readline keybindings {{{ inoremap d0 cnoremap inoremap ^ inoremap cnoremap cnoremap inoremap getline('.')=~'^\s*$'&&col('.')>strlen(getline('.'))?"0\C-D>\Esc>kJs":"\Left>" cnoremap inoremap col('.')>strlen(getline('.'))?"\C-D>":"\Del>" cnoremap getcmdpos()>strlen(getcmdline())?"\C-D>":"\Del>" inoremap col('.')>strlen(getline('.'))pumvisible()?"\C-E>":"\End>" inoremap col('.')>strlen(getline('.'))?"\C-F>":"\Right>" cnoremap getcmdpos()>strlen(getcmdline())?&cedit:"\Right>" inoremap :call search('\<', 'b') inoremap :call search('\>') cnoremap =cmdForwardWord() cnoremap =cmdBackwardWord() noremap! dw cnoremap noremap! function! s:cmdBackwardWord () let line = getcmdline() let pos = getcmdpos() let n = 0 let m = 1 let me = 1 "let pat = '\v[^A-Z][A-Z]\zs|\w+|\W\s+' let pat = '\C\v>|\W\zs\s+|[^A-Z]\zs[A-Z]' while (n < pos && n != -1) let m = match(line, pat, me) let me = matchend(line, pat, me) if (m == -1 || m+1 >= pos) break end let n = m endwhile if (n <= 1) call setcmdpos(1) | else call setcmdpos(n + 1) | end return '' endfu function! s:cmdForwardWord () let line = getcmdline() let pos = getcmdpos() let n = match(line, '\C\v>|\W\zs\s+|[^A-Z]\zs[A-Z]', pos) if n == -1 call setcmdpos(len(line) + 1) else call setcmdpos(n + 1) end return '' endfu "}}} " 1}}} "=============================================================================== " Insert {{{1 inoremap " 1}}} "=============================================================================== " Autocomplete & Snippets (, , etc) {{{1 let UltiSnipsExpandTrigger = "" let UltiSnipsJumpForwardTrigger = "" let UltiSnipsJumpBackwardTrigger = "" let ycm_key_invoke_completion = '' let ycm_key_list_select_completion = [ '' ] let ycm_key_list_previous_completion = [ '' ] inoremap " Filename autocompletion inoremap inoremap =I_CR() inoremap =I_TAB() inoremap =I_S_TAB() inoremap =I_SPACE() smap :call UltiSnips#JumpForwards() smap :call UltiSnips#JumpBackwards() func! I_CR () if Ulti_canExpand() return Ulti_expand() | end if pumvisible() return "\\=Ulti_expand()\" | end "return delimitMate#ExpandReturn() . "\u" return "\\u" endfu func! I_SPACE () "if delimitMate#ShouldJump() && pumvisible() "return delimitMate#JumpAny() | end if pumvisible() return "\\" . "\" end return "\u" . "\" endfu fu! I_TAB () if pumvisible() return "\" | end if Ulti_canExpand() return Ulti_expand() | end if Ulti_canJump() return Ulti_jump('1') | end if (getline('.')[col('.')-2] =~? '\w\|\.' \ && getline('.')[col('.')-1] !~? '\w' ) return get(b:, 'tab_complete', &omnifunc != '' ? "\\" : "\")."\" | end if exists('b:tab_key') return b:tab_key | end return "\" endfu fu! I_S_TAB () if Ulti_canJump() && !pumvisible() return Ulti_jump('0') | end if pumvisible() return "\" | end return "\" endfu " SECTION: UltiSnips helpers function! Ulti_canExpand() if !has('python3') | return 0 | end py3 << EOF import vim from UltiSnips import UltiSnips_Manager, vim_helper before = vim_helper.buf.line_till_cursor sn=UltiSnips_Manager._snips(before, False) vim.command('return %i' % len(sn)) EOF endfunction function! Ulti_canJump() if !has('python3') | return 0 | end py3 << EOF import vim from UltiSnips import UltiSnips_Manager if UltiSnips_Manager._current_snippet: vim.command('return 1') else: vim.command('return 0') EOF endfunction function! Ulti_jump(dir) py3 << EOF import vim from UltiSnips import UltiSnips_Manager if UltiSnips_Manager._current_snippet: if vim.eval('a:dir') == '1': UltiSnips_Manager.jump_forwards() else: UltiSnips_Manager.jump_backwards() EOF return "" endfu function! Ulti_expand() call UltiSnips#ExpandSnippet() return "" endfu " }}}1 "=============================================================================== " Command maps {{{1 " set wildchar= " set wildcharm= set wildcharm= " cmap wilder#in_context() ? wilder#next() : "\" " cmap wilder#in_context() ? wilder#previous() : "\" " Open CmdWindow set cedit= cnoremap " Insert all matches cnoremap " Insert... cnoremap . '%' cnoremap 5 '%' cnoremap =getline('.') " alt-u ~ go up cnoremap " Abbreviations: @cabbr cabbrev pp Pp cabbrev hh vert h cabbrev sudo w !sudo tee % >/dev/null " Insert-like mappings " Movement functions function! s:mapCmdPairs() let s:cmd_pairs = { \'(': ')', \'[': ']', \'{': '}', \'"': '"', \"'": "'" \} for k in keys(s:cmd_pairs) let opening = k let closing = s:cmd_pairs[k] execute 'cnoremap ' . opening . ' ' . opening . closing .'' if closing == '"' execute "cnoremap " . closing . " cmdClosingPair('" . closing . "', '" . opening ."')" else execute 'cnoremap ' . closing . ' cmdClosingPair("' . closing . '", "' . opening .'")' end endfor cnoremap cmdDeletePair("\") cnoremap cmdDeletePair("\") endfu function! s:cmdClosingPair (closing, opening) let pos = getcmdpos() let line = getcmdline() let next = line[pos - 1] if next == a:closing return "\" elseif a:closing == a:opening return a:opening . a:closing . "\" else return a:closing end endfu function! s:isAtEndOfCmdline () return 1 return getcmdpos() == 1+len(getcmdline()) endfu function! s:cmdDeletePair (char) let pos = getcmdpos() let line = getcmdline() let char_before = line[pos - 2] let char_after = line[pos - 1] if has_key(s:cmd_pairs, char_before) \ && s:cmd_pairs[char_before] == char_after return "\\\" else return a:char end endfu " 1}}} "=============================================================================== " Folds, scroll {{{1 nnoremap 5zh nnoremap 4zl nnoremap zH nnoremap zL nnoremap za nnoremap zO " Recursive open/close nnoremap zm zM nnoremap zr zR nnoremap zR zr nnoremap zM zm " Mappings to easily toggle fold levels nnoremap z0 :set foldlevel=0 nnoremap z1 :set foldlevel=1 nnoremap z2 :set foldlevel=2 nnoremap z3 :set foldlevel=3 nnoremap z- :set foldlevel-=1 call Info('&foldlevel = ' . &foldlevel) nnoremap z+ :set foldlevel+=1 call Info('&foldlevel = ' . &foldlevel) " 1}}} "=============================================================================== " Options: ../plugin/options.vim " F-keys: ../plugin/f-keys.vim "=============================================================================== " vim: fdm=marker