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

📄 term.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif	/* USE_MOUSE */

#ifdef USE_SNIFF
    {
	char_u	name[2];

	name[0] = (int)KS_EXTRA;
	name[1] = (int)KE_SNIFF;
	add_termcode(name, (char_u *)"\233sniff");
    }
#endif

#if defined(AMIGA) || defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(__BEOS__) || defined(RISCOS)
	/* DEFAULT_TERM indicates that it is the machine console. */
    if (STRCMP(term, DEFAULT_TERM))
	term_console = FALSE;
    else
    {
	term_console = TRUE;
# ifdef AMIGA
	win_resize_on();	/* enable window resizing reports */
# endif
    }
#endif

#ifdef UNIX
/*
 * 'ttyfast' is default on for xterm, iris-ansi and a few others.
 */
    if (vim_is_fastterm(term))
	p_tf = TRUE;
#endif
#if defined(AMIGA) || defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(__BEOS__) || defined(RISCOS)
/*
 * 'ttyfast' is default on Amiga, MSDOS, Win32, BeBox, RISCOS and OS/2 consoles
 */
    if (term_console)
	p_tf = TRUE;
#endif

    ttest(TRUE);	/* make sure we have a valid set of terminal codes */

    full_screen = TRUE;	    /* we can use termcap codes from now on */
    set_term_defaults();    /* use current values as defaults */

    /*
     * Initialize the terminal with the appropriate termcap codes.
     * Set the mouse and window title if possible.
     * Don't do this when starting, need to parse the .vimrc first, because it
     * may redefine t_TI etc.
     */
    if (!starting)
    {
	starttermcap();		/* may change terminal mode */
#ifdef USE_MOUSE
	setmouse();		/* may start using the mouse */
#endif
	maketitle();		/* may display window title */
    }

	/* display initial screen after ttest() checking. jw. */
    if (width <= 0 || height <= 0)
    {
	/* termcap failed to report size */
	/* set defaults, in case ui_get_winsize also fails */
	width = 80;
#if defined MSDOS  ||  defined WIN32
	height = 25;	    /* console is often 25 lines */
#else
	height = 24;	    /* most terminals are 24 lines */
#endif
    }
    set_winsize(width, height, FALSE);	/* may change Rows */
    if (!starting)
    {
	if (scroll_region)
	    scroll_region_reset();	    /* In case Rows changed */
	check_map_keycodes();	/* check mappings for terminal codes used */

#ifdef AUTOCMD
	{
	    BUF		*old_curbuf;

	    /*
	     * Execute the TermChanged autocommands for each buffer that is
	     * loaded.
	     */
	    old_curbuf = curbuf;
	    for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
	    {
		if (curbuf->b_ml.ml_mfp != NULL)
		    apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
								      curbuf);
	    }
	    if (buf_valid(old_curbuf))
		curbuf = old_curbuf;
	}
#endif
    }

    return OK;
}

#ifdef USE_MOUSE
    void
set_mouse_termcode(n, s)
    int		n;	/* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
    char_u	*s;
{
    char_u	name[2];

    name[0] = n;
    name[1] = K_FILLER;
    add_termcode(name, s);
}

# ifdef UNIX
    void
del_mouse_termcode(n)
    int		n;	/* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
{
    char_u	name[2];

    name[0] = n;
    name[1] = K_FILLER;
    del_termcode(name);
}
# endif
#endif /* USE_MOUSE */

#ifdef HAVE_TGETENT
/*
 * Call tgetent()
 * Return error message if it fails, NULL if it's OK.
 */
    static char_u *
tgetent_error(tbuf, term)
    char_u  *tbuf;
    char_u  *term;
{
    int	    i;

    i = TGETENT(tbuf, term);
    if (i == -1)
	return (char_u *)"Cannot open termcap file";
    if (i == 0)
#ifdef TERMINFO
	return (char_u *)"Terminal entry not found in terminfo";
#else
	return (char_u *)"Terminal entry not found in termcap";
#endif
    return NULL;
}
#endif /* HAVE_TGETENT */

#if defined(HAVE_TGETENT) && (defined(UNIX) || defined(__EMX__))
/*
 * Get Columns and Rows from the termcap. Used after a window signal if the
 * ioctl() fails. It doesn't make sense to call tgetent each time if the "co"
 * and "li" entries never change. But on some systems this works.
 * Errors while getting the entries are ignored.
 */
    void
getlinecol()
{
    char_u	    tbuf[TBUFSZ];

    if (T_NAME != NULL && *T_NAME != NUL && TGETENT(tbuf, T_NAME) > 0)
    {
	if (Columns == 0)
	    Columns = tgetnum("co");
	if (Rows == 0)
	    Rows = tgetnum("li");
    }
}
#endif /* defined(HAVE_TGETENT) && defined(UNIX) */

/*
 * Get a string entry from the termcap and add it to the list of termcodes.
 * Used for <t_xx> special keys.
 * Give an error message for failure when not sourcing.
 * If force given, replace an existing entry.
 * Return FAIL if the entry was not found, OK if the entry was added.
 */
    int
add_termcap_entry(name, force)
    char_u  *name;
    int	    force;
{
    char_u  *term;
    int	    key;
    struct builtin_term *termp;
#ifdef HAVE_TGETENT
    char_u  *string;
    int	    i;
    int	    builtin_first;
    char_u  tbuf[TBUFSZ];
    char_u  tstrbuf[TBUFSZ];
    char_u  *tp = tstrbuf;
    char_u  *error_msg = NULL;
#endif

/*
 * If the GUI is running or will start in a moment, we only support the keys
 * that the GUI can produce.
 */
#ifdef USE_GUI
    if (gui.in_use || gui.starting)
	return gui_mch_haskey(name);
#endif

    if (!force && find_termcode(name) != NULL)	    /* it's already there */
	return OK;

    term = T_NAME;
    if (term == NULL || *term == NUL)	    /* 'term' not defined yet */
	return FAIL;

    if (term_is_builtin(term))		    /* name starts with "builtin_" */
    {
	term += 8;
#ifdef HAVE_TGETENT
	builtin_first = TRUE;
#endif
    }
#ifdef HAVE_TGETENT
    else
	builtin_first = p_tbi;
#endif

#ifdef HAVE_TGETENT
/*
 * We can get the entry from the builtin termcap and from the external one.
 * If 'ttybuiltin' is on or the terminal name starts with "builtin_", try
 * builtin termcap first.
 * If 'ttybuiltin' is off, try external termcap first.
 */
    for (i = 0; i < 2; ++i)
    {
	if (!builtin_first == i)
#endif
	/*
	 * Search in builtin termcap
	 */
	{
	    termp = find_builtin_term(term);
	    if (termp->bt_string != NULL)	/* found it */
	    {
		key = TERMCAP2KEY(name[0], name[1]);
		while (termp->bt_entry != (int)KS_NAME)
		{
		    if ((int)termp->bt_entry == key)
		    {
			add_termcode(name, (char_u *)termp->bt_string);
			return OK;
		    }
		    ++termp;
		}
	    }
	}
#ifdef HAVE_TGETENT
	else
	/*
	 * Search in external termcap
	 */
	{
	    error_msg = tgetent_error(tbuf, term);
	    if (error_msg == NULL)
	    {
		string = TGETSTR((char *)name, &tp);
		if (string != NULL && *string != NUL)
		{
		    add_termcode(name, string);
		    return OK;
		}
	    }
	}
    }
#endif

    if (sourcing_name == NULL)
    {
#ifdef HAVE_TGETENT
	if (error_msg != NULL)
	    EMSG(error_msg);
	else
#endif
	    EMSG2("No \"%s\" entry in termcap", name);
    }
    return FAIL;
}

    static int
term_is_builtin(name)
    char_u  *name;
{
    return (STRNCMP(name, "builtin_", (size_t)8) == 0);
}

#ifdef USE_GUI
    int
term_is_gui(name)
    char_u  *name;
{
    return (STRCMP(name, "builtin_gui") == 0 || STRCMP(name, "gui") == 0);
}
#endif

#if !defined(HAVE_TGETENT) || defined(AMIGA) || defined(PROTO)

    char_u *
tltoa(i)
    unsigned long i;
{
    static char_u buf[16];
    char_u	*p;

    p = buf + 15;
    *p = '\0';
    do
    {
	--p;
	*p = (char_u) (i % 10 + '0');
	i /= 10;
    }
    while (i > 0 && p > buf);
    return p;
}
#endif

#ifndef HAVE_TGETENT

/*
 * minimal tgoto() implementation.
 * no padding and we only parse for %i %d and %+char
 */
char *tgoto __ARGS((char *, int, int));

    char *
tgoto(cm, x, y)
    char *cm;
    int x, y;
{
    static char buf[30];
    char *p, *s, *e;

    if (!cm)
	return "OOPS";
    e = buf + 29;
    for (s = buf; s < e && *cm; cm++)
    {
	if (*cm != '%')
	{
	    *s++ = *cm;
	    continue;
	}
	switch (*++cm)
	{
	case 'd':
	    p = (char *)tltoa((unsigned long)y);
	    y = x;
	    while (*p)
		*s++ = *p++;
	    break;
	case 'i':
	    x++;
	    y++;
	    break;
	case '+':
	    *s++ = (char)(*++cm + y);
	    y = x;
	    break;
	case '%':
	    *s++ = *cm;
	    break;
	default:
	    return "OOPS";
	}
    }
    *s = '\0';
    return buf;
}

#endif /* HAVE_TGETENT */

/*
 * Set the terminal name and initialize the terminal options.
 * If "name" is NULL or empty, get the terminal name from the environment.
 * If that fails, use the default terminal name.
 */
    void
termcapinit(name)
    char_u *name;
{
    char_u	*term;

    if (name != NULL && *name == NUL)
	name = NULL;	    /* empty name is equal to no name */
    term = name;

#ifdef __BEOS__
    /*
     * TERM environment variable is normally set to 'ansi' on the Bebox;
     * Since the BeBox doesn't quite support full ANSI yet, we use our
     * own custom 'ansi-beos' termcap instead, unless the -T option has
     * been given on the command line.
     */
    if (term == NULL
		 && strcmp((char *)mch_getenv((char_u *)"TERM"), "ansi") == 0)
	term = DEFAULT_TERM;
#endif
#ifndef WIN32
    if (term == NULL)
	term = mch_getenv((char_u *)"TERM");
#endif
    if (term == NULL || *term == NUL)
	term = DEFAULT_TERM;
    set_string_option_direct((char_u *)"term", -1, term, TRUE);

    /* Set the default terminal name. */
    set_string_default("term", term);
    set_string_default("ttytype", term);

    /*
     * Avoid using "term" here, because the next mch_getenv() may overwrite it.
     */
    set_termname(T_NAME != NULL ? T_NAME : term);
}

/*
 * the number of calls to ui_write is reduced by using the buffer "out_buf"
 */
#ifdef DOS16
# define OUT_SIZE	255		/* only have 640K total... */
#else
# define OUT_SIZE	2047
#endif
	    /* Add one to allow mch_write() in os_win32.c to append a NUL */
static char_u		out_buf[OUT_SIZE + 1];
static int		out_pos = 0;	/* number of chars in out_buf */

/*
 * out_flush(): flush the output buffer
 */
    void
out_flush()
{
    int	    len;

    if (out_pos != 0)
    {
	/* set out_pos to 0 before ui_write, to avoid recursiveness */
	len = out_pos;
	out_pos = 0;
	ui_write(out_buf, len);
    }
}

#ifdef USE_GUI
/*
 * out_trash(): Throw away the contents of the output buffer
 */
    void
out_trash()
{
    out_pos = 0;
}
#endif

/*
 * out_char(c): put a character into the output buffer.
 *		Flush it if it becomes full.
 * This should not be used for outputting text on the screen (use functions
 * like msg_puts() and screen_putchar() for that).
 */
    void
out_char(c)
    unsigned	c;
{
#if defined(UNIX) || defined(VMS) || defined(AMIGA)
    if (c == '\n')	/* turn LF into CR-LF (CRMOD doesn't seem to do this) */
	out_char('\r');
#endif

    out_buf[out_pos++] = c;

    /* For testing we flush each time. */
    if (out_pos >= OUT_SIZE || p_wd)
	out_flush();
}

static void out_char_nf __ARGS((unsigned));

/*
 * out_char_nf(c): like out_char(), but don't flush when p_wd is set
 */
    static void
out_char_nf(c)
    unsigned	c;
{
#if defined(UNIX) || defined(VMS) || defined(AMIGA)
    if (c == '\n')	/* turn LF into CR-LF (CRMOD doesn't seem to do this) */
	out_char_nf('\r');
#endif

⌨️ 快捷键说明

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