📄 term.c
字号:
{K_S_DOWN, "[S-KD]"},
{K_S_LEFT, "[S-KL]"},
{K_S_RIGHT, "[S-KR]"},
{K_F1, "[F1]"},
{K_F2, "[F2]"},
{K_F3, "[F3]"},
{K_F4, "[F4]"},
{K_F5, "[F5]"},
{K_F6, "[F6]"},
{K_F7, "[F7]"},
{K_F8, "[F8]"},
{K_F9, "[F9]"},
{K_F10, "[F10]"},
{K_F11, "[F11]"},
{K_F12, "[F12]"},
{K_S_F1, "[S-F1]"},
{K_S_F2, "[S-F2]"},
{K_S_F3, "[S-F3]"},
{K_S_F4, "[S-F4]"},
{K_S_F5, "[S-F5]"},
{K_S_F6, "[S-F6]"},
{K_S_F7, "[S-F7]"},
{K_S_F8, "[S-F8]"},
{K_S_F9, "[S-F9]"},
{K_S_F10, "[S-F10]"},
{K_S_F11, "[S-F11]"},
{K_S_F12, "[S-F12]"},
{K_HELP, "[HELP]"},
{K_UNDO, "[UNDO]"},
{K_BS, "[BS]"},
{K_INS, "[INS]"},
{K_DEL, "[DEL]"},
{K_HOME, "[HOME]"},
{K_END, "[END]"},
{K_PAGEUP, "[PAGEUP]"},
{K_PAGEDOWN, "[PAGEDOWN]"},
{K_KHOME, "[KHOME]"},
{K_KEND, "[KEND]"},
{K_KPAGEUP, "[KPAGEUP]"},
{K_KPAGEDOWN, "[KPAGEDOWN]"},
{K_MOUSE, "[MOUSE]"},
{K_KPLUS, "[KPLUS]"},
{K_KMINUS, "[KMINUS]"},
{K_KDIVIDE, "[KDIVIDE]"},
{K_KMULTIPLY, "[KMULTIPLY]"},
{K_KENTER, "[KENTER]"},
# endif
#endif /* NO_BUILTIN_TCAPS */
/*
* The most minimal terminal: only clear screen and cursor positioning
* Always included.
*/
{(int)KS_NAME, "dumb"},
{(int)KS_CL, "\014"},
#ifdef TERMINFO
{(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
#else
{(int)KS_CM, "\033[%i%d;%dH"},
#endif
/*
* end marker
*/
{(int)KS_NAME, NULL}
}; /* end of builtin_termcaps */
/*
* DEFAULT_TERM is used, when no terminal is specified with -T option or $TERM.
*/
#ifdef RISCOS
# define DEFAULT_TERM (char_u *)"riscos"
#endif
#ifdef AMIGA
# define DEFAULT_TERM (char_u *)"amiga"
#endif
#ifdef WIN32
# define DEFAULT_TERM (char_u *)"win32"
#endif
#ifdef MSDOS
# define DEFAULT_TERM (char_u *)"pcterm"
#endif
#if defined(UNIX) && !defined(__MINT__)
# define DEFAULT_TERM (char_u *)"ansi"
#endif
#ifdef __MINT__
# define DEFAULT_TERM (char_u *)"vt52"
#endif
#ifdef __EMX__
# define DEFAULT_TERM (char_u *)"os2ansi"
#endif
#ifdef VMS
# define DEFAULT_TERM (char_u *)"ansi"
#endif
#ifdef __BEOS__
# undef DEFAULT_TERM
# define DEFAULT_TERM (char_u *)"beos-ansi"
#endif
#ifdef macintosh
# define DEFAULT_TERM (char_u *)"mac-ansi"
#endif
/*
* Term_strings contains currently used terminal output strings.
* It is initialized with the default values by parse_builtin_tcap().
* The values can be changed by setting the option with the same name.
*/
char_u *(term_strings[(int)KS_LAST + 1]);
static int need_gather = FALSE; /* need to fill termleader[] */
static char_u termleader[256 + 1]; /* for check_termcode() */
static struct builtin_term *
find_builtin_term(term)
char_u *term;
{
struct builtin_term *p;
p = builtin_termcaps;
while (p->bt_string != NULL)
{
if (p->bt_entry == (int)KS_NAME)
{
#ifdef UNIX
if (STRCMP(p->bt_string, "iris-ansi") == 0 && vim_is_iris(term))
return p;
else if (STRCMP(p->bt_string, "xterm") == 0 && vim_is_xterm(term))
return p;
else
#endif
if (STRCMP(term, p->bt_string) == 0)
return p;
}
++p;
}
return p;
}
/*
* Parsing of the builtin termcap entries.
* Caller should check if 'name' is a valid builtin term.
* The terminal's name is not set, as this is already done in termcapinit().
*/
static void
parse_builtin_tcap(term)
char_u *term;
{
struct builtin_term *p;
char_u name[2];
p = find_builtin_term(term);
for (++p; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p)
{
if ((int)p->bt_entry < 0x100) /* KS_xx entry */
{
if (term_strings[p->bt_entry] == NULL ||
term_strings[p->bt_entry] == empty_option)
term_strings[p->bt_entry] = (char_u *)p->bt_string;
}
else
{
name[0] = KEY2TERMCAP0((int)p->bt_entry);
name[1] = KEY2TERMCAP1((int)p->bt_entry);
if (find_termcode(name) == NULL)
add_termcode(name, (char_u *)p->bt_string);
}
}
}
/*
* Set terminal options for terminal "term".
* Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
*
* While doing this, until ttest(), some options may be NULL, be careful.
*/
int
set_termname(term)
char_u *term;
{
struct builtin_term *termp;
#ifdef HAVE_TGETENT
int builtin_first = p_tbi;
int try;
int termcap_cleared = FALSE;
static char nr_colors[15]; /* string for number of colors */
#endif
int width = 0, height = 0;
char_u *error_msg = NULL;
char_u *bs_p, *del_p;
if (term_is_builtin(term))
{
term += 8;
#ifdef HAVE_TGETENT
builtin_first = 1;
#endif
}
/*
* If HAVE_TGETENT is not defined, only the builtin termcap is used, otherwise:
* If builtin_first is TRUE:
* 0. try builtin termcap
* 1. try external termcap
* 2. if both fail default to a builtin terminal
* If builtin_first is FALSE:
* 1. try external termcap
* 2. try builtin termcap, if both fail default to a builtin terminal
*/
#ifdef HAVE_TGETENT
for (try = builtin_first ? 0 : 1; try < 3; ++try)
{
/*
* Use external termcap
*/
if (try == 1)
{
char_u *p;
static char_u tstrbuf[TBUFSZ];
int i;
char_u tbuf[TBUFSZ];
char_u *tp;
static char *(key_names[]) =
{
"ku", "kd", "kr", /* "kl" is a special case */
# ifdef ARCHIE
"su", "sd", /* Termcap code made up! */
# endif
"#4", "%i",
"k1", "k2", "k3", "k4", "k5", "k6",
"k7", "k8", "k9", "k;", "F1", "F2",
"%1", "&8", "kb", "kI", "kD", "kh",
"@7", "kP", "kN", "K1", "K3", "K4", "K5",
NULL
};
static struct {
enum SpecialKey dest; /* index in term_strings[] */
char *name; /* termcap name for string */
} string_names[] =
{ {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
{KS_CL, "cl"}, {KS_CD, "cd"},
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
{KS_VS, "vs"}, {KS_ME, "me"}, {KS_MR, "mr"},
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
{KS_US, "us"}, {KS_CM, "cm"}, {KS_SR, "sr"},
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
{KS_ND, "nd"}, {KS_OP, "op"},
{(enum SpecialKey)0, NULL}
};
/*
* If the external termcap does not have a matching entry, try the
* builtin ones.
*/
if ((error_msg = tgetent_error(tbuf, term)) == NULL)
{
tp = tstrbuf;
if (!termcap_cleared)
{
clear_termoptions(); /* clear old options */
termcap_cleared = TRUE;
}
/* get output strings */
for (i = 0; string_names[i].name != NULL; ++i)
{
if (term_str(string_names[i].dest) == NULL
|| term_str(string_names[i].dest) == empty_option)
term_str(string_names[i].dest) =
TGETSTR(string_names[i].name, &tp);
}
if ((T_MS == NULL || T_MS == empty_option) && tgetflag("ms"))
T_MS = (char_u *)"y";
if ((T_XS == NULL || T_XS == empty_option) && tgetflag("xs"))
T_XS = (char_u *)"y";
if ((T_DB == NULL || T_DB == empty_option) && tgetflag("db"))
T_DB = (char_u *)"y";
if ((T_DA == NULL || T_DA == empty_option) && tgetflag("da"))
T_DA = (char_u *)"y";
/* get key codes */
for (i = 0; key_names[i] != NULL; ++i)
{
if (find_termcode((char_u *)key_names[i]) == NULL)
add_termcode((char_u *)key_names[i],
TGETSTR(key_names[i], &tp));
}
/* if cursor-left == backspace, ignore it (televideo 925) */
if (find_termcode((char_u *)"kl") == NULL)
{
p = TGETSTR("kl", &tp);
if (p != NULL && *p != Ctrl('H'))
add_termcode((char_u *)"kl", p);
}
if (height == 0)
height = tgetnum("li");
if (width == 0)
width = tgetnum("co");
/*
* Get number of colors. If non-zero, store as string in
* nr_colors[].
*/
i = tgetnum("Co");
if (i > 0)
{
sprintf(nr_colors, "%d", i);
T_CCO = (char_u *)nr_colors;
}
# ifndef hpux
BC = (char *)TGETSTR("bc", &tp);
UP = (char *)TGETSTR("up", &tp);
p = TGETSTR("pc", &tp);
if (p)
PC = *p;
# endif /* hpux */
}
}
else /* try == 0 || try == 2 */
#endif /* HAVE_TGETENT */
/*
* Use builtin termcap
*/
{
#ifdef HAVE_TGETENT
/*
* If builtin termcap was already used, there is no need to search
* for the builtin termcap again, quit now.
*/
if (try == 2 && builtin_first && termcap_cleared)
break;
#endif
/*
* search for 'term' in builtin_termcaps[]
*/
termp = find_builtin_term(term);
if (termp->bt_string == NULL) /* did not find it */
{
#ifdef HAVE_TGETENT
/*
* If try == 0, first try the external termcap. If that is not
* found we'll get back here with try == 2.
* If termcap_cleared is set we used the external termcap,
* don't complain about not finding the term in the builtin
* termcap.
*/
if (try == 0) /* try external one */
continue;
if (termcap_cleared) /* found in external termcap */
break;
#endif
mch_errmsg("\r\n");
if (error_msg != NULL)
{
mch_errmsg((char *)error_msg);
mch_errmsg("\r\n");
}
mch_errmsg("'");
mch_errmsg((char *)term);
mch_errmsg("' not known. Available builtin terminals are:\r\n");
for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL;
++termp)
{
if (termp->bt_entry == (int)KS_NAME)
{
#ifdef HAVE_TGETENT
mch_errmsg(" builtin_");
#else
mch_errmsg(" ");
#endif
mch_errmsg(termp->bt_string);
mch_errmsg("\r\n");
}
}
if (!starting) /* when user typed :set term=xxx, quit here */
{
screen_start(); /* don't know where cursor is now */
wait_return(TRUE);
return FAIL;
}
term = DEFAULT_TERM;
mch_errmsg("defaulting to '");
mch_errmsg((char *)term);
mch_errmsg("'\r\n");
screen_start(); /* don't know where cursor is now */
ui_delay(2000L, TRUE);
set_string_option_direct((char_u *)"term", -1, term, TRUE);
mch_display_error();
}
out_flush();
#ifdef HAVE_TGETENT
if (!termcap_cleared)
{
#endif
clear_termoptions(); /* clear old options */
#ifdef HAVE_TGETENT
termcap_cleared = TRUE;
}
#endif
parse_builtin_tcap(term);
#ifdef USE_GUI
if (term_is_gui(term))
{
out_flush();
gui_init();
#ifdef HAVE_TGETENT
break; /* don't try using external termcap */
#endif
}
#endif /* USE_GUI */
}
#ifdef HAVE_TGETENT
}
#endif
/*
* special: There is no info in the termcap about whether the cursor
* positioning is relative to the start of the screen or to the start of the
* scrolling region. We just guess here. Only msdos pcterm is known to do it
* relative.
*/
if (STRCMP(term, "pcterm") == 0)
T_CCS = (char_u *)"yes";
else
T_CCS = empty_option;
#ifdef UNIX
/*
* Any "stty" settings override the default for t_kb from the termcap.
* This is in os_unix.c, because it depends a lot on the version of unix that
* is being used.
* Don't do this when the GUI is active, it uses "t_kb" and "t_kD" directly.
*/
#ifdef USE_GUI
if (!gui.in_use)
#endif
get_stty();
#endif
/*
* If the termcap has no entry for 'bs' and/or 'del' and the ioctl() also
* didn't work, use the default CTRL-H
* The default for t_kD is DEL, unless t_kb is DEL.
* The vim_strsave'd strings are probably lost forever, well it's only two
* bytes. Don't do this when the GUI is active, it uses "t_kb" and "t_kD"
* directly.
*/
#ifdef USE_GUI
if (!gui.in_use)
#endif
{
bs_p = find_termcode((char_u *)"kb");
del_p = find_termcode((char_u *)"kD");
if (bs_p == NULL || *bs_p == NUL)
add_termcode((char_u *)"kb", (bs_p = (char_u *)"\010"));
if ((del_p == NULL || *del_p == NUL) &&
(bs_p == NULL || *bs_p != '\177'))
add_termcode((char_u *)"kD", (char_u *)"\177");
}
#ifdef USE_MOUSE
# ifdef UNIX
/* for Unix, set the 'ttymouse' option to the type of mouse to be used.
* The termcode for the mouse is added as a side effect in option.c */
{
char_u *p;
p = (char_u *)"";
# ifdef NETTERM_MOUSE
p = (char_u *)"netterm";
# endif
# ifdef DEC_MOUSE
p = (char_u *)"dec";
# endif
# ifdef XTERM_MOUSE
if (vim_is_xterm(term))
p = (char_u *)"xterm";
# endif
set_option_value((char_u *)"ttym", 0L, p);
}
# else
set_mouse_termcode(KS_MOUSE, (char_u *)"\233M");
# endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -