]> granicus.if.org Git - vim/commitdiff
patch 9.0.1061: cannot display 'showcmd' somewhere else v9.0.1061
authorLuuk van Baal <luukvbaal@gmail.com>
Thu, 15 Dec 2022 13:15:39 +0000 (13:15 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 15 Dec 2022 13:15:39 +0000 (13:15 +0000)
Problem:    Cannot display 'showcmd' somewhere else.
Solution:   Add the 'showcmdloc' option. (Luuk van Baal, closes #11684)

19 files changed:
runtime/doc/options.txt
src/buffer.c
src/drawscreen.c
src/globals.h
src/normal.c
src/option.h
src/optiondefs.h
src/optionstr.c
src/proto/drawscreen.pro
src/screen.c
src/testdir/dumps/Test_statusline_showcmd_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_statusline_showcmd_2.dump [new file with mode: 0644]
src/testdir/dumps/Test_statusline_showcmd_3.dump [new file with mode: 0644]
src/testdir/dumps/Test_tabline_showcmd_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_tabline_showcmd_2.dump [new file with mode: 0644]
src/testdir/gen_opt_test.vim
src/testdir/test_statusline.vim
src/testdir/test_tabline.vim
src/version.c

index e95f63f75118f785534a9938b867c128d7776ebc..87fd2cf3273e009bb21c8f4f5dc713b0b32fcd62 100644 (file)
@@ -7220,9 +7220,25 @@ A jump table for the options with a short description can be found at |Q_op|.
        - When selecting more than one line, the number of lines.
        - When selecting a block, the size in screen characters:
          {lines}x{columns}.
+       This information can be displayed in an alternative location using the
+       'showcmdloc' option.
        NOTE: This option is set to the Vi default value when 'compatible' is
        set and to the Vim default value when 'compatible' is reset.
 
+                       *'showcmdloc'* *'sloc'*
+'showcmdloc' 'sloc'    string  (default "last")
+       This option can be used to display the (partially) entered command in
+       another location.  Possible values are:
+         last          Last line of the screen (default).
+         statusline    Status line of the current window.
+         tabline       First line of the screen if 'showtabine' is enabled.
+       Setting this option to "statusline" or "tabline" means that these will
+       be redrawn whenever the command changes, which can be on every key
+       pressed.
+       The %S 'statusline' item can be used in 'statusline' or 'tabline' to
+       place the text.  Without a custom 'statusline' or 'tabline' it will be
+       displayed in a convenient location.
+
                        *'showfulltag'* *'sft'* *'noshowfulltag'* *'nosft'*
 'showfulltag' 'sft'    boolean (default off)
                        global
@@ -7720,6 +7736,7 @@ A jump table for the options with a short description can be found at |Q_op|.
        P S   Percentage through file of displayed window.  This is like the
              percentage described for 'ruler'.  Always 3 in length, unless
              translated.
+       S S   'showcmd' content, see 'showcmdloc'.
        a S   Argument list status as in default title.  ({current} of {max})
              Empty if the argument file count is zero or one.
        { NF  Evaluate expression between '%{' and '}' and substitute result.
index eba5dd2d579233806c8443b3d76ec92d731fb23c..7e4772921a4798e0529b5c817ea96e5faa5d0614 100644 (file)
@@ -4775,6 +4775,11 @@ build_stl_str_hl(
            get_rel_pos(wp, str, TMPLEN);
            break;
 
+       case STL_SHOWCMD:
+           if (p_sc && STRCMP(opt_name, p_sloc) == 0)
+               str = showcmd_buf;
+           break;
+
        case STL_ARGLISTSTAT:
            fillable = FALSE;
            buf_tmp[0] = 0;
index 77828089c2442f176935e1a2c05bdd032a76ac16..13892bb7ca20a604ed9f721ffca6215aca33cc76 100644 (file)
@@ -73,8 +73,6 @@ static void redraw_custom_statusline(win_T *wp);
 static int  did_update_one_window;
 #endif
 
-static void win_redr_status(win_T *wp, int ignore_pum);
-
 /*
  * Based on the current value of curwin->w_topline, transfer a screenfull
  * of stuff from Filemem to ScreenLines[], and update curwin->w_botline.
@@ -423,7 +421,7 @@ statusline_row(win_T *wp)
  * If "ignore_pum" is TRUE, also redraw statusline when the popup menu is
  * displayed.
  */
-    static void
+    void
 win_redr_status(win_T *wp, int ignore_pum UNUSED)
 {
     int                row;
@@ -548,6 +546,16 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED)
                                                   - 1 + wp->w_wincol), attr);
 
        win_redr_ruler(wp, TRUE, ignore_pum);
+
+       // Draw the 'showcmd' information if 'showcmdloc' == "statusline".
+       if (p_sc && *p_sloc == 's')
+       {
+           int width = MIN(10, this_ru_col - len - 2);
+
+           if (width > 0)
+               screen_puts_len(showcmd_buf, width, row,
+                               wp->w_wincol + this_ru_col - width - 1, attr);
+       }
     }
 
     /*
index ced28baed55295aa8c99f9f78b6530df4ec1f93a..009165dd8d28c4effce52db54ea842fae1e01281 100644 (file)
@@ -2038,3 +2038,7 @@ EXTERN int skip_win_fix_cursor INIT(= FALSE);
 EXTERN int skip_win_fix_scroll INIT(= FALSE);
 // Skip update_topline() call while executing win_fix_scroll().
 EXTERN int skip_update_topline INIT(= FALSE);
+
+// 'showcmd' buffer shared between normal.c and statusline.c
+#define SHOWCMD_BUFLEN (SHOWCMD_COLS + 1 + 30)
+EXTERN char_u showcmd_buf[SHOWCMD_BUFLEN];
index 3f48ad85a5565c57bc38fd833c7d184afbb82aff..4df6b6a50647671324ebaf71b5783eb5758f6138 100644 (file)
@@ -1574,8 +1574,6 @@ may_clear_cmdline(void)
  * Routines for displaying a partly typed command
  */
 
-#define SHOWCMD_BUFLEN (SHOWCMD_COLS + 1 + 30)
-static char_u  showcmd_buf[SHOWCMD_BUFLEN];
 static char_u  old_showcmd_buf[SHOWCMD_BUFLEN];  // For push_showcmd()
 static int     showcmd_is_clear = TRUE;
 static int     showcmd_visual = FALSE;
@@ -1798,22 +1796,25 @@ pop_showcmd(void)
     static void
 display_showcmd(void)
 {
-    int            len;
+    int            len = (int)STRLEN(showcmd_buf);
 
+    showcmd_is_clear = (len == 0);
     cursor_off();
 
-    len = (int)STRLEN(showcmd_buf);
-    if (len == 0)
-       showcmd_is_clear = TRUE;
-    else
+    if (*p_sloc == 's')
+       win_redr_status(curwin, FALSE);
+    else if (*p_sloc == 't')
+       draw_tabline();
+    else // 'showcmdloc' is "last" or empty
     {
-       screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0);
-       showcmd_is_clear = FALSE;
-    }
+       if (!showcmd_is_clear)
+           screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0);
 
