aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/CMakeLists.txt9
-rw-r--r--src/nvim/api/ui.c33
-rw-r--r--src/nvim/cursor_shape.c47
-rw-r--r--src/nvim/cursor_shape.h3
-rw-r--r--src/nvim/ex_cmds.c12
-rw-r--r--src/nvim/ex_getln.c16
-rw-r--r--src/nvim/getchar.h5
-rw-r--r--src/nvim/mouse.c1
-rw-r--r--src/nvim/os/env.c17
-rw-r--r--src/nvim/screen.h4
-rw-r--r--src/nvim/search.h6
-rw-r--r--src/nvim/syntax.h2
-rw-r--r--src/nvim/tui/tui.c120
-rw-r--r--src/nvim/ui.c41
-rw-r--r--src/nvim/ui.h5
-rw-r--r--src/nvim/ui_bridge.c24
-rw-r--r--src/nvim/version.h2
-rw-r--r--src/nvim/window.h2
18 files changed, 207 insertions, 142 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index a91657f1bd..db5e62fd67 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -429,7 +429,6 @@ function(get_test_target prefix sfile relative_path_var target_var)
endfunction()
set(NO_SINGLE_CHECK_HEADERS
- getchar.h
if_cscope_defs.h
misc2.h
msgpack_rpc/server.h
@@ -441,24 +440,16 @@ set(NO_SINGLE_CHECK_HEADERS
quickfix.h
regexp.h
regexp_defs.h
- screen.h
- search.h
sha256.h
sign_defs.h
spell.h
spellfile.h
- syntax.h
syntax_defs.h
tag.h
terminal.h
tui/tui.h
- ugrid.h
- ui.h
- ui_bridge.h
undo.h
undo_defs.h
- version.h
- window.h
)
foreach(hfile ${NVIM_HEADERS})
get_test_target(test-includes "${hfile}" relative_path texe)
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 3cc2870792..2a33d2ad72 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -73,7 +73,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
ui->clear = remote_ui_clear;
ui->eol_clear = remote_ui_eol_clear;
ui->cursor_goto = remote_ui_cursor_goto;
- ui->cursor_style_set = remote_ui_cursor_style_set;
+ ui->mode_info_set = remote_ui_mode_info_set;
ui->update_menu = remote_ui_update_menu;
ui->busy_start = remote_ui_busy_start;
ui->busy_stop = remote_ui_busy_stop;
@@ -269,19 +269,14 @@ static void remote_ui_mouse_off(UI *ui)
push_call(ui, "mouse_off", args);
}
-static void remote_ui_mode_change(UI *ui, int mode)
+static void remote_ui_mode_change(UI *ui, int mode_idx)
{
Array args = ARRAY_DICT_INIT;
- if (mode == INSERT) {
- ADD(args, STRING_OBJ(cstr_to_string("insert")));
- } else if (mode == REPLACE) {
- ADD(args, STRING_OBJ(cstr_to_string("replace")));
- } else if (mode == CMDLINE) {
- ADD(args, STRING_OBJ(cstr_to_string("cmdline")));
- } else {
- assert(mode == NORMAL);
- ADD(args, STRING_OBJ(cstr_to_string("normal")));
- }
+
+ char *full_name = shape_table[mode_idx].full_name;
+ ADD(args, STRING_OBJ(cstr_to_string(full_name)));
+
+ ADD(args, INTEGER_OBJ(mode_idx));
push_call(ui, "mode_change", args);
}
@@ -303,12 +298,12 @@ static void remote_ui_scroll(UI *ui, int count)
push_call(ui, "scroll", args);
}
-static void remote_ui_cursor_style_set(UI *ui, bool enabled, Dictionary data)
+static void remote_ui_mode_info_set(UI *ui, bool guicursor_enabled, Array data)
{
Array args = ARRAY_DICT_INIT;
- ADD(args, BOOLEAN_OBJ(enabled));
- ADD(args, copy_object(DICTIONARY_OBJ(data)));
- push_call(ui, "cursor_style_set", args);
+ ADD(args, BOOLEAN_OBJ(guicursor_enabled));
+ ADD(args, copy_object(ARRAY_OBJ(data)));
+ push_call(ui, "mode_info_set", args);
}
static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
@@ -396,8 +391,10 @@ static void remote_ui_update_sp(UI *ui, int sp)
static void remote_ui_flush(UI *ui)
{
UIData *data = ui->data;
- channel_send_event(data->channel_id, "redraw", data->buffer);
- data->buffer = (Array)ARRAY_DICT_INIT;
+ if (data->buffer.size > 0) {
+ channel_send_event(data->channel_id, "redraw", data->buffer);
+ data->buffer = (Array)ARRAY_DICT_INIT;
+ }
}
static void remote_ui_suspend(UI *ui)
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index 24a5672d0f..dcc680f806 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -14,7 +14,7 @@
#include "nvim/ui.h"
/// Handling of cursor and mouse pointer shapes in various modes.
-static cursorentry_T shape_table[SHAPE_IDX_COUNT] =
+cursorentry_T shape_table[SHAPE_IDX_COUNT] =
{
// Values are set by 'guicursor' and 'mouseshape'.
// Adjust the SHAPE_IDX_ defines when changing this!
@@ -37,11 +37,11 @@ static cursorentry_T shape_table[SHAPE_IDX_COUNT] =
{ "showmatch", 0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR },
};
-/// Converts cursor_shapes into a Dictionary of dictionaries
-/// @return dictionary of the form {"normal" : { "cursor_shape": ... }, ...}
-Dictionary cursor_shape_dict(void)
+/// Converts cursor_shapes into an Array of Dictionaries
+/// @return Array of the form {[ "cursor_shape": ... ], ...}
+Array mode_style_array(void)
{
- Dictionary all = ARRAY_DICT_INIT;
+ Array all = ARRAY_DICT_INIT;
for (int i = 0; i < SHAPE_IDX_COUNT; i++) {
Dictionary dic = ARRAY_DICT_INIT;
@@ -65,9 +65,10 @@ Dictionary cursor_shape_dict(void)
PUT(dic, "hl_id", INTEGER_OBJ(cur->id));
PUT(dic, "id_lm", INTEGER_OBJ(cur->id_lm));
}
+ PUT(dic, "name", STRING_OBJ(cstr_to_string(cur->full_name)));
PUT(dic, "short_name", STRING_OBJ(cstr_to_string(cur->name)));
- PUT(all, cur->full_name, DICTIONARY_OBJ(dic));
+ ADD(all, DICTIONARY_OBJ(dic));
}
return all;
@@ -243,7 +244,7 @@ char_u *parse_shape_opt(int what)
shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
}
}
- ui_cursor_style_set();
+ ui_mode_info_set();
return NULL;
}
@@ -263,3 +264,35 @@ int cursor_mode_str2int(const char *mode)
return -1;
}
+
+/// Return the index into shape_table[] for the current mode.
+int cursor_get_mode_idx(void)
+{
+ if (State == SHOWMATCH) {
+ return SHAPE_IDX_SM;
+ } else if (State & VREPLACE_FLAG) {
+ return SHAPE_IDX_R;
+ } else if (State & REPLACE_FLAG) {
+ return SHAPE_IDX_R;
+ } else if (State & INSERT) {
+ return SHAPE_IDX_I;
+ } else if (State & CMDLINE) {
+ if (cmdline_at_end()) {
+ return SHAPE_IDX_C;
+ } else if (cmdline_overstrike()) {
+ return SHAPE_IDX_CR;
+ } else {
+ return SHAPE_IDX_CI;
+ }
+ } else if (finish_op) {
+ return SHAPE_IDX_O;
+ } else if (VIsual_active) {
+ if (*p_sel == 'e') {
+ return SHAPE_IDX_VE;
+ } else {
+ return SHAPE_IDX_V;
+ }
+ } else {
+ return SHAPE_IDX_N;
+ }
+}
diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h
index 7cf65cba3c..2c466603f0 100644
--- a/src/nvim/cursor_shape.h
+++ b/src/nvim/cursor_shape.h
@@ -25,7 +25,7 @@ SHAPE_IDX_MORE = 14, ///< Hit-return or More
SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line
SHAPE_IDX_SM = 16, ///< showing matching paren
SHAPE_IDX_COUNT = 17
-} MouseMode;
+} ModeShape;
typedef enum {
SHAPE_BLOCK = 0, ///< block cursor
@@ -53,6 +53,7 @@ typedef struct cursor_entry {
char used_for; ///< SHAPE_MOUSE and/or SHAPE_CURSOR
} cursorentry_T;
+extern cursorentry_T shape_table[SHAPE_IDX_COUNT];
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor_shape.h.generated.h"
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 117ef6a507..7726e0fc6d 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2877,8 +2877,11 @@ void ex_z(exarg_T *eap)
if (end > curbuf->b_ml.ml_line_count)
end = curbuf->b_ml.ml_line_count;
- if (curs > curbuf->b_ml.ml_line_count)
+ if (curs > curbuf->b_ml.ml_line_count) {
curs = curbuf->b_ml.ml_line_count;
+ } else if (curs < 1) {
+ curs = 1;
+ }
for (i = start; i <= end; i++) {
if (minus && i == lnum) {
@@ -2898,8 +2901,11 @@ void ex_z(exarg_T *eap)
}
}
- curwin->w_cursor.lnum = curs;
- ex_no_reprint = TRUE;
+ if (curwin->w_cursor.lnum != curs) {
+ curwin->w_cursor.lnum = curs;
+ curwin->w_cursor.col = 0;
+ }
+ ex_no_reprint = true;
}
/*
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 1affdb2fe7..eed4bf6066 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -354,6 +354,7 @@ static int command_line_check(VimState *state)
quit_more = false; // reset after CTRL-D which had a more-prompt
cursorcmd(); // set the cursor on the right spot
+ ui_cursor_shape();
return 1;
}
@@ -2095,6 +2096,18 @@ redraw:
return (char_u *)line_ga.ga_data;
}
+bool cmdline_overstrike(void)
+{
+ return ccline.overstrike;
+}
+
+
+/// Return true if the cursor is at the end of the cmdline.
+bool cmdline_at_end(void)
+{
+ return (ccline.cmdpos >= ccline.cmdlen);
+}
+
/*
* Allocate a new command line buffer.
* Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
@@ -2265,6 +2278,7 @@ void putcmdline(int c, int shift)
draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
msg_no_more = FALSE;
cursorcmd();
+ ui_cursor_shape();
}
/*
@@ -2284,6 +2298,7 @@ void unputcmdline(void)
draw_cmdline(ccline.cmdpos, 1);
msg_no_more = FALSE;
cursorcmd();
+ ui_cursor_shape();
}
/*
@@ -2601,6 +2616,7 @@ void redrawcmdline(void)
compute_cmdrow();
redrawcmd();
cursorcmd();
+ ui_cursor_shape();
}
static void redrawcmdprompt(void)
diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h
index bdf65909b6..28584e0534 100644
--- a/src/nvim/getchar.h
+++ b/src/nvim/getchar.h
@@ -1,6 +1,10 @@
#ifndef NVIM_GETCHAR_H
#define NVIM_GETCHAR_H
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h"
+
/* Values for "noremap" argument of ins_typebuf(). Also used for
* map->m_noremap and menu->noremap[]. */
#define REMAP_YES 0 /* allow remapping */
@@ -12,6 +16,7 @@
#define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */
#define KEYLEN_REMOVED 9999 /* keylen value for removed sequence */
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "getchar.h.generated.h"
#endif
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 6088488388..b1c146d406 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -459,6 +459,7 @@ void setmouse(void)
{
int checkfor;
+ ui_cursor_shape();
/* be quick when mouse is off */
if (*p_mouse == NUL)
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 72bd0bf788..8f7a6e72b5 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -915,9 +915,20 @@ bool os_term_is_nice(void)
return true;
#else
const char *vte_version = os_getenv("VTE_VERSION");
- return (vte_version && atoi(vte_version) >= 3900)
- || NULL != os_getenv("KONSOLE_PROFILE_NAME")
- || NULL != os_getenv("KONSOLE_DBUS_SESSION");
+ if ((vte_version && atoi(vte_version) >= 3900)
+ || os_getenv("KONSOLE_PROFILE_NAME")
+ || os_getenv("KONSOLE_DBUS_SESSION")) {
+ return true;
+ }
+ const char *termprg = os_getenv("TERM_PROGRAM");
+ if (termprg && striequal(termprg, "iTerm.app")) {
+ return true;
+ }
+ const char *term = os_getenv("TERM");
+ if (term && strncmp(term, "rxvt", 4) == 0) {
+ return true;
+ }
+ return false;
#endif
}
diff --git a/src/nvim/screen.h b/src/nvim/screen.h
index 81a8b9ed4c..17515d4253 100644
--- a/src/nvim/screen.h
+++ b/src/nvim/screen.h
@@ -3,6 +3,10 @@
#include <stdbool.h>
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/pos.h"
+
/*
* flags for update_screen()
* The higher the value, the higher the priority
diff --git a/src/nvim/search.h b/src/nvim/search.h
index d4e40cb287..cb50742990 100644
--- a/src/nvim/search.h
+++ b/src/nvim/search.h
@@ -4,6 +4,12 @@
#include <stdbool.h>
#include <stdint.h>
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/normal.h"
+#include "nvim/os/time.h"
+
/* Values for the find_pattern_in_path() function args 'type' and 'action': */
#define FIND_ANY 1
#define FIND_DEFINE 2
diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h
index 574e3372e2..bb733ead30 100644
--- a/src/nvim/syntax.h
+++ b/src/nvim/syntax.h
@@ -4,7 +4,7 @@
#include <stdbool.h>
#include "nvim/buffer_defs.h"
-
+#include "nvim/ex_cmds_defs.h"
/// Terminal highlighting attribute bits.
/// Attributes above HL_ALL are used for syntax highlighting.
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 941fdb2570..ae7551098d 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -43,6 +43,15 @@
#define OUTBUF_SIZE 0xffff
#define TOO_MANY_EVENTS 1000000
+#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1))
+
+typedef enum TermType {
+ kTermUnknown,
+ kTermGnome,
+ kTermiTerm,
+ kTermKonsole,
+ kTermRxvt,
+} TermType;
typedef struct {
int top, bot, left, right;
@@ -76,7 +85,8 @@ typedef struct {
bool busy;
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
HlAttrs print_attrs;
- int showing_mode;
+ ModeShape showing_mode;
+ TermType term;
struct {
int enable_mouse, disable_mouse;
int enable_bracketed_paste, disable_bracketed_paste;
@@ -104,7 +114,7 @@ UI *tui_start(void)
ui->clear = tui_clear;
ui->eol_clear = tui_eol_clear;
ui->cursor_goto = tui_cursor_goto;
- ui->cursor_style_set = tui_cursor_style_set;
+ ui->mode_info_set = tui_mode_info_set;
ui->update_menu = tui_update_menu;
ui->busy_start = tui_busy_start;
ui->busy_stop = tui_busy_stop;
@@ -134,7 +144,7 @@ static void terminfo_start(UI *ui)
data->can_use_terminal_scroll = true;
data->bufpos = 0;
data->bufsize = sizeof(data->buf) - CNORM_COMMAND_MAX_SIZE;
- data->showing_mode = 0;
+ data->showing_mode = SHAPE_IDX_N;
data->unibi_ext.enable_mouse = -1;
data->unibi_ext.disable_mouse = -1;
data->unibi_ext.set_cursor_color = -1;
@@ -176,7 +186,7 @@ static void terminfo_stop(UI *ui)
{
TUIData *data = ui->data;
// Destroy output stuff
- tui_mode_change(ui, NORMAL);
+ tui_mode_change(ui, SHAPE_IDX_N);
tui_mouse_off(ui);
unibi_out(ui, unibi_exit_attribute_mode);
// cursor should be set to normal before exiting alternate screen
@@ -475,27 +485,24 @@ static cursorentry_T decode_cursor_entry(Dictionary args)
return r;
}
-static void tui_cursor_style_set(UI *ui, bool enabled, Dictionary args)
+static void tui_mode_info_set(UI *ui, bool guicursor_enabled, Array args)
{
- cursor_style_enabled = enabled;
- if (!enabled) {
+ cursor_style_enabled = guicursor_enabled;
+ if (!guicursor_enabled) {
return; // Do not send cursor style control codes.
}
TUIData *data = ui->data;
assert(args.size);
- // Keys: as defined by `shape_table`.
+
+ // cursor style entries as defined by `shape_table`.
for (size_t i = 0; i < args.size; i++) {
- char *mode_name = args.items[i].key.data;
- const int mode_id = cursor_mode_str2int(mode_name);
- assert(mode_id >= 0);
- cursorentry_T r = decode_cursor_entry(args.items[i].value.data.dictionary);
- r.full_name = mode_name;
- data->cursor_shapes[mode_id] = r;
+ assert(args.items[i].type == kObjectTypeDictionary);
+ cursorentry_T r = decode_cursor_entry(args.items[i].data.dictionary);
+ data->cursor_shapes[i] = r;
}
- MouseMode cursor_mode = tui_mode2cursor(data->showing_mode);
- tui_set_cursor(ui, cursor_mode);
+ tui_set_mode(ui, data->showing_mode);
}
static void tui_update_menu(UI *ui)
@@ -531,8 +538,7 @@ static void tui_mouse_off(UI *ui)
}
}
-/// @param mode one of SHAPE_XXX
-static void tui_set_cursor(UI *ui, MouseMode mode)
+static void tui_set_mode(UI *ui, ModeShape mode)
{
if (!cursor_style_enabled) {
return;
@@ -540,14 +546,14 @@ static void tui_set_cursor(UI *ui, MouseMode mode)
TUIData *data = ui->data;
cursorentry_T c = data->cursor_shapes[mode];
int shape = c.shape;
- bool inside_tmux = os_getenv("TMUX") != NULL;
+ bool is_tmux = os_getenv("TMUX") != NULL;
unibi_var_t vars[26 + 26] = { { 0 } };
-# define TMUX_WRAP(seq) (inside_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
+# define TMUX_WRAP(seq) (is_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
// Support changing cursor shape on some popular terminals.
const char *vte_version = os_getenv("VTE_VERSION");
- if (os_getenv("KONSOLE_PROFILE_NAME") || os_getenv("KONSOLE_DBUS_SESSION")) {
+ if (data->term == kTermKonsole) {
// Konsole uses a proprietary escape code to set the cursor shape
// and does not support DECSCUSR.
switch (shape) {
@@ -587,42 +593,12 @@ static void tui_set_cursor(UI *ui, MouseMode mode)
}
}
-/// Returns cursor mode from edit mode
-static MouseMode tui_mode2cursor(int mode)
-{
- switch (mode) {
- case INSERT: return SHAPE_IDX_I;
- case CMDLINE: return SHAPE_IDX_C;
- case REPLACE: return SHAPE_IDX_R;
- case NORMAL:
- default: return SHAPE_IDX_N;
- }
-}
-
/// @param mode editor mode
-static void tui_mode_change(UI *ui, int mode)
+static void tui_mode_change(UI *ui, int mode_idx)
{
TUIData *data = ui->data;
-
- if (mode == INSERT) {
- if (data->showing_mode != INSERT) {
- tui_set_cursor(ui, SHAPE_IDX_I);
- }
- } else if (mode == CMDLINE) {
- if (data->showing_mode != CMDLINE) {
- tui_set_cursor(ui, SHAPE_IDX_C);
- }
- } else if (mode == REPLACE) {
- if (data->showing_mode != REPLACE) {
- tui_set_cursor(ui, SHAPE_IDX_R);
- }
- } else {
- assert(mode == NORMAL);
- if (data->showing_mode != NORMAL) {
- tui_set_cursor(ui, SHAPE_IDX_N);
- }
- }
- data->showing_mode = mode;
+ tui_set_mode(ui, (ModeShape)mode_idx);
+ data->showing_mode = (ModeShape)mode_idx;
}
static void tui_set_scroll_region(UI *ui, int top, int bot, int left,
@@ -954,6 +930,24 @@ static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str,
}
}
+static TermType detect_term(const char *term, const char *colorterm)
+{
+ if (STARTS_WITH(term, "rxvt")) {
+ return kTermRxvt;
+ }
+ if (os_getenv("KONSOLE_PROFILE_NAME") || os_getenv("KONSOLE_DBUS_SESSION")) {
+ return kTermKonsole;
+ }
+ const char *termprg = os_getenv("TERM_PROGRAM");
+ if (termprg && strstr(termprg, "iTerm.app")) {
+ return kTermiTerm;
+ }
+ if (colorterm && strstr(colorterm, "gnome-terminal")) {
+ return kTermGnome;
+ }
+ return kTermUnknown;
+}
+
static void fix_terminfo(TUIData *data)
{
unibi_term *ut = data->ut;
@@ -963,10 +957,9 @@ static void fix_terminfo(TUIData *data)
if (!term) {
goto end;
}
+ data->term = detect_term(term, colorterm);
-#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1))
-
- if (STARTS_WITH(term, "rxvt")) {
+ if (data->term == kTermRxvt) {
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");
@@ -978,7 +971,7 @@ static void fix_terminfo(TUIData *data)
unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
}
- if (STARTS_WITH(term, "xterm") || STARTS_WITH(term, "rxvt")) {
+ if (STARTS_WITH(term, "xterm") || data->term == kTermRxvt) {
const char *normal = unibi_get_str(ut, unibi_cursor_normal);
if (!normal) {
unibi_set_str(ut, unibi_cursor_normal, "\x1b[?25h");
@@ -1015,7 +1008,7 @@ static void fix_terminfo(TUIData *data)
if ((colorterm && strstr(colorterm, "256"))
|| strstr(term, "256")
|| strstr(term, "xterm")) {
- // Assume TERM~=xterm or COLORTERM~=256 supports 256 colors.
+ // Assume TERM=~xterm or COLORTERM=~256 supports 256 colors.
unibi_set_num(ut, unibi_max_colors, 256);
unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF);
unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB);
@@ -1023,8 +1016,13 @@ static void fix_terminfo(TUIData *data)
end:
// Fill some empty slots with common terminal strings
- data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
- ut, NULL, "\033]12;#%p1%06x\007");
+ if (data->term == kTermiTerm) {
+ data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
+ ut, NULL, "\033]Pl%p1%06x\033\\");
+ } else {
+ data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
+ ut, NULL, "\033]12;#%p1%06x\007");
+ }
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?1002h\x1b[?1006h");
data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, NULL,
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index cfa186987c..69916fa4cd 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -56,6 +56,7 @@ static int current_attr_code = 0;
static bool pending_cursor_update = false;
static int busy = 0;
static int height, width;
+static int old_mode_idx = -1;
// UI_CALL invokes a function on all registered UI instances. The functions can
// have 0-5 arguments (configurable by SELECT_NTH).
@@ -153,12 +154,6 @@ void ui_event(char *name, Array args)
}
}
-// May update the shape of the cursor.
-void ui_cursor_shape(void)
-{
- ui_mode_change();
-}
-
void ui_refresh(void)
{
if (!ui_active()) {
@@ -183,7 +178,9 @@ void ui_refresh(void)
row = col = 0;
screen_resize(width, height);
pum_set_external(pum_external);
- ui_cursor_style_set();
+ ui_mode_info_set();
+ old_mode_idx = -1;
+ ui_cursor_shape();
}
static void ui_refresh_event(void **argv)
@@ -381,12 +378,12 @@ void ui_cursor_goto(int new_row, int new_col)
pending_cursor_update = true;
}
-void ui_cursor_style_set(void)
+void ui_mode_info_set(void)
{
- Dictionary style = cursor_shape_dict();
+ Array style = mode_style_array();
bool enabled = (*p_guicursor != NUL);
- UI_CALL(cursor_style_set, enabled, style);
- api_free_dictionary(style);
+ UI_CALL(mode_info_set, enabled, style);
+ api_free_array(style);
}
void ui_update_menu(void)
@@ -544,25 +541,19 @@ static void flush_cursor_update(void)
}
}
-// Notify that the current mode has changed. Can be used to change cursor
-// shape, for example.
-static void ui_mode_change(void)
+/// Check if current mode has changed.
+/// May update the shape of the cursor.
+void ui_cursor_shape(void)
{
- int mode;
if (!full_screen) {
return;
}
- // Get a simple UI mode out of State.
- if ((State & REPLACE) == REPLACE) {
- mode = REPLACE;
- } else if (State & INSERT) {
- mode = INSERT;
- } else if (State & CMDLINE) {
- mode = CMDLINE;
- } else {
- mode = NORMAL;
+ int mode_idx = cursor_get_mode_idx();
+
+ if (old_mode_idx != mode_idx) {
+ old_mode_idx = mode_idx;
+ UI_CALL(mode_change, mode_idx);
}
- UI_CALL(mode_change, mode);
conceal_check_cursur_line();
}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index 8ffc5a45a6..fcf52ac9e1 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -6,6 +6,7 @@
#include <stdint.h>
#include "api/private/defs.h"
+#include "nvim/buffer_defs.h"
typedef struct {
bool bold, underline, undercurl, italic, reverse;
@@ -22,13 +23,13 @@ struct ui_t {
void (*clear)(UI *ui);
void (*eol_clear)(UI *ui);
void (*cursor_goto)(UI *ui, int row, int col);
- void (*cursor_style_set)(UI *ui, bool enabled, Dictionary cursor_styles);
+ void (*mode_info_set)(UI *ui, bool enabled, Array cursor_styles);
void (*update_menu)(UI *ui);
void (*busy_start)(UI *ui);
void (*busy_stop)(UI *ui);
void (*mouse_on)(UI *ui);
void (*mouse_off)(UI *ui);
- void (*mode_change)(UI *ui, int mode);
+ void (*mode_change)(UI *ui, int mode_idx);
void (*set_scroll_region)(UI *ui, int top, int bot, int left, int right);
void (*scroll)(UI *ui, int count);
void (*highlight_set)(UI *ui, HlAttrs attrs);
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 2c70b46c14..5697c765ba 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -63,7 +63,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
rv->bridge.clear = ui_bridge_clear;
rv->bridge.eol_clear = ui_bridge_eol_clear;
rv->bridge.cursor_goto = ui_bridge_cursor_goto;
- rv->bridge.cursor_style_set = ui_bridge_cursor_style_set;
+ rv->bridge.mode_info_set = ui_bridge_mode_info_set;
rv->bridge.update_menu = ui_bridge_update_menu;
rv->bridge.busy_start = ui_bridge_busy_start;
rv->bridge.busy_stop = ui_bridge_busy_stop;
@@ -183,23 +183,23 @@ static void ui_bridge_cursor_goto_event(void **argv)
ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2]));
}
-static void ui_bridge_cursor_style_set(UI *b, bool enabled, Dictionary styles)
+static void ui_bridge_mode_info_set(UI *b, bool enabled, Array modes)
{
bool *enabledp = xmalloc(sizeof(*enabledp));
- Object *stylesp = xmalloc(sizeof(*stylesp));
+ Object *modesp = xmalloc(sizeof(*modesp));
*enabledp = enabled;
- *stylesp = copy_object(DICTIONARY_OBJ(styles));
- UI_CALL(b, cursor_style_set, 3, b, enabledp, stylesp);
+ *modesp = copy_object(ARRAY_OBJ(modes));
+ UI_CALL(b, mode_info_set, 3, b, enabledp, modesp);
}
-static void ui_bridge_cursor_style_set_event(void **argv)
+static void ui_bridge_mode_info_set_event(void **argv)
{
UI *ui = UI(argv[0]);
bool *enabled = argv[1];
- Object *styles = argv[2];
- ui->cursor_style_set(ui, *enabled, styles->data.dictionary);
+ Object *modes = argv[2];
+ ui->mode_info_set(ui, *enabled, modes->data.array);
xfree(enabled);
- api_free_object(*styles);
- xfree(styles);
+ api_free_object(*modes);
+ xfree(modes);
}
static void ui_bridge_update_menu(UI *b)
@@ -252,9 +252,9 @@ static void ui_bridge_mouse_off_event(void **argv)
ui->mouse_off(ui);
}
-static void ui_bridge_mode_change(UI *b, int mode)
+static void ui_bridge_mode_change(UI *b, int mode_idx)
{
- UI_CALL(b, mode_change, 2, b, INT2PTR(mode));
+ UI_CALL(b, mode_change, 2, b, INT2PTR(mode_idx));
}
static void ui_bridge_mode_change_event(void **argv)
{
diff --git a/src/nvim/version.h b/src/nvim/version.h
index 1de809e539..a0babfb156 100644
--- a/src/nvim/version.h
+++ b/src/nvim/version.h
@@ -1,6 +1,8 @@
#ifndef NVIM_VERSION_H
#define NVIM_VERSION_H
+#include "nvim/ex_cmds_defs.h"
+
// defined in version.c
extern char* Version;
extern char* longVersion;
diff --git a/src/nvim/window.h b/src/nvim/window.h
index 2ac4c00c28..82b3fe5e88 100644
--- a/src/nvim/window.h
+++ b/src/nvim/window.h
@@ -3,6 +3,8 @@
#include <stdbool.h>
+#include "nvim/buffer_defs.h"
+
/* Values for file_name_in_line() */
#define FNAME_MESS 1 /* give error message */
#define FNAME_EXP 2 /* expand to path */