aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-12-16 14:27:41 +0300
committerZyX <kp-pav@yandex.ru>2017-12-16 14:27:41 +0300
commit7f3b9a4acc503709c89a501aaee304ff208bd995 (patch)
tree73e2d477fc8664ccaffad9dbc000132c7fa82857 /src
parent76ffe0c5aa51fe4fe14811e86867af2c711190a1 (diff)
parent7afd26a6d189d1ca798f93db8661bd656a37265f (diff)
downloadrneovim-7f3b9a4acc503709c89a501aaee304ff208bd995.tar.gz
rneovim-7f3b9a4acc503709c89a501aaee304ff208bd995.tar.bz2
rneovim-7f3b9a4acc503709c89a501aaee304ff208bd995.zip
Merge branch 'master' into hide-container-impl
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui.c1
-rw-r--r--src/nvim/api/ui_events.in.h2
-rw-r--r--src/nvim/edit.c4
-rw-r--r--src/nvim/eval.c25
-rw-r--r--src/nvim/eval/encode.c2
-rw-r--r--src/nvim/eval/typval.c16
-rw-r--r--src/nvim/eval/typval_encode.c.h2
-rw-r--r--src/nvim/ex_eval.c14
-rw-r--r--src/nvim/generators/gen_api_ui_events.lua15
-rw-r--r--src/nvim/generators/gen_options.lua1
-rw-r--r--src/nvim/getchar.c29
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/hashtab.c2
-rw-r--r--src/nvim/memfile.c5
-rw-r--r--src/nvim/memline.c68
-rw-r--r--src/nvim/message.c47
-rw-r--r--src/nvim/message.h9
-rw-r--r--src/nvim/option.c50
-rw-r--r--src/nvim/option_defs.h3
-rw-r--r--src/nvim/options.lua29
-rw-r--r--src/nvim/os/env.c2
-rw-r--r--src/nvim/os/pty_process_unix.c8
-rw-r--r--src/nvim/os/signal.c3
-rw-r--r--src/nvim/quickfix.c2
-rw-r--r--src/nvim/regexp.c23
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/tui/tui.c51
-rw-r--r--src/nvim/ui.c1
-rw-r--r--src/nvim/ui.h2
-rw-r--r--src/nvim/ui_bridge.c24
-rw-r--r--src/nvim/undo.c20
-rw-r--r--src/nvim/version.c2
-rw-r--r--src/nvim/window.c2
33 files changed, 312 insertions, 156 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index a9eaccfac5..35508fde6b 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -93,6 +93,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
ui->suspend = remote_ui_suspend;
ui->set_title = remote_ui_set_title;
ui->set_icon = remote_ui_set_icon;
+ ui->option_set = remote_ui_option_set;
ui->event = remote_ui_event;
memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index 847b21072a..3d2253e918 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -58,6 +58,8 @@ void set_title(String title)
FUNC_API_SINCE(3);
void set_icon(String icon)
FUNC_API_SINCE(3);
+void option_set(String name, Object value)
+ FUNC_API_SINCE(4) FUNC_API_BRIDGE_IMPL;
void popupmenu_show(Array items, Integer selected, Integer row, Integer col)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 2fa4a52387..649357c7ea 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1927,7 +1927,7 @@ bool vim_is_ctrl_x_key(int c)
case CTRL_X_EVAL:
return (c == Ctrl_P || c == Ctrl_N);
}
- EMSG(_(e_internal));
+ internal_error("vim_is_ctrl_x_key()");
return false;
}
@@ -4681,7 +4681,7 @@ static int ins_complete(int c, bool enable_pum)
line = ml_get(curwin->w_cursor.lnum);
compl_pattern = vim_strnsave(line + compl_col, compl_length);
} else {
- EMSG2(_(e_intern2), "ins_complete()");
+ internal_error("ins_complete()");
return FAIL;
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 3aaa5f349d..74b0cdc746 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1099,10 +1099,11 @@ static void restore_vimvar(int idx, typval_T *save_tv)
vimvars[idx].vv_tv = *save_tv;
if (vimvars[idx].vv_type == VAR_UNKNOWN) {
hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
- if (HASHITEM_EMPTY(hi))
- EMSG2(_(e_intern2), "restore_vimvar()");
- else
+ if (HASHITEM_EMPTY(hi)) {
+ internal_error("restore_vimvar()");
+ } else {
hash_remove(&vimvarht, hi);
+ }
}
}
@@ -1570,7 +1571,7 @@ ex_let_vars (
}
break;
} else if (*arg != ',' && *arg != ']') {
- EMSG2(_(e_intern2), "ex_let_vars()");
+ internal_error("ex_let_vars()");
return FAIL;
}
}
@@ -2969,7 +2970,7 @@ int do_unlet(const char *const name, const size_t name_len, const int forceit)
d = di->di_tv.vval.v_dict;
}
if (d == NULL) {
- EMSG2(_(e_intern2), "do_unlet()");
+ internal_error("do_unlet()");
return FAIL;
}
hashitem_T *hi = hash_find(ht, (const char_u *)varname);
@@ -7985,7 +7986,7 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
}
case VAR_UNKNOWN: {
- EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
+ internal_error("f_empty(UNKNOWN)");
break;
}
}
@@ -17149,7 +17150,7 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
}
case VAR_UNKNOWN: {
- EMSG2(_(e_intern2), "f_type(UNKNOWN)");
+ internal_error("f_type(UNKNOWN)");
break;
}
}
@@ -18999,7 +19000,7 @@ static void set_var(const char *name, const size_t name_len, typval_T *const tv,
}
return;
} else if (v->di_tv.v_type != tv->v_type) {
- EMSG2(_(e_intern2), "set_var()");
+ internal_error("set_var()");
}
}
@@ -19266,7 +19267,7 @@ int var_item_copy(const vimconv_T *const conv,
}
break;
case VAR_UNKNOWN:
- EMSG2(_(e_intern2), "var_item_copy(UNKNOWN)");
+ internal_error("var_item_copy(UNKNOWN)");
ret = FAIL;
}
--recurse;
@@ -20954,11 +20955,11 @@ void func_unref(char_u *name)
if (fp == NULL && isdigit(*name)) {
#ifdef EXITFREE
if (!entered_free_all_mem) {
- EMSG2(_(e_intern2), "func_unref()");
+ internal_error("func_unref()");
abort();
}
#else
- EMSG2(_(e_intern2), "func_unref()");
+ internal_error("func_unref()");
abort();
#endif
}
@@ -20997,7 +20998,7 @@ void func_ref(char_u *name)
} else if (isdigit(*name)) {
// Only give an error for a numbered function.
// Fail silently, when named or lambda function isn't found.
- EMSG2(_(e_intern2), "func_ref()");
+ internal_error("func_ref()");
}
}
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index b7af102681..31779a544f 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -346,7 +346,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
do { \
const char *const fun_ = (const char *)(fun); \
if (fun_ == NULL) { \
- EMSG2(_(e_intern2), "string(): NULL function name"); \
+ internal_error("string(): NULL function name"); \
ga_concat(gap, "function(NULL"); \
} else { \
ga_concat(gap, "function("); \
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 5040695b09..53c56d0ffd 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1880,14 +1880,20 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
tv->v_lock = VAR_UNLOCKED; \
} while (0)
+static inline void _nothing_conv_empty_dict(typval_T *const tv,
+ dict_T **const dictp)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(2)
+{
+ tv_dict_unref(*dictp);
+ *dictp = NULL;
+ if (tv != NULL) {
+ tv->v_lock = VAR_UNLOCKED;
+ }
+}
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
do { \
assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
- tv_dict_unref((dict_T *)dict); \
- *((dict_T **)&dict) = NULL; \
- if (tv != NULL) { \
- ((typval_T *)tv)->v_lock = VAR_UNLOCKED; \
- } \
+ _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
} while (0)
static inline int _nothing_conv_real_list_after_start(
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index e9531178ef..f2d0d7265f 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -624,7 +624,7 @@ _convert_one_value_regular_dict: {}
break;
}
case VAR_UNKNOWN: {
- EMSG2(_(e_intern2), STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()");
+ internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()");
return FAIL;
}
}
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 9037b3c151..4010a088c8 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -517,7 +517,7 @@ static void discard_exception(except_T *excp, int was_finished)
char_u *saved_IObuff;
if (excp == NULL) {
- EMSG(_(e_internal));
+ internal_error("discard_exception()");
return;
}
@@ -619,8 +619,9 @@ static void catch_exception(except_T *excp)
*/
static void finish_exception(except_T *excp)
{
- if (excp != caught_stack)
- EMSG(_(e_internal));
+ if (excp != caught_stack) {
+ internal_error("finish_exception()");
+ }
caught_stack = caught_stack->caught;
if (caught_stack != NULL) {
set_vim_var_string(VV_EXCEPTION, (char *) caught_stack->value, -1);
@@ -1422,8 +1423,9 @@ void ex_catch(exarg_T *eap)
* ":endtry" or when the catch clause is left by a ":continue",
* ":break", ":return", ":finish", error, interrupt, or another
* exception. */
- if (cstack->cs_exception[cstack->cs_idx] != current_exception)
- EMSG(_(e_internal));
+ if (cstack->cs_exception[cstack->cs_idx] != current_exception) {
+ internal_error("ex_catch()");
+ }
} else {
/*
* If there is a preceding catch clause and it caught the exception,
@@ -1547,7 +1549,7 @@ void ex_finally(exarg_T *eap)
* exception will be discarded. */
if (did_throw && cstack->cs_exception[cstack->cs_idx]
!= current_exception)
- EMSG(_(e_internal));
+ internal_error("ex_finally()");
}
/*
diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua
index d2b90db707..2666ca6e6f 100644
--- a/src/nvim/generators/gen_api_ui_events.lua
+++ b/src/nvim/generators/gen_api_ui_events.lua
@@ -37,7 +37,7 @@ function write_arglist(output, ev, need_copy)
for j = 1, #ev.parameters do
local param = ev.parameters[j]
local kind = string.upper(param[1])
- local do_copy = need_copy and (kind == "ARRAY" or kind == "DICTIONARY" or kind == "STRING")
+ local do_copy = need_copy and (kind == "ARRAY" or kind == "DICTIONARY" or kind == "STRING" or kind == "OBJECT")
output:write(' ADD(args, ')
if do_copy then
output:write('copy_object(')
@@ -91,7 +91,7 @@ for i = 1, #events do
recv_cleanup = recv_cleanup..' api_free_string('..param[2]..');\n'
argc = argc+2
elseif param[1] == 'Array' then
- send = send..' Array copy_'..param[2]..' = copy_array('..param[2]..');\n'
+ send = send..' Array '..copy..' = copy_array('..param[2]..');\n'
argv = argv..', '..copy..'.items, INT2PTR('..copy..'.size)'
recv = (recv..' Array '..param[2]..
' = (Array){.items = argv['..argc..'],'..
@@ -99,6 +99,15 @@ for i = 1, #events do
recv_argv = recv_argv..', '..param[2]
recv_cleanup = recv_cleanup..' api_free_array('..param[2]..');\n'
argc = argc+2
+ elseif param[1] == 'Object' then
+ send = send..' Object *'..copy..' = xmalloc(sizeof(Object));\n'
+ send = send..' *'..copy..' = copy_object('..param[2]..');\n'
+ argv = argv..', '..copy
+ recv = recv..' Object '..param[2]..' = *(Object *)argv['..argc..'];\n'
+ recv_argv = recv_argv..', '..param[2]
+ recv_cleanup = (recv_cleanup..' api_free_object('..param[2]..');\n'..
+ ' xfree(argv['..argc..']);\n')
+ argc = argc+1
elseif param[1] == 'Integer' or param[1] == 'Boolean' then
argv = argv..', INT2PTR('..param[2]..')'
recv_argv = recv_argv..', PTR2INT(argv['..argc..'])'
@@ -119,7 +128,7 @@ for i = 1, #events do
write_signature(bridge_output, ev, 'UI *ui')
bridge_output:write('\n{\n')
bridge_output:write(send)
- bridge_output:write(' UI_BRIDGE_CALL(ui, '..ev.name..', '..argc..', ui'..argv..');\n}\n')
+ bridge_output:write(' UI_BRIDGE_CALL(ui, '..ev.name..', '..argc..', ui'..argv..');\n}\n\n')
end
end
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua
index 36562c0be9..fdc00d5dc0 100644
--- a/src/nvim/generators/gen_options.lua
+++ b/src/nvim/generators/gen_options.lua
@@ -36,6 +36,7 @@ local redraw_flags={
all_windows='P_RALL',
everything='P_RCLR',
curswant='P_CURSWANT',
+ ui_option='P_UI_OPTION',
}
local list_flags={
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 4f8a8528a0..1b5d3472ab 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -254,16 +254,17 @@ static void add_buff(buffheader_T *const buf, const char *const s,
return;
}
- if (buf->bh_first.b_next == NULL) { /* first add to list */
+ if (buf->bh_first.b_next == NULL) { // first add to list
buf->bh_space = 0;
buf->bh_curr = &(buf->bh_first);
- } else if (buf->bh_curr == NULL) { /* buffer has already been read */
- EMSG(_("E222: Add to read buffer"));
+ } else if (buf->bh_curr == NULL) { // buffer has already been read
+ IEMSG(_("E222: Add to read buffer"));
return;
- } else if (buf->bh_index != 0)
+ } else if (buf->bh_index != 0) {
memmove(buf->bh_first.b_next->b_str,
- buf->bh_first.b_next->b_str + buf->bh_index,
- STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
+ buf->bh_first.b_next->b_str + buf->bh_index,
+ STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
+ }
buf->bh_index = 0;
size_t len;
@@ -1152,14 +1153,16 @@ void alloc_typebuf(void)
*/
void free_typebuf(void)
{
- if (typebuf.tb_buf == typebuf_init)
- EMSG2(_(e_intern2), "Free typebuf 1");
- else
+ if (typebuf.tb_buf == typebuf_init) {
+ internal_error("Free typebuf 1");
+ } else {
xfree(typebuf.tb_buf);
- if (typebuf.tb_noremap == noremapbuf_init)
- EMSG2(_(e_intern2), "Free typebuf 2");
- else
+ }
+ if (typebuf.tb_noremap == noremapbuf_init) {
+ internal_error("Free typebuf 2");
+ } else {
xfree(typebuf.tb_noremap);
+ }
}
/*
@@ -3905,7 +3908,7 @@ makemap (
c1 = 't';
break;
default:
- EMSG(_("E228: makemap: Illegal mode"));
+ IEMSG(_("E228: makemap: Illegal mode"));
return FAIL;
}
do { /* do this twice if c2 is set, 3 times with c3 */
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index ef56954aa0..dd216f177f 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -1043,6 +1043,7 @@ EXTERN char_u e_for[] INIT(= N_("E588: :endfor without :for"));
EXTERN char_u e_exists[] INIT(= N_("E13: File exists (add ! to override)"));
EXTERN char_u e_failed[] INIT(= N_("E472: Command failed"));
EXTERN char_u e_internal[] INIT(= N_("E473: Internal error"));
+EXTERN char_u e_intern2[] INIT(= N_("E685: Internal error: %s"));
EXTERN char_u e_interr[] INIT(= N_("Interrupted"));
EXTERN char_u e_invaddr[] INIT(= N_("E14: Invalid address"));
EXTERN char_u e_invarg[] INIT(= N_("E474: Invalid argument"));
@@ -1134,7 +1135,6 @@ EXTERN char_u e_write[] INIT(= N_("E80: Error while writing"));
EXTERN char_u e_zerocount[] INIT(= N_("E939: Positive count required"));
EXTERN char_u e_usingsid[] INIT(= N_(
"E81: Using <SID> not in a script context"));
-EXTERN char_u e_intern2[] INIT(= N_("E685: Internal error: %s"));
EXTERN char_u e_maxmempat[] INIT(= N_(
"E363: pattern uses more memory than 'maxmempattern'"));
EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer"));
diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c
index 3397788b00..526bc284a4 100644
--- a/src/nvim/hashtab.c
+++ b/src/nvim/hashtab.c
@@ -208,7 +208,7 @@ int hash_add(hashtab_T *ht, char_u *key)
hash_T hash = hash_hash(key);
hashitem_T *hi = hash_lookup(ht, (const char *)key, STRLEN(key), hash);
if (!HASHITEM_EMPTY(hi)) {
- EMSG2(_(e_intern2), "hash_add()");
+ internal_error("hash_add()");
return FAIL;
}
hash_add_item(ht, hi, key, hash);
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index 4428dd42aa..4eeba12b87 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.c
@@ -376,8 +376,9 @@ void mf_put(memfile_T *mfp, bhdr_T *hp, bool dirty, bool infile)
{
unsigned flags = hp->bh_flags;
- if ((flags & BH_LOCKED) == 0)
- EMSG(_("E293: block was not locked"));
+ if ((flags & BH_LOCKED) == 0) {
+ IEMSG(_("E293: block was not locked"));
+ }
flags &= ~BH_LOCKED;
if (dirty) {
flags |= BH_DIRTY;
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index f28a9e60f4..80775c607d 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -293,7 +293,7 @@ int ml_open(buf_T *buf)
*/
hp = mf_new(mfp, false, 1);
if (hp->bh_bnum != 0) {
- EMSG(_("E298: Didn't get block nr 0?"));
+ IEMSG(_("E298: Didn't get block nr 0?"));
goto error;
}
b0p = hp->bh_data;
@@ -335,7 +335,7 @@ int ml_open(buf_T *buf)
if ((hp = ml_new_ptr(mfp)) == NULL)
goto error;
if (hp->bh_bnum != 1) {
- EMSG(_("E298: Didn't get block nr 1?"));
+ IEMSG(_("E298: Didn't get block nr 1?"));
goto error;
}
pp = hp->bh_data;
@@ -351,7 +351,7 @@ int ml_open(buf_T *buf)
*/
hp = ml_new_data(mfp, FALSE, 1);
if (hp->bh_bnum != 2) {
- EMSG(_("E298: Didn't get block nr 2?"));
+ IEMSG(_("E298: Didn't get block nr 2?"));
goto error;
}
@@ -635,13 +635,14 @@ static void ml_upd_block0(buf_T *buf, upd_block0_T what)
if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL)
return;
b0p = hp->bh_data;
- if (ml_check_b0_id(b0p) == FAIL)
- EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
- else {
- if (what == UB_FNAME)
+ if (ml_check_b0_id(b0p) == FAIL) {
+ IEMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
+ } else {
+ if (what == UB_FNAME) {
set_b0_fname(b0p, buf);
- else /* what == UB_SAME_DIR */
+ } else { // what == UB_SAME_DIR
set_b0_dir_flag(b0p, buf);
+ }
}
mf_put(mfp, hp, true, false);
}
@@ -1742,11 +1743,11 @@ ml_get_buf (
if (lnum > buf->b_ml.ml_line_count) { /* invalid line number */
if (recursive == 0) {
- /* Avoid giving this message for a recursive call, may happen when
- * the GUI redraws part of the text. */
- ++recursive;
- EMSGN(_("E315: ml_get: invalid lnum: %" PRId64), lnum);
- --recursive;
+ // Avoid giving this message for a recursive call, may happen when
+ // the GUI redraws part of the text.
+ recursive++;
+ IEMSGN(_("E315: ml_get: invalid lnum: %" PRId64), lnum);
+ recursive--;
}
errorret:
STRCPY(IObuff, "???");
@@ -1774,11 +1775,11 @@ errorret:
*/
if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL) {
if (recursive == 0) {
- /* Avoid giving this message for a recursive call, may happen
- * when the GUI redraws part of the text. */
- ++recursive;
- EMSGN(_("E316: ml_get: cannot find line %" PRId64), lnum);
- --recursive;
+ // Avoid giving this message for a recursive call, may happen
+ // when the GUI redraws part of the text.
+ recursive++;
+ IEMSGN(_("E316: ml_get: cannot find line %" PRId64), lnum);
+ recursive--;
}
goto errorret;
}
@@ -2162,7 +2163,7 @@ ml_append_int (
return FAIL;
pp = hp->bh_data; /* must be pointer block */
if (pp->pb_id != PTR_ID) {
- EMSG(_("E317: pointer block id wrong 3"));
+ IEMSG(_("E317: pointer block id wrong 3"));
mf_put(mfp, hp, false, false);
return FAIL;
}
@@ -2295,8 +2296,8 @@ ml_append_int (
* Safety check: fallen out of for loop?
*/
if (stack_idx < 0) {
- EMSG(_("E318: Updated too many blocks?"));
- buf->b_ml.ml_stack_top = 0; /* invalidate stack */
+ IEMSG(_("E318: Updated too many blocks?"));
+ buf->b_ml.ml_stack_top = 0; // invalidate stack
}
}
@@ -2435,7 +2436,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int message)
return FAIL;
pp = hp->bh_data; /* must be pointer block */
if (pp->pb_id != PTR_ID) {
- EMSG(_("E317: pointer block id wrong 4"));
+ IEMSG(_("E317: pointer block id wrong 4"));
mf_put(mfp, hp, false, false);
return FAIL;
}
@@ -2630,9 +2631,9 @@ static void ml_flush_line(buf_T *buf)
new_line = buf->b_ml.ml_line_ptr;
hp = ml_find_line(buf, lnum, ML_FIND);
- if (hp == NULL)
- EMSGN(_("E320: Cannot find line %" PRId64), lnum);
- else {
+ if (hp == NULL) {
+ IEMSGN(_("E320: Cannot find line %" PRId64), lnum);
+ } else {
dp = hp->bh_data;
idx = lnum - buf->b_ml.ml_locked_low;
start = ((dp->db_index[idx]) & DB_INDEX_MASK);
@@ -2841,7 +2842,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
pp = (PTR_BL *)(dp); /* must be pointer block */
if (pp->pb_id != PTR_ID) {
- EMSG(_("E317: pointer block id wrong"));
+ IEMSG(_("E317: pointer block id wrong"));
goto error_block;
}
@@ -2878,13 +2879,14 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
break;
}
}
- if (idx >= (int)pp->pb_count) { /* past the end: something wrong! */
- if (lnum > buf->b_ml.ml_line_count)
- EMSGN(_("E322: line number out of range: %" PRId64 " past the end"),
- lnum - buf->b_ml.ml_line_count);
+ if (idx >= (int)pp->pb_count) { // past the end: something wrong!
+ if (lnum > buf->b_ml.ml_line_count) {
+ IEMSGN(_("E322: line number out of range: %" PRId64 " past the end"),
+ lnum - buf->b_ml.ml_line_count);
- else
- EMSGN(_("E323: line count wrong in block %" PRId64), bnum);
+ } else {
+ IEMSGN(_("E323: line count wrong in block %" PRId64), bnum);
+ }
goto error_block;
}
if (action == ML_DELETE) {
@@ -2960,7 +2962,7 @@ static void ml_lineadd(buf_T *buf, int count)
pp = hp->bh_data; /* must be pointer block */
if (pp->pb_id != PTR_ID) {
mf_put(mfp, hp, false, false);
- EMSG(_("E317: pointer block id wrong 2"));
+ IEMSG(_("E317: pointer block id wrong 2"));
break;
}
pp->pb_pointer[ip->ip_index].pe_line_count += count;
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 5c8f0655bf..1d9a4de9c0 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -583,19 +583,60 @@ void emsg_invreg(int name)
/// Print an error message with unknown number of arguments
bool emsgf(const char *const fmt, ...)
{
+ bool ret;
+
+ va_list ap;
+ va_start(ap, fmt);
+ ret = emsgfv(fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+/// Print an error message with unknown number of arguments
+static bool emsgfv(const char *fmt, va_list ap)
+{
static char errbuf[IOSIZE];
if (emsg_not_now()) {
return true;
}
- va_list ap;
- va_start(ap, fmt);
vim_vsnprintf(errbuf, sizeof(errbuf), fmt, ap, NULL);
- va_end(ap);
return emsg((const char_u *)errbuf);
}
+/// Same as emsg(...), but abort on error when ABORT_ON_INTERNAL_ERROR is
+/// defined. It is used for internal errors only, so that they can be
+/// detected when fuzzing vim.
+void iemsg(const char *s)
+{
+ msg((char_u *)s);
+#ifdef ABORT_ON_INTERNAL_ERROR
+ abort();
+#endif
+}
+
+/// Same as emsgf(...) but abort on error when ABORT_ON_INTERNAL_ERROR is
+/// defined. It is used for internal errors only, so that they can be
+/// detected when fuzzing vim.
+void iemsgf(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ (void)emsgfv(s, ap);
+ va_end(ap);
+#ifdef ABORT_ON_INTERNAL_ERROR
+ abort();
+#endif
+}
+
+/// Give an "Internal error" message.
+void internal_error(char *where)
+{
+ IEMSG2(_(e_intern2), where);
+}
+
static void msg_emsgf_event(void **argv)
{
char *s = argv[0];
diff --git a/src/nvim/message.h b/src/nvim/message.h
index 904a9d3ca1..82935a36a9 100644
--- a/src/nvim/message.h
+++ b/src/nvim/message.h
@@ -49,6 +49,15 @@
/// Like #EMSG, but for messages with one "%" PRIu64 inside
#define EMSGU(s, n) emsgf((const char *) (s), (uint64_t)(n))
+/// Like #EMSG, but for internal messages
+#define IEMSG(s) iemsg((const char *)(s))
+
+/// Like #EMSG2, but for internal messages
+#define IEMSG2(s, p) iemsgf((const char *)(s), (p))
+
+/// Like #EMSGN, but for internal messages
+#define IEMSGN(s, n) iemsgf((const char *)(s), (int64_t)(n))
+
/// Display message at the recorded position
#define MSG_PUTS(s) msg_puts((const char *)(s))
diff --git a/src/nvim/option.c b/src/nvim/option.c
index f8a05f133d..a345906200 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -74,6 +74,7 @@
#include "nvim/undo.h"
#include "nvim/window.h"
#include "nvim/os/os.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/os/input.h"
#include "nvim/os/lang.h"
@@ -248,6 +249,7 @@ typedef struct vimoption {
#define P_RWINONLY 0x10000000U ///< only redraw current window
#define P_NDNAME 0x20000000U ///< only normal dir name chars allowed
+#define P_UI_OPTION 0x40000000U ///< send option to remote ui
#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
@@ -1188,6 +1190,7 @@ do_set (
set_options_default(OPT_FREE | opt_flags);
didset_options();
didset_options2();
+ ui_refresh_options();
redraw_all_later(CLEAR);
} else {
showoptions(1, opt_flags);
@@ -1815,6 +1818,10 @@ do_set (
NULL, false, NULL);
reset_v_option_vars();
xfree(saved_origval);
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ STRING_OBJ(cstr_as_string(*(char **)varp)));
+ }
}
} else {
// key code option(FIXME(tarruda): Show a warning or something
@@ -2251,7 +2258,7 @@ int was_set_insecurely(char_u *opt, int opt_flags)
uint32_t *flagp = insecure_flag(idx, opt_flags);
return (*flagp & P_INSECURE) != 0;
}
- EMSG2(_(e_intern2), "was_set_insecurely()");
+ internal_error("was_set_insecurely()");
return -1;
}
@@ -2310,8 +2317,8 @@ set_string_option_direct (
if (idx == -1) { // Use name.
idx = findoption((const char *)name);
if (idx < 0) { // Not found (should not happen).
- EMSG2(_(e_intern2), "set_string_option_direct()");
- EMSG2(_("For option %s"), name);
+ internal_error("set_string_option_direct()");
+ IEMSG2(_("For option %s"), name);
return;
}
}
@@ -2417,6 +2424,10 @@ static char *set_string_option(const int opt_idx, const char *const value,
NULL, false, NULL);
reset_v_option_vars();
xfree(saved_oldval);
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ STRING_OBJ(cstr_as_string((char *)(*varp))));
+ }
}
return r;
@@ -4024,6 +4035,10 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
(char_u *) options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ BOOLEAN_OBJ(value));
+ }
}
comp_col(); /* in case 'ruler' or 'showcmd' changed */
@@ -4429,6 +4444,10 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
(char_u *) options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ INTEGER_OBJ(value));
+ }
}
comp_col(); /* in case 'columns' or 'ls' changed */
@@ -4999,6 +5018,29 @@ static int optval_default(vimoption_T *p, char_u *varp)
return STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0;
}
+/// Send update to UIs with values of UI relevant options
+void ui_refresh_options(void)
+{
+ for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
+ uint32_t flags = options[opt_idx].flags;
+ if (!(flags & P_UI_OPTION)) {
+ continue;
+ }
+ String name = cstr_as_string(options[opt_idx].fullname);
+ void *varp = options[opt_idx].var;
+ Object value = OBJECT_INIT;
+ if (flags & P_BOOL) {
+ value = BOOLEAN_OBJ(*(int *)varp);
+ } else if (flags & P_NUM) {
+ value = INTEGER_OBJ(*(long *)varp);
+ } else if (flags & P_STRING) {
+ // cstr_as_string handles NULL string
+ value = STRING_OBJ(cstr_as_string(*(char **)varp));
+ }
+ ui_call_option_set(name, value);
+ }
+}
+
/*
* showoneopt: show the value of one option
* must not be called with a hidden option!
@@ -5542,7 +5584,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
case PV_SCL: return (char_u *)&(curwin->w_p_scl);
case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
- default: EMSG(_("E356: get_varp ERROR"));
+ default: IEMSG(_("E356: get_varp ERROR"));
}
/* always return a valid pointer to avoid a crash! */
return (char_u *)&(curbuf->b_p_wm);
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index b16f222705..1b978137ae 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -447,6 +447,9 @@ EXTERN char_u *p_popt; // 'printoptions'
EXTERN char_u *p_header; // 'printheader'
EXTERN int p_prompt; // 'prompt'
EXTERN char_u *p_guicursor; // 'guicursor'
+EXTERN char_u *p_guifont; // 'guifont'
+EXTERN char_u *p_guifontset; // 'guifontset'
+EXTERN char_u *p_guifontwide; // 'guifontwide'
EXTERN char_u *p_hf; // 'helpfile'
EXTERN long p_hh; // 'helpheight'
EXTERN char_u *p_hlg; // 'helplang'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index dd28a765fd..45efd49391 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -68,7 +68,8 @@ return {
type='bool', scope={'global'},
vi_def=true,
vim=true,
- redraw={'everything'},
+ redraw={'everything', 'ui_option'},
+
varname='p_arshape',
defaults={if_true={vi=true}}
},
@@ -91,7 +92,7 @@ return {
full_name='ambiwidth', abbreviation='ambw',
type='string', scope={'global'},
vi_def=true,
- redraw={'everything'},
+ redraw={'everything', 'ui_option'},
varname='p_ambw',
defaults={if_true={vi="single"}}
},
@@ -661,7 +662,7 @@ return {
full_name='emoji', abbreviation='emo',
type='bool', scope={'global'},
vi_def=true,
- redraw={'everything'},
+ redraw={'everything', 'ui_option'},
varname='p_emoji',
defaults={if_true={vi=true}}
},
@@ -1021,23 +1022,26 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
vi_def=true,
- redraw={'everything'},
- enable_if=false,
+ varname='p_guifont',
+ redraw={'everything', 'ui_option'},
+ defaults={if_true={vi=""}}
},
{
full_name='guifontset', abbreviation='gfs',
type='string', list='onecomma', scope={'global'},
vi_def=true,
- redraw={'everything'},
- enable_if=false,
+ varname='p_guifontset',
+ redraw={'everything', 'ui_option'},
+ defaults={if_true={vi=""}}
},
{
full_name='guifontwide', abbreviation='gfw',
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
vi_def=true,
- redraw={'everything'},
- enable_if=false,
+ redraw={'everything', 'ui_option'},
+ varname='p_guifontwide',
+ defaults={if_true={vi=""}}
},
{
full_name='guioptions', abbreviation='go',
@@ -2164,7 +2168,7 @@ return {
full_name='showtabline', abbreviation='stal',
type='number', scope={'global'},
vi_def=true,
- redraw={'all_windows'},
+ redraw={'all_windows', 'ui_option'},
varname='p_stal',
defaults={if_true={vi=1}}
},
@@ -2435,7 +2439,7 @@ return {
full_name='termguicolors', abbreviation='tgc',
type='bool', scope={'global'},
vi_def=false,
- redraw={'everything'},
+ redraw={'everything', 'ui_option'},
varname='p_tgc',
defaults={if_true={vi=false}}
},
@@ -2505,11 +2509,10 @@ return {
full_name='titleold',
type='string', scope={'global'},
secure=true,
- gettext=true,
no_mkrc=true,
vi_def=true,
varname='p_titleold',
- defaults={if_true={vi=N_("")}}
+ defaults={if_true={vi=""}}
},
{
full_name='titlestring',
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index de0cd10d9c..999fcd434a 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -887,7 +887,7 @@ bool os_setenv_append_path(const char *fname)
# define MAX_ENVPATHLEN INT_MAX
#endif
if (!path_is_absolute_path((char_u *)fname)) {
- EMSG2(_(e_intern2), "os_setenv_append_path()");
+ internal_error("os_setenv_append_path()");
return false;
}
const char *tail = (char *)path_tail_with_sep((char_u *)fname);
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index 53301e4b53..855ca2ae47 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -72,8 +72,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
ELOG("forkpty failed: %s", strerror(errno));
return status;
} else if (pid == 0) {
- init_child(ptyproc);
- abort();
+ init_child(ptyproc); // never returns
}
// make sure the master file descriptor is non blocking
@@ -163,14 +162,15 @@ static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL
Process *proc = (Process *)ptyproc;
if (proc->cwd && os_chdir(proc->cwd) != 0) {
- fprintf(stderr, "chdir failed: %s\n", strerror(errno));
+ ELOG("chdir failed: %s", strerror(errno));
return;
}
char *prog = ptyproc->process.argv[0];
setenv("TERM", ptyproc->term_name ? ptyproc->term_name : "ansi", 1);
execvp(prog, ptyproc->process.argv);
- fprintf(stderr, "execvp failed: %s: %s\n", strerror(errno), prog);
+ ELOG("execvp failed: %s: %s", strerror(errno), prog);
+ _exit(122); // 122 is EXEC_FAILED in the Vim source.
}
static void init_termios(struct termios *termios) FUNC_ATTR_NONNULL_ALL
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index fd6d3b32e4..732be072e1 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -10,6 +10,7 @@
#endif
#include "nvim/ascii.h"
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/globals.h"
#include "nvim/memline.h"
@@ -162,7 +163,7 @@ static void on_signal(SignalWatcher *handle, int signum, void *data)
}
break;
default:
- fprintf(stderr, "Invalid signal %d", signum);
+ ELOG("invalid signal: %d", signum);
break;
}
}
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index a4dc9c68ce..7e2193b8bb 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -2856,7 +2856,7 @@ static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last)
if (old_last == NULL) {
if (buf != curbuf) {
- EMSG2(_(e_intern2), "qf_fill_buffer()");
+ internal_error("qf_fill_buffer()");
return;
}
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 463a408885..a1332a43dd 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -458,16 +458,13 @@ static int toggle_Magic(int x)
/* Used for an error (down from) vim_regcomp(): give the error message, set
* rc_did_emsg and return NULL */
-#define EMSG_RET_NULL(m) return (EMSG(m), rc_did_emsg = TRUE, (void *)NULL)
-#define EMSG_RET_FAIL(m) return (EMSG(m), rc_did_emsg = TRUE, FAIL)
-#define EMSG2_RET_NULL(m, \
- c) return (EMSG2((m), \
- (c) ? "" : "\\"), rc_did_emsg = TRUE, \
- (void *)NULL)
-#define EMSG2_RET_FAIL(m, \
- c) return (EMSG2((m), \
- (c) ? "" : "\\"), rc_did_emsg = TRUE, \
- FAIL)
+#define EMSG_RET_NULL(m) return (EMSG(m), rc_did_emsg = true, (void *)NULL)
+#define IEMSG_RET_NULL(m) return (IEMSG(m), rc_did_emsg = true, (void *)NULL)
+#define EMSG_RET_FAIL(m) return (EMSG(m), rc_did_emsg = true, FAIL)
+#define EMSG2_RET_NULL(m, c) \
+ return (EMSG2((m), (c) ? "" : "\\"), rc_did_emsg = true, (void *)NULL)
+#define EMSG2_RET_FAIL(m, c) \
+ return (EMSG2((m), (c) ? "" : "\\"), rc_did_emsg = true, FAIL)
#define EMSG_ONE_RET_NULL EMSG2_RET_NULL(_( \
"E369: invalid item in %s%%[]"), reg_magic == MAGIC_ALL)
@@ -1891,8 +1888,8 @@ static char_u *regatom(int *flagp)
case Magic(')'):
if (one_exactly)
EMSG_ONE_RET_NULL;
- EMSG_RET_NULL(_(e_internal)); /* Supposed to be caught earlier. */
- /* NOTREACHED */
+ IEMSG_RET_NULL(_(e_internal)); // Supposed to be caught earlier.
+ // NOTREACHED
case Magic('='):
case Magic('?'):
@@ -4534,7 +4531,7 @@ regmatch (
brace_max[no] = OPERAND_MAX(scan);
brace_count[no] = 0;
} else {
- EMSG(_(e_internal)); /* Shouldn't happen */
+ internal_error("BRACE_LIMITS");
status = RA_FAIL;
}
}
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 6a1b46fb5b..d2b2575f6a 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -5354,7 +5354,7 @@ add_sound_suggest (
// Find the word nr in the soundfold tree.
sfwordnr = soundfold_find(slang, goodword);
if (sfwordnr < 0) {
- EMSG2(_(e_intern2), "add_sound_suggest()");
+ internal_error("add_sound_suggest()");
return;
}
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 60897c08da..021bb6eac4 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -70,6 +70,7 @@ typedef struct {
UIBridgeData *bridge;
Loop *loop;
bool stop;
+ uv_timer_t after_startup_timer;
unibi_var_t params[9];
char buf[OUTBUF_SIZE];
size_t bufpos;
@@ -151,6 +152,7 @@ UI *tui_start(void)
ui->suspend = tui_suspend;
ui->set_title = tui_set_title;
ui->set_icon = tui_set_icon;
+ ui->option_set= tui_option_set;
ui->event = tui_event;
memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
@@ -168,24 +170,6 @@ static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index,
return unibi_run(str, data->params, buf, len);
}
-/// Emits some termcodes after Nvim startup, which were observed to slowdown
-/// rendering during startup in tmux 2.3 (+focus-events). #7649
-static void terminfo_after_startup_event(void **argv)
-{
- UI *ui = argv[0];
- bool defer = argv[1] != NULL; // clever(?) boolean without malloc() dance.
- TUIData *data = ui->data;
- if (defer) { // We're on the main-loop. Now forward to the TUI loop.
- loop_schedule(data->loop,
- event_create(terminfo_after_startup_event, 2, ui, NULL));
- return;
- }
- // Enable bracketed paste
- unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
- // Enable focus reporting
- unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting);
-}
-
static void termname_set_event(void **argv)
{
char *termname = argv[0];
@@ -265,6 +249,9 @@ static void terminfo_start(UI *ui)
unibi_out(ui, unibi_enter_ca_mode);
unibi_out(ui, unibi_keypad_xmit);
unibi_out(ui, unibi_clear_screen);
+ // Enable bracketed paste
+ unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
+
uv_loop_init(&data->write_loop);
if (data->out_isatty) {
uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0);
@@ -277,9 +264,6 @@ static void terminfo_start(UI *ui)
uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0);
uv_pipe_open(&data->output_handle.pipe, data->out_fd);
}
-
- loop_schedule(&main_loop,
- event_create(terminfo_after_startup_event, 2, ui, ui));
}
static void terminfo_stop(UI *ui)
@@ -307,6 +291,18 @@ static void terminfo_stop(UI *ui)
unibi_destroy(data->ut);
}
+static void after_startup_timer_cb(uv_timer_t *handle)
+ FUNC_ATTR_NONNULL_ALL
+{
+ UI *ui = handle->data;
+ TUIData *data = ui->data;
+ uv_timer_stop(&data->after_startup_timer);
+
+ // Emit this after Nvim startup, not during. This works around a tmux
+ // 2.3 bug(?) which caused slow drawing during startup. #7649
+ unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting);
+}
+
static void tui_terminal_start(UI *ui)
{
TUIData *data = ui->data;
@@ -316,6 +312,8 @@ static void tui_terminal_start(UI *ui)
update_size(ui);
signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
term_input_start(&data->input);
+
+ uv_timer_start(&data->after_startup_timer, after_startup_timer_cb, 500, 0);
}
static void tui_terminal_stop(UI *ui)
@@ -349,6 +347,8 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
#ifdef UNIX
signal_watcher_start(&data->cont_handle, sigcont_cb, SIGCONT);
#endif
+ uv_timer_init(&data->loop->uv, &data->after_startup_timer);
+ data->after_startup_timer.data = ui;
#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
@@ -367,6 +367,7 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
loop_poll_events(&tui_loop, -1); // tui_loop.events is never processed
}
+ uv_close((uv_handle_t *)&data->after_startup_timer, NULL);
ui_bridge_stopped(bridge);
term_input_destroy(&data->input);
signal_watcher_stop(&data->cont_handle);
@@ -1136,6 +1137,14 @@ static void tui_set_icon(UI *ui, String icon)
{
}
+static void tui_option_set(UI *ui, String name, Object value)
+{
+ if (strequal(name.data, "termguicolors")) {
+ // NB: value for bridge is set in ui_bridge.c
+ ui->rgb = value.data.boolean;
+ }
+}
+
// NB: if we start to use this, the ui_bridge must be updated
// to make a copy for the tui thread
static void tui_event(UI *ui, char *name, Array args, bool *args_consumed)
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 3b8b3ac9a7..81da88c54a 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -339,6 +339,7 @@ void ui_attach_impl(UI *ui)
}
uis[ui_count++] = ui;
+ ui_refresh_options();
ui_refresh();
}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index f1ea0716e6..0e40a1a215 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -31,11 +31,9 @@ struct ui_t {
bool ui_ext[UI_WIDGETS]; ///< Externalized widgets
int width, height;
void *data;
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui_events.generated.h"
#endif
-
void (*event)(UI *ui, char *name, Array args, bool *args_consumed);
void (*stop)(UI *ui);
};
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 7573fa1653..0a69cf0ecb 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -66,6 +66,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
rv->bridge.suspend = ui_bridge_suspend;
rv->bridge.set_title = ui_bridge_set_title;
rv->bridge.set_icon = ui_bridge_set_icon;
+ rv->bridge.option_set = ui_bridge_option_set;
rv->scheduler = scheduler;
for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
@@ -144,6 +145,29 @@ static void ui_bridge_highlight_set_event(void **argv)
xfree(argv[1]);
}
+static void ui_bridge_option_set(UI *ui, String name, Object value)
+{
+ // Assumes bridge is only used by TUI
+ if (strequal(name.data, "termguicolors")) {
+ ui->rgb = value.data.boolean;
+ }
+ String copy_name = copy_string(name);
+ Object *copy_value = xmalloc(sizeof(Object));
+ *copy_value = copy_object(value);
+ UI_BRIDGE_CALL(ui, option_set, 4, ui,
+ copy_name.data, INT2PTR(copy_name.size), copy_value);
+}
+static void ui_bridge_option_set_event(void **argv)
+{
+ UI *ui = UI(argv[0]);
+ String name = (String){ .data = argv[1], .size = (size_t)argv[2] };
+ Object value = *(Object *)argv[3];
+ ui->option_set(ui, name, value);
+ api_free_string(name);
+ api_free_object(value);
+ xfree(argv[3]);
+}
+
static void ui_bridge_suspend(UI *b)
{
UIBridgeData *data = (UIBridgeData *)b;
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 3d7ebc8837..f611a3bb29 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -2096,8 +2096,8 @@ void undo_time(long step, int sec, int file, int absolute)
uhp = uhp->uh_prev.ptr;
if (uhp == NULL || uhp->uh_walk != mark) {
- /* Need to redo more but can't find it... */
- EMSG2(_(e_intern2), "undo_time()");
+ // Need to redo more but can't find it...
+ internal_error("undo_time()");
break;
}
}
@@ -2163,8 +2163,8 @@ static void u_undoredo(int undo)
if (top > curbuf->b_ml.ml_line_count || top >= bot
|| bot > curbuf->b_ml.ml_line_count + 1) {
unblock_autocmds();
- EMSG(_("E438: u_undo: line numbers wrong"));
- changed(); /* don't want UNCHANGED now */
+ IEMSG(_("E438: u_undo: line numbers wrong"));
+ changed(); // don't want UNCHANGED now
return;
}
@@ -2655,7 +2655,7 @@ static void u_unch_branch(u_header_T *uhp)
static u_entry_T *u_get_headentry(void)
{
if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) {
- EMSG(_("E439: undo list corrupt"));
+ IEMSG(_("E439: undo list corrupt"));
return NULL;
}
return curbuf->b_u_newhead->uh_entry;
@@ -2684,11 +2684,11 @@ static void u_getbot(void)
extra = curbuf->b_ml.ml_line_count - uep->ue_lcount;
uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count) {
- EMSG(_("E440: undo line missing"));
- uep->ue_bot = uep->ue_top + 1; /* assume all lines deleted, will
- * get all the old lines back
- * without deleting the current
- * ones */
+ IEMSG(_("E440: undo line missing"));
+ uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will
+ // get all the old lines back
+ // without deleting the current
+ // ones
}
curbuf->b_u_newhead->uh_getbot_entry = NULL;
diff --git a/src/nvim/version.c b/src/nvim/version.c
index e8cf1d0f0b..8ab9fc1a4b 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -1182,7 +1182,7 @@ static const int included_patches[] = {
// 77 NA
// 76 NA
75,
- // 74,
+ 74,
73,
// 72 NA
// 71 NA
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 583314d437..5e85a9bede 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2115,7 +2115,7 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
ptp = ptp->tp_next)
;
if (ptp == NULL) {
- EMSG2(_(e_intern2), "win_close_othertab()");
+ internal_error("win_close_othertab()");
return;
}
ptp->tp_next = tp->tp_next;