-    // clear the rest of an old message by outputting up to SHOWCMD_COLS
-    // spaces
-    screen_puts((char_u *)"          " + len, (int)Rows - 1, sc_col + len, 0);
+       // clear the rest of an old message by outputting up to SHOWCMD_COLS
+       // spaces
+       screen_puts((char_u *)"          " + len,
+                                               (int)Rows - 1, sc_col + len, 0);
+    }
 
     setcursor();           // put cursor back where it belongs
 }
index 6f2701344c2c2832d8bbc5c5cc4183c7d5431dfb..a11fa4167bb44fbcb4674c43791a4835d0b435fc 100644 (file)
@@ -343,6 +343,7 @@ typedef enum {
 #define STL_ALTPERCENT 'P'             // percentage as TOP BOT ALL or NN%
 #define STL_ARGLISTSTAT        'a'             // argument list status as (x of y)
 #define STL_PAGENUM    'N'             // page number (when printing)
+#define STL_SHOWCMD    'S'             // 'showcmd' buffer
 #define STL_VIM_EXPR   '{'             // start of expression to substitute
 #define STL_MIDDLEMARK '='             // separation between left and right
 #define STL_TRUNCMARK  '<'             // truncation mark if line is too long
@@ -350,7 +351,7 @@ typedef enum {
 #define STL_HIGHLIGHT  '#'             // highlight name
 #define STL_TABPAGENR  'T'             // tab page label nr
 #define STL_TABCLOSENR 'X'             // tab page close nr
-#define STL_ALL                ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#")
+#define STL_ALL                ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaNS{#")
 
 // flags used for parsed 'wildmode'
 #define WIM_FULL       0x01
@@ -892,6 +893,7 @@ EXTERN int  p_sn;           // 'shortname'
 EXTERN char_u  *p_sbr;         // 'showbreak'
 #endif
 EXTERN int     p_sc;           // 'showcmd'
+EXTERN char_u  *p_sloc;        // 'showcmdloc'
 EXTERN int     p_sft;          // 'showfulltag'
 EXTERN int     p_sm;           // 'showmatch'
 EXTERN int     p_smd;          // 'showmode'
index 449e7efdafa08c626f1ac90898994eb60c5cd9e5..de9fb6a33fc5871ebfedb908d89952b10ffc2be8 100644 (file)
@@ -2240,6 +2240,9 @@ static struct vimoption options[] =
                                (char_u *)TRUE
 #endif
                                } SCTX_INIT},
