Patch 9.0.0697
Problem: Cursor in wrong position with Visual substitute.
Solution: When restoring 'linebreak' mark the virtual column as invalid.
(closes #11309, closes #11311)
Files: src/ops.c, src/testdir/test_visual.vim,
src/testdir/test_listlbr.vim,
src/testdir/dumps/Test_linebreak_reset_restore_1.dump
*** ../vim-9.0.0696/src/ops.c 2022-09-16 22:16:54.404074904 +0100
--- src/ops.c 2022-10-08 16:39:35.327858697 +0100
***************
*** 2208,2213 ****
--- 2208,2242 ----
}
/*
+ * Reset 'linebreak' and take care of side effects.
+ * Returns the previous value, to be passed to restore_lbr().
+ */
+ static int
+ reset_lbr(void)
+ {
+ if (!curwin->w_p_lbr)
+ return FALSE;
+ // changing 'linebreak' may require w_virtcol to be updated
+ curwin->w_p_lbr = FALSE;
+ curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
+ return TRUE;
+ }
+
+ /*
+ * Restore 'linebreak' and take care of side effects.
+ */
+ static void
+ restore_lbr(int lbr_saved)
+ {
+ if (!curwin->w_p_lbr && lbr_saved)
+ {
+ // changing 'linebreak' may require w_virtcol to be updated
+ curwin->w_p_lbr = TRUE;
+ curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
+ }
+ }
+
+ /*
* prepare a few things for block mode yank/delete/tilde
*
* for delete:
***************
*** 2235,2245 ****
char_u *prev_pend;
chartabsize_T cts;
#ifdef FEAT_LINEBREAK
! int lbr_saved = curwin->w_p_lbr;
!
! // Avoid a problem with unwanted linebreaks in block mode.
! curwin->w_p_lbr = FALSE;
#endif
bdp->startspaces = 0;
bdp->endspaces = 0;
bdp->textlen = 0;
--- 2264,2273 ----
char_u *prev_pend;
chartabsize_T cts;
#ifdef FEAT_LINEBREAK
! // Avoid a problem with unwanted linebreaks in block mode.
! int lbr_saved = reset_lbr();
#endif
+
bdp->startspaces = 0;
bdp->endspaces = 0;
bdp->textlen = 0;
***************
*** 2369,2375 ****
bdp->textcol = (colnr_T) (pstart - line);
bdp->textstart = pstart;
#ifdef FEAT_LINEBREAK
! curwin->w_p_lbr = lbr_saved;
#endif
}
--- 2397,2403 ----
bdp->textcol = (colnr_T) (pstart - line);
bdp->textstart = pstart;
#ifdef FEAT_LINEBREAK
! restore_lbr(lbr_saved);
#endif
}
***************
*** 3570,3578 ****
#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;
if (oap->motion_force == 'V')
--- 3598,3604 ----
#ifdef FEAT_LINEBREAK
// Avoid a problem with unwanted linebreaks in block mode.
! (void)reset_lbr();
#endif
oap->is_VIsual = VIsual_active;
if (oap->motion_force == 'V')
***************
*** 3908,3914 ****
{
#ifdef FEAT_LINEBREAK
// make sure redrawing is correct
! curwin->w_p_lbr = lbr_saved;
#endif
redraw_curbuf_later(UPD_INVERTED);
}
--- 3934,3940 ----
{
#ifdef FEAT_LINEBREAK
// make sure redrawing is correct
! restore_lbr(lbr_saved);
#endif
redraw_curbuf_later(UPD_INVERTED);
}
***************
*** 3948,3954 ****
))
{
#ifdef FEAT_LINEBREAK
! curwin->w_p_lbr = lbr_saved;
#endif
redraw_curbuf_later(UPD_INVERTED);
}
--- 3974,3980 ----
))
{
#ifdef FEAT_LINEBREAK
! restore_lbr(lbr_saved);
#endif
redraw_curbuf_later(UPD_INVERTED);
}
***************
*** 4036,4042 ****
else
{
#ifdef FEAT_LINEBREAK
! curwin->w_p_lbr = lbr_saved;
#endif
oap->excl_tr_ws = cap->cmdchar == 'z';
(void)op_yank(oap, FALSE, !gui_yank);
--- 4062,4068 ----
else
{
#ifdef FEAT_LINEBREAK
! restore_lbr(lbr_saved);
#endif
oap->excl_tr_ws = cap->cmdchar == 'z';
(void)op_yank(oap, FALSE, !gui_yank);
***************
*** 4065,4071 ****
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! curwin->w_p_lbr = lbr_saved;
#endif
// Reset finish_op now, don't want it set inside edit().
finish_op = FALSE;
--- 4091,4097 ----
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! restore_lbr(lbr_saved);
#endif
// Reset finish_op now, don't want it set inside edit().
finish_op = FALSE;
***************
*** 4143,4149 ****
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! curwin->w_p_lbr = lbr_saved;
#endif
// call 'operatorfunc'
op_function(oap);
--- 4169,4175 ----
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! restore_lbr(lbr_saved);
#endif
// call 'operatorfunc'
op_function(oap);
***************
*** 4172,4183 ****
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! curwin->w_p_lbr = lbr_saved;
#endif
op_insert(oap, cap->count1);
#ifdef FEAT_LINEBREAK
// Reset linebreak, so that formatting works correctly.
! curwin->w_p_lbr = FALSE;
#endif
// TODO: when inserting in several lines, should format all
--- 4198,4209 ----
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! restore_lbr(lbr_saved);
#endif
op_insert(oap, cap->count1);
#ifdef FEAT_LINEBREAK
// Reset linebreak, so that formatting works correctly.
! (void)reset_lbr();
#endif
// TODO: when inserting in several lines, should format all
***************
*** 4203,4209 ****
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! curwin->w_p_lbr = lbr_saved;
#endif
op_replace(oap, cap->nchar);
}
--- 4229,4235 ----
#ifdef FEAT_LINEBREAK
// Restore linebreak, so that when the user edits it looks as
// before.
! restore_lbr(lbr_saved);
#endif
op_replace(oap, cap->nchar);
}
***************
*** 4246,4252 ****
{
VIsual_active = TRUE;
#ifdef FEAT_LINEBREAK
! curwin->w_p_lbr = lbr_saved;
#endif
op_addsub(oap, cap->count1, redo_VIsual.rv_arg);
VIsual_active = FALSE;
--- 4272,4278 ----
{
VIsual_active = TRUE;
#ifdef FEAT_LINEBREAK
! restore_lbr(lbr_saved);
#endif
op_addsub(oap, cap->count1, redo_VIsual.rv_arg);
VIsual_active = FALSE;
***************
*** 4265,4271 ****
|| oap->op_type == OP_DELETE))
{
#ifdef FEAT_LINEBREAK
! curwin->w_p_lbr = FALSE;
#endif
coladvance(curwin->w_curswant = old_col);
}
--- 4291,4297 ----
|| oap->op_type == OP_DELETE))
{
#ifdef FEAT_LINEBREAK
! (void)reset_lbr();
#endif
coladvance(curwin->w_curswant = old_col);
}
***************
*** 4279,4284 ****
motion_force = NUL;
}
#ifdef FEAT_LINEBREAK
! curwin->w_p_lbr = lbr_saved;
#endif
}
--- 4305,4310 ----
motion_force = NUL;
}
#ifdef FEAT_LINEBREAK
! restore_lbr(lbr_saved);
#endif
}
*** ../vim-9.0.0696/src/testdir/test_visual.vim 2022-09-02 21:55:45.511049444
+0100
--- src/testdir/test_visual.vim 2022-10-08 16:33:10.667914109 +0100
***************
*** 1501,1505 ****
--- 1501,1537 ----
exe 'bwipe!' buf2
endfunc
+ " Test that cursor is drawn at correct position after an operator in Visual
+ " mode when 'linebreak' and 'showcmd' are enabled.
+ func Test_visual_operator_with_linebreak()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set linebreak showcmd noshowmode
+ call setline(1, repeat('a', &columns - 10) .. ' bbbbbbbbbb c')
+ END
+ call writefile(lines, 'XTest_visual_op_linebreak', 'D')
+
+ let buf = RunVimInTerminal('-S XTest_visual_op_linebreak', {'rows': 6})
+
+ call term_sendkeys(buf, '$v$')
+ call WaitForAssert({-> assert_equal(13, term_getcursor(buf)[1])})
+ call term_sendkeys(buf, 'zo')
+ call WaitForAssert({-> assert_equal(12, term_getcursor(buf)[1])})
+
+ call term_sendkeys(buf, "$\<C-V>$")
+ call WaitForAssert({-> assert_equal(13, term_getcursor(buf)[1])})
+ call term_sendkeys(buf, 'I')
+ call WaitForAssert({-> assert_equal(12, term_getcursor(buf)[1])})
+
+ call term_sendkeys(buf, "\<Esc>$v$")
+ call WaitForAssert({-> assert_equal(13, term_getcursor(buf)[1])})
+ call term_sendkeys(buf, 's')
+ call WaitForAssert({-> assert_equal(12, term_getcursor(buf)[1])})
+
+ " clean up
+ call term_sendkeys(buf, "\<Esc>")
+ call StopVimInTerminal(buf)
+ endfunc
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-9.0.0696/src/testdir/test_listlbr.vim 2022-10-03
17:07:29.993542954 +0100
--- src/testdir/test_listlbr.vim 2022-10-08 16:25:35.301384797 +0100
***************
*** 8,13 ****
--- 8,14 ----
CheckFeature conceal
source view_util.vim
+ source screendump.vim
function s:screen_lines(lnum, width) abort
return ScreenLines(a:lnum, a:width)
***************
*** 133,138 ****
--- 134,159 ----
call s:close_windows()
endfunc
+ func Test_linebreak_reset_restore()
+ CheckScreendump
+
+ let lines =<< trim END
+ vim9script
+ &linebreak = true
+ &showcmd = true
+ &showmode = false
+ ('a'->repeat(&columns - 10) .. ' ' .. 'b'->repeat(10) .. '
c')->setline(1)
+ END
+ call writefile(lines, 'XlbrResetRestore', 'D')
+ let buf = RunVimInTerminal('-S XlbrResetRestore', {'rows': 8})
+
+ call term_sendkeys(buf, '$v$s')
+ call VerifyScreenDump(buf, 'Test_linebreak_reset_restore_1', {})
+
+ call term_sendkeys(buf, "\<Esc>")
+ call StopVimInTerminal(buf)
+ endfunc
+
func Test_virtual_block()
call s:test_windows('setl sbr=+')
call setline(1, [
*** ../vim-9.0.0696/src/testdir/dumps/Test_linebreak_reset_restore_1.dump
2022-10-08 16:40:12.463845375 +0100
--- src/testdir/dumps/Test_linebreak_reset_restore_1.dump 2022-10-08
16:25:38.933372180 +0100
***************
*** 0 ****
--- 1,8 ----
+ |a+0&#ffffff0@64| @9
+ |b@9| > @63
+ |~+0#4040ff13&| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ | +0#0000000&@56|1|,|7|8|-|8|7| @6|A|l@1|
*** ../vim-9.0.0696/src/version.c 2022-10-08 15:30:52.271540199 +0100
--- src/version.c 2022-10-08 16:39:55.987851931 +0100
***************
*** 701,702 ****
--- 701,704 ----
{ /* Add new patch number below this line */
+ /**/
+ 697,
/**/
--
LAUNCELOT: At last! A call! A cry of distress ...
(he draws his sword, and turns to CONCORDE)
Concorde! Brave, Concorde ... you shall not have died in vain!
CONCORDE: I'm not quite dead, sir ...
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
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].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/20221008154231.1EF501C0D0A%40moolenaar.net.