vimrc.d/maps.vim

Don’t limit ourselves to plain ASCII encoding:

scriptencoding utf-8

Enforce vim script implementation to reduce ambiguities and improve robustness:

scriptversion 4

Set up map to quickly move among buffers:

noremap <M-Left> <Cmd>call keymaps#switch_buf(v:count1 * -1)<CR>
noremap <M-Right> <Cmd>call keymaps#switch_buf(v:count1 * 1)<CR>

Note

I love 'hidden', as it really suits the way I work. However, it also means I occasionally have to skip through things I don’t care about in :bnext, and I don’t love that. The above mapping skips the buffers I wouldn’t care about and provides a more useful to me version of buffer cycling.

I hate you so much right now:

if exists('$VIM_DISABLE_CURSORS')
    for s:k in ['Up', 'Down', 'Left', 'Right']
        execute printf('nnoremap <%s> <nop>', s:k)
        execute printf('inoremap <%s> <nop>', s:k)
    endfor
endif

Note

I’ll add that this isn’t about [hjkl] purism, I’m truly not interested in that argument. This is entirely about forcing me to use text objects more often.

Begin new line easily from within insert mode:

inoremap <C-CR> <C-o>o
inoremap <S-CR> <C-o>O

Tip

The mnemonic here is <Shift> opens above and <Ctrl> open below, much like their position on many keyboards.

Make <C-g> verbose by default:

nnoremap <silent> <C-g> 2<C-g>

Map Q to reformat paragraphs just as everyone else does:

nnoremap <silent> Q gqap

Tip

Should you have reason to need Ex mode, then you’ll probably find the gQ interface nicer anyhow.

Easy access to man pages when using a custom 'keywordprg':

nnoremap <C-?> <Cmd>execute printf('Man %d <C-R><C-W>', v:count)<CR>

Logical Y mapping, behaves like D:

nnoremap Y y$

Note

This makes so much sense that it is even described in the Y help text, and excellently describes the benefit that would come from breaking backwards compatibility.

Re-grab selection after {de,in}dent for easier repeating:

vnoremap < <gv
vnoremap > >gv

Visual mode indent that matches how it feels in insert:

vnoremap <Tab> >gv
vnoremap <Backspace> <gv

<Home> darts between start of line and start of text:

inoremap <home> <Cmd>call keymaps#home_skip()<CR>
nnoremap <home> <Cmd>call keymaps#home_skip()<CR>

Add <F10> build bindings that are muscle memory reminders of my childhood:

nnoremap <F10> <Cmd>call misc#call_build()<CR>
nnoremap <S-F10> <Cmd>call misc#call_build('check')<CR>

Open file under cursor, like netrw but without the rest:

if executable('xdg-open')
    nnoremap gx
    \   <Cmd>call system('xdg-open ' .. shellescape(expand('<cfile>:p')))<CR>
endif

Maps to jump Window management:

nnoremap <C-w><Bar> <C-w>v
nnoremap <C-w>- <C-w>s
nnoremap <Tab> <C-w>p
if has('quickfix')
    nnoremap <S-Tab> <C-w>P
endif

Tip

Imagine that <C-w>| and <C-w>- are cleaving the window to match the key.

Help related maps:

call keymaps#mnemonic_map('Help', #{key: '?'})

for s:t in ['function-list', 'pattern', 'quickref', 'registers']
    execute printf('nnoremap [Help]%.1s <Cmd>help %s<CR>', s:t, s:t)
endfor

nnoremap [Help]c <Cmd>helpclose<CR>

I don’t use vi movement keys in command-line mode, so we can use them for shortcuts:

cnoremap <C-h> vert help<Space>

Ping the cursor position as a visual cue when returning to a session:

nnoremap <C-Space> <Cmd>call display#cursor_ping()<CR>

Add map to toggle conceal support, which is useful when co-workers freak out when you’re showing code:

if has('conceal')
    nnoremap <M-Space> <Cmd>call display#conceal_toggle()<CR>
endif
Screenshot of conceal mode toggling

Insert current buffer’s directory at command line:

cnoremap <M-.> <C-r>=expand('%:p:h') .. '/'<CR>

Scroll wheel moves through undo list, and through branches with <Shift>. Can’t for the life of me remember who was demoing something similar as a feature, but thanks for the idea!

for s:m in ['i', 'n']
    let s:break_insert = s:m ==# 'i' ? '<C-o>' : ''
    for [s:mod, s:key, s:cmd] in [
    \   ['', 'Up', 'u'], ['', 'Down', '<C-r>'],
    \   ['S-', 'Up', 'g-'], ['S-', 'Down', 'g+']
    \ ]
        execute printf('%snoremap <%sScrollWheel%s> %s%s', s:m, s:mod,
        \              s:key, s:break_insert, s:cmd)
    endfor
endfor

Make insert mode maps for accessing all completion modes without needless hand stretching::

if has('insert_expand')
    for s:key in misc#str2chars('lnkti]fdvuos')
        execute printf('inoremap <silent> <LocalLeader>,%s <C-x><C-%s>',
        \              s:key, s:key)
    endfor
endif

Add mappings to highlight lines:

call keymaps#mnemonic_map('Display', #{key: 'D', modes: 'nv'})
nnoremap [Display]lh <Cmd>call display#add_line_highlight()<CR>
nnoremap [Display]lc <Cmd>call display#clear_line_highlights()<CR>

Tip

This is extremely useful for showing other people code, and unlike simply using linewise visual mode you can maintain the highlights whilst doing other things.

Highlight matches for last search only within visual region:

if has('extra_search')
    nnoremap [Display]ms
    \   <Cmd>execute printf('match Search /\%%V%s\%%V/', getreg('/'))<CR>
    nnoremap [Display]mc <Cmd>match none<CR>
endif

Quickly correct close spelling mistakes without changing cursor position:

call keymaps#mnemonic_map('Spell', #{key: 'z'})
for s:dir in ['[', ']']
    for s:type in ['bad', 'full']
        for s:auto in [v:false, v:true]
            execute printf(
            \   'nnoremap [Spell]%s%s%s ' ..
            \   ':call misc#preserve_layout("normal! %s%s%sz=")<CR>',
            \   s:auto ? '' : 'q',
            \   s:dir ==# ']' ? 'n' : 'l',
            \   s:type ==# 'bad' ? 'W' : 'w',
            \   s:dir,
            \   s:type ==# 'bad' ? 'S' : 's',
            \   s:auto ? '1' :'')
        endfor
    endfor
endfor

Tip

The mnemonic here is query fix, last, next, word for likely misspelled words, and W for positively misspelled words. Therefore, \zlW fixes the last misspelled word using vim’s best guess, and \zqlW pops up a menu with choices for that same misspelled word.

Quickly add close words to dictionaries without changing cursor position:

for s:dir in ['[', ']']
    for s:type in ['bad', 'full']
        for s:local in [v:false, v:true]
            execute printf(
            \   'nnoremap [Spell]%s%s%s ' ..
            \   ':call misc#preserve_layout("normal! %s%sz%s")<CR>',
            \   s:dir ==# ']' ? 'n' : 'l',
            \   s:local ? 'A' : 'a',
            \   s:type ==# 'bad' ? 'W' : 'w',
            \   s:dir,
            \   s:type ==# 'bad' ? 'S' : 's',
            \   s:local ? 'G' :'g')
        endfor
    endfor
endfor

Tip

The mnemonic here is last, next, add to dictionary, Add to internal list, word for likely misspelled words, and W for positively misspelled words. Therefore, \znAw adds the next misspelled or unusual word to the internal list, and \zqaw adds that word to first file in 'spellfile'.