On Fri, Sep 07, 2012 at 04:20:40AM +0200, Dominique Pellé wrote:
> Thanks Simon for the patch!  Some remarks:

Hello Dominique,

> - It's better to send the patch as attachment because long
>   lines were messed up by mail somehow.

Thanks for the suggestion, will do it in the future. It's weird
though, plain text patches work fine for other projects.

> - I manually fixed the long lines in patch and it applied.
>   But I saw a warning:
>
>   Hunk #1 succeeded at 1902 with fuzz 2 (offset -1 lines).
>
>   The patch was probably not made against the latest Vim
>   in Mercurial.

Maybe a few of my local commits interfered, sorry for that.

> - declaration of screen_screencol() and screen_screenrow()
>   were missing in src/proto/screen.c.pro, so when compiling,
>   I saw warnings:
>
> screen.c:10260:1: warning: no previous prototype for
> ‘screen_screencol’ [-Wmissing-prototypes]
> screen.c:10269:1: warning: no previous prototype for
> ‘screen_screenrow’ [-Wmissing-prototypes]

Thank you, somehow I didn't see those warnings.

> - in ":help screenrow()"  I noticed a repeated word in:
>   "screen row of *the the* cursor

Thanks.

> I attach a patch against Vim-7.3.659 which:
>
> - addresses all above minor issues
> - combine my original patch with your tests in one single
>   patch for convenience.

Thanks. One minor issue though, the additional documentation for
screen_screencol()/_screenrow() is not correct, because it starts
from 0 (because I wanted to "export" the static variable
unchanged). The functions in eval.c start from 1.

I updated the comment in the attached patch.

> PS: worth noticing that instead of...
>
> nnoremap <expr> GG ":echom ".screencol()."\n"
>
> ... we can also use:
>
> nnoremap <silent> GG :echom screencol()<CR>

Thanks, I added this as another example to the documentation.

Revised patch (this time definitely from hg tip) attached.

Regards,
Simon
-- 
+ privacy is necessary
+ using gnupg http://gnupg.org
+ public key id: 0x92FEFDB7E44C32F9
From 8e01f47fda8f6e4f6dee2431b0c3c70dfda5ba65 Mon Sep 17 00:00:00 2001
Message-Id: <8e01f47fda8f6e4f6dee2431b0c3c70dfda5ba65.1347025877.git.si...@ruderich.org>
From: Simon Ruderich <[email protected]>
Date: Fri, 7 Sep 2012 15:46:32 +0200
Subject: [PATCH] Add screencol() and screenrow(), add tests for +conceal.

---
 runtime/doc/eval.txt  |   23 ++++++++++++-
 src/eval.c            |   28 ++++++++++++++++
 src/proto/screen.pro  |    2 +
 src/screen.c          |   35 +++++++++++++++++++-
 src/testdir/Makefile  |    4 +-
 src/testdir/test88.in |   85 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/testdir/test88.ok |   23 +++++++++++++
 7 files changed, 195 insertions(+), 5 deletions(-)
 create mode 100644 src/testdir/test88.in
 create mode 100644 src/testdir/test88.ok

diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 2ae65ff..08499cb 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1903,6 +1903,8 @@ repeat( {expr}, {count})	String	repeat {expr} {count} times
 resolve( {filename})		String	get filename a shortcut points to
 reverse( {list})		List	reverse {list} in-place
 round( {expr})			Float	round off {expr}
+screencol()			Number	current cursor column
+screenrow()			Number	current cursor row
 search( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
 				Number	search for {pattern}
 searchdecl( {name} [, {global} [, {thisblock}]])
@@ -4866,8 +4868,25 @@ round({expr})							*round()*
 			echo round(-4.5)
 <			-5.0
 		{only available when compiled with the |+float| feature}
-		
-		
+
+screencol()							*screencol()*
+		The result is a Number, which is the current screen column of
+		the cursor. This function is mainly used for testing.
+
+		Note: Always returns the current screen column, thus if used
+		in a command (e.g. ":echo screencol()") it will return the
+		column inside the command line, which is 1 when the command is
+		executed. To get the cursor position in the file use one of
+		the following mappings: >
+			nnoremap <expr> GG ":echom ".screencol()."\n"
+			nnoremap <silent> GG :echom screencol()<CR>
+<
+screenrow()							*screenrow()*
+		The result is a Number, which is the current screen row of the
+		cursor. This function is mainly used for testing.
+
+		Note: Same restrictions as |screencol()|.
+
 search({pattern} [, {flags} [, {stopline} [, {timeout}]]])	*search()*
 		Search for regexp pattern {pattern}.  The search starts at the
 		cursor position (you can use |cursor()| to set it).
diff --git a/src/eval.c b/src/eval.c
index 98b2a33..1ac27de 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -668,6 +668,8 @@ static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv));
 #ifdef FEAT_FLOAT
 static void f_round __ARGS((typval_T *argvars, typval_T *rettv));
 #endif
+static void f_screencol __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_screenrow __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_search __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv));
@@ -8032,6 +8034,8 @@ static struct fst
 #ifdef FEAT_FLOAT
     {"round",		1, 1, f_round},
 #endif
+    {"screencol",	0, 0, f_screencol},
+    {"screenrow",	0, 0, f_screenrow},
     {"search",		1, 4, f_search},
     {"searchdecl",	1, 3, f_searchdecl},
     {"searchpair",	3, 7, f_searchpair},
