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

📄 term.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
    out_buf[out_pos++] = c;

    if (out_pos >= OUT_SIZE)
	out_flush();
}

/*
 * A never-padding out_str.
 * use this whenever you don't want to run the string through tputs.
 * tputs above is harmless, but tputs from the termcap library
 * is likely to strip off leading digits, that it mistakes for padding
 * information. (jw)
 * This should only be used for writing terminal codes, not for outputting
 * normal text (use functions like msg_puts() and screen_putchar() for that).
 */
    void
out_str_nf(s)
    char_u *s;
{
    if (out_pos > OUT_SIZE - 20)  /* avoid terminal strings being split up */
	out_flush();
    while (*s)
	out_char_nf(*s++);

    /* For testing we write one string at a time. */
    if (p_wd)
	out_flush();
}

/*
 * out_str(s): Put a string character at a time into the output buffer.
 * If HAVE_TGETENT is defined use the termcap parser. (jw)
 * This should only be used for writing terminal codes, not for outputting
 * normal text (use functions like msg_puts() and screen_putchar() for that).
 */
    void
out_str(s)
    char_u	 *s;
{
    if (out_pos > OUT_SIZE - 20)  /* avoid terminal strings being split up */
	out_flush();
    if (s != NULL && *s)
#ifdef HAVE_TGETENT
	tputs((char *)s, 1, TPUTSFUNCAST out_char_nf);
#else
	while (*s)
	    out_char_nf(*s++);
#endif

    /* For testing we write one string at a time. */
    if (p_wd)
	out_flush();
}

/*
 * cursor positioning using termcap parser. (jw)
 */
    void
term_windgoto(row, col)
    int	    row;
    int	    col;
{
    OUT_STR(tgoto((char *)T_CM, col, row));
}

    void
term_cursor_right(i)
    int	    i;
{
    OUT_STR(tgoto((char *)T_CRI, 0, i));
}

    void
term_append_lines(line_count)
    int	    line_count;
{
    OUT_STR(tgoto((char *)T_CAL, 0, line_count));
}

    void
term_delete_lines(line_count)
    int	    line_count;
{
    OUT_STR(tgoto((char *)T_CDL, 0, line_count));
}

    void
term_fg_color(n)
    int	    n;
{
    /* Use "AF" termcap entry if present, "Sf" entry otherwise */
    if (*T_CAF)
	term_color(T_CAF, n);
    else if (*T_CSF)
	term_color(T_CSF, n);
}

    void
term_bg_color(n)
    int	    n;
{
    /* Use "AB" termcap entry if present, "Sb" entry otherwise */
    if (*T_CAB)
	term_color(T_CAB, n);
    else if (*T_CSB)
	term_color(T_CSB, n);
}

    static void
term_color(s, n)
    char_u  *s;
    int	    n;
{
    /* Special handling of 16 colors, because termcap can't handle it */
    if (n > 7 && atoi((char *)T_CCO) == 16
	      && s[0] == ESC && s[1] == '[' && s[2] != NUL
#ifdef TERMINFO
	      && STRCMP(s + 3, "%p1%dm") == 0
#else
	      && STRCMP(s + 3, "%dm") == 0
#endif
		)
    {
	if (s[2] == '3')	/* foreground */
	{
#ifdef TERMINFO
	    OUT_STR(tgoto("\033[9%p1%dm", 0, n - 8));
#else
	    OUT_STR(tgoto("\033[9%dm", 0, n - 8));
#endif
	    return;
	}
	if (s[2] == '4')	/* background */
	{
#ifdef TERMINFO
	    OUT_STR(tgoto("\033[10%p1%dm", 0, n - 8));
#else
	    OUT_STR(tgoto("\033[10%dm", 0, n - 8));
#endif
	    return;
	}

    }
    OUT_STR(tgoto((char *)s, 0, n));
}

/*
 * Make sure we have a valid set or terminal options.
 * Replace all entries that are NULL by empty_option
 */
    void
