0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

patch 9.0.1061: cannot display 'showcmd' somewhere else

Problem:    Cannot display 'showcmd' somewhere else.
Solution:   Add the 'showcmdloc' option. (Luuk van Baal, closes #11684)
This commit is contained in:
Luuk van Baal
2022-12-15 13:15:39 +00:00
committed by Bram Moolenaar
parent 3d473ee1a6
commit ba936f6f4e
19 changed files with 152 additions and 18 deletions

View 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 more than one line, the number of lines.
- When selecting a block, the size in screen characters: - When selecting a block, the size in screen characters:
{lines}x{columns}. {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 NOTE: This option is set to the Vi default value when 'compatible' is
set and to the Vim default value when 'compatible' is reset. 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'* *'noshowfulltag'* *'nosft'*
'showfulltag' 'sft' boolean (default off) 'showfulltag' 'sft' boolean (default off)
global 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 P S Percentage through file of displayed window. This is like the
percentage described for 'ruler'. Always 3 in length, unless percentage described for 'ruler'. Always 3 in length, unless
translated. translated.
S S 'showcmd' content, see 'showcmdloc'.
a S Argument list status as in default title. ({current} of {max}) a S Argument list status as in default title. ({current} of {max})
Empty if the argument file count is zero or one. Empty if the argument file count is zero or one.
{ NF Evaluate expression between '%{' and '}' and substitute result. { NF Evaluate expression between '%{' and '}' and substitute result.

View File

@@ -4775,6 +4775,11 @@ build_stl_str_hl(
get_rel_pos(wp, str, TMPLEN); get_rel_pos(wp, str, TMPLEN);
break; break;
case STL_SHOWCMD:
if (p_sc && STRCMP(opt_name, p_sloc) == 0)
str = showcmd_buf;
break;
case STL_ARGLISTSTAT: case STL_ARGLISTSTAT:
fillable = FALSE; fillable = FALSE;
buf_tmp[0] = 0; buf_tmp[0] = 0;

View File

@@ -73,8 +73,6 @@ static void redraw_custom_statusline(win_T *wp);
static int did_update_one_window; static int did_update_one_window;
#endif #endif
static void win_redr_status(win_T *wp, int ignore_pum);
/* /*
* Based on the current value of curwin->w_topline, transfer a screenfull * Based on the current value of curwin->w_topline, transfer a screenfull
* of stuff from Filemem to ScreenLines[], and update curwin->w_botline. * 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 * If "ignore_pum" is TRUE, also redraw statusline when the popup menu is
* displayed. * displayed.
*/ */
static void void
win_redr_status(win_T *wp, int ignore_pum UNUSED) win_redr_status(win_T *wp, int ignore_pum UNUSED)
{ {
int row; int row;
@@ -548,6 +546,16 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED)
- 1 + wp->w_wincol), attr); - 1 + wp->w_wincol), attr);
win_redr_ruler(wp, TRUE, ignore_pum); 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);
}
} }
/* /*

View File

@@ -2038,3 +2038,7 @@ EXTERN int skip_win_fix_cursor INIT(= FALSE);
EXTERN int skip_win_fix_scroll INIT(= FALSE); EXTERN int skip_win_fix_scroll INIT(= FALSE);
// Skip update_topline() call while executing win_fix_scroll(). // Skip update_topline() call while executing win_fix_scroll().
EXTERN int skip_update_topline INIT(= FALSE); 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];

View File

@@ -1574,8 +1574,6 @@ may_clear_cmdline(void)
* Routines for displaying a partly typed command * 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 char_u old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd()
static int showcmd_is_clear = TRUE; static int showcmd_is_clear = TRUE;
static int showcmd_visual = FALSE; static int showcmd_visual = FALSE;
@@ -1798,22 +1796,25 @@ pop_showcmd(void)
static void static void
display_showcmd(void) display_showcmd(void)
{ {
int len; int len = (int)STRLEN(showcmd_buf);
showcmd_is_clear = (len == 0);
cursor_off(); cursor_off();
len = (int)STRLEN(showcmd_buf); if (*p_sloc == 's')
if (len == 0) win_redr_status(curwin, FALSE);
showcmd_is_clear = TRUE; else if (*p_sloc == 't')
else draw_tabline();
else // 'showcmdloc' is "last" or empty
{ {
if (!showcmd_is_clear)
screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0); screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0);
showcmd_is_clear = FALSE;
}
// clear the rest of an old message by outputting up to SHOWCMD_COLS // clear the rest of an old message by outputting up to SHOWCMD_COLS
// spaces // spaces
screen_puts((char_u *)" " + len, (int)Rows - 1, sc_col + len, 0); screen_puts((char_u *)" " + len,
(int)Rows - 1, sc_col + len, 0);
}
setcursor(); // put cursor back where it belongs setcursor(); // put cursor back where it belongs
} }

View File

@@ -343,6 +343,7 @@ typedef enum {
#define STL_ALTPERCENT 'P' // percentage as TOP BOT ALL or NN% #define STL_ALTPERCENT 'P' // percentage as TOP BOT ALL or NN%
#define STL_ARGLISTSTAT 'a' // argument list status as (x of y) #define STL_ARGLISTSTAT 'a' // argument list status as (x of y)
#define STL_PAGENUM 'N' // page number (when printing) #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_VIM_EXPR '{' // start of expression to substitute
#define STL_MIDDLEMARK '=' // separation between left and right #define STL_MIDDLEMARK '=' // separation between left and right
#define STL_TRUNCMARK '<' // truncation mark if line is too long #define STL_TRUNCMARK '<' // truncation mark if line is too long
@@ -350,7 +351,7 @@ typedef enum {
#define STL_HIGHLIGHT '#' // highlight name #define STL_HIGHLIGHT '#' // highlight name
#define STL_TABPAGENR 'T' // tab page label nr #define STL_TABPAGENR 'T' // tab page label nr
#define STL_TABCLOSENR 'X' // tab page close 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' // flags used for parsed 'wildmode'
#define WIM_FULL 0x01 #define WIM_FULL 0x01
@@ -892,6 +893,7 @@ EXTERN int p_sn; // 'shortname'
EXTERN char_u *p_sbr; // 'showbreak' EXTERN char_u *p_sbr; // 'showbreak'
#endif #endif
EXTERN int p_sc; // 'showcmd' EXTERN int p_sc; // 'showcmd'
EXTERN char_u *p_sloc; // 'showcmdloc'
EXTERN int p_sft; // 'showfulltag' EXTERN int p_sft; // 'showfulltag'
EXTERN int p_sm; // 'showmatch' EXTERN int p_sm; // 'showmatch'
EXTERN int p_smd; // 'showmode' EXTERN int p_smd; // 'showmode'

View File

@@ -2240,6 +2240,9 @@ static struct vimoption options[] =
(char_u *)TRUE (char_u *)TRUE
#endif #endif
} SCTX_INIT}, } 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, {"showfulltag", "sft", P_BOOL|P_VI_DEF,
(char_u *)&p_sft, PV_NONE, (char_u *)&p_sft, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT},

View File

@@ -93,6 +93,7 @@ static char *(p_scl_values[]) = {"yes", "no", "auto", "number", NULL};
#if defined(MSWIN) && defined(FEAT_TERMINAL) #if defined(MSWIN) && defined(FEAT_TERMINAL)
static char *(p_twt_values[]) = {"winpty", "conpty", "", NULL}; static char *(p_twt_values[]) = {"winpty", "conpty", "", NULL};
#endif #endif
static char *(p_sloc_values[]) = {"last", "statusline", "tabline", NULL};
static int check_opt_strings(char_u *val, char **values, int list); 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); static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, int list);
@@ -1894,6 +1895,12 @@ did_set_string_option(
} }
#endif #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) #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
// 'toolbar' // 'toolbar'

View File

@@ -1,6 +1,7 @@
/* drawscreen.c */ /* drawscreen.c */
int update_screen(int type_arg); int update_screen(int type_arg);
int statusline_row(win_T *wp); int statusline_row(win_T *wp);
void win_redr_status(win_T *wp, int ignore_pum);
void showruler(int always); void showruler(int always);
void win_redr_ruler(win_T *wp, int always, int ignore_pum); void win_redr_ruler(win_T *wp, int always, int ignore_pum);
void after_updating_screen(int may_resize_shell); void after_updating_screen(int may_resize_shell);

