aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKunMing Xie <qqzz014@gmail.com>2018-06-21 17:36:26 +0800
committerJustin M. Keyes <justinkz@gmail.com>2018-06-21 11:36:26 +0200
commit7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87 (patch)
treefe8c991ec9bbb4f3c72cd3a3b53d08e3540d5354 /src
parentb92d6f490d93f788f018d7c8417d68d2d3de1a95 (diff)
downloadrneovim-7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87.tar.gz
rneovim-7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87.tar.bz2
rneovim-7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87.zip
vim-patch:8.0.0468: g< after aborting an Ex command (#7941)
Problem: After aborting an Ex command g< does not work. (Marcin Szamotulski) Solution: Postpone clearing scrollback messages to until the command line has been entered. Also fix that the screen isn't redrawn if after g< the command line is cancelled. https://github.com/vim/vim/commit/f2405ed2321da4a879fe0b0703af780fc0432c63
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_getln.c3
-rw-r--r--src/nvim/memory.c4
-rw-r--r--src/nvim/message.c87
3 files changed, 63 insertions, 31 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 774007c66e..3372edb8fd 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -273,6 +273,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
ccline.last_colors = (ColoredCmdline){ .cmdbuff = NULL,
.colors = KV_INITIAL_VALUE };
+ sb_text_start_cmdline();
// autoindent for :insert and :append
if (s->firstc <= 0) {
@@ -480,6 +481,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
xfree(ccline.last_colors.cmdbuff);
kv_destroy(ccline.last_colors.colors);
+ sb_text_end_cmdline();
+
{
char_u *p = ccline.cmdbuff;
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index bfc2f208dd..b2aef13946 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -66,7 +66,7 @@ void try_to_free_memory(void)
trying_to_free = true;
// free any scrollback text
- clear_sb_text();
+ clear_sb_text(true);
// Try to save all buffers and release as many blocks as possible
mf_release_all();
@@ -633,7 +633,7 @@ void free_all_mem(void)
free_signs();
set_expr_line(NULL);
diff_clear(curtab);
- clear_sb_text(); /* free any scrollback text */
+ clear_sb_text(true); // free any scrollback text
/* Free some global vars. */
xfree(last_cmdline);
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 2643d644a9..097c8b16e4 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1759,12 +1759,11 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
}
inc_msg_scrolled();
- need_wait_return = TRUE; /* may need wait_return in main() */
- if (must_redraw < VALID)
- must_redraw = VALID;
- redraw_cmdline = TRUE;
- if (cmdline_row > 0 && !exmode_active)
- --cmdline_row;
+ need_wait_return = true; // may need wait_return in main()
+ redraw_cmdline = true;
+ if (cmdline_row > 0 && !exmode_active) {
+ cmdline_row--;
+ }
/*
* If screen is completely filled and 'more' is set then wait
@@ -1921,30 +1920,38 @@ static void inc_msg_scrolled(void)
xfree(tofree);
}
msg_scrolled++;
+ if (must_redraw < VALID) {
+ must_redraw = VALID;
+ }
}
-static msgchunk_T *last_msgchunk = NULL; /* last displayed text */
+static msgchunk_T *last_msgchunk = NULL; // last displayed text
+typedef enum {
+ SB_CLEAR_NONE = 0,
+ SB_CLEAR_ALL,
+ SB_CLEAR_CMDLINE_BUSY,
+ SB_CLEAR_CMDLINE_DONE
+} sb_clear_T;
-static int do_clear_sb_text = FALSE; /* clear text on next msg */
+// When to clear text on next msg.
+static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE;
-/*
- * Store part of a printed message for displaying when scrolling back.
- */
-static void
-store_sb_text (
- char_u **sb_str, /* start of string */
- char_u *s, /* just after string */
+/// Store part of a printed message for displaying when scrolling back.
+static void store_sb_text(
+ char_u **sb_str, // start of string
+ char_u *s, // just after string
int attr,
int *sb_col,
- int finish /* line ends */
+ int finish // line ends
)
{
msgchunk_T *mp;
- if (do_clear_sb_text) {
- clear_sb_text();
- do_clear_sb_text = FALSE;
+ if (do_clear_sb_text == SB_CLEAR_ALL
+ || do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) {
+ clear_sb_text(do_clear_sb_text == SB_CLEAR_ALL);
+ do_clear_sb_text = SB_CLEAR_NONE;
}
if (s > *sb_str) {
@@ -1976,21 +1983,43 @@ store_sb_text (
*/
void may_clear_sb_text(void)
{
- do_clear_sb_text = TRUE;
+ do_clear_sb_text = SB_CLEAR_ALL;
}
-/*
- * Clear any text remembered for scrolling back.
- * Called when redrawing the screen.
- */
-void clear_sb_text(void)
+/// Starting to edit the command line, do not clear messages now.
+void sb_text_start_cmdline(void)
+{
+ do_clear_sb_text = SB_CLEAR_CMDLINE_BUSY;
+ msg_sb_eol();
+}
+
+/// Ending to edit the command line. Clear old lines but the last one later.
+void sb_text_end_cmdline(void)
+{
+ do_clear_sb_text = SB_CLEAR_CMDLINE_DONE;
+}
+
+/// Clear any text remembered for scrolling back.
+/// When "all" is FALSE keep the last line.
+/// Called when redrawing the screen.
+void clear_sb_text(int all)
{
msgchunk_T *mp;
+ msgchunk_T **lastp;
+
+ if (all) {
+ lastp = &last_msgchunk;
+ } else {
+ if (last_msgchunk == NULL) {
+ return;
+ }
+ lastp = &last_msgchunk->sb_prev;
+ }
- while (last_msgchunk != NULL) {
- mp = last_msgchunk->sb_prev;
- xfree(last_msgchunk);
- last_msgchunk = mp;
+ while (*lastp != NULL) {
+ mp = (*lastp)->sb_prev;
+ xfree(*lastp);
+ *lastp = mp;
}
}