aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjluehrs2 <jluehrs2@uiuc.edu>2008-04-30 17:01:57 -0500
committerjluehrs2 <jluehrs2@uiuc.edu>2008-04-30 17:01:57 -0500
commit5d4e5d33db2c06cb21d42609179499c4d5afd4b5 (patch)
treefedc32529d364e9fae20e06af4994349468b97e4
parent400808d6142f8713ee244cf154287f9a2857dc7a (diff)
downloadvim-textobj-5d4e5d33db2c06cb21d42609179499c4d5afd4b5.tar.gz
vim-textobj-5d4e5d33db2c06cb21d42609179499c4d5afd4b5.zip
split the textobj stuff out into its own file
-rw-r--r--vim/plugin/textobj.vim234
-rw-r--r--vimrc231
2 files changed, 238 insertions, 227 deletions
diff --git a/vim/plugin/textobj.vim b/vim/plugin/textobj.vim
new file mode 100644
index 0000000..a32509e
--- /dev/null
+++ b/vim/plugin/textobj.vim
@@ -0,0 +1,234 @@
+" Text object creation {{{
+let s:text_object_number = 0
+function Textobj(char, callback)
+ let s:text_object_number += 1
+ function s:textobj_{s:text_object_number}(inner, operator, count, callback)
+ try
+ let pos = getpos('.')
+ sandbox let [startline, startcol, endline, endcol] = function(a:callback)(a:inner, a:count)
+ catch /no-match/
+ return
+ finally
+ call setpos('.', pos)
+ endtry
+ if startline == endline
+ let objlength = endcol - startcol + 1
+ else
+ let lines = getline(startline + 1, endline - 1)
+ let lines = [strpart(getline(startline), startcol - 1)] +
+ \ lines +
+ \ [strpart(getline(endline), 0, endcol)]
+ let objlength = 0
+ for line in lines
+ let objlength += strlen(line) + 1
+ endfor
+ let objlength -= 1
+ endif
+ if startcol > strlen(getline(startline))
+ let startcol = 1
+ let startline += 1
+ let objlength -= 1
+ endif
+ call cursor(startline, startcol)
+ exe 'normal! '.a:operator.objlength.' '
+
+ if a:operator == 'c'
+ normal! l
+ startinsert
+ elseif a:operator == 'v'
+ exe "normal! \<BS>"
+ endif
+ endfunction
+
+ exe 'onoremap <silent>a'.a:char.' <Esc>:call <SID>textobj_'.s:text_object_number.'(0, v:operator, v:prevcount, "'.a:callback.'")<CR>'
+ exe 'onoremap <silent>i'.a:char.' <Esc>:call <SID>textobj_'.s:text_object_number.'(1, v:operator, v:prevcount, "'.a:callback.'")<CR>'
+ exe 'xnoremap <silent>a'.a:char.' <Esc>:call <SID>textobj_'.s:text_object_number.'(0, "v", v:prevcount, "'.a:callback.'")<CR>'
+ exe 'xnoremap <silent>i'.a:char.' <Esc>:call <SID>textobj_'.s:text_object_number.'(1, "v", v:prevcount, "'.a:callback.'")<CR>'
+endfunction
+" }}}
+" Text object definitions {{{
+" / for regex {{{
+function s:textobj_regex(inner, count)
+ let pos = getpos('.')
+
+ let line = strpart(getline(pos[1]), 0, pos[2])
+ let lines = getline(1, pos[1] - 1) + [line]
+ let linenum = pos[1]
+ for line in reverse(lines)
+ let objstart = match(line, '.*\zs\\\@<!/') + 1
+ if objstart != 0
+ break
+ endif
+ let linenum -= 1
+ endfor
+ if objstart == 0
+ throw 'no-match'
+ endif
+ let objstart += a:inner
+ let objstartline = linenum
+
+ let line = strpart(getline(pos[1]), pos[2] - 1)
+ let lines = [line] + getline(pos[1] + 1, line('$'))
+ let linenum = pos[1]
+ for line in lines
+ let objend = match(line, '\\\@<!/') + 1
+ if objend != 0
+ if linenum == pos[1]
+ " have to account for the possibility of a split escape
+ " sequence
+ if objend == 1
+ if getline(pos[1])[pos[2] - 2] == '\'
+ let objend = match(line, '\\\@<!/', 1) + 1
+ if objend == 0
+ let linenum += 1
+ continue
+ endif
+ else
+ " if we're sitting on a /, don't do anything, since it's
+ " impossible to know which direction to look
+ throw 'no-match'
+ endif
+ endif
+ let objend += pos[2] - 1
+ endif
+ break
+ endif
+ let linenum += 1
+ endfor
+ if objend == 0
+ throw 'no-match'
+ endif
+ let objend -= a:inner
+ let objendline = linenum
+
+ return [objstartline, objstart, objendline, objend]
+endfunction
+" }}}
+" f for folds {{{
+function s:textobj_fold(inner, count)
+ if foldlevel(line('.')) == 0
+ throw 'no-match'
+ endif
+ exe 'normal! '.a:count.'[z'
+ let startline = line('.') + a:inner
+ normal! ]z
+ let endline = line('.') - a:inner
+
+ return [startline, 1, endline, strlen(getline(endline))]
+endfunction
+" }}}
+" , for function arguments {{{
+function s:textobj_arg(inner, count)
+ let pos = getpos('.')
+ let curchar = getline(pos[1])[pos[2] - 1]
+ if curchar == ','
+ if getline(pos[1])[pos[2] - 2] =~ '\s'
+ normal! gE
+ else
+ exe "normal! \<BS>"
+ endif
+ return s:textobj_arg(a:inner, a:count)
+ elseif curchar =~ '\s'
+ normal! W
+ return s:textobj_arg(a:inner, a:count)
+ endif
+
+ let line = strpart(getline(pos[1]), 0, pos[2])
+ let lines = getline(1, pos[1] - 1) + [line]
+ let linenum = pos[1]
+ for line in reverse(lines)
+ let argbegin = matchend(line, '.*\%(,\s*\|(\)') + 1
+ if argbegin != 0
+ while argbegin > strlen(line)
+ let linenum += 1
+ let line = getline(linenum)
+ let argbegin = matchend(line, '^\s*') + 1
+ endwhile
+ break
+ endif
+ let linenum -= 1
+ endfor
+ if argbegin == 0
+ throw 'no-match'
+ endif
+ let argstartline = linenum
+
+ let line = strpart(getline(pos[1]), pos[2] - 1)
+ let lines = [line] + getline(pos[1] + 1, line('$'))
+ let linenum = pos[1]
+ for line in lines
+ let argend = match(line, '\zs.\?\%(,\|)\)') + 1
+ if argend != 0
+ if linenum == pos[1]
+ let argend += pos[2] - 1
+ endif
+ if argend == 1 && getline(linenum)[argend - 1] == ')'
+ let linenum -= 1
+ let argend = strlen(getline(linenum))
+ endif
+ break
+ endif
+ let linenum += 1
+ endfor
+ if argend == 0
+ throw 'no-match'
+ endif
+ let argendline = linenum
+
+ if a:inner == 0
+ let endline = getline(argendline)
+ let startline = getline(argstartline)
+ if argend >= strlen(endline)
+ let argend = 0
+ let argendline += 1
+ let endline = getline(argendline)
+ endif
+ if endline[argend] == ')' && startline[argbegin - 2] != '('
+ let argbegin = match(strpart(startline, 0, argbegin - 1), '\s*$')
+ while argbegin == 0
+ let argstartline -= 1
+ let startline = getline(argstartline)
+ let argbegin = strlen(startline)
+ endwhile
+ elseif endline[argend] != ')'
+ let argend += matchend(strpart(endline, argend + 1), '^\s*') + 1
+ if startline[argbegin - 2] == '('
+ for line in [strpart(endline, argend)] +
+ \ getline(argendline + 1, line('$'))
+ let argincr = matchend(line, '\s*\ze\S')
+ if argincr != -1
+ let argend += argincr
+ break
+ endif
+ let argendline += 1
+ let argend = 0
+ endfor
+ endif
+ endif
+ if argend >= strlen(endline)
+ if argendline == argstartline
+ let newbegin = matchend(strpart(endline, 0, argbegin), '.*,')
+ if newbegin != -1
+ let argbegin = newbegin + 1
+ endif
+ endif
+ let argend = 0
+ let argendline += 1
+ endif
+ endif
+
+ return [argstartline, argbegin, argendline, argend]
+endfunction
+" }}}
+" }}}
+" Text object creation {{{
+if exists("g:Textobj_regex_enable") && g:Textobj_regex_enable
+ call Textobj('/', "<SID>textobj_regex")
+endif
+if exists("g:Textobj_fold_enable") && g:Textobj_fold_enable
+ call Textobj('f', "<SID>textobj_fold")
+endif
+if exists("g:Textobj_arg_enable") && g:Textobj_arg_enable
+ call Textobj(',', "<SID>textobj_arg")
+endif
+" }}}
diff --git a/vimrc b/vimrc
index 8bb8a47..750b82b 100644
--- a/vimrc
+++ b/vimrc
@@ -279,233 +279,10 @@ if file_readable(s:session_file) && expand("%:.") !~ '^/'
autocmd VimLeave * call delete(s:session_file) | exec 'TlistSessionSave ' . s:session_file
endif
" }}}
-" }}}
-" Text objects {{{
-" Text object creation {{{
-let g:text_object_number = 0
-function Textobj(char, callback)
- let g:text_object_number += 1
- function Textobj_{g:text_object_number}(inner, operator, count, callback)
- try
- let pos = getpos('.')
- sandbox let [startline, startcol, endline, endcol] = function(a:callback)(a:inner, a:count)
- catch /no-match/
- return
- finally
- call setpos('.', pos)
- endtry
- if startline == endline
- let objlength = endcol - startcol + 1
- else
- let lines = getline(startline + 1, endline - 1)
- let lines = [strpart(getline(startline), startcol - 1)] +
- \ lines +
- \ [strpart(getline(endline), 0, endcol)]
- let objlength = 0
- for line in lines
- let objlength += strlen(line) + 1
- endfor
- let objlength -= 1
- endif
- if startcol > strlen(getline(startline))
- let startcol = 1
- let startline += 1
- let objlength -= 1
- endif
- call cursor(startline, startcol)
- exe 'normal! '.a:operator.objlength.' '
-
- if a:operator == 'c'
- normal! l
- startinsert
- elseif a:operator == 'v'
- exe "normal! \<BS>"
- endif
- endfunction
-
- exe 'onoremap <silent>a'.a:char.' <Esc>:call Textobj_'.g:text_object_number.'(0, v:operator, v:prevcount, "'.a:callback.'")<CR>'
- exe 'onoremap <silent>i'.a:char.' <Esc>:call Textobj_'.g:text_object_number.'(1, v:operator, v:prevcount, "'.a:callback.'")<CR>'
- exe 'xnoremap <silent>a'.a:char.' <Esc>:call Textobj_'.g:text_object_number.'(0, "v", v:prevcount, "'.a:callback.'")<CR>'
- exe 'xnoremap <silent>i'.a:char.' <Esc>:call Textobj_'.g:text_object_number.'(1, "v", v:prevcount, "'.a:callback.'")<CR>'
-endfunction
-" }}}
-" Text objects {{{
-" / for regex {{{
-function Textobj_regex(inner, count)
- let pos = getpos('.')
-
- let line = strpart(getline(pos[1]), 0, pos[2])
- let lines = getline(1, pos[1] - 1) + [line]
- let linenum = pos[1]
- for line in reverse(lines)
- let objstart = match(line, '.*\zs\\\@<!/') + 1
- if objstart != 0
- break
- endif
- let linenum -= 1
- endfor
- if objstart == 0
- throw 'no-match'
- endif
- let objstart += a:inner
- let objstartline = linenum
-
- let line = strpart(getline(pos[1]), pos[2] - 1)
- let lines = [line] + getline(pos[1] + 1, line('$'))
- let linenum = pos[1]
- for line in lines
- let objend = match(line, '\\\@<!/') + 1
- if objend != 0
- if linenum == pos[1]
- " have to account for the possibility of a split escape
- " sequence
- if objend == 1
- if getline(pos[1])[pos[2] - 2] == '\'
- let objend = match(line, '\\\@<!/', 1) + 1
- if objend == 0
- let linenum += 1
- continue
- endif
- else
- " if we're sitting on a /, don't do anything, since it's
- " impossible to know which direction to look
- throw 'no-match'
- endif
- endif
- let objend += pos[2] - 1
- endif
- break
- endif
- let linenum += 1
- endfor
- if objend == 0
- throw 'no-match'
- endif
- let objend -= a:inner
- let objendline = linenum
-
- return [objstartline, objstart, objendline, objend]
-endfunction
-call Textobj('/', 'Textobj_regex')
-" }}}
-" f for folds {{{
-function Textobj_fold(inner, count)
- if foldlevel(line('.')) == 0
- throw 'no-match'
- endif
- exe 'normal! '.a:count.'[z'
- let startline = line('.') + a:inner
- normal! ]z
- let endline = line('.') - a:inner
-
- return [startline, 1, endline, strlen(getline(endline))]
-endfunction
-call Textobj('f', 'Textobj_fold')
-" }}}
-" , for function arguments {{{
-function Textobj_arg(inner, count)
- let pos = getpos('.')
- let curchar = getline(pos[1])[pos[2] - 1]
- if curchar == ','
- if getline(pos[1])[pos[2] - 2] =~ '\s'
- normal! gE
- else
- exe "normal! \<BS>"
- endif
- return Textobj_arg(a:inner, a:count)
- elseif curchar =~ '\s'
- normal! W
- return Textobj_arg(a:inner, a:count)
- endif
-
- let line = strpart(getline(pos[1]), 0, pos[2])
- let lines = getline(1, pos[1] - 1) + [line]
- let linenum = pos[1]
- for line in reverse(lines)
- let argbegin = matchend(line, '.*\%(,\s*\|(\)') + 1
- if argbegin != 0
- while argbegin > strlen(line)
- let linenum += 1
- let line = getline(linenum)
- let argbegin = matchend(line, '^\s*') + 1
- endwhile
- break
- endif
- let linenum -= 1
- endfor
- if argbegin == 0
- throw 'no-match'
- endif
- let argstartline = linenum
-
- let line = strpart(getline(pos[1]), pos[2] - 1)
- let lines = [line] + getline(pos[1] + 1, line('$'))
- let linenum = pos[1]
- for line in lines
- let argend = match(line, '\zs.\?\%(,\|)\)') + 1
- if argend != 0
- if linenum == pos[1]
- let argend += pos[2] - 1
- endif
- if argend == 1 && getline(linenum)[argend - 1] == ')'
- let linenum -= 1
- let argend = strlen(getline(linenum))
- endif
- break
- endif
- let linenum += 1
- endfor
- if argend == 0
- throw 'no-match'
- endif
- let argendline = linenum
-
- if a:inner == 0
- let endline = getline(argendline)
- let startline = getline(argstartline)
- if argend >= strlen(endline)
- let argend = 0
- let argendline += 1
- let endline = getline(argendline)
- endif
- if endline[argend] == ')' && startline[argbegin - 2] != '('
- let argbegin = match(strpart(startline, 0, argbegin - 1), '\s*$')
- while argbegin == 0
- let argstartline -= 1
- let startline = getline(argstartline)
- let argbegin = strlen(startline)
- endwhile
- elseif endline[argend] != ')'
- let argend += matchend(strpart(endline, argend + 1), '^\s*') + 1
- if startline[argbegin - 2] == '('
- for line in [strpart(endline, argend)] +
- \ getline(argendline + 1, line('$'))
- let argincr = matchend(line, '\s*\ze\S')
- if argincr != -1
- let argend += argincr
- break
- endif
- let argendline += 1
- let argend = 0
- endfor
- endif
- endif
- if argend >= strlen(endline)
- if argendline == argstartline
- let newbegin = matchend(strpart(endline, 0, argbegin), '.*,')
- if newbegin != -1
- let argbegin = newbegin + 1
- endif
- endif
- let argend = 0
- let argendline += 1
- endif
- endif
-
- return [argstartline, argbegin, argendline, argend]
-endfunction
-call Textobj(',', 'Textobj_arg')
-" }}}
+" Textobj {{{
+let g:Textobj_regex_enable = 1
+let g:Textobj_fold_enable = 1
+let g:Textobj_arg_enable = 1
" }}}
" }}}