@@ -15717,6 +15721,30 @@ f_round(argvars, rettv)
 #endif
 
 /*
+ * "screencol()" function
+ *
+ * First column start as 1 to be consistent with virtcol().
+ */
+    static void
+f_screencol(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = screen_screencol() + 1;
+}
+
+/*
+ * "screenrow()" function
+ */
+    static void
+f_screenrow(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_number = screen_screenrow() + 1;
+}
+
+/*
  * "search()" function
  */
     static void
diff --git a/src/proto/screen.pro b/src/proto/screen.pro
index be791e0..33d584e 100644
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -50,4 +50,6 @@ int redrawing __ARGS((void));
 int messaging __ARGS((void));
 void showruler __ARGS((int always));
 int number_width __ARGS((win_T *wp));
+int screen_screencol __ARGS((void));
+int screen_screenrow __ARGS((void));
 /* vim: set ft=c : */
diff --git a/src/screen.c b/src/screen.c
index 92eb232..ff34477 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -4269,7 +4269,20 @@ win_line(wp, lnum, startrow, endrow, nochange)
 		{
 		    /* tab amount depends on current column */
 		    n_extra = (int)wp->w_buffer->b_p_ts
-				   - VCOL_HLC % (int)wp->w_buffer->b_p_ts - 1;
+					- vcol % (int)wp->w_buffer->b_p_ts - 1;
+#ifdef FEAT_CONCEAL
+		    /* Tab alignment should be identical regardless of
+		     * 'conceallevel' value. So tab compensates of all
+		     * previous concealed characters, and thus resets
+		     * vcol_off and boguscols accumulated so far in the
+		     * line. Note that the tab can be longer than 'tabstop'
+		     * when there are concealed characters. */
+		    n_extra += vcol_off;
+		    vcol -= vcol_off;
+		    vcol_off = 0;
+		    col -= boguscols;
+		    boguscols = 0;
+#endif
 #ifdef FEAT_MBYTE
 		    mb_utf8 = FALSE;	/* don't draw as UTF-8 */
 #endif
@@ -10251,3 +10264,23 @@ number_width(wp)
     return n;
 }
 #endif
+
+/*
+ * Return the current cursor column. This is the actual position on the
+ * screen. First column start as 0.
+ */
+    int
+screen_screencol()
+{
+    return screen_cur_col;
+}
+
+/*
+ * Return the current cursor row. This is the actual position on the screen.
+ * First row starts at 0.
+ */
+    int
+screen_screenrow()
+{
+    return screen_cur_row;
+}
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index 20d9781..936bca9 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -13,7 +13,7 @@ VIMPROG = ../vim
 
 SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
 		test7.out test8.out test9.out test10.out test11.out \
-		test12.out  test13.out test14.out test15.out test17.out \
+		test12.out test13.out test14.out test15.out test17.out \
 		test18.out test19.out test20.out test21.out test22.out \
 		test23.out test24.out test25.out test26.out test27.out \
 		test28.out test29.out test30.out test31.out test32.out \
@@ -27,7 +27,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
 		test69.out test70.out test71.out test72.out test73.out \
 		test74.out test75.out test76.out test77.out test78.out \
 		test79.out test80.out test81.out test82.out test83.out \
-		test84.out test85.out test86.out test87.out
+		test84.out test85.out test86.out test87.out test88.out \
 
 SCRIPTS_GUI = test16.out
 
diff --git a/src/testdir/test88.in b/src/testdir/test88.in
new file mode 100644
index 0000000..1536b3b
--- /dev/null
+++ b/src/testdir/test88.in
@@ -0,0 +1,85 @@
+vim: set ft=vim
+
+Tests for correct display (cursor column position) with +conceal and
+tabulators.
+
+STARTTEST
+:so small.vim
+:if !has('conceal')
+   e! test.ok
+   wq! test.out
+:endif
+:" Conceal settings.
+:set conceallevel=2
+:set concealcursor=nc
+:syntax match test /|/ conceal
+:" Save current cursor position. Only works in <expr> mode, can't be used
+:" with :normal because it moves the cursor to the command line. Thanks to ZyX
+:" <[email protected]> for the idea to use an <expr> mapping.
+:let positions = []
+:nnoremap <expr> GG ":let positions += ['".screenrow().":".screencol()."']\n"
+:" Start test.
+/^start:
+:normal ztj
+GGk
+:" We should end up in the same column when running these commands on the two
+:" lines.
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j
+GGk
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j0j
+GGk
+:" Same for next test block.
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j
+GGk
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j0j
+GGk
+:" And check W with multiple tabs and conceals in a line.
+:normal W
+GGk
+:normal W
+GGk
+:normal W
+GGk
+:normal $
+GGk
+:normal 0j
+GGk
+:normal W
+GGk
+:normal W
+GGk
+:normal W
+GGk
+:normal $
+GGk
+:" Display result.
+:call append('$', 'end:')
+:call append('$', positions)
+:/^end/,$wq! test.out
+ENDTEST
+
+start:
+.concealed.     text
+|concealed|	text
+
+	.concealed.	text
+	|concealed|	text
+
+.a.	.b.	.c.	.d.
+|a|	|b|	|c|	|d|
diff --git a/src/testdir/test88.ok b/src/testdir/test88.ok
new file mode 100644
index 0000000..e726258
--- /dev/null
+++ b/src/testdir/test88.ok
@@ -0,0 +1,23 @@
+end:
+2:1
+2:17
+2:20
+3:1
+3:17
+3:20
+5:8
+5:25
+5:28
+6:8
+6:25
+6:28
+8:1
+8:9
+8:17
+8:25
+8:27
+9:1
+9:9
+9:17
+9:25
+9:26
-- 
1.7.7.3

Attachment: pgpHYKTjHxMQs.pgp
Description: PGP signature

Raspunde prin e-mail lui