Hi Urtica!

On Do, 25 Jun 2015, Urtica dioica wrote:

> I've only been playing with this for a few minutes, but there are lots of 
> problems.
> 
> 1. vg<C-A> with :se nf=alpha doesn't do letters.
> 
> a
> a
> a
> --- :se nf=alpha<CR>VGg<C-A>
> b
> b
> b

That was intentionally, I didn't think this would be useful.
Should be fixed with the attached patch.

> 
> 2. Minus signs are never added or removed.
> 
> 0
> --- V<C-X>
> 1
> 
> Another:
> 
> -1
> --- V3<C-A>
> -2

Should be fixed with the attached patch.

> 
> 3. Even if multiple columns are selected, it acts on only one column. The 
> column it selects can be unusual.
> 
> This makes sense:
> 
> 0x9
> 0x9
> 0x9
> --- <C-V>3$<C-A>
> 0xa
> 0xa
> 0xa
> 
> This uses the same visual area, but with a different result:
> 
> 0x9
> 0x9
> 0x9
> --- $<C-V>++<C-A>
> 0x10
> 0x10
> 0x10

Should be fixed with the attached patch.

> 
> This increments a number that wasn't in the visual area:
> 
> 0 0
> 0 0
> 0 0
> --- $v++<C-A>
> 0 1
> 0 1
> 0 1

Should work now.

> 
> 4. If you dot repeat, you get an ordinary C-X/C-A.
> 
> 0x0
> 0x0
> --- $<C-V>j10<C-A>.
> 0x10
> 0x1a

> 
> Note that the cursor ends at the bottom-right, opposite of most visual mode 
> commands. This makes useful dot repeats difficult.

This is tricky. It seems, taking care of the visual selection for redo 
is usually done in do_pending_operator(). However since <C-A>/<C-X> is 
no ordinary operation, do_pending_operator is never completely called. I 
have added some logic for taking care of linewise selection, since those 
seems to be most useful most of the time. Not sure how to handle block- 
or characterwise selections correctly (or where). 

> 5. Overflow.
> 
> 1
> 1
> 1
> --- VGg<C-X>
> 0
> 18446744073709551615
> 18446744073709551614

Fixed.

> Found another one. If the column we're adding to has a line that 
> doesn't extend long enough, every line after that will be ignored.
> 
> Lines 1-2, 4-5 are indented. The middle line has no character in column 2. 
> The middle line gets incremented despite not being in the visual area, while 
> the lines below are ignored:
> 
>  1
>  1
> 1
>  1
>  1
> --- $<C-V>G<C-A>
>  2
>  2
> 2
>  1
>  1

Fixed.

> 
> It's also interesting how line visual works. It only applies to lines that 
> start with a number:
> 
> 1
> --- >>V<C-A>
>         1


I believe this is correct.

Attached patch addresses these issues and adds more tests.

Best,
Christian
-- 
Am Anfang gehören alle Gedanken der Liebe. Später gehört dann alle
Liebe den Gedanken.
                -- Albert Einstein

-- 
-- 
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

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/normal.c b/src/normal.c
--- a/src/normal.c
+++ b/src/normal.c
@@ -4204,7 +4204,24 @@ nv_addsub(cap)
     int visual = VIsual_active;
     if (cap->oap->op_type == OP_NOP
 	    && do_addsub((int)cap->cmdchar, cap->count1, cap->arg) == OK)
-	prep_redo_cmd(cap);
+    {
+	if (visual)
+	{
+	    ResetRedobuff();
+	    AppendCharToRedobuff(VIsual_mode);
+	    if (VIsual_mode == 'V')
+	    {
+		AppendNumberToRedobuff(cap->oap->line_count);
+		AppendCharToRedobuff('j');
+	    }
+	    AppendNumberToRedobuff(cap->count1);
+	    if (cap->nchar != NUL)
+		AppendCharToRedobuff(cap->nchar);
+	    AppendCharToRedobuff(cap->cmdchar);
+	}
+	else
+	    prep_redo_cmd(cap);
+    }
     else
 	clearopbeep(cap->oap);
     if (visual)
diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -5386,7 +5386,7 @@ do_addsub(command, Prenum1, g_cmd)
     int		hex;		/* 'X' or 'x': hex; '0': octal */
     static int	hexupper = FALSE;	/* 0xABC */
     unsigned long n;
-    long	offset = 0;		/* line offset for Ctrl_V mode */
+    unsigned long offset = 0;		/* line offset for Ctrl_V mode */
     long_u	oldn;
     char_u	*ptr;
     int		c;
@@ -5398,10 +5398,12 @@ do_addsub(command, Prenum1, g_cmd)
     int		firstdigit;
     int		subtract;
     int		negative = FALSE;
+    int		was_positive = TRUE;
     int		visual = VIsual_active;
     int		i;
     int		lnum = curwin->w_cursor.lnum;
     int		lnume = curwin->w_cursor.lnum;
+    int		startcol;
 
     dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL);	/* "heX" */
     dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL);	/* "Octal" */
@@ -5431,14 +5433,14 @@ do_addsub(command, Prenum1, g_cmd)
 	curbuf->b_visual.vi_end = curwin->w_cursor;
 	curbuf->b_visual.vi_mode = VIsual_mode;
 
-	col = VIsual.col;
+	if (VIsual_mode != 'v')
+	    startcol = VIsual.col < curwin->w_cursor.col ? VIsual.col
+		: curwin->w_cursor.col;
+	else
+	    startcol = VIsual.col;
+	col = startcol;
 	lnum = VIsual.lnum;
 	lnume = curwin->w_cursor.lnum;
-	if (ptr[col] == '-')
-	{
-	    negative = TRUE;
-	    col++;
-	}
     }
     else
     {
@@ -5481,9 +5483,16 @@ do_addsub(command, Prenum1, g_cmd)
     {
 	curwin->w_cursor.lnum = i;
 	ptr = ml_get_curline();
+	if ((int)STRLEN(ptr) <= col)
+	    /* try again on next line */
+	    continue;
+	if (visual && ptr[col] == '-')
+	{
+	    negative = TRUE;
+	    was_positive = FALSE;
+	    col++;
+	}
 	RLADDSUBFIX(ptr);
-	if ((int)STRLEN(ptr) <= col)
-	    col = 0;
 	/*
 	 * If a number was found, and saving for undo works, replace the number.
 	 */
@@ -5598,6 +5607,14 @@ do_addsub(command, Prenum1, g_cmd)
 		    negative = FALSE;
 	    }
 
+	    if (visual && !was_positive && !negative)
+	    {
+		/* need to remove the '-' */
+		col--;
+		length++;
+	    }
+
+
 	    /*
 	     * Delete the old number.
 	     */
@@ -5634,8 +5651,7 @@ do_addsub(command, Prenum1, g_cmd)
 	    if (buf1 == NULL)
 		return FAIL;
 	    ptr = buf1;
-	    /* do not add leading '-' for visual mode */
-	    if (negative && !visual)
+	    if (negative && (!visual || (visual && was_positive)))
 	    {
 		*ptr++ = '-';
 	    }
@@ -5654,23 +5670,15 @@ do_addsub(command, Prenum1, g_cmd)
 	     * Put the number characters in buf2[].
 	     */
 	    if (hex == 0)
-		sprintf((char *)buf2, "%lu", n + offset);
+		sprintf((char *)buf2, "%lu", n);
 	    else if (hex == '0')
-		sprintf((char *)buf2, "%lo", n + offset);
+		sprintf((char *)buf2, "%lo", n);
 	    else if (hex && hexupper)
-		sprintf((char *)buf2, "%lX", n + offset);
+		sprintf((char *)buf2, "%lX", n);
 	    else
-		sprintf((char *)buf2, "%lx", n + offset);
+		sprintf((char *)buf2, "%lx", n);
 	    length -= (int)STRLEN(buf2);
 
-	    if (g_cmd)
-	    {
-		if (subtract)
-		    offset -= (unsigned long)Prenum1;
-		else
-		    offset += (unsigned long)Prenum1;
-	    }
-
 	    /*
 	     * Adjust number of zeros to the new number of digits, so the
 	     * total length of the number remains the same.
@@ -5685,13 +5693,27 @@ do_addsub(command, Prenum1, g_cmd)
 	    ins_str(buf1);		/* insert the new number */
 	    vim_free(buf1);
 	}
-	--curwin->w_cursor.col;
+
+	if (g_cmd)
+	{
+	    offset = (unsigned long)Prenum1;
+	    g_cmd = 0;
+	}
+	/* reset */
+	subtract = FALSE;
+	negative = FALSE;
+	if (visual && VIsual_mode != Ctrl_V)
+	    col = 0;
+	else
+	    col = startcol;
+	Prenum1 += offset;
 	curwin->w_set_curswant = TRUE;
 #ifdef FEAT_RIGHTLEFT
 	ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
 	RLADDSUBFIX(ptr);
 #endif
     }
+    --curwin->w_cursor.col;
     return OK;
 }
 
diff --git a/src/testdir/test_increment.in b/src/testdir/test_increment.in
--- a/src/testdir/test_increment.in
+++ b/src/testdir/test_increment.in
@@ -6,6 +6,7 @@ Test cases
 1) Ctrl-A on visually selected number
 Text:
 foobar-10
+    Expected:
     1)    Ctrl-A on start of line:
 	foobar-9
     2)    Ctrl-A on visually selected "-10":
@@ -24,6 +25,7 @@ 20
 30
 40
 
+    Expected:
     1) Ctrl-A on visually selected lines:
 11
 21
@@ -46,6 +48,7 @@ 30
 
 40
 
+    Expected:
     1) 2 g Ctrl-A on visually selected lines:
 12
 
@@ -66,24 +69,137 @@ 32
 4) Ctrl-A on non-number
 Text:
 foobar-10
+    Expected:
     1) visually select foobar:
     foobar-10
 
+5) g<Ctrl-A> on letter
+Test:
+a
+a
+a
+a
+    Expected:
+    1) g Ctrl-A on visually selected lines
+    b
+    c
+    d
+    e
+
+6) g<Ctrl-A> on letter
+Test:
+z
+z
+z
+z
+    Expected:
+    1) g Ctrl-X on visually selected lines
+    y
+    x
+    w
+    v
+
+7) <Ctrl-A> on letter
+Test:
+2
+1
+0
+-1
+-2
+
+    Expected:
+    1) Ctrl-A on visually selected lines
+    3
+    2
+    1
+    0
+    -1
+
+    2) Ctrl-X on visually selected lines
+    1
+    0
+    -1
+    -2
+    -3
+8) Block increment on 0x9
+Text:
+0x9
+0x9
+    Expected:
+    1) Ctrl-A on visually block selected region (cursor at beginning):
+    0xa
+    0xa
+    2) Ctrl-A on visually block selected region (cursor at end)
+    0xa
+    0xa
+
+9) Increment and redo
+Text:
+2
+2
+
+3
+3
+
+    Expected:
+    1) 2 Ctrl-A on first 2 visually selected lines
+    4
+    4
+    2) redo (.) on 3
+    5
+    5
+10) sequentially decrement 1
+Text:
+1
+1
+1
+1
+    Expected:
+    1) g Ctrl-X on visually selected lines
+    0
+    -1
+    -2
+    -3
+
+11) visually block selected indented lines
+Text:
+    1
+1
+    1
+    1
+    Expexted:
+    1) g Ctrl-A on block selected indented lines
+    2
+1
+    3
+    4
+
+12) visually selected several columns
+Text:
+0 0
+0 0
+0 0
+    Expected:
+    1) 'v' select last zero and first zeroes
+    0 1
+    1 0
+    1 0
+
 STARTTEST
 :so small.vim
 
 :" Test 1
 :/^S1=/+,/^E1=/-y a
