aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/better-text-objs.txt62
-rw-r--r--plugin/better-text-objs.vim148
-rw-r--r--readme.txt6
3 files changed, 216 insertions, 0 deletions
diff --git a/doc/better-text-objs.txt b/doc/better-text-objs.txt
new file mode 100644
index 0000000..7a83d25
--- /dev/null
+++ b/doc/better-text-objs.txt
@@ -0,0 +1,62 @@
1*better-text-objs.txt* Provide additional text objects
2
3
4==============================================================================
5INTRODUCTION *better-text-objs-intro*
6
7This is a collection of handy text objects I found online,
8written by romainl and habamax. I found these useful and
9decided to package them into a plugin.
10
11==============================================================================
12OVERVIEW *better-text-objs-overview*
13
14Pair |better-text-objs-pair|
15Line |better-text-objs-line|
16Number |better-text-objs-number|
17Buffer |better-text-objs-buffer|
18Indent |better-text-objs-indent|
19
20==============================================================================
21PAIR *better-text-objs-pair*
22
23`i_ i. i: i, i; i| i/ i\ i* i+ i- i#`
24`a_ a. a: a, a; a| a/ a\ a* a+ a- a#`
25
26Text objects in and around any two matching pairs of characters on the same
27line.
28
29==============================================================================
30LINE *better-text-objs-line*
31
32`il al`
33
34Text objects to represent in and around the current line.
35
36==============================================================================
37NUMBER *better-text-objs-number*
38
39`in an`
40
41Text objects in and around a number (if present) under the cursor.
42
43==============================================================================
44BUFFER *better-text-objs-number*
45
46`i% a%`
47
48Text objects representing the active buffer, `i%` excludes the first and last
49lines of the buffer, `a%` includes all lines of the buffer.
50
51==============================================================================
52INDENT *better-text-objs-number*
53
54`ii ai`
55
56Text objects to represent the text at the same indent level, useful for indent
57based programming languages, such as Python or Haskell. `ii` includes only
58text at the same indent level, `ai` includes one line before and one line
59after the current indent level.
60
61------------------------------------------------------------------------------
62vim:tw=78:ts=8:ft=help:norl:
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#
7for 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>'
12endfor
13
14" line text objects
15" -----------------
16" il al
17xnoremap il g_o^
18onoremap il :<C-u>normal vil<CR>
19xnoremap al $o0
20onoremap al :<C-u>normal val<CR>
21
22" number text object (integer and float)
23" --------------------------------------
24" in
25function! VisualNumber()
26 call search('\d\([^0-9\.]\|$\)', 'cW')
27 normal v
28 call search('\(^\|[^0-9\.]\d\)', 'becW')
29endfunction
30xnoremap in :<C-u>call VisualNumber()<CR>
31onoremap in :<C-u>normal vin<CR>
32
33" buffer text objects
34" -------------------
35" i% a%
36xnoremap i% :<C-u>let z = @/\|1;/^./kz<CR>G??<CR>:let @/ = z<CR>V'z
37onoremap i% :<C-u>normal vi%<CR>
38xnoremap a% GoggV
39onoremap a% :<C-u>normal va%<CR>
40
41" square brackets text objects
42" ----------------------------
43" ir ar
44xnoremap ir i[
45xnoremap ar a[
46onoremap ir :normal vi[<CR>
47onoremap ar :normal va[<CR>
48
49" C++ style block comment text objects
50" ------------------------------------
51" i? a?
52xnoremap a? [*o]*
53onoremap a? :<C-u>normal va?V<CR>
54xnoremap i? [*jo]*k
55onoremap i? :<C-u>normal vi?V<CR>
56
57" last change text object
58" -----------------------
59" ik ak
60xnoremap ik `]o`[
61onoremap ik :<C-u>normal vik<CR>
62onoremap ak :<C-u>normal vikV<CR>
63
64
65" Indent text object
66" ------------------
67" ii ai
68func! 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
122endfunc
123
124
125func! s:nextnonblank(lnum) abort
126 let res = nextnonblank(a:lnum)
127 if res == 0
128 let res = line('$')+1
129 endif
130 return res
131endfunc
132
133
134func! 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
143endfunc
144
145onoremap <silent>ii :<C-u>call <sid>indent_textobj(v:true)<CR>
146onoremap <silent>ai :<C-u>call <sid>indent_textobj(v:false)<CR>
147xnoremap <silent>ii :<C-u>call <sid>indent_textobj(v:true)<CR>
148xnoremap <silent>ai :<C-u>call <sid>indent_textobj(v:false)<CR>
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..695e391
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,6 @@
1better-text-objs
2----------------
3
4This is a collection of handy text objects I found online,
5written by romainl and habamax. I found these useful and
6decided to package them into a plugin.