In normal mode ( and ) move to the previous or next first character in the sentence, respectively.How do I move to the very last character.If all of my sentences end with a period I can use )T. (first character of the next sentence, then backwards to the first period) but I want a more robust solution to use in a macro.I know about as and is while in visual mode, so vis<ESC> works (visual mode, then select inside the sentence, then exit visual mode), but that seemspretty ugly to me, and I can't use it as a motion with other commands.I'm at a loss.  Help!
How do I move to the last character in a sentence?
cursor movement;cursor motions
From my research into this, you need to define at least two custom motions. The first will be for just moving the cursor, and the second will be for use in operators. For a full functioning setup, it is much more complicated, and I would recommend looking at the code in CamelCaseMotion by Ingo Karkat which shows significantly more thought on doing this right than I do below. Most of my answer is based on quick information found in Vim help and experimentation.In the following examples, I'm going to remap the ) and ( motions to do the each end of a sentence. You can use other characters as you wish by modifying the example. I'm also going your example of vis<ESC> as the more robust option (compared to )T.). In doing so, if you are already at the end of a sentence, you end up staying at the end instead of moving to the end after this one, because of the way is works. You can try replacing it with as for different results. This should actually work for turning either side of a text object into a motion.First, the normal mode movementNote This doesn't work in visual mode or operator pending modefunction! MoveToEnd(type, ...)    exe normal `]endfunctionmap <silent> \) :set opfunc=MoveToEnd<CR>g@nmap ) \)isFirst, we define a new function called MoveToEnd whose sole job is to put the cursor at the the last character of the previously changed or yanked text, which is the ] mark (see :help ']).Next, we create a custom operator \) that calls our MoveToEnd function on whatever motion is given to it. In this way, the ] mark becomes the end of the selection given to our new operator. (see :help map-operator)Finally, we map ) to call our custom operator with the is mostion, thereby effectively giving the equivalent of vis<ESC> without changing the last visual selection and without changing modes.The reverse is similar, just using the other directions:function! MoveToBeginning(type, ...)    exe normal `[endfunctionmap <silent> \( :set opfunc=MoveToBeginning<CR>g@:nmap ( \(isSecond, the operator movementThis one is trickier. Our motion above destroys the start position, so operators like 'd' end up working against nothing. What we need is to be able to save our start position and add the end position. :help omap-info (operator pending mapping) gives a tip on doing this, which is to actually use visual mode.What we'll do then, is save our position to one end of the visual selection register, use our normal mode motion from above, set the other visual selection register, and then activate visual mode:function! SelectToEnd()    normal m<  Set start point of visual selection    normal )   Move to end of sentance (relies on mapping from earlier)    normal m>  Set end point of visual selection    normal gv   'Go Visual' activate visual mode using selection marksendfunctionomap ) :call SelectToEnd()<CR>And for our back motion:function! SelectToBeginning()    normal m>  Set end point to current position (since we are moving backwards)    normal (   Move to beginning of sentence (relies on mapping from earlier)    normal m<  Set start point    normal gv  Activate visual mode based on our new marksendfunctionomap ( :call SelectToBeginning()With this, you can do d) to delete to the end of the sentence (instead of the original of deleting to the beginning of the next one). All other operators should work as well.