aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api')
-rw-r--r--src/nvim/api/deprecated.c40
-rw-r--r--src/nvim/api/extmark.c24
-rw-r--r--src/nvim/api/keysets_defs.h1
-rw-r--r--src/nvim/api/options.c55
-rw-r--r--src/nvim/api/private/helpers.c27
-rw-r--r--src/nvim/api/private/helpers.h6
-rw-r--r--src/nvim/api/ui_events.in.h4
-rw-r--r--src/nvim/api/vim.c64
-rw-r--r--src/nvim/api/win_config.c13
9 files changed, 132 insertions, 102 deletions
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
index 6376011106..b38a7d4173 100644
--- a/src/nvim/api/deprecated.c
+++ b/src/nvim/api/deprecated.c
@@ -533,7 +533,7 @@ void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err)
FUNC_API_SINCE(1)
FUNC_API_DEPRECATED_SINCE(11)
{
- set_option_to(channel_id, NULL, kOptReqGlobal, name, value, err);
+ set_option_to(channel_id, NULL, kOptScopeGlobal, name, value, err);
}
/// Gets the global value of an option.
@@ -546,7 +546,7 @@ Object nvim_get_option(String name, Error *err)
FUNC_API_SINCE(1)
FUNC_API_DEPRECATED_SINCE(11)
{
- return get_option_from(NULL, kOptReqGlobal, name, err);
+ return get_option_from(NULL, kOptScopeGlobal, name, err);
}
/// Gets a buffer option value
@@ -566,7 +566,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
return (Object)OBJECT_INIT;
}
- return get_option_from(buf, kOptReqBuf, name, err);
+ return get_option_from(buf, kOptScopeBuf, name, err);
}
/// Sets a buffer option value. Passing `nil` as value deletes the option (only
@@ -588,7 +588,7 @@ void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object
return;
}
- set_option_to(channel_id, buf, kOptReqBuf, name, value, err);
+ set_option_to(channel_id, buf, kOptScopeBuf, name, value, err);
}
/// Gets a window option value
@@ -608,7 +608,7 @@ Object nvim_win_get_option(Window window, String name, Error *err)
return (Object)OBJECT_INIT;
}
- return get_option_from(win, kOptReqWin, name, err);
+ return get_option_from(win, kOptScopeWin, name, err);
}
/// Sets a window option value. Passing `nil` as value deletes the option (only
@@ -630,26 +630,32 @@ void nvim_win_set_option(uint64_t channel_id, Window window, String name, Object
return;
}
- set_option_to(channel_id, win, kOptReqWin, name, value, err);
+ set_option_to(channel_id, win, kOptScopeWin, name, value, err);
}
/// Gets the value of a global or local (buffer, window) option.
///
/// @param[in] from Pointer to buffer or window for local option value.
-/// @param req_scope Requested option scope. See OptReqScope in option.h.
+/// @param req_scope Requested option scope. See OptScope in option.h.
/// @param name The option name.
/// @param[out] err Details of an error that may have occurred.
///
/// @return the option value.
-static Object get_option_from(void *from, OptReqScope req_scope, String name, Error *err)
+static Object get_option_from(void *from, OptScope req_scope, String name, Error *err)
{
VALIDATE_S(name.size > 0, "option name", "<empty>", {
return (Object)OBJECT_INIT;
});
- OptVal value = get_option_value_strict(find_option(name.data), req_scope, from, err);
- if (ERROR_SET(err)) {
- return (Object)OBJECT_INIT;
+ OptIndex opt_idx = find_option(name.data);
+ OptVal value = NIL_OPTVAL;
+
+ if (option_has_scope(opt_idx, req_scope)) {
+ value = get_option_value_for(opt_idx, req_scope == kOptScopeGlobal ? OPT_GLOBAL : OPT_LOCAL,
+ req_scope, from, err);
+ if (ERROR_SET(err)) {
+ return (Object)OBJECT_INIT;
+ }
}
VALIDATE_S(value.type != kOptValTypeNil, "option name", name.data, {
@@ -662,11 +668,11 @@ static Object get_option_from(void *from, OptReqScope req_scope, String name, Er
/// Sets the value of a global or local (buffer, window) option.
///
/// @param[in] to Pointer to buffer or window for local option value.
-/// @param req_scope Requested option scope. See OptReqScope in option.h.
+/// @param req_scope Requested option scope. See OptScope in option.h.
/// @param name The option name.
/// @param value New option value.
/// @param[out] err Details of an error that may have occurred.
-static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, String name,
+static void set_option_to(uint64_t channel_id, void *to, OptScope req_scope, String name,
Object value, Error *err)
{
VALIDATE_S(name.size > 0, "option name", "<empty>", {
@@ -689,12 +695,12 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope,
return;
});
- int attrs = get_option_attrs(opt_idx);
// For global-win-local options -> setlocal
// For win-local options -> setglobal and setlocal (opt_flags == 0)
- const int opt_flags = (req_scope == kOptReqWin && !(attrs & SOPT_GLOBAL))
- ? 0
- : (req_scope == kOptReqGlobal) ? OPT_GLOBAL : OPT_LOCAL;
+ const int opt_flags
+ = (req_scope == kOptScopeWin && !option_has_scope(opt_idx, kOptScopeGlobal))
+ ? 0
+ : ((req_scope == kOptScopeGlobal) ? OPT_GLOBAL : OPT_LOCAL);
WITH_SCRIPT_CONTEXT(channel_id, {
set_option_value_for(name.data, opt_idx, optval, opt_flags, req_scope, to, err);
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index 7786c30624..c94b8df9ea 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -381,8 +381,9 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// - id : id of the extmark to edit.
/// - end_row : ending line of the mark, 0-based inclusive.
/// - end_col : ending col of the mark, 0-based exclusive.
-/// - hl_group : name of the highlight group used to highlight
-/// this mark.
+/// - hl_group : highlight group used for the text range. This and below
+/// highlight groups can be supplied either as a string or as an integer,
+/// the latter of which can be obtained using |nvim_get_hl_id_by_name()|.
/// - hl_eol : when true, for a multiline highlight covering the
/// EOL of a line, continue the highlight for the rest
/// of the screen line (just like for diff and
@@ -392,9 +393,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// text chunk with specified highlight. `highlight` element
/// can either be a single highlight group, or an array of
/// multiple highlight groups that will be stacked
-/// (highest priority last). A highlight group can be supplied
-/// either as a string or as an integer, the latter which
-/// can be obtained using |nvim_get_hl_id_by_name()|.
+/// (highest priority last).
/// - virt_text_pos : position of virtual text. Possible values:
/// - "eol": right after eol character (default).
/// - "overlay": display over the specified column, without
@@ -465,15 +464,12 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// buffer or end of the line respectively. Defaults to true.
/// - sign_text: string of length 1-2 used to display in the
/// sign column.
-/// - sign_hl_group: name of the highlight group used to
-/// highlight the sign column text.
-/// - number_hl_group: name of the highlight group used to
-/// highlight the number column.
-/// - line_hl_group: name of the highlight group used to
-/// highlight the whole line.
-/// - cursorline_hl_group: name of the highlight group used to
-/// highlight the sign column text when the cursor is on
-/// the same line as the mark and 'cursorline' is enabled.
+/// - sign_hl_group: highlight group used for the sign column text.
+/// - number_hl_group: highlight group used for the number column.
+/// - line_hl_group: highlight group used for the whole line.
+/// - cursorline_hl_group: highlight group used for the sign
+/// column text when the cursor is on the same line as the
+/// mark and 'cursorline' is enabled.
/// - conceal: string which should be either empty or a single
/// character. Enable concealing similar to |:syn-conceal|.
/// When a character is supplied it is used as |:syn-cchar|.
diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h
index 552612dd13..96aabb851f 100644
--- a/src/nvim/api/keysets_defs.h
+++ b/src/nvim/api/keysets_defs.h
@@ -119,6 +119,7 @@ typedef struct {
Array bufpos;
Boolean external;
Boolean focusable;
+ Boolean mouse;
Boolean vertical;
Integer zindex;
Object border;
diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c
index 1a0edd551e..3289daeb6f 100644
--- a/src/nvim/api/options.c
+++ b/src/nvim/api/options.c
@@ -23,8 +23,8 @@
#endif
static int validate_option_value_args(Dict(option) *opts, char *name, OptIndex *opt_idxp,
- int *scope, OptReqScope *req_scope, void **from,
- char **filetype, Error *err)
+ int *scope, OptScope *req_scope, void **from, char **filetype,
+ Error *err)
{
#define HAS_KEY_X(d, v) HAS_KEY(d, option, v)
if (HAS_KEY_X(opts, scope)) {
@@ -39,14 +39,14 @@ static int validate_option_value_args(Dict(option) *opts, char *name, OptIndex *
}
}
- *req_scope = kOptReqGlobal;
+ *req_scope = kOptScopeGlobal;
if (filetype != NULL && HAS_KEY_X(opts, filetype)) {
*filetype = opts->filetype.data;
}
if (HAS_KEY_X(opts, win)) {
- *req_scope = kOptReqWin;
+ *req_scope = kOptScopeWin;
*from = find_window_by_handle(opts->win, err);
if (ERROR_SET(err)) {
return FAIL;
@@ -59,7 +59,7 @@ static int validate_option_value_args(Dict(option) *opts, char *name, OptIndex *
return FAIL;
});
*scope = OPT_LOCAL;
- *req_scope = kOptReqBuf;
+ *req_scope = kOptScopeBuf;
*from = find_buffer_by_handle(opts->buf, err);
if (ERROR_SET(err)) {
return FAIL;
@@ -78,18 +78,17 @@ static int validate_option_value_args(Dict(option) *opts, char *name, OptIndex *
});
*opt_idxp = find_option(name);
- int flags = get_option_attrs(*opt_idxp);
- if (flags == 0) {
- // hidden or unknown option
+ if (*opt_idxp == kOptInvalid) {
+ // unknown option
api_set_error(err, kErrorTypeValidation, "Unknown option '%s'", name);
- } else if (*req_scope == kOptReqBuf || *req_scope == kOptReqWin) {
+ } else if (*req_scope == kOptScopeBuf || *req_scope == kOptScopeWin) {
// if 'buf' or 'win' is passed, make sure the option supports it
- int req_flags = *req_scope == kOptReqBuf ? SOPT_BUF : SOPT_WIN;
- if (!(flags & req_flags)) {
- char *tgt = *req_scope & kOptReqBuf ? "buf" : "win";
- char *global = flags & SOPT_GLOBAL ? "global " : "";
- char *req = flags & SOPT_BUF ? "buffer-local "
- : flags & SOPT_WIN ? "window-local " : "";
+ if (!option_has_scope(*opt_idxp, *req_scope)) {
+ char *tgt = *req_scope == kOptScopeBuf ? "buf" : "win";
+ char *global = option_has_scope(*opt_idxp, kOptScopeGlobal) ? "global " : "";
+ char *req = option_has_scope(*opt_idxp, kOptScopeBuf)
+ ? "buffer-local "
+ : (option_has_scope(*opt_idxp, kOptScopeWin) ? "window-local " : "");
api_set_error(err, kErrorTypeValidation, "'%s' cannot be passed for %s%soption '%s'",
tgt, global, req, name);
@@ -153,7 +152,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
{
OptIndex opt_idx = 0;
int scope = 0;
- OptReqScope req_scope = kOptReqGlobal;
+ OptScope req_scope = kOptScopeGlobal;
void *from = NULL;
char *filetype = NULL;
@@ -166,6 +165,14 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
buf_T *ftbuf = do_ft_buf(filetype, &aco, err);
if (ERROR_SET(err)) {
+ if (ftbuf != NULL) {
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+
+ assert(curbuf != ftbuf); // safety check
+ wipe_buffer(ftbuf, false);
+ }
+
return (Object)OBJECT_INIT;
}
@@ -175,7 +182,6 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
}
OptVal value = get_option_value_for(opt_idx, scope, req_scope, from, err);
- bool hidden = is_option_hidden(opt_idx);
if (ftbuf != NULL) {
// restore curwin/curbuf and a few other things
@@ -189,7 +195,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
goto err;
}
- VALIDATE_S(!hidden && value.type != kOptValTypeNil, "option", name.data, {
+ VALIDATE_S(value.type != kOptValTypeNil, "option", name.data, {
goto err;
});
@@ -219,7 +225,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(
{
OptIndex opt_idx = 0;
int scope = 0;
- OptReqScope req_scope = kOptReqGlobal;
+ OptScope req_scope = kOptScopeGlobal;
void *to = NULL;
if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &to, NULL, err)) {
return;
@@ -231,9 +237,8 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(
// - option is global or local to window (global-local)
//
// Then force scope to local since we don't want to change the global option
- if (req_scope == kOptReqWin && scope == 0) {
- int flags = get_option_attrs(opt_idx);
- if (flags & SOPT_GLOBAL) {
+ if (req_scope == kOptScopeWin && scope == 0) {
+ if (option_has_scope(opt_idx, kOptScopeGlobal)) {
scope = OPT_LOCAL;
}
}
@@ -306,15 +311,15 @@ Dict nvim_get_option_info2(String name, Dict(option) *opts, Arena *arena, Error
{
OptIndex opt_idx = 0;
int scope = 0;
- OptReqScope req_scope = kOptReqGlobal;
+ OptScope req_scope = kOptScopeGlobal;
void *from = NULL;
if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &from, NULL,
err)) {
return (Dict)ARRAY_DICT_INIT;
}
- buf_T *buf = (req_scope == kOptReqBuf) ? (buf_T *)from : curbuf;
- win_T *win = (req_scope == kOptReqWin) ? (win_T *)from : curwin;
+ buf_T *buf = (req_scope == kOptScopeBuf) ? (buf_T *)from : curbuf;
+ win_T *win = (req_scope == kOptScopeWin) ? (win_T *)from : curwin;
return get_vimoption(name, scope, buf, win, arena, err);
}
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index e1fb4ed732..8ddaecc58e 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -771,7 +771,7 @@ int object_to_hl_id(Object obj, const char *what, Error *err)
int id = (int)obj.data.integer;
return (1 <= id && id <= highlight_num_groups()) ? id : 0;
} else {
- api_set_error(err, kErrorTypeValidation, "Invalid highlight: %s", what);
+ api_set_error(err, kErrorTypeValidation, "Invalid hl_group: %s", what);
return 0;
}
}
@@ -809,31 +809,22 @@ HlMessage parse_hl_msg(Array chunks, Error *err)
{
HlMessage hl_msg = KV_INITIAL_VALUE;
for (size_t i = 0; i < chunks.size; i++) {
- if (chunks.items[i].type != kObjectTypeArray) {
- api_set_error(err, kErrorTypeValidation, "Chunk is not an array");
+ VALIDATE_T("chunk", kObjectTypeArray, chunks.items[i].type, {
goto free_exit;
- }
+ });
Array chunk = chunks.items[i].data.array;
- if (chunk.size == 0 || chunk.size > 2
- || chunk.items[0].type != kObjectTypeString
- || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) {
- api_set_error(err, kErrorTypeValidation,
- "Chunk is not an array with one or two strings");
+ VALIDATE((chunk.size > 0 && chunk.size <= 2 && chunk.items[0].type == kObjectTypeString),
+ "%s", "Invalid chunk: expected Array with 1 or 2 Strings", {
goto free_exit;
- }
+ });
String str = copy_string(chunk.items[0].data.string, NULL);
- int attr = 0;
+ int hl_id = 0;
if (chunk.size == 2) {
- String hl = chunk.items[1].data.string;
- if (hl.size > 0) {
- // TODO(bfredl): use object_to_hl_id and allow integer
- int hl_id = syn_check_group(hl.data, hl.size);
- attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
- }
+ hl_id = object_to_hl_id(chunk.items[1], "text highlight", err);
}
- kv_push(hl_msg, ((HlMessageChunk){ .text = str, .attr = attr }));
+ kv_push(hl_msg, ((HlMessageChunk){ .text = str, .hl_id = hl_id }));
}
return hl_msg;
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index 57932e067e..d06f5c9c65 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -111,6 +111,12 @@ typedef kvec_withinit_t(Object, 16) ArrayBuilder;
#define STATIC_CSTR_AS_OBJ(s) STRING_OBJ(STATIC_CSTR_AS_STRING(s))
#define STATIC_CSTR_TO_OBJ(s) STRING_OBJ(STATIC_CSTR_TO_STRING(s))
+#define API_CLEAR_STRING(s) \
+ do { \
+ XFREE_CLEAR(s.data); \
+ s.size = 0; \
+ } while (0)
+
// Helpers used by the generated msgpack-rpc api wrappers
#define api_init_boolean
#define api_init_integer
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index 2bd8792d71..0ed208fc1a 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -102,7 +102,7 @@ void win_pos(Integer grid, Window win, Integer startrow, Integer startcol, Integ
Integer height)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
void win_float_pos(Integer grid, Window win, String anchor, Integer anchor_grid, Float anchor_row,
- Float anchor_col, Boolean focusable, Integer zindex)
+ Float anchor_col, Boolean mouse_enabled, Integer zindex)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
void win_external_pos(Integer grid, Window win)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
@@ -159,7 +159,7 @@ void wildmenu_hide(void)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void msg_show(String kind, Array content, Boolean replace_last)
- FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
+ FUNC_API_SINCE(6) FUNC_API_FAST FUNC_API_REMOTE_ONLY;
void msg_clear(void)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
void msg_showcmd(Array content)
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 8c88a19147..83f9aa573d 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -594,10 +594,12 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Arena *arena, Er
kvi_init(cookie.rv);
int flags = DIP_DIRFILE | (all ? DIP_ALL : 0);
+ TryState tstate;
+
+ try_enter(&tstate);
+ do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie);
+ vim_ignored = try_leave(&tstate, err);
- TRY_WRAP(err, {
- do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie);
- });
return arena_take_arraybuilder(arena, &cookie.rv);
}
@@ -777,12 +779,12 @@ void nvim_set_vvar(String name, Object value, Error *err)
/// Echo a message.
///
/// @param chunks A list of `[text, hl_group]` arrays, each representing a
-/// text chunk with specified highlight. `hl_group` element
-/// can be omitted for no highlight.
+/// text chunk with specified highlight group name or ID.
+/// `hl_group` element can be omitted for no highlight.
/// @param history if true, add to |message-history|.
/// @param opts Optional parameters.
-/// - verbose: Message was printed as a result of 'verbose' option
-/// if Nvim was invoked with -V3log_file, the message will be
+/// - verbose: Message is printed as a result of 'verbose' option.
+/// If Nvim was invoked with -V3log_file, the message will be
/// redirected to the log_file and suppressed from direct output.
void nvim_echo(Array chunks, Boolean history, Dict(echo_opts) *opts, Error *err)
FUNC_API_SINCE(7)
@@ -796,7 +798,7 @@ void nvim_echo(Array chunks, Boolean history, Dict(echo_opts) *opts, Error *err)
verbose_enter();
}
- msg_multiattr(hl_msg, history ? "echomsg" : "echo", history);
+ msg_multihl(hl_msg, history ? "echomsg" : "echo", history);
if (opts->verbose) {
verbose_leave();
@@ -1002,10 +1004,10 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
if (scratch) {
- set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL, 0, kOptReqBuf,
- buf);
- set_option_direct_for(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL, 0, kOptReqBuf,
- buf);
+ set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL, 0,
+ kOptScopeBuf, buf);
+ set_option_direct_for(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL, 0,
+ kOptScopeBuf, buf);
assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already
buf->b_p_swf = false;
buf->b_p_ml = false;
@@ -1317,15 +1319,15 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow,
return; // Nothing to do.
}
- reg->y_array = arena_alloc(arena, lines.size * sizeof(uint8_t *), true);
+ reg->y_array = arena_alloc(arena, lines.size * sizeof(String), true);
reg->y_size = lines.size;
for (size_t i = 0; i < lines.size; i++) {
VALIDATE_T("line", kObjectTypeString, lines.items[i].type, {
return;
});
String line = lines.items[i].data.string;
- reg->y_array[i] = arena_memdupz(arena, line.data, line.size);
- memchrsub(reg->y_array[i], NUL, NL, line.size);
+ reg->y_array[i] = copy_string(line, arena);
+ memchrsub(reg->y_array[i].data, NUL, NL, line.size);
}
finish_yankreg_from_object(reg, false);
@@ -2161,11 +2163,11 @@ Dict nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena *arena,
if (num_id) {
stc_hl_id = num_id;
} else if (statuscol.use_cul) {
- stc_hl_id = HLF_CLN + 1;
+ stc_hl_id = HLF_CLN;
} else if (wp->w_p_rnu) {
- stc_hl_id = (lnum < wp->w_cursor.lnum ? HLF_LNA : HLF_LNB) + 1;
+ stc_hl_id = (lnum < wp->w_cursor.lnum ? HLF_LNA : HLF_LNB);
} else {
- stc_hl_id = HLF_N + 1;
+ stc_hl_id = HLF_N;
}
set_vim_var_nr(VV_LNUM, lnum);
@@ -2396,14 +2398,22 @@ void nvim__redraw(Dict(redraw) *opts, Error *err)
redraw_buf_range_later(rbuf, first, last);
}
- bool flush = opts->flush;
+ // Redraw later types require update_screen() so call implicitly unless set to false.
+ if (HAS_KEY(opts, redraw, valid) || HAS_KEY(opts, redraw, range)) {
+ opts->flush = HAS_KEY(opts, redraw, flush) ? opts->flush : true;
+ }
+
+ // When explicitly set to false and only "redraw later" types are present,
+ // don't call ui_flush() either.
+ bool flush_ui = opts->flush;
if (opts->tabline) {
// Flush later in case tabline was just hidden or shown for the first time.
if (redraw_tabline && firstwin->w_lines_valid == 0) {
- flush = true;
+ opts->flush = true;
} else {
draw_tabline();
}
+ flush_ui = true;
}
bool save_lz = p_lz;
@@ -2414,31 +2424,35 @@ void nvim__redraw(Dict(redraw) *opts, Error *err)
if (win == NULL) {
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (buf == NULL || wp->w_buffer == buf) {
- redraw_status(wp, opts, &flush);
+ redraw_status(wp, opts, &opts->flush);
}
}
} else {
- redraw_status(win, opts, &flush);
+ redraw_status(win, opts, &opts->flush);
}
+ flush_ui = true;
}
win_T *cwin = win ? win : curwin;
// Allow moving cursor to recently opened window and make sure it is drawn #28868.
if (opts->cursor && (!cwin->w_grid.target || !cwin->w_grid.target->valid)) {
- flush = true;
+ opts->flush = true;
}
// Redraw pending screen updates when explicitly requested or when determined
// that it is necessary to properly draw other requested components.
- if (flush && !cmdpreview) {
+ if (opts->flush && !cmdpreview) {
update_screen();
}
if (opts->cursor) {
setcursor_mayforce(cwin, true);
+ flush_ui = true;
}
- ui_flush();
+ if (flush_ui) {
+ ui_flush();
+ }
RedrawingDisabled = save_rd;
p_lz = save_lz;
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index f63fdc5381..6f5a9a90c0 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -129,7 +129,12 @@
/// fractional.
/// - focusable: Enable focus by user actions (wincmds, mouse events).
/// Defaults to true. Non-focusable windows can be entered by
-/// |nvim_set_current_win()|.
+/// |nvim_set_current_win()|, or, when the `mouse` field is set to true,
+/// by mouse events. See |focusable|.
+/// - mouse: Specify how this window interacts with mouse events.
+/// Defaults to `focusable` value.
+/// - If false, mouse events pass through this window.
+/// - If true, mouse events interact with this window normally.
/// - external: GUI should display the window as an external
/// top-level window. Currently accepts no other positioning
/// configuration together with this.
@@ -714,6 +719,7 @@ Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err)
PUT_KEY_X(rv, focusable, config->focusable);
PUT_KEY_X(rv, external, config->external);
PUT_KEY_X(rv, hide, config->hide);
+ PUT_KEY_X(rv, mouse, config->mouse);
if (wp->w_floating) {
PUT_KEY_X(rv, width, config->width);
@@ -1202,6 +1208,11 @@ static bool parse_win_config(win_T *wp, Dict(win_config) *config, WinConfig *fco
if (HAS_KEY_X(config, focusable)) {
fconfig->focusable = config->focusable;
+ fconfig->mouse = config->focusable;
+ }
+
+ if (HAS_KEY_X(config, mouse)) {
+ fconfig->mouse = config->mouse;
}
if (HAS_KEY_X(config, zindex)) {