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
|