diff options
author | Akshay <[email protected]> | 2020-11-04 14:53:19 +0000 |
---|---|---|
committer | Akshay <[email protected]> | 2020-11-04 14:53:19 +0000 |
commit | 07bffe8c51ce575db0b1ea8571c3e182254c0e2a (patch) | |
tree | c04056462449d9c6c7f5bcbbf65055bd465cc13a /plugin |
init
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/better-text-objs.vim | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/plugin/better-text-objs.vim b/plugin/better-text-objs.vim new file mode 100644 index 0000000..e959e6e --- /dev/null +++ b/plugin/better-text-objs.vim | |||
@@ -0,0 +1,148 @@ | |||
1 | " Credits: romainl and habamax | ||
2 | |||
3 | " 24 simple text objects | ||
4 | " ---------------------- | ||
5 | " i_ i. i: i, i; i| i/ i\ i* i+ i- i# | ||
6 | " a_ a. a: a, a; a| a/ a\ a* a+ a- a# | ||
7 | for char in [ '_', '.', ':', ',', ';', '<bar>', '/', '<bslash>', '*', '+', '-', '#' ] | ||
8 | execute 'xnoremap i' . char . ' :<C-u>normal! T' . char . 'vt' . char . '<CR>' | ||
9 | execute 'onoremap i' . char . ' :normal vi' . char . '<CR>' | ||
10 | execute 'xnoremap a' . char . ' :<C-u>normal! F' . char . 'vf' . char . '<CR>' | ||
11 | execute 'onoremap a' . char . ' :normal va' . char . '<CR>' | ||
12 | endfor | ||
13 | |||
14 | " line text objects | ||
15 | " ----------------- | ||
16 | " il al | ||
17 | xnoremap il g_o^ | ||
18 | onoremap il :<C-u>normal vil<CR> | ||
19 | xnoremap al $o0 | ||
20 | onoremap al :<C-u>normal val<CR> | ||
21 | |||
22 | " number text object (integer and float) | ||
23 | " -------------------------------------- | ||
24 | " in | ||
25 | function! VisualNumber() | ||
26 | call search('\d\([^0-9\.]\|$\)', 'cW') | ||
27 | normal v | ||
28 | call search('\(^\|[^0-9\.]\d\)', 'becW') | ||
29 | endfunction | ||
30 | xnoremap in :<C-u>call VisualNumber()<CR> | ||
31 | onoremap in :<C-u>normal vin<CR> | ||
32 | |||
33 | " buffer text objects | ||
34 | " ------------------- | ||
35 | " i% a% | ||
36 | xnoremap i% :<C-u>let z = @/\|1;/^./kz<CR>G??<CR>:let @/ = z<CR>V'z | ||
37 | onoremap i% :<C-u>normal vi%<CR> | ||
38 | xnoremap a% GoggV | ||
39 | onoremap a% :<C-u>normal va%<CR> | ||
40 | |||
41 | " square brackets text objects | ||
42 | " ---------------------------- | ||
43 | " ir ar | ||
44 | xnoremap ir i[ | ||
45 | xnoremap ar a[ | ||
46 | onoremap ir :normal vi[<CR> | ||
47 | onoremap ar :normal va[<CR> | ||
48 | |||
49 | " C++ style block comment text objects | ||
50 | " ------------------------------------ | ||
51 | " i? a? | ||
52 | xnoremap a? [*o]* | ||
53 | onoremap a? :<C-u>normal va?V<CR> | ||
54 | xnoremap i? [*jo]*k | ||
55 | onoremap i? :<C-u>normal vi?V<CR> | ||
56 | |||
57 | " last change text object | ||
58 | " ----------------------- | ||
59 | " ik ak | ||
60 | xnoremap ik `]o`[ | ||
61 | onoremap ik :<C-u>normal vik<CR> | ||
62 | onoremap ak :<C-u>normal vikV<CR> | ||
63 | |||
64 | |||
65 | " Indent text object | ||
66 | " ------------------ | ||
67 | " ii ai | ||
68 | func! s:indent_textobj(inner) | ||
69 | if getline('.') =~ '^\s*$' | ||
70 | let ln_start = s:detect_nearest_line() | ||
71 | let ln_end = ln_start | ||
72 | else | ||
73 | let ln_start = line('.') | ||
74 | let ln_end = ln_start | ||
75 | endif | ||
76 | |||
77 | let indent = indent(ln_start) | ||
78 | if indent > 0 | ||
79 | while indent(ln_start) >= indent && ln_start > 0 | ||
80 | let ln_start = prevnonblank(ln_start-1) | ||
81 | endwhile | ||
82 | |||
83 | while indent(ln_end) >= indent && ln_end <= line('$') | ||
84 | let ln_end = s:nextnonblank(ln_end+1) | ||
85 | endwhile | ||
86 | else | ||
87 | while indent(ln_start) == 0 && ln_start > 0 && getline(ln_start) !~ '^\s*$' | ||
88 | let ln_start -= 1 | ||
89 | endwhile | ||
90 | while indent(ln_start) > 0 && ln_start > 0 | ||
91 | let ln_start = prevnonblank(ln_start-1) | ||
92 | endwhile | ||
93 | while indent(ln_start) == 0 && ln_start > 0 && getline(ln_start) !~ '^\s*$' | ||
94 | let ln_start -= 1 | ||
95 | endwhile | ||
96 | |||
97 | while indent(ln_end) == 0 && ln_end <= line('$') && getline(ln_end) !~ '^\s*$' | ||
98 | let ln_end += 1 | ||
99 | endwhile | ||
100 | while indent(ln_end) > 0 && ln_end <= line('$') | ||
101 | let ln_end = s:nextnonblank(ln_end+1) | ||
102 | endwhile | ||
103 | endif | ||
104 | |||
105 | if a:inner || indent == 0 | ||
106 | let ln_start = s:nextnonblank(ln_start+1) | ||
107 | endif | ||
108 | |||
109 | if a:inner | ||
110 | let ln_end = prevnonblank(ln_end-1) | ||
111 | else | ||
112 | let ln_end = ln_end-1 | ||
113 | endif | ||
114 | |||
115 | if ln_end < ln_start | ||
116 | let ln_end = ln_start | ||
117 | endif | ||
118 | |||
119 | exe ln_end | ||
120 | normal! V | ||
121 | exe ln_start | ||
122 | endfunc | ||
123 | |||
124 | |||
125 | func! s:nextnonblank(lnum) abort | ||
126 | let res = nextnonblank(a:lnum) | ||
127 | if res == 0 | ||
128 | let res = line('$')+1 | ||
129 | endif | ||
130 | return res | ||
131 | endfunc | ||
132 | |||
133 | |||
134 | func! s:detect_nearest_line() abort | ||
135 | let lnum = line('.') | ||
136 | let nline = s:nextnonblank(lnum) | ||
137 | let pline = prevnonblank(lnum) | ||
138 | if abs(nline - lnum) > abs(pline - lnum) || getline(nline) =~ '^\s*$' | ||
139 | return pline | ||
140 | else | ||
141 | return nline | ||
142 | endif | ||
143 | endfunc | ||
144 | |||
145 | onoremap <silent>ii :<C-u>call <sid>indent_textobj(v:true)<CR> | ||
146 | onoremap <silent>ai :<C-u>call <sid>indent_textobj(v:false)<CR> | ||
147 | xnoremap <silent>ii :<C-u>call <sid>indent_textobj(v:true)<CR> | ||
148 | xnoremap <silent>ai :<C-u>call <sid>indent_textobj(v:false)<CR> | ||