aboutsummaryrefslogtreecommitdiff
path: root/plugin/remappings.vim
blob: f29f0a43303dba04eb9f59cbc072c248e5e010fd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

" Remap i{",',`} and a{",',`} to search for the next string. This is more like how objects like i( and i{ work.
"
" The behavior inside the quotes should remain unchanged.
onoremap <silent> i" <cmd>call <sid>find_quote('i', '"')<cr>
onoremap <silent> a" <cmd>call <sid>find_quote('a', '"')<cr>
onoremap <silent> i' <cmd>call <sid>find_quote('i', "'")<cr>
onoremap <silent> a' <cmd>call <sid>find_quote('a', "'")<cr>
onoremap <silent> i` <cmd>call <sid>find_quote('i', '`')<cr>
onoremap <silent> a` <cmd>call <sid>find_quote('a', '`')<cr>
vnoremap <silent> i" <cmd>call <sid>find_quote('i', '"')<cr>
vnoremap <silent> a" <cmd>call <sid>find_quote('a', '"')<cr>
vnoremap <silent> i' <cmd>call <sid>find_quote('i', "'")<cr>
vnoremap <silent> a' <cmd>call <sid>find_quote('a', "'")<cr>
vnoremap <silent> i` <cmd>call <sid>find_quote('i', '`')<cr>
vnoremap <silent> a` <cmd>call <sid>find_quote('a', '`')<cr>

function! s:find_quote(ai, q) abort
  let l = getline('.')[:col('.') - 2]

  let cnt = 0
  let skip = 0
  for c in l
    if c ==# a:q && !skip
      let cnt = !cnt
    endif

    if c ==# '\'
      let skip = 1
    else
      let skip = 0
    endif
  endfor

  let flags = 'W'
  if cnt == 1
    let flags .= 'b'
  endif

  exec "normal! \<esc>"
  call search(a:q . '\zs.', flags)
  exec "normal! v" . a:ai . a:q
endfunction

" Fix silly yank behavior.
nnoremap Y y$

" . in visual mode will replay the last command on each line in the visual mode.
vnoremap . <cmd>call <sid>visual_repeat()<cr>

function! s:visual_repeat()
  exec "normal! \<esc>"

  let [_, _, c, _] = getpos('.')
  let [b, l1_, _, p] = getpos("'<")
  let [_, l2_, _, _] = getpos("'>")

  let l1 = min([l1_, l2_])
  let l2 = max([l1_, l2_])

  let l = l1

  while l <= l2
    let newpos = [b, l, c, p]
    call setpos('.', newpos)
    if newpos == getpos('.')
      " Only execute if the new position was valid.
      normal! .
    endif
    let l += 1
  endwhile
endfunction