summaryrefslogtreecommitdiffstats
path: root/src/message.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-07-27 21:13:01 +0000
committerBram Moolenaar <Bram@vim.org>2005-07-27 21:13:01 +0000
commit87e25fdf80c7b45deee9c59389b51503e906d93b (patch)
treee477f86746245499e324e1d1e9ccada6aed035e9 /src/message.c
parent231334e6efbf3a7f89183f8257e09492534a5f8c (diff)
updated for version 7.0117v7.0117
Diffstat (limited to 'src/message.c')
-rw-r--r--src/message.c843
1 files changed, 580 insertions, 263 deletions
diff --git a/src/message.c b/src/message.c
index 94b8851998..81c0a8e6e9 100644
--- a/src/message.c
+++ b/src/message.c
@@ -29,7 +29,12 @@ static void msg_home_replace_attr __ARGS((char_u *fname, int attr));
static char_u *screen_puts_mbyte __ARGS((char_u *s, int l, int attr));
#endif
static void msg_puts_attr_len __ARGS((char_u *str, int maxlen, int attr));
-static void t_puts __ARGS((int t_col, char_u *t_s, char_u *s, int attr));
+static void msg_puts_display __ARGS((char_u *str, int maxlen, int attr, int recurse));
+static void msg_scroll_up __ARGS((void));
+static void store_sb_text __ARGS((char_u **sb_str, char_u *s, int attr, int *sb_col, int finish));
+static void t_puts __ARGS((int *t_col, char_u *t_s, char_u *s, int attr));
+static void msg_puts_printf __ARGS((char_u *str, int maxlen));
+static int do_more_prompt __ARGS((int typed_char));
static void msg_screen_putchar __ARGS((int c, int attr));
static int msg_check_screen __ARGS((void));
static void redir_write __ARGS((char_u *s, int maxlen));
@@ -924,6 +929,22 @@ wait_return(redraw)
c = K_IGNORE;
}
#endif
+ if (p_more && !p_cp && (c == 'b' || c == 'k' || c == 'u'))
+ {
+ /* scroll back to show older messages */
+ do_more_prompt(c);
+ if (quit_more)
+ {
+ c = CAR; /* just pretend CR was hit */
+ quit_more = FALSE;
+ got_int = FALSE;
+ }
+ else
+ {
+ c = K_IGNORE;
+ hit_return_msg();
+ }
+ }
} while ((had_got_int && c == Ctrl_C)
|| c == K_IGNORE
#ifdef FEAT_GUI
@@ -1031,14 +1052,18 @@ wait_return(redraw)
static void
hit_return_msg()
{
- if (msg_didout) /* start on a new line */
+ int save_p_more = p_more;
+
+ p_more = FALSE; /* don't want see this message when scrolling back */
+ if (msg_didout) /* start on a new line */
msg_putchar('\n');
if (got_int)
MSG_PUTS(_("Interrupt: "));
- MSG_PUTS_ATTR(_("Hit ENTER or type command to continue"), hl_attr(HLF_R));
+ MSG_PUTS_ATTR(_("Press ENTER or type command to continue"), hl_attr(HLF_R));
if (!msg_use_printf())
msg_clr_eos();
+ p_more = save_p_more;
}
/*
@@ -1515,7 +1540,7 @@ msg_prt_line(s, list)
if (*s == NUL && !(list && lcs_eol != NUL))
msg_putchar(' ');
- for (;;)
+ while (!got_int)
{
if (n_extra)
{
@@ -1711,22 +1736,10 @@ msg_puts_attr_len(str, maxlen, attr)
int maxlen;
int attr;
{
- int oldState;
- char_u *s = str;
- char_u *p;
- char_u buf[4];
- char_u *t_s = str; /* string from "t_s" to "s" is still todo */
- int t_col = 0; /* screen cells todo, 0 when "t_s" not used */
-#ifdef FEAT_MBYTE
- int l;
- int cw;
-#endif
- int c;
-
/*
* If redirection is on, also write to the redirection file.
*/
- redir_write(s, maxlen);
+ redir_write(str, maxlen);
/*
* Don't print anything when using ":silent cmd".
@@ -1737,7 +1750,7 @@ msg_puts_attr_len(str, maxlen, attr)
/* if MSG_HIST flag set, add message to history */
if ((attr & MSG_HIST) && maxlen < 0)
{
- add_msg_hist(s, -1, attr);
+ add_msg_hist(str, -1, attr);
attr &= ~MSG_HIST;
}
@@ -1759,72 +1772,42 @@ msg_puts_attr_len(str, maxlen, attr)
* cursor is.
*/
if (msg_use_printf())
- {
-#ifdef WIN3264
- if (!(silent_mode && p_verbose == 0))
- mch_settmode(TMODE_COOK); /* handle '\r' and '\n' correctly */
-#endif
- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
- {
- if (!(silent_mode && p_verbose == 0))
- {
- p = &buf[0];
- /* NL --> CR NL translation (for Unix, not for "--version") */
- /* NL --> CR translation (for Mac) */
- if (*s == '\n' && !info_message)
- *p++ = '\r';
-#if defined(USE_CR) && !defined(MACOS_X_UNIX)
- else
-#endif
- *p++ = *s;
- *p = '\0';
- if (info_message) /* informative message, not an error */
- mch_msg((char *)buf);
- else
- mch_errmsg((char *)buf);
- }
-
- /* primitive way to compute the current column */
-#ifdef FEAT_RIGHTLEFT
- if (cmdmsg_rl)
- {
- if (*s == '\r' || *s == '\n')
- msg_col = Columns - 1;
- else
- --msg_col;
- }
- else
-#endif
- {
- if (*s == '\r' || *s == '\n')
- msg_col = 0;
- else
- ++msg_col;
- }
- ++s;
- }
- msg_didout = TRUE; /* assume that line is not empty */
+ msg_puts_printf(str, maxlen);
+ else
+ msg_puts_display(str, maxlen, attr, FALSE);
+}
-#ifdef WIN3264
- if (!(silent_mode && p_verbose == 0))
- mch_settmode(TMODE_RAW);
+/*
+ * The display part of msg_puts_attr_len().
+ * May be called recursively to display scroll-back text.
+ */
+ static void
+msg_puts_display(str, maxlen, attr, recurse)
+ char_u *str;
+ int maxlen;
+ int attr;
+ int recurse;
+{
+ char_u *s = str;
+ char_u *t_s = str; /* string from "t_s" to "s" is still todo */
+ int t_col = 0; /* screen cells todo, 0 when "t_s" not used */
+#ifdef FEAT_MBYTE
+ int l;
+ int cw;
#endif
- return;
- }
+ char_u *sb_str = str;
+ int sb_col = msg_col;
+ int wrap;
did_wait_return = FALSE;
while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
{
/*
- * The screen is scrolled up when:
- * - When outputting a newline in the last row
- * - when outputting a character in the last column of the last row
- * (some terminals scroll automatically, some don't. To avoid
- * problems we scroll ourselves)
+ * We are at the end of the screen line when:
+ * - When outputting a newline.
+ * - When outputting a character in the last column.
*/
- if (msg_row >= Rows - 1
- && (*s == '\n'
- || (
+ if (!recurse && msg_row >= Rows - 1 && (*s == '\n' || (
#ifdef FEAT_RIGHTLEFT
cmdmsg_rl
? (
@@ -1844,47 +1827,55 @@ msg_puts_attr_len(str, maxlen, attr)
# endif
))))
{
+ /*
+ * The screen is scrolled up when at the last row (some terminals
+ * scroll automatically, some don't. To avoid problems we scroll
+ * ourselves).
+ */
if (t_col > 0)
- {
/* output postponed text */
- t_puts(t_col, t_s, s, attr);
- t_col = 0;
- }
+ t_puts(&t_col, t_s, s, attr);
/* When no more prompt an no more room, truncate here */
if (msg_no_more && lines_left == 0)
break;
-#ifdef FEAT_GUI
- /* Remove the cursor before scrolling, ScreenLines[] is going to
- * become invalid. */
- if (gui.in_use)
- gui_undraw_cursor();
-#endif
- /* scrolling up always works */
- screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
- if (!can_clear((char_u *)" "))
- {
- /* Scrolling up doesn't result in the right background. Set
- * the background here. It's not efficient, but avoids that
- * we have to do it all over the code. */
- screen_fill((int)Rows - 1, (int)Rows, 0,
- (int)Columns, ' ', ' ', 0);
-
- /* Also clear the last char of the last but one line if it was
- * not cleared before to avoid a scroll-up. */
- if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1]
- == (sattr_T)-1)
- screen_fill((int)Rows - 2, (int)Rows - 1,
- (int)Columns - 1, (int)Columns, ' ', ' ', 0);
- }
+ /* Scroll the screen up one line. */
+ msg_scroll_up();
msg_row = Rows - 2;
if (msg_col >= Columns) /* can happen after screen resize */
msg_col = Columns - 1;
+ /* Display char in last column before showing more-prompt. */
+ if (*s >= ' '
+#ifdef FEAT_RIGHTLEFT
+ && !cmdmsg_rl
+#endif
+ )
+ {
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ {
+ if (enc_utf8 && maxlen >= 0)
+ /* avoid including composing chars after the end */
+ l = utfc_ptr2len_check_len(s,
+ (int)((str + maxlen) - s));
+ else
+ l = (*mb_ptr2len_check)(s);
+ s = screen_puts_mbyte(s, l, attr);
+ }
+ else
+#endif
+ msg_screen_putchar(*s++, attr);
+ }
+
+ if (p_more)
+ /* store text for scrolling back */
+ store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+
++msg_scrolled;
- need_wait_return = TRUE; /* may need wait_return in main() */
+ need_wait_return = TRUE; /* may need wait_return in main() */
if (must_redraw < VALID)
must_redraw = VALID;
redraw_cmdline = TRUE;
@@ -1892,170 +1883,38 @@ msg_puts_attr_len(str, maxlen, attr)
--cmdline_row;
/*
- * if screen is completely filled wait for a character
+ * If screen is completely filled and 'more' is set then wait
+ * for a character.
*/
if (p_more && --lines_left == 0 && State != HITRETURN
&& !msg_no_more && !exmode_active)
{
- oldState = State;
- State = ASKMORE;
-#ifdef FEAT_MOUSE
- setmouse();
-#endif
- msg_moremsg(FALSE);
- for (;;)
- {
- /*
- * Get a typed character directly from the user.
- */
- c = get_keystroke();
-
-#if defined(FEAT_MENU) && defined(FEAT_GUI)
- if (c == K_MENU)
- {
- int idx = get_menu_index(current_menu, ASKMORE);
-
- /* Used a menu. If it starts with CTRL-Y, it must
- * be a "Copy" for the clipboard. Otherwise
- * assume that we end */
- if (idx == MENU_INDEX_INVALID)
- continue;
- c = *current_menu->strings[idx];
- if (c != NUL && current_menu->strings[idx][1] != NUL)
- ins_typebuf(current_menu->strings[idx] + 1,
- current_menu->noremap[idx], 0, TRUE,
- current_menu->silent[idx]);
- }
-#endif
-
- switch (c)
- {
- case BS:
- case 'k':
- case K_UP:
- if (!more_back_used)
- {
- msg_moremsg(TRUE);
- continue;
- }
- more_back = 1;
- lines_left = 1;
- break;
- case CAR: /* one extra line */
- case NL:
- case 'j':
- case K_DOWN:
- lines_left = 1;
- break;
- case ':': /* start new command line */
-#ifdef FEAT_CON_DIALOG
- if (!confirm_msg_used)
-#endif
- {
- /* Since got_int is set all typeahead will be
- * flushed, but we want to keep this ':', remember
- * that in a special way. */
- typeahead_noflush(':');
- cmdline_row = Rows - 1; /* put ':' on this line */
- skip_redraw = TRUE; /* skip redraw once */
- need_wait_return = FALSE; /* don't wait in main() */
- }
- /*FALLTHROUGH*/
- case 'q': /* quit */
- case Ctrl_C:
- case ESC:
#ifdef FEAT_CON_DIALOG
- if (confirm_msg_used)
- {
- /* Jump to the choices of the dialog. */
- s = confirm_msg_tail;
- lines_left = Rows - 1;
- }
- else
-#endif
- {
- got_int = TRUE;
- quit_more = TRUE;
- }
- break;
- case 'u': /* Up half a page */
- case K_PAGEUP:
- if (!more_back_used)
- {
- msg_moremsg(TRUE);
- continue;
- }
- more_back = Rows / 2;
- /*FALLTHROUGH*/
- case 'd': /* Down half a page */
- lines_left = Rows / 2;
- break;
- case 'b': /* one page back */
- if (!more_back_used)
- {
- msg_moremsg(TRUE);
- continue;
- }
- more_back = Rows - 1;
- /*FALLTHROUGH*/
- case ' ': /* one extra page */
- case K_PAGEDOWN:
- case K_LEFTMOUSE:
- lines_left = Rows - 1;
- break;
-
-#ifdef FEAT_CLIPBOARD
- case Ctrl_Y:
- /* Strange way to allow copying (yanking) a modeless
- * selection at the more prompt. Use CTRL-Y,
- * because the same is used in Cmdline-mode and at the
- * hit-enter prompt. However, scrolling one line up
- * might be expected... */
- if (clip_star.state == SELECT_DONE)
- clip_copy_modeless_selection(TRUE);
- continue;
-#endif
- default: /* no valid response */
- msg_moremsg(TRUE);
- continue;
- }
- break;
- }
-
- /* clear the --more-- message */
- screen_fill((int)Rows - 1, (int)Rows,
- 0, (int)Columns, ' ', ' ', 0);
- State = oldState;
-#ifdef FEAT_MOUSE
- setmouse();
+ if (do_more_prompt(NUL))
+ s = confirm_msg_tail;
+#else
+ (void)do_more_prompt(NUL);
#endif
if (quit_more)
- {
- msg_row = Rows - 1;
- msg_col = 0;
- return; /* the string is not displayed! */
- }
-#ifdef FEAT_RIGHTLEFT
- if (cmdmsg_rl)
- msg_col = Columns - 1;
-#endif
+ return;
}
}
- if (t_col > 0
- && (vim_strchr((char_u *)"\n\r\b\t", *s) != NULL
- || *s == BELL
+ wrap = *s == '\n'
|| msg_col + t_col >= Columns
#ifdef FEAT_MBYTE
|| (has_mbyte && (*mb_ptr2cells)(s) > 1
&& msg_col + t_col >= Columns - 1)
#endif
- ))
- {
+ ;
+ if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
+ || *s == '\t' || *s == BELL))
/* output any postponed text */
- t_puts(t_col, t_s, s, attr);
- t_col = 0;
- }
+ t_puts(&t_col, t_s, s, attr);
+
+ if (wrap && p_more && !recurse)
+ /* store text for scrolling back */
+ store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
if (*s == '\n') /* go to next line */
{
@@ -2073,7 +1932,7 @@ msg_puts_attr_len(str, maxlen, attr)
if (msg_col)
--msg_col;
}
- else if (*s == TAB) /* translate into spaces */
+ else if (*s == TAB) /* translate Tab into spaces */
{
do
msg_screen_putchar(' ', attr);
@@ -2141,17 +2000,172 @@ msg_puts_attr_len(str, maxlen, attr)
/* output any postponed text */
if (t_col > 0)
- t_puts(t_col, t_s, s, attr);
+ t_puts(&t_col, t_s, s, attr);
+ if (p_more && !recurse)
+ store_sb_text(&sb_str, s, attr, &sb_col, FALSE);
msg_check();
}
/*
+ * Scroll the screen up one line for displaying the next message line.
+ */
+ static void
+msg_scroll_up()
+{
+#ifdef FEAT_GUI
+ /* Remove the cursor before scrolling, ScreenLines[] is going
+ * to become invalid. */
+ if (gui.in_use)
+ gui_undraw_cursor();
+#endif
+ /* scrolling up always works */
+ screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
+
+ if (!can_clear((char_u *)" "))
+ {
+ /* Scrolling up doesn't result in the right background. Set the
+ * background here. It's not efficient, but avoids that we have to do
+ * it all over the code. */
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+
+ /* Also clear the last char of the last but one line if it was not
+ * cleared before to avoid a scroll-up. */
+ if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1] == (sattr_T)-1)
+ screen_fill((int)Rows - 2, (int)Rows - 1,
+ (int)Columns - 1, (int)Columns, ' ', ' ', 0);
+ }
+}
+
+/*
+ * To be able to scroll back at the "more" and "hit-enter" prompts we need to
+ * store the displayed text and remember where screen lines start.
+ */
+typedef struct msgchunk_S msgchunk_T;
+struct msgchunk_S
+{
+ msgchunk_T *sb_next;
+ msgchunk_T *sb_prev;
+ char sb_eol; /* TRUE when line ends after this text */
+ int sb_msg_col; /* column in which text starts */
+ int sb_attr; /* text attributes */
+ char_u sb_text[1]; /* text to be displayed, actually longer */
+};
+
+static msgchunk_T *last_msgchunk = NULL; /* last displayed text */
+
+static msgchunk_T *msg_sb_start __ARGS((msgchunk_T *mps));
+static msgchunk_T *disp_sb_line __ARGS((int row, msgchunk_T *smp));
+
+/*
+ * Store part of a printed message for displaying when scrolling back.
+ */
+ static void
+store_sb_text(sb_str, s, attr, sb_col, finish)
+ char_u **sb_str; /* start of string */
+ char_u *s; /* just after string */
+ int attr;
+ int *sb_col;
+ int finish; /* line ends */
+{
+ msgchunk_T *mp;
+
+ if (s > *sb_str)
+ {
+ mp = (msgchunk_T *)alloc((int)(sizeof(msgchunk_T) + (s - *sb_str)));
+ if (mp != NULL)
+ {
+ mp->sb_eol = finish;
+ mp->sb_msg_col = *sb_col;
+ mp->sb_attr = attr;
+ vim_strncpy(mp->sb_text, *sb_str, s - *sb_str);
+
+ if (last_msgchunk == NULL)
+ {
+ last_msgchunk = mp;
+ mp->sb_prev = NULL;
+ }
+ else
+ {
+ mp->sb_prev = last_msgchunk;
+ last_msgchunk->sb_next = mp;
+ last_msgchunk = mp;
+ }
+ mp->sb_next = NULL;
+ }
+ }
+ else if (finish && last_msgchunk != NULL)
+ last_msgchunk->sb_eol = TRUE;
+
+ *sb_str = s;
+ *sb_col = 0;
+}
+
+/*
+ * Clear any text remembered for scrolling back.
+ * Called when redrawing the screen.
+ */
+ void
+clear_sb_text()
+{
+ msgchunk_T *mp;
+
+ while (last_msgchunk != NULL)
+ {
+ mp = last_msgchunk->sb_prev;
+ vim_free(last_msgchunk);
+ last_msgchunk = mp;
+ }
+ last_msgchunk = NULL;
+}
+
+/*
+ * Move to the start of screen line in already displayed text.
+ */
+ static msgchunk_T *
+msg_sb_start(mps)
+ msgchunk_T *mps;
+{
+ msgchunk_T *mp = mps;
+
+ while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol)
+ mp = mp->sb_prev;
+ return mp;
+}
+
+/*
+ * Display a screen line from previously displayed text at row "row".
+ * Returns a pointer to the text for the next line (can be NULL).
+ */
+ static msgchunk_T *
+disp_sb_line(row, smp)
+ int row;
+ msgchunk_T *smp;
+{
+ msgchunk_T *mp = smp;
+ char_u *p;
+
+ for (;;)
+ {
+ msg_row = row;
+ msg_col = mp->sb_msg_col;
+ p = mp->sb_text;
+ if (*p == '\n') /* don't display the line break */
+ ++p;
+ msg_puts_display(p, -1, mp->sb_attr, TRUE);
+ if (mp->sb_eol || mp->sb_next == NULL)
+ break;
+ mp = mp->sb_next;
+ }
+ return mp->sb_next;
+}
+
+/*
* Output any postponed text for msg_puts_attr_len().
*/
static void
t_puts(t_col, t_s, s, attr)
- int t_col;
+ int *t_col;
char_u *t_s;
char_u *s;
int attr;
@@ -2159,7 +2173,8 @@ t_puts(t_col, t_s, s, attr)
/* output postponed text */
msg_didout = TRUE; /* remember that line is not empty */
screen_puts_len(t_s, (int)(s - t_s), msg_row, msg_col, attr);
- msg_col += t_col;
+ msg_col += *t_col;
+ *t_col = 0;
#ifdef FEAT_MBYTE
/* If the string starts with a composing character don't increment the
* column position for it. */
@@ -2173,7 +2188,6 @@ t_puts(t_col, t_s, s, attr)
}
}
-
/*
* Returns TRUE when messages should be printed with mch_errmsg().
* This is used when there is no valid screen, so we can see error messages.
@@ -2193,6 +2207,309 @@ msg_use_printf()
);
}
+/*
+ * Print a message when there is no valid screen.
+ */
+ static void
+msg_puts_printf(str, maxlen)
+ char_u *str;
+ int maxlen;
+{
+ char_u *s = str;
+ char_u buf[4];
+ char_u *p;
+
+#ifdef WIN3264
+ if (!(silent_mode && p_verbose == 0))
+ mch_settmode(TMODE_COOK); /* handle '\r' and '\n' correctly */
+#endif
+ while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
+ {
+ if (!(silent_mode && p_verbose == 0))
+ {
+ /* NL --> CR NL translation (for Unix, not for "--version") */
+ /* NL --> CR translation (for Mac) */
+ p = &buf[0];
+ if (*s == '\n' && !info_message)
+ *p++ = '\r';
+#if defined(USE_CR) && !defined(MACOS_X_UNIX)
+ else
+#endif
+ *p++ = *s;
+ *p = '\0';
+ if (info_message) /* informative message, not an error */
+ mch_msg((char *)buf);
+ else
+ mch_errmsg((char *)buf);
+ }
+
+ /* primitive way to compute the current column */
+#ifdef FEAT_RIGHTLEFT
+ if (cmdmsg_rl)
+ {
+ if (*s == '\r' || *s == '\n')
+ msg_col = Columns - 1;
+ else
+ --msg_col;
+ }
+ else
+#endif
+ {
+ if (*s == '\r' || *s == '\n')
+ msg_col = 0;
+ else
+ ++msg_col;
+ }
+ ++s;
+ }
+ msg_didout = TRUE; /* assume that line is not empty */
+
+#ifdef WIN3264
+ if (!(silent_mode && p_verbose == 0))
+ mch_settmode(TMODE_RAW);
+#endif
+}
+
+/*
+ * Show the more-prompt and handle the user response.
+ * This takes care of scrolling back and displaying previously displayed text.
+ * When at hit-enter prompt "typed_char" is the already typed character.
+ * Returns TRUE when jumping ahead to "confirm_msg_tail".
+ */
+ static int
+do_more_prompt(typed_char)
+ int typed_char;
+{
+ int used_typed_char = typed_char;
+ int oldState = State;
+ int c;
+#ifdef FEAT_CON_DIALOG
+ int retval = FALSE;
+#endif
+ int scroll;
+ msgchunk_T *mp_last = NULL;
+ msgchunk_T *mp;
+ int i;
+
+ State = ASKMORE;
+#ifdef FEAT_MOUSE
+ setmouse();
+#endif
+ msg_moremsg(FALSE);
+ for (;;)
+ {
+ /*
+ * Get a typed character directly from the user.
+ */
+ if (used_typed_char != NUL)
+ {
+ c = used_typed_char; /* was typed at hit-enter prompt */
+ used_typed_char = NUL;
+ }
+ else
+ c = get_keystroke();
+
+#if defined(FEAT_MENU) && defined(FEAT_GUI)
+ if (c == K_MENU)
+ {
+ int idx = get_menu_index(current_menu, ASKMORE);
+
+ /* Used a menu. If it starts with CTRL-Y, it must
+ * be a "Copy" for the clipboard. Otherwise
+ * assume that we end */
+ if (idx == MENU_INDEX_INVALID)
+ continue;
+ c = *current_menu->strings[idx];
+ if (c != NUL && current_menu->strings[idx][1] != NUL)
+ ins_typebuf(current_menu->strings[idx] + 1,
+ current_menu->noremap[idx], 0, TRUE,
+ current_menu->silent[idx]);
+ }
+#endif
+
+ scroll = 0;
+ switch (c)
+ {
+ case BS: /* scroll one line back */
+ case K_BS:
+ case 'k':
+ case K_UP:
+ scroll = -1;
+ break;
+
+ case CAR: /* one extra line */
+ case NL:
+ case 'j':
+ case K_DOWN:
+ scroll = 1;
+ break;
+
+ case 'u': /* Up half a page */
+ case K_PAGEUP:
+ scroll = -(Rows / 2);
+ break;
+
+ case 'd': /* Down half a page */
+ scroll = Rows / 2;
+ break;
+
+ case 'b': /* one page back */
+ scroll = -(Rows - 1);
+ break;
+
+ case ' ': /* one extra page */
+ case K_PAGEDOWN:
+ case K_LEFTMOUSE:
+ scroll = Rows - 1;
+ break;
+
+ case ':': /* start new command line */
+#ifdef FEAT_CON_DIALOG
+ if (!confirm_msg_used)
+#endif
+ {
+ /* Since got_int is set all typeahead will be flushed, but we
+ * want to keep this ':', remember that in a special way. */
+ typeahead_noflush(':');
+ cmdline_row = Rows - 1; /* put ':' on this line */
+ skip_redraw = TRUE; /* skip redraw once */
+ need_wait_return = FALSE; /* don't wait in main() */
+ }
+ /*FALLTHROUGH*/
+ case 'q': /* quit */
+ case Ctrl_C:
+ case ESC:
+#ifdef FEAT_CON_DIALOG
+ if (confirm_msg_used)
+ {
+ /* Jump to the choices of the dialog. */
+ retval = TRUE;
+ lines_left = Rows - 1;
+ }
+ else
+#endif
+ {
+ got_int = TRUE;
+ quit_more = TRUE;
+ }
+ break;
+
+#ifdef FEAT_CLIPBOARD
+ case Ctrl_Y:
+ /* Strange way to allow copying (yanking) a modeless
+ * selection at the more prompt. Use CTRL-Y,
+ * because the same is used in Cmdline-mode and at the
+ * hit-enter prompt. However, scrolling one line up
+ * might be expected... */
+ if (clip_star.state == SELECT_DONE)
+ clip_copy_modeless_selection(TRUE);
+ continue;
+#endif
+ default: /* no valid response */
+ msg_moremsg(TRUE);
+ continue;
+ }
+
+ if (scroll != 0)
+ {
+ if (scroll < 0)
+ {
+ /* go to start of last line */
+ if (mp_last == NULL)
+ mp = msg_sb_start(last_msgchunk);
+ else if (mp_last->sb_prev != NULL)
+ mp = msg_sb_start(mp_last->sb_prev);
+ else
+ mp = NULL;
+
+ /* go to start of line at top of the screen */
+ for (i = 0; i < Rows - 2 && mp != NULL && mp->sb_prev != NULL;
+ ++i)
+ mp = msg_sb_start(mp->sb_prev);
+
+ if (mp != NULL && mp->sb_prev != NULL)
+ {
+ /* Find line to be displayed at top. */
+ for (i = 0; i > scroll; --i)
+ {
+ if (mp == NULL || mp->sb_prev == NULL)
+ break;
+ mp = msg_sb_start(mp->sb_prev);
+ if (mp_last == NULL)
+ mp_last = msg_sb_start(last_msgchunk);
+ else
+ mp_last = msg_sb_start(mp_last->sb_prev);
+ }
+
+ if (scroll == -1 && screen_ins_lines(0, 0, 1,
+ (int)Rows, NULL) == OK)
+ {
+ /* clear last line, display line at top */
+ screen_fill((int)Rows - 1, (int)Rows, 0,
+ (int)Columns, ' ', ' ', 0);
+ (void)disp_sb_line(0, mp);
+ }
+ else
+ {
+ /* redisplay */
+ screenclear();
+ for (i = 0; i < Rows - 1; ++i)
+ mp = disp_sb_line(i, mp);
+ }
+ scroll = 0;
+ }
+ }
+ else
+ {
+ /* First display any text that we scrolled back. */
+ while (scroll > 0 && mp_last != NULL)
+ {
+ /* scroll up, display line at bottom */
+ msg_scroll_up();
+ screen_fill((int)Rows - 2, (int)Rows - 1, 0,
+ (int)Columns, ' ', ' ', 0);
+ mp_last = disp_sb_line((int)Rows - 2, mp_last);
+ --scroll;
+ }
+ }
+
+ if (scroll <= 0)
+ {
+ /* displayed the requested text, more prompt again */
+ msg_moremsg(FALSE);
+ continue;
+ }
+
+ /* display more text, return to caller */
+ lines_left = scroll;
+ }
+
+ break;
+ }
+
+ /* clear the --more-- message */
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ State = oldState;
+#ifdef FEAT_MOUSE
+ setmouse();
+#endif
+ if (quit_more)
+ {
+ msg_row = Rows - 1;
+ msg_col = 0;
+ }
+#ifdef FEAT_RIGHTLEFT
+ else if (cmdmsg_rl)
+ msg_col = Columns - 1;
+#endif
+
+#ifdef FEAT_CON_DIALOG
+ return retval;
+#else
+ return FALSE;
+#endif
+}
+
#if defined(USE_MCH_ERRMSG) || defined(PROTO)
#ifdef mch_errmsg
@@ -2344,15 +2661,15 @@ msg_screen_putchar(c, attr)
msg_moremsg(full)
int full;
{
- int attr;
+ int attr;
+ char_u *s = (char_u *)_("-- More --");
attr = hl_attr(HLF_M);
- screen_puts((char_u *)_("-- More --"), (int)Rows - 1, 0, attr);
+ screen_puts(s, (int)Rows - 1, 0, attr);
if (full)
- screen_puts(more_back_used
- ? (char_u *)_(" (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)")
- : (char_u *)_(" (RET: line, SPACE: page, d: half page, q: quit)"),
- (int)Rows - 1, 10, attr);
+ screen_puts((char_u *)
+ _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "),
+ (int)Rows - 1, vim_strsize(s), attr);
}
/*