[ACCEPTED]-The behavior of ; to repeat the last t command bothers me. Can you help me make it better?-vim

Accepted answer
Score: 37

As of Vim version 7.3.235 this annoyance has been 10 amended. Now the default is the behaviour 9 you had expected in the first place: ; makes 8 the cursor jump to right before the second 7 "r".

This was the patch announcement:

Patch 6 7.3.235
Problem: ";" gets stuck 5 on a "t" command, it's not useful.
Solution: Add 4 the ';' flag in 'cpo'. (Christian Brabandt)

The 3 old behaviour has been demoted to a compatibility 2 option. You can bring it back with :set cpo+=;. See 1 :h cpo-;.

Score: 11

Maybe it's not the answer you are looking 14 for but I could not resist writing a VIM 13 script for this. I put it in my .vimrc and 12 it works for me:

map ; :call Semicolon()<CR>
function Semicolon()
   let s:pos1 = getpos(".")
   normal! ;
   let s:pos2 = getpos(".")
   if s:pos1 == s:pos2
      normal! 2;
   endif
endfunction 

The basic idea is that ; will 11 not move to the next match, but 2; will (if 10 there is a match). The script supports ; after 9 any of tTfF. The easiest way to implement the 8 , command is to write a similar function 7 for that.

EDIT Changed the script after Luc's 6 excellent suggestion

EDIT2

OK, these things are 5 always more difficult than I originally 4 think. The current mapping has the following 3 problems:

  1. Suppose you did a search like tr above. Now what should d; or c; do? As far as I'm concerned they should delete or change up until the first r not the second. This can be solved by only doing the mapping for normal and visual mode, not operator pending mode.
  2. The current mapping does not work in visual mode. i.e., if you type v;;;; after the first ; the editor is no longer in visual mode (because of the :call). This can be solved by calling the function using @= instead of :call.

So now I end up with the following 2 in my .vimrc (I also made one function for 1 , and ;):

" Remap ; and , commands so they also work after t and T
" Only do the remapping for normal and visual mode, not operator pending
" Use @= instead of :call to prevent leaving visual mode
nmap ; @=FixCommaAndSemicolon(";")<CR>
nmap , @=FixCommaAndSemicolon(",")<CR>
vmap ; @=FixCommaAndSemicolon(";")<CR>
vmap , @=FixCommaAndSemicolon(",")<CR>
function FixCommaAndSemicolon(command)
   let s:pos1 = getpos(".")
   execute "normal! " . a:command
   let s:pos2 = getpos(".")
   if s:pos1 == s:pos2
      execute "normal! 2" . a:command
   endif
   return ""
endfunction 
Score: 2

2 comments one: Can you map ; to the lt_ command 2 you are looking for? 2nd: Why not use 2tr 1 or /r followed by n instead?

Score: 1

It sounds like your problem is more with 6 the behaviour of t rather than ;.

In your example, lets 5 say you start at 'e':

stackov[e]rflow rocks

I'm guessing you'd 4 (reasonably) expect tr to jump forward to 3 [ ]rocks rather than staying in place.

If so, you 2 should leave ; as is and perhaps remap t to 1 lt or something.

More Related questions