View File

@@ -4389,8 +4389,18 @@ draw_tabline(void)
c = ' '; c = ' ';
screen_fill(0, 1, col, (int)Columns, c, c, attr_fill); 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. // 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); screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
TabPageIdxs[Columns - 1] = -999; TabPageIdxs[Columns - 1] = -999;

View File

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

View File

@@ -0,0 +1,6 @@
|a+0&#ffffff0| @73
|b| @73
>c| @73
|~+0#4040ff13&| @73
|1+3#0000000&|2|3|4| @70
| +0&&@74

View File

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

View File

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

View File

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

View File

@@ -132,6 +132,7 @@ let test_values = {
\ 'selection': [['old', 'inclusive'], ['', 'xxx']], \ 'selection': [['old', 'inclusive'], ['', 'xxx']],
\ 'selectmode': [['', 'mouse', 'key,cmd'], ['xxx']], \ 'selectmode': [['', 'mouse', 'key,cmd'], ['xxx']],
\ 'sessionoptions': [['', 'blank', 'help,options,slash'], ['xxx']], \ 'sessionoptions': [['', 'blank', 'help,options,slash'], ['xxx']],
\ 'showcmdloc': [['last', 'statusline', 'tabline'], ['xxx']],
\ 'signcolumn': [['', 'auto', 'no'], ['xxx', 'no,yes']], \ 'signcolumn': [['', 'auto', 'no'], ['xxx', 'no,yes']],
\ 'spellfile': [['', 'file.en.add', '/tmp/dir\ with\ space/en.utf-8.add'], ['xxx', '/tmp/file']], \ 'spellfile': [['', 'file.en.add', '/tmp/dir\ with\ space/en.utf-8.add'], ['xxx', '/tmp/file']],
\ 'spelllang': [['', 'xxx', 'sr@latin'], ['not&lang', "that\\\rthere"]], \ 'spelllang': [['', 'xxx', 'sr@latin'], ['not&lang', "that\\\rthere"]],

View File

@@ -558,4 +558,26 @@ func Test_statusline_highlight_truncate()
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -1,6 +1,9 @@
" Test for tabline " Test for tabline
source shared.vim source shared.vim
source view_util.vim
source check.vim
source screendump.vim
func TablineWithCaughtError() func TablineWithCaughtError()
let s:func_in_tabline_called = 1 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") call RunVim([], [], "-e -s -S Xclickscript -c qa")
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1061,
/**/ /**/
1060, 1060,
/**/ /**/