-:/^E1/+put a
-:/^E1/+2put a
-f-v$:/^E1/+3put a
-f1v$:/^E1/+4put a
-f-v$:/^E1/+5put a
+:/^E1=/+put a
+:/^E1=/+2put a
+f-v$:/^E1=/+3put a
+f1v$:/^E1=/+4put a
+f-v$:/^E1=/+5put a
 f1v$
 
 :" Test 22
 :/^S2=/+,/^E2=/-y a
-:/^E2/+put a
+:/^E2=/+put a
 V3k$:.+put a
 V3k$
 
@@ -98,6 +214,49 @@ V6k2g
 :/^E4=/+put a
 vf-
 
+:" Test 5
+:set nrformats+=alpha
+:/^S5=/+,/^E5=/-y a
+:/^E5=/+put a
+v3kg
+
+:" Test 6
+:/^S6=/+,/^E6=/-y a
+:/^E6=/+put a
+v3kg
+
+:" Test 7
+:/^S7=/+,/^E7=/-y a
+:/^E7=/+put a
+V4k:.+put a
+V4k
+
+:" Test 8
+:/^S8=/+,/^E8=/-y a
+:/^E8=/+put a
+kj$:.+put a
+k$+
+
+:" Test 9
+:/^S9=/+,/^E9=/-y a
+:/^E9=/+put a
+5kVj22j.
+
+:" Test 10
+:/^S10=/+,/^E10=/-y a
+:/^E10=/+put a
+V3kg
+
+: Test 11
+:/^S11=/+,/^E11=/-y a
+:/^E11=/+put a
+3kf13jg
+
+:" Test 12
+:/^S12=/+,/^E12=/-y a
+:/^E12=/+put a
+2k$v++
+
 :" Save the report
 :/^# Test 1/,$w! test.out
 :qa!
@@ -139,5 +298,93 @@ foobar-10
 E4=====
 
 
+
+# Test 5
+S5====
+a
+a
+a
+a
+E5====
+
+
+# Test 6
+S6====
+z
+z
+z
+z
+E6====
+
+
+
+# Test 7
+S7====
+2
+1
+0
+-1
+-2
+E7====
+
+
+
+# Test 8
+S8====
+0x9
+0x9
+E8====
+
+
+
+
+# Test 9
+S9====
+2
+2
+
+3
+3
+
+E9====
+
+
+
+
+# Test 10
+S10====
+1
+1
+1
+1
+E10====
+
+
+
+
+# Test 11
+S11====
+    1
+1
+    1
+    1
+E11====
+
+
+
+# Test 12
+S12====
+0 0
+0 0
+0 0
+E12====
+
+
+
+
+
+
+
+
 ENDTEST
 
diff --git a/src/testdir/test_increment.ok b/src/testdir/test_increment.ok
--- a/src/testdir/test_increment.ok
+++ b/src/testdir/test_increment.ok
@@ -62,5 +62,132 @@ E4=====
 
 foobar-10
 
+
+# Test 5
+S5====
+a
+a
+a
+a
+E5====
+
+b
+c
+d
+e
+
+# Test 6
+S6====
+z
+z
+z
+z
+E6====
+
+y
+x
+w
+v
+
+
+# Test 7
+S7====
+2
+1
+0
+-1
+-2
+E7====
+
+3
+2
+1
+0
+-1
+
+1
+0
+-1
+-2
+-3
+
+# Test 8
+S8====
+0x9
+0x9
+E8====
+
+0xa
+0xa
+
+0xa
+0xa
+
+
+# Test 9
+S9====
+2
+2
+
+3
+3
+
+E9====
+
+4
+4
+
+5
+5
+
+
+
+
+# Test 10
+S10====
+1
+1
+1
+1
+E10====
+
+0
+-1
+-2
+-3
+
+
+
+# Test 11
+S11====
+    1
+1
+    1
+    1
+E11====
+
+    2
+1
+    3
+    4
+
+
+# Test 12
+S12====
+0 0
+0 0
+0 0
+E12====
+
+0 1
+1 0
+1 0
+
+
+
+
+
+
+
 ENDTEST
 

Raspunde prin e-mail lui