Fix the commit reference mapping `<leader>grc` in the case that nothing follows the commit hash on the line. In that case the join would add a trailing space. `gJ` is not suitable as that would break in the other case that text follows. When splitting the line behind the commit hash, the space in front of whatever follows is deleted. Thus when joining everything together at the end, there would be no space between the closing parentheses and the rest. Using the `system()` was the only solution I found to insert the subject directly behind the hash without destroying the formatting and the text behind it. For this to work the trailing newline had to be cut off of git's output.
190 lines
6.1 KiB
VimL
190 lines
6.1 KiB
VimL
" Keybindings """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
|
" Stop highlighting search result when pressing Return
|
|
nnoremap <silent> <Esc> :nohlsearch<CR><Esc>
|
|
|
|
" Indentation jump
|
|
" https://vim.fandom.com/wiki/Move_to_next/previous_line_with_same_indentation
|
|
" noremap <silent> <C-k> :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%<' . line('.') . 'l\S', 'be')<CR>
|
|
" noremap <silent> <C-j> :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%>' . line('.') . 'l\S', 'e')<CR>
|
|
|
|
" Split view navigation
|
|
" Create new panes
|
|
nnoremap <C-w>N :vsplit<CR>
|
|
nnoremap <C-w>n :split<CR>
|
|
|
|
" 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<Left><Left><Left>
|
|
vnoremap S :s//gc<Left><Left><Left>
|
|
endif
|
|
|
|
" Interact with the system clipboard
|
|
if (has('clipboard') || has('nvim'))
|
|
map <leader>y "+y
|
|
map <leader>Y "+Y
|
|
map <leader>d "+d
|
|
map <leader>p "+p
|
|
map <leader>P "+P
|
|
endif
|
|
|
|
" Ctrl-Backspace should delete words in insert mode and on command-line.
|
|
noremap! <C-H> <C-W>
|
|
|
|
" Correct word with best/first suggestion.
|
|
noremap <leader>c 1z=
|
|
" Correct next or last misspelled word (and their non-rare/region versions)
|
|
" without moving
|
|
" TODO: see :keepjumps
|
|
" Problem: with keepjumps the <C-O> is not possible anymore
|
|
noremap <leader>]s ]s1z=<C-O>
|
|
noremap <leader>[s [s1z=<C-O>
|
|
noremap <leader>]S ]S1z=<C-O>
|
|
noremap <leader>[S [S1z=<C-O>
|
|
|
|
" Toggle spell, cycle and set spelllang
|
|
map <leader>st :set spell=!&spell<CR>
|
|
map <leader>sc :call CycleSpellLang()<CR>
|
|
map <leader>ss :set spelllang=
|
|
" Umlaute and sz in Insert and Command-line mode when spelllang is set to `de`
|
|
autocmd OptionSet spelllang silent call NewSpellLang(v:option_new, v:option_old)
|
|
function! NewSpellLang(new_lang, old_lang)
|
|
let &spellfile = $XDG_DATA_HOME . '/vim/spell/' . a:new_lang . '.utf-8.add'
|
|
|
|
let mappings = {
|
|
\ 'ae': 'ä',
|
|
\ 'Ae': 'Ä',
|
|
\ 'oe': 'ö',
|
|
\ 'Oe': 'Ö',
|
|
\ 'ue': 'ü',
|
|
\ 'Ue': 'Ü',
|
|
\ 'sz': 'ß',
|
|
\ }
|
|
if (a:new_lang == 'de')
|
|
for [key, value] in items(mappings)
|
|
execute 'map! <buffer>' key value
|
|
endfor
|
|
elseif (a:old_lang == 'de')
|
|
for key in keys(mappings)
|
|
execute 'unmap! <buffer>' key
|
|
endfor
|
|
endif
|
|
endfunction
|
|
|
|
" Jump through jump table but center
|
|
noremap <Tab> <Tab>zz
|
|
noremap <C-O> <C-O>zz
|
|
nmap <S-Tab> <C-O>
|
|
|
|
" Terminal
|
|
if (has('nvim'))
|
|
tnoremap <leader><Esc> <C-\><C-n>
|
|
nmap <leader><CR> :split +terminal<CR>i
|
|
nmap <leader>v<CR> :vsplit +terminal<CR>i
|
|
elseif (has('terminal'))
|
|
nmap <leader><CR> :terminal<CR>
|
|
endif
|
|
|
|
" Plugin specific bindings
|
|
if (get(g:, 'loaded_fzf'))
|
|
nmap <leader>f :Files<CR>
|
|
nmap <leader>j :Lines<CR>
|
|
nmap <leader>/ :Lines<CR>
|
|
" TODO: fix this?
|
|
if (get(g:, 'loaded_gutentags') || 1)
|
|
nmap <leader>t :Tags<CR>
|
|
endif
|
|
endif
|
|
|
|
" Search for selected text.
|
|
" Taken from https://vim.fandom.com/wiki/Search_for_visually_selected_text
|
|
vnoremap * y/\V<C-R>=escape(@",'/\')<CR><CR>
|
|
vnoremap # y?\V<C-R>=escape(@",'?\')<CR><CR>
|
|
|
|
" 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 <expr> 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 <leader>grc :let subject=system('git show -s --format="(\"%s\")" <C-R><C-W>')<CR>ea <C-R>=subject[:-2]<CR><Esc>
|
|
if exists('g:loaded_fugitive')
|
|
nmap <leader>gc :G commit<CR>
|
|
|
|
nmap <leader>ga :G add -- %<CR>
|
|
nmap <leader>gs :G stash -- %<CR>
|
|
nmap <leader>gu :G checkout -- %<CR>
|
|
else
|
|
" only works if a file is already opened
|
|
nnoremap <leader>gcd :cd %:h <Bar> cd `git rev-parse --show-toplevel`<CR>
|
|
endif
|
|
|
|
if exists('g:loaded_gitgutter')
|
|
" Add `g` prefix to hunk bindings
|
|
|
|
" Mnemonic: "git hunk <add|undo|preview>"
|
|
nmap <leader>gha <Plug>(GitGutterStageHunk)
|
|
xmap <leader>gha <Plug>(GitGutterStageHunk)
|
|
" TODO: nmap <leader>ghs <Plug>(GitGutterStashHunk)
|
|
nmap <leader>ghu <Plug>(GitGutterUndoHunk)
|
|
nmap <leader>ghp <Plug>(GitGutterPreviewHunk)
|
|
|
|
" Add hunk/h version to textobject bindings that use `c` (for `change I
|
|
" presume?) (e.g. ic -> ih)
|
|
omap ih <Plug>(GitGutterTextObjectInnerPending)
|
|
omap ah <Plug>(GitGutterTextObjectOuterPending)
|
|
xmap ih <Plug>(GitGutterTextObjectInnerVisual)
|
|
xmap ah <Plug>(GitGutterTextObjectOuterVisual)
|
|
" Same for hunk navigation bindings
|
|
nmap [h <Plug>(GitGutterPrevHunk)
|
|
nmap ]h <Plug>(GitGutterNextHunk)
|
|
endif
|
|
|
|
" Y should behave like D & C does
|
|
nnoremap Y y$
|
|
|
|
" Move lines up and down while correcting the indentation
|
|
" https://vim.fandom.com/wiki/Moving_lines_up_or_down
|
|
" (Use arrows, as Alt-{j,k} is used by my terminal for scrollback)
|
|
nnoremap <silent> <A-Up> :m .-2<CR>==
|
|
nnoremap <silent> <A-Down> :m .+1<CR>==
|
|
vnoremap <silent> <A-Up> :m '<-2<CR>gv=gv
|
|
vnoremap <silent> <A-Down> :m '>+1<CR>gv=gv
|
|
inoremap <silent> <A-Up> <Esc>:m .-2<CR>==gi
|
|
inoremap <silent> <A-Down> <Esc>:m .+1<CR>==gi
|
|
|
|
" Fix & command to also use last flags
|
|
nnoremap & :&&<CR>
|
|
xnoremap & :&&<CR>
|
|
|
|
" see :help i_ctrl-g_u
|
|
" Do not break undo sequence when using the arrow keys or home and end in insert
|
|
" mode
|
|
inoremap <Left> <C-G>U<Left>
|
|
inoremap <Right> <C-G>U<Right>
|
|
inoremap <expr> <Home> col('.') == match(getline('.'), '\S') + 1 ?
|
|
\ repeat('<C-G>U<Left>', col('.') - 1) :
|
|
\ (col('.') < match(getline('.'), '\S') ?
|
|
\ repeat('<C-G>U<Right>', match(getline('.'), '\S') + 0) :
|
|
\ repeat('<C-G>U<Left>', col('.') - 1 - match(getline('.'), '\S')))
|
|
inoremap <expr> <End> repeat('<C-G>U<Right>', col('$') - col('.'))
|
|
" Make insert-mode texts repeatable by `.` with the closing parentheses at the
|
|
" right position
|
|
inoremap ( ()<C-G>U<Left>
|
|
" break undo sequence with every space and newline, making insert mode changes
|
|
" revertible in smaller chunks
|
|
inoremap <Space> <C-G>u<Space>
|
|
inoremap <CR> <C-G>u<CR>
|
|
|
|
" Open the manpage in the WORD under cursor
|
|
nnoremap gm :Man <C-r><C-a><CR>
|
|
xnoremap gm :Man <C-r><C-a><CR>
|