⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 message.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
}

    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 + -