aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt8
-rw-r--r--config/CMakeLists.txt4
-rw-r--r--config/config.h.in13
-rw-r--r--scripts/msgpack-gen.lua2
-rw-r--r--src/nvim/CMakeLists.txt24
-rw-r--r--src/nvim/charset.c19
-rw-r--r--src/nvim/eval.c28
-rw-r--r--src/nvim/ex_cmds.c5
-rw-r--r--src/nvim/ex_cmds.lua2
-rw-r--r--src/nvim/ex_cmds2.c4
-rw-r--r--src/nvim/ex_docmd.c37
-rw-r--r--src/nvim/ex_getln.c29
-rw-r--r--src/nvim/fileio.c7
-rw-r--r--src/nvim/garray.c20
-rw-r--r--src/nvim/getchar.c69
-rw-r--r--src/nvim/globals.h9
-rw-r--r--src/nvim/hardcopy.c5
-rw-r--r--src/nvim/keymap.c23
-rw-r--r--src/nvim/main.c139
-rw-r--r--src/nvim/map.c2
-rw-r--r--src/nvim/message.c68
-rw-r--r--src/nvim/misc1.c30
-rw-r--r--src/nvim/mouse.c6
-rw-r--r--src/nvim/msgpack_rpc/channel.c16
-rw-r--r--src/nvim/msgpack_rpc/helpers.c16
-rw-r--r--src/nvim/normal.c19
-rw-r--r--src/nvim/option.c62
-rw-r--r--src/nvim/os/event.c5
-rw-r--r--src/nvim/os/input.c168
-rw-r--r--src/nvim/os/rstream.c9
-rw-r--r--src/nvim/os/signal.c24
-rw-r--r--src/nvim/os_unix.c410
-rw-r--r--src/nvim/screen.c411
-rw-r--r--src/nvim/sha256.c37
-rw-r--r--src/nvim/strings.c11
-rw-r--r--src/nvim/syntax.c494
-rw-r--r--src/nvim/syntax.h1
-rw-r--r--src/nvim/syntax_defs.h20
-rw-r--r--src/nvim/term.c2771
-rw-r--r--src/nvim/tui/term_input.inl246
-rw-r--r--src/nvim/tui/tui.c752
-rw-r--r--src/nvim/tui/tui.h8
-rw-r--r--src/nvim/ui.c201
-rw-r--r--src/nvim/ui.h1
-rw-r--r--src/nvim/version.c28
-rw-r--r--src/nvim/vim.h3
-rw-r--r--test/functional/api/window_spec.lua2
-rw-r--r--test/functional/helpers.lua9
-rw-r--r--test/functional/legacy/051_highlight_spec.lua40
-rw-r--r--test/functional/shell/viml_system_spec.lua42
-rw-r--r--test/functional/ui/screen.lua6
51 files changed, 1496 insertions, 4869 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42eb50ac43..111e8b76d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -182,6 +182,14 @@ include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS})
find_package(LuaJit REQUIRED)
include_directories(SYSTEM ${LUAJIT_INCLUDE_DIRS})
+set(LIBUNIBILIUM_USE_STATIC ON)
+find_package(LibUnibilium REQUIRED)
+include_directories(SYSTEM ${LIBUNIBILIUM_INCLUDE_DIRS})
+
+set(LIBTERMKEY_USE_STATIC ON)
+find_package(LibTermkey REQUIRED)
+include_directories(SYSTEM ${LIBTERMEY_INCLUDE_DIRS})
+
find_package(LibIntl)
if(LibIntl_FOUND)
include_directories(SYSTEM ${LibIntl_INCLUDE_DIRS})
diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt
index c620c96e61..1ee5c78adf 100644
--- a/config/CMakeLists.txt
+++ b/config/CMakeLists.txt
@@ -23,7 +23,6 @@ check_include_files(locale.h HAVE_LOCALE_H)
check_include_files(pwd.h HAVE_PWD_H)
check_include_files(strings.h HAVE_STRINGS_H)
check_include_files(stropts.h HAVE_STROPTS_H)
-check_include_files(sys/ioctl.h HAVE_SYS_IOCTL_H)
check_include_files(sys/param.h HAVE_SYS_PARAM_H)
check_include_files(sys/time.h HAVE_SYS_TIME_H)
check_include_files(sys/wait.h HAVE_SYS_WAIT_H)
@@ -33,9 +32,6 @@ if(NOT HAVE_SYS_WAIT_H AND UNIX)
endif()
check_include_files(sys/utsname.h HAVE_SYS_UTSNAME_H)
check_include_files(utime.h HAVE_UTIME_H)
-check_include_files(termcap.h HAVE_TERMCAP_H)
-check_include_files(termios.h HAVE_TERMIOS_H)
-check_include_files(termio.h HAVE_TERMIO_H)
check_include_files(unistd.h HAVE_UNISTD_H)
check_include_files(utime.h HAVE_UTIME_H)
diff --git a/config/config.h.in b/config/config.h.in
index 0a2aa4786e..9e6f3d8e13 100644
--- a/config/config.h.in
+++ b/config/config.h.in
@@ -53,15 +53,10 @@
#cmakedefine HAVE_STRINGS_H
#cmakedefine HAVE_STRNCASECMP
#cmakedefine HAVE_STROPTS_H
-#cmakedefine HAVE_SYS_IOCTL_H
#cmakedefine HAVE_SYS_PARAM_H
#cmakedefine HAVE_SYS_TIME_H
#cmakedefine HAVE_SYS_UTSNAME_H
#cmakedefine HAVE_SYS_WAIT_H
-#cmakedefine HAVE_TERMCAP_H
-#cmakedefine HAVE_TERMIOS_H
-#cmakedefine HAVE_TERMIO_H
-#define HAVE_TGETENT 1
#cmakedefine HAVE_UNISTD_H
#define HAVE_UP_BC_PC 1
#cmakedefine HAVE_UTIME
@@ -70,8 +65,6 @@
#cmakedefine HAVE_WORKING_LIBINTL
#define RETSIGTYPE void
#define SIGRETURN return
-#define TERMINFO 1
-#define TGETENT_ZERO_ERR 0
#define TIME_WITH_SYS_TIME 1
#cmakedefine UNIX
#define USEMAN_S 1
@@ -79,9 +72,3 @@
#define FEAT_BROWSE
#define FEAT_CSCOPE
#define FEAT_MOUSE
-#define FEAT_MOUSE_NET
-#define FEAT_MOUSE_SGR
-#define FEAT_MOUSE_TTY
-#define FEAT_MOUSE_URXVT
-#define FEAT_MOUSE_XTERM
-#define FEAT_TERMRESPONSE
diff --git a/scripts/msgpack-gen.lua b/scripts/msgpack-gen.lua
index d31a062a68..9ff9b4cf6f 100644
--- a/scripts/msgpack-gen.lua
+++ b/scripts/msgpack-gen.lua
@@ -287,7 +287,7 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
{
String m = {
.data=(char *)name,
- .size=min(name_len, ]]..max_fname_len..[[)
+ .size=MIN(name_len, ]]..max_fname_len..[[)
};
MsgpackRpcRequestHandler rv =
map_get(String, MsgpackRpcRequestHandler)(methods, m);
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 6fc5022d48..922b8b85a1 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -26,13 +26,16 @@ file(MAKE_DIRECTORY ${GENERATED_DIR}/os)
file(MAKE_DIRECTORY ${GENERATED_DIR}/api)
file(MAKE_DIRECTORY ${GENERATED_DIR}/api/private)
file(MAKE_DIRECTORY ${GENERATED_DIR}/msgpack_rpc)
+file(MAKE_DIRECTORY ${GENERATED_DIR}/tui)
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR})
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/os)
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/api)
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/api/private)
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/msgpack_rpc)
+file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/tui)
-file(GLOB NEOVIM_SOURCES *.c os/*.c api/*.c api/private/*.c msgpack_rpc/*.c)
+file(GLOB NEOVIM_SOURCES *.c os/*.c api/*.c api/private/*.c msgpack_rpc/*.c
+ tui/*.c)
file(GLOB_RECURSE NEOVIM_HEADERS *.h)
foreach(sfile ${NEOVIM_SOURCES})
@@ -164,19 +167,6 @@ if (LibIntl_FOUND)
list(APPEND NVIM_LINK_LIBRARIES ${LibIntl_LIBRARY})
endif()
-check_library_exists(curses tgetent "" HAVE_LIBCURSES)
-if (HAVE_LIBCURSES)
- list(APPEND NVIM_LINK_LIBRARIES curses)
-else()
- check_library_exists(tinfo tgetent "" HAVE_LIBTINFO)
- if (HAVE_LIBTINFO)
- list(APPEND NVIM_LINK_LIBRARIES tinfo)
- else()
- find_package(Curses REQUIRED)
- list(APPEND NVIM_LINK_LIBRARIES ${CURSES_LIBRARY})
- endif()
-endif()
-
if(Iconv_LIBRARIES)
list(APPEND NVIM_LINK_LIBRARIES ${Iconv_LIBRARIES})
endif()
@@ -186,8 +176,12 @@ list(APPEND NVIM_LINK_LIBRARIES
${LIBUV_LIBRARIES}
${MSGPACK_LIBRARIES}
${LUAJIT_LIBRARIES}
+ ${LIBTICKIT_LIBRARIES}
+ ${LIBTERMKEY_LIBRARIES}
+ ${LIBUNIBILIUM_LIBRARIES}
m
- ${CMAKE_THREAD_LIBS_INIT})
+ ${CMAKE_THREAD_LIBS_INIT}
+ )
add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES}
${NEOVIM_HEADERS})
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 6fb5ebf3e4..b8fcd2de09 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1849,25 +1849,6 @@ int hex2nr(int c)
return c - '0';
}
-#if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK)
-
-/// Convert two hex characters to a byte.
-/// Return -1 if one of the characters is not hex.
-///
-/// @param p
-///
-/// @return The two hex characters converted to a byte or -1 if one of the
-/// character is not hex.
-int hexhex2nr(char_u *p)
-{
- if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1])) {
- return -1;
- }
- return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
-}
-
-#endif // if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK)
-
/// Return true if "str" starts with a backslash that should be removed.
/// For WIN32 this is only done when the character after the
/// backslash is not a normal file name character.
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index a4bd4d89ef..97993eb651 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -9955,14 +9955,8 @@ static void f_has(typval_T *argvars, typval_T *rettv)
#endif
"tag_binary",
"tag_old_static",
-#ifdef TERMINFO
- "terminfo",
-#endif
"termresponse",
"textobjects",
-#ifdef HAVE_TGETENT
- "tgetent",
-#endif
"title",
"user-commands", /* was accidentally included in 5.4 */
"user_commands",
@@ -14424,13 +14418,10 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv)
if (argvars[2].v_type != VAR_UNKNOWN) {
mode = get_tv_string_buf(&argvars[2], modebuf);
modec = TOLOWER_ASC(mode[0]);
- if (modec != 't' && modec != 'c' && modec != 'g')
+ if (modec != 'c' && modec != 'g')
modec = 0; /* replace invalid with current */
} else {
- if (abstract_ui || t_colors > 1)
- modec = 'c';
- else
- modec = 't';
+ modec = 'c';
}
@@ -18080,21 +18071,6 @@ static int function_exists(char_u *name)
return n;
}
-char_u *get_expanded_name(char_u *name, int check)
-{
- char_u *nm = name;
- char_u *p;
-
- p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
-
- if (p != NULL && *nm == NUL)
- if (!check || translated_function_exists(p))
- return p;
-
- free(p);
- return NULL;
-}
-
/// Return TRUE if "name" looks like a builtin function name: starts with a
/// lower case letter and doesn't contain AUTOLOAD_CHAR.
/// "len" is the length of "name", or -1 for NUL terminated.
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index b03c25a098..49f33c5017 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1232,9 +1232,6 @@ do_shell (
* avoid having to type return below.
*/
msg_putchar('\r'); /* put cursor at start of line */
- if (!autocmd_busy) {
- stoptermcap();
- }
msg_putchar('\n'); /* may shift screen one line up */
/* warning message before calling the shell */
@@ -1292,8 +1289,6 @@ do_shell (
wait_return(msg_silent == 0);
no_wait_return = save_nwr;
}
-
- starttermcap(); /* start termcap if not done by wait_return() */
}
/* display any error messages now */
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index aade4d736d..98a2b2814d 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -2483,7 +2483,7 @@ return {
{
command='winpos',
flags=bit.bor(EXTRA, TRLBAR, CMDWIN),
- func='ex_winpos',
+ func='ex_ni',
},
{
command='wnext',
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 7de47cb296..9bcbfa2f26 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -155,10 +155,6 @@ void do_debug(char_u *cmd)
#define CMD_INTERRUPT 6
- /* Make sure we are in raw mode and start termcap mode. Might have side
- * effects... */
- starttermcap();
-
++RedrawingDisabled; /* don't redisplay the window */
++no_wait_return; /* don't wait for return */
did_emsg = FALSE; /* don't use error from debugged stuff */
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 9b48398d96..7ff69a3d41 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -146,10 +146,6 @@ struct dbg_stuff {
# define gui_mch_find_dialog ex_ni
# define gui_mch_replace_dialog ex_ni
# define ex_helpfind ex_ni
-#if defined(FEAT_GUI) || defined(UNIX) || defined(MSWIN)
-#else
-# define ex_winpos ex_ni
-#endif
static int did_lcd; /* whether ":lcd" was produced for a session */
#ifndef HAVE_WORKING_LIBINTL
# define ex_language ex_ni
@@ -5397,13 +5393,11 @@ static void ex_stop(exarg_T *eap)
windgoto((int)Rows - 1, 0);
out_char('\n');
out_flush();
- stoptermcap();
out_flush(); /* needed for SUN to restore xterm buffer */
mch_restore_title(3); /* restore window titles */
ui_suspend(); /* call machine specific function */
maketitle();
resettitle(); /* force updating the title */
- starttermcap();
scroll_start(); /* scroll screen before redrawing */
redraw_later_clear();
shell_resized(); /* may have resized window */
@@ -6438,7 +6432,7 @@ static void ex_winsize(exarg_T *eap)
p = arg;
h = getdigits_int(&arg);
if (*p != NUL && *arg == NUL)
- screen_resize(w, h, TRUE);
+ screen_resize(w, h);
else
EMSG(_("E465: :winsize requires two number arguments"));
}
@@ -6473,35 +6467,6 @@ static void ex_wincmd(exarg_T *eap)
}
}
-#if defined(FEAT_GUI) || defined(UNIX) || defined(MSWIN)
-/*
- * ":winpos".
- */
-static void ex_winpos(exarg_T *eap)
-{
- int x, y;
- char_u *arg = eap->arg;
- char_u *p;
-
- if (*arg == NUL) {
- EMSG(_("E188: Obtaining window position not implemented for this platform"));
- } else {
- x = getdigits_int(&arg);
- arg = skipwhite(arg);
- p = arg;
- y = getdigits_int(&arg);
- if (*p == NUL || *arg != NUL) {
- EMSG(_("E466: :winpos requires two number arguments"));
- return;
- }
-# ifdef HAVE_TGETENT
- if (*T_CWP)
- term_set_winpos(x, y);
-# endif
- }
-}
-#endif
-
/*
* Handle command that work like operators: ":delete", ":yank", ":>" and ":<".
*/
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 2855f0cc12..6a3bd16feb 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -4618,35 +4618,6 @@ int del_history_idx(int histype, int idx)
return TRUE;
}
-
-/*
- * Very specific function to remove the value in ":set key=val" from the
- * history.
- */
-void remove_key_from_history(void)
-{
- char_u *p;
- int i;
-
- i = hisidx[HIST_CMD];
- if (i < 0)
- return;
- p = history[HIST_CMD][i].hisstr;
- if (p != NULL)
- for (; *p; ++p)
- if (STRNCMP(p, "key", 3) == 0 && !isalpha(p[3])) {
- p = vim_strchr(p + 3, '=');
- if (p == NULL)
- break;
- ++p;
- for (i = 0; p[i] && !vim_iswhite(p[i]); ++i)
- if (p[i] == '\\' && p[i + 1])
- ++i;
- STRMOVE(p, p + i);
- --p;
- }
-}
-
/*
* Get indices "num1,num2" that specify a range within a list (not a range of
* text lines in a buffer!) from a string. Used for ":history" and ":clist".
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index a4728b245b..dd6e5ace3f 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1813,7 +1813,6 @@ failed:
* Switch on raw mode now and clear the screen.
*/
if (read_stdin) {
- starttermcap();
screenclear();
}
@@ -6471,12 +6470,6 @@ int has_cmdundefined(void)
return first_autopat[(int)EVENT_CMDUNDEFINED] != NULL;
}
-/// @returns true when there is an FuncUndefined autocommand defined.
-int has_funcundefined(void)
-{
- return first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL;
-}
-
static int
apply_autocmds_group (
event_T event,
diff --git a/src/nvim/garray.c b/src/nvim/garray.c
index c3a3426e87..31a79db209 100644
--- a/src/nvim/garray.c
+++ b/src/nvim/garray.c
@@ -198,23 +198,3 @@ void ga_append(garray_T *gap, char c)
{
GA_APPEND(char, gap, c);
}
-
-#if defined(UNIX) || defined(WIN3264)
-
-/// Append the text in "gap" below the cursor line and clear "gap".
-///
-/// @param gap
-void append_ga_line(garray_T *gap)
-{
- // Remove trailing CR.
- if (!GA_EMPTY(gap)
- && !curbuf->b_p_bin
- && (((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)) {
- gap->ga_len--;
- }
- ga_append(gap, NUL);
- ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
- gap->ga_len = 0;
-}
-
-#endif // if defined(UNIX) || defined(WIN3264)
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index d97c983133..b8a145483f 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1203,7 +1203,6 @@ void save_typeahead(tasave_T *tp)
readbuf1.bh_first.b_next = NULL;
tp->save_readbuf2 = readbuf2;
readbuf2.bh_first.b_next = NULL;
- tp->save_inputbuf = input_buffer_save();
}
/*
@@ -1224,7 +1223,6 @@ void restore_typeahead(tasave_T *tp)
readbuf1 = tp->save_readbuf1;
free_buff(&readbuf2);
readbuf2 = tp->save_readbuf2;
- input_buffer_restore(tp->save_inputbuf);
}
/*
@@ -1546,22 +1544,6 @@ int vpeekc(void)
}
/*
- * Like vpeekc(), but don't allow mapping. Do allow checking for terminal
- * codes.
- */
-int vpeekc_nomap(void)
-{
- int c;
-
- ++no_mapping;
- ++allow_keys;
- c = vpeekc();
- --no_mapping;
- --allow_keys;
- return c;
-}
-
-/*
* Check if any character is available, also half an escape sequence.
* Trick: when no typeahead found, but there is something in the typeahead
* buffer, it must be an ESC that is recognized as the start of a key code.
@@ -1929,8 +1911,6 @@ static int vgetorpeek(int advance)
if ((mp == NULL || max_mlen >= mp_match_len)
&& keylen != KEYLEN_PART_MAP) {
- int save_keylen = keylen;
-
/*
* When no matching mapping found or found a
* non-matching mapping that matches at least what the
@@ -1947,25 +1927,7 @@ static int vgetorpeek(int advance)
|| (p_remap && typebuf.tb_noremap[
typebuf.tb_off] == RM_YES))
&& !timedout) {
- keylen = check_termcode(max_mlen + 1,
- NULL, 0, NULL);
-
- /* If no termcode matched but 'pastetoggle'
- * matched partially it's like an incomplete key
- * sequence. */
- if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
- keylen = KEYLEN_PART_KEY;
-
- /*
- * When getting a partial match, but the last
- * characters were not typed, don't wait for a
- * typed character to complete the termcode.
- * This helps a lot when a ":normal" command ends
- * in an ESC.
- */
- if (keylen < 0
- && typebuf.tb_len == typebuf.tb_maplen)
- keylen = 0;
+ keylen = 0;
} else
keylen = 0;
if (keylen == 0) { /* no matching terminal code */
@@ -2515,29 +2477,27 @@ fix_input_buffer (
int script /* TRUE when reading from a script */
)
{
- if (abstract_ui) {
- // Should not escape K_SPECIAL/CSI while in embedded mode because vim key
- // codes keys are processed in input.c/input_enqueue.
+ if (!using_script()) {
+ // Should not escape K_SPECIAL/CSI reading input from the user because vim
+ // key codes keys are processed in input.c/input_enqueue.
buf[len] = NUL;
return len;
}
+ // Reading from script, need to process special bytes
int i;
char_u *p = buf;
- /*
- * Two characters are special: NUL and K_SPECIAL.
- * When compiled With the GUI CSI is also special.
- * Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
- * Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
- * Replace CSI by K_SPECIAL KS_EXTRA KE_CSI
- * Don't replace K_SPECIAL when reading a script file.
- */
+ // Two characters are special: NUL and K_SPECIAL.
+ // Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
+ // Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
+ // Replace CSI by K_SPECIAL KS_EXTRA KE_CSI
+ // Don't replace K_SPECIAL when reading a script file.
for (i = len; --i >= 0; ++p) {
if (p[0] == NUL
|| (p[0] == K_SPECIAL
&& !script
- && (i < 2 || p[1] != KS_EXTRA || is_user_input(p[2])))) {
+ && (i < 2 || p[1] != KS_EXTRA))) {
memmove(p + 3, p + 1, (size_t)i);
p[2] = K_THIRD(p[0]);
p[1] = K_SECOND(p[0]);
@@ -2546,7 +2506,7 @@ fix_input_buffer (
len += 2;
}
}
- *p = NUL; /* add trailing NUL */
+ *p = NUL; // add trailing NUL
return len;
}
@@ -3772,11 +3732,6 @@ eval_map_expr (
return res;
}
-static bool is_user_input(int k)
-{
- return k != (int)KE_EVENT && k != (int)KE_CURSORHOLD;
-}
-
/*
* Copy "p" to allocated memory, escaping K_SPECIAL and CSI so that the result
* can be put in the typeahead buffer.
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 1aa90777fa..86c28e823a 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -904,13 +904,10 @@ EXTERN char_u *use_viminfo INIT(= NULL); /* name of viminfo file to use */
EXTERN FILE *scriptin[NSCRIPT]; /* streams to read script from */
EXTERN int curscript INIT(= 0); /* index in scriptin[] */
EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
-EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */
/* volatile because it is used in signal handler catch_sigint(). */
EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
signal occurred */
-EXTERN int termcap_active INIT(= FALSE); /* set by starttermcap() */
-EXTERN int cur_tmode INIT(= TMODE_COOK); /* input terminal mode */
EXTERN int bangredo INIT(= FALSE); /* set to TRUE with ! command */
EXTERN int searchcmdlen; /* length of previous search cmd */
EXTERN int reg_do_extmatch INIT(= 0); /* Used when compiling regexp:
@@ -1237,14 +1234,8 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
EXTERN int ignored;
EXTERN char *ignoredp;
-/* Temporarily moved these static variables to assist in migrating from
- * os_unix.c */
-EXTERN int curr_tmode INIT(= TMODE_COOK); /* contains current terminal mode */
-
// If a msgpack-rpc channel should be started over stdin/stdout
EXTERN bool embedded_mode INIT(= false);
-// Using the "abstract_ui" termcap
-EXTERN bool abstract_ui INIT(= false);
/// Used to track the status of external functions.
/// Currently only used for iconv().
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index c01f763d20..2dbe33d6e2 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -617,10 +617,7 @@ void ex_hardcopy(exarg_T *eap)
eap->forceit) == FAIL)
return;
- if (t_colors > 1)
- settings.modec = 'c';
- else
- settings.modec = 't';
+ settings.modec = 'c';
if (!syntax_present(curwin))
settings.do_syntax = FALSE;
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 251926c01a..8d98a0a95d 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -752,26 +752,3 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
}
return 0; /* Shouldn't get here */
}
-
-/*
- * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
- * the given information about which mouse button is down, and whether the
- * mouse was clicked, dragged or released.
- */
-int
-get_pseudo_mouse_code (
- int button, /* eg MOUSE_LEFT */
- int is_click,
- int is_drag
-)
-{
- int i;
-
- for (i = 0; mouse_table[i].pseudo_code; i++)
- if (button == mouse_table[i].button
- && is_click == mouse_table[i].is_click
- && is_drag == mouse_table[i].is_drag) {
- return mouse_table[i].pseudo_code;
- }
- return (int)KE_IGNORE; /* not recognized, ignore it */
-}
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 6e24806c56..f2891f0979 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -95,7 +95,12 @@ typedef struct {
char_u *use_ef; /* 'errorfile' from -q argument */
int want_full_screen;
- bool stdout_isatty; /* is stdout a terminal? */
+ bool input_isatty; // stdin is a terminal
+ bool output_isatty; // stdout is a terminal
+ bool err_isatty; // stderr is a terminal
+ bool headless; // Dont try to start an user interface
+ // or read/write to stdio(unless
+ // embedding)
char_u *term; /* specified terminal name */
int no_swap_file; /* "-n" argument used */
int use_debug_break_level;
@@ -197,9 +202,7 @@ int main(int argc, char **argv)
early_init();
- /*
- * Check if we have an interactive window.
- */
+ // Check if we have an interactive window.
check_and_set_isatty(&params);
/*
@@ -242,34 +245,20 @@ int main(int argc, char **argv)
printf(_("%d files to edit\n"), GARGCOUNT);
if (params.want_full_screen && !silent_mode) {
- if (embedded_mode) {
- // embedded mode implies abstract_ui
- termcapinit((uint8_t *)"abstract_ui");
- } else {
- // set terminal name and get terminal capabilities (will set full_screen)
- // Do some initialization of the screen
- termcapinit(params.term);
- }
+ termcapinit((uint8_t *)"abstract_ui");
screen_start(); /* don't know where cursor is now */
TIME_MSG("Termcap init");
}
event_init();
-
- if (abstract_ui) {
- full_screen = true;
- t_colors = 256;
- T_CCO = (uint8_t *)"256";
- } else {
- // Print a warning if stdout is not a terminal TODO(tarruda): Remove this
- // check once the new terminal UI is implemented
- check_tty(&params);
- }
+ full_screen = true;
+ t_colors = 256;
+ T_CCO = (uint8_t *)"256";
+ check_tty(&params);
/*
* Set the default values for the options that use Rows and Columns.
*/
- ui_get_shellsize(); /* inits Rows and Columns */
win_init_size();
/* Set the 'diff' option now, so that it can be checked for in a .vimrc
* file. There is no buffer yet though. */
@@ -382,25 +371,22 @@ int main(int argc, char **argv)
newline_on_exit = TRUE;
#endif
- /*
- * When done something that is not allowed or error message call
- * wait_return. This must be done before starttermcap(), because it may
- * switch to another screen. It must be done after settmode(TMODE_RAW),
- * because we want to react on a single key stroke.
- * Call settmode and starttermcap here, so the T_KS and T_TI may be
- * defined by termcapinit and redefined in .exrc.
- */
- settmode(TMODE_RAW);
- TIME_MSG("setting raw mode");
+ if (!params.headless && (params.output_isatty || params.err_isatty)) {
+ if (params.input_isatty && (need_wait_return || msg_didany)) {
+ // Since at this point there's no UI instance running yet, error messages
+ // would have been printed to stdout. Before starting (which can result
+ // in a alternate screen buffer being shown) we need confirmation that
+ // the user has seen the messages and that is done with a call to
+ // wait_return. For that to work, stdin must be openend temporarily.
+ input_start_stdin();
+ wait_return(TRUE);
+ TIME_MSG("waiting for return");
+ input_stop_stdin();
+ }
- if (need_wait_return || msg_didany) {
- wait_return(TRUE);
- TIME_MSG("waiting for return");
+ ui_builtin_start();
}
- starttermcap(); // start termcap if not done by wait_return()
- TIME_MSG("start termcap");
- may_req_ambiguous_char_width();
setmouse(); // may start using the mouse
if (scroll_region) {
@@ -480,10 +466,6 @@ int main(int argc, char **argv)
no_wait_return = FALSE;
starting = 0;
- /* Requesting the termresponse is postponed until here, so that a "-c q"
- * argument doesn't make it appear in the shell Vim was started from. */
- may_req_termresponse();
-
/* start in insert mode */
if (p_im)
need_start_insertmode = TRUE;
@@ -965,14 +947,14 @@ static void command_line_scan(mparm_T *parmp)
c = argv[0][argv_idx++];
switch (c) {
case NUL: /* "vim -" read from stdin */
- /* "ex -" silent mode */
- if (exmode_active)
+ if (exmode_active) {
+ // "ex -" silent mode
silent_mode = TRUE;
- else {
- if (parmp->edit_type != EDIT_NONE)
+ } else {
+ if (parmp->edit_type != EDIT_NONE) {
mainerr(ME_TOO_MANY_ARGS, argv[0]);
+ }
parmp->edit_type = EDIT_STDIN;
- read_cmd_fd = 2; /* read from stderr instead of stdin */
}
argv_idx = -1; /* skip to next argument */
break;
@@ -1004,8 +986,11 @@ static void command_line_scan(mparm_T *parmp)
}
mch_exit(0);
+ } else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
+ parmp->headless = true;
} else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
embedded_mode = true;
+ parmp->headless = true;
} else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
#if !defined(UNIX)
parmp->literal = TRUE;
@@ -1418,7 +1403,8 @@ static void init_params(mparm_T *paramp, int argc, char **argv)
memset(paramp, 0, sizeof(*paramp));
paramp->argc = argc;
paramp->argv = argv;
- paramp->want_full_screen = TRUE;
+ paramp->headless = false;
+ paramp->want_full_screen = true;
paramp->use_debug_break_level = -1;
paramp->window_count = -1;
}
@@ -1439,15 +1425,13 @@ static void init_startuptime(mparm_T *paramp)
starttime = time(NULL);
}
-/*
- * Check if we have an interactive window.
- */
static void check_and_set_isatty(mparm_T *paramp)
{
- paramp->stdout_isatty = os_isatty(STDOUT_FILENO);
+ paramp->input_isatty = os_isatty(fileno(stdin));
+ paramp->output_isatty = os_isatty(fileno(stdout));
+ paramp->err_isatty = os_isatty(fileno(stderr));
TIME_MSG("window checked");
}
-
/*
* Get filename from command line, given that there is one.
*/
@@ -1532,28 +1516,43 @@ static void handle_tag(char_u *tagname)
}
}
-/*
- * Print a warning if stdout is not a terminal.
- * When starting in Ex mode and commands come from a file, set Silent mode.
- */
+// Print a warning if stdout is not a terminal.
+// When starting in Ex mode and commands come from a file, set Silent mode.
static void check_tty(mparm_T *parmp)
{
+ if (parmp->headless) {
+ return;
+ }
+
// is active input a terminal?
- bool input_isatty = os_isatty(read_cmd_fd);
if (exmode_active) {
- if (!input_isatty)
- silent_mode = TRUE;
- } else if (parmp->want_full_screen && (!parmp->stdout_isatty || !input_isatty)
- ) {
- if (!parmp->stdout_isatty)
+ if (!parmp->input_isatty) {
+ silent_mode = true;
+ }
+ } else if (parmp->want_full_screen && (!parmp->err_isatty
+ && (!parmp->output_isatty || !parmp->input_isatty))) {
+
+ if (!parmp->output_isatty) {
mch_errmsg(_("Vim: Warning: Output is not to a terminal\n"));
- if (!input_isatty)
+ }
+
+ if (!parmp->input_isatty) {
mch_errmsg(_("Vim: Warning: Input is not from a terminal\n"));
+ }
+
out_flush();
- if (scriptin[0] == NULL)
+
+ if (scriptin[0] == NULL) {
os_delay(2000L, true);
+ }
+
TIME_MSG("Warning delay");
}
+
+ if (parmp->edit_type != EDIT_STDIN && !parmp->input_isatty) {
+ // read commands from directly from stdin
+ input_start_stdin();
+ }
}
/*
@@ -1573,13 +1572,6 @@ static void read_stdin(void)
msg_didany = i;
TIME_MSG("reading stdin");
check_swap_exists_action();
- /*
- * Close stdin and dup it from stderr. Required for GPM to work
- * properly, and for running external commands.
- * Is there any other system that cannot do this?
- */
- close(0);
- ignored = dup(2);
}
/*
@@ -2104,6 +2096,7 @@ static void usage(void)
mch_msg(_(" -i <nviminfo> Use <nviminfo> instead of .nviminfo\n"));
mch_msg(_(" --api-info Dump API metadata serialized to msgpack and exit\n"));
mch_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n"));
+ mch_msg(_(" --headless Don't start a user interface\n"));
mch_msg(_(" --version Print version information and exit\n"));
mch_msg(_(" -h | --help Print this help message and exit\n"));
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 3f485cb952..31fe8a01ea 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -100,7 +100,7 @@ static inline khint_t String_hash(String s)
static inline bool String_eq(String a, String b)
{
- return strncmp(a.data, b.data, min(a.size, b.size)) == 0;
+ return strncmp(a.data, b.data, MIN(a.size, b.size)) == 0;
}
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 87b0253d70..825b8b2550 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -40,6 +40,7 @@
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/term.h"
+#include "nvim/ui.h"
#include "nvim/mouse.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
@@ -915,15 +916,6 @@ void wait_return(int redraw)
State = oldState; /* restore State before set_shellsize */
setmouse();
msg_check();
-
-#if defined(UNIX)
- /*
- * When switching screens, we need to output an extra newline on exit.
- */
- if (swapping_screen() && !termcap_active)
- newline_on_exit = TRUE;
-#endif
-
need_wait_return = FALSE;
did_wait_return = TRUE;
emsg_on_display = FALSE; /* can delete error message now */
@@ -936,11 +928,9 @@ void wait_return(int redraw)
}
if (tmpState == SETWSIZE) { /* got resize event while in vgetc() */
- starttermcap(); /* start termcap before redrawing */
shell_resized();
} else if (!skip_redraw
&& (redraw == TRUE || (msg_scrolled != 0 && redraw != -1))) {
- starttermcap(); /* start termcap before redrawing */
redraw_later(VALID);
}
}
@@ -979,17 +969,6 @@ void set_keep_msg(char_u *s, int attr)
}
/*
- * If there currently is a message being displayed, set "keep_msg" to it, so
- * that it will be displayed again after redraw.
- */
-void set_keep_msg_from_hist(void)
-{
- if (keep_msg == NULL && last_msg_hist != NULL && msg_scrolled == 0
- && (State & NORMAL))
- set_keep_msg(last_msg_hist->msg, last_msg_hist->attr);
-}
-
-/*
* Prepare for outputting characters in the command line.
*/
void msg_start(void)
@@ -1780,19 +1759,6 @@ static void msg_scroll_up(void)
{
/* scrolling up always works */
screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
-
- if (!can_clear((char_u *)" ")) {
- /* Scrolling up doesn't result in the right background. Set the
- * background here. It's not efficient, but avoids that we have to do
- * it all over the code. */
- screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
-
- /* Also clear the last char of the last but one line if it was not
- * cleared before to avoid a scroll-up. */
- if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1] == (sattr_T)-1)
- screen_fill((int)Rows - 2, (int)Rows - 1,
- (int)Columns - 1, (int)Columns, ' ', ' ', 0);
- }
}
/*
@@ -1975,19 +1941,11 @@ static void t_puts(int *t_col, char_u *t_s, char_u *s, int attr)
}
}
-/*
- * Returns TRUE when messages should be printed with mch_errmsg().
- * 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.
- */
+// Returns TRUE when messages should be printed to stdout/stderr, which
+// happens when no UIs are attached and nvim is not being embedded
int msg_use_printf(void)
{
- return !msg_check_screen()
- || (swapping_screen() && !termcap_active)
- ;
+ return !embedded_mode && !ui_active();
}
/*
@@ -2379,24 +2337,6 @@ void repeat_message(void)
}
/*
- * 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(void)
-{
- 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.
* Skip this when ":silent" was used, no need to clear for redirection.
*/
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 383e2bf6a5..a7e471625b 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -2395,11 +2395,6 @@ int get_keystroke(void)
} else if (len > 0)
++waited; /* keep track of the waiting time */
- /* Incomplete termcode and not timed out yet: get more characters */
- if ((n = check_termcode(1, buf, buflen, &len)) < 0
- && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm)))
- continue;
-
if (n == KEYLEN_REMOVED) { /* key code removed */
if (must_redraw != 0 && !need_wait_return && (State & CMDLINE) == 0) {
/* Redrawing was postponed, do it now. */
@@ -3301,28 +3296,6 @@ home_replace_save (
return dst;
}
-void prepare_to_exit(void)
-{
-#if defined(SIGHUP) && defined(SIG_IGN)
- /* Ignore SIGHUP, because a dropped connection causes a read error, which
- * makes Vim exit and then handling SIGHUP causes various reentrance
- * problems. */
- signal(SIGHUP, SIG_IGN);
-#endif
-
- {
- windgoto((int)Rows - 1, 0);
-
- /*
- * Switch terminal mode back now, so messages end up on the "normal"
- * screen (if there are two screens).
- */
- settmode(TMODE_COOK);
- stoptermcap();
- out_flush();
- }
-}
-
/*
* Preserve files and exit.
* When called IObuff must contain a message.
@@ -3340,9 +3313,6 @@ void preserve_exit(void)
}
really_exiting = true;
-
- prepare_to_exit();
-
out_str(IObuff);
screen_start(); // don't know where cursor is now
out_flush();
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 9f67bd1760..84a1732a6a 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -451,12 +451,6 @@ void setmouse(void)
if (*p_mouse == NUL)
return;
- /* don't switch mouse on when not in raw mode (Ex mode) */
- if (!abstract_ui && cur_tmode != TMODE_RAW) {
- mch_setmouse(false);
- return;
- }
-
if (VIsual_active)
checkfor = MOUSE_VISUAL;
else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 7ae45ee84a..58c181e4de 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -103,9 +103,7 @@ void channel_init(void)
channel_from_stdio();
}
- if (abstract_ui) {
- remote_ui_init();
- }
+ remote_ui_init();
}
/// Teardown the module
@@ -176,13 +174,6 @@ void channel_from_stream(uv_stream_t *stream)
channel->data.streams.uv = stream;
}
-bool channel_exists(uint64_t id)
-{
- Channel *channel;
- return (channel = pmap_get(uint64_t)(channels, id)) != NULL
- && !channel->closed;
-}
-
/// Sends event/arguments to channel
///
/// @param id The channel id. If 0, the event will be sent to all
@@ -665,10 +656,7 @@ static void on_stdio_close(Event e)
static void free_channel(Channel *channel)
{
- if (abstract_ui) {
- remote_ui_disconnect(channel->id);
- }
-
+ remote_ui_disconnect(channel->id);
pmap_del(uint64_t)(channels, channel->id);
msgpack_unpacker_free(channel->unpacker);
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 54e8b83cd0..355176aa5f 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -295,22 +295,6 @@ void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res)
}
}
-/// Finishes the msgpack-rpc call with an error message.
-///
-/// @param msg The error message
-/// @param res A packer that contains the response
-void msgpack_rpc_error(char *msg, msgpack_packer *res)
- FUNC_ATTR_NONNULL_ALL
-{
- size_t len = strlen(msg);
-
- // error message
- msgpack_pack_bin(res, len);
- msgpack_pack_bin_body(res, msg, len);
- // Nil result
- msgpack_pack_nil(res);
-}
-
/// Handler executed when an invalid method name is passed
Object msgpack_rpc_handle_missing_method(uint64_t channel_id,
uint64_t request_id,
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index e147280723..8c7deaa243 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1834,7 +1834,6 @@ do_mouse (
bool fixindent /* PUT_FIXINDENT if fixing indent necessary */
)
{
- static bool do_always = false; /* ignore 'mouse' setting next time */
static bool got_click = false; /* got a click some time back */
int which_button; /* MOUSE_LEFT, _MIDDLE or _RIGHT */
@@ -1859,23 +1858,6 @@ do_mouse (
save_cursor = curwin->w_cursor;
- // When "abstract_ui" is active, always recognize mouse events, otherwise:
- // - Ignore mouse event in normal mode if 'mouse' doesn't include 'n'.
- // - Ignore mouse event in visual mode if 'mouse' doesn't include 'v'.
- // - For command line and insert mode 'mouse' is checked before calling
- // do_mouse().
- if (!abstract_ui) {
- if (do_always)
- do_always = false;
- else {
- if (VIsual_active) {
- if (!mouse_has(MOUSE_VISUAL))
- return false;
- } else if (State == NORMAL && !mouse_has(MOUSE_NORMAL))
- return false;
- }
- }
-
for (;; ) {
which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag);
if (is_drag) {
@@ -1996,7 +1978,6 @@ do_mouse (
stuffcharReadbuff('y');
stuffcharReadbuff(K_MIDDLEMOUSE);
}
- do_always = true; /* ignore 'mouse' setting next time */
return false;
}
/*
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 71d19e24f1..7242c2d925 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -4226,23 +4226,6 @@ did_set_string_option (
}
-
-
-#if defined(FEAT_MOUSE_TTY) && defined(UNIX)
- /* 'ttymouse' */
- else if (varp == &p_ttym) {
- /* Switch the mouse off before changing the escape sequences used for
- * that. */
- mch_setmouse(FALSE);
- if (opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE) != OK)
- errmsg = e_invarg;
- else
- check_mouse_termcode();
- if (termcap_active)
- setmouse(); /* may switch it on again */
- }
-#endif
-
/* 'selection' */
else if (varp == &p_sel) {
if (*p_sel == NUL
@@ -5439,8 +5422,7 @@ set_num_option (
curbuf->b_p_iminsert = B_IMODE_NONE;
}
p_iminsert = curbuf->b_p_iminsert;
- if (termcap_active) /* don't do this in the alternate screen */
- showmode();
+ showmode();
/* Show/unshow value of 'keymap' in status lines. */
status_redraw_curbuf();
} else if (pp == &p_window) {
@@ -5559,12 +5541,11 @@ set_num_option (
*/
if (old_Rows != Rows || old_Columns != Columns) {
/* Changing the screen size is not allowed while updating the screen. */
- if (updating_screen)
+ if (updating_screen) {
*pp = old_value;
- else if (full_screen
- )
- screen_resize((int)Columns, (int)Rows, TRUE);
- else {
+ } else if (full_screen) {
+ screen_resize((int)Columns, (int)Rows);
+ } else {
/* Postpone the resizing; check the size and cmdline position for
* messages. */
check_shellsize();
@@ -5970,27 +5951,6 @@ set_option_value (
return NULL;
}
-/*
- * Get the terminal code for a terminal option.
- * Returns NULL when not found.
- */
-char_u *get_term_code(char_u *tname)
-{
- int opt_idx;
- char_u *varp;
-
- if (tname[0] != 't' || tname[1] != '_' ||
- tname[2] == NUL || tname[3] == NUL)
- return NULL;
- if ((opt_idx = findoption(tname)) >= 0) {
- varp = get_varp(&(options[opt_idx]));
- if (varp != NULL)
- varp = *(char_u **)(varp);
- return varp;
- }
- return find_termcode(tname + 2);
-}
-
char_u *get_highlight_default(void)
{
int i;
@@ -6414,7 +6374,6 @@ void clear_termoptions(void)
*/
mch_setmouse(FALSE); /* switch mouse off */
mch_restore_title(3); /* restore window titles */
- stoptermcap(); /* stop termcap mode */
free_termoptions();
}
@@ -7832,17 +7791,6 @@ int option_was_set(char_u *name)
}
/*
- * Reset the flag indicating option "name" was set.
- */
-void reset_option_was_set(char_u *name)
-{
- int idx = findoption(name);
-
- if (idx >= 0)
- options[idx].flags &= ~P_WAS_SET;
-}
-
-/*
* fill_breakat_flags() -- called when 'breakat' changes value.
*/
static void fill_breakat_flags(void)
diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c
index 45ea8f28b5..9a15bf92d0 100644
--- a/src/nvim/os/event.c
+++ b/src/nvim/os/event.c
@@ -54,7 +54,6 @@ void event_init(void)
wstream_init();
// Initialize input events
input_init();
- input_start();
// Timer to wake the event loop if a timeout argument is passed to
// `event_poll`
// Signals
@@ -75,13 +74,11 @@ void event_teardown(void)
process_events_from(immediate_events);
process_events_from(deferred_events);
-
+ input_stop_stdin();
channel_teardown();
job_teardown();
server_teardown();
signal_teardown();
- input_stop();
- input_teardown();
// this last `uv_run` will return after all handles are stopped, it will
// also take care of finishing any uv_close calls made by other *_teardown
// functions.
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 2ae4558f3d..2c2b0fc871 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -19,7 +19,6 @@
#include "nvim/fileio.h"
#include "nvim/ex_cmds2.h"
#include "nvim/getchar.h"
-#include "nvim/term.h"
#include "nvim/main.h"
#include "nvim/misc1.h"
@@ -32,9 +31,9 @@ typedef enum {
kInputEof
} InbufPollResult;
-static RStream *read_stream;
-static RBuffer *read_buffer, *input_buffer;
-static bool eof = false, started_reading = false;
+static RStream *read_stream = NULL;
+static RBuffer *read_buffer = NULL, *input_buffer = NULL;
+static bool eof = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/input.c.generated.h"
@@ -45,43 +44,29 @@ static bool eof = false, started_reading = false;
void input_init(void)
{
input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN);
-
- if (abstract_ui) {
- return;
- }
-
- read_buffer = rbuffer_new(READ_BUFFER_SIZE);
- read_stream = rstream_new(read_cb, read_buffer, NULL);
- rstream_set_file(read_stream, read_cmd_fd);
}
-void input_teardown(void)
+void input_start_stdin(void)
{
- if (abstract_ui) {
- return;
- }
-
- rstream_free(read_stream);
-}
-
-// Listen for input
-void input_start(void)
-{
- if (abstract_ui) {
+ if (read_stream) {
return;
}
+ read_buffer = rbuffer_new(READ_BUFFER_SIZE);
+ read_stream = rstream_new(read_cb, read_buffer, NULL);
+ rstream_set_file(read_stream, fileno(stdin));
rstream_start(read_stream);
}
-// Stop listening for input
-void input_stop(void)
+void input_stop_stdin(void)
{
- if (abstract_ui) {
+ if (!read_stream) {
return;
}
rstream_stop(read_stream);
+ rstream_free(read_stream);
+ read_stream = NULL;
}
// Low level input function.
@@ -141,11 +126,9 @@ bool os_char_avail(void)
}
// Check for CTRL-C typed by reading all available characters.
-// In cooked mode we should get SIGINT, no need to check.
void os_breakcheck(void)
{
- if (curr_tmode == TMODE_RAW)
- input_poll(0);
+ event_poll(0);
}
/// Test whether a file descriptor refers to a terminal.
@@ -157,34 +140,13 @@ bool os_isatty(int fd)
return uv_guess_handle(fd) == UV_TTY;
}
-/// Return the contents of the input buffer and make it empty. The returned
-/// pointer must be passed to `input_buffer_restore()` later.
-String input_buffer_save(void)
-{
- size_t inbuf_size = rbuffer_pending(input_buffer);
- String rv = {
- .data = xmemdup(rbuffer_read_ptr(input_buffer), inbuf_size),
- .size = inbuf_size
- };
- rbuffer_consumed(input_buffer, inbuf_size);
- return rv;
-}
-
-/// Restore the contents of the input buffer and free `str`
-void input_buffer_restore(String str)
-{
- rbuffer_consumed(input_buffer, rbuffer_pending(input_buffer));
- rbuffer_write(input_buffer, str.data, str.size);
- free(str.data);
-}
-
size_t input_enqueue(String keys)
{
char *ptr = keys.data, *end = ptr + keys.size;
while (rbuffer_available(input_buffer) >= 6 && ptr < end) {
uint8_t buf[6] = {0};
- unsigned int new_size = trans_special((uint8_t **)&ptr, buf, false);
+ unsigned int new_size = trans_special((uint8_t **)&ptr, buf, true);
if (!new_size) {
if (*ptr == '<') {
@@ -215,15 +177,19 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
unsigned int bufsize)
{
int mouse_code = 0;
+ int type = 0;
if (bufsize == 3) {
mouse_code = buf[2];
+ type = buf[1];
} else if (bufsize == 6) {
// prefixed with K_SPECIAL KS_MODIFIER mod
mouse_code = buf[5];
+ type = buf[4];
}
- if (!((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE)
+ if (type != KS_EXTRA
+ || !((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE)
|| (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) {
return bufsize;
}
@@ -298,7 +264,7 @@ static bool input_poll(int ms)
prof_inchar_enter();
}
- event_poll_until(ms, input_ready());
+ event_poll_until(ms, input_ready() || eof);
if (do_profiling == PROF_YES && ms) {
prof_inchar_exit();
@@ -307,96 +273,31 @@ static bool input_poll(int ms)
return input_ready();
}
+void input_done(void)
+{
+ eof = true;
+}
+
// This is a replacement for the old `WaitForChar` function in os_unix.c
static InbufPollResult inbuf_poll(int ms)
{
- if (typebuf_was_filled || rbuffer_pending(input_buffer)) {
+ if (input_ready() || input_poll(ms)) {
return kInputAvail;
}
- if (input_poll(ms)) {
- return eof && rstream_pending(read_stream) == 0 ?
- kInputEof :
- kInputAvail;
- }
-
- return kInputNone;
-}
-
-static void stderr_switch(void)
-{
- int mode = cur_tmode;
- // We probably set the wrong file descriptor to raw mode. Switch back to
- // cooked mode
- settmode(TMODE_COOK);
- // Stop the idle handle
- rstream_stop(read_stream);
- // Use stderr for stdin, also works for shell commands.
- read_cmd_fd = 2;
- // Initialize and start the input stream
- rstream_set_file(read_stream, read_cmd_fd);
- rstream_start(read_stream);
- // Set the mode back to what it was
- settmode(mode);
+ return eof ? kInputEof : kInputNone;
}
static void read_cb(RStream *rstream, void *data, bool at_eof)
{
if (at_eof) {
- if (!started_reading
- && rstream_is_regular_file(rstream)
- && os_isatty(STDERR_FILENO)) {
- // Read error. Since stderr is a tty we switch to reading from it. This
- // is for handling for cases like "foo | xargs vim" because xargs
- // redirects stdin from /dev/null. Previously, this was done in ui.c
- stderr_switch();
- } else {
- eof = true;
- }
+ eof = true;
}
- convert_input();
- process_interrupts();
- started_reading = true;
-}
-
-static void convert_input(void)
-{
- if (abstract_ui || !rbuffer_available(input_buffer)) {
- // No input buffer space
- return;
- }
-
- bool convert = input_conv.vc_type != CONV_NONE;
- // Set unconverted data/length
- char *data = rbuffer_read_ptr(read_buffer);
- size_t data_length = rbuffer_pending(read_buffer);
- size_t converted_length = data_length;
-
- if (convert) {
- // Perform input conversion according to `input_conv`
- size_t unconverted_length = 0;
- data = (char *)string_convert_ext(&input_conv,
- (uint8_t *)data,
- (int *)&converted_length,
- (int *)&unconverted_length);
- data_length -= unconverted_length;
- }
-
- // The conversion code will be gone eventually, for now assume `input_buffer`
- // always has space for the converted data(it's many times the size of
- // `read_buffer`, so it's hard to imagine a scenario where the converted data
- // doesn't fit)
- assert(converted_length <= rbuffer_available(input_buffer));
- // Write processed data to input buffer.
- (void)rbuffer_write(input_buffer, data, converted_length);
- // Adjust raw buffer pointers
- rbuffer_consumed(read_buffer, data_length);
-
- if (convert) {
- // data points to memory allocated by `string_convert_ext`, free it.
- free(data);
- }
+ char *buf = rbuffer_read_ptr(read_buffer);
+ size_t buf_size = rbuffer_pending(read_buffer);
+ (void)rbuffer_write(input_buffer, buf, buf_size);
+ rbuffer_consumed(read_buffer, buf_size);
}
static void process_interrupts(void)
@@ -440,9 +341,8 @@ static int push_event_key(uint8_t *buf, int maxlen)
static bool input_ready(void)
{
return typebuf_was_filled || // API call filled typeahead
- rbuffer_pending(input_buffer) > 0 || // Stdin input
- event_has_deferred() || // Events must be processed
- (!abstract_ui && eof); // Stdin closed
+ rbuffer_pending(input_buffer) > 0 || // Input buffer filled
+ event_has_deferred(); // Events must be processed
}
// Exit because of an input read error.
diff --git a/src/nvim/os/rstream.c b/src/nvim/os/rstream.c
index e36a0213c8..a46e7d6f3c 100644
--- a/src/nvim/os/rstream.c
+++ b/src/nvim/os/rstream.c
@@ -271,15 +271,6 @@ void rstream_set_file(RStream *rstream, uv_file file)
rstream->free_handle = true;
}
-/// Tests if the stream is backed by a regular file
-///
-/// @param rstream The `RStream` instance
-/// @return True if the underlying file descriptor represents a regular file
-bool rstream_is_regular_file(RStream *rstream)
-{
- return rstream->file_type == UV_FILE;
-}
-
/// Starts watching for events from a `RStream` instance.
///
/// @param rstream The `RStream` instance
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index d074ace884..df21bed446 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -20,7 +20,7 @@
KMEMPOOL_INIT(SignalEventPool, int, SignalEventFreer)
kmempool_t(SignalEventPool) *signal_event_pool = NULL;
-static uv_signal_t sint, spipe, shup, squit, sterm, swinch;
+static uv_signal_t spipe, shup, squit, sterm;
#ifdef SIGPWR
static uv_signal_t spwr;
#endif
@@ -30,24 +30,18 @@ static bool rejecting_deadly;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/signal.c.generated.h"
#endif
+
void signal_init(void)
{
signal_event_pool = kmp_init(SignalEventPool);
- uv_signal_init(uv_default_loop(), &sint);
uv_signal_init(uv_default_loop(), &spipe);
uv_signal_init(uv_default_loop(), &shup);
uv_signal_init(uv_default_loop(), &squit);
uv_signal_init(uv_default_loop(), &sterm);
- uv_signal_init(uv_default_loop(), &swinch);
- uv_signal_start(&sint, signal_cb, SIGINT);
uv_signal_start(&spipe, signal_cb, SIGPIPE);
uv_signal_start(&shup, signal_cb, SIGHUP);
uv_signal_start(&squit, signal_cb, SIGQUIT);
uv_signal_start(&sterm, signal_cb, SIGTERM);
- if (!abstract_ui) {
- // TODO(tarruda): There must be an API function for resizing window
- uv_signal_start(&swinch, signal_cb, SIGWINCH);
- }
#ifdef SIGPWR
uv_signal_init(uv_default_loop(), &spwr);
uv_signal_start(&spwr, signal_cb, SIGPWR);
@@ -57,12 +51,10 @@ void signal_init(void)
void signal_teardown(void)
{
signal_stop();
- uv_close((uv_handle_t *)&sint, NULL);
uv_close((uv_handle_t *)&spipe, NULL);
uv_close((uv_handle_t *)&shup, NULL);
uv_close((uv_handle_t *)&squit, NULL);
uv_close((uv_handle_t *)&sterm, NULL);
- uv_close((uv_handle_t *)&swinch, NULL);
#ifdef SIGPWR
uv_close((uv_handle_t *)&spwr, NULL);
#endif
@@ -70,12 +62,10 @@ void signal_teardown(void)
void signal_stop(void)
{
- uv_signal_stop(&sint);
uv_signal_stop(&spipe);
uv_signal_stop(&shup);
uv_signal_stop(&squit);
uv_signal_stop(&sterm);
- uv_signal_stop(&swinch);
#ifdef SIGPWR
uv_signal_stop(&spwr);
#endif
@@ -94,16 +84,12 @@ void signal_accept_deadly(void)
static char * signal_name(int signum)
{
switch (signum) {
- case SIGINT:
- return "SIGINT";
#ifdef SIGPWR
case SIGPWR:
return "SIGPWR";
#endif
case SIGPIPE:
return "SIGPIPE";
- case SIGWINCH:
- return "SIGWINCH";
case SIGTERM:
return "SIGTERM";
case SIGQUIT:
@@ -148,9 +134,6 @@ static void on_signal_event(Event event)
kmp_free(SignalEventPool, signal_event_pool, event.data);
switch (signum) {
- case SIGINT:
- got_int = true;
- break;
#ifdef SIGPWR
case SIGPWR:
// Signal of a power failure(eg batteries low), flush the swap files to
@@ -161,9 +144,6 @@ static void on_signal_event(Event event)
case SIGPIPE:
// Ignore
break;
- case SIGWINCH:
- shell_resized();
- break;
case SIGTERM:
case SIGQUIT:
case SIGHUP:
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index d674db951f..455ed737ff 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -56,18 +56,10 @@
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/msgpack_rpc/defs.h"
-#if defined(HAVE_SYS_IOCTL_H)
-# include <sys/ioctl.h>
-#endif
-
#ifdef HAVE_STROPTS_H
# include <stropts.h>
#endif
-#if defined(HAVE_TERMIOS_H)
-# include <termios.h>
-#endif
-
#ifdef HAVE_SELINUX
# include <selinux/selinux.h>
static int selinux_enabled = -1;
@@ -82,53 +74,6 @@ static int did_set_title = FALSE;
static char_u *oldicon = NULL;
static int did_set_icon = FALSE;
-/*
- * If the machine has job control, use it to suspend the program,
- * otherwise fake it by starting a new shell.
- */
-void mch_suspend(void)
-{
-#if defined(SIGTSTP)
- out_flush(); /* needed to make cursor visible on some systems */
- settmode(TMODE_COOK);
- out_flush(); /* needed to disable mouse on some systems */
-
- // Note: compiler defines _REENTRANT when given -pthread flag.
-# if defined(_REENTRANT) && defined(SIGCONT)
- sigcont_received = FALSE;
-# endif
- uv_kill(0, SIGTSTP); // send ourselves a STOP signal
-# if defined(_REENTRANT) && defined(SIGCONT)
- /*
- * Wait for the SIGCONT signal to be handled. It generally happens
- * immediately, but somehow not all the time. Do not call pause()
- * because there would be race condition which would hang Vim if
- * signal happened in between the test of sigcont_received and the
- * call to pause(). If signal is not yet received, call sleep(0)
- * to just yield CPU. Signal should then be received. If somehow
- * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
- * further if signal is not received after 1+2+3+4 ms (not expected
- * to happen).
- */
- {
- long wait_time;
- for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++)
- /* Loop is not entered most of the time */
- os_delay(wait_time, false);
- }
-# endif
-
- /*
- * Set oldtitle to NULL, so the current title is obtained again.
- */
- free(oldtitle);
- oldtitle = NULL;
- settmode(TMODE_RAW);
- need_check_timestamps = TRUE;
- did_check_timestamps = FALSE;
-#endif
-}
-
static int get_x11_title(int test_only)
{
return FALSE;
@@ -161,7 +106,6 @@ int mch_can_restore_icon(void)
*/
void mch_settitle(char_u *title, char_u *icon)
{
- int type = 0;
static int recursive = 0;
if (T_NAME == NULL) /* no terminal name (yet) */
@@ -175,39 +119,13 @@ void mch_settitle(char_u *title, char_u *icon)
return;
++recursive;
- /*
- * if the window ID and the display is known, we may use X11 calls
- */
-
- /*
- * Note: if "t_ts" is set, title is set with escape sequence rather
- * than x11 calls, because the x11 calls don't always work
- */
- if ((type || *T_TS != NUL || abstract_ui) && title != NULL) {
- if (oldtitle == NULL
- ) /* first call but not in GUI, save title */
- (void)get_x11_title(FALSE);
-
- if (abstract_ui) {
- ui_set_title((char *)title);
- } else if (*T_TS != NUL) /* it's OK if t_fs is empty */
- term_settitle(title);
+ if (title != NULL) {
+ ui_set_title((char *)title);
did_set_title = TRUE;
}
- if ((type || *T_CIS != NUL || abstract_ui) && icon != NULL) {
- if (oldicon == NULL
- ) /* first call, save icon */
- get_x11_icon(FALSE);
-
- if (abstract_ui) {
- ui_set_icon((char *)icon);
- } else if (*T_CIS != NUL) {
- out_str(T_CIS); /* set icon start */
- out_str_nf(icon);
- out_str(T_CIE); /* set icon end */
- out_flush();
- }
+ if (icon != NULL) {
+ ui_set_icon((char *)icon);
did_set_icon = TRUE;
}
--recursive;
@@ -246,17 +164,6 @@ int vim_is_xterm(char_u *name)
}
/*
- * Return TRUE if "name" appears to be that of a terminal
- * known to support the xterm-style mouse protocol.
- * Relies on term_is_xterm having been set to its correct value.
- */
-int use_xterm_like_mouse(char_u *name)
-{
- return name != NULL
- && (term_is_xterm || STRNICMP(name, "screen", 6) == 0);
-}
-
-/*
* Return non-zero when using an xterm mouse, according to 'ttymouse'.
* Return 1 for "xterm".
* Return 2 for "xterm2".
@@ -481,7 +388,6 @@ void mch_exit(int r)
exiting = TRUE;
{
- settmode(TMODE_COOK);
mch_restore_title(3); /* restore xterm title and icon name */
/*
* When t_ti is not empty but it doesn't cause swapping terminal
@@ -492,9 +398,7 @@ void mch_exit(int r)
if (swapping_screen() && !newline_on_exit)
exit_scroll();
- /* Stop termcap: May need to check for T_CRV response, which
- * requires RAW mode. */
- stoptermcap();
+ ui_builtin_stop();
/*
* A newline is only required after a message in the alternate screen.
@@ -524,143 +428,6 @@ void mch_exit(int r)
exit(r);
}
-void mch_settmode(int tmode)
-{
- static int first = TRUE;
-
-#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
- defined(HAVE_TERMIOS_H))
- /*
- * for "new" tty systems
- */
-# ifdef HAVE_TERMIOS_H
- static struct termios told;
- struct termios tnew;
-# else
- static struct termio told;
- struct termio tnew;
-# endif
-
- if (first) {
- first = FALSE;
-# if defined(HAVE_TERMIOS_H)
- tcgetattr(read_cmd_fd, &told);
-# else
- ioctl(read_cmd_fd, TCGETA, &told);
-# endif
- }
-
- tnew = told;
- if (tmode == TMODE_RAW) {
- /*
- * ~ICRNL enables typing ^V^M
- */
- tnew.c_iflag &= ~ICRNL;
- tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
-# if defined(IEXTEN)
- | IEXTEN /* IEXTEN enables typing ^V on SOLARIS */
-# endif
- );
-# ifdef ONLCR /* don't map NL -> CR NL, we do it ourselves */
- tnew.c_oflag &= ~ONLCR;
-# endif
- tnew.c_cc[VMIN] = 1; /* return after 1 char */
- tnew.c_cc[VTIME] = 0; /* don't wait */
- } else if (tmode == TMODE_SLEEP)
- tnew.c_lflag &= ~(ECHO);
-
-# if defined(HAVE_TERMIOS_H)
- {
- int n = 10;
-
- /* A signal may cause tcsetattr() to fail (e.g., SIGCONT). Retry a
- * few times. */
- while (tcsetattr(read_cmd_fd, TCSANOW, &tnew) == -1
- && errno == EINTR && n > 0)
- --n;
- }
-# else
- ioctl(read_cmd_fd, TCSETA, &tnew);
-# endif
-
-#else
-
- /*
- * for "old" tty systems
- */
-# ifndef TIOCSETN
-# define TIOCSETN TIOCSETP /* for hpux 9.0 */
-# endif
- static struct sgttyb ttybold;
- struct sgttyb ttybnew;
-
- if (first) {
- first = FALSE;
- ioctl(read_cmd_fd, TIOCGETP, &ttybold);
- }
-
- ttybnew = ttybold;
- if (tmode == TMODE_RAW) {
- ttybnew.sg_flags &= ~(CRMOD | ECHO);
- ttybnew.sg_flags |= RAW;
- } else if (tmode == TMODE_SLEEP)
- ttybnew.sg_flags &= ~(ECHO);
- ioctl(read_cmd_fd, TIOCSETN, &ttybnew);
-#endif
- curr_tmode = tmode;
-}
-
-/*
- * Try to get the code for "t_kb" from the stty setting
- *
- * Even if termcap claims a backspace key, the user's setting *should*
- * prevail. stty knows more about reality than termcap does, and if
- * somebody's usual erase key is DEL (which, for most BSD users, it will
- * be), they're going to get really annoyed if their erase key starts
- * doing forward deletes for no reason. (Eric Fischer)
- */
-void get_stty(void)
-{
- char_u buf[2];
- char_u *p;
-
-#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
- defined(HAVE_TERMIOS_H))
- /* for "new" tty systems */
-# ifdef HAVE_TERMIOS_H
- struct termios keys;
-# else
- struct termio keys;
-# endif
-
-# if defined(HAVE_TERMIOS_H)
- if (tcgetattr(read_cmd_fd, &keys) != -1)
-# else
- if (ioctl(read_cmd_fd, TCGETA, &keys) != -1)
-# endif
- {
- buf[0] = keys.c_cc[VERASE];
- intr_char = keys.c_cc[VINTR];
-#else
- /* for "old" tty systems */
- struct sgttyb keys;
-
- if (ioctl(read_cmd_fd, TIOCGETP, &keys) != -1) {
- buf[0] = keys.sg_erase;
- intr_char = keys.sg_kill;
-#endif
- buf[1] = NUL;
- add_termcode((char_u *)"kb", buf, FALSE);
-
- /*
- * If <BS> and <DEL> are now the same, redefine <DEL>.
- */
- p = find_termcode((char_u *)"kD");
- if (p != NULL && p[0] == buf[0] && p[1] == buf[1])
- do_fixdel(NULL);
- }
-}
-
/*
* Set mouse clicks on or off.
*/
@@ -712,173 +479,6 @@ void mch_setmouse(int on)
}
-/// Sets the mouse termcode, depending on the 'term' and 'ttymouse' options.
-void check_mouse_termcode(void)
-{
- xterm_conflict_mouse = false;
-
- if (use_xterm_mouse()
- && use_xterm_mouse() != 3
- ) {
- set_mouse_termcode(KS_MOUSE, (char_u *)(term_is_8bit(T_NAME)
- ? "\233M"
- : "\033[M"));
- if (*p_mouse != NUL) {
- /* force mouse off and maybe on to send possibly new mouse
- * activation sequence to the xterm, with(out) drag tracing. */
- mch_setmouse(FALSE);
- setmouse();
- }
- } else
- del_mouse_termcode(KS_MOUSE);
-
-
- /* There is no conflict, but one may type "ESC }" from Insert mode. Don't
- * define it in the GUI or when using an xterm. */
- if (!use_xterm_mouse()
- )
- set_mouse_termcode(KS_NETTERM_MOUSE,
- (char_u *)"\033}");
- else
- del_mouse_termcode(KS_NETTERM_MOUSE);
-
- // Conflicts with xterm mouse: "\033[" and "\033[M".
- // Also conflicts with the xterm termresponse, skip this if it was requested
- // already.
- if (!use_xterm_mouse()) {
- set_mouse_termcode(KS_DEC_MOUSE, (char_u *)(term_is_8bit(T_NAME)
- ? "\233" : "\033["));
- xterm_conflict_mouse = true;
- }
- else {
- del_mouse_termcode(KS_DEC_MOUSE);
- }
- /* same as the dec mouse */
- if (use_xterm_mouse() == 3 && !did_request_esc_sequence()) {
- set_mouse_termcode(KS_URXVT_MOUSE,
- (char_u *)(term_is_8bit(T_NAME) ? "\233" : "\033["));
- if (*p_mouse != NUL) {
- mch_setmouse(false);
- setmouse();
- }
- resume_get_esc_sequence();
- } else {
- del_mouse_termcode(KS_URXVT_MOUSE);
- }
- // There is no conflict with xterm mouse.
- if (use_xterm_mouse() == 4) {
- set_mouse_termcode(KS_SGR_MOUSE, (char_u *)(term_is_8bit(T_NAME)
- ? "\233<"
- : "\033[<"));
-
- if (*p_mouse != NUL) {
- mch_setmouse(FALSE);
- setmouse();
- }
- } else {
- del_mouse_termcode(KS_SGR_MOUSE);
- }
-}
-
-/*
- * Try to get the current window size:
- * 1. with an ioctl(), most accurate method
- * 2. from the environment variables LINES and COLUMNS
- * 3. from the termcap
- * 4. keep using the old values
- * Return OK when size could be determined, FAIL otherwise.
- */
-int mch_get_shellsize(void)
-{
- long rows = 0;
- long columns = 0;
- char_u *p;
-
- /*
- * 1. try using an ioctl. It is the most accurate method.
- *
- * Try using TIOCGWINSZ first, some systems that have it also define
- * TIOCGSIZE but don't have a struct ttysize.
- */
-# ifdef TIOCGWINSZ
- {
- struct winsize ws;
- int fd = 1;
-
- /* When stdout is not a tty, use stdin for the ioctl(). */
- if (!isatty(fd) && isatty(read_cmd_fd))
- fd = read_cmd_fd;
- if (ioctl(fd, TIOCGWINSZ, &ws) == 0) {
- columns = ws.ws_col;
- rows = ws.ws_row;
- }
- }
-# else /* TIOCGWINSZ */
-# ifdef TIOCGSIZE
- {
- struct ttysize ts;
- int fd = 1;
-
- /* When stdout is not a tty, use stdin for the ioctl(). */
- if (!isatty(fd) && isatty(read_cmd_fd))
- fd = read_cmd_fd;
- if (ioctl(fd, TIOCGSIZE, &ts) == 0) {
- columns = ts.ts_cols;
- rows = ts.ts_lines;
- }
- }
-# endif /* TIOCGSIZE */
-# endif /* TIOCGWINSZ */
-
- /*
- * 2. get size from environment
- * When being POSIX compliant ('|' flag in 'cpoptions') this overrules
- * the ioctl() values!
- */
- if (columns == 0 || rows == 0 || vim_strchr(p_cpo, CPO_TSIZE) != NULL) {
- if ((p = (char_u *)os_getenv("LINES")))
- rows = atoi((char *)p);
- if ((p = (char_u *)os_getenv("COLUMNS")))
- columns = atoi((char *)p);
- }
-
-#ifdef HAVE_TGETENT
- /*
- * 3. try reading "co" and "li" entries from termcap
- */
- if (columns == 0 || rows == 0)
- getlinecol(&columns, &rows);
-#endif
-
- /*
- * 4. If everything fails, use the old values
- */
- if (columns <= 0 || rows <= 0)
- return FAIL;
-
- Rows = rows;
- Columns = columns;
- limit_screen_size();
- return OK;
-}
-
-/*
- * Try to set the window size to Rows and Columns.
- */
-void mch_set_shellsize(void)
-{
- if (*T_CWS) {
- /*
- * NOTE: if you get an error here that term_set_winsize() is
- * undefined, check the output of configure. It could probably not
- * find a ncurses, termcap or termlib library.
- */
- term_set_winsize((int)Rows, (int)Columns);
- out_flush();
- screen_start(); /* don't know where cursor is now */
- }
-}
-
/*
* mch_expand_wildcards() - this code does wild-card pattern matching using
* the shell
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 7e7a7c1148..80a87e9f7b 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -232,119 +232,6 @@ void redraw_buf_later(buf_T *buf, int type)
}
/*
- * Redraw as soon as possible. When the command line is not scrolled redraw
- * right away and restore what was on the command line.
- * Return a code indicating what happened.
- */
-int redraw_asap(int type)
-{
- int rows;
- int r;
- int ret = 0;
- schar_T *screenline; /* copy from ScreenLines[] */
- sattr_T *screenattr; /* copy from ScreenAttrs[] */
- int i;
- u8char_T *screenlineUC = NULL; /* copy from ScreenLinesUC[] */
- u8char_T *screenlineC[MAX_MCO]; /* copy from ScreenLinesC[][] */
- schar_T *screenline2 = NULL; /* copy from ScreenLines2[] */
- const bool l_enc_utf8 = enc_utf8;
- const int l_enc_dbcs = enc_dbcs;
- const long l_p_mco = p_mco;
-
- redraw_later(type);
- if (msg_scrolled || (State != NORMAL && State != NORMAL_BUSY))
- return ret;
-
- /* Allocate space to save the text displayed in the command line area. */
- rows = Rows - cmdline_row;
- screenline = xmalloc((size_t)(rows * Columns * sizeof(schar_T)));
- screenattr = xmalloc((size_t)(rows * Columns * sizeof(sattr_T)));
-
- if (l_enc_utf8) {
- screenlineUC = xmalloc((size_t)(rows * Columns * sizeof(u8char_T)));
-
- for (i = 0; i < l_p_mco; ++i) {
- screenlineC[i] = xmalloc((size_t)(rows * Columns * sizeof(u8char_T)));
- }
- }
- if (l_enc_dbcs == DBCS_JPNU) {
- screenline2 = xmalloc((size_t)(rows * Columns * sizeof(schar_T)));
- }
-
- /* Save the text displayed in the command line area. */
- for (r = 0; r < rows; ++r) {
- memmove(screenline + r * Columns,
- ScreenLines + LineOffset[cmdline_row + r],
- (size_t)Columns * sizeof(schar_T));
- memmove(screenattr + r * Columns,
- ScreenAttrs + LineOffset[cmdline_row + r],
- (size_t)Columns * sizeof(sattr_T));
- if (l_enc_utf8) {
- memmove(screenlineUC + r * Columns,
- ScreenLinesUC + LineOffset[cmdline_row + r],
- (size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < l_p_mco; ++i)
- memmove(screenlineC[i] + r * Columns,
- ScreenLinesC[r] + LineOffset[cmdline_row + r],
- (size_t)Columns * sizeof(u8char_T));
- }
- if (l_enc_dbcs == DBCS_JPNU)
- memmove(screenline2 + r * Columns,
- ScreenLines2 + LineOffset[cmdline_row + r],
- (size_t)Columns * sizeof(schar_T));
- }
-
- update_screen(0);
- ret = 3;
-
- if (must_redraw == 0) {
- int off = (int)(current_ScreenLine - ScreenLines);
-
- /* Restore the text displayed in the command line area. */
- for (r = 0; r < rows; ++r) {
- memmove(current_ScreenLine,
- screenline + r * Columns,
- (size_t)Columns * sizeof(schar_T));
- memmove(ScreenAttrs + off,
- screenattr + r * Columns,
- (size_t)Columns * sizeof(sattr_T));
- if (l_enc_utf8) {
- memmove(ScreenLinesUC + off,
- screenlineUC + r * Columns,
- (size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < l_p_mco; ++i)
- memmove(ScreenLinesC[i] + off,
- screenlineC[i] + r * Columns,
- (size_t)Columns * sizeof(u8char_T));
- }
- if (l_enc_dbcs == DBCS_JPNU)
- memmove(ScreenLines2 + off,
- screenline2 + r * Columns,
- (size_t)Columns * sizeof(schar_T));
- SCREEN_LINE(cmdline_row + r, 0, Columns, Columns, FALSE);
- }
- ret = 4;
- }
-
- free(screenline);
- free(screenattr);
- if (l_enc_utf8) {
- free(screenlineUC);
- for (i = 0; i < l_p_mco; ++i)
- free(screenlineC[i]);
- }
- if (l_enc_dbcs == DBCS_JPNU)
- free(screenline2);
-
- /* Show the intro message when appropriate. */
- maybe_intro_message();
-
- setcursor();
-
- return ret;
-}
-
-/*
* Changed something in the current window, at buffer line "lnum", that
* requires that line and possibly other lines to be redrawn.
* Used when entering/leaving Insert mode with the cursor on a folded line.
@@ -4472,23 +4359,6 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, int rl
if (char_cells == 2)
ScreenLines[off_to + 1] = ScreenLines[off_from + 1];
-#if defined(FEAT_GUI) || defined(UNIX)
- /* The bold trick makes a single column of pixels appear in the
- * next character. When a bold character is removed, the next
- * character should be redrawn too. This happens for our own GUI
- * and for some xterms. */
- if (
-# ifdef UNIX
- term_is_xterm
-# endif
- ) {
- hl = ScreenAttrs[off_to];
- if (hl > HL_ALL)
- hl = syn_attr2attr(hl);
- if (hl & HL_BOLD)
- redraw_next = TRUE;
- }
-#endif
ScreenAttrs[off_to] = ScreenAttrs[off_from];
/* For simplicity set the attributes of second half of a
* double-wide character equal to the first half. */
@@ -5456,24 +5326,6 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
if (need_redraw
|| force_redraw_this
) {
-#if defined(FEAT_GUI) || defined(UNIX)
- /* The bold trick makes a single row of pixels appear in the next
- * character. When a bold character is removed, the next
- * character should be redrawn too. This happens for our own GUI
- * and for some xterms. */
- if (need_redraw && ScreenLines[off] != ' ' && (
-# ifdef UNIX
- term_is_xterm
-# endif
- )) {
- int n = ScreenAttrs[off];
-
- if (n > HL_ALL)
- n = syn_attr2attr(n);
- if (n & HL_BOLD)
- force_redraw_next = TRUE;
- }
-#endif
/* When at the end of the text and overwriting a two-cell
* character with a one-cell character, need to clear the next
* cell. Also when overwriting the left halve of a two-cell char
@@ -5837,157 +5689,26 @@ next_search_hl_pos(
static void screen_start_highlight(int attr)
{
- attrentry_T *aep = NULL;
-
screen_attr = attr;
if (full_screen) {
- if (abstract_ui) {
- char buf[20];
- sprintf(buf, "\033|%dh", attr);
- OUT_STR(buf);
- } else {
- if (attr > HL_ALL) { /* special HL attr. */
- if (t_colors > 1)
- aep = syn_cterm_attr2entry(attr);
- else
- aep = syn_term_attr2entry(attr);
- if (aep == NULL) /* did ":syntax clear" */
- attr = 0;
- else
- attr = aep->ae_attr;
- }
- if ((attr & HL_BOLD) && T_MD != NULL) /* bold */
- out_str(T_MD);
- else if (aep != NULL && t_colors > 1 && aep->ae_u.cterm.fg_color
- && cterm_normal_fg_bold)
- /* If the Normal FG color has BOLD attribute and the new HL
- * has a FG color defined, clear BOLD. */
- out_str(T_ME);
- if ((attr & HL_STANDOUT) && T_SO != NULL) /* standout */
- out_str(T_SO);
- if ((attr & (HL_UNDERLINE | HL_UNDERCURL)) && T_US != NULL)
- /* underline or undercurl */
- out_str(T_US);
- if ((attr & HL_ITALIC) && T_CZH != NULL) /* italic */
- out_str(T_CZH);
- if ((attr & HL_INVERSE) && T_MR != NULL) /* inverse (reverse) */
- out_str(T_MR);
-
- /*
- * Output the color or start string after bold etc., in case the
- * bold etc. override the color setting.
- */
- if (aep != NULL) {
- if (t_colors > 1) {
- if (aep->ae_u.cterm.fg_color)
- term_fg_color(aep->ae_u.cterm.fg_color - 1);
- if (aep->ae_u.cterm.bg_color)
- term_bg_color(aep->ae_u.cterm.bg_color - 1);
- } else {
- if (aep->ae_u.term.start != NULL)
- out_str(aep->ae_u.term.start);
- }
- }
- }
+ char buf[20];
+ sprintf(buf, "\033|%dh", attr);
+ OUT_STR(buf);
}
}
void screen_stop_highlight(void)
{
- int do_ME = FALSE; /* output T_ME code */
-
if (screen_attr != 0) {
- if (abstract_ui) {
- // Handled in ui.c
- char buf[20];
- sprintf(buf, "\033|%dH", screen_attr);
- OUT_STR(buf);
- } else {
- if (screen_attr > HL_ALL) { /* special HL attr. */
- attrentry_T *aep;
-
- if (t_colors > 1) {
- /*
- * Assume that t_me restores the original colors!
- */
- aep = syn_cterm_attr2entry(screen_attr);
- if (aep != NULL && (aep->ae_u.cterm.fg_color
- || aep->ae_u.cterm.bg_color))
- do_ME = TRUE;
- } else {
- aep = syn_term_attr2entry(screen_attr);
- if (aep != NULL && aep->ae_u.term.stop != NULL) {
- if (STRCMP(aep->ae_u.term.stop, T_ME) == 0)
- do_ME = TRUE;
- else
- out_str(aep->ae_u.term.stop);
- }
- }
- if (aep == NULL) /* did ":syntax clear" */
- screen_attr = 0;
- else
- screen_attr = aep->ae_attr;
- }
-
- /*
- * Often all ending-codes are equal to T_ME. Avoid outputting the
- * same sequence several times.
- */
- if (screen_attr & HL_STANDOUT) {
- if (STRCMP(T_SE, T_ME) == 0)
- do_ME = TRUE;
- else
- out_str(T_SE);
- }
- if (screen_attr & (HL_UNDERLINE | HL_UNDERCURL)) {
- if (STRCMP(T_UE, T_ME) == 0)
- do_ME = TRUE;
- else
- out_str(T_UE);
- }
- if (screen_attr & HL_ITALIC) {
- if (STRCMP(T_CZR, T_ME) == 0)
- do_ME = TRUE;
- else
- out_str(T_CZR);
- }
- if (do_ME || (screen_attr & (HL_BOLD | HL_INVERSE)))
- out_str(T_ME);
-
- if (t_colors > 1) {
- /* set Normal cterm colors */
- if (cterm_normal_fg_color != 0)
- term_fg_color(cterm_normal_fg_color - 1);
- if (cterm_normal_bg_color != 0)
- term_bg_color(cterm_normal_bg_color - 1);
- if (cterm_normal_fg_bold)
- out_str(T_MD);
- }
- }
+ // Handled in ui.c
+ char buf[20];
+ sprintf(buf, "\033|%dH", screen_attr);
+ OUT_STR(buf);
}
screen_attr = 0;
}
/*
- * Reset the colors for a cterm. Used when leaving Vim.
- * The machine specific code may override this again.
- */
-void reset_cterm_colors(void)
-{
- if (!abstract_ui && t_colors > 1) {
- /* set Normal cterm colors */
- if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0) {
- out_str(T_OP);
- screen_attr = -1;
- }
- if (cterm_normal_fg_bold) {
- out_str(T_ME);
- screen_attr = -1;
- }
- }
-}
-
-/*
* Put character ScreenLines["off"] on the screen at position "row" and "col",
* using the attributes from ScreenAttrs["off"].
*/
@@ -6138,7 +5859,6 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
int end_off;
int did_delete;
int c;
- int norm_term;
#if defined(FEAT_GUI) || defined(UNIX)
int force_next = FALSE;
#endif
@@ -6153,7 +5873,6 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
return;
/* it's a "normal" terminal when not in a GUI or cterm */
- norm_term = (!abstract_ui && t_colors <= 1);
for (row = start_row; row < end_row; ++row) {
if (has_mbyte
) {
@@ -6174,11 +5893,7 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
did_delete = FALSE;
if (c2 == ' '
&& end_col == Columns
- && can_clear(T_CE)
- && (attr == 0
- || (norm_term
- && attr <= HL_ALL
- && ((attr & ~(HL_BOLD | HL_ITALIC)) == 0)))) {
+ && attr == 0) {
/*
* check if we really need to clear something
*/
@@ -6227,24 +5942,6 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
|| force_next
#endif
) {
-#if defined(FEAT_GUI) || defined(UNIX)
- /* The bold trick may make a single row of pixels appear in
- * the next character. When a bold character is removed, the
- * next character should be redrawn too. This happens for our
- * own GUI and for some xterms. */
- if (
-# ifdef UNIX
- term_is_xterm
-# endif
- ) {
- if (ScreenLines[off] != ' '
- && (ScreenAttrs[off] > HL_ALL
- || ScreenAttrs[off] & HL_BOLD))
- force_next = TRUE;
- else
- force_next = FALSE;
- }
-#endif
ScreenLines[off] = c;
if (enc_utf8) {
if (c >= 0x80) {
@@ -6584,10 +6281,6 @@ static void screenclear2(void)
return;
}
- if (!abstract_ui) {
- screen_attr = -1; /* force setting the Normal colors */
- }
-
screen_stop_highlight(); /* don't want highlighting here */
@@ -6597,17 +6290,9 @@ static void screenclear2(void)
LineWraps[i] = FALSE;
}
- if (can_clear(T_CL)) {
- out_str(T_CL); /* clear the display */
- clear_cmdline = FALSE;
- mode_displayed = FALSE;
- } else {
- /* can't clear the screen, mark all chars with invalid attributes */
- for (i = 0; i < Rows; ++i)
- lineinvalid(LineOffset[i], (int)Columns);
- clear_cmdline = TRUE;
- }
-
+ out_str(T_CL); /* clear the display */
+ clear_cmdline = FALSE;
+ mode_displayed = FALSE;
screen_cleared = TRUE; /* can use contents of ScreenLines now */
win_rest_invalid(firstwin);
@@ -6637,15 +6322,6 @@ static void lineclear(unsigned off, int width)
}
/*
- * Mark one line in ScreenLines invalid by setting the attributes to an
- * invalid value.
- */
-static void lineinvalid(unsigned off, int width)
-{
- (void)memset(ScreenAttrs + off, -1, (size_t)width * sizeof(sattr_T));
-}
-
-/*
* Copy part of a Screenline for vertically split window "wp".
*/
static void linecopy(int to, int from, win_T *wp)
@@ -6672,16 +6348,6 @@ static void linecopy(int to, int from, win_T *wp)
}
/*
- * Return TRUE if clearing with term string "p" would work.
- * It can't work when the string is empty or it won't set the right background.
- */
-int can_clear(char_u *p)
-{
- return abstract_ui || (*p != NUL && (t_colors <= 1
- || cterm_normal_bg_color == 0 || *T_UT != NUL));
-}
-
-/*
* Reset cursor position. Use whenever cursor was moved because of outputting
* something directly to the screen (shell commands) or a terminal control
* code.
@@ -7167,7 +6833,7 @@ screen_ins_lines (
int cursor_row;
int type;
int result_empty;
- int can_ce = can_clear(T_CE);
+ int can_ce = true;
/*
* FAIL if
@@ -7207,7 +6873,7 @@ screen_ins_lines (
result_empty = (row + line_count >= end);
if (wp != NULL && wp->w_width != Columns && *T_CSV == NUL)
type = USE_REDRAW;
- else if (can_clear(T_CD) && result_empty)
+ else if (result_empty)
type = USE_T_CD;
else if (*T_CAL != NUL && (line_count > 1 || *T_AL == NUL))
type = USE_T_CAL;
@@ -7260,10 +6926,7 @@ screen_ins_lines (
while ((j -= line_count) >= row)
linecopy(j + line_count, j, wp);
j += line_count;
- if (can_clear((char_u *)" "))
- lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
- else
- lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
+ lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
LineWraps[j] = FALSE;
} else {
j = end - 1 - i;
@@ -7274,10 +6937,7 @@ screen_ins_lines (
}
LineOffset[j + line_count] = temp;
LineWraps[j + line_count] = FALSE;
- if (can_clear((char_u *)" "))
- lineclear(temp, (int)Columns);
- else
- lineinvalid(temp, (int)Columns);
+ lineclear(temp, (int)Columns);
}
}
@@ -7364,7 +7024,7 @@ screen_del_lines (
* We can delete lines only when 'db' flag not set or when 'ce' option
* available.
*/
- can_delete = (*T_DB == NUL || can_clear(T_CE));
+ can_delete = true;
/*
* There are six ways to delete lines:
@@ -7380,7 +7040,7 @@ screen_del_lines (
*/
if (wp != NULL && wp->w_width != Columns && *T_CSV == NUL)
type = USE_REDRAW;
- else if (can_clear(T_CD) && result_empty)
+ else if (result_empty)
type = USE_T_CD;
else if (row == 0 && (
/* On the Amiga, somehow '\n' on the last line doesn't always scroll
@@ -7390,9 +7050,7 @@ screen_del_lines (
type = USE_NL;
else if (*T_CDL != NUL && line_count > 1 && can_delete)
type = USE_T_CDL;
- else if (can_clear(T_CE) && result_empty
- && (wp == NULL || wp->w_width == Columns)
- )
+ else if (result_empty && (wp == NULL || wp->w_width == Columns))
type = USE_T_CE;
else if (*T_DL != NUL && can_delete)
type = USE_T_DL;
@@ -7424,10 +7082,7 @@ screen_del_lines (
while ((j += line_count) <= end - 1)
linecopy(j - line_count, j, wp);
j -= line_count;
- if (can_clear((char_u *)" "))
- lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
- else
- lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
+ lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
LineWraps[j] = FALSE;
} else {
/* whole width, moving the line pointers is faster */
@@ -7439,10 +7094,7 @@ screen_del_lines (
}
LineOffset[j - line_count] = temp;
LineWraps[j - line_count] = FALSE;
- if (can_clear((char_u *)" "))
- lineclear(temp, (int)Columns);
- else
- lineinvalid(temp, (int)Columns);
+ lineclear(temp, (int)Columns);
}
}
@@ -8153,7 +7805,7 @@ int screen_screenrow(void)
* If 'mustset' is FALSE, we may try to get the real window size and if
* it fails use 'width' and 'height'.
*/
-void screen_resize(int width, int height, int mustset)
+void screen_resize(int width, int height)
{
static int busy = FALSE;
@@ -8182,24 +7834,15 @@ void screen_resize(int width, int height, int mustset)
++busy;
- // TODO(tarruda): "mustset" is still used in the old tests, which don't use
- // "abstract_ui" yet. This will change when a new TUI is merged.
- if (abstract_ui || mustset || (ui_get_shellsize() == FAIL && height != 0)) {
- Rows = height;
- Columns = width;
- }
+ Rows = height;
+ Columns = width;
check_shellsize();
height = Rows;
width = Columns;
-
- if (abstract_ui) {
- // Clear the output buffer to ensure UIs don't receive redraw command meant
- // for invalid screen sizes.
- out_buf_clear();
- ui_resize(width, height);
- } else {
- mch_set_shellsize();
- }
+ // Clear the output buffer to ensure UIs don't receive redraw command meant
+ // for invalid screen sizes.
+ out_buf_clear();
+ ui_resize(width, height);
/* The window layout used to be adjusted here, but it now happens in
* screenalloc() (also invoked from screenclear()). That is because the
diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c
index e5e29768af..46b8d47c00 100644
--- a/src/nvim/sha256.c
+++ b/src/nvim/sha256.c
@@ -351,40 +351,3 @@ bool sha256_self_test(void)
}
return failures == false;
}
-
-/// Fill "header[header_len]" with random_data.
-/// Also "salt[salt_len]" when "salt" is not NULL.
-///
-/// @param header
-/// @param header_len
-/// @param salt
-/// @param salt_len
-void sha2_seed(char_u *restrict header, size_t header_len,
- char_u *restrict salt, size_t salt_len)
-{
- static char_u random_data[1000];
- char_u sha256sum[SHA256_SUM_SIZE];
- context_sha256_T ctx;
-
- unsigned int seed = (unsigned int) os_hrtime();
-
- size_t i;
- for (i = 0; i < sizeof(random_data) - 1; i++) {
- random_data[i] = (char_u) ((os_hrtime() ^ (uint64_t)rand_r(&seed)) & 0xff);
- }
- sha256_start(&ctx);
- sha256_update(&ctx, random_data, sizeof(random_data));
- sha256_finish(&ctx, sha256sum);
-
- // put first block into header.
- for (i = 0; i < header_len; i++) {
- header[i] = sha256sum[i % sizeof(sha256sum)];
- }
-
- // put remaining block into salt.
- if (salt != NULL) {
- for (i = 0; i < salt_len; i++) {
- salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)];
- }
- }
-}
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 20fa35ed1c..2a0014c6c1 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -301,17 +301,6 @@ void del_trailing_spaces(char_u *ptr)
}
/*
- * Like strncpy(), but always terminate the result with one NUL.
- * "to" must be "len + 1" long!
- */
-void vim_strncpy(char_u *restrict to, const char_u *restrict from, size_t len)
- FUNC_ATTR_NONNULL_ALL
-{
- STRNCPY(to, from, len);
- to[len] = NUL;
-}
-
-/*
* Like strcat(), but make sure the result fits in "tosize" bytes and is
* always NUL terminated.
*/
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index c88088f25f..744a6c68fd 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -49,40 +49,32 @@
#include "nvim/os/os.h"
#include "nvim/os/time.h"
-/*
- * Structure that stores information about a highlight group.
- * The ID of a highlight group is also called group ID. It is the index in
- * the highlight_ga array PLUS ONE.
- */
+// Structure that stores information about a highlight group.
+// The ID of a highlight group is also called group ID. It is the index in
+// the highlight_ga array PLUS ONE.
struct hl_group {
- char_u *sg_name; /* highlight group name */
- char_u *sg_name_u; /* uppercase of sg_name */
- /* for normal terminals */
- int sg_term; /* "term=" highlighting attributes */
- char_u *sg_start; /* terminal string for start highl */
- char_u *sg_stop; /* terminal string for stop highl */
- int sg_term_attr; /* Screen attr for term mode */
- /* for color terminals */
- int sg_cterm; /* "cterm=" highlighting attr */
- int sg_cterm_bold; /* bold attr was set for light color */
- int sg_cterm_fg; /* terminal fg color number + 1 */
- int sg_cterm_bg; /* terminal bg color number + 1 */
- int sg_cterm_attr; /* Screen attr for color term mode */
- /* Store the sp color name for the GUI or synIDattr() */
- int sg_gui; /* "gui=" highlighting attributes */
+ char_u *sg_name; // highlight group name
+ char_u *sg_name_u; // uppercase of sg_name
+ int sg_attr; // Screen attr
+ int sg_link; // link to this highlight group ID
+ int sg_set; // combination of SG_* flags
+ scid_T sg_scriptID; // script in which the group was last set
+ // for terminal UIs
+ int sg_cterm; // "cterm=" highlighting attr
+ int sg_cterm_fg; // terminal fg color number + 1
+ int sg_cterm_bg; // terminal bg color number + 1
+ int sg_cterm_bold; // bold attr was set for light color
+ // for RGB UIs
+ int sg_gui; // "gui=" highlighting attributes
RgbValue sg_rgb_fg; // RGB foreground color
RgbValue sg_rgb_bg; // RGB background color
uint8_t *sg_rgb_fg_name; // RGB foreground color name
uint8_t *sg_rgb_bg_name; // RGB background color name
- int sg_link; /* link to this highlight group ID */
- int sg_set; /* combination of SG_* flags */
- scid_T sg_scriptID; /* script in which the group was last set */
};
-#define SG_TERM 1 /* term has been set */
-#define SG_CTERM 2 /* cterm has been set */
-#define SG_GUI 4 /* gui has been set */
-#define SG_LINK 8 /* link has been set */
+#define SG_CTERM 2 // cterm has been set
+#define SG_GUI 4 // gui has been set
+#define SG_LINK 8 // link has been set
// highlight groups for 'highlight' option
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
@@ -221,7 +213,7 @@ struct name_list {
/*
* An attribute number is the index in attr_table plus ATTR_OFF.
*/
-#define ATTR_OFF (HL_ALL + 1)
+#define ATTR_OFF 1
static char *(spo_name_tab[SPO_COUNT]) =
@@ -6054,7 +6046,6 @@ do_highlight (
)
{
char_u *name_end;
- char_u *p;
char_u *linep;
char_u *key_start;
char_u *arg_start;
@@ -6242,7 +6233,7 @@ do_highlight (
if (STRCMP(key, "NONE") == 0) {
if (!init || HL_TABLE()[idx].sg_set == 0) {
if (!init)
- HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI;
+ HL_TABLE()[idx].sg_set |= SG_CTERM+SG_GUI;
highlight_clear(idx);
}
continue;
@@ -6312,20 +6303,14 @@ do_highlight (
}
if (error)
break;
- if (*key == 'T') {
- if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM)) {
- if (!init)
- HL_TABLE()[idx].sg_set |= SG_TERM;
- HL_TABLE()[idx].sg_term = attr;
- }
- } else if (*key == 'C') {
+ if (*key == 'C') {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
if (!init)
HL_TABLE()[idx].sg_set |= SG_CTERM;
HL_TABLE()[idx].sg_cterm = attr;
HL_TABLE()[idx].sg_cterm_bold = FALSE;
}
- } else {
+ } else if (*key == 'G') {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
if (!init)
HL_TABLE()[idx].sg_set |= SG_GUI;
@@ -6438,27 +6423,17 @@ do_highlight (
}
color &= 7; /* truncate to 8 colors */
} else if (t_colors == 16 || t_colors == 88 || t_colors == 256) {
- /*
- * Guess: if the termcap entry ends in 'm', it is
- * probably an xterm-like terminal. Use the changed
- * order for colors.
- */
- if (*T_CAF != NUL)
- p = T_CAF;
- else
- p = T_CSF;
- if (abstract_ui || (*p != NUL && *(p + STRLEN(p) - 1) == 'm'))
- switch (t_colors) {
- case 16:
- color = color_numbers_8[i];
- break;
- case 88:
- color = color_numbers_88[i];
- break;
- case 256:
- color = color_numbers_256[i];
- break;
- }
+ switch (t_colors) {
+ case 16:
+ color = color_numbers_8[i];
+ break;
+ case 88:
+ color = color_numbers_88[i];
+ break;
+ case 256:
+ color = color_numbers_256[i];
+ break;
+ }
}
}
}
@@ -6471,8 +6446,6 @@ do_highlight (
cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD);
{
must_redraw = CLEAR;
- if (termcap_active && color >= 0)
- term_fg_color(color);
}
}
} else {
@@ -6482,8 +6455,6 @@ do_highlight (
{
must_redraw = CLEAR;
if (color >= 0) {
- if (termcap_active)
- term_bg_color(color);
if (t_colors < 16)
i = (color == 0 || color == 4);
else
@@ -6536,73 +6507,9 @@ do_highlight (
normal_bg = HL_TABLE()[idx].sg_rgb_bg;
}
} else if (STRCMP(key, "GUISP") == 0) {
- // Ignored
+ // Ignored for now
} else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) {
- char_u buf[100];
- char_u *tname;
-
- if (!init)
- HL_TABLE()[idx].sg_set |= SG_TERM;
-
- /*
- * The "start" and "stop" arguments can be a literal escape
- * sequence, or a comma separated list of terminal codes.
- */
- if (STRNCMP(arg, "t_", 2) == 0) {
- off = 0;
- buf[0] = 0;
- while (arg[off] != NUL) {
- /* Isolate one termcap name */
- for (len = 0; arg[off + len] &&
- arg[off + len] != ','; ++len)
- ;
- tname = vim_strnsave(arg + off, len);
- /* lookup the escape sequence for the item */
- p = get_term_code(tname);
- free(tname);
- if (p == NULL) /* ignore non-existing things */
- p = (char_u *)"";
-
- /* Append it to the already found stuff */
- if ((int)(STRLEN(buf) + STRLEN(p)) >= 99) {
- EMSG2(_("E422: terminal code too long: %s"), arg);
- error = TRUE;
- break;
- }
- STRCAT(buf, p);
-
- /* Advance to the next item */
- off += len;
- if (arg[off] == ',') /* another one follows */
- ++off;
- }
- } else {
- /*
- * Copy characters from arg[] to buf[], translating <> codes.
- */
- for (p = arg, off = 0; off < 100 - 6 && *p; ) {
- len = (int)trans_special(&p, buf + off, FALSE);
- if (len > 0) /* recognized special char */
- off += len;
- else /* copy as normal char */
- buf[off++] = *p++;
- }
- buf[off] = NUL;
- }
- if (error)
- break;
-
- if (STRCMP(buf, "NONE") == 0) /* resetting the value */
- p = NULL;
- else
- p = vim_strsave(buf);
- if (key[2] == 'A') {
- free(HL_TABLE()[idx].sg_start);
- HL_TABLE()[idx].sg_start = p;
- } else {
- free(HL_TABLE()[idx].sg_stop);
- HL_TABLE()[idx].sg_stop = p;
- }
+ // Ignored for now
} else {
EMSG2(_("E423: Illegal argument: %s"), key_start);
error = TRUE;
@@ -6628,12 +6535,9 @@ do_highlight (
syn_unadd_group();
else {
if (is_normal_group) {
- HL_TABLE()[idx].sg_term_attr = 0;
- HL_TABLE()[idx].sg_cterm_attr = 0;
- if (abstract_ui) {
- // If the normal group has changed, it is simpler to refresh every UI
- ui_refresh();
- }
+ HL_TABLE()[idx].sg_attr = 0;
+ // If the normal group has changed, it is simpler to refresh every UI
+ ui_refresh();
} else
set_hl_attr(idx);
HL_TABLE()[idx].sg_scriptID = current_SID;
@@ -6678,10 +6582,11 @@ void restore_cterm_colors(void)
*/
static int hl_has_settings(int idx, int check_link)
{
- return HL_TABLE()[idx].sg_term_attr != 0
- || HL_TABLE()[idx].sg_cterm_attr != 0
+ return HL_TABLE()[idx].sg_attr != 0
|| HL_TABLE()[idx].sg_cterm_fg != 0
|| HL_TABLE()[idx].sg_cterm_bg != 0
+ || HL_TABLE()[idx].sg_rgb_fg_name != NULL
+ || HL_TABLE()[idx].sg_rgb_bg_name != NULL
|| (check_link && (HL_TABLE()[idx].sg_set & SG_LINK));
}
@@ -6690,17 +6595,11 @@ static int hl_has_settings(int idx, int check_link)
*/
static void highlight_clear(int idx)
{
- HL_TABLE()[idx].sg_term = 0;
- free(HL_TABLE()[idx].sg_start);
- HL_TABLE()[idx].sg_start = NULL;
- free(HL_TABLE()[idx].sg_stop);
- HL_TABLE()[idx].sg_stop = NULL;
- HL_TABLE()[idx].sg_term_attr = 0;
+ HL_TABLE()[idx].sg_attr = 0;
HL_TABLE()[idx].sg_cterm = 0;
HL_TABLE()[idx].sg_cterm_bold = FALSE;
HL_TABLE()[idx].sg_cterm_fg = 0;
HL_TABLE()[idx].sg_cterm_bg = 0;
- HL_TABLE()[idx].sg_cterm_attr = 0;
HL_TABLE()[idx].sg_gui = 0;
HL_TABLE()[idx].sg_rgb_fg = -1;
HL_TABLE()[idx].sg_rgb_bg = -1;
@@ -6720,23 +6619,20 @@ static void highlight_clear(int idx)
* Note that this table is used by ALL buffers. This is required because the
* GUI can redraw at any time for any buffer.
*/
-static garray_T term_attr_table = GA_EMPTY_INIT_VALUE;
-
-#define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx]
-
-static garray_T cterm_attr_table = GA_EMPTY_INIT_VALUE;
+static garray_T attr_table = GA_EMPTY_INIT_VALUE;
-#define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_attr_table.ga_data)[idx]
+#define ATTR_ENTRY(idx) ((attrentry_T *)attr_table.ga_data)[idx]
/*
* Return the attr number for a set of colors and font.
- * Add a new entry to the term_attr_table, cterm_attr_table or gui_attr_table
+ * Add a new entry to the term_attr_table, attr_table or gui_attr_table
* if the combination is new.
* Return 0 for error.
*/
-static int get_attr_entry(garray_T *table, attrentry_T *aep)
+static int get_attr_entry(attrentry_T *aep)
{
+ garray_T *table = &attr_table;
attrentry_T *taep;
static int recursive = FALSE;
@@ -6751,31 +6647,14 @@ static int get_attr_entry(garray_T *table, attrentry_T *aep)
*/
for (int i = 0; i < table->ga_len; ++i) {
taep = &(((attrentry_T *)table->ga_data)[i]);
- if ( aep->ae_attr == taep->ae_attr
- && (
- (table == &term_attr_table
- && (aep->ae_u.term.start == NULL)
- == (taep->ae_u.term.start == NULL)
- && (aep->ae_u.term.start == NULL
- || STRCMP(aep->ae_u.term.start,
- taep->ae_u.term.start) == 0)
- && (aep->ae_u.term.stop == NULL)
- == (taep->ae_u.term.stop == NULL)
- && (aep->ae_u.term.stop == NULL
- || STRCMP(aep->ae_u.term.stop,
- taep->ae_u.term.stop) == 0))
- || (table == &cterm_attr_table
- && aep->ae_u.cterm.fg_color
- == taep->ae_u.cterm.fg_color
- && aep->ae_u.cterm.bg_color
- == taep->ae_u.cterm.bg_color
- && aep->fg_color
- == taep->fg_color
- && aep->bg_color
- == taep->bg_color)
- ))
-
+ if (aep->cterm_ae_attr == taep->cterm_ae_attr
+ && aep->cterm_fg_color == taep->cterm_fg_color
+ && aep->cterm_bg_color == taep->cterm_bg_color
+ && aep->rgb_ae_attr == taep->rgb_ae_attr
+ && aep->rgb_fg_color == taep->rgb_fg_color
+ && aep->rgb_bg_color == taep->rgb_bg_color) {
return i + ATTR_OFF;
+ }
}
if (table->ga_len + ATTR_OFF > MAX_TYPENR) {
@@ -6801,156 +6680,83 @@ static int get_attr_entry(garray_T *table, attrentry_T *aep)
recursive = FALSE;
}
- /*
- * This is a new combination of colors and font, add an entry.
- */
+
+ // This is a new combination of colors and font, add an entry.
taep = GA_APPEND_VIA_PTR(attrentry_T, table);
memset(taep, 0, sizeof(*taep));
- taep->ae_attr = aep->ae_attr;
- if (table == &term_attr_table) {
- if (aep->ae_u.term.start == NULL)
- taep->ae_u.term.start = NULL;
- else
- taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start);
- if (aep->ae_u.term.stop == NULL)
- taep->ae_u.term.stop = NULL;
- else
- taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop);
- } else if (table == &cterm_attr_table) {
- taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color;
- taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color;
- taep->fg_color = aep->fg_color;
- taep->bg_color = aep->bg_color;
- }
+ taep->cterm_ae_attr = aep->cterm_ae_attr;
+ taep->cterm_fg_color = aep->cterm_fg_color;
+ taep->cterm_bg_color = aep->cterm_bg_color;
+ taep->rgb_ae_attr = aep->rgb_ae_attr;
+ taep->rgb_fg_color = aep->rgb_fg_color;
+ taep->rgb_bg_color = aep->rgb_bg_color;
return table->ga_len - 1 + ATTR_OFF;
}
-/*
- * Clear all highlight tables.
- */
+// Clear all highlight tables.
void clear_hl_tables(void)
{
- attrentry_T *taep;
-
- for (int i = 0; i < term_attr_table.ga_len; ++i) {
- taep = &(((attrentry_T *)term_attr_table.ga_data)[i]);
- free(taep->ae_u.term.start);
- free(taep->ae_u.term.stop);
- }
- ga_clear(&term_attr_table);
- ga_clear(&cterm_attr_table);
+ ga_clear(&attr_table);
}
-/*
- * Combine special attributes (e.g., for spelling) with other attributes
- * (e.g., for syntax highlighting).
- * "prim_attr" overrules "char_attr".
- * This creates a new group when required.
- * Since we expect there to be few spelling mistakes we don't cache the
- * result.
- * Return the resulting attributes.
- */
+// Combine special attributes (e.g., for spelling) with other attributes
+// (e.g., for syntax highlighting).
+// "prim_attr" overrules "char_attr".
+// This creates a new group when required.
+// Since we expect there to be few spelling mistakes we don't cache the
+// result.
+// Return the resulting attributes.
int hl_combine_attr(int char_attr, int prim_attr)
{
attrentry_T *char_aep = NULL;
attrentry_T *spell_aep;
attrentry_T new_en;
- if (char_attr == 0)
+ if (char_attr == 0) {
return prim_attr;
- if (char_attr <= HL_ALL && prim_attr <= HL_ALL)
- return char_attr | prim_attr;
-
- if (abstract_ui || t_colors > 1) {
- if (char_attr > HL_ALL)
- char_aep = syn_cterm_attr2entry(char_attr);
- if (char_aep != NULL)
- new_en = *char_aep;
- else {
- memset(&new_en, 0, sizeof(new_en));
- if (char_attr <= HL_ALL)
- new_en.ae_attr = char_attr;
- }
-
- if (prim_attr <= HL_ALL)
- new_en.ae_attr |= prim_attr;
- else {
- spell_aep = syn_cterm_attr2entry(prim_attr);
- if (spell_aep != NULL) {
- new_en.ae_attr |= spell_aep->ae_attr;
- if (spell_aep->ae_u.cterm.fg_color > 0)
- new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color;
- if (spell_aep->ae_u.cterm.bg_color > 0)
- new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color;
- if (spell_aep->fg_color >= 0)
- new_en.fg_color = spell_aep->fg_color;
- if (spell_aep->bg_color >= 0)
- new_en.bg_color = spell_aep->bg_color;
- }
- }
- return get_attr_entry(&cterm_attr_table, &new_en);
}
- if (char_attr > HL_ALL)
- char_aep = syn_term_attr2entry(char_attr);
- if (char_aep != NULL)
+ // Find the entry for char_attr
+ char_aep = syn_cterm_attr2entry(char_attr);
+
+ if (char_aep != NULL) {
+ // Copy all attributes from char_aep to the new entry
new_en = *char_aep;
- else {
+ } else {
memset(&new_en, 0, sizeof(new_en));
- if (char_attr <= HL_ALL)
- new_en.ae_attr = char_attr;
}
- if (prim_attr <= HL_ALL)
- new_en.ae_attr |= prim_attr;
- else {
- spell_aep = syn_term_attr2entry(prim_attr);
- if (spell_aep != NULL) {
- new_en.ae_attr |= spell_aep->ae_attr;
- if (spell_aep->ae_u.term.start != NULL) {
- new_en.ae_u.term.start = spell_aep->ae_u.term.start;
- new_en.ae_u.term.stop = spell_aep->ae_u.term.stop;
- }
- }
- }
- return get_attr_entry(&term_attr_table, &new_en);
-}
-
-
-/*
- * Get the highlight attributes (HL_BOLD etc.) from an attribute nr.
- * Only to be used when "attr" > HL_ALL.
- */
-int syn_attr2attr(int attr)
-{
- attrentry_T *aep;
+ spell_aep = syn_cterm_attr2entry(prim_attr);
+ if (spell_aep != NULL) {
+ new_en.cterm_ae_attr |= spell_aep->cterm_ae_attr;
+ new_en.rgb_ae_attr |= spell_aep->rgb_ae_attr;
- if (abstract_ui || t_colors > 1)
- aep = syn_cterm_attr2entry(attr);
- else
- aep = syn_term_attr2entry(attr);
+ if (spell_aep->cterm_fg_color > 0) {
+ new_en.cterm_fg_color = spell_aep->cterm_fg_color;
+ }
- if (aep == NULL) /* highlighting not set */
- return 0;
- return aep->ae_attr;
-}
+ if (spell_aep->cterm_bg_color > 0) {
+ new_en.cterm_bg_color = spell_aep->cterm_bg_color;
+ }
+ if (spell_aep->rgb_fg_color >= 0) {
+ new_en.rgb_fg_color = spell_aep->rgb_fg_color;
+ }
-attrentry_T *syn_term_attr2entry(int attr)
-{
- attr -= ATTR_OFF;
- if (attr >= term_attr_table.ga_len) /* did ":syntax clear" */
- return NULL;
- return &(TERM_ATTR_ENTRY(attr));
+ if (spell_aep->rgb_bg_color >= 0) {
+ new_en.rgb_bg_color = spell_aep->rgb_bg_color;
+ }
+ }
+ return get_attr_entry(&new_en);
}
attrentry_T *syn_cterm_attr2entry(int attr)
{
attr -= ATTR_OFF;
- if (attr >= cterm_attr_table.ga_len) /* did ":syntax clear" */
+ if (attr >= attr_table.ga_len) /* did ":syntax clear" */
return NULL;
- return &(CTERM_ATTR_ENTRY(attr));
+ return &(ATTR_ENTRY(attr));
}
#define LIST_ATTR 1
@@ -6965,13 +6771,6 @@ static void highlight_list_one(int id)
sgp = &HL_TABLE()[id - 1]; /* index is ID minus one */
didh = highlight_list_arg(id, didh, LIST_ATTR,
- sgp->sg_term, NULL, "term");
- didh = highlight_list_arg(id, didh, LIST_STRING,
- 0, sgp->sg_start, "start");
- didh = highlight_list_arg(id, didh, LIST_STRING,
- 0, sgp->sg_stop, "stop");
-
- didh = highlight_list_arg(id, didh, LIST_ATTR,
sgp->sg_cterm, NULL, "cterm");
didh = highlight_list_arg(id, didh, LIST_INT,
sgp->sg_cterm_fg, NULL, "ctermfg");
@@ -7049,7 +6848,7 @@ char_u *
highlight_has_attr (
int id,
int flag,
- int modec /* 'g' for GUI, 'c' for cterm, 't' for term */
+ int modec // 'g' for GUI, 'c' for cterm
)
{
int attr;
@@ -7057,12 +6856,11 @@ highlight_has_attr (
if (id <= 0 || id > highlight_ga.ga_len)
return NULL;
- if (modec == 'g')
+ if (modec == 'g') {
attr = HL_TABLE()[id - 1].sg_gui;
- else if (modec == 'c')
+ } else {
attr = HL_TABLE()[id - 1].sg_cterm;
- else
- attr = HL_TABLE()[id - 1].sg_term;
+ }
if (attr & flag)
return (char_u *)"1";
@@ -7179,37 +6977,16 @@ set_hl_attr (
if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0)
return;
- /*
- * For the term mode: If there are other than "normal" highlighting
- * attributes, need to allocate an attr number.
- */
- if (sgp->sg_start == NULL && sgp->sg_stop == NULL)
- sgp->sg_term_attr = sgp->sg_term;
- else {
- at_en.ae_attr = sgp->sg_term;
- at_en.ae_u.term.start = sgp->sg_start;
- at_en.ae_u.term.stop = sgp->sg_stop;
- sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en);
- }
-
- /*
- * For the color term mode: If there are other than "normal"
- * highlighting attributes, need to allocate an attr number.
- */
- if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0
- && sgp->sg_rgb_fg == -1 && sgp->sg_rgb_bg == -1) {
- sgp->sg_cterm_attr = sgp->sg_cterm;
- } else {
- at_en.ae_attr = abstract_ui ? sgp->sg_gui : sgp->sg_cterm;
- at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg;
- at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg;
- // FIXME(tarruda): The "unset value" for rgb is -1, but since hlgroup is
- // initialized with 0(by garray functions), check for sg_rgb_{f,b}g_name
- // before setting attr_entry->{f,g}g_color to a other than -1
- at_en.fg_color = sgp->sg_rgb_fg_name ? sgp->sg_rgb_fg : -1;
- at_en.bg_color = sgp->sg_rgb_bg_name ? sgp->sg_rgb_bg : -1;
- sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en);
- }
+ at_en.cterm_ae_attr = sgp->sg_cterm;
+ at_en.cterm_fg_color = sgp->sg_cterm_fg;
+ at_en.cterm_bg_color = sgp->sg_cterm_bg;
+ at_en.rgb_ae_attr = sgp->sg_gui;
+ // FIXME(tarruda): The "unset value" for rgb is -1, but since hlgroup is
+ // initialized with 0(by garray functions), check for sg_rgb_{f,b}g_name
+ // before setting attr_entry->{f,g}g_color to a other than -1
+ at_en.rgb_fg_color = sgp->sg_rgb_fg_name ? sgp->sg_rgb_fg : -1;
+ at_en.rgb_bg_color = sgp->sg_rgb_bg_name ? sgp->sg_rgb_bg : -1;
+ sgp->sg_attr = get_attr_entry(&at_en);
}
/*
@@ -7348,18 +7125,11 @@ static void syn_unadd_group(void)
*/
int syn_id2attr(int hl_id)
{
- int attr;
struct hl_group *sgp;
hl_id = syn_get_final_id(hl_id);
sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */
-
- if (abstract_ui || t_colors > 1)
- attr = sgp->sg_cterm_attr;
- else
- attr = sgp->sg_term_attr;
-
- return attr;
+ return sgp->sg_attr;
}
@@ -7446,11 +7216,12 @@ int highlight_changed(void)
* bold-underlined.
*/
attr = 0;
+ bool colon = false;
for (; *p && *p != ','; ++p) { /* parse upto comma */
if (vim_iswhite(*p)) /* ignore white space */
continue;
- if (attr > HL_ALL) /* Combination with ':' is not allowed. */
+ if (colon) /* Combination with ':' is not allowed. */
return FAIL;
switch (*p) {
@@ -7472,6 +7243,7 @@ int highlight_changed(void)
case ':': ++p; /* highlight group name */
if (attr || *p == NUL) /* no combinations */
return FAIL;
+ colon = true;
end = vim_strchr(p, ',');
if (end == NULL)
end = p + STRLEN(p);
@@ -7506,7 +7278,6 @@ int highlight_changed(void)
hlcnt = highlight_ga.ga_len;
if (id_S == 0) { /* Make sure id_S is always valid to simplify code below */
memset(&HL_TABLE()[hlcnt + 9], 0, sizeof(struct hl_group));
- HL_TABLE()[hlcnt + 9].sg_term = highlight_attr[HLF_S];
id_S = hlcnt + 10;
}
for (int i = 0; i < 9; i++) {
@@ -7521,7 +7292,6 @@ int highlight_changed(void)
highlight_user[i] = syn_id2attr(id);
if (id_SNC == 0) {
memset(&hlt[hlcnt + i], 0, sizeof(struct hl_group));
- hlt[hlcnt + i].sg_term = highlight_attr[HLF_SNC];
hlt[hlcnt + i].sg_cterm = highlight_attr[HLF_SNC];
hlt[hlcnt + i].sg_gui = highlight_attr[HLF_SNC];
} else
@@ -7531,20 +7301,26 @@ int highlight_changed(void)
hlt[hlcnt + i].sg_link = 0;
/* Apply difference between UserX and HLF_S to HLF_SNC */
- hlt[hlcnt + i].sg_term ^=
- hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term;
- if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start)
- hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start;
- if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop)
- hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop;
- hlt[hlcnt + i].sg_cterm ^=
- hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm;
- if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg)
+ hlt[hlcnt + i].sg_cterm ^= hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm;
+
+ if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg) {
hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg;
- if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg)
+ }
+
+ if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg) {
hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg;
- hlt[hlcnt + i].sg_gui ^=
- hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui;
+ }
+
+ hlt[hlcnt + i].sg_gui ^= hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui;
+
+ if (hlt[id - 1].sg_rgb_fg != hlt[id_S - 1].sg_rgb_fg) {
+ hlt[hlcnt + i].sg_rgb_fg = hlt[id - 1].sg_rgb_fg;
+ }
+
+ if (hlt[id - 1].sg_rgb_bg != hlt[id_S - 1].sg_rgb_bg) {
+ hlt[hlcnt + i].sg_rgb_bg = hlt[id - 1].sg_rgb_bg;
+ }
+
highlight_ga.ga_len = hlcnt + i + 1;
set_hl_attr(hlcnt + i); /* At long last we can apply */
highlight_stlnc[i] = syn_id2attr(hlcnt + i + 1);
diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h
index 93088180b9..af2ac719c6 100644
--- a/src/nvim/syntax.h
+++ b/src/nvim/syntax.h
@@ -16,7 +16,6 @@
#define HL_UNDERLINE 0x08
#define HL_UNDERCURL 0x10
#define HL_STANDOUT 0x20
-#define HL_ALL 0x3f
#define HL_CONTAINED 0x01 /* not used on toplevel */
#define HL_TRANSP 0x02 /* has no highlighting */
diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h
index abf7ea5a7d..67cf672ef2 100644
--- a/src/nvim/syntax_defs.h
+++ b/src/nvim/syntax_defs.h
@@ -67,23 +67,11 @@ struct syn_state {
* may have made the state invalid */
};
-/*
- * Structure shared between syntax.c, screen.c and gui_x11.c.
- */
+// Structure shared between syntax.c, screen.c
typedef struct attr_entry {
- short ae_attr; /* HL_BOLD, etc. */
- RgbValue fg_color, bg_color;
- union {
- struct {
- char_u *start; /* start escape sequence */
- char_u *stop; /* stop escape sequence */
- } term;
- struct {
- /* These colors need to be > 8 bits to hold 256. */
- uint16_t fg_color; /* foreground color number */
- uint16_t bg_color; /* background color number */
- } cterm;
- } ae_u;
+ short rgb_ae_attr, cterm_ae_attr; // HL_BOLD, etc.
+ RgbValue rgb_fg_color, rgb_bg_color;
+ int cterm_fg_color, cterm_bg_color;
} attrentry_T;
#endif // NVIM_SYNTAX_DEFS_H
diff --git a/src/nvim/term.c b/src/nvim/term.c
index 14c087cb60..fa85860cb0 100644
--- a/src/nvim/term.c
+++ b/src/nvim/term.c
@@ -58,20 +58,6 @@
#include "nvim/os/time.h"
#include "nvim/os/input.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().
- */
-# define TPUTSFUNCAST (int (*)(int))
-#endif
#undef tgetstr
@@ -101,62 +87,7 @@ struct builtin_term {
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "term.c.generated.h"
#endif
-#if defined(FEAT_GUI) \
- || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM) \
- || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)))
-static int get_bytes_from_buf(char_u *, char_u *, int);
-#endif
-
-#ifdef HAVE_TGETENT
-static char_u *tgetent_error(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(char *, char **);
-
-/* Change this to "if 1" to debug what happens with termresponse. */
-# define LOG_TR(msg)
-/* Request Terminal Version status: */
-# define CRV_GET 1 /* send T_CRV when switched to RAW mode */
-# define CRV_SENT 2 /* did send T_CRV, waiting for answer */
-# define CRV_GOT 3 /* received T_CRV response */
-static int crv_status = CRV_GET;
-/* Request Cursor position report: */
-# define U7_GET 1 /* send T_U7 when switched to RAW mode */
-# define U7_SENT 2 /* did send T_U7, waiting for answer */
-# define U7_GOT 3 /* received T_U7 response */
-static int u7_status = U7_GET;
-/*
- * 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) vim_tgetstr((s), (p))
-# define TGETENT(b, t) tgetent((char *)(b), (char *)(t))
-#endif /* HAVE_TGETENT */
-
-static int xt_index_in = 0;
-static int xt_index_out = 0;
static bool detected_8bit = false; // detected 8-bit terminal
@@ -190,771 +121,6 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_CM, "\033|%p1%d;%p2%dM"},
// there are no key sequences here, for "abstract_ui" vim key codes are
// parsed directly in input_enqueue()
-
-
-#ifndef NO_BUILTIN_TCAPS
-
-# if 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_UT, "y"}, /* guessed */
- {(int)KS_LE, "\b"},
-# 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(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS)
- /*
- * 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_UT, "y"}, /* guessed */
- {(int)KS_LE, "\b"},
-# 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(ALL_BUILTIN_TCAPS)
- /*
- * 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 os_inchar(), because we cannot handle NULs in key codes.
- * CTRL-arrow is used instead of SHIFT-arrow.
- */
- {(int)KS_NAME, "pcansi"},
- {(int)KS_DL, "\033[M"},
- {(int)KS_AL, "\033[L"},
- {(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_UT, "y"}, /* guessed */
- {(int)KS_LE, "\b"},
-# 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
-
-
-# if defined(WIN3264) || defined(ALL_BUILTIN_TCAPS)
- /*
- * These codes are valid for the Win32 Console . The entries that start with
- * ESC | are translated into console calls in os_win32.c. The function keys
- * are also translated in os_win32.c.
- */
- {(int)KS_NAME, "win32"},
- {(int)KS_CE, "\033|K"}, /* clear to end of line */
- {(int)KS_AL, "\033|L"}, /* add new blank line */
-# ifdef TERMINFO
- {(int)KS_CAL, "\033|%p1%dL"}, /* add number of new blank lines */
-# else
- {(int)KS_CAL, "\033|%dL"}, /* add number of new blank lines */
-# endif
- {(int)KS_DL, "\033|M"}, /* delete line */
-# ifdef TERMINFO
- {(int)KS_CDL, "\033|%p1%dM"}, /* delete number of lines */
-# else
- {(int)KS_CDL, "\033|%dM"}, /* delete number of lines */
-# endif
- {(int)KS_CL, "\033|J"}, /* clear screen */
- {(int)KS_CD, "\033|j"}, /* clear to end of display */
- {(int)KS_VI, "\033|v"}, /* cursor invisible */
- {(int)KS_VE, "\033|V"}, /* cursor visible */
-
- {(int)KS_ME, "\033|0m"}, /* normal */
- {(int)KS_MR, "\033|112m"}, /* reverse: black on lightgray */
- {(int)KS_MD, "\033|15m"}, /* bold: white on black */
- {(int)KS_SO, "\033|31m"}, /* standout: white on blue */
- {(int)KS_SE, "\033|0m"}, /* standout end */
- {(int)KS_CZH, "\033|225m"}, /* italic: blue text on yellow */
- {(int)KS_CZR, "\033|0m"}, /* italic end */
- {(int)KS_US, "\033|67m"}, /* underscore: cyan text on red */
- {(int)KS_UE, "\033|0m"}, /* underscore end */
- {(int)KS_CCO, "16"}, /* allow 16 colors */
-# ifdef TERMINFO
- {(int)KS_CAB, "\033|%p1%db"}, /* set background color */
- {(int)KS_CAF, "\033|%p1%df"}, /* set foreground color */
-# else
- {(int)KS_CAB, "\033|%db"}, /* set background color */
- {(int)KS_CAF, "\033|%df"}, /* set foreground color */
-# endif
-
- {(int)KS_MS, "y"}, /* save to move cur in reverse mode */
- {(int)KS_UT, "y"},
- {(int)KS_LE, "\b"},
-# ifdef TERMINFO
- {(int)KS_CM, "\033|%i%p1%d;%p2%dH"}, /* cursor motion */
-# else
- {(int)KS_CM, "\033|%i%d;%dH"}, /* cursor motion */
-# endif
- {(int)KS_VB, "\033|B"}, /* visual bell */
- {(int)KS_TI, "\033|S"}, /* put terminal in termcap mode */
- {(int)KS_TE, "\033|E"}, /* out of termcap mode */
-# ifdef TERMINFO
- {(int)KS_CS, "\033|%i%p1%d;%p2%dr"}, /* scroll region */
-# else
- {(int)KS_CS, "\033|%i%d;%dr"}, /* scroll region */
-# endif
-
- {K_UP, "\316H"},
- {K_DOWN, "\316P"},
- {K_LEFT, "\316K"},
- {K_RIGHT, "\316M"},
- {K_S_UP, "\316\304"},
- {K_S_DOWN, "\316\317"},
- {K_S_LEFT, "\316\311"},
- {K_C_LEFT, "\316s"},
- {K_S_RIGHT, "\316\313"},
- {K_C_RIGHT, "\316t"},
- {K_S_TAB, "\316\017"},
- {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"},
- {K_F12, "\316\206"},
- {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"},
- {K_S_F12, "\316\210"},
- {K_INS, "\316R"},
- {K_DEL, "\316S"},
- {K_HOME, "\316G"},
- {K_S_HOME, "\316\302"},
- {K_C_HOME, "\316w"},
- {K_END, "\316O"},
- {K_S_END, "\316\315"},
- {K_C_END, "\316u"},
- {K_PAGEDOWN, "\316Q"},
- {K_PAGEUP, "\316I"},
- {K_KPLUS, "\316N"},
- {K_KMINUS, "\316J"},
- {K_KMULTIPLY, "\316\067"},
- {K_K0, "\316\332"},
- {K_K1, "\316\336"},
- {K_K2, "\316\342"},
- {K_K3, "\316\346"},
- {K_K4, "\316\352"},
- {K_K5, "\316\356"},
- {K_K6, "\316\362"},
- {K_K7, "\316\366"},
- {K_K8, "\316\372"},
- {K_K9, "\316\376"},
-# endif
-
-# if defined(ALL_BUILTIN_TCAPS)
- /*
- * VT320 is working as an ANSI terminal compatible DEC terminal.
- * (it covers VT1x0, VT2x0 and VT3x0 up to VT320 on VMS as well)
- * Note: K_F1...K_F5 are for internal use, should not be defined.
- * TODO:- rewrite ESC[ codes to CSI
- * - keyboard languages (CSI ? 26 n)
- */
- {(int)KS_NAME, "vt320"},
- {(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_CD, "\033[J"},
- {(int)KS_CCO, "8"}, /* allow 8 colors */
- {(int)KS_ME, "\033[0m"},
- {(int)KS_MR, "\033[7m"},
- {(int)KS_MD, "\033[1m"}, /* bold mode */
- {(int)KS_SE, "\033[22m"}, /* normal mode */
- {(int)KS_UE, "\033[24m"}, /* exit underscore mode */
- {(int)KS_US, "\033[4m"}, /* underscore mode */
- {(int)KS_CZH, "\033[34;43m"}, /* italic mode: blue text on yellow */
- {(int)KS_CZR, "\033[0m"}, /* italic mode end */
- {(int)KS_CAB, "\033[4%dm"}, /* set background color (ANSI) */
- {(int)KS_CAF, "\033[3%dm"}, /* set foreground color (ANSI) */
- {(int)KS_CSB, "\033[102;%dm"}, /* set screen background color */
- {(int)KS_CSF, "\033[101;%dm"}, /* set screen foreground color */
- {(int)KS_MS, "y"},
- {(int)KS_UT, "y"},
- {(int)KS_LE, "\b"},
-# 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, "\033[A"},
- {K_DOWN, "\033[B"},
- {K_RIGHT, "\033[C"},
- {K_LEFT, "\033[D"},
- {K_F1, "\033[11~"},
- {K_F2, "\033[12~"},
- {K_F3, "\033[13~"},
- {K_F4, "\033[14~"},
- {K_F5, "\033[15~"},
- {K_F6, "\033[17~"},
- {K_F7, "\033[18~"},
- {K_F8, "\033[19~"},
- {K_F9, "\033[20~"},
- {K_F10, "\033[21~"},
- {K_F11, "\033[23~"},
- {K_F12, "\033[24~"},
- {K_F13, "\033[25~"},
- {K_F14, "\033[26~"},
- {K_F15, "\033[28~"}, /* Help */
- {K_F16, "\033[29~"}, /* Select */
- {K_F17, "\033[31~"},
- {K_F18, "\033[32~"},
- {K_F19, "\033[33~"},
- {K_F20, "\033[34~"},
- {K_INS, "\033[2~"},
- {K_DEL, "\033[3~"},
- {K_HOME, "\033[1~"},
- {K_END, "\033[4~"},
- {K_PAGEUP, "\033[5~"},
- {K_PAGEDOWN, "\033[6~"},
- {K_KPLUS, "\033Ok"}, /* keypad plus */
- {K_KMINUS, "\033Om"}, /* keypad minus */
- {K_KDIVIDE, "\033Oo"}, /* keypad / */
- {K_KMULTIPLY, "\033Oj"}, /* keypad * */
- {K_KENTER, "\033OM"}, /* keypad Enter */
- {K_BS, "\x7f"}, /* for some reason 0177 doesn't work */
-# endif
-
-# if defined(ALL_BUILTIN_TCAPS)
- /*
- * Ordinary vt52
- */
- {(int)KS_NAME, "vt52"},
- {(int)KS_CE, "\033K"},
- {(int)KS_CD, "\033J"},
- {(int)KS_CM, "\033Y%+ %+ "},
- {(int)KS_LE, "\b"},
- {(int)KS_AL, "\033T"},
- {(int)KS_DL, "\033U"},
- {(int)KS_CL, "\033H\033J"},
- {(int)KS_ME, "\033SO"},
- {(int)KS_MR, "\033S2"},
- {(int)KS_MS, "y"},
-# endif
-
-# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS)
- {(int)KS_NAME, "xterm"},
- {(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
-# ifdef TERMINFO
- {(int)KS_CS, "\033[%i%p1%d;%p2%dr"},
-# else
- {(int)KS_CS, "\033[%i%d;%dr"},
-# endif
- {(int)KS_CL, "\033[H\033[2J"},
- {(int)KS_CD, "\033[J"},
- {(int)KS_ME, "\033[m"},
- {(int)KS_MR, "\033[7m"},
- {(int)KS_MD, "\033[1m"},
- {(int)KS_UE, "\033[m"},
- {(int)KS_US, "\033[4m"},
- {(int)KS_MS, "y"},
- {(int)KS_UT, "y"},
- {(int)KS_LE, "\b"},
-# 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
- {(int)KS_KS, "\033[?1h\033="},
- {(int)KS_KE, "\033[?1l\033>"},
- {(int)KS_CIS, "\033]1;"},
- {(int)KS_CIE, "\007"},
- {(int)KS_TS, "\033]2;"},
- {(int)KS_FS, "\007"},
-# ifdef TERMINFO
- {(int)KS_CWS, "\033[8;%p1%d;%p2%dt"},
- {(int)KS_CWP, "\033[3;%p1%d;%p2%dt"},
-# else
- {(int)KS_CWS, "\033[8;%d;%dt"},
- {(int)KS_CWP, "\033[3;%d;%dt"},
-# endif
- {(int)KS_CRV, "\033[>c"},
- {(int)KS_U7, "\033[6n"},
-
- {K_UP, "\033O*A"},
- {K_DOWN, "\033O*B"},
- {K_RIGHT, "\033O*C"},
- {K_LEFT, "\033O*D"},
- /* An extra set of cursor keys for vt100 mode */
- {K_XUP, "\033[1;*A"},
- {K_XDOWN, "\033[1;*B"},
- {K_XRIGHT, "\033[1;*C"},
- {K_XLEFT, "\033[1;*D"},
- /* An extra set of function keys for vt100 mode */
- {K_XF1, "\033O*P"},
- {K_XF2, "\033O*Q"},
- {K_XF3, "\033O*R"},
- {K_XF4, "\033O*S"},
- {K_F1, "\033[11;*~"},
- {K_F2, "\033[12;*~"},
- {K_F3, "\033[13;*~"},
- {K_F4, "\033[14;*~"},
- {K_F5, "\033[15;*~"},
- {K_F6, "\033[17;*~"},
- {K_F7, "\033[18;*~"},
- {K_F8, "\033[19;*~"},
- {K_F9, "\033[20;*~"},
- {K_F10, "\033[21;*~"},
- {K_F11, "\033[23;*~"},
- {K_F12, "\033[24;*~"},
- {K_S_TAB, "\033[Z"},
- {K_HELP, "\033[28;*~"},
- {K_UNDO, "\033[26;*~"},
- {K_INS, "\033[2;*~"},
- {K_HOME, "\033[1;*H"},
- /* {K_S_HOME, "\033O2H"}, */
- /* {K_C_HOME, "\033O5H"}, */
- {K_KHOME, "\033[1;*~"},
- {K_XHOME, "\033O*H"}, /* other Home */
- {K_ZHOME, "\033[7;*~"}, /* other Home */
- {K_END, "\033[1;*F"},
- /* {K_S_END, "\033O2F"}, */
- /* {K_C_END, "\033O5F"}, */
- {K_KEND, "\033[4;*~"},
- {K_XEND, "\033O*F"}, /* other End */
- {K_ZEND, "\033[8;*~"},
- {K_PAGEUP, "\033[5;*~"},
- {K_PAGEDOWN, "\033[6;*~"},
- {K_KPLUS, "\033O*k"}, /* keypad plus */
- {K_KMINUS, "\033O*m"}, /* keypad minus */
- {K_KDIVIDE, "\033O*o"}, /* keypad / */
- {K_KMULTIPLY, "\033O*j"}, /* keypad * */
- {K_KENTER, "\033O*M"}, /* keypad Enter */
- {K_KPOINT, "\033O*n"}, /* keypad . */
- {K_KDEL, "\033[3;*~"}, /* keypad Del */
-
- {BT_EXTRA_KEYS, ""},
- {TERMCAP2KEY('k', '0'), "\033[10;*~"}, /* F0 */
- {TERMCAP2KEY('F', '3'), "\033[25;*~"}, /* F13 */
- /* F14 and F15 are missing, because they send the same codes as the undo
- * and help key, although they don't work on all keyboards. */
- {TERMCAP2KEY('F', '6'), "\033[29;*~"}, /* F16 */
- {TERMCAP2KEY('F', '7'), "\033[31;*~"}, /* F17 */
- {TERMCAP2KEY('F', '8'), "\033[32;*~"}, /* F18 */
- {TERMCAP2KEY('F', '9'), "\033[33;*~"}, /* F19 */
- {TERMCAP2KEY('F', 'A'), "\033[34;*~"}, /* F20 */
-
- {TERMCAP2KEY('F', 'B'), "\033[42;*~"}, /* F21 */
- {TERMCAP2KEY('F', 'C'), "\033[43;*~"}, /* F22 */
- {TERMCAP2KEY('F', 'D'), "\033[44;*~"}, /* F23 */
- {TERMCAP2KEY('F', 'E'), "\033[45;*~"}, /* F24 */
- {TERMCAP2KEY('F', 'F'), "\033[46;*~"}, /* F25 */
- {TERMCAP2KEY('F', 'G'), "\033[47;*~"}, /* F26 */
- {TERMCAP2KEY('F', 'H'), "\033[48;*~"}, /* F27 */
- {TERMCAP2KEY('F', 'I'), "\033[49;*~"}, /* F28 */
- {TERMCAP2KEY('F', 'J'), "\033[50;*~"}, /* F29 */
- {TERMCAP2KEY('F', 'K'), "\033[51;*~"}, /* F30 */
-
- {TERMCAP2KEY('F', 'L'), "\033[52;*~"}, /* F31 */
- {TERMCAP2KEY('F', 'M'), "\033[53;*~"}, /* F32 */
- {TERMCAP2KEY('F', 'N'), "\033[54;*~"}, /* F33 */
- {TERMCAP2KEY('F', 'O'), "\033[55;*~"}, /* F34 */
- {TERMCAP2KEY('F', 'P'), "\033[56;*~"}, /* F35 */
- {TERMCAP2KEY('F', 'Q'), "\033[57;*~"}, /* F36 */
- {TERMCAP2KEY('F', 'R'), "\033[58;*~"}, /* F37 */
-# endif
-
-# if defined(DEBUG) || defined(ALL_BUILTIN_TCAPS)
- /*
- * for debugging
- */
- {(int)KS_NAME, "debug"},
- {(int)KS_CE, "[CE]"},
- {(int)KS_CD, "[CD]"},
- {(int)KS_AL, "[AL]"},
-# ifdef TERMINFO
- {(int)KS_CAL, "[CAL%p1%d]"},
-# else
- {(int)KS_CAL, "[CAL%d]"},
-# endif
- {(int)KS_DL, "[DL]"},
-# ifdef TERMINFO
- {(int)KS_CDL, "[CDL%p1%d]"},
-# else
- {(int)KS_CDL, "[CDL%d]"},
-# endif
-# ifdef TERMINFO
- {(int)KS_CS, "[%p1%dCS%p2%d]"},
-# else
- {(int)KS_CS, "[%dCS%d]"},
-# endif
-# ifdef TERMINFO
- {(int)KS_CSV, "[%p1%dCSV%p2%d]"},
-# else
- {(int)KS_CSV, "[%dCSV%d]"},
-# endif
-# ifdef TERMINFO
- {(int)KS_CAB, "[CAB%p1%d]"},
- {(int)KS_CAF, "[CAF%p1%d]"},
- {(int)KS_CSB, "[CSB%p1%d]"},
- {(int)KS_CSF, "[CSF%p1%d]"},
-# else
- {(int)KS_CAB, "[CAB%d]"},
- {(int)KS_CAF, "[CAF%d]"},
- {(int)KS_CSB, "[CSB%d]"},
- {(int)KS_CSF, "[CSF%d]"},
-# endif
- {(int)KS_OP, "[OP]"},
- {(int)KS_LE, "[LE]"},
- {(int)KS_CL, "[CL]"},
- {(int)KS_VI, "[VI]"},
- {(int)KS_VE, "[VE]"},
- {(int)KS_VS, "[VS]"},
- {(int)KS_ME, "[ME]"},
- {(int)KS_MR, "[MR]"},
- {(int)KS_MB, "[MB]"},
- {(int)KS_MD, "[MD]"},
- {(int)KS_SE, "[SE]"},
- {(int)KS_SO, "[SO]"},
- {(int)KS_UE, "[UE]"},
- {(int)KS_US, "[US]"},
- {(int)KS_UCE, "[UCE]"},
- {(int)KS_UCS, "[UCS]"},
- {(int)KS_MS, "[MS]"},
- {(int)KS_UT, "[UT]"},
-# ifdef TERMINFO
- {(int)KS_CM, "[%p1%dCM%p2%d]"},
-# else
- {(int)KS_CM, "[%dCM%d]"},
-# endif
- {(int)KS_SR, "[SR]"},
-# ifdef TERMINFO
- {(int)KS_CRI, "[CRI%p1%d]"},
-# else
- {(int)KS_CRI, "[CRI%d]"},
-# endif
- {(int)KS_VB, "[VB]"},
- {(int)KS_KS, "[KS]"},
- {(int)KS_KE, "[KE]"},
- {(int)KS_TI, "[TI]"},
- {(int)KS_TE, "[TE]"},
- {(int)KS_CIS, "[CIS]"},
- {(int)KS_CIE, "[CIE]"},
- {(int)KS_TS, "[TS]"},
- {(int)KS_FS, "[FS]"},
-# ifdef TERMINFO
- {(int)KS_CWS, "[%p1%dCWS%p2%d]"},
- {(int)KS_CWP, "[%p1%dCWP%p2%d]"},
-# else
- {(int)KS_CWS, "[%dCWS%d]"},
- {(int)KS_CWP, "[%dCWP%d]"},
-# endif
- {(int)KS_CRV, "[CRV]"},
- {(int)KS_U7, "[U7]"},
- {K_UP, "[KU]"},
- {K_DOWN, "[KD]"},
- {K_LEFT, "[KL]"},
- {K_RIGHT, "[KR]"},
- {K_XUP, "[xKU]"},
- {K_XDOWN, "[xKD]"},
- {K_XLEFT, "[xKL]"},
- {K_XRIGHT, "[xKR]"},
- {K_S_UP, "[S-KU]"},
- {K_S_DOWN, "[S-KD]"},
- {K_S_LEFT, "[S-KL]"},
- {K_C_LEFT, "[C-KL]"},
- {K_S_RIGHT, "[S-KR]"},
- {K_C_RIGHT, "[C-KR]"},
- {K_F1, "[F1]"},
- {K_XF1, "[xF1]"},
- {K_F2, "[F2]"},
- {K_XF2, "[xF2]"},
- {K_F3, "[F3]"},
- {K_XF3, "[xF3]"},
- {K_F4, "[F4]"},
- {K_XF4, "[xF4]"},
- {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_XF1, "[S-xF1]"},
- {K_S_F2, "[S-F2]"},
- {K_S_XF2, "[S-xF2]"},
- {K_S_F3, "[S-F3]"},
- {K_S_XF3, "[S-xF3]"},
- {K_S_F4, "[S-F4]"},
- {K_S_XF4, "[S-xF4]"},
- {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_KINS, "[KINS]"},
- {K_DEL, "[DEL]"},
- {K_KDEL, "[KDEL]"},
- {K_HOME, "[HOME]"},
- {K_S_HOME, "[C-HOME]"},
- {K_C_HOME, "[C-HOME]"},
- {K_KHOME, "[KHOME]"},
- {K_XHOME, "[XHOME]"},
- {K_ZHOME, "[ZHOME]"},
- {K_END, "[END]"},
- {K_S_END, "[C-END]"},
- {K_C_END, "[C-END]"},
- {K_KEND, "[KEND]"},
- {K_XEND, "[XEND]"},
- {K_ZEND, "[ZEND]"},
- {K_PAGEUP, "[PAGEUP]"},
- {K_PAGEDOWN, "[PAGEDOWN]"},
- {K_KPAGEUP, "[KPAGEUP]"},
- {K_KPAGEDOWN, "[KPAGEDOWN]"},
- {K_MOUSE, "[MOUSE]"},
- {K_KPLUS, "[KPLUS]"},
- {K_KMINUS, "[KMINUS]"},
- {K_KDIVIDE, "[KDIVIDE]"},
- {K_KMULTIPLY, "[KMULTIPLY]"},
- {K_KENTER, "[KENTER]"},
- {K_KPOINT, "[KPOINT]"},
- {K_K0, "[K0]"},
- {K_K1, "[K1]"},
- {K_K2, "[K2]"},
- {K_K3, "[K3]"},
- {K_K4, "[K4]"},
- {K_K5, "[K5]"},
- {K_K6, "[K6]"},
- {K_K7, "[K7]"},
- {K_K8, "[K8]"},
- {K_K9, "[K9]"},
-# 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 */
@@ -1009,8 +175,6 @@ void term_init(void)
char_u *(term_strings[(int)KS_LAST + 1]);
static bool need_gather = false; // need to fill termleader[]
-static char_u termleader[256 + 1]; // for check_termcode()
-static bool check_for_codes = false; // check for key code response
static struct builtin_term *find_builtin_term(char_u *term)
{
@@ -1076,38 +240,6 @@ static void parse_builtin_tcap(char_u *term)
}
/*
- * Set number of colors.
- * Store it as a number in t_colors.
- * Store it as a string in T_CCO (using nr_colors[]).
- */
-static void set_color_count(int nr)
-{
- char_u nr_colors[20]; /* string for number of colors */
-
- t_colors = nr;
- if (t_colors > 1)
- sprintf((char *)nr_colors, "%d", t_colors);
- else
- *nr_colors = NUL;
- set_string_option_direct((char_u *)"t_Co", -1, nr_colors, OPT_FREE, 0);
-}
-
-#ifdef HAVE_TGETENT
-static char *(key_names[]) =
-{
- /* Do this one first, it may cause a screen redraw. */
- "Co",
- "ku", "kd", "kr", "kl",
- "#2", "#4", "%i", "*7",
- "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", "kB",
- NULL
-};
-#endif
-
-/*
* Set terminal options for terminal "term".
* Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
*
@@ -1115,11 +247,6 @@ static char *(key_names[]) =
*/
int set_termname(char_u *term)
{
-#ifdef HAVE_TGETENT
- int builtin_first = p_tbi;
- int try;
- int termcap_cleared = FALSE;
-#endif
int width = 0, height = 0;
char_u *error_msg = NULL;
char_u *bs_p, *del_p;
@@ -1128,17 +255,11 @@ int set_termname(char_u *term)
if (silent_mode)
return OK;
- if (!STRCMP(term, "abstract_ui")) {
- abstract_ui = true;
- }
-
+ term = (uint8_t *)"abstract_ui";
detected_8bit = false; // reset 8-bit detection
if (term_is_builtin(term)) {
term += 8;
-#ifdef HAVE_TGETENT
- builtin_first = 1;
-#endif
}
/*
@@ -1151,146 +272,15 @@ int set_termname(char_u *term)
* 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 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_UCE, "Ce"}, {KS_UCS, "Cs"},
- {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"}, {KS_CRV, "RV"},
- {KS_CIS, "IS"}, {KS_CIE, "IE"},
- {KS_TS, "ts"}, {KS_FS, "fs"},
- {KS_CWP, "WP"}, {KS_CWS, "WS"},
- {KS_CSI, "SI"}, {KS_CEI, "EI"},
- {KS_U7, "u7"},
- {(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);
- }
-
- /* tgetflag() returns 1 if the flag is present, 0 if not and
- * possibly -1 if the flag doesn't exist. */
- if ((T_MS == NULL || T_MS == empty_option)
- && tgetflag("ms") > 0)
- T_MS = (char_u *)"y";
- if ((T_XS == NULL || T_XS == empty_option)
- && tgetflag("xs") > 0)
- T_XS = (char_u *)"y";
- if ((T_DB == NULL || T_DB == empty_option)
- && tgetflag("db") > 0)
- T_DB = (char_u *)"y";
- if ((T_DA == NULL || T_DA == empty_option)
- && tgetflag("da") > 0)
- T_DA = (char_u *)"y";
- if ((T_UT == NULL || T_UT == empty_option)
- && tgetflag("ut") > 0)
- T_UT = (char_u *)"y";
-
-
- /*
- * get key codes
- */
- for (i = 0; key_names[i] != NULL; ++i) {
- if (find_termcode((char_u *)key_names[i]) == NULL) {
- p = TGETSTR(key_names[i], &tp);
- /* if cursor-left == backspace, ignore it (televideo
- * 925) */
- if (p != NULL
- && (*p != Ctrl_H
- || key_names[i][0] != 'k'
- || key_names[i][1] != 'l'))
- add_termcode((char_u *)key_names[i], p, FALSE);
- }
- }
-
- if (height == 0)
- height = tgetnum("li");
- if (width == 0)
- width = tgetnum("co");
-
- /*
- * Get number of colors (if not done already).
- */
- if (term_str(KS_CCO) == NULL
- || term_str(KS_CCO) == empty_option)
- set_color_count(tgetnum("Co"));
-
- BC = (char *)TGETSTR("bc", &tp);
- UP = (char *)TGETSTR("up", &tp);
- p = TGETSTR("pc", &tp);
- if (p)
- PC = (char)*p;
- }
- } 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[]
*/
struct builtin_term *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) {
@@ -1304,11 +294,7 @@ int set_termname(char_u *term)
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");
}
@@ -1333,19 +319,9 @@ int set_termname(char_u *term)
display_errors();
}
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 HAVE_TGETENT
-}
-#endif
/*
* special: There is no info in the termcap about whether the cursor
@@ -1358,16 +334,6 @@ int set_termname(char_u *term)
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.
- */
- 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
@@ -1390,39 +356,10 @@ int set_termname(char_u *term)
term_is_xterm = vim_is_xterm(term);
#endif
-# if defined(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 = (char_u *)"";
- if (use_xterm_like_mouse(term)) {
- if (use_xterm_mouse())
- p = NULL; /* keep existing value, might be "xterm2" */
- else
- p = (char_u *)"xterm";
- }
- if (p != NULL) {
- set_option_value((char_u *)"ttym", 0L, p, 0);
- /* Reset the WAS_SET flag, 'ttymouse' can be set to "sgr" or
- * "xterm2" in check_termcode(). */
- reset_option_was_set((char_u *)"ttym");
- }
- if (p == NULL
- )
- check_mouse_termcode(); /* set mouse termcode anyway */
- }
-# else
- set_mouse_termcode(KS_MOUSE, (char_u *)"\233M");
-# 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 */
- LOG_TR("setting crv_status to CRV_GET");
- crv_status = CRV_GET; /* Get terminal version later */
/*
* Initialize the terminal with the appropriate termcap codes.
@@ -1431,7 +368,6 @@ int set_termname(char_u *term)
* may redefine t_TI etc.
*/
if (starting != NO_SCREEN) {
- starttermcap(); /* may change terminal mode */
setmouse(); /* may start using the mouse */
maketitle(); /* may display window title */
}
@@ -1443,7 +379,7 @@ int set_termname(char_u *term)
width = 80;
height = 24; /* most terminals are 24 lines */
}
- screen_resize(width, height, FALSE); /* may change Rows */
+ screen_resize(width, height); // may change Rows
if (starting != NO_SCREEN) {
if (scroll_region)
scroll_region_reset(); /* In case Rows changed */
@@ -1465,8 +401,6 @@ int set_termname(char_u *term)
}
}
- may_req_termresponse();
-
return OK;
}
@@ -1477,99 +411,6 @@ int set_termname(char_u *term)
# define HMT_URXVT 16
# define HMT_SGR 32
-void
-set_mouse_termcode (
- char_u n, /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
- char_u *s
-)
-{
- char_u name[2] = { n, KE_FILLER };
-
- add_termcode(name, s, FALSE);
-}
-
-# if (defined(UNIX) && defined(FEAT_MOUSE_TTY))
-void
-del_mouse_termcode (
- char_u n /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
-)
-{
- char_u name[2] = { n, KE_FILLER };
-
- del_termcode(name);
-}
-# endif
-
-#ifdef HAVE_TGETENT
-/*
- * Call tgetent()
- * Return error message if it fails, NULL if it's OK.
- */
-static char_u *tgetent_error(char_u *tbuf, char_u *term)
-{
- int i = TGETENT(tbuf, term);
- if (i < 0 /* -1 is always an error */
-# ifdef TGETENT_ZERO_ERR
- || i == 0 /* sometimes zero is also an error */
-# endif
- ) {
- /* On FreeBSD tputs() gets a SEGV after a tgetent() which fails. Call
- * tgetent() with the always existing "dumb" entry to avoid a crash or
- * hang. */
- (void)TGETENT(tbuf, "dumb");
-
- if (i < 0)
-# ifdef TGETENT_ZERO_ERR
- return (char_u *)_("E557: Cannot open termcap file");
- if (i == 0)
-# endif
-#ifdef TERMINFO
- return (char_u *)_("E558: Terminal entry not found in terminfo");
-#else
- return (char_u *)_("E559: Terminal entry not found in termcap");
-#endif
- }
- return NULL;
-}
-
-/*
- * Some versions of tgetstr() have been reported to return -1 instead of NULL.
- * Fix that here.
- */
-static char_u *vim_tgetstr(char *s, char_u **pp)
-{
- char *p = tgetstr(s, (char **)pp);
- if (p == (char *)-1)
- p = NULL;
- return (char_u *)p;
-}
-#endif /* HAVE_TGETENT */
-
-#if defined(HAVE_TGETENT) && (defined(UNIX) || defined(MACOS_X))
-/*
- * 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 (
- long *cp, /* pointer to columns */
- long *rp /* pointer to rows */
-)
-{
- char_u tbuf[TBUFSZ];
-
- if (T_NAME != NULL && *T_NAME != NUL &&
- tgetent_error(tbuf, T_NAME) == NULL) {
- if (*cp == 0)
- *cp = tgetnum("co");
- if (*rp == 0)
- *rp = 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.
@@ -1582,15 +423,6 @@ int add_termcap_entry(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
@@ -1606,25 +438,8 @@ int add_termcap_entry(char_u *name, int force)
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
*/
@@ -1642,29 +457,8 @@ int add_termcap_entry(char_u *name, int force)
}
}
}
-#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, FALSE);
- return OK;
- }
- }
- }
-}
-#endif
if (sourcing_name == NULL) {
-#ifdef HAVE_TGETENT
- if (error_msg != NULL)
- EMSG(error_msg);
- else
-#endif
EMSG2(_("E436: No \"%s\" entry in termcap"), name);
}
return FAIL;
@@ -1705,8 +499,6 @@ static char_u term_7to8bit(char_u *p)
}
-#if !defined(HAVE_TGETENT)
-
char_u *tltoa(unsigned long i)
{
static char_u buf[16];
@@ -1719,54 +511,6 @@ char_u *tltoa(unsigned long i)
} 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
- */
-
-static char *tgoto(char *cm, int x, int y)
-{
- static char buf[30];
-
- if (!cm)
- return "OOPS";
- char *e = buf + 29;
- for (char *s = buf; s < e && *cm; cm++) {
- if (*cm != '%') {
- *s++ = *cm;
- continue;
- }
- switch (*++cm) {
- case 'd':
- char *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.
@@ -1795,20 +539,6 @@ void termcapinit(char_u *name)
set_termname(T_NAME != NULL ? T_NAME : term);
}
-/// Write s[len] to the screen.
-void term_write(char_u *s, size_t len)
-{
- (void) fwrite(s, len, 1, stdout);
-
-#ifdef UNIX
- if (p_wd) { // Unix is too fast, slow down a bit more
- assert(p_wd >= 0
- && (sizeof(long) <= sizeof(uint64_t) || p_wd <= UINT64_MAX));
- os_microdelay((uint64_t)p_wd);
- }
-#endif
-}
-
/*
* the number of calls to ui_write is reduced by using the buffer "out_buf"
*/
@@ -1913,12 +643,8 @@ void out_str(char_u *s)
/* avoid terminal strings being split up */
if (out_pos > OUT_SIZE - 20)
out_flush();
-#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)
@@ -1931,103 +657,30 @@ void out_str(char_u *s)
*/
void term_windgoto(int row, int col)
{
- OUT_STR(tgoto((char *)T_CM, col, row));
+ char buf[32];
+ snprintf(buf, sizeof(buf), "\033|%d;%dM", row, col);
+ OUT_STR(buf);
}
void term_cursor_right(int i)
{
- OUT_STR(tgoto((char *)T_CRI, 0, i));
+ abort();
}
void term_append_lines(int line_count)
{
- OUT_STR(tgoto((char *)T_CAL, 0, line_count));
+ char buf[32];
+ snprintf(buf, sizeof(buf), "\033|%dI", line_count);
+ OUT_STR(buf);
}
void term_delete_lines(int line_count)
{
- OUT_STR(tgoto((char *)T_CDL, 0, line_count));
-}
-
-#if defined(HAVE_TGETENT)
-void term_set_winpos(int x, int y)
-{
- /* Can't handle a negative value here */
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
- OUT_STR(tgoto((char *)T_CWP, y, x));
-}
-
-void term_set_winsize(int width, int height)
-{
- OUT_STR(tgoto((char *)T_CWS, height, width));
-}
-#endif
-
-void term_fg_color(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);
+ char buf[32];
+ snprintf(buf, sizeof(buf), "\033|%dD", line_count);
+ OUT_STR(buf);
}
-void term_bg_color(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(char_u *s, int n)
-{
- char buf[20];
- int i = 2; /* index in s[] just after <Esc>[ or CSI */
-
- /* Special handling of 16 colors, because termcap can't handle it */
- /* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */
- /* Also accept CSI instead of <Esc>[ */
- if (n >= 8 && t_colors >= 16
- && ((s[0] == ESC && s[1] == '[') || (s[0] == CSI && (i = 1) == 1))
- && s[i] != NUL
- && (STRCMP(s + i + 1, "%p1%dm") == 0
- || STRCMP(s + i + 1, "%dm") == 0)
- && (s[i] == '3' || s[i] == '4')) {
- const char *fmt =
-#ifdef TERMINFO
- "%s%s%%p1%%dm";
-#else
- "%s%s%%dm";
-#endif
- sprintf(buf,
- fmt,
- i == 2 ? "\033[" : "\233",
- s[i] == '3' ? (n >= 16 ? "38;5;" : "9")
- : (n >= 16 ? "48;5;" : "10"));
- OUT_STR(tgoto(buf, 0, n >= 16 ? n : n - 8));
- } else
- OUT_STR(tgoto((char *)s, 0, n));
-}
-
-#if defined(UNIX) || defined(MACOS_X)
-/*
- * Generic function to set window title, using t_ts and t_fs.
- */
-void term_settitle(char_u *title)
-{
- /* t_ts takes one argument: column in status line */
- OUT_STR(tgoto((char *)T_TS, 0, 0)); /* set title start */
- out_str_nf(title);
- out_str(T_FS); /* set title end */
- out_flush();
-}
-#endif
-
/*
* Make sure we have a valid set or terminal options.
* Replace all entries that are NULL by empty_option
@@ -2118,43 +771,6 @@ void ttest(int pairs)
t_colors = atoi((char *)T_CCO);
}
-#if defined(FEAT_GUI) \
- || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM) \
- || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)))
-/*
- * 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(char_u *buf, char_u *bytes, int num_bytes)
-{
- int len = 0;
- char_u c;
-
- for (int 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;
- /* else it should be KS_SPECIAL; when followed by KE_FILLER c is
- * K_SPECIAL, or followed by KE_CSI and c must be CSI. */
- if (buf[len++] == (int)KE_CSI)
- c = CSI;
- } else if (c == CSI && buf[len] == KS_EXTRA
- && buf[len + 1] == (int)KE_CSI)
- /* CSI is stored as CSI KS_SPECIAL KE_CSI to avoid confusion with
- * the start of a special key, see add_to_input_buf_csi(). */
- len += 2;
- bytes[i] = c;
- }
- return len;
-}
-#endif
-
/*
* Check if the new shell size is valid, correct it if it's too small or way
* too big.
@@ -2206,11 +822,7 @@ void win_new_shellsize(void)
*/
void shell_resized(void)
{
- if (abstract_ui) {
- ui_refresh();
- } else {
- screen_resize(0, 0, FALSE);
- }
+ ui_refresh();
}
/*
@@ -2223,7 +835,6 @@ void shell_resized_check(void)
long old_Columns = Columns;
if (!exiting) {
- (void)ui_get_shellsize();
check_shellsize();
if (old_Rows != Rows || old_Columns != Columns)
shell_resized();
@@ -2231,232 +842,6 @@ void shell_resized_check(void)
}
/*
- * Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
- * commands and Ex mode).
- */
-void settmode(int tmode)
-{
- if (abstract_ui) {
- return;
- }
-
- if (full_screen) {
- /*
- * 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 || cur_tmode != TMODE_COOK) {
- {
- /* May need to check for T_CRV response and termcodes, it
- * doesn't work in Cooked mode, an external program may get
- * them. */
- if (tmode != TMODE_RAW && (crv_status == CRV_SENT
- || u7_status == U7_SENT))
- (void)vpeekc_nomap();
- check_for_codes_from_term();
- }
- if (tmode != TMODE_RAW)
- mch_setmouse(FALSE); /* switch mouse off */
- out_flush();
- mch_settmode(tmode); /* machine specific function */
- cur_tmode = tmode;
- if (tmode == TMODE_RAW)
- setmouse(); /* may switch mouse on */
- out_flush();
- }
- may_req_termresponse();
- }
-}
-
-void starttermcap(void)
-{
- if (full_screen && !termcap_active) {
- out_str(T_TI); /* start termcap mode */
- out_str(T_KS); /* start "keypad transmit" mode */
- out_flush();
- termcap_active = TRUE;
- screen_start(); /* don't know where cursor is now */
- if (!abstract_ui) {
- may_req_termresponse();
- /* Immediately check for a response. If t_Co changes, we don't
- * want to redraw with wrong colors first. */
- if (crv_status == CRV_SENT) {
- check_for_codes_from_term();
- }
- }
- }
-}
-
-void stoptermcap(void)
-{
- screen_stop_highlight();
- reset_cterm_colors();
- if (termcap_active) {
- if (!abstract_ui) {
- /* May need to discard T_CRV or T_U7 response. */
- if (crv_status == CRV_SENT || u7_status == U7_SENT) {
-# ifdef UNIX
- /* Give the terminal a chance to respond. */
- os_delay(100L, false);
-# endif
-# ifdef TCIFLUSH
- /* Discard data received but not read. */
- if (exiting)
- tcflush(fileno(stdin), TCIFLUSH);
-# endif
- }
- /* Check for termcodes first, otherwise an external program may
- * get them. */
- check_for_codes_from_term();
- }
- out_str(T_KE); /* stop "keypad transmit" mode */
- out_flush();
- termcap_active = FALSE;
- cursor_on(); /* just in case it is still off */
- out_str(T_TE); /* stop termcap mode */
- screen_start(); /* don't know where cursor is now */
- out_flush();
- }
-}
-
-#if defined(UNIX)
-/// Returns true when the xterm version was requested or anything else that
-/// would send an ESC sequence back to Vim.
-///
-/// If not sent yet, prevent it from being sent soon.
-/// Used to check whether it is OK to enable checking for DEC mouse codes,
-/// which conflict with may xterm ESC sequences.
-bool did_request_esc_sequence(void)
-{
- if (crv_status == CRV_GET) {
- crv_status = 0;
- }
- if (u7_status == U7_GET) {
- u7_status = 0;
- }
- return crv_status == CRV_SENT || u7_status == U7_SENT
- || xt_index_out > xt_index_in;
-}
-
-/// If requesting the version was disabled in did_request_esc_sequence(),
-/// enable it again.
-void resume_get_esc_sequence(void)
-{
- if (crv_status == 0) {
- crv_status = CRV_GET;
- }
- if (u7_status == 0) {
- u7_status = U7_GET;
- }
-}
-#endif
-
-/*
- * Request version string (for xterm) when needed.
- * Only do this after switching to raw mode, otherwise the result will be
- * echoed.
- * Only do this after startup has finished, to avoid that the response comes
- * while executing "-c !cmd" or even after "-c quit".
- * Only do this after termcap mode has been started, otherwise the codes for
- * the cursor keys may be wrong.
- * Only do this when 'esckeys' is on, otherwise the response causes trouble in
- * Insert mode.
- * On Unix only do it when both output and input are a tty (avoid writing
- * request to terminal while reading from a file).
- * Do not do this when a mouse is being detected that starts with the same ESC
- * sequence as the termresponse.
- * The result is caught in check_termcode().
- */
-void may_req_termresponse(void)
-{
- if (crv_status == CRV_GET
- && cur_tmode == TMODE_RAW
- && starting == 0
- && termcap_active
- && p_ek
-# ifdef UNIX
- && isatty(1)
- && isatty(read_cmd_fd)
- && !xterm_conflict_mouse
-# endif
- && *T_CRV != NUL) {
- LOG_TR("Sending CRV");
- out_str(T_CRV);
- crv_status = CRV_SENT;
- /* check for the characters now, otherwise they might be eaten by
- * get_keystroke() */
- out_flush();
- (void)vpeekc_nomap();
- }
-}
-
-/*
- * Check how the terminal treats ambiguous character width (UAX #11).
- * First, we move the cursor to (1, 0) and print a test ambiguous character
- * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position.
- * If the terminal treats \u25bd as single width, the position is (1, 1),
- * or if it is treated as double width, that will be (1, 2).
- * This function has the side effect that changes cursor position, so
- * it must be called immediately after entering termcap mode.
- */
-void may_req_ambiguous_char_width(void)
-{
- if (u7_status == U7_GET
- && cur_tmode == TMODE_RAW
- && termcap_active
- && p_ek
-# ifdef UNIX
- && isatty(1)
- && isatty(read_cmd_fd)
-# endif
- && *T_U7 != NUL
- && !option_was_set((char_u *)"ambiwidth")) {
- char_u buf[16];
-
- LOG_TR("Sending U7 request");
- /* Do this in the second row. In the first row the returned sequence
- * may be CSI 1;2R, which is the same as <S-F3>. */
- term_windgoto(1, 0);
- buf[mb_char2bytes(0x25bd, buf)] = 0;
- out_str(buf);
- out_str(T_U7);
- u7_status = U7_SENT;
- out_flush();
- term_windgoto(1, 0);
- out_str((char_u *)" ");
- term_windgoto(0, 0);
- /* check for the characters now, otherwise they might be eaten by
- * get_keystroke() */
- out_flush();
- (void)vpeekc_nomap();
- }
-}
-
-# ifdef DEBUG_TERMRESPONSE
-static void log_tr(char *msg) {
- static FILE *fd_tr = NULL;
- static proftime_T start;
-
- if (fd_tr == NULL) {
- fd_tr = fopen("termresponse.log", "w");
- profile_start(&start);
- }
- proftime_T now = start;
- profile_end(&now);
- fprintf(fd_tr, "%s: %s %s\n",
- profile_msg(&now),
- must_redraw == NOT_VALID ? "NV"
- : must_redraw == CLEAR ? "CL" : " ",
- msg);
-}
-
-# endif
-
-/*
* Return TRUE when saving and restoring the screen.
*/
int swapping_screen(void)
@@ -2478,22 +863,12 @@ void scroll_start(void)
}
}
-static int cursor_is_off = FALSE;
-
/*
* Enable the cursor.
*/
void cursor_on(void)
{
- if (abstract_ui) {
- ui_cursor_on();
- return;
- }
-
- if (cursor_is_off) {
- out_str(T_VE);
- cursor_is_off = FALSE;
- }
+ ui_cursor_on();
}
/*
@@ -2501,37 +876,7 @@ void cursor_on(void)
*/
void cursor_off(void)
{
- if (abstract_ui) {
- ui_cursor_off();
- return;
- }
-
- if (full_screen) {
- if (!cursor_is_off)
- out_str(T_VI); /* disable cursor */
- cursor_is_off = TRUE;
- }
-}
-
-/*
- * Set cursor shape to match Insert mode.
- */
-void term_cursor_shape(void)
-{
- static int showing_insert_mode = MAYBE;
-
- if (!full_screen || *T_CSI == NUL || *T_CEI == NUL)
- return;
-
- if (State & INSERT) {
- if (showing_insert_mode != TRUE)
- out_str(T_CSI); /* Insert mode cursor */
- showing_insert_mode = TRUE;
- } else {
- if (showing_insert_mode != FALSE)
- out_str(T_CEI); /* non-Insert mode cursor */
- showing_insert_mode = FALSE;
- }
+ ui_cursor_off();
}
/*
@@ -2542,11 +887,18 @@ void term_cursor_shape(void)
*/
void scroll_region_set(win_T *wp, int off)
{
- OUT_STR(tgoto((char *)T_CS, wp->w_winrow + wp->w_height - 1,
- wp->w_winrow + off));
- if (*T_CSV != NUL && wp->w_width != Columns)
- OUT_STR(tgoto((char *)T_CSV, wp->w_wincol + wp->w_width - 1,
- wp->w_wincol));
+ char buf[32];
+
+ snprintf(buf, sizeof(buf), "\033|%d;%dR", wp->w_winrow + wp->w_height - 1,
+ wp->w_winrow + off);
+ OUT_STR(buf);
+
+ if (wp->w_width != Columns) {
+ snprintf(buf, sizeof(buf), "\033|%d;%dV", wp->w_wincol + wp->w_width - 1,
+ wp->w_wincol);
+ OUT_STR(buf);
+ }
+
screen_start(); /* don't know where cursor is now */
}
@@ -2555,9 +907,13 @@ void scroll_region_set(win_T *wp, int off)
*/
void scroll_region_reset(void)
{
- OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0));
- if (*T_CSV != NUL)
- OUT_STR(tgoto((char *)T_CSV, (int)Columns - 1, 0));
+ char buf[32];
+
+ snprintf(buf, sizeof(buf), "\033|%d;%dR", (int)Rows - 1, 0);
+ OUT_STR(buf);
+ snprintf(buf, sizeof(buf), "\033|%d;%dV", (int)Columns - 1, 0);
+ OUT_STR(buf);
+
screen_start(); /* don't know where cursor is now */
}
@@ -2584,12 +940,6 @@ void clear_termcodes(void)
termcodes = NULL;
tc_max_len = 0;
-#ifdef HAVE_TGETENT
- BC = (char *)empty_option;
- UP = (char *)empty_option;
- PC = NUL; /* set pad character to NUL */
- ospeed = 0;
-#endif
need_gather = true; // need to fill termleader[]
}
@@ -2748,27 +1098,6 @@ static void del_termcode_idx(size_t idx)
termcodes[i] = termcodes[i + 1];
}
-/*
- * Called when detected that the terminal sends 8-bit codes.
- * Convert all 7-bit codes to their 8-bit equivalent.
- */
-static void switch_to_8bit(void)
-{
- /* Only need to do something when not already using 8-bit codes. */
- if (!term_is_8bit(T_NAME)) {
- for (size_t i = 0; i < tc_len; ++i) {
- char_u c = term_7to8bit(termcodes[i].code);
- if (c != 0) {
- STRMOVE(termcodes[i].code + 1, termcodes[i].code + 2);
- termcodes[i].code[0] = c;
- }
- }
- need_gather = true; // need to fill termleader[]
- }
- detected_8bit = true;
- LOG_TR("Switching to 8 bit");
-}
-
static linenr_T orig_topline = 0;
static int orig_topfill = 0;
@@ -2788,847 +1117,6 @@ void set_mouse_topline(win_T *wp)
}
/*
- * Check if typebuf.tb_buf[] contains a terminal key code.
- * Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off
- * + max_offset].
- * Return 0 for no match, -1 for partial match, > 0 for full match.
- * Return KEYLEN_REMOVED when a key code was deleted.
- * With a match, the match is removed, the replacement code is inserted in
- * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is
- * returned.
- * When "buf" is not NULL, buf[bufsize] is used instead of typebuf.tb_buf[].
- * "buflen" is then the length of the string in buf[] and is updated for
- * inserts and deletes.
- */
-int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen)
-{
- if (abstract_ui) {
- // codes are parsed by input.c/input_enqueue
- return 0;
- }
-
- char_u *tp;
- char_u *p;
- int slen = 0; /* init for GCC */
- int modslen;
- int len;
- int retval = 0;
- int offset;
- char_u key_name[2];
- int modifiers;
- int key;
- int new_slen;
- int extra;
- char_u string[MAX_KEY_CODE_LEN + 1];
- int i, j;
-# if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
- || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
- char_u bytes[6];
- int num_bytes;
-# endif
- int mouse_code = 0; /* init for GCC */
- int is_click, is_drag;
- int wheel_code = 0;
- int current_button;
- static int held_button = MOUSE_RELEASE;
- static int orig_num_clicks = 1;
- static int orig_mouse_code = 0x0;
- int cpo_koffset;
-
- cpo_koffset = (vim_strchr(p_cpo, CPO_KOFFSET) != NULL);
-
- /*
- * Speed up the checks for terminal codes by gathering all first bytes
- * used in termleader[]. Often this is just a single <Esc>.
- */
- if (need_gather)
- gather_termleader();
-
- /*
- * Check at several positions in typebuf.tb_buf[], to catch something like
- * "x<Up>" that can be mapped. Stop at max_offset, because characters
- * after that cannot be used for mapping, and with @r commands
- * typebuf.tb_buf[] can become very long.
- * This is used often, KEEP IT FAST!
- */
- for (offset = 0; offset < max_offset; ++offset) {
- if (buf == NULL) {
- if (offset >= typebuf.tb_len)
- break;
- tp = typebuf.tb_buf + typebuf.tb_off + offset;
- len = typebuf.tb_len - offset; /* length of the input */
- } else {
- if (offset >= *buflen)
- break;
- tp = buf + offset;
- len = *buflen - offset;
- }
-
- /*
- * Don't check characters after K_SPECIAL, those are already
- * translated terminal chars (avoid translating ~@^Hx).
- */
- if (*tp == K_SPECIAL) {
- offset += 2; /* there are always 2 extra characters */
- continue;
- }
-
- /*
- * Skip this position if the character does not appear as the first
- * character in term_strings. This speeds up a lot, since most
- * termcodes start with the same character (ESC or CSI).
- */
- i = *tp;
- for (p = termleader; *p && *p != i; ++p)
- ;
- if (*p == NUL)
- continue;
-
- /*
- * Skip this position if p_ek is not set and tp[0] is an ESC and we
- * are in Insert mode.
- */
- if (*tp == ESC && !p_ek && (State & INSERT))
- continue;
-
- key_name[0] = NUL; /* no key name found yet */
- key_name[1] = NUL; /* no key name found yet */
- modifiers = 0; /* no modifiers yet */
-
- size_t idx;
- {
- for (idx = 0; idx < tc_len; ++idx) {
- /*
- * Ignore the entry if we are not at the start of
- * typebuf.tb_buf[]
- * and there are not enough characters to make a match.
- * But only when the 'K' flag is in 'cpoptions'.
- */
- slen = termcodes[idx].len;
- if (cpo_koffset && offset && len < slen)
- continue;
- if (STRNCMP(termcodes[idx].code, tp,
- (size_t)(slen > len ? len : slen)) == 0) {
- if (len < slen) /* got a partial sequence */
- return -1; /* need to get more chars */
-
- /*
- * When found a keypad key, check if there is another key
- * that matches and use that one. This makes <Home> to be
- * found instead of <kHome> when they produce the same
- * key code.
- */
- if (termcodes[idx].name[0] == 'K'
- && VIM_ISDIGIT(termcodes[idx].name[1])) {
- for (size_t j = idx + 1; j < tc_len; ++j)
- if (termcodes[j].len == slen
- && STRNCMP(termcodes[idx].code,
- termcodes[j].code, slen) == 0) {
- idx = j;
- break;
- }
- }
-
- key_name[0] = termcodes[idx].name[0];
- key_name[1] = termcodes[idx].name[1];
- break;
- }
-
- /*
- * Check for code with modifier, like xterm uses:
- * <Esc>[123;*X (modslen == slen - 3)
- * Also <Esc>O*X and <M-O>*X (modslen == slen - 2).
- * When there is a modifier the * matches a number.
- * When there is no modifier the ;* or * is omitted.
- */
- if (termcodes[idx].modlen > 0) {
- modslen = termcodes[idx].modlen;
- if (cpo_koffset && offset && len < modslen)
- continue;
- if (STRNCMP(termcodes[idx].code, tp,
- (size_t)(modslen > len ? len : modslen)) == 0) {
- int n;
-
- if (len <= modslen) /* got a partial sequence */
- return -1; /* need to get more chars */
-
- if (tp[modslen] == termcodes[idx].code[slen - 1])
- slen = modslen + 1; /* no modifiers */
- else if (tp[modslen] != ';' && modslen == slen - 3)
- continue; /* no match */
- else {
- /* Skip over the digits, the final char must
- * follow. */
- for (j = slen - 2; j < len && isdigit(tp[j]); ++j)
- ;
- ++j;
- if (len < j) /* got a partial sequence */
- return -1; /* need to get more chars */
- if (tp[j - 1] != termcodes[idx].code[slen - 1])
- continue; /* no match */
-
- /* Match! Convert modifier bits. */
- n = atoi((char *)tp + slen - 2) - 1;
- if (n & 1)
- modifiers |= MOD_MASK_SHIFT;
- if (n & 2)
- modifiers |= MOD_MASK_ALT;
- if (n & 4)
- modifiers |= MOD_MASK_CTRL;
- if (n & 8)
- modifiers |= MOD_MASK_META;
-
- slen = j;
- }
- key_name[0] = termcodes[idx].name[0];
- key_name[1] = termcodes[idx].name[1];
- break;
- }
- }
- }
- }
-
- if (key_name[0] == NUL
- /* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */
- || key_name[0] == KS_URXVT_MOUSE
- || u7_status == U7_SENT
- ) {
- /* Check for some responses from terminal start with "<Esc>[" or
- * CSI.
- *
- * - xterm version string: <Esc>[>{x};{vers};{y}c
- * Also eat other possible responses to t_RV, rxvt returns
- * "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
- * mrxvt has been reported to have "+" in the version. Assume
- * the escape sequence ends with a letter or one of "{|}~".
- *
- * - cursor position report: <Esc>[{row};{col}R
- * The final byte is 'R'. now it is only used for checking for
- * ambiguous-width character state.
- */
- p = tp[0] == CSI ? tp + 1 : tp + 2;
- if ((*T_CRV != NUL || *T_U7 != NUL)
- && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
- || (tp[0] == CSI && len >= 2))
- && (VIM_ISDIGIT(*p) || *p == '>' || *p == '?')) {
- int col;
- int row_char = 0;
- j = 0;
- extra = 0;
- for (i = 2 + (tp[0] != CSI); i < len
- && !(tp[i] >= '{' && tp[i] <= '~')
- && !ASCII_ISALPHA(tp[i]); ++i)
- if (tp[i] == ';' && ++j == 1) {
- extra = i + 1;
- row_char = tp[i - 1];
- }
- if (i == len) {
- LOG_TR("Not enough characters for CRV");
- return -1;
- }
- if (extra > 0) {
- col = atoi((char *)tp + extra);
- } else {
- col = 0;
- }
-
- /* Eat it when it has 2 arguments and ends in 'R'. Also when
- * u7_status is not "sent", it may be from a previous Vim that
- * just exited. But not for <S-F3>, it sends something
- * similar, check for row and column to make sense. */
- if (j == 1 && tp[i] == 'R' && row_char == '2' && col >= 2) {
- char *aw = NULL;
-
- LOG_TR("Received U7 status");
- u7_status = U7_GOT;
- did_cursorhold = TRUE;
- if (col == 2) {
- aw = "single";
- } else if (col == 3) {
- aw = "double";
- }
-
- if (aw != NULL && STRCMP(aw, p_ambw) != 0) {
- /* Setting the option causes a screen redraw. Do that
- * right away if possible, keeping any messages. */
- set_option_value((char_u *)"ambw", 0L, (char_u *)aw, 0);
-#ifdef DEBUG_TERMRESPONSE
- {
- char buf[100];
- int r = redraw_asap(CLEAR);
-
- sprintf(buf, "set 'ambiwidth', redraw_asap(): %d",
- r);
- log_tr(buf);
- }
-#else
- redraw_asap(CLEAR);
-#endif
- }
- key_name[0] = (int)KS_EXTRA;
- key_name[1] = (int)KE_IGNORE;
- slen = i + 1;
- } else
- /* eat it when at least one digit and ending in 'c' */
- if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c') {
- LOG_TR("Received CRV");
- crv_status = CRV_GOT;
- did_cursorhold = TRUE;
-
- /* If this code starts with CSI, you can bet that the
- * terminal uses 8-bit codes. */
- if (tp[0] == CSI)
- switch_to_8bit();
-
- /* rxvt sends its version number: "20703" is 2.7.3.
- * Ignore it for when the user has set 'term' to xterm,
- * even though it's an rxvt. */
- if (extra > 0)
- extra = atoi((char *)tp + extra);
- if (extra > 20000)
- extra = 0;
-
- if (tp[1 + (tp[0] != CSI)] == '>' && j == 2) {
- /* Only set 'ttymouse' automatically if it was not set
- * by the user already. */
- if (!option_was_set((char_u *)"ttym")) {
-# ifdef TTYM_SGR
- if (extra >= 277)
- set_option_value((char_u *)"ttym", 0L,
- (char_u *)"sgr", 0);
- else
-# endif
- /* if xterm version >= 95 use mouse dragging */
- if (extra >= 95)
- set_option_value((char_u *)"ttym", 0L,
- (char_u *)"xterm2", 0);
- }
-
- /* if xterm version >= 141 try to get termcap codes */
- if (extra >= 141) {
- LOG_TR("Enable checking for XT codes");
- check_for_codes = TRUE;
- need_gather = true;
- req_codes_from_term();
- }
- }
- set_vim_var_string(VV_TERMRESPONSE, tp, i + 1);
- apply_autocmds(EVENT_TERMRESPONSE,
- NULL, NULL, FALSE, curbuf);
- key_name[0] = (int)KS_EXTRA;
- key_name[1] = (int)KE_IGNORE;
- slen = i + 1;
- }
- }
- /* Check for '<Esc>P1+r<hex bytes><Esc>\'. A "0" instead of the
- * "1" means an invalid request. */
- else if (check_for_codes
- && ((tp[0] == ESC && tp[1] == 'P' && len >= 2)
- || tp[0] == DCS)) {
- j = 1 + (tp[0] != DCS);
- for (i = j; i < len; ++i)
- if ((tp[i] == ESC && tp[i + 1] == '\\' && i + 1 < len)
- || tp[i] == STERM) {
- if (i - j >= 3 && tp[j + 1] == '+' && tp[j + 2] == 'r')
- got_code_from_term(tp + j, i);
- key_name[0] = (int)KS_EXTRA;
- key_name[1] = (int)KE_IGNORE;
- slen = i + 1 + (tp[i] == ESC);
- break;
- }
-
- if (i == len) {
- LOG_TR("not enough characters for XT");
- return -1; /* not enough characters */
- }
- }
- }
-
- if (key_name[0] == NUL)
- continue; /* No match at this position, try next one */
-
- /* We only get here when we have a complete termcode match */
-
- /*
- * If it is a mouse click, get the coordinates.
- */
- if (key_name[0] == KS_MOUSE
- || key_name[0] == KS_NETTERM_MOUSE
- || key_name[0] == KS_DEC_MOUSE
- || key_name[0] == KS_URXVT_MOUSE
- || key_name[0] == KS_SGR_MOUSE
- ) {
- is_click = is_drag = FALSE;
-
-# if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
- || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
- if (key_name[0] == (int)KS_MOUSE) {
- /*
- * For xterm we get "<t_mouse>scr", where
- * s == encoded button state:
- * 0x20 = left button down
- * 0x21 = middle button down
- * 0x22 = right button down
- * 0x23 = any button release
- * 0x60 = button 4 down (scroll wheel down)
- * 0x61 = button 5 down (scroll wheel up)
- * add 0x04 for SHIFT
- * add 0x08 for ALT
- * add 0x10 for CTRL
- * add 0x20 for mouse drag (0x40 is drag with left button)
- * c == column + ' ' + 1 == column + 33
- * r == row + ' ' + 1 == row + 33
- *
- * The coordinates are passed on through global variables.
- * Ugly, but this avoids trouble with mouse clicks at an
- * unexpected moment and allows for mapping them.
- */
- for (;; ) {
- {
- num_bytes = get_bytes_from_buf(tp + slen, bytes, 3);
- if (num_bytes == -1) /* not enough coordinates */
- return -1;
- mouse_code = bytes[0];
- mouse_col = bytes[1] - ' ' - 1;
- mouse_row = bytes[2] - ' ' - 1;
- }
- slen += num_bytes;
-
- /* If the following bytes is also a mouse code and it has
- * the same code, dump this one and get the next. This
- * makes dragging a whole lot faster. */
- j = termcodes[idx].len;
- if (STRNCMP(tp, tp + slen, (size_t)j) == 0
- && tp[slen + j] == mouse_code
- && tp[slen + j + 1] != NUL
- && tp[slen + j + 2] != NUL
- )
- slen += j;
- else
- break;
- }
- }
-
- if (key_name[0] == KS_URXVT_MOUSE
- || key_name[0] == KS_SGR_MOUSE) {
- for (;; ) {
- /* URXVT 1015 mouse reporting mode:
- * Almost identical to xterm mouse mode, except the values
- * are decimal instead of bytes.
- *
- * \033[%d;%d;%dM
- * ^-- row
- * ^----- column
- * ^-------- code
- *
- * SGR 1006 mouse reporting mode:
- * Almost identical to xterm mouse mode, except the values
- * are decimal instead of bytes.
- *
- * \033[<%d;%d;%dM
- * ^-- row
- * ^----- column
- * ^-------- code
- *
- * \033[<%d;%d;%dm : mouse release event
- * ^-- row
- * ^----- column
- * ^-------- code
- */
- p = tp + slen;
-
- mouse_code = getdigits_int(&p);
- if (*p++ != ';')
- return -1;
-
- /* when mouse reporting is SGR, add 32 to mouse code */
- if (key_name[0] == KS_SGR_MOUSE)
- mouse_code += 32;
-
- mouse_col = getdigits_int(&p) - 1;
- if (*p++ != ';')
- return -1;
-
- mouse_row = getdigits_int(&p) - 1;
- if (key_name[0] == KS_SGR_MOUSE && *p == 'm')
- mouse_code |= MOUSE_RELEASE;
- else if (*p != 'M')
- return -1;
- p++;
-
- slen += (int)(p - (tp + slen));
-
- /* skip this one if next one has same code (like xterm
- * case) */
- j = termcodes[idx].len;
- if (STRNCMP(tp, tp + slen, (size_t)j) == 0) {
- int slen2;
- int cmd_complete = 0;
-
- /* check if the command is complete by looking for the
- * 'M' */
- for (slen2 = slen; slen2 < len; slen2++) {
- if (tp[slen2] == 'M'
- || (key_name[0] == KS_SGR_MOUSE
- && tp[slen2] == 'm')) {
- cmd_complete = 1;
- break;
- }
- }
- p += j;
- if (cmd_complete && getdigits_int(&p) == mouse_code) {
- slen += j; /* skip the \033[ */
- continue;
- }
- }
- break;
- }
- }
-
- if (key_name[0] == (int)KS_MOUSE
- || key_name[0] == (int)KS_URXVT_MOUSE
- || key_name[0] == KS_SGR_MOUSE
- ) {
- /*
- * Handle mouse events.
- * Recognize the xterm mouse wheel, but not in the GUI, the
- * Linux console with GPM and the Win32 console
- * (multi-clicks use >= 0x60).
- */
- if (mouse_code >= MOUSEWHEEL_LOW
- ) {
- /* Keep the mouse_code before it's changed, so that we
- * remember that it was a mouse wheel click. */
- wheel_code = mouse_code;
- } else if (held_button == MOUSE_RELEASE
- && (mouse_code == 0x23 || mouse_code == 0x24)) {
- /* Apparently used by rxvt scroll wheel. */
- wheel_code = mouse_code - 0x23 + MOUSEWHEEL_LOW;
- }
-
-# if defined(UNIX) && defined(FEAT_MOUSE_TTY)
- else if (use_xterm_mouse() > 1) {
- if (mouse_code & MOUSE_DRAG_XTERM)
- mouse_code |= MOUSE_DRAG;
- }
-# endif
- }
-# endif /* !UNIX || FEAT_MOUSE_XTERM */
- if (key_name[0] == (int)KS_NETTERM_MOUSE) {
- int mc, mr;
-
- /* expect a rather limited sequence like: balancing {
- * \033}6,45\r
- * '6' is the row, 45 is the column
- */
- p = tp + slen;
- mr = getdigits_int(&p);
- if (*p++ != ',')
- return -1;
- mc = getdigits_int(&p);
- if (*p++ != '\r')
- return -1;
-
- mouse_col = mc - 1;
- mouse_row = mr - 1;
- mouse_code = MOUSE_LEFT;
- slen += (int)(p - (tp + slen));
- }
- if (key_name[0] == (int)KS_DEC_MOUSE) {
- /* The DEC Locator Input Model
- * Netterm delivers the code sequence:
- * \033[2;4;24;80&w (left button down)
- * \033[3;0;24;80&w (left button up)
- * \033[6;1;24;80&w (right button down)
- * \033[7;0;24;80&w (right button up)
- * CSI Pe ; Pb ; Pr ; Pc ; Pp & w
- * Pe is the event code
- * Pb is the button code
- * Pr is the row coordinate
- * Pc is the column coordinate
- * Pp is the third coordinate (page number)
- * Pe, the event code indicates what event caused this report
- * The following event codes are defined:
- * 0 - request, the terminal received an explicit request
- * for a locator report, but the locator is unavailable
- * 1 - request, the terminal received an explicit request
- * for a locator report
- * 2 - left button down
- * 3 - left button up
- * 4 - middle button down
- * 5 - middle button up
- * 6 - right button down
- * 7 - right button up
- * 8 - fourth button down
- * 9 - fourth button up
- * 10 - locator outside filter rectangle
- * Pb, the button code, ASCII decimal 0-15 indicating which
- * buttons are down if any. The state of the four buttons
- * on the locator correspond to the low four bits of the
- * decimal value,
- * "1" means button depressed
- * 0 - no buttons down,
- * 1 - right,
- * 2 - middle,
- * 4 - left,
- * 8 - fourth
- * Pr is the row coordinate of the locator position in the page,
- * encoded as an ASCII decimal value.
- * If Pr is omitted, the locator position is undefined
- * (outside the terminal window for example).
- * Pc is the column coordinate of the locator position in the
- * page, encoded as an ASCII decimal value.
- * If Pc is omitted, the locator position is undefined
- * (outside the terminal window for example).
- * Pp is the page coordinate of the locator position
- * encoded as an ASCII decimal value.
- * The page coordinate may be omitted if the locator is on
- * page one (the default). We ignore it anyway.
- */
- int Pe, Pb, Pr, Pc;
-
- p = tp + slen;
-
- /* get event status */
- Pe = getdigits_int(&p);
- if (*p++ != ';')
- return -1;
-
- /* get button status */
- Pb = getdigits_int(&p);
- if (*p++ != ';')
- return -1;
-
- /* get row status */
- Pr = getdigits_int(&p);
- if (*p++ != ';')
- return -1;
-
- /* get column status */
- Pc = getdigits_int(&p);
-
- /* the page parameter is optional */
- if (*p == ';') {
- p++;
- (void)getdigits_int(&p);
- }
- if (*p++ != '&')
- return -1;
- if (*p++ != 'w')
- return -1;
-
- mouse_code = 0;
- switch (Pe) {
- case 0: return -1; /* position request while unavailable */
- case 1: /* a response to a locator position request includes
- the status of all buttons */
- Pb &= 7; /* mask off and ignore fourth button */
- if (Pb & 4)
- mouse_code = MOUSE_LEFT;
- if (Pb & 2)
- mouse_code = MOUSE_MIDDLE;
- if (Pb & 1)
- mouse_code = MOUSE_RIGHT;
- if (Pb) {
- held_button = mouse_code;
- mouse_code |= MOUSE_DRAG;
- }
- is_drag = TRUE;
- showmode();
- break;
- case 2: mouse_code = MOUSE_LEFT;
- break;
- case 3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
- break;
- case 4: mouse_code = MOUSE_MIDDLE;
- break;
- case 5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
- break;
- case 6: mouse_code = MOUSE_RIGHT;
- break;
- case 7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
- break;
- case 8: return -1; /* fourth button down */
- case 9: return -1; /* fourth button up */
- case 10: return -1; /* mouse outside of filter rectangle */
- default: return -1; /* should never occur */
- }
-
- mouse_col = Pc - 1;
- mouse_row = Pr - 1;
-
- slen += (int)(p - (tp + slen));
- }
-
- /* Interpret the mouse code */
- current_button = (mouse_code & MOUSE_CLICK_MASK);
- if (current_button == MOUSE_RELEASE
- && wheel_code == 0
- ) {
- /*
- * If we get a mouse drag or release event when
- * there is no mouse button held down (held_button ==
- * MOUSE_RELEASE), produce a K_IGNORE below.
- * (can happen when you hold down two buttons
- * and then let them go, or click in the menu bar, but not
- * on a menu, and drag into the text).
- */
- if ((mouse_code & MOUSE_DRAG) == MOUSE_DRAG)
- is_drag = TRUE;
- current_button = held_button;
- } else if (wheel_code == 0) {
- {
- static int orig_mouse_col = 0;
- static int orig_mouse_row = 0;
-
- static uint64_t orig_mouse_time = 0; // time of previous mouse click
- uint64_t mouse_time = os_hrtime(); // time of current mouse click
-
- // compute the time elapsed since the previous mouse click and
- // convert it from ns to ms because p_mouset is stored as ms
- long timediff = (long) (mouse_time - orig_mouse_time) / 1000000;
- orig_mouse_time = mouse_time;
-
- if (mouse_code == orig_mouse_code
- && timediff < p_mouset
- && orig_num_clicks != 4
- && orig_mouse_col == mouse_col
- && orig_mouse_row == mouse_row
- && ((orig_topline == curwin->w_topline
- && orig_topfill == curwin->w_topfill
- )
- /* Double click in tab pages line also works
- * when window contents changes. */
- || (mouse_row == 0 && firstwin->w_winrow > 0)
- )
- )
- ++orig_num_clicks;
- else
- orig_num_clicks = 1;
- orig_mouse_col = mouse_col;
- orig_mouse_row = mouse_row;
- orig_topline = curwin->w_topline;
- orig_topfill = curwin->w_topfill;
- }
- is_click = TRUE;
- orig_mouse_code = mouse_code;
- }
- if (!is_drag)
- held_button = mouse_code & MOUSE_CLICK_MASK;
-
- /*
- * Translate the actual mouse event into a pseudo mouse event.
- * First work out what modifiers are to be used.
- */
- if (orig_mouse_code & MOUSE_SHIFT)
- modifiers |= MOD_MASK_SHIFT;
- if (orig_mouse_code & MOUSE_CTRL)
- modifiers |= MOD_MASK_CTRL;
- if (orig_mouse_code & MOUSE_ALT)
- modifiers |= MOD_MASK_ALT;
- if (orig_num_clicks == 2)
- modifiers |= MOD_MASK_2CLICK;
- else if (orig_num_clicks == 3)
- modifiers |= MOD_MASK_3CLICK;
- else if (orig_num_clicks == 4)
- modifiers |= MOD_MASK_4CLICK;
-
- /* Work out our pseudo mouse event */
- key_name[0] = (int)KS_EXTRA;
- if (wheel_code != 0) {
- if (wheel_code & MOUSE_CTRL)
- modifiers |= MOD_MASK_CTRL;
- if (wheel_code & MOUSE_ALT)
- modifiers |= MOD_MASK_ALT;
- key_name[1] = (wheel_code & 1)
- ? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
- } else {
- key_name[1] = (char_u)get_pseudo_mouse_code(current_button,
- is_click, is_drag);
- }
- }
-
-
- /*
- * Change <xHome> to <Home>, <xUp> to <Up>, etc.
- */
- key = handle_x_keys(TERMCAP2KEY(key_name[0], key_name[1]));
-
- /*
- * Add any modifier codes to our string.
- */
- new_slen = 0; /* Length of what will replace the termcode */
- if (modifiers != 0) {
- /* Some keys have the modifier included. Need to handle that here
- * to make mappings work. */
- key = simplify_key(key, &modifiers);
- if (modifiers != 0) {
- string[new_slen++] = K_SPECIAL;
- string[new_slen++] = (int)KS_MODIFIER;
- string[new_slen++] = (char_u)modifiers;
- }
- }
-
- /* Finally, add the special key code to our string */
- key_name[0] = (char_u)KEY2TERMCAP0(key);
- key_name[1] = (char_u)KEY2TERMCAP1(key);
- if (key_name[0] == KS_KEY) {
- /* from ":set <M-b>=xx" */
- if (has_mbyte)
- new_slen += (*mb_char2bytes)(key_name[1], string + new_slen);
- else
- string[new_slen++] = key_name[1];
- } else if (new_slen == 0 && key_name[0] == KS_EXTRA
- && key_name[1] == KE_IGNORE) {
- /* Do not put K_IGNORE into the buffer, do return KEYLEN_REMOVED
- * to indicate what happened. */
- retval = KEYLEN_REMOVED;
- } else {
- string[new_slen++] = K_SPECIAL;
- string[new_slen++] = key_name[0];
- string[new_slen++] = key_name[1];
- }
- string[new_slen] = NUL;
- extra = new_slen - slen;
- if (buf == NULL) {
- if (extra < 0)
- /* remove matched chars, taking care of noremap */
- del_typebuf(-extra, offset);
- else if (extra > 0)
- /* insert the extra space we need */
- ins_typebuf(string + slen, REMAP_YES, offset, FALSE, FALSE);
-
- /*
- * Careful: del_typebuf() and ins_typebuf() may have reallocated
- * typebuf.tb_buf[]!
- */
- memmove(typebuf.tb_buf + typebuf.tb_off + offset, string,
- (size_t)new_slen);
- } else {
- if (extra < 0)
- /* remove matched characters */
- memmove(buf + offset, buf + offset - extra,
- (size_t)(*buflen + offset + extra));
- else if (extra > 0) {
- /* Insert the extra space we need. If there is insufficient
- * space return -1. */
- if (*buflen + extra + new_slen >= bufsize)
- return -1;
- memmove(buf + offset + extra, buf + offset,
- (size_t)(*buflen - offset));
- }
- memmove(buf + offset, string, (size_t)new_slen);
- *buflen = *buflen + extra + new_slen;
- }
- return retval == 0 ? (len + extra + offset) : retval;
- }
-
- LOG_TR("normal character");
-
- return 0; /* no match found */
-}
-
-/*
* Replace any terminal code strings in from[] with the equivalent internal
* vim representation. This is used for the "from" and "to" part of a
* mapping, and the "to" part of a menu command.
@@ -3833,32 +1321,6 @@ ssize_t find_term_bykeys(char_u *src)
}
/*
- * Gather the first characters in the terminal key codes into a string.
- * Used to speed up check_termcode().
- */
-static void gather_termleader(void)
-{
- if (abstract_ui) {
- return;
- }
-
- int len = 0;
-
- if (check_for_codes)
- termleader[len++] = DCS; /* the termcode response starts with DCS
- in 8-bit mode */
- termleader[len] = NUL;
-
- for (size_t i = 0; i < tc_len; ++i)
- if (vim_strchr(termleader, termcodes[i].code[0]) == NULL) {
- termleader[len++] = termcodes[i].code[0];
- termleader[len] = NUL;
- }
-
- need_gather = false;
-}
-
-/*
* Show all termcodes (for ":set termcap")
* This code looks a lot like showoptions(), but is different.
*/
@@ -3977,171 +1439,6 @@ int show_one_termcode(char_u *name, char_u *code, int printit)
}
/*
- * For Xterm >= 140 compiled with OPT_TCAP_QUERY: Obtain the actually used
- * termcap codes from the terminal itself.
- * We get them one by one to avoid a very long response string.
- */
-static void req_codes_from_term(void)
-{
- xt_index_out = 0;
- xt_index_in = 0;
- req_more_codes_from_term();
-}
-
-static void req_more_codes_from_term(void)
-{
- char buf[11];
- int old_idx = xt_index_out;
-
- /* Don't do anything when going to exit. */
- if (exiting)
- return;
-
- /* Send up to 10 more requests out than we received. Avoid sending too
- * many, there can be a buffer overflow somewhere. */
- while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL) {
-# ifdef DEBUG_TERMRESPONSE
- char dbuf[100];
-
- sprintf(dbuf, "Requesting XT %d: %s",
- xt_index_out, key_names[xt_index_out]);
- log_tr(dbuf);
-# endif
- sprintf(buf, "\033P+q%02x%02x\033\\",
- key_names[xt_index_out][0], key_names[xt_index_out][1]);
- out_str_nf((char_u *)buf);
- ++xt_index_out;
- }
-
- /* Send the codes out right away. */
- if (xt_index_out != old_idx)
- out_flush();
-}
-
-/*
- * Decode key code response from xterm: '<Esc>P1+r<name>=<string><Esc>\'.
- * A "0" instead of the "1" indicates a code that isn't supported.
- * Both <name> and <string> are encoded in hex.
- * "code" points to the "0" or "1".
- */
-static void got_code_from_term(char_u *code, int len)
-{
-#define XT_LEN 100
- char_u name[3];
- char_u str[XT_LEN];
- ssize_t i;
- int j = 0;
- int c;
-
- /* A '1' means the code is supported, a '0' means it isn't.
- * When half the length is > XT_LEN we can't use it.
- * Our names are currently all 2 characters. */
- if (code[0] == '1' && code[7] == '=' && len / 2 < XT_LEN) {
- /* Get the name from the response and find it in the table. */
- int byte = hexhex2nr(code + 3);
- assert(byte != -1);
- name[0] = (char_u)byte;
- byte = hexhex2nr(code + 5);
- assert(byte != -1);
- name[1] = (char_u)byte;
- name[2] = NUL;
- for (i = 0; key_names[i] != NULL; ++i) {
- if (STRCMP(key_names[i], name) == 0) {
- assert(i <= INT_MAX);
- xt_index_in = (int)i;
- break;
- }
- }
-# ifdef DEBUG_TERMRESPONSE
- {
- char buf[100];
-
- sprintf(buf, "Received XT %d: %s", xt_index_in, (char *)name);
- log_tr(buf);
- }
-# endif
- if (key_names[i] != NULL) {
- for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2)
- str[j++] = (char_u)c;
- str[j] = NUL;
- if (name[0] == 'C' && name[1] == 'o') {
- /* Color count is not a key code. */
- int i = atoi((char *)str);
- if (i != t_colors) {
- /* Nr of colors changed, initialize highlighting and
- * redraw everything. This causes a redraw, which usually
- * clears the message. Try keeping the message if it
- * might work. */
- set_keep_msg_from_hist();
- set_color_count(i);
- init_highlight(TRUE, FALSE);
-#ifdef DEBUG_TERMRESPONSE
- {
- char buf[100];
- int r = redraw_asap(CLEAR);
-
- sprintf(buf, "Received t_Co, redraw_asap(): %d", r);
- log_tr(buf);
- }
-#else
- redraw_asap(CLEAR);
-#endif
- }
- } else {
- /* First delete any existing entry with the same code. */
- i = find_term_bykeys(str);
- if (i >= 0)
- del_termcode_idx((size_t)i);
- add_termcode(name, str, ATC_FROM_TERM);
- }
- }
- }
-
- /* May request more codes now that we received one. */
- ++xt_index_in;
- req_more_codes_from_term();
-}
-
-/*
- * Check if there are any unanswered requests and deal with them.
- * This is called before starting an external program or getting direct
- * keyboard input. We don't want responses to be send to that program or
- * handled as typed text.
- */
-static void check_for_codes_from_term(void)
-{
- int c;
-
- /* If no codes requested or all are answered, no need to wait. */
- if (xt_index_out == 0 || xt_index_out == xt_index_in)
- return;
-
- /* Vgetc() will check for and handle any response.
- * Keep calling vpeekc() until we don't get any responses. */
- ++no_mapping;
- ++allow_keys;
- for (;; ) {
- c = vpeekc();
- if (c == NUL) /* nothing available */
- break;
-
- /* If a response is recognized it's replaced with K_IGNORE, must read
- * it from the input stream. If there is no K_IGNORE we can't do
- * anything, break here (there might be some responses further on, but
- * we don't want to throw away any typed chars). */
- if (c != K_SPECIAL && c != K_IGNORE)
- break;
- c = vgetc();
- if (c != K_IGNORE) {
- vungetc(c);
- break;
- }
- }
- --no_mapping;
- --allow_keys;
-}
-
-/*
* Translate an internal mapping/abbreviation representation into the
* corresponding external one recognized by :map/:abbrev commands;
* respects the current B/k/< settings of 'cpoption'.
diff --git a/src/nvim/tui/term_input.inl b/src/nvim/tui/term_input.inl
new file mode 100644
index 0000000000..0c0e6c07c9
--- /dev/null
+++ b/src/nvim/tui/term_input.inl
@@ -0,0 +1,246 @@
+#include <termkey.h>
+
+#include "nvim/ascii.h"
+#include "nvim/os/os.h"
+#include "nvim/os/input.h"
+#include "nvim/os/rstream.h"
+
+
+struct term_input {
+ int in_fd;
+ TermKey *tk;
+ uv_tty_t input_handle;
+ uv_timer_t timer_handle;
+ RBuffer *read_buffer;
+ RStream *read_stream;
+};
+
+static void forward_simple_utf8(TermKeyKey *key)
+{
+ size_t len = 0;
+ char buf[64];
+ char *ptr = key->utf8;
+
+ while (*ptr) {
+ if (*ptr == '<') {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "<lt>");
+ } else {
+ buf[len++] = *ptr;
+ }
+ ptr++;
+ }
+
+ buf[len] = 0;
+ input_enqueue((String){.data = buf, .size = len});
+}
+
+static void forward_modified_utf8(TermKey *tk, TermKeyKey *key)
+{
+ size_t len;
+ char buf[64];
+
+ if (key->type == TERMKEY_TYPE_KEYSYM
+ && key->code.sym == TERMKEY_SYM_ESCAPE) {
+ len = (size_t)snprintf(buf, sizeof(buf), "<Esc>");
+ } else {
+ len = termkey_strfkey(tk, buf, sizeof(buf), key, TERMKEY_FORMAT_VIM);
+ }
+
+ input_enqueue((String){.data = buf, .size = len});
+}
+
+static void forward_mouse_event(TermKey *tk, TermKeyKey *key)
+{
+ char buf[64];
+ size_t len = 0;
+ int button, row, col;
+ TermKeyMouseEvent ev;
+ termkey_interpret_mouse(tk, key, &ev, &button, &row, &col);
+
+ if (ev != TERMKEY_MOUSE_PRESS && ev != TERMKEY_MOUSE_DRAG) {
+ return;
+ }
+
+ row--; col--; // Termkey uses 1-based coordinates
+ buf[len++] = '<';
+
+ if (key->modifiers & TERMKEY_KEYMOD_SHIFT) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "S-");
+ }
+
+ if (key->modifiers & TERMKEY_KEYMOD_CTRL) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "C-");
+ }
+
+ if (key->modifiers & TERMKEY_KEYMOD_ALT) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "A-");
+ }
+
+ if (button == 1) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Left");
+ } else if (button == 2) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Middle");
+ } else if (button == 3) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Right");
+ }
+
+ if (ev == TERMKEY_MOUSE_PRESS) {
+ if (button == 4) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp");
+ } else if (button == 5) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelDown");
+ } else {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse");
+ }
+ } else if (ev == TERMKEY_MOUSE_DRAG) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag");
+ }
+
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row);
+ input_enqueue((String){.data = buf, .size = len});
+}
+
+static TermKeyResult tk_getkey(TermKey *tk, TermKeyKey *key, bool force)
+{
+ return force ? termkey_getkey_force(tk, key) : termkey_getkey(tk, key);
+}
+
+static void timer_cb(uv_timer_t *handle);
+
+static int get_key_code_timeout(void)
+{
+ Integer ms = 0;
+ bool timeout = false;
+ // Check 'timeout' and 'ttimeout' to determine if we should send ESC
+ // after 'ttimeoutlen'. See :help 'ttimeout' for more information
+ Error err;
+ timeout = vim_get_option(cstr_as_string("timeout"), &err).data.boolean;
+ if (!timeout) {
+ timeout = vim_get_option(cstr_as_string("ttimeout"), &err).data.boolean;
+ }
+
+ if (timeout) {
+ ms = vim_get_option(cstr_as_string("ttimeoutlen"), &err).data.integer;
+ }
+
+ return (int)ms;
+}
+
+static void tk_getkeys(TermInput *input, bool force)
+{
+ TermKeyKey key;
+ TermKeyResult result;
+
+ while ((result = tk_getkey(input->tk, &key, force)) == TERMKEY_RES_KEY) {
+ if (key.type == TERMKEY_TYPE_UNICODE && !key.modifiers) {
+ forward_simple_utf8(&key);
+ } else if (key.type == TERMKEY_TYPE_UNICODE ||
+ key.type == TERMKEY_TYPE_FUNCTION ||
+ key.type == TERMKEY_TYPE_KEYSYM) {
+ forward_modified_utf8(input->tk, &key);
+ } else if (key.type == TERMKEY_TYPE_MOUSE) {
+ forward_mouse_event(input->tk, &key);
+ }
+ }
+
+ if (result != TERMKEY_RES_AGAIN) {
+ return;
+ }
+
+ int ms = get_key_code_timeout();
+
+ if (ms > 0) {
+ // Stop the current timer if already running
+ uv_timer_stop(&input->timer_handle);
+ uv_timer_start(&input->timer_handle, timer_cb, (uint32_t)ms, 0);
+ } else {
+ tk_getkeys(input, true);
+ }
+}
+
+
+static void timer_cb(uv_timer_t *handle)
+{
+ tk_getkeys(handle->data, true);
+}
+
+static void read_cb(RStream *rstream, void *rstream_data, bool eof)
+{
+ if (eof) {
+ input_done();
+ return;
+ }
+
+ TermInput *input = rstream_data;
+
+ do {
+ char *ptr = rbuffer_read_ptr(input->read_buffer);
+ size_t len = rbuffer_pending(input->read_buffer);
+ if (len > 1 && ptr[0] == ESC && ptr[1] == NUL) {
+ // skip the ESC and NUL and push one <esc> to the input buffer
+ termkey_push_bytes(input->tk, ptr, 1);
+ rbuffer_consumed(input->read_buffer, 2);
+ tk_getkeys(input, true);
+ continue;
+ }
+ // Find the next 'esc' and push everything up to it(excluding)
+ size_t i;
+ for (i = ptr[0] == ESC ? 1 : 0; i < len; i++) {
+ if (ptr[i] == '\x1b') {
+ break;
+ }
+ }
+ size_t consumed = termkey_push_bytes(input->tk, ptr, i);
+ rbuffer_consumed(input->read_buffer, consumed);
+ tk_getkeys(input, false);
+ } while (rbuffer_pending(input->read_buffer));
+}
+
+static TermInput *term_input_new(void)
+{
+ TermInput *rv = xmalloc(sizeof(TermInput));
+ // read input from stderr if stdin is not a tty
+ rv->in_fd = os_isatty(0) ? 0 : (os_isatty(2) ? 2 : 0);
+
+ // Set terminal encoding based on environment(taken from libtermkey source
+ // code)
+ const char *e;
+ int flags = 0;
+ if (((e = os_getenv("LANG")) || (e = os_getenv("LC_MESSAGES"))
+ || (e = os_getenv("LC_ALL"))) && (e = strchr(e, '.')) && e++ &&
+ (strcasecmp(e, "UTF-8") == 0 || strcasecmp(e, "UTF8") == 0)) {
+ flags |= TERMKEY_FLAG_UTF8;
+ } else {
+ flags |= TERMKEY_FLAG_RAW;
+ }
+
+ rv->tk = termkey_new_abstract(os_getenv("TERM"), flags);
+ int curflags = termkey_get_canonflags(rv->tk);
+ termkey_set_canonflags(rv->tk, curflags | TERMKEY_CANON_DELBS);
+ // setup input handle
+ uv_tty_init(uv_default_loop(), &rv->input_handle, rv->in_fd, 1);
+ uv_tty_set_mode(&rv->input_handle, UV_TTY_MODE_RAW);
+ rv->input_handle.data = NULL;
+ rv->read_buffer = rbuffer_new(0xfff);
+ rv->read_stream = rstream_new(read_cb, rv->read_buffer, rv);
+ rstream_set_stream(rv->read_stream, (uv_stream_t *)&rv->input_handle);
+ rstream_start(rv->read_stream);
+ // initialize a timer handle for handling ESC with libtermkey
+ uv_timer_init(uv_default_loop(), &rv->timer_handle);
+ rv->timer_handle.data = rv;
+ return rv;
+}
+
+static void term_input_destroy(TermInput *input)
+{
+ uv_tty_reset_mode();
+ uv_timer_stop(&input->timer_handle);
+ rstream_stop(input->read_stream);
+ rstream_free(input->read_stream);
+ uv_close((uv_handle_t *)&input->input_handle, NULL);
+ uv_close((uv_handle_t *)&input->timer_handle, NULL);
+ termkey_destroy(input->tk);
+ event_poll(0); // Run once to remove references to input/timer handles
+ free(input->input_handle.data);
+ free(input);
+}
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
new file mode 100644
index 0000000000..720970c424
--- /dev/null
+++ b/src/nvim/tui/tui.c
@@ -0,0 +1,752 @@
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <uv.h>
+#include <unibilium.h>
+
+#include "nvim/lib/kvec.h"
+
+#include "nvim/vim.h"
+#include "nvim/ui.h"
+#include "nvim/map.h"
+#include "nvim/memory.h"
+#include "nvim/api/vim.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/os/event.h"
+#include "nvim/tui/tui.h"
+
+typedef struct term_input TermInput;
+
+#include "term_input.inl"
+
+typedef struct {
+ int top, bot, left, right;
+} Rect;
+
+typedef struct {
+ char data[7];
+ HlAttrs attrs;
+} Cell;
+
+typedef struct {
+ PMap(cstr_t) *option_cache;
+ unibi_var_t params[9];
+ char buf[0xffff];
+ size_t bufpos;
+ TermInput *input;
+ uv_loop_t *write_loop;
+ unibi_term *ut;
+ uv_tty_t output_handle;
+ uv_signal_t winch_handle;
+ Rect scroll_region;
+ kvec_t(Rect) invalid_regions;
+ int row, col;
+ int bg, fg;
+ int out_fd;
+ int old_height;
+ bool can_use_terminal_scroll;
+ HlAttrs attrs, print_attrs;
+ Cell **screen;
+ struct {
+ size_t enable_mouse, disable_mouse;
+ } unibi_ext;
+} TUIData;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "tui/tui.c.generated.h"
+#endif
+
+#define EMPTY_ATTRS ((HlAttrs){false, false, false, false, false, -1, -1})
+
+#define FOREACH_CELL(ui, top, bot, left, right, go, code) \
+ do { \
+ TUIData *data = ui->data; \
+ for (int row = top; row <= bot; ++row) { \
+ Cell *cells = data->screen[row]; \
+ if (go) { \
+ unibi_goto(ui, row, left); \
+ } \
+ for (int col = left; col <= right; ++col) { \
+ Cell *cell = cells + col; \
+ (void)(cell); \
+ code; \
+ } \
+ } \
+ } while (0)
+
+
+void tui_start(void)
+{
+ TUIData *data = xcalloc(1, sizeof(TUIData));
+ UI *ui = xcalloc(1, sizeof(UI));
+ ui->data = data;
+ data->attrs = data->print_attrs = EMPTY_ATTRS;
+ data->fg = data->bg = -1;
+ data->can_use_terminal_scroll = true;
+ data->bufpos = 0;
+ data->option_cache = pmap_new(cstr_t)();
+
+ // write output to stderr if stdout is not a tty
+ data->out_fd = os_isatty(1) ? 1 : (os_isatty(2) ? 2 : 1);
+ kv_init(data->invalid_regions);
+ // setup term input
+ data->input = term_input_new();
+ // setup unibilium
+ data->ut = unibi_from_env();
+ if (!data->ut) {
+ // For some reason could not read terminfo file, use a dummy entry that
+ // will be populated with common values by fix_terminfo below
+ data->ut = unibi_dummy();
+ }
+ fix_terminfo(data);
+ // Enter alternate screen and clear
+ unibi_out(ui, unibi_enter_ca_mode, NULL);
+ unibi_out(ui, unibi_clear_screen, NULL);
+
+ // setup output handle in a separate event loop(we wanna do synchronous
+ // write to the tty)
+ data->write_loop = xmalloc(sizeof(uv_loop_t));
+ uv_loop_init(data->write_loop);
+ uv_tty_init(data->write_loop, &data->output_handle, data->out_fd, 0);
+
+ // Obtain screen dimensions
+ update_size(ui);
+
+ // listen for SIGWINCH
+ uv_signal_init(uv_default_loop(), &data->winch_handle);
+ uv_signal_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
+ data->winch_handle.data = ui;
+
+ ui->stop = tui_stop;
+ ui->rgb = false;
+ ui->data = data;
+ ui->resize = tui_resize;
+ ui->clear = tui_clear;
+ ui->eol_clear = tui_eol_clear;
+ ui->cursor_goto = tui_cursor_goto;
+ ui->cursor_on = tui_cursor_on;
+ ui->cursor_off = tui_cursor_off;
+ ui->mouse_on = tui_mouse_on;
+ ui->mouse_off = tui_mouse_off;
+ ui->insert_mode = tui_insert_mode;
+ ui->normal_mode = tui_normal_mode;
+ ui->set_scroll_region = tui_set_scroll_region;
+ ui->scroll = tui_scroll;
+ ui->highlight_set = tui_highlight_set;
+ ui->put = tui_put;
+ ui->bell = tui_bell;
+ ui->visual_bell = tui_visual_bell;
+ ui->update_fg = tui_update_fg;
+ ui->update_bg = tui_update_bg;
+ ui->flush = tui_flush;
+ ui->suspend = tui_suspend;
+ ui->set_title = tui_set_title;
+ ui->set_icon = tui_set_icon;
+ // Attach
+ ui_attach(ui);
+}
+
+static void tui_stop(UI *ui)
+{
+ TUIData *data = ui->data;
+ // Destroy common stuff
+ kv_destroy(data->invalid_regions);
+ uv_signal_stop(&data->winch_handle);
+ uv_close((uv_handle_t *)&data->winch_handle, NULL);
+ // Destroy input stuff
+ term_input_destroy(data->input);
+ // Destroy output stuff
+ tui_normal_mode(ui);
+ tui_mouse_off(ui);
+ unibi_out(ui, unibi_exit_attribute_mode, NULL);
+ unibi_out(ui, unibi_cursor_normal, NULL);
+ unibi_out(ui, unibi_exit_ca_mode, NULL);
+ flush_buf(ui);
+ uv_close((uv_handle_t *)&data->output_handle, NULL);
+ uv_run(data->write_loop, UV_RUN_DEFAULT);
+ if (uv_loop_close(data->write_loop)) {
+ abort();
+ }
+ free(data->write_loop);
+ unibi_destroy(data->ut);
+ char *opt_value;
+ map_foreach_value(data->option_cache, opt_value, {
+ free(opt_value);
+ });
+ pmap_free(cstr_t)(data->option_cache);
+ destroy_screen(data);
+ free(data);
+ free(ui);
+ ui_detach(ui);
+}
+
+static void try_resize(Event ev)
+{
+ UI *ui = ev.data;
+ update_size(ui);
+ ui_refresh();
+}
+
+static void sigwinch_cb(uv_signal_t *handle, int signum)
+{
+ // Queue the event because resizing can result in recursive event_poll calls
+ event_push((Event) {
+ .data = handle->data,
+ .handler = try_resize
+ }, false);
+}
+
+static bool attrs_differ(HlAttrs a1, HlAttrs a2)
+{
+ return a1.foreground != a2.foreground || a1.background != a2.background
+ || a1.bold != a2.bold || a1.italic != a2.italic
+ || a1.undercurl != a2.undercurl || a1.underline != a2.underline
+ || a1.reverse != a2.reverse;
+}
+
+static void update_attrs(UI *ui, HlAttrs attrs)
+{
+ TUIData *data = ui->data;
+ unibi_out(ui, unibi_exit_attribute_mode, NULL);
+
+ data->params[0].i = attrs.foreground != -1 ? attrs.foreground : data->fg;
+ if (data->params[0].i != -1) {
+ unibi_out(ui, unibi_set_a_foreground, NULL);
+ }
+
+ data->params[0].i = attrs.background != -1 ? attrs.background : data->bg;
+ if (data->params[0].i != -1) {
+ unibi_out(ui, unibi_set_a_background, NULL);
+ }
+
+ if (attrs.bold) {
+ unibi_out(ui, unibi_enter_bold_mode, NULL);
+ }
+ if (attrs.italic) {
+ unibi_out(ui, unibi_enter_italics_mode, NULL);
+ }
+ if (attrs.underline) {
+ unibi_out(ui, unibi_enter_underline_mode, NULL);
+ }
+ if (attrs.reverse) {
+ unibi_out(ui, unibi_enter_reverse_mode, NULL);
+ }
+}
+
+static void print_cell(UI *ui, Cell *ptr)
+{
+ TUIData *data = ui->data;
+ if (attrs_differ(ptr->attrs, data->print_attrs)) {
+ update_attrs(ui, ptr->attrs);
+ data->print_attrs = ptr->attrs;
+ }
+ out(ui, ptr->data);
+}
+
+static void clear_region(UI *ui, int top, int bot, int left, int right,
+ bool refresh)
+{
+ TUIData *data = ui->data;
+ HlAttrs clear_attrs = EMPTY_ATTRS;
+ clear_attrs.foreground = data->fg;
+ clear_attrs.background = data->bg;
+
+ bool cleared = false;
+ if (refresh && data->bg == -1 && right == ui->width -1) {
+ // Background is set to the default color and the right edge matches the
+ // screen end, try to use terminal codes for clearing the requested area.
+ if (left == 0) {
+ if (bot == ui->height - 1) {
+ if (top == 0) {
+ unibi_out(ui, unibi_clear_screen, NULL);
+ } else {
+ unibi_goto(ui, top, 0);
+ unibi_out(ui, unibi_clr_eos, NULL);
+ }
+ cleared = true;
+ }
+ }
+
+ if (!cleared) {
+ // iterate through each line and clear with clr_eol
+ for (int row = top; row <= bot; ++row) {
+ unibi_goto(ui, row, left);
+ unibi_out(ui, unibi_clr_eol, NULL);
+ }
+ cleared = true;
+ }
+ }
+
+ bool clear = refresh && !cleared;
+ FOREACH_CELL(ui, top, bot, left, right, clear, {
+ cell->data[0] = ' ';
+ cell->data[1] = 0;
+ cell->attrs = clear_attrs;
+ if (clear) {
+ print_cell(ui, cell);
+ }
+ });
+
+ // restore cursor
+ unibi_goto(ui, data->row, data->col);
+}
+
+static void tui_resize(UI *ui, int width, int height)
+{
+ TUIData *data = ui->data;
+ destroy_screen(data);
+
+ data->screen = xmalloc((size_t)height * sizeof(Cell *));
+ for (int i = 0; i < height; i++) {
+ data->screen[i] = xcalloc((size_t)width, sizeof(Cell));
+ }
+
+ data->old_height = height;
+ data->scroll_region.top = 0;
+ data->scroll_region.bot = height - 1;
+ data->scroll_region.left = 0;
+ data->scroll_region.right = width - 1;
+ data->row = data->col = 0;
+}
+
+static void tui_clear(UI *ui)
+{
+ TUIData *data = ui->data;
+ clear_region(ui, data->scroll_region.top, data->scroll_region.bot,
+ data->scroll_region.left, data->scroll_region.right, true);
+}
+
+static void tui_eol_clear(UI *ui)
+{
+ TUIData *data = ui->data;
+ clear_region(ui, data->row, data->row, data->col,
+ data->scroll_region.right, true);
+}
+
+static void tui_cursor_goto(UI *ui, int row, int col)
+{
+ TUIData *data = ui->data;
+ data->row = row;
+ data->col = col;
+ unibi_goto(ui, row, col);
+}
+
+static void tui_cursor_on(UI *ui)
+{
+ unibi_out(ui, unibi_cursor_normal, NULL);
+}
+
+static void tui_cursor_off(UI *ui)
+{
+ unibi_out(ui, unibi_cursor_invisible, NULL);
+}
+
+static void tui_mouse_on(UI *ui)
+{
+ TUIData *data = ui->data;
+ unibi_out(ui, (int)data->unibi_ext.enable_mouse, NULL);
+}
+
+static void tui_mouse_off(UI *ui)
+{
+ TUIData *data = ui->data;
+ unibi_out(ui, (int)data->unibi_ext.disable_mouse, NULL);
+}
+
+static void tui_insert_mode(UI *ui)
+{
+ unibi_out(ui, -1, "t_SI");
+}
+
+static void tui_normal_mode(UI *ui)
+{
+ unibi_out(ui, -1, "t_EI");
+}
+
+static void tui_set_scroll_region(UI *ui, int top, int bot, int left,
+ int right)
+{
+ TUIData *data = ui->data;
+ data->scroll_region.top = top;
+ data->scroll_region.bot = bot;
+ data->scroll_region.left = left;
+ data->scroll_region.right = right;
+
+ data->can_use_terminal_scroll =
+ left == 0 && right == ui->width - 1
+ && ((top == 0 && bot == ui->height - 1)
+ || unibi_get_str(data->ut, unibi_change_scroll_region));
+}
+
+static void tui_scroll(UI *ui, int count)
+{
+ TUIData *data = ui->data;
+ int top = data->scroll_region.top;
+ int bot = data->scroll_region.bot;
+ int left = data->scroll_region.left;
+ int right = data->scroll_region.right;
+
+ if (data->can_use_terminal_scroll) {
+ // Change terminal scroll region and move cursor to the top
+ data->params[0].i = top;
+ data->params[1].i = bot;
+ unibi_out(ui, unibi_change_scroll_region, NULL);
+ unibi_goto(ui, top, left);
+ }
+
+ // Compute start/stop/step for the loop below, also use terminal scroll
+ // if possible
+ int start, stop, step;
+ if (count > 0) {
+ start = top;
+ stop = bot - count + 1;
+ step = 1;
+ if (data->can_use_terminal_scroll) {
+ if (count == 1) {
+ unibi_out(ui, unibi_delete_line, NULL);
+ } else {
+ data->params[0].i = count;
+ unibi_out(ui, unibi_parm_delete_line, NULL);
+ }
+ }
+
+ } else {
+ start = bot;
+ stop = top - count - 1;
+ step = -1;
+ if (data->can_use_terminal_scroll) {
+ if (count == -1) {
+ unibi_out(ui, unibi_insert_line, NULL);
+ } else {
+ data->params[0].i = -count;
+ unibi_out(ui, unibi_parm_insert_line, NULL);
+ }
+ }
+ }
+
+ if (data->can_use_terminal_scroll) {
+ // Restore terminal scroll region and cursor
+ data->params[0].i = 0;
+ data->params[1].i = ui->height - 1;
+ unibi_out(ui, unibi_change_scroll_region, NULL);
+ unibi_goto(ui, data->row, data->col);
+ }
+
+ int i;
+ // Scroll internal screen
+ for (i = start; i != stop; i += step) {
+ Cell *target_row = data->screen[i] + left;
+ Cell *source_row = data->screen[i + count] + left;
+ memcpy(target_row, source_row, sizeof(Cell) * (size_t)(right - left + 1));
+ }
+
+ // clear emptied region, updating the terminal if its builtin scrolling
+ // facility was used. This is done when the background color is not the
+ // default, since scrolling may leave wrong background in the cleared area.
+ bool update_clear = data->bg != -1 && data->can_use_terminal_scroll;
+ if (count > 0) {
+ clear_region(ui, stop, stop + count - 1, left, right, update_clear);
+ } else {
+ clear_region(ui, stop + count + 1, stop, left, right, update_clear);
+ }
+
+ if (!data->can_use_terminal_scroll) {
+ // Mark the entire scroll region as invalid for redrawing later
+ invalidate(ui, data->scroll_region.top, data->scroll_region.bot,
+ data->scroll_region.left, data->scroll_region.right);
+ }
+}
+
+static void tui_highlight_set(UI *ui, HlAttrs attrs)
+{
+ ((TUIData *)ui->data)->attrs = attrs;
+}
+
+static void tui_put(UI *ui, uint8_t *text, size_t size)
+{
+ TUIData *data = ui->data;
+ Cell *cell = data->screen[data->row] + data->col;
+ cell->data[size] = 0;
+ cell->attrs = data->attrs;
+
+ if (text) {
+ memcpy(cell->data, text, size);
+ }
+
+ print_cell(ui, cell);
+ data->col += 1;
+}
+
+static void tui_bell(UI *ui)
+{
+ unibi_out(ui, unibi_bell, NULL);
+}
+
+static void tui_visual_bell(UI *ui)
+{
+ unibi_out(ui, unibi_flash_screen, NULL);
+}
+
+static void tui_update_fg(UI *ui, int fg)
+{
+ ((TUIData *)ui->data)->fg = fg;
+}
+
+static void tui_update_bg(UI *ui, int bg)
+{
+ ((TUIData *)ui->data)->bg = bg;
+}
+
+static void tui_flush(UI *ui)
+{
+ TUIData *data = ui->data;
+
+ while (kv_size(data->invalid_regions)) {
+ Rect r = kv_pop(data->invalid_regions);
+ FOREACH_CELL(ui, r.top, r.bot, r.left, r.right, true, {
+ print_cell(ui, cell);
+ });
+ }
+
+ unibi_goto(ui, data->row, data->col);
+ flush_buf(ui);
+}
+
+static void tui_suspend(UI *ui)
+{
+ tui_stop(ui);
+ kill(0, SIGTSTP);
+ tui_start();
+}
+
+static void tui_set_title(UI *ui, char *title)
+{
+ TUIData *data = ui->data;
+ if (!(unibi_get_str(data->ut, unibi_to_status_line)
+ && unibi_get_str(data->ut, unibi_from_status_line))) {
+ return;
+ }
+ unibi_out(ui, unibi_to_status_line, NULL);
+ out(ui, title);
+ unibi_out(ui, unibi_from_status_line, NULL);
+}
+
+static void tui_set_icon(UI *ui, char *icon)
+{
+}
+
+static void invalidate(UI *ui, int top, int bot, int left, int right)
+{
+ TUIData *data = ui->data;
+ Rect *intersects = NULL;
+ // Increase dimensions before comparing to ensure adjacent regions are
+ // treated as intersecting
+ --top;
+ ++bot;
+ --left;
+ ++right;
+
+ for (size_t i = 0; i < kv_size(data->invalid_regions); i++) {
+ Rect *r = &kv_A(data->invalid_regions, i);
+ if (!(top > r->bot || bot < r->top
+ || left > r->right || right < r->left)) {
+ intersects = r;
+ break;
+ }
+ }
+
+ ++top;
+ --bot;
+ ++left;
+ --right;
+
+ if (intersects) {
+ // If top/bot/left/right intersects with a invalid rect, we replace it
+ // by the union
+ intersects->top = MIN(top, intersects->top);
+ intersects->bot = MAX(bot, intersects->bot);
+ intersects->left = MIN(left, intersects->left);
+ intersects->right = MAX(right, intersects->right);
+ } else {
+ // Else just add a new entry;
+ kv_push(Rect, data->invalid_regions, ((Rect){top, bot, left, right}));
+ }
+}
+
+static void update_size(UI *ui)
+{
+ TUIData *data = ui->data;
+ int width = 0, height = 0;
+ // 1 - try from a system call(ioctl/TIOCGWINSZ on unix)
+ if (!uv_tty_get_winsize(&data->output_handle, &width, &height)) {
+ goto end;
+ }
+
+ // 2 - use $LINES/$COLUMNS if available
+ const char *val;
+ int advance;
+ if ((val = os_getenv("LINES"))
+ && sscanf(val, "%d%n", &height, &advance) != EOF && advance
+ && (val = os_getenv("COLUMNS"))
+ && sscanf(val, "%d%n", &width, &advance) != EOF && advance) {
+ goto end;
+ }
+
+ // 3- read from terminfo if available
+ height = unibi_get_num(data->ut, unibi_lines);
+ width = unibi_get_num(data->ut, unibi_columns);
+
+end:
+ if (width <= 0 || height <= 0) {
+ // use a default of 80x24
+ width = 80;
+ height = 24;
+ }
+
+ ui->width = width;
+ ui->height = height;
+}
+
+static void unibi_goto(UI *ui, int row, int col)
+{
+ TUIData *data = ui->data;
+ data->params[0].i = row;
+ data->params[1].i = col;
+ unibi_out(ui, unibi_cursor_address, NULL);
+}
+
+static void unibi_out(UI *ui, int unibi_index, char *nvim_override)
+{
+ TUIData *data = ui->data;
+
+ const char *str = NULL;
+
+ if (nvim_override) {
+ str = get_term_option(ui, nvim_override);
+ } else if (unibi_index >= 0) {
+ if (unibi_index < unibi_string_begin_) {
+ str = unibi_get_ext_str(data->ut, (unsigned)unibi_index);
+ } else {
+ str = unibi_get_str(data->ut, (unsigned)unibi_index);
+ }
+ }
+
+ if (str) {
+ data->bufpos += unibi_run(str, data->params, data->buf + data->bufpos,
+ sizeof(data->buf) - data->bufpos);
+ }
+}
+
+static void out(UI *ui, const char *str)
+{
+ TUIData *data = ui->data;
+ data->bufpos += (size_t)snprintf(data->buf + data->bufpos,
+ sizeof(data->buf) - data->bufpos, "%s", str);
+}
+
+static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str,
+ const char *val)
+{
+ if (!unibi_get_str(ut, str)) {
+ unibi_set_str(ut, str, val);
+ }
+}
+
+static void fix_terminfo(TUIData *data)
+{
+ unibi_term *ut = data->ut;
+
+ const char *term = os_getenv("TERM");
+ if (!term) {
+ goto end;
+ }
+
+#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1))
+
+ if (STARTS_WITH(term, "rxvt")) {
+ unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b[m\x1b(B");
+ unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<20/>\x1b[?5l");
+ unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
+ } else if (STARTS_WITH(term, "screen")) {
+ unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
+ }
+
+ if (STARTS_WITH(term, "xterm") || STARTS_WITH(term, "rxvt")) {
+ unibi_set_if_empty(ut, unibi_cursor_normal, "\x1b[?12l\x1b[?25h");
+ unibi_set_if_empty(ut, unibi_cursor_invisible, "\x1b[?25l");
+ unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<100/>\x1b[?5l");
+ unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b(B\x1b[m");
+ unibi_set_if_empty(ut, unibi_change_scroll_region, "\x1b[%i%p1%d;%p2%dr");
+ unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[2J");
+ unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]2");
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
+ }
+
+end:
+ // Fill some empty slots with common terminal strings
+ data->unibi_ext.enable_mouse = unibi_add_ext_str(ut, NULL,
+ "\x1b[?1002h\x1b[?1006h");
+ data->unibi_ext.disable_mouse = unibi_add_ext_str(ut, NULL,
+ "\x1b[?1002l\x1b[?1006l");
+
+ unibi_set_if_empty(ut, unibi_cursor_address, "\x1b[%i%p1%d;%p2%dH");
+ unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b[0;10m");
+ unibi_set_if_empty(ut, unibi_set_a_foreground,
+ "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m");
+ unibi_set_if_empty(ut, unibi_set_a_background,
+ "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m");
+ unibi_set_if_empty(ut, unibi_enter_bold_mode, "\x1b[1m");
+ unibi_set_if_empty(ut, unibi_enter_underline_mode, "\x1b[4m");
+ unibi_set_if_empty(ut, unibi_enter_reverse_mode, "\x1b[7m");
+ unibi_set_if_empty(ut, unibi_bell, "\x07");
+ unibi_set_if_empty(data->ut, unibi_enter_ca_mode, "\x1b[?1049h");
+ unibi_set_if_empty(data->ut, unibi_exit_ca_mode, "\x1b[?1049l");
+ unibi_set_if_empty(ut, unibi_delete_line, "\x1b[M");
+ unibi_set_if_empty(ut, unibi_parm_delete_line, "\x1b[%p1%dM");
+ unibi_set_if_empty(ut, unibi_insert_line, "\x1b[L");
+ unibi_set_if_empty(ut, unibi_parm_insert_line, "\x1b[%p1%dL");
+ unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[J");
+ unibi_set_if_empty(ut, unibi_clr_eol, "\x1b[K");
+ unibi_set_if_empty(ut, unibi_clr_eos, "\x1b[J");
+}
+
+static void flush_buf(UI *ui)
+{
+ static uv_write_t req;
+ static uv_buf_t buf;
+ TUIData *data = ui->data;
+ buf.base = data->buf;
+ buf.len = data->bufpos;
+ uv_write(&req, (uv_stream_t *)&data->output_handle, &buf, 1, NULL);
+ uv_run(data->write_loop, UV_RUN_DEFAULT);
+ data->bufpos = 0;
+}
+
+static char *get_term_option(UI *ui, char *option)
+{
+ TUIData *data = ui->data;
+
+ char *rv = pmap_get(cstr_t)(data->option_cache, option);
+ if (!rv) {
+ Error err;
+ Object val = vim_get_option(cstr_as_string(option), &err);
+ if (val.type == kObjectTypeString) {
+ rv = val.data.string.data;
+ pmap_put(cstr_t)(data->option_cache, option, rv);
+ }
+ }
+
+ return rv;
+}
+
+static void destroy_screen(TUIData *data)
+{
+ if (data->screen) {
+ for (int i = 0; i < data->old_height; i++) {
+ free(data->screen[i]);
+ }
+ free(data->screen);
+ }
+}
diff --git a/src/nvim/tui/tui.h b/src/nvim/tui/tui.h
new file mode 100644
index 0000000000..07523bc124
--- /dev/null
+++ b/src/nvim/tui/tui.h
@@ -0,0 +1,8 @@
+#ifndef NVIM_TUI_TUI_H
+#define NVIM_TUI_TUI_H
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "tui/tui.h.generated.h"
+#endif
+
+#endif // NVIM_TUI_TUI_H
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index a8ca58d633..af8989f397 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -46,6 +46,7 @@
#include "nvim/syntax.h"
#include "nvim/term.h"
#include "nvim/window.h"
+#include "nvim/tui/tui.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui.c.generated.h"
@@ -59,8 +60,8 @@ static int row, col;
static struct {
int top, bot, left, right;
} sr;
-static int current_highlight_mask = 0;
-static bool cursor_enabled = true;
+static int current_attr_code = 0;
+static bool cursor_enabled = true, pending_cursor_update = false;
static int height, width;
// This set of macros allow us to use UI_CALL to invoke any function on
@@ -71,6 +72,7 @@ static int height, width;
// works.
#define UI_CALL(...) \
do { \
+ flush_cursor_update(); \
for (size_t i = 0; i < ui_count; i++) { \
UI *ui = uis[i]; \
UI_CALL_HELPER(CNT(__VA_ARGS__), __VA_ARGS__); \
@@ -80,8 +82,18 @@ static int height, width;
#define SELECT_NTH(a1, a2, a3, a4, a5, a6, ...) a6
#define UI_CALL_HELPER(c, ...) UI_CALL_HELPER2(c, __VA_ARGS__)
#define UI_CALL_HELPER2(c, ...) UI_CALL_##c(__VA_ARGS__)
-#define UI_CALL_MORE(method, ...) ui->method(ui, __VA_ARGS__)
-#define UI_CALL_ZERO(method) ui->method(ui)
+#define UI_CALL_MORE(method, ...) if (ui->method) ui->method(ui, __VA_ARGS__)
+#define UI_CALL_ZERO(method) if (ui->method) ui->method(ui)
+
+void ui_builtin_start(void)
+{
+ tui_start();
+}
+
+void ui_builtin_stop(void)
+{
+ UI_CALL(stop);
+}
void ui_write(uint8_t *s, int len)
{
@@ -90,28 +102,7 @@ void ui_write(uint8_t *s, int len)
return;
}
- if (abstract_ui) {
- parse_abstract_ui_codes(s, len);
- return;
- }
-
- if (!len) {
- return;
- }
-
- char_u *tofree = NULL;
-
- if (output_conv.vc_type != CONV_NONE) {
- /* Convert characters from 'encoding' to 'termencoding'. */
- tofree = string_convert(&output_conv, s, &len);
- if (tofree != NULL)
- s = tofree;
- }
-
- term_write(s, len);
-
- if (output_conv.vc_type != CONV_NONE)
- free(tofree);
+ parse_abstract_ui_codes(s, len);
}
bool ui_rgb_attached(void)
@@ -124,6 +115,11 @@ bool ui_rgb_attached(void)
return false;
}
+bool ui_active(void)
+{
+ return ui_count != 0;
+}
+
/*
* If the machine has job control, use it to suspend the program,
* otherwise fake it by starting a new shell.
@@ -131,12 +127,8 @@ bool ui_rgb_attached(void)
*/
void ui_suspend(void)
{
- if (abstract_ui) {
- UI_CALL(suspend);
- UI_CALL(flush);
- } else {
- mch_suspend();
- }
+ UI_CALL(suspend);
+ UI_CALL(flush);
}
void ui_set_title(char *title)
@@ -152,46 +144,16 @@ void ui_set_icon(char *icon)
}
/*
- * Try to get the current Vim shell size. Put the result in Rows and Columns.
- * Use the new sizes as defaults for 'columns' and 'lines'.
- * Return OK when size could be determined, FAIL otherwise.
- */
-int ui_get_shellsize(void)
-{
- if (abstract_ui) {
- return FAIL;
- }
-
- int retval;
-
- retval = mch_get_shellsize();
-
- check_shellsize();
-
- /* adjust the default for 'lines' and 'columns' */
- if (retval == OK) {
- set_number_default("lines", Rows);
- set_number_default("columns", Columns);
- }
- return retval;
-}
-
-/*
* May update the shape of the cursor.
*/
void ui_cursor_shape(void)
{
- if (abstract_ui) {
- ui_change_mode();
- } else {
- term_cursor_shape();
- conceal_check_cursur_line();
- }
+ ui_change_mode();
}
void ui_refresh(void)
{
- if (!ui_count) {
+ if (!ui_active()) {
return;
}
@@ -203,7 +165,7 @@ void ui_refresh(void)
height = ui->height < height ? ui->height : height;
}
- screen_resize(width, height, true);
+ screen_resize(width, height);
}
void ui_resize(int new_width, int new_height)
@@ -241,20 +203,12 @@ void ui_cursor_off(void)
void ui_mouse_on(void)
{
- if (abstract_ui) {
- UI_CALL(mouse_on);
- } else {
- mch_setmouse(true);
- }
+ UI_CALL(mouse_on);
}
void ui_mouse_off(void)
{
- if (abstract_ui) {
- UI_CALL(mouse_off);
- } else {
- mch_setmouse(false);
- }
+ UI_CALL(mouse_off);
}
// Notify that the current mode has changed. Can be used to change cursor
@@ -319,77 +273,82 @@ void ui_detach(UI *ui)
}
}
-static void highlight_start(int mask)
+static void highlight_start(int attr_code)
{
- if (mask > HL_ALL) {
- // attribute code
- current_highlight_mask = mask;
- } else {
- // attribute mask
- current_highlight_mask |= mask;
- }
+ current_attr_code = attr_code;
if (!ui_count) {
return;
}
- set_highlight_args(current_highlight_mask);
+ set_highlight_args(current_attr_code);
}
static void highlight_stop(int mask)
{
- if (mask > HL_ALL) {
- // attribute code
- current_highlight_mask = HL_NORMAL;
- } else {
- // attribute mask
- current_highlight_mask &= ~mask;
+ current_attr_code = HL_NORMAL;
+
+ if (!ui_count) {
+ return;
}
- set_highlight_args(current_highlight_mask);
+ set_highlight_args(current_attr_code);
}
-static void set_highlight_args(int mask)
+static void set_highlight_args(int attr_code)
{
HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1 };
- attrentry_T *aep = NULL;
+ HlAttrs cterm_attrs = rgb_attrs;
- if (mask > HL_ALL) {
- aep = syn_cterm_attr2entry(mask);
- mask = aep ? aep->ae_attr : 0;
+ if (attr_code == HL_NORMAL) {
+ goto end;
}
- rgb_attrs.bold = mask & HL_BOLD;
- rgb_attrs.underline = mask & HL_UNDERLINE;
- rgb_attrs.undercurl = mask & HL_UNDERCURL;
- rgb_attrs.italic = mask & HL_ITALIC;
- rgb_attrs.reverse = mask & (HL_INVERSE | HL_STANDOUT);
- HlAttrs cterm_attrs = rgb_attrs;
+ int rgb_mask = 0;
+ int cterm_mask = 0;
+ attrentry_T *aep = syn_cterm_attr2entry(attr_code);
- if (aep) {
- if (aep->fg_color != normal_fg) {
- rgb_attrs.foreground = aep->fg_color;
- }
+ if (!aep) {
+ goto end;
+ }
- if (aep->bg_color != normal_bg) {
- rgb_attrs.background = aep->bg_color;
- }
+ rgb_mask = aep->rgb_ae_attr;
+ cterm_mask = aep->cterm_ae_attr;
+
+ rgb_attrs.bold = rgb_mask & HL_BOLD;
+ rgb_attrs.underline = rgb_mask & HL_UNDERLINE;
+ rgb_attrs.undercurl = rgb_mask & HL_UNDERCURL;
+ rgb_attrs.italic = rgb_mask & HL_ITALIC;
+ rgb_attrs.reverse = rgb_mask & (HL_INVERSE | HL_STANDOUT);
+ cterm_attrs.bold = cterm_mask & HL_BOLD;
+ cterm_attrs.underline = cterm_mask & HL_UNDERLINE;
+ cterm_attrs.undercurl = cterm_mask & HL_UNDERCURL;
+ cterm_attrs.italic = cterm_mask & HL_ITALIC;
+ cterm_attrs.reverse = cterm_mask & (HL_INVERSE | HL_STANDOUT);
+
+ if (aep->rgb_fg_color != normal_fg) {
+ rgb_attrs.foreground = aep->rgb_fg_color;
+ }
- if (cterm_normal_fg_color != aep->ae_u.cterm.fg_color) {
- cterm_attrs.foreground = aep->ae_u.cterm.fg_color - 1;
- }
+ if (aep->rgb_bg_color != normal_bg) {
+ rgb_attrs.background = aep->rgb_bg_color;
+ }
- if (cterm_normal_bg_color != aep->ae_u.cterm.bg_color) {
- cterm_attrs.background = aep->ae_u.cterm.bg_color - 1;
- }
+ if (cterm_normal_fg_color != aep->cterm_fg_color) {
+ cterm_attrs.foreground = aep->cterm_fg_color - 1;
}
+ if (cterm_normal_bg_color != aep->cterm_bg_color) {
+ cterm_attrs.background = aep->cterm_bg_color - 1;
+ }
+
+end:
UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs));
}
static void parse_abstract_ui_codes(uint8_t *ptr, int len)
{
- if (!ui_count) {
+ if (!ui_active()) {
return;
}
@@ -558,5 +517,13 @@ static void ui_cursor_goto(int new_row, int new_col)
}
row = new_row;
col = new_col;
- UI_CALL(cursor_goto, row, col);
+ pending_cursor_update = true;
+}
+
+static void flush_cursor_update(void)
+{
+ if (pending_cursor_update) {
+ pending_cursor_update = false;
+ UI_CALL(cursor_goto, row, col);
+ }
}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index 099f2643d5..4bc3983578 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -38,6 +38,7 @@ struct ui_t {
void (*suspend)(UI *ui);
void (*set_title)(UI *ui, char *title);
void (*set_icon)(UI *ui, char *icon);
+ void (*stop)(UI *ui);
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 748e2ded07..02d5f66260 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -136,21 +136,6 @@ static char *(features[]) = {
"+tag_binary",
"+tag_old_static",
"-tag_any_white",
-#if defined(UNIX)
-
- // only Unix can have terminfo instead of termcap
-# ifdef TERMINFO
- "+terminfo",
-# else // ifdef TERMINFO
- "-terminfo",
-# endif // ifdef TERMINFO
-#else // unix always includes termcap support
-# ifdef HAVE_TGETENT
- "+tgetent",
-# else // ifdef HAVE_TGETENT
- "-tgetent",
-# endif // ifdef HAVE_TGETENT
-#endif // if defined(UNIX)
"+termresponse",
"+textobjects",
"+title",
@@ -813,19 +798,6 @@ static char *(extra_patches[]) = {
NULL
};
-int highest_patch(void)
-{
- int i;
- int h = 0;
-
- for (i = 0; included_patches[i] != 0; ++i) {
- if (included_patches[i] > h) {
- h = included_patches[i];
- }
- }
- return h;
-}
-
/// Checks whether patch `n` has been included.
///
/// @param n The patch number.
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index a766d71553..be3f246ff4 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -8,7 +8,8 @@
#ifndef NVIM_VIM_H
# define NVIM_VIM_H
-#define min(X, Y) (X < Y ? X : Y)
+#define MIN(X, Y) (X < Y ? X : Y)
+#define MAX(X, Y) (X > Y ? X : Y)
#include "nvim/types.h"
#include "nvim/pos.h" // for linenr_T, MAXCOL, etc...
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index f3ac90de21..456252522d 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -4,6 +4,7 @@ local clear, nvim, buffer, curbuf, curbuf_contents, window, curwin, eq, neq,
ok, feed, rawfeed, insert, eval = helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf,
helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
helpers.neq, helpers.ok, helpers.feed, helpers.rawfeed, helpers.insert, helpers.eval
+local wait = helpers.wait
-- check if str is visible at the beginning of some line
local function is_visible(str)
@@ -55,6 +56,7 @@ describe('window_* functions', function()
insert("epilogue")
win = curwin()
feed('gg')
+ wait() -- let nvim process the 'gg' command
-- cursor position is at beginning
eq({1, 0}, window('get_cursor', win))
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index ea98ff4ce3..fc6bf80d7e 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -229,11 +229,15 @@ local function curbuf(method, ...)
return buffer(method, buf, ...)
end
+local function wait()
+ session:request('vim_eval', '1')
+end
+
local function curbuf_contents()
-- Before inspecting the buffer, execute 'vim_eval' to wait until all
-- previously sent keys are processed(vim_eval is a deferred function, and
-- only processed after all input)
- session:request('vim_eval', '1')
+ wait()
return table.concat(curbuf('get_line_slice', 0, -1, true, true), '\n')
end
@@ -284,5 +288,6 @@ return {
curbuf = curbuf,
curwin = curwin,
curtab = curtab,
- curbuf_contents = curbuf_contents
+ curbuf_contents = curbuf_contents,
+ wait = wait
}
diff --git a/test/functional/legacy/051_highlight_spec.lua b/test/functional/legacy/051_highlight_spec.lua
index f35b70f93f..19eb4104cd 100644
--- a/test/functional/legacy/051_highlight_spec.lua
+++ b/test/functional/legacy/051_highlight_spec.lua
@@ -1,23 +1,44 @@
-- vim: set foldmethod=marker foldmarker=[[,]] :
-- Tests for ":highlight".
+local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
+local wait = helpers.wait
describe(':highlight', function()
setup(clear)
it('is working', function()
+ local screen = Screen.new(35, 10)
+ screen:attach()
-- Basic test if ":highlight" doesn't crash
execute('highlight')
+ -- FIXME(tarruda): We need to be sure the prompt is displayed before
+ -- continuing, or risk a race condition where some of the following input
+ -- is discarded resulting in test failure
+ screen:expect([[
+ :highlight |
+ SpecialKey xxx ctermfg=4 |
+ guifg=Blue |
+ EndOfBuffer xxx links to NonText|
+ |
+ NonText xxx ctermfg=12 |
+ gui=bold |
+ guifg=Blue |
+ Directory xxx ctermfg=4 |
+ -- More --^ |
+ ]])
+ feed('q')
+ wait() -- wait until we're back to normal
execute('hi Search')
-- Test setting colors.
-- Test clearing one color and all doesn't generate error or warning
- execute('hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan')
- execute('hi Group2 term= cterm=')
- execute('hi Group3 term=underline cterm=bold')
+ execute('hi NewGroup cterm=italic ctermfg=DarkBlue ctermbg=Grey gui=NONE guifg=#00ff00 guibg=Cyan')
+ execute('hi Group2 cterm=NONE')
+ execute('hi Group3 cterm=bold')
execute('redir! @a')
execute('hi NewGroup')
execute('hi Group2')
@@ -29,7 +50,7 @@ describe(':highlight', function()
execute('hi Group2')
execute('hi clear')
execute('hi Group3')
- execute([[hi Crash term='asdf]])
+ execute([[hi Crash cterm='asdf]])
execute('redir END')
-- Filter ctermfg and ctermbg, the numbers depend on the terminal
@@ -48,11 +69,15 @@ describe(':highlight', function()
expect([[
- NewGroup xxx term=bold cterm=italic ctermfg=2 ctermbg=3
+ NewGroup xxx cterm=italic
+ ctermfg=2
+ ctermbg=3
+ guifg=#00ff00
+ guibg=Cyan
Group2 xxx cleared
- Group3 xxx term=underline cterm=bold
+ Group3 xxx cterm=bold
NewGroup xxx cleared
@@ -65,6 +90,7 @@ describe(':highlight', function()
Group3 xxx cleared
- E475: term='asdf]])
+ E475: cterm='asdf]])
+ screen:detach()
end)
end)
diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua
index b35f070159..85c055d3be 100644
--- a/test/functional/shell/viml_system_spec.lua
+++ b/test/functional/shell/viml_system_spec.lua
@@ -77,27 +77,7 @@ describe('system()', function()
]])
end)
- it('`yes` and is directly interrupted with CTRL-C', function()
- feed(':call system("yes")<cr><c-c>')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- Type :quit<Enter> to exit Vim |
- ]])
- end)
-
- it('`yes` and is a little bit later interrupted with CTRL-C', function()
+ it('`yes` and is interrupted with CTRL-C', function()
feed(':call system("yes")<cr>')
feed('<c-c>')
screen:expect([[
@@ -247,26 +227,6 @@ describe('systemlist()', function()
]])
end)
- it('`yes` and is directly interrupted with CTRL-C', function()
- feed(':call systemlist("yes | xargs")<cr><c-c>')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- Type :quit<Enter> to exit Vim |
- ]])
- end)
-
it('`yes` and is a little bit later interrupted with CTRL-C', function()
feed(':call systemlist("yes | xargs")<cr>')
feed('<c-c>')
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index cd8c2bc399..a20907791b 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -116,7 +116,11 @@ local debug_screen
local default_screen_timeout = 2500
if os.getenv('VALGRIND') then
- default_screen_timeout = 7500
+ default_screen_timeout = default_screen_timeout * 3
+end
+
+if os.getenv('CI_TARGET') then
+ default_screen_timeout = default_screen_timeout * 3
end
local colors = request('vim_get_color_map')