Update: Well, I made a plugin. Get it from ctholho/vim-textobj-sentence-line.
The plugin supports is
and as
motions. I didn't test all possible conditions but it does the job reliably. It also remaps the )
and (
motion to behave in the same way. Thanks to brhfl whose answer provided the building blocks for this.
Based on the answer of brhfl I cobbled something together that supports is
and as
. It still doesn't behave exactly like the old sentence text object and I post it here merely for completeness.
Install kana/vim-textobj-user and put this into your .vimrc.
function! NewSentence_inner()
call search('\(^\|\.\s\w\|\!\s\w\|?\s\w\)', 'bce')
let head_pos = getpos('.')
call search('\($\|\.\|\!\|?\)', 'ce')
let tail_pos = getpos('.')
return ['v',head_pos,tail_pos]
endfunction
function! NewSentence_outer()
call search('\(^\|\.\s\w\|\!\s\w\|?\s\w\)', 'bce')
let head_pos = getpos('.')
call search('\($\|\.\s\|\!\s\|?\s\)', 'e')
let tail_pos = getpos('.')
" handle last sentence of line, except if it's the only one
if col('.') == col('$') && getline('.') =~ '\(.\+\(\.\|\!\|?\)\)\{2,}'
let head_pos[2] = head_pos[2] - 1
let tail_pos[2] = tail_pos[2] - 1
endif
return ['v',head_pos,tail_pos]
endfunction
call textobj#user#plugin('fsent',{
\ 'fsent':{
\ 'select-i-function':'NewSentence_inner',
\ 'select-i':'is',
\ 'select-a-function':'NewSentence_outer',
\ 'select-a':'as',
\ },
\})
NewSentence_inner()
looks for the beginning of a line, the end of a sentence. The flags bce
mean that it looks in reverse, accepts matches under the cursor and moves the cursor to the end of the match. To get tail_pos
it looks for punctiation.
NewSentence_outer()
does the same but gives extra care to whitespace of the last sentence of a line.
if col('.') == col('$') && getline('.') =~ '\(.\+\(\.\|\!\|?\)\)\{2,}'
checks if it is at the last position of the line and if the line has at least two sentences. If that's the case the selection shifts one position to the left.