mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:9.0.1061: cannot display 'showcmd' somewhere else
Problem: Cannot display 'showcmd' somewhere else.
Solution: Add the 'showcmdloc' option. (Luuk van Baal, closes vim/vim#11684)
ba936f6f4e
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
This commit is contained in:
parent
357aab4c65
commit
5b89d480e3
@ -86,7 +86,12 @@ The following new APIs or features were added.
|
||||
• When using Nvim inside tmux 3.2 or later, the default clipboard provider
|
||||
will now copy to the system clipboard. |provider-clipboard|
|
||||
|
||||
• 'splitkeep' option to control the scroll behavior of horizontal splits.
|
||||
• |'showcmdloc'| option to display the 'showcmd' information in the
|
||||
status line or tab line. A new %S statusline item is available to place
|
||||
the 'showcmd' text in a custom 'statusline'. Useful for when |'cmdheight'|
|
||||
is set to 0.
|
||||
|
||||
• |'splitkeep'| option to control the scroll behavior of horizontal splits.
|
||||
|
||||
• |nvim_select_popupmenu_item()| now supports |cmdline-completion| popup menu.
|
||||
|
||||
|
@ -5641,7 +5641,6 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
global
|
||||
Show (partial) command in the last line of the screen. Set this
|
||||
option off if your terminal is slow.
|
||||
The option has no effect when 'cmdheight' is zero.
|
||||
In Visual mode the size of the selected area is shown:
|
||||
- When selecting characters within a line, the number of characters.
|
||||
If the number of bytes is different it is also displayed: "2-6"
|
||||
@ -5649,6 +5648,22 @@ 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, useful when 'cmdheight' is 0.
|
||||
|
||||
*'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 'showtabline' 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)
|
||||
@ -6120,6 +6135,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.
|
||||
|
@ -68,6 +68,7 @@
|
||||
#include "nvim/spellfile.h"
|
||||
#include "nvim/spellsuggest.h"
|
||||
#include "nvim/state.h"
|
||||
#include "nvim/statusline.h"
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/syntax.h"
|
||||
#include "nvim/tag.h"
|
||||
@ -1782,8 +1783,6 @@ void may_clear_cmdline(void)
|
||||
}
|
||||
|
||||
// Routines for displaying a partly typed command
|
||||
#define SHOWCMD_BUFLEN (SHOWCMD_COLS + 1 + 30)
|
||||
static char showcmd_buf[SHOWCMD_BUFLEN];
|
||||
static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd()
|
||||
static bool showcmd_is_clear = true;
|
||||
static bool showcmd_visual = false;
|
||||
@ -1977,14 +1976,20 @@ void pop_showcmd(void)
|
||||
|
||||
static void display_showcmd(void)
|
||||
{
|
||||
if (p_ch == 0 && !ui_has(kUIMessages)) {
|
||||
// TODO(bfredl): would be nice to show in global statusline, perhaps
|
||||
int len = (int)strlen(showcmd_buf);
|
||||
showcmd_is_clear = (len == 0);
|
||||
|
||||
if (*p_sloc == 's') {
|
||||
win_redr_status(curwin);
|
||||
setcursor(); // put cursor back where it belongs
|
||||
return;
|
||||
}
|
||||
|
||||
int len;
|
||||
len = (int)strlen(showcmd_buf);
|
||||
showcmd_is_clear = (len == 0);
|
||||
if (*p_sloc == 't') {
|
||||
draw_tabline();
|
||||
setcursor(); // put cursor back where it belongs
|
||||
return;
|
||||
}
|
||||
// 'showcmdloc' is "last" or empty
|
||||
|
||||
if (ui_has(kUIMessages)) {
|
||||
MAXSIZE_TEMP_ARRAY(content, 1);
|
||||
|
@ -72,6 +72,12 @@ typedef struct cmdarg_S {
|
||||
#define CA_COMMAND_BUSY 1 // skip restarting edit() once
|
||||
#define CA_NO_ADJ_OP_END 2 // don't adjust operator end
|
||||
|
||||
// columns needed by shown command
|
||||
#define SHOWCMD_COLS 10
|
||||
// 'showcmd' buffer shared between normal.c and statusline.c
|
||||
#define SHOWCMD_BUFLEN (SHOWCMD_COLS + 1 + 30)
|
||||
EXTERN char showcmd_buf[SHOWCMD_BUFLEN];
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "normal.h.generated.h"
|
||||
#endif
|
||||
|
@ -336,6 +336,7 @@ enum {
|
||||
STL_ALTPERCENT = 'P', ///< Percentage as TOP BOT ALL or NN%.
|
||||
STL_ARGLISTSTAT = 'a', ///< Argument list status as (x of y).
|
||||
STL_PAGENUM = 'N', ///< Page number (when printing).
|
||||
STL_SHOWCMD = 'S', ///< 'showcmd' buffer
|
||||
STL_VIM_EXPR = '{', ///< Start of expression to substitute.
|
||||
STL_SEPARATE = '=', ///< Separation between alignment sections.
|
||||
STL_TRUNCMARK = '<', ///< Truncation mark if line is too long.
|
||||
@ -353,8 +354,8 @@ enum {
|
||||
STL_HELPFLAG, STL_HELPFLAG_ALT, STL_FILETYPE, STL_FILETYPE_ALT, \
|
||||
STL_PREVIEWFLAG, STL_PREVIEWFLAG_ALT, STL_MODIFIED, STL_MODIFIED_ALT, \
|
||||
STL_QUICKFIX, STL_PERCENTAGE, STL_ALTPERCENT, STL_ARGLISTSTAT, STL_PAGENUM, \
|
||||
STL_VIM_EXPR, STL_SEPARATE, STL_TRUNCMARK, STL_USER_HL, STL_HIGHLIGHT, \
|
||||
STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \
|
||||
STL_SHOWCMD, STL_VIM_EXPR, STL_SEPARATE, STL_TRUNCMARK, STL_USER_HL, \
|
||||
STL_HIGHLIGHT, STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \
|
||||
0, \
|
||||
})
|
||||
|
||||
@ -696,6 +697,7 @@ EXTERN long p_sw; ///< 'shiftwidth'
|
||||
EXTERN char *p_shm; // 'shortmess'
|
||||
EXTERN char *p_sbr; // 'showbreak'
|
||||
EXTERN int p_sc; // 'showcmd'
|
||||
EXTERN char *p_sloc; // 'showcmdloc'
|
||||
EXTERN int p_sft; // 'showfulltag'
|
||||
EXTERN int p_sm; // 'showmatch'
|
||||
EXTERN int p_smd; // 'showmode'
|
||||
|
@ -2183,6 +2183,13 @@ return {
|
||||
varname='p_sc',
|
||||
defaults={if_true=true}
|
||||
},
|
||||
{
|
||||
full_name='showcmdloc', abbreviation='sloc',
|
||||
short_desc=N_("change location of partial command"),
|
||||
type='string', scope={'global'},
|
||||
varname='p_sloc',
|
||||
defaults={if_true="last"}
|
||||
},
|
||||
{
|
||||
full_name='showfulltag', abbreviation='sft',
|
||||
short_desc=N_("show full tag pattern when completing tag"),
|
||||
|
@ -126,6 +126,7 @@ static char *(p_icm_values[]) = { "nosplit", "split", NULL };
|
||||
static char *(p_jop_values[]) = { "stack", "view", NULL };
|
||||
static char *(p_tpf_values[]) = { "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL };
|
||||
static char *(p_rdb_values[]) = { "compositor", "nothrottle", "invalid", "nodelta", NULL };
|
||||
static char *(p_sloc_values[]) = { "last", "statusline", "tabline", NULL };
|
||||
|
||||
/// All possible flags for 'shm'.
|
||||
static char SHM_ALL[] = { SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW,
|
||||
@ -1275,6 +1276,10 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
|
||||
&& (curwin->w_p_nu || curwin->w_p_rnu)) {
|
||||
curwin->w_nrwidth_line_count = 0;
|
||||
}
|
||||
} else if (varp == &p_sloc) { // 'showcmdloc'
|
||||
if (check_opt_strings(p_sloc, p_sloc_values, false) != OK) {
|
||||
errmsg = e_invarg;
|
||||
}
|
||||
} else if (varp == &curwin->w_p_fdc
|
||||
|| varp == &curwin->w_allbuf_opt.wo_fdc) {
|
||||
// 'foldcolumn'
|
||||
|
@ -163,6 +163,16 @@ void win_redr_status(win_T *wp)
|
||||
}
|
||||
|
||||
win_redr_ruler(wp, true);
|
||||
|
||||
// Draw the 'showcmd' information if 'showcmdloc' == "statusline".
|
||||
if (p_sc && *p_sloc == 's') {
|
||||
int sc_width = MIN(10, this_ru_col - len - 2);
|
||||
|
||||
if (width > 0) {
|
||||
grid_puts_len(&default_grid, showcmd_buf, sc_width, row,
|
||||
wp->w_wincol + this_ru_col - sc_width - 1, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// May need to draw the character below the vertical separator.
|
||||
@ -832,8 +842,18 @@ void draw_tabline(void)
|
||||
}
|
||||
grid_fill(&default_grid, 0, 1, col, 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) {
|
||||
grid_puts_len(&default_grid, showcmd_buf, width, 0,
|
||||
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) {
|
||||
grid_putchar(&default_grid, 'X', 0, Columns - 1, attr_nosel);
|
||||
tab_page_click_defs[Columns - 1] = (StlClickDefinition) {
|
||||
.type = kStlClickTabClose,
|
||||
@ -1485,6 +1505,12 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n
|
||||
str = buf_tmp;
|
||||
break;
|
||||
|
||||
case STL_SHOWCMD:
|
||||
if (p_sc && strcmp(opt_name, p_sloc) == 0) {
|
||||
str = showcmd_buf;
|
||||
}
|
||||
break;
|
||||
|
||||
case STL_ARGLISTSTAT:
|
||||
fillable = false;
|
||||
|
||||
|
@ -565,4 +565,26 @@ func Test_statusline_highlight_truncate()
|
||||
call delete('XTest_statusline')
|
||||
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
|
||||
|
@ -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
|
||||
@ -160,5 +163,23 @@ func Test_mouse_click_in_tab()
|
||||
call delete('Xclickscript')
|
||||
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
|
||||
|
@ -235,8 +235,6 @@ enum { FOLD_TEXT_LEN = 51, }; //!< buffer size for get_foldtext()
|
||||
// destination and mess up the screen.
|
||||
#define PERROR(msg) (void)semsg("%s: %s", (msg), strerror(errno))
|
||||
|
||||
#define SHOWCMD_COLS 10 // columns needed by shown command
|
||||
|
||||
#include "nvim/path.h"
|
||||
|
||||
// Enums need a typecast to be used as array index.
|
||||
|
@ -68,4 +68,51 @@ describe('statusline', function()
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
-- oldtest: Test_statusline_showcmd()
|
||||
it('showcmdloc=statusline works', function()
|
||||
screen:set_default_attr_ids({
|
||||
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
|
||||
[1] = {background = Screen.colors.LightGrey}, -- Visual
|
||||
[2] = {bold = true}, -- MoreMsg
|
||||
[3] = {bold = true, reverse = true}, -- StatusLine
|
||||
})
|
||||
exec([[
|
||||
set showcmd
|
||||
set laststatus=2
|
||||
set statusline=%S
|
||||
set showcmdloc=statusline
|
||||
call setline(1, ['a', 'b', 'c'])
|
||||
]])
|
||||
feed('<C-V>Gl')
|
||||
screen:expect([[
|
||||
{1:a} |
|
||||
{1:b} |
|
||||
{1:c}^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{3:3x2 }|
|
||||
{2:-- VISUAL BLOCK --} |
|
||||
]])
|
||||
feed('<Esc>1234')
|
||||
screen:expect([[
|
||||
a |
|
||||
b |
|
||||
^c |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{3:1234 }|
|
||||
|
|
||||
]])
|
||||
feed('<Esc>:set statusline=<CR>:<CR>1234')
|
||||
screen:expect([[
|
||||
a |
|
||||
b |
|
||||
^c |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{3:[No Name] [+] 1234 }|
|
||||
: |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
53
test/functional/legacy/tabline_spec.lua
Normal file
53
test/functional/legacy/tabline_spec.lua
Normal file
@ -0,0 +1,53 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local clear = helpers.clear
|
||||
local exec = helpers.exec
|
||||
local feed = helpers.feed
|
||||
|
||||
before_each(clear)
|
||||
|
||||
describe('tabline', function()
|
||||
local screen
|
||||
|
||||
before_each(function()
|
||||
screen = Screen.new(50, 7)
|
||||
screen:attach()
|
||||
end)
|
||||
|
||||
-- oldtest: Test_tabline_showcmd()
|
||||
it('showcmdloc=tabline works', function()
|
||||
screen:set_default_attr_ids({
|
||||
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
|
||||
[1] = {background = Screen.colors.LightGrey}, -- Visual
|
||||
[2] = {bold = true}, -- MoreMsg, TabLineSel
|
||||
[3] = {reverse = true}, -- TabLineFill
|
||||
[4] = {background = Screen.colors.LightGrey, underline = true}, -- TabLine
|
||||
})
|
||||
exec([[
|
||||
set showcmd
|
||||
set showtabline=2
|
||||
set showcmdloc=tabline
|
||||
call setline(1, ['a', 'b', 'c'])
|
||||
]])
|
||||
feed('<C-V>Gl')
|
||||
screen:expect([[
|
||||
{2: + [No Name] }{3: }{4:3x2}{3: }|
|
||||
{1:a} |
|
||||
{1:b} |
|
||||
{1:c}^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{2:-- VISUAL BLOCK --} |
|
||||
]])
|
||||
feed('<Esc>1234')
|
||||
screen:expect([[
|
||||
{2: + [No Name] }{3: }{4:1234}{3: }|
|
||||
a |
|
||||
b |
|
||||
^c |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
|
|
||||
]])
|
||||
end)
|
||||
end)
|
Loading…
Reference in New Issue
Block a user