On 2013-02-17 Sunday at 22:15 +0100 Christian Brabandt wrote:
> On So, 17 Feb 2013, Bram Moolenaar wrote:
> 
> > I think using mb_string2cells() is wrong, because it counts double-wide
> > characters as two, while "l" counts them as one.
> 
> Oh, I didn't know that.
> 
> > How about using w_cursor.vcol but move with "|" instead of "l"?
> 
> You mean w_cursor.col and using '|' instead of 'l'. That won't help 
> here, I am afraid.
> 
> If we have a multi-byte built, we also have eval feature, right?
> So can't we use something like this:
> 
> norm! 06l
> if 1
>      call setpos('.', ....)
> endif
> 
> Since getpos() or winsaveview uses the byte-value of w_cursor.col this 
> should work.

The idea using setpos() looks promising.  Two patches in attachments, the first 
implements setpos() in src/ex_docmd.c, the second adds adapted v2 of my 
test{91,92} scripts.  In C locale and in en_US.ISO-8859-1 locale both tests 
succeed here, but in en_US.utf8 locale test91 fails and only test92 succeeds:

pushd path/to/sourcetree/vim-7.3.822
patch -N -p1 -u -i attachment1.patch
patch -N -p1 -u -i attachment2.patch
pushd src/testdir
rm -f test{91,92}.{out,failed,messages}
env {LANG,LC_CTYPE,LC_MESSAGES}=en_US.utf8 make -j1
> Test results:
> test91 FAILED

diff -u test91.{failed,ok}
> --- test91.failed       2013-02-18 19:10:56.448951101 +0100
> +++ test91.ok   2013-02-18 19:07:26.238965475 +0100
> @@ -1,6 +1,6 @@
>  call setpos('.', [0, line('.'), 16, 0])
>  call setpos('.', [0, line('.'), 16, 0])
>  call setpos('.', [0, line('.'), 16, 0])
> -call setpos('.', [0, line('.'), 15, 0])
> +call setpos('.', [0, line('.'), 16, 0])
>  call setpos('.', [0, line('.'), 16, 0])
>  call setpos('.', [0, line('.'), 16, 0])

grep '[=.]' test91.messages
> LANG=en_US.utf8
> LC_MESSAGES=en_US.utf8
> LC_ALL=
> test91.in
>   fileencoding=utf-8
>   termencoding=
>   encoding=utf-8

-- 
Regards
Roland Eggner
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -10824,19 +10824,23 @@ put_view(fd, wp, add_edit, flagp, curren
                            (long)wp->w_width / 2, (long)wp->w_width) < 0
                        || put_eol(fd) == FAIL
                        || put_line(fd, "if s:c > 0") == FAIL
+                       || put_line(fd,
+                           "  exe 'call setpos(\x27.\x27, [0, line(\x27.\x27), 
' . s:c + 1 . ', 0])'") == FAIL
                        || fprintf(fd,
-                           "  exe 'normal! 0' . s:c . 'lzs' . (%ld - s:c) . 
'l'",
+                           "  exe 'normal! zs' . (%ld - s:c) . 'l'",
                            (long)wp->w_cursor.col) < 0
                        || put_eol(fd) == FAIL
                        || put_line(fd, "else") == FAIL
-                       || fprintf(fd, "  normal! 0%dl", wp->w_cursor.col) < 0
+                       || fprintf(fd, "  call setpos('.', [0, line('.'), %d, 
0])",
+                           wp->w_cursor.col + 1) < 0
                        || put_eol(fd) == FAIL
                        || put_line(fd, "endif") == FAIL)
                    return FAIL;
            }
            else
            {
-               if (fprintf(fd, "normal! 0%dl", wp->w_cursor.col) < 0
+               if (fprintf(fd, "call setpos('.', [0, line('.'), %d, 0])",
+                           wp->w_cursor.col + 1) < 0
                        || put_eol(fd) == FAIL)
                    return FAIL;
            }
diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak
--- a/src/testdir/Make_amiga.mak
+++ b/src/testdir/Make_amiga.mak
@@ -32,7 +32,7 @@ SCRIPTS = test1.out test3.out test4.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 test88.out \
-               test89.out test90.out
+               test89.out test90.out test91.out test92.out
 
 .SUFFIXES: .in .out
 
@@ -139,3 +139,5 @@ test84.out: test84.in
 test88.out: test88.in
 test89.out: test89.in
 test90.out: test90.in
+test91.out: test91.in
+test92.out: test92.in
diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak
--- a/src/testdir/Make_dos.mak
+++ b/src/testdir/Make_dos.mak
@@ -31,7 +31,7 @@ SCRIPTS =     test3.out test4.out test5.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 test88.out \
-               test89.out test90.out
+               test89.out test90.out test91.out test92.out
 
 SCRIPTS32 =    test50.out test70.out
 
diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak
--- a/src/testdir/Make_ming.mak
+++ b/src/testdir/Make_ming.mak
@@ -51,7 +51,7 @@ SCRIPTS =     test3.out test4.out test5.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 test88.out \
-               test89.out test90.out
+               test89.out test90.out test91.out test92.out
 
 SCRIPTS32 =    test50.out test70.out
 
diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak
--- a/src/testdir/Make_os2.mak
+++ b/src/testdir/Make_os2.mak
@@ -32,7 +32,7 @@ SCRIPTS = test1.out test3.out test4.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 test88.out \
-               test89.out test90.out
+               test89.out test90.out test91.out test92.out
 
 .SUFFIXES: .in .out
 
diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -77,7 +77,7 @@ SCRIPT = test1.out  test2.out  test3.out
         test71.out test72.out test74.out test75.out test76.out \
         test77.out test78.out test79.out test80.out test81.out \
         test82.out test83.out test84.out test88.out test89.out \
-        test90.out
+        test90.out test91.out test92.out
 
 # Known problems:
 # Test 30: a problem around mac format - unknown reason
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -28,7 +28,7 @@ SCRIPTS = test1.out test2.out test3.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 test88.out \
-               test89.out test90.out
+               test89.out test90.out test91.out test92.out
 
 SCRIPTS_GUI = test16.out
 
@@ -58,7 +58,7 @@ clean:
 test1.out: test1.in
        -rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START)
        $(RUN_VIM) $*.in
