aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShougo <Shougo.Matsu@gmail.com>2022-06-13 18:40:51 +0900
committerGitHub <noreply@github.com>2022-06-13 02:40:51 -0700
commit663cbe2620278eae658895f82f3eb9bc89310e73 (patch)
tree84708a2e6743eda4c351ffd311885039137b7b79 /src
parent2f71d4708e997454a0d05d51122a56146b89af92 (diff)
downloadrneovim-663cbe2620278eae658895f82f3eb9bc89310e73.tar.gz
rneovim-663cbe2620278eae658895f82f3eb9bc89310e73.tar.bz2
rneovim-663cbe2620278eae658895f82f3eb9bc89310e73.zip
feat: cmdheight=0 #16251
Fix https://github.com/neovim/neovim/issues/1004 Limitation: All outputs need hit-enter prompt. Related: https://github.com/neovim/neovim/pull/6732 https://github.com/neovim/neovim/pull/4382
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_getln.c30
-rw-r--r--src/nvim/message.c34
-rw-r--r--src/nvim/normal.c4
-rw-r--r--src/nvim/ops.c4
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/screen.c11
-rw-r--r--src/nvim/testdir/test_window_cmd.vim10
-rw-r--r--src/nvim/window.c13
8 files changed, 77 insertions, 31 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 94ce1ec495..46cc4b5c7e 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -108,11 +108,9 @@ typedef enum {
kCmdRedrawAll,
} CmdRedraw;
-/*
- * Variables shared between getcmdline(), redrawcmdline() and others.
- * These need to be saved when using CTRL-R |, that's why they are in a
- * structure.
- */
+// Variables shared between getcmdline(), redrawcmdline() and others.
+// These need to be saved when using CTRL-R |, that's why they are in a
+// structure.
struct cmdline_info {
char_u *cmdbuff; // pointer to command line buffer
int cmdbufflen; // length of cmdbuff
@@ -139,6 +137,7 @@ struct cmdline_info {
bool special_shift; ///< shift of last putcmdline char
CmdRedraw redraw_state; ///< needed redraw for external cmdline
};
+
/// Last value of prompt_id, incremented when doing new prompt
static unsigned last_prompt_id = 0;
@@ -689,6 +688,14 @@ static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, bool
/// @param init_ccline clear ccline first
static uint8_t *command_line_enter(int firstc, long count, int indent, bool init_ccline)
{
+ bool cmdheight0 = p_ch < 1 && !ui_has(kUIMessages) && vpeekc() == NUL;
+
+ if (cmdheight0) {
+ // If cmdheight is 0, cmdheight must be set to 1 when we enter command line.
+ set_option_value("ch", 1L, NULL, 0);
+ redraw_statuslines();
+ }
+
// can be invoked recursively, identify each level
static int cmdline_level = 0;
cmdline_level++;
@@ -976,6 +983,11 @@ theend:
ccline.cmdbuff = NULL;
}
+ if (cmdheight0) {
+ // Restore cmdheight
+ set_option_value("ch", 0L, NULL, 0);
+ }
+
return p;
}
@@ -2670,6 +2682,12 @@ char *getcmdline_prompt(const char firstc, const char *const prompt, const int a
return ret;
}
+// Return current cmdline prompt
+char_u *get_cmdprompt(void)
+{
+ return ccline.cmdprompt;
+}
+
/*
* Return TRUE when the text must not be changed and we can't switch to
* another window or buffer. Used when editing the command line etc.
@@ -3777,7 +3795,7 @@ void redrawcmd(void)
msg_no_more = TRUE;
draw_cmdline(0, ccline.cmdlen);
msg_clr_eos();
- msg_no_more = FALSE;
+ msg_no_more = false;
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
diff --git a/src/nvim/message.c b/src/nvim/message.c
index f250f6de58..23ceb0ba4c 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -18,6 +18,7 @@
#include "nvim/eval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
+#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/garray.h"
@@ -163,6 +164,7 @@ void msg_grid_validate(void)
{
grid_assign_handle(&msg_grid);
bool should_alloc = msg_use_grid();
+ int max_rows = Rows - p_ch;
if (should_alloc && (msg_grid.rows != Rows || msg_grid.cols != Columns
|| !msg_grid.chars)) {
// TODO(bfredl): eventually should be set to "invalid". I e all callers
@@ -174,7 +176,7 @@ void msg_grid_validate(void)
msg_grid.dirty_col = xcalloc(Rows, sizeof(*msg_grid.dirty_col));
// Tricky: allow resize while pager is active
- int pos = msg_scrolled ? msg_grid_pos : Rows - p_ch;
+ int pos = msg_scrolled ? msg_grid_pos : max_rows;
ui_comp_put_grid(&msg_grid, pos, 0, msg_grid.rows, msg_grid.cols,
false, true);
ui_call_grid_resize(msg_grid.handle, msg_grid.cols, msg_grid.rows);
@@ -184,7 +186,7 @@ void msg_grid_validate(void)
msg_grid.focusable = false;
msg_grid_adj.target = &msg_grid;
if (!msg_scrolled) {
- msg_grid_set_pos(Rows - p_ch, false);
+ msg_grid_set_pos(max_rows, false);
}
} else if (!should_alloc && msg_grid.chars) {
ui_comp_remove_grid(&msg_grid);
@@ -195,8 +197,8 @@ void msg_grid_validate(void)
msg_grid_adj.row_offset = 0;
msg_grid_adj.target = &default_grid;
redraw_cmdline = true;
- } else if (msg_grid.chars && !msg_scrolled && msg_grid_pos != Rows - p_ch) {
- msg_grid_set_pos(Rows - p_ch, false);
+ } else if (msg_grid.chars && !msg_scrolled && msg_grid_pos != max_rows) {
+ msg_grid_set_pos(max_rows, false);
}
if (msg_grid.chars && cmdline_row < msg_grid_pos) {
@@ -1386,7 +1388,9 @@ void msg_start(void)
need_fileinfo = false;
}
- if (need_clr_eos) {
+ bool no_msg_area = !ui_has(kUIMessages) && p_ch < 1;
+
+ if (need_clr_eos || (no_msg_area && redrawing_cmdline)) {
// Halfway an ":echo" command and getting an (error) message: clear
// any text from the command.
need_clr_eos = false;
@@ -1395,10 +1399,11 @@ void msg_start(void)
if (!msg_scroll && full_screen) { // overwrite last message
msg_row = cmdline_row;
- msg_col =
- cmdmsg_rl ? Columns - 1 :
- 0;
- } else if (msg_didout) { // start message on next line
+ msg_col = cmdmsg_rl ? Columns - 1 : 0;
+ if (no_msg_area && get_cmdprompt() == NULL) {
+ msg_row -= 1;
+ }
+ } else if (msg_didout || no_msg_area) { // start message on next line
msg_putchar('\n');
did_return = true;
cmdline_row = msg_row;
@@ -3055,7 +3060,7 @@ void repeat_message(void)
/// Skip this when ":silent" was used, no need to clear for redirection.
void msg_clr_eos(void)
{
- if (msg_silent == 0) {
+ if (msg_silent == 0 && p_ch > 0) {
msg_clr_eos_force();
}
}
@@ -3077,10 +3082,11 @@ void msg_clr_eos_force(void)
msg_row = msg_grid_pos;
}
- grid_fill(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol, ' ',
- ' ', HL_ATTR(HLF_MSG));
- grid_fill(&msg_grid_adj, msg_row + 1, Rows, 0, Columns, ' ', ' ',
- HL_ATTR(HLF_MSG));
+ grid_fill(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol,
+ ' ', ' ', HL_ATTR(HLF_MSG));
+ if (p_ch > 0) {
+ grid_fill(&msg_grid_adj, msg_row + 1, Rows, 0, Columns, ' ', ' ', HL_ATTR(HLF_MSG));
+ }
redraw_cmdline = true; // overwritten the command line
if (msg_row < Rows - 1 || msg_col == (cmdmsg_rl ? Columns : 0)) {
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 3603e11f5d..87a9e1e765 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2747,6 +2747,10 @@ void pop_showcmd(void)
static void display_showcmd(void)
{
+ if (p_ch < 1 && !ui_has(kUIMessages)) {
+ return;
+ }
+
int len;
len = (int)STRLEN(showcmd_buf);
showcmd_is_clear = (len == 0);
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 7dcf4c433e..0f202b2fd3 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -6041,6 +6041,10 @@ void cursor_pos_info(dict_T *dict)
// Don't shorten this message, the user asked for it.
p = p_shm;
p_shm = (char_u *)"";
+ if (p_ch < 1) {
+ msg_start();
+ msg_scroll = true;
+ }
msg((char *)IObuff);
p_shm = p;
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 35736fd5eb..ca9c7468cf 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -4365,7 +4365,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf,
errmsg = e_positive;
}
} else if (pp == &p_ch) {
- int minval = ui_has(kUIMessages) ? 0 : 1;
+ int minval = 0;
if (value < minval) {
errmsg = e_positive;
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 4142409ee0..2ee7cd44f7 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6132,6 +6132,10 @@ void unshowmode(bool force)
// Clear the mode message.
void clearmode(void)
{
+ if (p_ch <= 0 && !ui_has(kUIMessages)) {
+ return;
+ }
+
const int save_msg_row = msg_row;
const int save_msg_col = msg_col;
@@ -6500,7 +6504,6 @@ static void win_redr_ruler(win_T *wp, bool always)
if (*p_ruf) {
int save_called_emsg = called_emsg;
-
called_emsg = false;
win_redr_custom(wp, false, true);
if (called_emsg) {
@@ -6558,6 +6561,10 @@ static void win_redr_ruler(win_T *wp, bool always)
off = 0;
}
+ if (!part_of_status && p_ch < 1 && !ui_has(kUIMessages)) {
+ return;
+ }
+
// In list mode virtcol needs to be recomputed
colnr_T virtcol = wp->w_virtcol;
if (wp->w_p_list && wp->w_p_lcs_chars.tab1 == NUL) {
@@ -6770,7 +6777,7 @@ void screen_resize(int width, int height)
Columns = width;
check_shellsize();
int max_p_ch = Rows - min_rows() + 1;
- if (!ui_has(kUIMessages) && p_ch > max_p_ch) {
+ if (!ui_has(kUIMessages) && p_ch > 0 && p_ch > max_p_ch) {
p_ch = max_p_ch ? max_p_ch : 1;
}
height = Rows;
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index 798122dc5d..0fe5fc59eb 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -887,6 +887,7 @@ func Test_floatwin_splitmove()
endfunc
func Test_window_resize()
+ throw 'Skipped: Nvim supports cmdheight=0'
" Vertical :resize (absolute, relative, min and max size).
vsplit
vert resize 8
@@ -1028,9 +1029,14 @@ func Test_win_move_statusline()
call assert_equal(h0, winheight(0))
call assert_equal(1, &cmdheight)
endfor
+ " Nvim supports cmdheight=0
+ set cmdheight=0
call assert_true(win_move_statusline(0, 1))
- call assert_equal(h0, winheight(0))
- call assert_equal(1, &cmdheight)
+ "call assert_equal(h0, winheight(0))
+ "call assert_equal(1, &cmdheight)
+ call assert_equal(h0 + 1, winheight(0))
+ call assert_equal(0, &cmdheight)
+ set cmdheight&
" check win_move_statusline from bottom window on top window ID
let id = win_getid(1)
for offset in range(5)
diff --git a/src/nvim/window.c b/src/nvim/window.c
index e09a7cd97e..e08db2261b 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -907,7 +907,7 @@ void ui_ext_win_position(win_T *wp)
int comp_col = (int)col - (east ? wp->w_width_outer : 0);
comp_row += grid->comp_row;
comp_col += grid->comp_col;
- comp_row = MAX(MIN(comp_row, Rows - wp->w_height_outer - 1), 0);
+ comp_row = MAX(MIN(comp_row, Rows - wp->w_height_outer - (p_ch > 0 ? 1 : 0)), 0);
comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
wp->w_winrow = comp_row;
wp->w_wincol = comp_col;
@@ -1144,6 +1144,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
if (flags & WSP_ROOM) {
needed += p_wh - wmh1 + oldwin->w_winbar_height;
}
+ if (p_ch < 1) {
+ needed += 1; // Adjust for cmdheight=0.
+ }
if (flags & (WSP_BOT | WSP_TOP)) {
minheight = frame_minheight(topframe, NOWIN) + need_status;
available = topframe->fr_height;
@@ -5501,7 +5504,7 @@ void win_setheight_win(int height, win_T *win)
}
}
cmdline_row = row;
- p_ch = MAX(Rows - cmdline_row, ui_has(kUIMessages) ? 0 : 1);
+ p_ch = MAX(Rows - cmdline_row, 0);
curtab->tp_ch_used = p_ch;
msg_row = row;
msg_col = 0;
@@ -5949,9 +5952,7 @@ void win_drag_status_line(win_T *dragwin, int offset)
up = false;
// Only dragging the last status line can reduce p_ch.
room = Rows - cmdline_row;
- if (curfr->fr_next == NULL) {
- room -= 1;
- } else {
+ if (curfr->fr_next != NULL) {
room -= p_ch + global_stl_height();
}
if (room < 0) {
@@ -6008,7 +6009,7 @@ void win_drag_status_line(win_T *dragwin, int offset)
clear_cmdline = true;
}
cmdline_row = row;
- p_ch = MAX(Rows - cmdline_row, ui_has(kUIMessages) ? 0 : 1);
+ p_ch = MAX(Rows - cmdline_row, 0);
curtab->tp_ch_used = p_ch;
redraw_all_later(SOME_VALID);
showmode();