aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval/encode.c2
-rw-r--r--src/nvim/misc1.c2
-rw-r--r--src/nvim/ops.c2
-rw-r--r--src/nvim/os/input.c4
-rw-r--r--src/nvim/tui/input.c7
-rw-r--r--src/nvim/tui/input.h3
-rw-r--r--src/nvim/tui/tui.c58
-rw-r--r--src/nvim/version.c2
8 files changed, 72 insertions, 8 deletions
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 61d7a38007..5af4893975 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -319,7 +319,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
do { \
int i; \
ga_concat(gap, "function("); \
- if (&pt->pt_name != NULL) { \
+ if (pt->pt_name != NULL) { \
size_t len; \
char_u *p; \
len = 3; \
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 4ab059c923..71aa6e83e5 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -566,7 +566,7 @@ open_line (
int i;
int l;
- for (i = 0; p[i] != NUL && i < lead_len; i += l) {
+ for (i = 0; i < lead_len && p[i] != NUL; i += l) {
l = (*mb_ptr2len)(p + i);
if (vim_strnsize(p, i + l) > repl_size)
break;
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index dfa89acb1a..9e95c1a3e7 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -4607,7 +4607,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
goto theend;
}
ptr = buf1;
- if (negative && (!visual || (visual && was_positive))) {
+ if (negative && (!visual || was_positive)) {
*ptr++ = '-';
}
if (pre) {
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 1307ab5e5a..b60a7eed36 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -39,8 +39,6 @@ static int events_enabled = 0;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/input.c.generated.h"
#endif
-// Helper function used to push bytes from the 'event' key sequence partially
-// between calls to os_inchar when maxlen < 3
void input_init(void)
{
@@ -389,6 +387,8 @@ static void process_interrupts(void)
}
}
+// Helper function used to push bytes from the 'event' key sequence partially
+// between calls to os_inchar when maxlen < 3
static int push_event_key(uint8_t *buf, int maxlen)
{
static const uint8_t key[3] = { K_SPECIAL, KS_EXTRA, KE_EVENT };
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 70d87a7ab2..8e5adb14f9 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -32,7 +32,14 @@ void term_input_init(TermInput *input, Loop *loop)
term = ""; // termkey_new_abstract assumes non-null (#2745)
}
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ input->tk = termkey_new_abstract(term,
+ TERMKEY_FLAG_UTF8 | TERMKEY_FLAG_NOSTART);
+ termkey_hook_terminfo_getstr(input->tk, input->tk_ti_hook_fn, NULL);
+ termkey_start(input->tk);
+#else
input->tk = termkey_new_abstract(term, TERMKEY_FLAG_UTF8);
+#endif
int curflags = termkey_get_canonflags(input->tk);
termkey_set_canonflags(input->tk, curflags | TERMKEY_CANON_DELBS);
diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h
index d7ee2b9e52..7d59cf5c6a 100644
--- a/src/nvim/tui/input.h
+++ b/src/nvim/tui/input.h
@@ -12,6 +12,9 @@ typedef struct term_input {
bool paste_enabled;
bool waiting;
TermKey *tk;
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook
+#endif
TimeWatcher timer_handle;
Loop *loop;
Stream read_stream;
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index bceb4ca4ff..74187e07c0 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -7,9 +7,13 @@
#include <uv.h>
#include <unibilium.h>
+#if defined(HAVE_TERMIOS_H)
+# include <termios.h>
+#endif
#include "nvim/lib/kvec.h"
+#include "nvim/ascii.h"
#include "nvim/vim.h"
#include "nvim/log.h"
#include "nvim/ui.h"
@@ -195,6 +199,11 @@ static void tui_terminal_start(UI *ui)
terminfo_start(ui);
update_size(ui);
signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
+
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
+#endif
+ term_input_init(&data->input, data->loop);
term_input_start(&data->input);
}
@@ -227,8 +236,6 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
signal_watcher_init(data->loop, &data->winch_handle, ui);
signal_watcher_init(data->loop, &data->cont_handle, data);
signal_watcher_start(&data->cont_handle, sigcont_cb, SIGCONT);
- // initialize input reading structures
- term_input_init(&data->input, &tui_loop);
tui_terminal_start(ui);
data->stop = false;
// allow the main thread to continue, we are ready to start handling UI
@@ -957,3 +964,50 @@ static void flush_buf(UI *ui, bool toggle_cursor)
unibi_out(ui, unibi_cursor_invisible);
}
}
+
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+/// Try to get "kbs" code from stty because "the terminfo kbs entry is extremely
+/// unreliable." (Vim, Bash, and tmux also do this.)
+///
+/// @see tmux/tty-keys.c fe4e9470bb504357d073320f5d305b22663ee3fd
+/// @see https://bugzilla.redhat.com/show_bug.cgi?id=142659
+static const char *tui_get_stty_erase(void)
+{
+ static char stty_erase[2] = { 0 };
+#if defined(ECHOE) && defined(ICANON) && defined(HAVE_TERMIOS_H)
+ struct termios t;
+ if (tcgetattr(input_global_fd(), &t) != -1) {
+ stty_erase[0] = (char)t.c_cc[VERASE];
+ stty_erase[1] = '\0';
+ ILOG("stty/termios:erase=%s", stty_erase);
+ }
+#endif
+ return stty_erase;
+}
+
+/// libtermkey hook to override terminfo entries.
+/// @see TermInput.tk_ti_hook_fn
+static const char *tui_tk_ti_getstr(const char *name, const char *value,
+ void *data)
+{
+ static const char *stty_erase = NULL;
+ if (stty_erase == NULL) {
+ stty_erase = tui_get_stty_erase();
+ }
+
+ if (strcmp(name, "key_backspace") == 0) {
+ ILOG("libtermkey:kbs=%s", value);
+ if (stty_erase != NULL && stty_erase[0] != 0) {
+ return stty_erase;
+ }
+ } else if (strcmp(name, "key_dc") == 0) {
+ ILOG("libtermkey:kdch1=%s", value);
+ // Vim: "If <BS> and <DEL> are now the same, redefine <DEL>."
+ if (stty_erase != NULL && strcmp(stty_erase, value) == 0) {
+ return stty_erase[0] == DEL ? (char *)CTRL_H_STR : (char *)DEL_STR;
+ }
+ }
+
+ return value;
+}
+#endif
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 16801eb733..220e0fc7af 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -660,7 +660,7 @@ static int included_patches[] = {
// 1783,
1782,
// 1781,
- // 1780,
+ 1780,
1779,
// 1778 NA
// 1777 NA