-       @/bin/sh -c "if diff test.out $*.ok; \
+       @/bin/sh -c "if diff -u test.out $*.ok; \
                then mv -f test.out $*.out; \
                else echo; \
                echo test1 FAILED - Something basic is wrong; \
@@ -74,7 +74,7 @@ test1.out: test1.in
 
        # For flaky tests retry one time.
        @/bin/sh -c "if test -f test.out -a $* = test61; then \
-                 if diff test.out $*.ok; \
+                 if diff -u test.out $*.ok; \
                  then echo flaky test ok first time; \
                  else rm -rf $*.failed $(RM_ON_RUN); \
                        $(RUN_VIM) $*.in; \
@@ -83,7 +83,7 @@ test1.out: test1.in
 
        # Check if the test.out file matches test.ok.
        @/bin/sh -c "if test -f test.out; then\
-                 if diff test.out $*.ok; \
+                 if diff -u test.out $*.ok; \
                  then mv -f test.out $*.out; \
                  else echo $* FAILED >>test.log; mv -f test.out $*.failed; \
                  fi \
diff --git a/src/testdir/test91.in b/src/testdir/test91.in
new file mode 100644
--- /dev/null
+++ b/src/testdir/test91.in
@@ -0,0 +1,56 @@
+vim: set ft=vim fenc=utf-8:
+
+Tests if :mksession saves cursor columns correctly in presence of tab and 
+multibyte characters when fileencoding=utf-8.
+
+STARTTEST
+:so mbyte.vim
+:if !has('mksession')
+   e! test.ok
+   wq! test.out
+:endif
+:set sessionoptions=buffers splitbelow fileencoding=utf-8
+:" debugging stuff START
+:redir > test91.messages
+:echo 'LANG=' . ( exists('$LANG') ? $LANG : '' )
+:echo 'LC_MESSAGES=' . ( exists('$LC_MESSAGES') ? $LC_MESSAGES : '' )
+:echo 'LC_ALL=' . ( exists('$LC_ALL') ? $LC_ALL : '' )
+:echo bufname('%')
+:set fileencoding? termencoding? encoding?
+:redir END
+:" debugging stuff END
+:" Start test.  For each of 6 test text lines create another window and 
position 
+:" the cursor at column 7.  Session file written by :mksession must contain 
six 
+:" lines “call setpos”, we delete deviating lines and save result as 
“test.out”. 
+:" For debugging purpose additionally report &{file,term,}encoding.
+/^start:
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:mksession! test.out
+:e! test.out
+:v/^call setpos/d
+:wqa!
+ENDTEST
+
+start:
+no multibyte chAracter
+       one tab examplE example
+two            consecutivE tabs
+one … multibyTe character
+a “b” two mUltibyte characters
+“c”1€ thrEe multibyte characters
diff --git a/src/testdir/test91.ok b/src/testdir/test91.ok
new file mode 100644
--- /dev/null
+++ b/src/testdir/test91.ok
@@ -0,0 +1,6 @@
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
diff --git a/src/testdir/test92.in b/src/testdir/test92.in
new file mode 100644
--- /dev/null
+++ b/src/testdir/test92.in
@@ -0,0 +1,56 @@
+vim: set ft=vim fenc=latin1:
+
+Tests if :mksession saves cursor columns correctly in presence of tab and 
+multibyte characters when fileencoding=latin1.
+
+STARTTEST
+:so mbyte.vim
+:if !has('mksession')
+   e! test.ok
+   wq! test.out
+:endif
+:set sessionoptions=buffers splitbelow fileencoding=latin1
+:" debugging stuff START
+:redir > test92.messages
+:echo 'LANG=' . ( exists('$LANG') ? $LANG : '' )
+:echo 'LC_MESSAGES=' . ( exists('$LC_MESSAGES') ? $LC_MESSAGES : '' )
+:echo 'LC_ALL=' . ( exists('$LC_ALL') ? $LC_ALL : '' )
+:echo bufname('%')
+:set fileencoding? termencoding? encoding?
+:redir END
+:" debugging stuff END
+:" Start test.  For each of 6 test text lines create another window and 
position 
+:" the cursor at column 7.  Session file written by :mksession must contain 
six 
+:" lines 'call setpos', we delete deviating lines and save result as 
'test.out'.  
+:" For debugging purpose additionally report &{file,term,}encoding.
+/^start:
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:split
+:normal j
+:call setpos('.', [0, line('.'), 16, 0])
+:mksession! test.out
+:e! test.out
+:v/^call setpos/d
+:wqa!
+ENDTEST
+
+start:
+no multibyte chAracter
+       one tab examplE example
+two            consecutivE tabs
+one � multibytE character
+a� �  two mulTibyte characters
+A���  three Multibyte characters
diff --git a/src/testdir/test92.ok b/src/testdir/test92.ok
new file mode 100644
--- /dev/null
+++ b/src/testdir/test92.ok
@@ -0,0 +1,6 @@
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])
+call setpos('.', [0, line('.'), 16, 0])

Attachment: pgpQ8pvEE5rfU.pgp
Description: PGP signature

Raspunde prin e-mail lui