📄 term.c
字号:
/* vi:set ts=8 sts=4 sw=4:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
*/
/*
*
* term.c: functions for controlling the terminal
*
* primitive termcap support for Amiga, MSDOS, and Win32 included
*
* NOTE: padding and variable substitution is not performed,
* when compiling without HAVE_TGETENT, we use tputs() and tgoto() dummies.
*/
/*
* Some systems have a prototype for tgetstr() with (char *) instead of
* (char **). This define removes that prototype. We include our own prototype
* below.
*/
#define tgetstr tgetstr_defined_wrong
#include "vim.h"
#ifdef HAVE_TGETENT
# ifdef HAVE_TERMIOS_H
# include <termios.h> /* seems to be required for some Linux */
# endif
# ifdef HAVE_TERMCAP_H
# include <termcap.h>
# endif
/*
* A few linux systems define outfuntype in termcap.h to be used as the third
* argument for tputs().
*/
# ifdef VMS
# define TPUTSFUNCAST
# else
# ifdef HAVE_OUTFUNTYPE
# define TPUTSFUNCAST (outfuntype)
# else
# define TPUTSFUNCAST (int (*)())
# endif
# endif
#endif
#undef tgetstr
/*
* Here are the builtin termcap entries. They are not stored as complete
* Tcarr structures, as such a structure is too big.
*
* The entries are compact, therefore they normally are included even when
* HAVE_TGETENT is defined. When HAVE_TGETENT is defined, the builtin entries
* can be accessed with "builtin_amiga", "builtin_ansi", "builtin_debug", etc.
*
* Each termcap is a list of builtin_term structures. It always starts with
* KS_NAME, which separates the entries. See parse_builtin_tcap() for all
* details.
* bt_entry is either a KS_xxx code (< 0x100), or a K_xxx code.
*/
struct builtin_term
{
int bt_entry;
char *bt_string;
};
/* start of keys that are not directly used by Vim but can be mapped */
#define BT_EXTRA_KEYS 0x101
static struct builtin_term *find_builtin_term __ARGS((char_u *name));
static void parse_builtin_tcap __ARGS((char_u *s));
static void term_color __ARGS((char_u *s, int n));
static void gather_termleader __ARGS((void));
static int get_bytes_from_buf __ARGS((char_u *, char_u *, int));
static int term_is_builtin __ARGS((char_u *));
#ifdef HAVE_TGETENT
static char_u *tgetent_error __ARGS((char_u *, char_u *));
/*
* Here is our own prototype for tgetstr(), any prototypes from the include
* files have been disabled by the define at the start of this file.
*/
char *tgetstr __ARGS((char *, char **));
/*
* Don't declare these variables if termcap.h contains them.
* Autoconf checks if these variables should be declared extern (not all
* systems have them).
* Some versions define ospeed to be speed_t, but that is incompatible with
* BSD, where ospeed is short and speed_t is long.
*/
# ifndef HAVE_OSPEED
# ifdef OSPEED_EXTERN
extern short ospeed;
# else
short ospeed;
# endif
# endif
# ifndef HAVE_UP_BC_PC
# ifdef UP_BC_PC_EXTERN
extern char *UP, *BC, PC;
# else
char *UP, *BC, PC;
# endif
# endif
# define TGETSTR(s, p) (char_u *)tgetstr((s), (char **)(p))
# define TGETENT(b, t) tgetent((char *)(b), (char *)(t))
#endif /* HAVE_TGETENT */
struct builtin_term builtin_termcaps[] =
{
#if defined(USE_GUI)
/*
* Motif/Athena pseudo term-cap.
*/
{(int)KS_NAME, "gui"},
{(int)KS_CE, "\033|$"},
{(int)KS_AL, "\033|i"},
# ifdef TERMINFO
{(int)KS_CAL, "\033|%p1%dI"},
# else
{(int)KS_CAL, "\033|%dI"},
# endif
{(int)KS_DL, "\033|d"},
# ifdef TERMINFO
{(int)KS_CDL, "\033|%p1%dD"},
{(int)KS_CS, "\033|%p1%d;%p2%dR"},
# else
{(int)KS_CDL, "\033|%dD"},
{(int)KS_CS, "\033|%d;%dR"},
# endif
{(int)KS_CL, "\033|C"},
{(int)KS_ME, "\033|31H"}, /* 31 = HL_ALL, H = off */
{(int)KS_MR, "\033|1h"}, /* 1 = HL_INVERSE, h = on */
{(int)KS_MD, "\033|2h"}, /* 2 = HL_BOLD, h = on */
{(int)KS_SE, "\033|16H"}, /* 16 = HL_STANDOUT, H = off */
{(int)KS_SO, "\033|16h"}, /* 16 = HL_STANDOUT, h = on */
{(int)KS_UE, "\033|8H"}, /* 8 = HL_UNDERLINE, H = off */
{(int)KS_US, "\033|8h"}, /* 8 = HL_UNDERLINE, h = on */
{(int)KS_CZR, "\033|4H"}, /* 4 = HL_ITALIC, H = off */
{(int)KS_CZH, "\033|4h"}, /* 4 = HL_ITALIC, h = on */
{(int)KS_VB, "\033|f"},
{(int)KS_MS, "y"},
{(int)KS_LE, "\010"}, /* cursur-left = BS */
{(int)KS_ND, "\014"}, /* cursor-right = CTRL-L */
# ifdef TERMINFO
{(int)KS_CM, "\033|%p1%d;%p2%dM"},
# else
{(int)KS_CM, "\033|%d;%dM"},
# endif
/* there are no key sequences here, the GUI sequences are recognized
* in check_termcodes() */
#endif
#ifndef NO_BUILTIN_TCAPS
# if defined(RISCOS) || defined(ALL_BUILTIN_TCAPS)
/*
* Default for the Acorn.
*/
{(int)KS_NAME, "riscos"},
{(int)KS_CL, "\014"}, /* Cls and Home Cursor */
{(int)KS_CM, "\001%d\001%d\002"}, /* Position cursor */
{(int)KS_CCO, "16"}, /* Allow 16 colors */
{(int)KS_CAF, "\001%d\021"}, /* Set foreground colour */
{(int)KS_CAB, "\001%d\022"}, /* Set background colour */
{(int)KS_ME, "\004"}, /* Normal mode */
{(int)KS_MR, "\005"}, /* Reverse */
{(int)KS_VI, "\016"}, /* Cursor invisible */
{(int)KS_VE, "\017"}, /* Cursor visible */
{(int)KS_VS, "\018"}, /* Cursor very visible */
{(int)KS_CS, "\001%d\001%d\003"}, /* Set scroll region */
{(int)KS_SR, "\023"}, /* Scroll text down */
{K_UP, "\217"},
{K_DOWN, "\216"},
{K_LEFT, "\214"},
{K_RIGHT, "\215"},
{K_S_UP, "\237"},
{K_S_DOWN, "\236"},
{K_S_LEFT, "\234"},
{K_S_RIGHT, "\235"},
{K_F1, "\201"},
{K_F2, "\202"},
{K_F3, "\203"},
{K_F4, "\204"},
{K_F5, "\205"},
{K_F6, "\206"},
{K_F7, "\207"},
{K_F8, "\208"},
{K_F9, "\209"},
{K_F10, "\312"},
{K_F11, "\313"},
{K_F12, "\314"},
{K_S_F1, "\221"},
{K_S_F2, "\222"},
{K_S_F3, "\223"},
{K_S_F4, "\224"},
{K_S_F5, "\225"},
{K_S_F6, "\226"},
{K_S_F7, "\227"},
{K_S_F8, "\228"},
{K_S_F9, "\229"},
{K_S_F10, "\332"},
{K_S_F11, "\333"},
{K_S_F12, "\334"},
{K_BS, "\010"},
{K_INS, "\315"},
{K_DEL, "\177"},
{K_HOME, "\036"},
{K_END, "\213"},
{K_PAGEUP, "\237"},
{K_PAGEDOWN, "\236"},
# endif /* Acorn terminal */
# if defined(AMIGA) || defined(ALL_BUILTIN_TCAPS)
/*
* Amiga console window, default for Amiga
*/
{(int)KS_NAME, "amiga"},
{(int)KS_CE, "\033[K"},
{(int)KS_CD, "\033[J"},
{(int)KS_AL, "\033[L"},
# ifdef TERMINFO
{(int)KS_CAL, "\033[%p1%dL"},
# else
{(int)KS_CAL, "\033[%dL"},
# endif
{(int)KS_DL, "\033[M"},
# ifdef TERMINFO
{(int)KS_CDL, "\033[%p1%dM"},
# else
{(int)KS_CDL, "\033[%dM"},
# endif
{(int)KS_CL, "\014"},
{(int)KS_VI, "\033[0 p"},
{(int)KS_VE, "\033[1 p"},
{(int)KS_ME, "\033[0m"},
{(int)KS_MR, "\033[7m"},
{(int)KS_MD, "\033[1m"},
{(int)KS_SE, "\033[0m"},
{(int)KS_SO, "\033[33m"},
{(int)KS_US, "\033[4m"},
{(int)KS_UE, "\033[0m"},
{(int)KS_CZH, "\033[3m"},
{(int)KS_CZR, "\033[0m"},
{(int)KS_MS, "y"},
{(int)KS_LE, "\010"},
# ifdef TERMINFO
{(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
# else
{(int)KS_CM, "\033[%i%d;%dH"},
# endif
# ifdef TERMINFO
{(int)KS_CRI, "\033[%p1%dC"},
# else
{(int)KS_CRI, "\033[%dC"},
# endif
{K_UP, "\233A"},
{K_DOWN, "\233B"},
{K_LEFT, "\233D"},
{K_RIGHT, "\233C"},
{K_S_UP, "\233T"},
{K_S_DOWN, "\233S"},
{K_S_LEFT, "\233 A"},
{K_S_RIGHT, "\233 @"},
{K_S_TAB, "\233Z"},
{K_F1, "\233\060~"},/* some compilers don't dig "\2330" */
{K_F2, "\233\061~"},
{K_F3, "\233\062~"},
{K_F4, "\233\063~"},
{K_F5, "\233\064~"},
{K_F6, "\233\065~"},
{K_F7, "\233\066~"},
{K_F8, "\233\067~"},
{K_F9, "\233\070~"},
{K_F10, "\233\071~"},
{K_S_F1, "\233\061\060~"},
{K_S_F2, "\233\061\061~"},
{K_S_F3, "\233\061\062~"},
{K_S_F4, "\233\061\063~"},
{K_S_F5, "\233\061\064~"},
{K_S_F6, "\233\061\065~"},
{K_S_F7, "\233\061\066~"},
{K_S_F8, "\233\061\067~"},
{K_S_F9, "\233\061\070~"},
{K_S_F10, "\233\061\071~"},
{K_HELP, "\233?~"},
{K_INS, "\233\064\060~"}, /* 101 key keyboard */
{K_PAGEUP, "\233\064\061~"}, /* 101 key keyboard */
{K_PAGEDOWN, "\233\064\062~"}, /* 101 key keyboard */
{K_HOME, "\233\064\064~"}, /* 101 key keyboard */
{K_END, "\233\064\065~"}, /* 101 key keyboard */
{BT_EXTRA_KEYS, ""},
{TERMCAP2KEY('#', '2'), "\233\065\064~"}, /* shifted home key */
{TERMCAP2KEY('#', '3'), "\233\065\060~"}, /* shifted insert key */
{TERMCAP2KEY('*', '7'), "\233\065\065~"}, /* shifted end key */
# endif
# if defined(__BEOS__) || defined(ALL_BUILTIN_TCAPS)
/*
* almost standard ANSI terminal, default for bebox
*/
{(int)KS_NAME, "beos-ansi"},
{(int)KS_CE, "\033[K"},
{(int)KS_CD, "\033[J"},
{(int)KS_AL, "\033[L"},
# ifdef TERMINFO
{(int)KS_CAL, "\033[%p1%dL"},
# else
{(int)KS_CAL, "\033[%dL"},
# endif
{(int)KS_DL, "\033[M"},
# ifdef TERMINFO
{(int)KS_CDL, "\033[%p1%dM"},
# else
{(int)KS_CDL, "\033[%dM"},
# endif
#ifdef BEOS_PR_OR_BETTER
# ifdef TERMINFO
{(int)KS_CS, "\033[%i%p1%d;%p2%dr"},
# else
{(int)KS_CS, "\033[%i%d;%dr"}, /* scroll region */
# endif
#endif
{(int)KS_CL, "\033[H\033[2J"},
#ifdef notyet
{(int)KS_VI, "[VI]"}, /* cursor invisible, VT320: CSI ? 25 l */
{(int)KS_VE, "[VE]"}, /* cursor visible, VT320: CSI ? 25 h */
#endif
{(int)KS_ME, "\033[m"}, /* normal mode */
{(int)KS_MR, "\033[7m"}, /* reverse */
{(int)KS_MD, "\033[1m"}, /* bold */
{(int)KS_SO, "\033[31m"}, /* standout mode: red */
{(int)KS_SE, "\033[m"}, /* standout end */
{(int)KS_CZH, "\033[35m"}, /* italic: purple */
{(int)KS_CZR, "\033[m"}, /* italic end */
{(int)KS_US, "\033[4m"}, /* underscore mode */
{(int)KS_UE, "\033[m"}, /* underscore end */
{(int)KS_CCO, "8"}, /* allow 8 colors */
# ifdef TERMINFO
{(int)KS_CAB, "\033[4%p1%dm"},/* set background color */
{(int)KS_CAF, "\033[3%p1%dm"},/* set foreground color */
# else
{(int)KS_CAB, "\033[4%dm"}, /* set background color */
{(int)KS_CAF, "\033[3%dm"}, /* set foreground color */
# endif
{(int)KS_OP, "\033[m"}, /* reset colors */
{(int)KS_MS, "y"}, /* safe to move cur in reverse mode */
{(int)KS_LE, "\010"},
# ifdef TERMINFO
{(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
# else
{(int)KS_CM, "\033[%i%d;%dH"},
# endif
{(int)KS_SR, "\033M"},
# ifdef TERMINFO
{(int)KS_CRI, "\033[%p1%dC"},
# else
{(int)KS_CRI, "\033[%dC"},
# endif
#if defined(BEOS_DR8)
{(int)KS_DB, ""}, /* hack! see screen.c */
#endif
{K_UP, "\033[A"},
{K_DOWN, "\033[B"},
{K_LEFT, "\033[D"},
{K_RIGHT, "\033[C"},
# endif
# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
/*
* standard ANSI terminal, default for unix
*/
{(int)KS_NAME, "ansi"},
{(int)KS_CE, "\033[K"},
{(int)KS_AL, "\033[L"},
# ifdef TERMINFO
{(int)KS_CAL, "\033[%p1%dL"},
# else
{(int)KS_CAL, "\033[%dL"},
# endif
{(int)KS_DL, "\033[M"},
# ifdef TERMINFO
{(int)KS_CDL, "\033[%p1%dM"},
# else
{(int)KS_CDL, "\033[%dM"},
# endif
{(int)KS_CL, "\033[H\033[2J"},
{(int)KS_ME, "\033[0m"},
{(int)KS_MR, "\033[7m"},
{(int)KS_MS, "y"},
{(int)KS_LE, "\010"},
# ifdef TERMINFO
{(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
# else
{(int)KS_CM, "\033[%i%d;%dH"},
# endif
# ifdef TERMINFO
{(int)KS_CRI, "\033[%p1%dC"},
# else
{(int)KS_CRI, "\033[%dC"},
# endif
# endif
# if defined(MSDOS) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
/*
* These codes are valid when nansi.sys or equivalent has been installed.
* Function keys on a PC are preceded with a NUL. These are converted into
* K_NUL '\316' in mch_inchar(), because we cannot handle NULs in key codes.
* CTRL-arrow is used instead of SHIFT-arrow.
*/
#ifdef __EMX__
{(int)KS_NAME, "os2ansi"},
#else
{(int)KS_NAME, "pcansi"},
{(int)KS_DL, "\033[M"},
{(int)KS_AL, "\033[L"},
#endif
{(int)KS_CE, "\033[K"},
{(int)KS_CL, "\033[2J"},
{(int)KS_ME, "\033[0m"},
{(int)KS_MR, "\033[5m"}, /* reverse: black on lightgrey */
{(int)KS_MD, "\033[1m"}, /* bold: white text */
{(int)KS_SE, "\033[0m"}, /* standout end */
{(int)KS_SO, "\033[31m"}, /* standout: white on blue */
{(int)KS_CZH, "\033[34;43m"}, /* italic mode: blue text on yellow */
{(int)KS_CZR, "\033[0m"}, /* italic mode end */
{(int)KS_US, "\033[36;41m"}, /* underscore mode: cyan text on red */
{(int)KS_UE, "\033[0m"}, /* underscore mode end */
{(int)KS_CCO, "8"}, /* allow 8 colors */
# ifdef TERMINFO
{(int)KS_CAB, "\033[4%p1%dm"},/* set background color */
{(int)KS_CAF, "\033[3%p1%dm"},/* set foreground color */
# else
{(int)KS_CAB, "\033[4%dm"}, /* set background color */
{(int)KS_CAF, "\033[3%dm"}, /* set foreground color */
# endif
{(int)KS_OP, "\033[0m"}, /* reset colors */
{(int)KS_MS, "y"},
{(int)KS_LE, "\010"},
# ifdef TERMINFO
{(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
# else
{(int)KS_CM, "\033[%i%d;%dH"},
# endif
# ifdef TERMINFO
{(int)KS_CRI, "\033[%p1%dC"},
# else
{(int)KS_CRI, "\033[%dC"},
# endif
{K_UP, "\316H"},
{K_DOWN, "\316P"},
{K_LEFT, "\316K"},
{K_RIGHT, "\316M"},
{K_S_LEFT, "\316s"},
{K_S_RIGHT, "\316t"},
{K_F1, "\316;"},
{K_F2, "\316<"},
{K_F3, "\316="},
{K_F4, "\316>"},
{K_F5, "\316?"},
{K_F6, "\316@"},
{K_F7, "\316A"},
{K_F8, "\316B"},
{K_F9, "\316C"},
{K_F10, "\316D"},
{K_F11, "\316\205"}, /* guessed */
{K_F12, "\316\206"}, /* guessed */
{K_S_F1, "\316T"},
{K_S_F2, "\316U"},
{K_S_F3, "\316V"},
{K_S_F4, "\316W"},
{K_S_F5, "\316X"},
{K_S_F6, "\316Y"},
{K_S_F7, "\316Z"},
{K_S_F8, "\316["},
{K_S_F9, "\316\\"},
{K_S_F10, "\316]"},
{K_S_F11, "\316\207"}, /* guessed */
{K_S_F12, "\316\210"}, /* guessed */
{K_INS, "\316R"},
{K_DEL, "\316S"},
{K_HOME, "\316G"},
{K_END, "\316O"},
{K_PAGEDOWN, "\316Q"},
{K_PAGEUP, "\316I"},
# endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -