]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0200: `gj`/`gk` not skipping over outer virtual text lines v9.1.0200
authorDylan Thacker-Smith <dylan.ah.smith@gmail.com>
Sun, 24 Mar 2024 08:43:25 +0000 (09:43 +0100)
committerChristian Brabandt <cb@256bit.org>
Sun, 24 Mar 2024 08:43:25 +0000 (09:43 +0100)
Problem:  `gj`/`gk` was updating the desired cursor virtual column to
          the outer virtual text, even though the actual cursor position
          was moved to not be on the virtual text, leading the need to
          do an extra `gj`/`gk` to move past each virtual text line.
          (rickhowe)
Solution: Exclude the outer virtual text when getting the line length
          for moving the cursor with `gj`/`gk`, so that no extra
          movement is needed to skip over virtual text lines.
          (Dylan Thacker-Smith)

fixes: #12028
related: #14262

Signed-off-by: Dylan Thacker-Smith <dylan.ah.smith@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/charset.c
src/normal.c
src/proto/charset.pro
src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_2.dump [new file with mode: 0644]
src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_3.dump [new file with mode: 0644]
src/testdir/test_textprop.vim
src/version.c

index 5ae90da5db6c94a64d240c8f6038e72a0bb10187..c9584a90f73f2f99aca4c8ba8069119a94e963e3 100644 (file)
@@ -798,6 +798,45 @@ linetabsize(win_T *wp, linenr_T lnum)
                       ml_get_buf(wp->w_buffer, lnum, FALSE), (colnr_T)MAXCOL);
 }
 
+/*
+ * Like linetabsize(), but excludes 'above'/'after'/'right'/'below' aligned
+ * virtual text, while keeping inline virtual text.
+ */
+    int
+linetabsize_no_outer(win_T *wp, linenr_T lnum)
+{
+#ifndef FEAT_PROP_POPUP
+    return linetabsize(wp, lnum);
+#else
+    chartabsize_T cts;
+    char_u *line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+
+    init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
+
+    if (cts.cts_text_prop_count)
+    {
+      int write_idx = 0;
+      for (int read_idx = 0; read_idx < cts.cts_text_prop_count; read_idx++)
+      {
+          textprop_T *tp = &cts.cts_text_props[read_idx];
+          if (tp->tp_col != MAXCOL)
+          {
+              if (read_idx != write_idx)
+                  cts.cts_text_props[write_idx] = *tp;
+              write_idx++;
+          }
+      }
+      cts.cts_text_prop_count = write_idx;
+      if (cts.cts_text_prop_count == 0)
+          VIM_CLEAR(cts.cts_text_props);
+    }
+
+    win_linetabsize_cts(&cts, (colnr_T)MAXCOL);
+    clear_chartabsize_arg(&cts);
+    return (int)cts.cts_vcol;
+#endif
+}
+
     void
 win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
 {
index 5ef3a9277c4adf6ad8fd3013c03efbee45997fce..531b6f9fb16bdcabd4cf9fb06a3cc62d3eb6ea0a 100644 (file)
@@ -2306,7 +2306,9 @@ find_decl(
     static int
 nv_screengo(oparg_T *oap, int dir, long dist)
 {
-    int                linelen = linetabsize(curwin, curwin->w_cursor.lnum);
+
+    int                linelen = linetabsize_no_outer(curwin, curwin->w_cursor.lnum);
+
     int                retval = OK;
     int                atend = FALSE;
     int                n;
@@ -2376,7 +2378,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
                }
                cursor_up_inner(curwin, 1);
 
-               linelen = linetabsize(curwin, curwin->w_cursor.lnum);
+               linelen = linetabsize_no_outer(curwin, curwin->w_cursor.lnum);
                if (linelen > width1)
                    curwin->w_curswant += (((linelen - width1 - 1) / width2)
                                                                + 1) * width2;
@@ -2413,7 +2415,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
                // clipped to column 0.
                if (curwin->w_curswant >= width1)
                    curwin->w_curswant -= width2;
-               linelen = linetabsize(curwin, curwin->w_cursor.lnum);
+               linelen = linetabsize_no_outer(curwin, curwin->w_cursor.lnum);
            }
        }
       }
index c915c5802fce543d8e38ef04043a8daa154c80f2..a74731931d730424ee217bc53951578493b14ccb 100644 (file)
@@ -20,6 +20,7 @@ int linetabsize_str(char_u *s);
 int linetabsize_col(int startcol, char_u *s);
 int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len);
 int linetabsize(win_T *wp, linenr_T lnum);
+int linetabsize_no_outer(win_T *wp, linenr_T lnum);
 void win_linetabsize_cts(chartabsize_T *cts, colnr_T len);
 int vim_isIDc(int c);
 int vim_isNormalIDc(int c);
diff --git a/src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_1.dump b/src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_1.dump
new file mode 100644 (file)
index 0000000..7a0b848
--- /dev/null
@@ -0,0 +1,16 @@
+| +0#af5f00255#ffffff0@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|1| |F+0#0000000&|i|r>s|t| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|2| |A+0#0000001#ffff4012|f|t|e|r| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@5
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3| +0#0000000&@35
+| +0#af5f00255&@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|3| |T+0#0000000&|h|i|r|d| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+@22|1|,|4|-|4|0| @7|A|l@1| 
diff --git a/src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_2.dump b/src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_2.dump
new file mode 100644 (file)
index 0000000..d463990
--- /dev/null
@@ -0,0 +1,16 @@
+| +0#af5f00255#ffffff0@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|1| |F+0#0000000&|i|r|s|t| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|2| >A+0#0000001#ffff4012|f|t|e|r| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@5
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3| +0#0000000&@35
+| +0#af5f00255&@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|3| |T+0#0000000&|h|i|r|d| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+@22|2|,|0|-|3|7| @7|A|l@1| 
diff --git a/src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_3.dump b/src/testdir/dumps/Test_prop_normal_gj_gk_over_outer_virtual_text_3.dump
new file mode 100644 (file)
index 0000000..85a469d
--- /dev/null
@@ -0,0 +1,16 @@
+| +0#af5f00255#ffffff0@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|1| |F+0#0000000&|i|r|s|t| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|2| |A+0#0000001#ffff4012|f|t|e|r| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@5
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3| +0#0000000&@35
+| +0#af5f00255&@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+| +0#af5f00255&@3|A+0#0000001#ffff4012|b|o|v|e| +0#0000000#ffffff0@30
+| +0#af5f00255&@1|3| |T+0#0000000&|h|i>r|d| |l|i|n|e| |f|i|t|s| |o|n| |s|c|r|e@1|n| |l|i|n|e|.|A+0#0000001#ffff4012|f|t|e|r
+| +0#af5f00255#ffffff0@3| +0#0000001#ffff4012|t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.| +0#0000000#ffffff0@10
+| +0#af5f00255&@3| +0#0000000&@5|R+0#0000001#ffff4012|i|g|h|t| |t|e|x|t| |w|r|a|p|s| |t|o| |n|e|x|t| |l|i|n|e|.
+| +0#af5f00255#ffffff0@3|B+0#0000001#ffff4012|e|l|o|w| +0#0000000#ffffff0@30
+@22|3|,|4|-|4|0| @7|A|l@1| 
index a06f73370620ad5da5740c4ce8e08e94f93590b6..a7057147d43e6435f0f6862d088b078d8c7d64a4 100644 (file)
@@ -2690,6 +2690,45 @@ func Test_prop_inserts_text_normal_gj_gk()
   call Run_test_prop_inserts_text_normal_gj_gk('set virtualedit=all')
 endfunc
 
+func Test_prop_normal_gj_gk_over_outer_virtual_text()
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+      vim9script
+      setlocal number
+      setline(1, ['First line fits on screen line.', '', 'Third line fits on screen line.'])
+
+      var vt = 'test'
+      prop_type_add(vt, {highlight: 'ToDo'})
+      for ln in range(1, line('$'))
+        prop_add(ln, 0, {type: vt, text: 'Above', text_align: 'above'})
+        prop_add(ln, 0, {type: vt, text: 'After text wraps to next line.', text_align: 'after', text_wrap: 'wrap'})
+        prop_add(ln, 0, {type: vt, text: 'Right text wraps to next line.', text_align: 'right', text_wrap: 'wrap'})
+        prop_add(ln, 0, {type: vt, text: 'Below', text_align: 'below'})
+      endfor
+      normal 3l
+  END
+  call writefile(lines, 'XscriptPropsNormal_gj_gk_over_outer', 'D')
+  let buf = RunVimInTerminal('-S XscriptPropsNormal_gj_gk_over_outer', #{rows: 16, cols: 40})
+  call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_over_outer_virtual_text_1', {})
+
+  call term_sendkeys(buf, "gj")
+  call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_over_outer_virtual_text_2', {})
+  call term_sendkeys(buf, "gj")
+  call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_over_outer_virtual_text_3', {})
+  call term_sendkeys(buf, "gk")
+  call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_over_outer_virtual_text_2', {})
+  call term_sendkeys(buf, "gk")
+  call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_over_outer_virtual_text_1', {})
+
+  call term_sendkeys(buf, "2gj")
+  call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_over_outer_virtual_text_3', {})
+  call term_sendkeys(buf, "2gk")
+  call VerifyScreenDump(buf, 'Test_prop_normal_gj_gk_over_outer_virtual_text_1', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 func Test_prop_inserts_text_visual_block()
   CheckRunVimInTerminal
 
index 32037e377849b9b3d7ce5e047309fe5771fb3a9b..0e5e399a81aec05c5219bb09cef61c8c3ea5caac 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    200,
 /**/
     199,
 /**/