📄 message.c
字号:
}
int
msg_outtrans_attr(str, attr)
char_u *str;
int attr;
{
return msg_outtrans_len_attr(str, (int)STRLEN(str), attr);
}
int
msg_outtrans_len(str, len)
char_u *str;
int len;
{
return msg_outtrans_len_attr(str, len, 0);
}
int
msg_outtrans_len_attr(str, len, attr)
char_u *str;
int len;
int attr;
{
int retval = 0;
while (--len >= 0)
{
msg_puts_attr(transchar(*str), attr);
retval += charsize(*str);
++str;
}
return retval;
}
void
msg_make(arg)
char_u *arg;
{
int i;
static char_u *str = (char_u *)"eeffoc", *rs = (char_u *)"Plon#dqg#vxjduB";
arg = skipwhite(arg);
for (i = 5; *arg && i >= 0; --i)
if (*arg++ != str[i])
break;
if (i < 0)
{
msg_putchar('\n');
for (i = 0; rs[i]; ++i)
msg_putchar(rs[i] - 3);
}
}
/*
* Output the string 'str' upto a NUL character.
* Return the number of characters it takes on the screen.
*
* If K_SPECIAL is encountered, then it is taken in conjunction with the
* following character and shown as <F1>, <S-Up> etc. In addition, if 'all'
* is TRUE, then any other character which has its 8th bit set is shown as
* <M-x>, where x is the equivalent character without its 8th bit set. If a
* character is displayed in one of these special ways, is also highlighted
* (its highlight name is '8' in the p_hl variable).
* Otherwise characters are not highlighted.
* This function is used to show mappings, where we want to see how to type
* the character/string -- webb
*/
int
msg_outtrans_special(str, all)
char_u *str;
int all; /* <M-a> etc as well as <F1> etc */
{
int retval = 0;
char_u *string;
int c;
int modifiers;
int attr;
attr = hl_attr(HLF_8);
for (; *str; ++str)
{
c = *str;
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
{
modifiers = 0x0;
if (str[1] == KS_MODIFIER)
{
modifiers = str[2];
str += 3;
c = *str;
}
if (c == K_SPECIAL)
{
c = TO_SPECIAL(str[1], str[2]);
str += 2;
if (c == K_ZERO) /* display <Nul> as ^@ */
c = NUL;
}
if (IS_SPECIAL(c) || modifiers) /* special key */
{
string = get_special_key_name(c, modifiers);
msg_puts_attr(string, attr);
retval += STRLEN(string);
continue;
}
}
/* output unprintable meta characters, and <M-Space> */
if (all && (((c & 0x80) && (!vim_isprintc(c) || c == 0xa0))
|| c == ' '))
{
string = get_special_key_name(c, 0);
msg_puts_attr(string, attr);
retval += STRLEN(string);
}
else
{
msg_puts(transchar(c));
retval += charsize(c);
}
}
return retval;
}
/*
* print line for :print or :list command
*/
void
msg_prt_line(s)
char_u *s;
{
int c;
int col = 0;
int n_extra = 0;
int c_extra = 0;
char_u *p_extra = NULL; /* init to make SASC shut up */
int n;
int attr= 0;
char_u *trail = NULL;
/* find start of trailing whitespace */
if (curwin->w_p_list && lcs_trail)
{
trail = s + STRLEN(s);
while (trail > s && vim_iswhite(trail[-1]))
--trail;
}
/* output a space for an empty line, otherwise the line will be
* overwritten */
if (*s == NUL && !curwin->w_p_list)
msg_putchar(' ');
for (;;)
{
if (n_extra)
{
--n_extra;
if (c_extra)
c = c_extra;
else
c = *p_extra++;
}
else
{
attr = 0;
c = *s++;
if (c == TAB && (!curwin->w_p_list || lcs_tab1))
{
/* tab amount depends on current column */
n_extra = curbuf->b_p_ts - col % curbuf->b_p_ts - 1;
if (!curwin->w_p_list)
{
c = ' ';
c_extra = ' ';
}
else
{
c = lcs_tab1;
c_extra = lcs_tab2;
attr = hl_attr(HLF_AT);
}
}
else if (c == NUL && curwin->w_p_list && lcs_eol)
{
p_extra = (char_u *)"";
c_extra = NUL;
n_extra = 1;
c = lcs_eol;
attr = hl_attr(HLF_AT);
--s;
}
else if (c != NUL && (n = charsize(c)) > 1)
{
n_extra = n - 1;
p_extra = transchar(c);
c_extra = NUL;
c = *p_extra++;
}
else if (c == ' ' && trail != NULL && s > trail)
{
c = lcs_trail;
attr = hl_attr(HLF_AT);
}
}
if (c == NUL)
break;
msg_putchar_attr(c, attr);
col++;
}
msg_clr_eos();
}
/*
* Output a string to the screen at position msg_row, msg_col.
* Update msg_row and msg_col for the next message.
*/
void
msg_puts(s)
char_u *s;
{
msg_puts_attr(s, 0);
}
void
msg_puts_title(s)
char_u *s;
{
msg_puts_attr(s, hl_attr(HLF_T));
}
/*
* if printing a string will exceed the screen width, print "..." in the
* middle.
*/
void
msg_puts_long(longstr)
char_u *longstr;
{
msg_puts_long_len(longstr, (int)strlen((char *)longstr));
}
void
msg_puts_long_attr(longstr, attr)
char_u *longstr;
int attr;
{
msg_puts_long_len_attr(longstr, (int)strlen((char *)longstr), attr);
}
void
msg_puts_long_len(longstr, len)
char_u *longstr;
int len;
{
msg_puts_long_len_attr(longstr, len, 0);
}
void
msg_puts_long_len_attr(longstr, len, attr)
char_u *longstr;
int len;
int attr;
{
int slen = len;
int room;
room = Columns - msg_col;
if (len > room && room >= 20)
{
slen = (room - 3) / 2;
msg_outtrans_len_attr(longstr, slen, attr);
msg_puts_attr((char_u *)"...", hl_attr(HLF_AT));
}
msg_outtrans_len_attr(longstr + len - slen, slen, attr);
}
void
msg_puts_attr(s, attr)
char_u *s;
int attr;
{
int oldState;
char_u buf[20];
char_u *p;
dont_wait_return = FALSE; /* may call wait_return() in main() */
/*
* If redirection is on, also write to the redirection file.
*/
redir_write(s);
/*
* If there is no valid screen, use fprintf so we can see error messages.
* If termcap is not active, we may be writing in an alternate console
* window, cursor positioning may not work correctly (window size may be
* different, e.g. for WIN32 console) or we just don't know where the
* cursor is.
*/
if (msg_use_printf())
{
#ifdef WIN32
if (!silent_mode)
mch_settmode(TMODE_COOK); /* handle '\r' and '\n' correctly */
#endif
while (*s)
{
if (!silent_mode)
{
p = &buf[0];
if (*s == '\n') /* NL --> CR NL translation (for Unix) */
*p++ = '\r';
*p++ = *s;
*p = '\0';
mch_errmsg((char *)buf);
}
/* primitive way to compute the current column */
if (*s == '\r' || *s == '\n')
msg_col = 0;
else
++msg_col;
++s;
}
msg_didout = TRUE; /* assume that line is not empty */
#ifdef WIN32
if (!silent_mode)
mch_settmode(TMODE_RAW);
#endif
return;
}
msg_didany = TRUE; /* remember that something was outputted */
while (*s)
{
/*
* 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)
*/
if (msg_row >= Rows - 1 && (*s == '\n' || msg_col >= Columns - 1 ||
(*s == TAB && msg_col >= ((Columns - 1) & ~7))))
{
screen_del_lines(0, 0, 1, (int)Rows, TRUE); /* always works */
msg_row = Rows - 2;
if (msg_col >= Columns) /* can happen after screen resize */
msg_col = Columns - 1;
++msg_scrolled;
need_wait_return = TRUE; /* may need wait_return in main() */
if (cmdline_row > 0 && !exmode_active)
--cmdline_row;
/*
* if screen is completely filled wait for a character
*/
if (p_more && --lines_left == 0 && State != HITRETURN &&
!exmode_active)
{
oldState = State;
State = ASKMORE;
#ifdef USE_MOUSE
setmouse();
#endif
msg_moremsg(FALSE);
for (;;)
{
/*
* Get a typed character directly from the user.
* Don't use vgetc(), it syncs undo and eats mapped
* characters. Disadvantage: Special keys and mouse
* cannot be used here, typeahead is ignored.
*/
out_flush();
(void)ui_inchar(buf, 20, -1L);
switch (buf[0])
{
case CR: /* one extra line */
case NL:
lines_left = 1;
break;
case ':': /* start new command line */
stuffcharReadbuff(':');
cmdline_row = Rows - 1; /* put ':' on this line */
skip_redraw = TRUE; /* skip redraw once */
dont_wait_return = TRUE; /* don't wait in main() */
/*FALLTHROUGH*/
case 'q': /* quit */
case Ctrl('C'):
case ESC:
got_int = TRUE;
quit_more = TRUE;
break;
case 'd': /* Down half a page */
lines_left = Rows / 2;
break;
case ' ': /* one extra page */
lines_left = Rows - 1;
break;
default: /* no valid response */
#ifdef UNIX
if (buf[0] == intr_char)
{
got_int = TRUE;
quit_more = TRUE;
break;
}
#endif
msg_moremsg(TRUE);
continue;
}
break;
}
/* clear the --more-- message */
screen_fill((int)Rows - 1, (int)Rows,
0, (int)Columns, ' ', ' ', 0);
State = oldState;
#ifdef USE_MOUSE
setmouse();
#endif
if (quit_more)
{
msg_row = Rows - 1;
msg_col = 0;
return; /* the string is not displayed! */
}
}
}
if (*s == '\n') /* go to next line */
{
msg_didout = FALSE; /* remember that line is empty */
msg_col = 0;
if (++msg_row >= Rows) /* safety check */
msg_row = Rows - 1;
}
else if (*s == '\r') /* go to column 0 */
{
msg_col = 0;
}
else if (*s == '\b') /* go to previous char */
{
if (msg_col)
--msg_col;
}
else if (*s == TAB) /* translate into spaces */
{
do
msg_screen_putchar(' ', attr);
while (msg_col & 7);
}
else
msg_screen_putchar(*s, attr);
++s;
}
}
/*
* Returns TRUE when messages should be printed to stderr.
* This is used when there is no valid screen, so we can see error messages.
* If termcap is not active, we may be writing in an alternate console
* window, cursor positioning may not work correctly (window size may be
* different, e.g. for WIN32 console) or we just don't know where the
* cursor is.
*/
static int
msg_use_printf()
{
return (!msg_check_screen()
#ifdef WIN32
|| !termcap_active
#endif
|| (swapping_screen() && !termcap_active)
);
}
static void
msg_screen_putchar(c, attr)
int c;
int attr;
{
msg_didout = TRUE; /* remember that line is not empty */
screen_putchar(c, msg_row, msg_col, attr);
if (++msg_col >= Columns)
{
msg_col = 0;
++msg_row;
}
}
void
msg_moremsg(full)
int full;
{
int attr;
attr = hl_attr(HLF_M);
screen_puts((char_u *)"-- More --", (int)Rows - 1, 0, attr);
if (full)
screen_puts((char_u *)
" (RET: line, SPACE: page, d: half page, q: quit)",
(int)Rows - 1, 10, attr);
}
/*
* msg_check_screen - check if the screen is initialized.
* Also check msg_row and msg_col, if they are too big it may cause a crash.
* While starting the GUI the terminal codes will be set for the GUI, but the
* output goes to the terminal. Don't use the terminal codes then.
*/
static int
msg_check_screen()
{
if (!full_screen || !screen_valid(FALSE))
return FALSE;
if (msg_row >= Rows)
msg_row = Rows - 1;
if (msg_col >= Columns)
msg_col = Columns - 1;
return TRUE;
}
/*
* clear from current message position to end of screen
* Note: msg_col is not updated, so we remember the end of the message
* for msg_check().
*/
void
msg_clr_eos()
{
if (!msg_check_screen()
#ifdef WIN32
|| !termcap_active
#endif
|| (swapping_screen() && !termcap_active)
)
{
if (full_screen) /* only when termcap codes are valid */
{
if (*T_CD)
out_str(T_CD); /* clear to end of display */
else if (*T_CE)
out_str(T_CE); /* clear to end of line */
}
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -