" Keybindings """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Stop highlighting search result when pressing Return nnoremap :nohlsearch " Indentation jump " https://vim.fandom.com/wiki/Move_to_next/previous_line_with_same_indentation " noremap :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%<' . line('.') . 'l\S', 'be') " noremap :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%>' . line('.') . 'l\S', 'e') " Split view navigation " Create new panes nnoremap N :vsplit nnoremap n :split " Substitute command if (exists('+inccommand') && &inccommand != '') nnoremap S :%s/ vnoremap S :s/ else " This does not work with live previewing commands (inccommand) since the " replace pattern is already defined and thus everything matching the search " pattern is just deleted. nnoremap S :%s//gc vnoremap S :s//gc endif " Interact with the system clipboard if (has('clipboard')) map y "+y map Y "+Y map p "+p map P "+P endif " Ctrl-Backspace should delete words in insert mode and on command-line. noremap! " Correct word with best/first suggestion. noremap c 1z= " Correct next or last misspelled word (and their non-rare/region versions) " without moving " TODO: see :keepjumps " Problem: with keepjumps the is not possible anymore noremap ]s ]s1z= noremap [s [s1z= noremap ]S ]S1z= noremap [S [S1z= " Toggle spell language between German and English function! CycleSpellLang() if (&spelllang == 'en') setl spelllang=de else setl spelllang=en endif endfunction " Toggle spell, cycle and set spelllang map st :set spell=!&spell map sc :call CycleSpellLang() map ss :set spelllang= " Jump through jump table but center noremap zz noremap zz nmap " Terminal if (has('nvim')) tnoremap nmap :split +terminali nmap v :vsplit +terminali elseif (has('terminal')) nmap :terminal endif " Plugin specific bindings if (get(g:, 'loaded_fzf')) nmap f :Files nmap j :Lines nmap / :Lines nmap h :Helptags " TODO: fix this? if (get(g:, 'loaded_gutentags') || 1) nmap t :Tags nmap bt :BTags endif endif " Search for selected text. " Taken from https://vim.fandom.com/wiki/Search_for_visually_selected_text vnoremap * y/\V=escape(@",'/\') vnoremap # y?\V=escape(@",'?\') " Extended `*`. Starts vim search (without jump) and ripgrep search for cword nmap * :let @/ = '\<' . expand('') . '\>' \ set hlsearch \ Rg \b=expand('')\b " Select last pasted text in same visual mode as it was selected (v, V, or ^V) " Taken from: https://vim.fandom.com/wiki/Selecting_your_pasted_text nnoremap gp '`[' . strpart(getregtype(), 0, 1) . '`]' " Git bindings " Insert a commit's subject behind the SHA1 that the cursor is currently on. " Mnemonic: "git reference commit" " NOTE: This uses `system` and not `:r!` to insert the text directly at the " cursor. `subject[:-2]` cuts off the trailing newline. nmap grc :let subject=system('git show -s --format="(\"%s\")" ')ea =subject[:-2] " Insert a Signed-off-by trailer nmap gso :r!git config --get user.name:r!git config --get user.emailI<A>kJISigned-off-by: " Add, stash or checkout the current file nmap ga :!git add -- % nmap gs :!git stash -- % nmap gu :!git checkout -- % if exists('g:loaded_fugitive') " Interactive `git status` nmap gg :G " Using fugitive.vim, start a commit and open the message in a new split nmap gc :G commit " Move to root of directory nmap gcd :Gcd " git blame in scroll bound vertical split (only the commit hashes, see " :help :Git_blame) nmap gb :G blameC else " Move to root of directory " NOTE: only works if a file is already opened nnoremap gcd :cd %:h cd `git rev-parse --show-toplevel` endif if exists('g:loaded_gitgutter') " Add `g` prefix to hunk bindings " Mnemonic: "git hunk " nmap gha (GitGutterStageHunk) " TODO: nmap ghs (GitGutterStashHunk) nmap ghu (GitGutterUndoHunk) nmap ghp (GitGutterPreviewHunk) " StageHunk can be used for single lines. Mnemonic w/o `h`unk xmap ga (GitGutterStageHunk) " Add hunk/h version to textobject bindings that use `c` (for `change I " presume?) (e.g. ic -> ih) omap ih (GitGutterTextObjectInnerPending) omap ah (GitGutterTextObjectOuterPending) xmap ih (GitGutterTextObjectInnerVisual) xmap ah (GitGutterTextObjectOuterVisual) " Same for hunk navigation bindings nmap [h (GitGutterPrevHunk) nmap ]h (GitGutterNextHunk) endif if (get(g:, 'loaded_fzf')) " git files that `git status` lists nmap gf :GFiles? " 'git log (log?)' and 'git log buffer ' map gll :Commits map glb :BCommits endif " Y should behave like D & C does nnoremap Y y$ " Clear line (`cc` but stay in normal mode) nmap dd 0D " Fix & command to also use last flags nnoremap & :&& xnoremap & :&& " see :help i_ctrl-g_u " Do not break undo sequence when using the arrow keys or home and end in insert " mode inoremap U inoremap U inoremap col('.') == match(getline('.'), '\S') + 1 ? \ repeat('U', col('.') - 1) : \ (col('.') < match(getline('.'), '\S') ? \ repeat('U', match(getline('.'), '\S') + 0) : \ repeat('U', col('.') - 1 - match(getline('.'), '\S'))) inoremap repeat('U', col('$') - col('.')) " Make insert-mode texts repeatable by `.` with the closing parentheses at the " right position inoremap ( ()U " break undo sequence with every space and newline, making insert mode changes " revertible in smaller chunks inoremap u inoremap u " Open the manpage in the WORD under cursor nnoremap gm :Man xnoremap gm :Man " Format the current paragraph nmap Q gqap " Swap movement mappings that act on display lines with the normal ones, making " it easier to navigate long wrapped lines. function! MapWrapMovement() if &wrap noremap j gj noremap k gk noremap 0 g0 noremap ^ g^ noremap $ g$ noremap gj j noremap gk k noremap g0 0 noremap g^ ^ noremap g$ $ else noremap j j noremap k k noremap 0 0 noremap ^ ^ noremap $ $ noremap gj gj noremap gk gk noremap g0 g0 noremap g^ g^ noremap g$ g$ endif endfunction augroup WrapMovementMappings au! au OptionSet wrap call MapWrapMovement() augroup END " Convert Unix timestamp to human readable " Mnemonic: "Unix timestamp convert" with pun to UTC nnoremap utc ciw=strftime("%F %T", @") vnoremap utc :s/\v(^\|[^0-9])\zs[0-9]{10}\ze([^0-9]\|$)/\=strftime("%F %T",submatch(0))/g " Match the behaviour of [[ and []. ]] forward to next '}' in the first column " and ][ fw to next '[', instead of the other way around. noremap ]] ][ noremap ][ ]] " Strip trailing whitespace nnoremap :silent! %s/\v\s+$// vnoremap :silent! '<,'>s/\v\s+$// " Convert double quotes to single nnoremap " :silent! %s/"/'/g vnoremap " :silent! '<,'>s/"/'/g " Keep selection when changing the indentation in visual mode vnoremap > >gv vnoremap <