summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2015-06-25 13:30:46 +0200
committerBram Moolenaar <Bram@vim.org>2015-06-25 13:30:46 +0200
commit74db34cc9162445e3d500ab2d61c5c19ce9af0ca (patch)
tree26a5af2942668bb6d872dbe4815e74f203b4cd77
parent66312acf145f9d09fbc0dfa5caeafb715d5fd9ed (diff)
downloadvim-git-74db34cc9162445e3d500ab2d61c5c19ce9af0ca.tar.gz
patch 7.4.753v7.4.753
Problem: Appending in Visual mode with 'linebreak' set does not work properly. Also when 'selection' is "exclusive". (Ingo Karkat) Solution: Recalculate virtual columns. (Christian Brabandt)
-rw-r--r--src/normal.c148
-rw-r--r--src/testdir/test_listlbr.in10
-rw-r--r--src/testdir/test_listlbr.ok5
-rw-r--r--src/testdir/test_listlbr_utf8.in5
-rw-r--r--src/testdir/test_listlbr_utf8.ok2
-rw-r--r--src/version.c2
6 files changed, 112 insertions, 60 deletions
diff --git a/src/normal.c b/src/normal.c
index dc223c2ae..9c9537f4b 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -174,6 +174,7 @@ static void nv_drop __ARGS((cmdarg_T *cap));
#ifdef FEAT_AUTOCMD
static void nv_cursorhold __ARGS((cmdarg_T *cap));
#endif
+static void get_op_vcol __ARGS((oparg_T *oap, colnr_T col, int initial));
static char *e_noident = N_("E349: No identifier under cursor");
@@ -1418,6 +1419,8 @@ do_pending_operator(cap, old_col, gui_yank)
{
#ifdef FEAT_LINEBREAK
/* Avoid a problem with unwanted linebreaks in block mode. */
+ if (curwin->w_p_lbr)
+ curwin->w_valid &= ~VALID_VIRTCOL;
curwin->w_p_lbr = FALSE;
#endif
oap->is_VIsual = VIsual_active;
@@ -1631,61 +1634,7 @@ do_pending_operator(cap, old_col, gui_yank)
if (VIsual_active || redo_VIsual_busy)
{
- if (VIsual_mode == Ctrl_V) /* block mode */
- {
- colnr_T start, end;
-
- oap->block_mode = TRUE;
-
- getvvcol(curwin, &(oap->start),
- &oap->start_vcol, NULL, &oap->end_vcol);
- if (!redo_VIsual_busy)
- {
- getvvcol(curwin, &(oap->end), &start, NULL, &end);
-
- if (start < oap->start_vcol)
- oap->start_vcol = start;
- if (end > oap->end_vcol)
- {
- if (*p_sel == 'e' && start >= 1
- && start - 1 >= oap->end_vcol)
- oap->end_vcol = start - 1;
- else
- oap->end_vcol = end;
- }
- }
-
- /* if '$' was used, get oap->end_vcol from longest line */
- if (curwin->w_curswant == MAXCOL)
- {
- curwin->w_cursor.col = MAXCOL;
- oap->end_vcol = 0;
- for (curwin->w_cursor.lnum = oap->start.lnum;
- curwin->w_cursor.lnum <= oap->end.lnum;
- ++curwin->w_cursor.lnum)
- {
- getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
- if (end > oap->end_vcol)
- oap->end_vcol = end;
- }
- }
- else if (redo_VIsual_busy)
- oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1;
- /*
- * Correct oap->end.col and oap->start.col to be the
- * upper-left and lower-right corner of the block area.
- *
- * (Actually, this does convert column positions into character
- * positions)
- */
- curwin->w_cursor.lnum = oap->end.lnum;
- coladvance(oap->end_vcol);
- oap->end = curwin->w_cursor;
-
- curwin->w_cursor = oap->start;
- coladvance(oap->start_vcol);
- oap->start = curwin->w_cursor;
- }
+ get_op_vcol(oap, redo_VIsual_vcol, TRUE);
if (!redo_VIsual_busy && !gui_yank)
{
@@ -1982,7 +1931,11 @@ do_pending_operator(cap, old_col, gui_yank)
#ifdef FEAT_LINEBREAK
/* Restore linebreak, so that when the user edits it looks as
* before. */
- curwin->w_p_lbr = lbr_saved;
+ if (curwin->w_p_lbr != lbr_saved)
+ {
+ curwin->w_p_lbr = lbr_saved;
+ get_op_vcol(oap, redo_VIsual_mode, FALSE);
+ }
#endif
/* Reset finish_op now, don't want it set inside edit(). */
finish_op = FALSE;
@@ -2082,7 +2035,11 @@ do_pending_operator(cap, old_col, gui_yank)
#ifdef FEAT_LINEBREAK
/* Restore linebreak, so that when the user edits it looks as
* before. */
- curwin->w_p_lbr = lbr_saved;
+ if (curwin->w_p_lbr != lbr_saved)
+ {
+ curwin->w_p_lbr = lbr_saved;
+ get_op_vcol(oap, redo_VIsual_mode, FALSE);
+ }
#endif
op_insert(oap, cap->count1);
#ifdef FEAT_LINEBREAK
@@ -2114,11 +2071,15 @@ do_pending_operator(cap, old_col, gui_yank)
#ifdef FEAT_VISUALEXTRA
else
{
-#ifdef FEAT_LINEBREAK
+# ifdef FEAT_LINEBREAK
/* Restore linebreak, so that when the user edits it looks as
* before. */
- curwin->w_p_lbr = lbr_saved;
-#endif
+ if (curwin->w_p_lbr != lbr_saved)
+ {
+ curwin->w_p_lbr = lbr_saved;
+ get_op_vcol(oap, redo_VIsual_mode, FALSE);
+ }
+# endif
op_replace(oap, cap->nchar);
}
#endif
@@ -9542,3 +9503,70 @@ nv_cursorhold(cap)
cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
}
#endif
+
+/*
+ * calculate start/end virtual columns for operating in block mode
+ */
+ static void
+get_op_vcol(oap, redo_VIsual_vcol, initial)
+ oparg_T *oap;
+ colnr_T redo_VIsual_vcol;
+ int initial; /* when true: adjust position for 'selectmode' */
+{
+ colnr_T start, end;
+
+ if (VIsual_mode != Ctrl_V)
+ return;
+
+ oap->block_mode = TRUE;
+
+#ifdef FEAT_MBYTE
+ /* prevent from moving onto a trail byte */
+ if (has_mbyte)
+ mb_adjustpos(curwin->w_buffer, &oap->end);
+#endif
+
+ getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
+ getvvcol(curwin, &(oap->end), &start, NULL, &end);
+
+ if (start < oap->start_vcol)
+ oap->start_vcol = start;
+ if (end > oap->end_vcol)
+ {
+ if (initial && *p_sel == 'e' && start >= 1
+ && start - 1 >= oap->end_vcol)
+ oap->end_vcol = start - 1;
+ else
+ oap->end_vcol = end;
+ }
+ /* if '$' was used, get oap->end_vcol from longest line */
+ if (curwin->w_curswant == MAXCOL)
+ {
+ curwin->w_cursor.col = MAXCOL;
+ oap->end_vcol = 0;
+ for (curwin->w_cursor.lnum = oap->start.lnum;
+ curwin->w_cursor.lnum <= oap->end.lnum;
+ ++curwin->w_cursor.lnum)
+ {
+ getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
+ if (end > oap->end_vcol)
+ oap->end_vcol = end;
+ }
+ }
+ else if (redo_VIsual_busy)
+ oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1;
+ /*
+ * Correct oap->end.col and oap->start.col to be the
+ * upper-left and lower-right corner of the block area.
+ *
+ * (Actually, this does convert column positions into character
+ * positions)
+ */
+ curwin->w_cursor.lnum = oap->end.lnum;
+ coladvance(oap->end_vcol);
+ oap->end = curwin->w_cursor;
+
+ curwin->w_cursor = oap->start;
+ coladvance(oap->start_vcol);
+ oap->start = curwin->w_cursor;
+}
diff --git a/src/testdir/test_listlbr.in b/src/testdir/test_listlbr.in
index f6618c5a4..6af48a75e 100644
--- a/src/testdir/test_listlbr.in
+++ b/src/testdir/test_listlbr.in
@@ -59,11 +59,21 @@ STARTTEST
:set cpo&vim linebreak
:let g:test ="Test 6: set linebreak with visual block mode"
:let line="REMOVE: this not"
+:$put =g:test
:$put =line
:let line="REMOVE: aaaaaaaaaaaaa"
:$put =line
:1/^REMOVE:
0jf x:$put
+:set cpo&vim linebreak
+:let g:test ="Test 7: set linebreak with visual block mode and v_b_A"
+:$put =g:test
+Golong line: 40afoobar aTARGET at end
+:exe "norm! $3B\<C-v>eAx\<Esc>"
+:set cpo&vim linebreak sbr=
+:let g:test ="Test 8: set linebreak with visual char mode and changing block"
+:$put =g:test
+Go1111-1111-1111-11-1111-1111-11110f-lv3lc2222bgj.
:%w! test.out
:qa!
ENDTEST
diff --git a/src/testdir/test_listlbr.ok b/src/testdir/test_listlbr.ok
index ee7466766..82881234c 100644
--- a/src/testdir/test_listlbr.ok
+++ b/src/testdir/test_listlbr.ok
@@ -32,7 +32,12 @@ Sabbbbbb bla
~
~
~
+Test 6: set linebreak with visual block mode
this not
aaaaaaaaaaaaa
REMOVE:
REMOVE:
+Test 7: set linebreak with visual block mode and v_b_A
+long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETx at end
+Test 8: set linebreak with visual char mode and changing block
+1111-2222-1111-11-1111-2222-1111
diff --git a/src/testdir/test_listlbr_utf8.in b/src/testdir/test_listlbr_utf8.in
index 7448142a6..61bb8a71b 100644
--- a/src/testdir/test_listlbr_utf8.in
+++ b/src/testdir/test_listlbr_utf8.in
@@ -91,6 +91,11 @@ GGlGGlGGlGGlGGlGGlGGlGGlGGlGGl
:else
: call append('$', "Not all attributes are different")
:endif
+:set cpo&vim linebreak selection=exclusive
+:let g:test ="Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char"
+:$put =g:test
+Golong line: 40afoobar aTARGETÃ' at end
+:exe "norm! $3B\<C-v>eAx\<Esc>"
:%w! test.out
:qa!
ENDTEST
diff --git a/src/testdir/test_listlbr_utf8.ok b/src/testdir/test_listlbr_utf8.ok
index 5bd35bdec..25316c753 100644
--- a/src/testdir/test_listlbr_utf8.ok
+++ b/src/testdir/test_listlbr_utf8.ok
@@ -44,3 +44,5 @@ Test 6: Screenattributes for comment
/* and some more */
ScreenAttributes for test6:
Attribut 0 and 1 and 3 and 5 are different!
+Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char
+long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETÃx' at end
diff --git a/src/version.c b/src/version.c
index 5a7e5ba38..c8eda4239 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 753,
+/**/
752,
/**/
751,