Hello list

I have implemented a minor new feature, "g|": the screen-line
counterpart to the existing "|" command (jump to [count] screen column).

Rationale:
- The pipe command is the only way* to move the cursor to a specific
  virtual column; similarly, the new "g|" command would provide a way to
  move the cursor to a specific virtual column on the screen line.
- It blends in well with the existing screen-line movement commands, g0
  g^ g$ gm gk gj.
- It is a useful generalization of the existing "gm" (middle of screen
  line) command.

(* This can also be achieved with setpos(), but only in a roundabout
fashion by first checking 'virtualedit', then manually calculating the
offset if the cursor is on a tab character.)

I suppose this would primarily be useful in plugins, eg. plugins which
need to do precise Visual block selection of text columns etc.

What do you think?

(Diff applies to the latest version 7.3.633 of Vim.)

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
*** ../vim-7.3.633/src/normal.c	2012-08-17 17:00:59.217354453 +0200
--- src/normal.c	2012-08-17 17:03:19.521352232 +0200
***************
*** 8193,8198 ****
--- 8193,8239 ----
  	break;
  
      /*
+      * "g|", like "|" but for screen lines.
+      */
+     case '|':
+ 	cap->oap->motion_type = MCHAR;
+ 	cap->oap->inclusive = FALSE;
+ 	if (curwin->w_p_wrap
+ #ifdef FEAT_VERTSPLIT
+ 		&& curwin->w_width != 0
+ #endif
+ 	    )
+ 	{
+ 	    int width1 = W_WIDTH(curwin) - curwin_col_off();
+ 	    int width2 = width1 + curwin_col_off2();
+ 
+ 	    validate_virtcol();
+ 	    i = 0;
+ 	    if (curwin->w_virtcol >= (colnr_T)width1 && width2 > 0)
+ 		i = (curwin->w_virtcol - width1) / width2 * width2 + width1;
+ 	    if (cap->count0 > 0)
+ 	    {
+ 		if (i >= width1)
+ 		    i += (cap->count0 >= width2 ? width2 : cap->count0) - 1;
+ 		else
+ 		    i += (cap->count0 >= width1 ? width1 : cap->count0) - 1;
+ 	    }
+ 	}
+ 	else
+ 	{
+ 	    i = curwin->w_leftcol;
+ 	    if (cap->count0 > 0)
+ 		i += ((cap->count0 > W_WIDTH(curwin) - curwin_col_off())
+ 		    ? W_WIDTH(curwin) - curwin_col_off() : cap->count0) - 1;
+ 	}
+ 	coladvance((colnr_T)i);
+ 
+ 	/* Make sure we stay in this column. */
+ 	curwin->w_curswant = i;
+ 	curwin->w_set_curswant = FALSE;
+ 	break;
+ 
+     /*
       * "g*" and "g#", like "*" and "#" but without using "\<" and "\>"
       */
      case '*':
*** ../vim-7.3.633/runtime/doc/index.txt	2012-08-17 17:00:58.521354466 +0200
--- runtime/doc/index.txt	2012-08-17 17:22:29.349334051 +0200
***************
*** 409,415 ****
  |yy|		["x]yy		   yank N lines [into buffer x]
  |z|		z{char}		   commands starting with 'z', see |z| below
  |{|		{		1  cursor N paragraphs backward
! |bar|		|		1  cursor to column N
  |}|		}		1  cursor N paragraphs forward
  |~|		~		2  'tildeop' off: switch case of N characters
  				   under cursor and move the cursor N
--- 409,415 ----
  |yy|		["x]yy		   yank N lines [into buffer x]
  |z|		z{char}		   commands starting with 'z', see |z| below
  |{|		{		1  cursor N paragraphs backward
! |bar|		|		1  cursor to screen column N
  |}|		}		1  cursor N paragraphs forward
  |~|		~		2  'tildeop' off: switch case of N characters
  				   under cursor and move the cursor N
***************
*** 767,772 ****
--- 767,776 ----
  |gw|		gw{motion}	2  format Nmove text and keep cursor
  |netrw-gx|	gx		   execute application for file name under the
  				   cursor (only with |netrw| plugin)
+ |gbar|		g|		1  when 'wrap' off go to screen column N of
+ 				   the current line that is on the screen;
+ 				   when 'wrap' on go to screen column N of the
+ 				   current screen line
  |g@|		g@{motion}	   call 'operatorfunc'
  |g~|		g~{motion}	2  swap case for Nmove text
  |g<Down>|	g<Down>		1  same as "gj"
*** ../vim-7.3.633/runtime/doc/motion.txt	2012-08-17 17:00:58.529354466 +0200
--- runtime/doc/motion.txt	2012-08-17 17:03:19.409352232 +0200
***************
*** 241,246 ****
--- 241,255 ----
  |			To screen column [count] in the current line.
  			|exclusive| motion.  Ceci n'est pas une pipe.
  
+ 							*gbar*
+ g|			When lines wrap ('wrap' on): To screen column [count]
+ 			in the current screen line.  |exclusive| motion.
+ 			When lines don't wrap ('wrap' off): To screen column
+ 			[count] of the current line that is visible on the
+ 			screen.
+ 			Differs from "|" when a line is wider than the screen.
+ 			{not in Vi}
+ 
  							*f*
  f{char}			To [count]'th occurrence of {char} to the right.  The
  			cursor is placed on {char} |inclusive|.
*** ../vim-7.3.633/runtime/doc/quickref.txt	2012-08-17 17:00:58.549354465 +0200
--- runtime/doc/quickref.txt	2012-08-13 17:46:05.424773450 +0200
***************
*** 47,53 ****
  |g$|	N  g$		to last character in screen line (differs from "$"
  			   when lines wrap)
  |gm|	   gm		to middle of the screen line
! |bar|	N  |		to column N (default: 1)
  |f|	N  f{char}	to the Nth occurrence of {char} to the right
  |F|	N  F{char}	to the Nth occurrence of {char} to the left
  |t|	N  t{char}	till before the Nth occurrence of {char} to the right
--- 47,55 ----
  |g$|	N  g$		to last character in screen line (differs from "$"
  			   when lines wrap)
  |gm|	   gm		to middle of the screen line
! |bar|	N  |		to screen column N (default: 1)
! |gbar|	N  g|		to screen column N of the screen line (differs from
! 			   "|" when lines wrap)
  |f|	N  f{char}	to the Nth occurrence of {char} to the right
  |F|	N  F{char}	to the Nth occurrence of {char} to the left
  |t|	N  t{char}	till before the Nth occurrence of {char} to the right

Raspunde prin e-mail lui