ttest(pairs)
    int	pairs;
{
    char    *t = NULL;

    check_options();		    /* make sure no options are NULL */

  /* hard requirements */
    if (*T_CL == NUL)		    /* erase display */
	t = "cl";
    if (*T_CM == NUL)		    /* cursor motion */
	t = "cm";

    if (t != NULL)
	EMSG2("terminal capability %s required", t);

/*
 * if "cs" defined, use a scroll region, it's faster.
 */
    if (*T_CS != NUL)
	scroll_region = TRUE;
    else
	scroll_region = FALSE;

    if (pairs)
    {
	/*
	 * optional pairs
	 */
	/* TP goes to normal mode for TI (invert) and TB (bold) */
	if (*T_ME == NUL)
	    T_ME = T_MR = T_MD = T_MB = empty_option;
	if (*T_SO == NUL || *T_SE == NUL)
	    T_SO = T_SE = empty_option;
	if (*T_US == NUL || *T_UE == NUL)
	    T_US = T_UE = empty_option;
	if (*T_CZH == NUL || *T_CZR == NUL)
	    T_CZH = T_CZR = empty_option;

	/* T_VE is needed even though T_VI is not defined */
	if (*T_VE == NUL)
	    T_VI = empty_option;

	/* if 'mr' or 'me' is not defined use 'so' and 'se' */
	if (*T_ME == NUL)
	{
	    T_ME = T_SE;
	    T_MR = T_SO;
	    T_MD = T_SO;
	}

	/* if 'so' or 'se' is not defined use 'mr' and 'me' */
	if (*T_SO == NUL)
	{
	    T_SE = T_ME;
	    if (*T_MR == NUL)
		T_SO = T_MD;
	    else
		T_SO = T_MR;
	}

	/* if 'ZH' or 'ZR' is not defined use 'mr' and 'me' */
	if (*T_CZH == NUL)
	{
	    T_CZR = T_ME;
	    if (*T_MR == NUL)
		T_CZH = T_MD;
	    else
		T_CZH = T_MR;
	}

	/* "Sb" and "Sf" come in pairs */
	if (*T_CSB == NUL || *T_CSF == NUL)
	{
	    T_CSB = empty_option;
	    T_CSF = empty_option;
	}

	/* "AB" and "AF" come in pairs */
	if (*T_CAB == NUL || *T_CAF == NUL)
	{
	    T_CAB = empty_option;
	    T_CAF = empty_option;
	}

	/* if 'Sb' and 'AB' are not defined, reset "Co" */
	if (*T_CSB == NUL && *T_CAB == NUL)
	    T_CCO = empty_option;

	/* Set 'weirdinvert' according to value of 't_xs' */
	p_wiv = (*T_XS != NUL);
    }
    need_gather = TRUE;
}

/*
 * Represent the given long_u as individual bytes, with the most significant
 * byte first, and store them in dst.
 */
    void
add_long_to_buf(val, dst)
    long_u  val;
    char_u  *dst;
{
    int	    i;
    int	    shift;

    for (i = 1; i <= sizeof(long_u); i++)
    {
	shift = 8 * (sizeof(long_u) - i);
	dst[i - 1] = (char_u) ((val >> shift) & 0xff);
    }
}

/*
 * Interpret the next string of bytes in buf as a long integer, with the most
 * significant byte first.  Note that it is assumed that buf has been through
 * inchar(), so that NUL and K_SPECIAL will be represented as three bytes each.
 * Puts result in val, and returns the number of bytes read from buf
 * (between sizeof(long_u) and 2 * sizeof(long_u)), or -1 if not enough bytes
 * were present.
 */
    int
get_long_from_buf(buf, val)
    char_u  *buf;
    long_u  *val;
{
    int	    len;
    char_u  bytes[sizeof(long_u)];
    int	    i;
    int	    shift;

    *val = 0;
    len = get_bytes_from_buf(buf, bytes, (int)sizeof(long_u));
    if (len != -1)
    {
	for (i = 0; i < sizeof(long_u); i++)
	{
	    shift = 8 * (sizeof(long_u) - 1 - i);
	    *val += (long_u)bytes[i] << shift;
	}
    }
    return len;
}

/*
 * Read the next num_bytes bytes from buf, and store them in bytes.  Assume
 * that buf has been through inchar().	Returns the actual number of bytes used
 * from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
 * available.
 */
    static int
get_bytes_from_buf(buf, bytes, num_bytes)
    char_u  *buf;
    char_u  *bytes;
    int	    num_bytes;
{
    int	    len = 0;
    int	    i;
    char_u  c;

    for (i = 0; i < num_bytes; i++)
    {
	if ((c = buf[len++]) == NUL)
	    return -1;
	if (c == K_SPECIAL)
	{
	    if (buf[len] == NUL || buf[len + 1] == NUL)	    /* cannot happen? */
		return -1;
	    if (buf[len++] == (int)KS_ZERO)
		c = NUL;
	    ++len;	/* skip K_FILLER */
	    /* else it should be KS_SPECIAL, and c already equals K_SPECIAL */
	}
	bytes[i] = c;
    }
    return len;
}

    void