+    {"showcmdloc",  "sloc", P_STRING|P_RSTAT,
+                           (char_u *)&p_sloc, PV_NONE,
+                           {(char_u *)"last", (char_u *)"last"} SCTX_INIT},
     {"showfulltag", "sft",  P_BOOL|P_VI_DEF,
                            (char_u *)&p_sft, PV_NONE,
                            {(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
index 53d3a1ac56b8d9a85cf12225d774b3aa656b04ca..08b9ebcfb45e7047e8891c69029f7ce0b1c1c3b6 100644 (file)
@@ -93,6 +93,7 @@ static char *(p_scl_values[]) = {"yes", "no", "auto", "number", NULL};
 #if defined(MSWIN) && defined(FEAT_TERMINAL)
 static char *(p_twt_values[]) = {"winpty", "conpty", "", NULL};
 #endif
+static char *(p_sloc_values[]) = {"last", "statusline", "tabline", NULL};
 
 static int check_opt_strings(char_u *val, char **values, int list);
 static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, int list);
@@ -1894,6 +1895,12 @@ did_set_string_option(
     }
 #endif
 
+    // 'showcmdloc'
+    else if (varp == &p_sloc)
+    {
+       if (check_opt_strings(p_sloc, p_sloc_values, FALSE) != OK)
+           errmsg = e_invalid_argument;
+    }
 
 #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
     // 'toolbar'
index 0f5ff02d274f42f7bda0934f772d796b7a08b91a..6fa5e2c4511dd13ef30f5cf1bf0bef998f586dc6 100644 (file)
@@ -1,6 +1,7 @@
 /* drawscreen.c */
 int update_screen(int type_arg);
 int statusline_row(win_T *wp);
+void win_redr_status(win_T *wp, int ignore_pum);
 void showruler(int always);
 void win_redr_ruler(win_T *wp, int always, int ignore_pum);
 void after_updating_screen(int may_resize_shell);
index c5c6a7ac97970f5dd80b5cf45296a8534b2b2434..a737dc05dbad26a77198965780f9fd57e066ec4d 100644 (file)
@@ -4389,8 +4389,18 @@ draw_tabline(void)
            c = ' ';
        screen_fill(0, 1, col, (int)Columns, c, c, attr_fill);
 
+       // Draw the 'showcmd' information if 'showcmdloc' == "tabline".
+       if (p_sc && *p_sloc == 't')
+       {
+           int width = MIN(10, (int)Columns - col - (tabcount > 1) * 3);
+
+           if (width > 0)
+               screen_puts_len(showcmd_buf, width, 0, (int)Columns
+                           - width - (tabcount > 1) * 2, attr_nosel);
+       }
+
        // Put an "X" for closing the current tab if there are several.
-       if (first_tabpage->tp_next != NULL)
+       if (tabcount > 1)
        {
            screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
            TabPageIdxs[Columns - 1] = -999;
diff --git a/src/testdir/dumps/Test_statusline_showcmd_1.dump b/src/testdir/dumps/Test_statusline_showcmd_1.dump
new file mode 100644 (file)
index 0000000..049e0f7
--- /dev/null
@@ -0,0 +1,6 @@
+|a+0&#e0e0e08| +0&#ffffff0@73
+|b+0&#e0e0e08| +0&#ffffff0@73
+|c+0&#e0e0e08> +0&#ffffff0@73
+|~+0#4040ff13&| @73
+|3+3#0000000&|x|2| @71
+|-+2&&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@56
diff --git a/src/testdir/dumps/Test_statusline_showcmd_2.dump b/src/testdir/dumps/Test_statusline_showcmd_2.dump
new file mode 100644 (file)
index 0000000..c443662
--- /dev/null
@@ -0,0 +1,6 @@
+|a+0&#ffffff0| @73
+|b| @73
+>c| @73
+|~+0#4040ff13&| @73
+|1+3#0000000&|2|3|4| @70
+| +0&&@74
diff --git a/src/testdir/dumps/Test_statusline_showcmd_3.dump b/src/testdir/dumps/Test_statusline_showcmd_3.dump
new file mode 100644 (file)
index 0000000..26ba377
--- /dev/null
@@ -0,0 +1,6 @@
+|a+0&#ffffff0| @73
+|b| @73
+>c| @73
+|~+0#4040ff13&| @73
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @32|1|2|3|4| @6|3|,|1| @11|A|l@1
+|:+0&&| @73
diff --git a/src/testdir/dumps/Test_tabline_showcmd_1.dump b/src/testdir/dumps/Test_tabline_showcmd_1.dump
new file mode 100644 (file)
index 0000000..de8f62c
--- /dev/null
@@ -0,0 +1,6 @@
+| +2&#ffffff0|+| |[|N|o| |N|a|m|e|]| | +1&&@51|3+8#0000001#e0e0e08|x|2| +1#0000000#ffffff0@6
+|a+0&#e0e0e08| +0&#ffffff0@73
+|b+0&#e0e0e08| +0&#ffffff0@73
+|c+0&#e0e0e08> +0&#ffffff0@73
+|~+0#4040ff13&| @73
+|-+2#0000000&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@38|3|,|2| @10|A|l@1| 
diff --git a/src/testdir/dumps/Test_tabline_showcmd_2.dump b/src/testdir/dumps/Test_tabline_showcmd_2.dump
new file mode 100644 (file)
index 0000000..b5a7283
--- /dev/null
@@ -0,0 +1,6 @@
+| +2&#ffffff0|+| |[|N|o| |N|a|m|e|]| | +1&&@51|1+8#0000001#e0e0e08|2|3|4| +1#0000000#ffffff0@5
+|a+0&&| @73
+|b| @73
+>c| @73
+|~+0#4040ff13&| @73
+| +0#0000000&@56|3|,|1| @10|A|l@1| 
index 7337217a31839362403351f773e29424485c0741..a18aa66dfa4d3e156b3246854918d59863aad7d5 100644 (file)
@@ -132,6 +132,7 @@ let test_values = {
       \ 'selection': [['old', 'inclusive'], ['', 'xxx']],
       \ 'selectmode': [['', 'mouse', 'key,cmd'], ['xxx']],
       \ 'sessionoptions': [['', 'blank', 'help,options,slash'], ['xxx']],
+      \ 'showcmdloc': [['last', 'statusline', 'tabline'], ['xxx']],
       \ 'signcolumn': [['', 'auto', 'no'], ['xxx', 'no,yes']],
       \ 'spellfile': [['', 'file.en.add', '/tmp/dir\ with\ space/en.utf-8.add'], ['xxx', '/tmp/file']],
       \ 'spelllang': [['', 'xxx', 'sr@latin'], ['not&lang', "that\\\rthere"]],
index 15f2083f023405061767ead53b4fd152ae7742f7..a829597655bf7092291687fd1857fd023f7b1383 100644 (file)
@@ -558,4 +558,26 @@ func Test_statusline_highlight_truncate()
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_statusline_showcmd()
+  CheckScreendump
+
+  let lines =<< trim END
+    set laststatus=2
+    set statusline=%S
+    set showcmdloc=statusline
+    call setline(1, ['a', 'b', 'c'])
+  END
+  call writefile(lines, 'XTest_statusline', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 6})
+  call feedkeys("\<C-V>Gl", "xt")
+  call VerifyScreenDump(buf, 'Test_statusline_showcmd_1', {})
+
+  call feedkeys("\<Esc>1234", "xt")
+  call VerifyScreenDump(buf, 'Test_statusline_showcmd_2', {})
+
+  call feedkeys("\<Esc>:set statusline=\<CR>:\<CR>1234", "xt")
+  call VerifyScreenDump(buf, 'Test_statusline_showcmd_3', {})
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index ab0268d65aa63c12261982e30e12081878de3359..da738846f88495bca6cc54bea5be800ff5e41d9f 100644 (file)
@@ -1,6 +1,9 @@
 " Test for tabline
 
 source shared.vim
+source view_util.vim
+source check.vim
+source screendump.vim
 
 func TablineWithCaughtError()
   let s:func_in_tabline_called = 1
@@ -158,5 +161,23 @@ func Test_mouse_click_in_tab()
   call RunVim([], [], "-e -s -S Xclickscript -c qa")
 endfunc
 
+func Test_tabline_showcmd()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabline=2
+    set showcmdloc=tabline
+    call setline(1, ['a', 'b', 'c'])
+  END
+  call writefile(lines, 'XTest_tabline', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabline', {'rows': 6})
+
+  call feedkeys("\<C-V>Gl", "xt")
+  call VerifyScreenDump(buf, 'Test_tabline_showcmd_1', {})
+
+  call feedkeys("\<Esc>1234", "xt")
+  call VerifyScreenDump(buf, 'Test_tabline_showcmd_2', {})
+endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
index 6951668e5465e43d06465fa398ca1116f5c209d1..8250a919b41ad9f99eb2071ea2708d0e35b02655 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1061,
 /**/
     1060,
 /**/