check_winsize()
{
    static int	old_Rows = 0;

    if (Columns < MIN_COLUMNS)
	Columns = MIN_COLUMNS;
    if (Rows < min_rows())	/* need room for one window and command line */
	Rows = min_rows();

    if (old_Rows != Rows)
    {
	old_Rows = Rows;
	screen_new_rows();	/* may need to update window sizes */
    }
}

/*
 * set window size
 * If 'mustset' is TRUE, we must set Rows and Columns, do not get real
 * window size (this is used for the :win command).
 * If 'mustset' is FALSE, we may try to get the real window size and if
 * it fails use 'width' and 'height'.
 */
    void
set_winsize(width, height, mustset)
    int	    width, height;
    int	    mustset;
{
    static int		busy = FALSE;

    /*
     * Avoid recursiveness, can happen when setting the window size causes
     * another window-changed signal.
     */
    if (busy)
	return;

    if (width < 0 || height < 0)    /* just checking... */
	return;

    if (State == HITRETURN || State == SETWSIZE) /* postpone the resizing */
    {
	State = SETWSIZE;
	return;
    }

    ++busy;

    if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
	screenclear();
    else
	screen_start();	    /* don't know where cursor is now */
#ifdef AMIGA
    out_flush();	    /* must do this before mch_get_winsize() for some
			       obscure reason */
#endif /* AMIGA */

    if (mustset || (ui_get_winsize() == FAIL && height != 0))
    {
	Rows = height;
	Columns = width;
	check_winsize();	/* always check, to get p_scroll right */
	ui_set_winsize();
    }
    else
	check_winsize();	/* always check, to get p_scroll right */

    if (!starting)
    {
	maketitle();

	/*
	 * We only redraw when it's needed:
	 * - While at the more prompt or executing an external command, don't
	 *   redraw, but position the cursor.
	 * - While editing the command line, only redraw that.
	 * - in Ex mode, don't redraw anything.
	 * - Otherwise, redraw right now, and position the cursor.
	 * Always need to call update_screen() or screenalloc(), to make
	 * sure Rows/Columns and the size of NextScreen is correct!
	 */
	if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM)
	{
	    screenalloc(FALSE);
	    if (State == ASKMORE)
	    {
		msg_moremsg(FALSE);	/* display --more-- message again */
		msg_row = Rows - 1;
	    }
#ifdef CON_DIALOG
	    else if (State == CONFIRM)
	    {
		display_confirm_msg();	/* display ":confirm" message again */
		msg_row = Rows - 1;
	    }
#endif
	    else
		windgoto(msg_row, msg_col); /* put cursor back */
	}
	else if (State == CMDLINE)
	{
	    update_screen(NOT_VALID);
	    redrawcmdline();
	}
	else if (exmode_active)
	{
	    screenalloc(FALSE);
	}
	else
	{
	    update_topline();
	    update_screen(NOT_VALID);
	    if (redrawing())
		setcursor();
	}
	cursor_on();	    /* redrawing may have switched it off */
    }
    out_flush();
    --busy;
}

/*
 * Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
 * commands and Ex mode).
 */
    void
settmode(tmode)
    int	 tmode;
{
    static int	oldtmode = TMODE_COOK;

#ifdef USE_GUI
    /* don't set the term where gvim was started to any mode */
    if (gui.in_use)
	return;
#endif

    if (full_screen)
    {
	/* In Ex mode, never set to RAW */
	if (exmode_active)
	    tmode = TMODE_COOK;

	/*
	 * When returning after calling a shell we want to really set the
	 * terminal to raw mode, even though we think it already is, because
	 * the shell program may have reset the terminal mode.
	 * When we think the terminal is normal, don't try to set it to
	 * normal again, because that causes problems (logout!) on some
	 * machines.
	 */
	if (tmode != TMODE_COOK || oldtmode != TMODE_COOK)
	{
	    out_flush();
	    mch_settmode(tmode);    /* machine specific function */
#ifdef USE_MOUSE
	    if (tmode != TMODE_RAW)
		mch_setmouse(FALSE);		/* switch mouse off */
	    else
		setmouse();			/* may switch mouse on */
#endif
	    out_flush();
	    oldtmode = tmode;
	}
    }
}

    void
starttermcap()
{
    screen_stop_highlight();
    if (full_screen && !termcap_active)
    {
	out_str(T_TI);			/* 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -