mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 11:28:22 +00:00
feat: get/set namespace properties #28728
ref https://github.com/neovim/neovim/pull/28432 ref https://github.com/neovim/neovim/issues/28469
This commit is contained in:
@@ -2758,8 +2758,6 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
|
|||||||
• url: A URL to associate with this extmark. In the TUI, the
|
• url: A URL to associate with this extmark. In the TUI, the
|
||||||
OSC 8 control sequence is used to generate a clickable
|
OSC 8 control sequence is used to generate a clickable
|
||||||
hyperlink to this URL.
|
hyperlink to this URL.
|
||||||
• scoped: boolean (EXPERIMENTAL) enables "scoping" for the
|
|
||||||
extmark. See |nvim__win_add_ns()|
|
|
||||||
|
|
||||||
Return: ~
|
Return: ~
|
||||||
Id of the created/updated extmark
|
Id of the created/updated extmark
|
||||||
@@ -2841,41 +2839,26 @@ nvim_set_decoration_provider({ns_id}, {opts})
|
|||||||
["end", tick]
|
["end", tick]
|
||||||
<
|
<
|
||||||
|
|
||||||
nvim__win_add_ns({window}, {ns_id}) *nvim__win_add_ns()*
|
nvim__ns_get({ns_id}) *nvim__ns_get()*
|
||||||
EXPERIMENTAL: this API will change in the future.
|
EXPERIMENTAL: this API will change in the future.
|
||||||
|
|
||||||
Scopes a namespace to the a window, so extmarks in the namespace will be
|
Get the properties for namespace
|
||||||
active only in the given window.
|
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {window} Window handle, or 0 for current window
|
• {ns_id} Namespace
|
||||||
• {ns_id} Namespace
|
|
||||||
|
|
||||||
Return: ~
|
Return: ~
|
||||||
true if the namespace was added, else false
|
Map defining the namespace properties, see |nvim__ns_set()|
|
||||||
|
|
||||||
nvim__win_del_ns({window}, {ns_id}) *nvim__win_del_ns()*
|
nvim__ns_set({ns_id}, {opts}) *nvim__ns_set()*
|
||||||
EXPERIMENTAL: this API will change in the future.
|
EXPERIMENTAL: this API will change in the future.
|
||||||
|
|
||||||
Unscopes a namespace (un-binds it from the given scope).
|
Set some properties for namespace
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {window} Window handle, or 0 for current window
|
• {ns_id} Namespace
|
||||||
• {ns_id} the namespace to remove
|
• {opts} Optional parameters to set:
|
||||||
|
• wins: a list of windows to be scoped in
|
||||||
Return: ~
|
|
||||||
true if the namespace was removed, else false
|
|
||||||
|
|
||||||
nvim__win_get_ns({window}) *nvim__win_get_ns()*
|
|
||||||
EXPERIMENTAL: this API will change in the future.
|
|
||||||
|
|
||||||
Gets the namespace scopes for a given window.
|
|
||||||
|
|
||||||
Parameters: ~
|
|
||||||
• {window} Window handle, or 0 for current window
|
|
||||||
|
|
||||||
Return: ~
|
|
||||||
a list of namespaces ids
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
@@ -155,8 +155,6 @@ The following new features were added.
|
|||||||
• |nvim_input_mouse()| supports mouse buttons "x1" and "x2".
|
• |nvim_input_mouse()| supports mouse buttons "x1" and "x2".
|
||||||
• Added "force_crlf" option field in |nvim_open_term()|.
|
• Added "force_crlf" option field in |nvim_open_term()|.
|
||||||
• Added |nvim_tabpage_set_win()| to set the current window of a tabpage.
|
• Added |nvim_tabpage_set_win()| to set the current window of a tabpage.
|
||||||
• |nvim__win_add_ns()| can bind a |namespace| to a window-local scope(s).
|
|
||||||
• Extmarks opt-in to this scoping via the `scoped` flag of |nvim_buf_set_extmark()|.
|
|
||||||
• Mapping APIs now support abbreviations when mode short-name has suffix "a".
|
• Mapping APIs now support abbreviations when mode short-name has suffix "a".
|
||||||
• Floating windows can now show footer with new `footer` and `footer_pos`
|
• Floating windows can now show footer with new `footer` and `footer_pos`
|
||||||
config fields. Uses |hl-FloatFooter| by default.
|
config fields. Uses |hl-FloatFooter| by default.
|
||||||
|
@@ -83,7 +83,7 @@ The following new features were added.
|
|||||||
|
|
||||||
API
|
API
|
||||||
|
|
||||||
• TODO
|
• |nvim__ns_set()| can set properties for a namespace
|
||||||
|
|
||||||
DEFAULTS
|
DEFAULTS
|
||||||
|
|
||||||
|
51
runtime/lua/vim/_meta/api.lua
generated
51
runtime/lua/vim/_meta/api.lua
generated
@@ -99,6 +99,25 @@ function vim.api.nvim__inspect_cell(grid, row, col) end
|
|||||||
---
|
---
|
||||||
function vim.api.nvim__invalidate_glyph_cache() end
|
function vim.api.nvim__invalidate_glyph_cache() end
|
||||||
|
|
||||||
|
--- @private
|
||||||
|
--- EXPERIMENTAL: this API will change in the future.
|
||||||
|
---
|
||||||
|
--- Get the properties for namespace
|
||||||
|
---
|
||||||
|
--- @param ns_id integer Namespace
|
||||||
|
--- @return vim.api.keyset.ns_opts
|
||||||
|
function vim.api.nvim__ns_get(ns_id) end
|
||||||
|
|
||||||
|
--- @private
|
||||||
|
--- EXPERIMENTAL: this API will change in the future.
|
||||||
|
---
|
||||||
|
--- Set some properties for namespace
|
||||||
|
---
|
||||||
|
--- @param ns_id integer Namespace
|
||||||
|
--- @param opts vim.api.keyset.ns_opts Optional parameters to set:
|
||||||
|
--- • wins: a list of windows to be scoped in
|
||||||
|
function vim.api.nvim__ns_set(ns_id, opts) end
|
||||||
|
|
||||||
--- @private
|
--- @private
|
||||||
--- EXPERIMENTAL: this API may change in the future.
|
--- EXPERIMENTAL: this API may change in the future.
|
||||||
---
|
---
|
||||||
@@ -144,36 +163,6 @@ function vim.api.nvim__stats() end
|
|||||||
--- @return any
|
--- @return any
|
||||||
function vim.api.nvim__unpack(str) end
|
function vim.api.nvim__unpack(str) end
|
||||||
|
|
||||||
--- @private
|
|
||||||
--- EXPERIMENTAL: this API will change in the future.
|
|
||||||
---
|
|
||||||
--- Scopes a namespace to the a window, so extmarks in the namespace will be
|
|
||||||
--- active only in the given window.
|
|
||||||
---
|
|
||||||
--- @param window integer Window handle, or 0 for current window
|
|
||||||
--- @param ns_id integer Namespace
|
|
||||||
--- @return boolean
|
|
||||||
function vim.api.nvim__win_add_ns(window, ns_id) end
|
|
||||||
|
|
||||||
--- @private
|
|
||||||
--- EXPERIMENTAL: this API will change in the future.
|
|
||||||
---
|
|
||||||
--- Unscopes a namespace (un-binds it from the given scope).
|
|
||||||
---
|
|
||||||
--- @param window integer Window handle, or 0 for current window
|
|
||||||
--- @param ns_id integer the namespace to remove
|
|
||||||
--- @return boolean
|
|
||||||
function vim.api.nvim__win_del_ns(window, ns_id) end
|
|
||||||
|
|
||||||
--- @private
|
|
||||||
--- EXPERIMENTAL: this API will change in the future.
|
|
||||||
---
|
|
||||||
--- Gets the namespace scopes for a given window.
|
|
||||||
---
|
|
||||||
--- @param window integer Window handle, or 0 for current window
|
|
||||||
--- @return integer[]
|
|
||||||
function vim.api.nvim__win_get_ns(window) end
|
|
||||||
|
|
||||||
--- Adds a highlight to buffer.
|
--- Adds a highlight to buffer.
|
||||||
---
|
---
|
||||||
--- Useful for plugins that dynamically generate highlights to a buffer (like
|
--- Useful for plugins that dynamically generate highlights to a buffer (like
|
||||||
@@ -686,8 +675,6 @@ function vim.api.nvim_buf_line_count(buffer) end
|
|||||||
--- • url: A URL to associate with this extmark. In the TUI, the
|
--- • url: A URL to associate with this extmark. In the TUI, the
|
||||||
--- OSC 8 control sequence is used to generate a clickable
|
--- OSC 8 control sequence is used to generate a clickable
|
||||||
--- hyperlink to this URL.
|
--- hyperlink to this URL.
|
||||||
--- • scoped: boolean (EXPERIMENTAL) enables "scoping" for the
|
|
||||||
--- extmark. See `nvim__win_add_ns()`
|
|
||||||
--- @return integer
|
--- @return integer
|
||||||
function vim.api.nvim_buf_set_extmark(buffer, ns_id, line, col, opts) end
|
function vim.api.nvim_buf_set_extmark(buffer, ns_id, line, col, opts) end
|
||||||
|
|
||||||
|
3
runtime/lua/vim/_meta/api_keysets.lua
generated
3
runtime/lua/vim/_meta/api_keysets.lua
generated
@@ -197,6 +197,9 @@ error('Cannot require a meta file')
|
|||||||
--- @field desc? string
|
--- @field desc? string
|
||||||
--- @field replace_keycodes? boolean
|
--- @field replace_keycodes? boolean
|
||||||
|
|
||||||
|
--- @class vim.api.keyset.ns_opts
|
||||||
|
--- @field wins? any[]
|
||||||
|
|
||||||
--- @class vim.api.keyset.open_term
|
--- @class vim.api.keyset.open_term
|
||||||
--- @field on_input? function
|
--- @field on_input? function
|
||||||
--- @field force_crlf? boolean
|
--- @field force_crlf? boolean
|
||||||
|
@@ -31,8 +31,6 @@ M.priorities = {
|
|||||||
--- Indicates priority of highlight
|
--- Indicates priority of highlight
|
||||||
--- (default: `vim.highlight.priorities.user`)
|
--- (default: `vim.highlight.priorities.user`)
|
||||||
--- @field priority? integer
|
--- @field priority? integer
|
||||||
---
|
|
||||||
--- @field package _scoped? boolean
|
|
||||||
|
|
||||||
--- Apply highlight group to range of text.
|
--- Apply highlight group to range of text.
|
||||||
---
|
---
|
||||||
@@ -47,7 +45,6 @@ function M.range(bufnr, ns, higroup, start, finish, opts)
|
|||||||
local regtype = opts.regtype or 'v'
|
local regtype = opts.regtype or 'v'
|
||||||
local inclusive = opts.inclusive or false
|
local inclusive = opts.inclusive or false
|
||||||
local priority = opts.priority or M.priorities.user
|
local priority = opts.priority or M.priorities.user
|
||||||
local scoped = opts._scoped or false
|
|
||||||
|
|
||||||
local v_maxcol = vim.v.maxcol
|
local v_maxcol = vim.v.maxcol
|
||||||
|
|
||||||
@@ -114,7 +111,6 @@ function M.range(bufnr, ns, higroup, start, finish, opts)
|
|||||||
end_col = end_col,
|
end_col = end_col,
|
||||||
priority = priority,
|
priority = priority,
|
||||||
strict = false,
|
strict = false,
|
||||||
scoped = scoped,
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -178,19 +174,18 @@ function M.on_yank(opts)
|
|||||||
yank_cancel()
|
yank_cancel()
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim__win_add_ns(winid, yank_ns)
|
vim.api.nvim__ns_set(yank_ns, { wins = { winid } })
|
||||||
M.range(bufnr, yank_ns, higroup, "'[", "']", {
|
M.range(bufnr, yank_ns, higroup, "'[", "']", {
|
||||||
regtype = event.regtype,
|
regtype = event.regtype,
|
||||||
inclusive = event.inclusive,
|
inclusive = event.inclusive,
|
||||||
priority = opts.priority or M.priorities.user,
|
priority = opts.priority or M.priorities.user,
|
||||||
_scoped = true,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
yank_cancel = function()
|
yank_cancel = function()
|
||||||
yank_timer = nil
|
yank_timer = nil
|
||||||
yank_cancel = nil
|
yank_cancel = nil
|
||||||
pcall(vim.api.nvim_buf_clear_namespace, bufnr, yank_ns, 0, -1)
|
pcall(vim.api.nvim_buf_clear_namespace, bufnr, yank_ns, 0, -1)
|
||||||
pcall(vim.api.nvim__win_del_ns, winid, yank_ns)
|
pcall(vim.api.nvim__ns_set, { wins = {} })
|
||||||
end
|
end
|
||||||
|
|
||||||
yank_timer = vim.defer_fn(yank_cancel, timeout)
|
yank_timer = vim.defer_fn(yank_cancel, timeout)
|
||||||
|
@@ -170,7 +170,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A
|
|||||||
DecorInline decor = { .ext = true, .data.ext.vt = vt, .data.ext.sh_idx = DECOR_ID_INVALID };
|
DecorInline decor = { .ext = true, .data.ext.vt = vt, .data.ext.sh_idx = DECOR_ID_INVALID };
|
||||||
|
|
||||||
extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, 0, true,
|
extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, 0, true,
|
||||||
false, false, false, false, NULL);
|
false, false, false, NULL);
|
||||||
return src_id;
|
return src_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "nvim/decoration_provider.h"
|
#include "nvim/decoration_provider.h"
|
||||||
#include "nvim/drawscreen.h"
|
#include "nvim/drawscreen.h"
|
||||||
#include "nvim/extmark.h"
|
#include "nvim/extmark.h"
|
||||||
|
#include "nvim/globals.h"
|
||||||
#include "nvim/grid.h"
|
#include "nvim/grid.h"
|
||||||
#include "nvim/highlight_group.h"
|
#include "nvim/highlight_group.h"
|
||||||
#include "nvim/map_defs.h"
|
#include "nvim/map_defs.h"
|
||||||
@@ -41,6 +42,7 @@ void api_extmark_free_all_mem(void)
|
|||||||
xfree(name.data);
|
xfree(name.data);
|
||||||
})
|
})
|
||||||
map_destroy(String, &namespace_ids);
|
map_destroy(String, &namespace_ids);
|
||||||
|
set_destroy(uint32_t, &namespace_localscope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new namespace or gets an existing one. [namespace]()
|
/// Creates a new namespace or gets an existing one. [namespace]()
|
||||||
@@ -179,10 +181,6 @@ static Array extmark_to_array(MTPair extmark, bool id, bool add_dict, bool hl_na
|
|||||||
PUT_C(dict, "invalid", BOOLEAN_OBJ(true));
|
PUT_C(dict, "invalid", BOOLEAN_OBJ(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mt_scoped(start)) {
|
|
||||||
PUT_C(dict, "scoped", BOOLEAN_OBJ(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
decor_to_dict_legacy(&dict, mt_decor(start), hl_name, arena);
|
decor_to_dict_legacy(&dict, mt_decor(start), hl_name, arena);
|
||||||
|
|
||||||
ADD_C(rv, DICTIONARY_OBJ(dict));
|
ADD_C(rv, DICTIONARY_OBJ(dict));
|
||||||
@@ -489,8 +487,6 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
|
|||||||
/// used together with virt_text.
|
/// used together with virt_text.
|
||||||
/// - url: A URL to associate with this extmark. In the TUI, the OSC 8 control
|
/// - url: A URL to associate with this extmark. In the TUI, the OSC 8 control
|
||||||
/// sequence is used to generate a clickable hyperlink to this URL.
|
/// sequence is used to generate a clickable hyperlink to this URL.
|
||||||
/// - scoped: boolean (EXPERIMENTAL) enables "scoping" for the extmark. See
|
|
||||||
/// |nvim__win_add_ns()|
|
|
||||||
///
|
///
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return Id of the created/updated extmark
|
/// @return Id of the created/updated extmark
|
||||||
@@ -749,11 +745,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opts->ephemeral && decor_state.win && decor_state.win->w_buffer == buf) {
|
if (opts->ephemeral && decor_state.win && decor_state.win->w_buffer == buf) {
|
||||||
if (opts->scoped) {
|
|
||||||
api_set_error(err, kErrorTypeException, "not yet implemented");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int r = (int)line;
|
int r = (int)line;
|
||||||
int c = (int)col;
|
int c = (int)col;
|
||||||
if (line2 == -1) {
|
if (line2 == -1) {
|
||||||
@@ -834,7 +825,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
|||||||
extmark_set(buf, (uint32_t)ns_id, &id, (int)line, (colnr_T)col, line2, col2,
|
extmark_set(buf, (uint32_t)ns_id, &id, (int)line, (colnr_T)col, line2, col2,
|
||||||
decor, decor_flags, right_gravity, opts->end_right_gravity,
|
decor, decor_flags, right_gravity, opts->end_right_gravity,
|
||||||
!GET_BOOL_OR_TRUE(opts, set_extmark, undo_restore),
|
!GET_BOOL_OR_TRUE(opts, set_extmark, undo_restore),
|
||||||
opts->invalidate, opts->scoped, err);
|
opts->invalidate, err);
|
||||||
if (ERROR_SET(err)) {
|
if (ERROR_SET(err)) {
|
||||||
decor_free(decor);
|
decor_free(decor);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -960,7 +951,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In
|
|||||||
decor.data.hl.hl_id = hl_id;
|
decor.data.hl.hl_id = hl_id;
|
||||||
|
|
||||||
extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end,
|
extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end,
|
||||||
decor, MT_FLAG_DECOR_HL, true, false, false, false, false, NULL);
|
decor, MT_FLAG_DECOR_HL, true, false, false, false, NULL);
|
||||||
return ns_id;
|
return ns_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1217,77 +1208,119 @@ String nvim__buf_debug_extmarks(Buffer buffer, Boolean keys, Boolean dot, Error
|
|||||||
|
|
||||||
/// EXPERIMENTAL: this API will change in the future.
|
/// EXPERIMENTAL: this API will change in the future.
|
||||||
///
|
///
|
||||||
/// Scopes a namespace to the a window, so extmarks in the namespace will be active only in the
|
/// Set some properties for namespace
|
||||||
/// given window.
|
|
||||||
///
|
///
|
||||||
/// @param window Window handle, or 0 for current window
|
|
||||||
/// @param ns_id Namespace
|
/// @param ns_id Namespace
|
||||||
/// @return true if the namespace was added, else false
|
/// @param opts Optional parameters to set:
|
||||||
Boolean nvim__win_add_ns(Window window, Integer ns_id, Error *err)
|
/// - wins: a list of windows to be scoped in
|
||||||
|
///
|
||||||
|
void nvim__ns_set(Integer ns_id, Dict(ns_opts) *opts, Error *err)
|
||||||
{
|
{
|
||||||
win_T *win = find_window_by_handle(window, err);
|
VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, {
|
||||||
if (!win) {
|
return;
|
||||||
return false;
|
});
|
||||||
|
|
||||||
|
bool set_scoped = true;
|
||||||
|
|
||||||
|
if (HAS_KEY(opts, ns_opts, wins)) {
|
||||||
|
if (opts->wins.size == 0) {
|
||||||
|
set_scoped = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set(ptr_t) windows = SET_INIT;
|
||||||
|
for (size_t i = 0; i < opts->wins.size; i++) {
|
||||||
|
Integer win = opts->wins.items[i].data.integer;
|
||||||
|
|
||||||
|
win_T *wp = find_window_by_handle((Window)win, err);
|
||||||
|
if (!wp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_put(ptr_t, &windows, wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
|
if (set_has(ptr_t, &windows, wp) && !set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id)) {
|
||||||
|
set_put(uint32_t, &wp->w_ns_set, (uint32_t)ns_id);
|
||||||
|
|
||||||
|
if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) {
|
||||||
|
changed_window_setting(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id) && !set_has(ptr_t, &windows, wp)) {
|
||||||
|
set_del(uint32_t, &wp->w_ns_set, (uint32_t)ns_id);
|
||||||
|
|
||||||
|
if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) {
|
||||||
|
changed_window_setting(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_destroy(ptr_t, &windows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (set_scoped && !set_has(uint32_t, &namespace_localscope, (uint32_t)ns_id)) {
|
||||||
|
set_put(uint32_t, &namespace_localscope, (uint32_t)ns_id);
|
||||||
|
|
||||||
|
// When a namespace becomes scoped, any window which contains
|
||||||
|
// elements associated with namespace needs to be redrawn
|
||||||
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
|
if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) {
|
||||||
|
changed_window_setting(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!set_scoped && set_has(uint32_t, &namespace_localscope, (uint32_t)ns_id)) {
|
||||||
|
set_del(uint32_t, &namespace_localscope, (uint32_t)ns_id);
|
||||||
|
|
||||||
|
// When a namespace becomes unscoped, any window which does not
|
||||||
|
// contain elements associated with namespace needs to be redrawn
|
||||||
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
|
if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) {
|
||||||
|
changed_window_setting(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// EXPERIMENTAL: this API will change in the future.
|
||||||
|
///
|
||||||
|
/// Get the properties for namespace
|
||||||
|
///
|
||||||
|
/// @param ns_id Namespace
|
||||||
|
/// @return Map defining the namespace properties, see |nvim__ns_set()|
|
||||||
|
Dict(ns_opts) nvim__ns_get(Integer ns_id, Arena *arena, Error *err)
|
||||||
|
{
|
||||||
|
Dict(ns_opts) opts = KEYDICT_INIT;
|
||||||
|
|
||||||
|
Array windows = ARRAY_DICT_INIT;
|
||||||
|
|
||||||
|
PUT_KEY(opts, ns_opts, wins, windows);
|
||||||
|
|
||||||
VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, {
|
VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, {
|
||||||
return false;
|
return opts;
|
||||||
});
|
});
|
||||||
|
|
||||||
set_put(uint32_t, &win->w_ns_set, (uint32_t)ns_id);
|
if (!set_has(uint32_t, &namespace_localscope, (uint32_t)ns_id)) {
|
||||||
|
return opts;
|
||||||
if (map_has(uint32_t, win->w_buffer->b_extmark_ns, (uint32_t)ns_id)) {
|
|
||||||
changed_window_setting(win);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
size_t count = 0;
|
||||||
}
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
|
if (set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id)) {
|
||||||
/// EXPERIMENTAL: this API will change in the future.
|
count++;
|
||||||
///
|
}
|
||||||
/// Gets the namespace scopes for a given window.
|
}
|
||||||
///
|
|
||||||
/// @param window Window handle, or 0 for current window
|
windows = arena_array(arena, count);
|
||||||
/// @return a list of namespaces ids
|
|
||||||
ArrayOf(Integer) nvim__win_get_ns(Window window, Arena *arena, Error *err)
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
{
|
if (set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id)) {
|
||||||
win_T *win = find_window_by_handle(window, err);
|
ADD(windows, INTEGER_OBJ(wp->handle));
|
||||||
if (!win) {
|
}
|
||||||
return (Array)ARRAY_DICT_INIT;
|
}
|
||||||
}
|
|
||||||
|
PUT_KEY(opts, ns_opts, wins, windows);
|
||||||
Array rv = arena_array(arena, set_size(&win->w_ns_set));
|
|
||||||
uint32_t i;
|
return opts;
|
||||||
set_foreach(&win->w_ns_set, i, {
|
|
||||||
ADD_C(rv, INTEGER_OBJ((Integer)(i)));
|
|
||||||
});
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// EXPERIMENTAL: this API will change in the future.
|
|
||||||
///
|
|
||||||
/// Unscopes a namespace (un-binds it from the given scope).
|
|
||||||
///
|
|
||||||
/// @param window Window handle, or 0 for current window
|
|
||||||
/// @param ns_id the namespace to remove
|
|
||||||
/// @return true if the namespace was removed, else false
|
|
||||||
Boolean nvim__win_del_ns(Window window, Integer ns_id, Error *err)
|
|
||||||
{
|
|
||||||
win_T *win = find_window_by_handle(window, err);
|
|
||||||
if (!win) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!set_has(uint32_t, &win->w_ns_set, (uint32_t)ns_id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_del(uint32_t, &win->w_ns_set, (uint32_t)ns_id);
|
|
||||||
|
|
||||||
if (map_has(uint32_t, win->w_buffer->b_extmark_ns, (uint32_t)ns_id)) {
|
|
||||||
changed_window_setting(win);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@@ -4,14 +4,29 @@
|
|||||||
|
|
||||||
#include "nvim/api/keysets_defs.h" // IWYU pragma: keep
|
#include "nvim/api/keysets_defs.h" // IWYU pragma: keep
|
||||||
#include "nvim/api/private/defs.h" // IWYU pragma: keep
|
#include "nvim/api/private/defs.h" // IWYU pragma: keep
|
||||||
|
#include "nvim/buffer_defs.h"
|
||||||
#include "nvim/decoration_defs.h" // IWYU pragma: keep
|
#include "nvim/decoration_defs.h" // IWYU pragma: keep
|
||||||
#include "nvim/macros_defs.h"
|
#include "nvim/macros_defs.h"
|
||||||
#include "nvim/map_defs.h"
|
#include "nvim/map_defs.h"
|
||||||
#include "nvim/types_defs.h"
|
#include "nvim/types_defs.h"
|
||||||
|
|
||||||
EXTERN Map(String, int) namespace_ids INIT( = MAP_INIT);
|
EXTERN Map(String, int) namespace_ids INIT( = MAP_INIT);
|
||||||
|
/// Non-global namespaces. A locally-scoped namespace may be "orphaned" if all
|
||||||
|
/// window(s) it was scoped to, are destroyed. Such orphans are tracked here to
|
||||||
|
/// avoid being mistaken as "global scope".
|
||||||
|
EXTERN Set(uint32_t) namespace_localscope INIT( = SET_INIT);
|
||||||
EXTERN handle_T next_namespace_id INIT( = 1);
|
EXTERN handle_T next_namespace_id INIT( = 1);
|
||||||
|
|
||||||
|
/// Returns true if the namespace is global or scoped in the given window.
|
||||||
|
static inline bool ns_in_win(uint32_t ns_id, win_T *wp)
|
||||||
|
{
|
||||||
|
if (!set_has(uint32_t, &namespace_localscope, ns_id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return set_has(uint32_t, &wp->w_ns_set, ns_id);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/extmark.h.generated.h"
|
# include "api/extmark.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -387,3 +387,8 @@ typedef struct {
|
|||||||
Window win;
|
Window win;
|
||||||
Buffer buf;
|
Buffer buf;
|
||||||
} Dict(redraw);
|
} Dict(redraw);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
OptionalKeys is_set__ns_opts_;
|
||||||
|
Array wins;
|
||||||
|
} Dict(ns_opts);
|
||||||
|
@@ -89,7 +89,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf, int src_id, int hl_id, lpos_T pos_start
|
|||||||
|
|
||||||
extmark_set(buf, (uint32_t)src_id, NULL,
|
extmark_set(buf, (uint32_t)src_id, NULL,
|
||||||
(int)lnum - 1, hl_start, (int)lnum - 1 + end_off, hl_end,
|
(int)lnum - 1, hl_start, (int)lnum - 1 + end_off, hl_end,
|
||||||
decor, MT_FLAG_DECOR_HL, true, false, true, false, false, NULL);
|
decor, MT_FLAG_DECOR_HL, true, false, true, false, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,7 +598,7 @@ int decor_redraw_col(win_T *wp, int col, int win_col, bool hidden, DecorState *s
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mt_scoped_in_win(mark, wp)) {
|
if (!ns_in_win(mark.ns, wp)) {
|
||||||
goto next_mark;
|
goto next_mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,7 +747,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!mt_end(mark) && !mt_invalid(mark) && mt_decor_sign(mark)
|
if (!mt_end(mark) && !mt_invalid(mark) && mt_decor_sign(mark)
|
||||||
&& mt_scoped_in_win(mark, wp)) {
|
&& ns_in_win(mark.ns, wp)) {
|
||||||
DecorSignHighlight *sh = decor_find_sign(mt_decor(mark));
|
DecorSignHighlight *sh = decor_find_sign(mt_decor(mark));
|
||||||
num_text += (sh->text[0] != NUL);
|
num_text += (sh->text[0] != NUL);
|
||||||
kv_push(signs, ((SignItem){ sh, mark.id }));
|
kv_push(signs, ((SignItem){ sh, mark.id }));
|
||||||
@@ -927,7 +927,7 @@ int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines, TriState has_fo
|
|||||||
while (true) {
|
while (true) {
|
||||||
MTKey mark = marktree_itr_current(itr);
|
MTKey mark = marktree_itr_current(itr);
|
||||||
DecorVirtText *vt = mt_decor_virt(mark);
|
DecorVirtText *vt = mt_decor_virt(mark);
|
||||||
if (mt_scoped_in_win(mark, wp)) {
|
if (ns_in_win(mark.ns, wp)) {
|
||||||
while (vt) {
|
while (vt) {
|
||||||
if (vt->flags & kVTIsLines) {
|
if (vt->flags & kVTIsLines) {
|
||||||
bool above = vt->flags & kVTLinesAbove;
|
bool above = vt->flags & kVTLinesAbove;
|
||||||
|
@@ -54,12 +54,12 @@
|
|||||||
/// must not be used during iteration!
|
/// must not be used during iteration!
|
||||||
void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col, int end_row,
|
void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col, int end_row,
|
||||||
colnr_T end_col, DecorInline decor, uint16_t decor_flags, bool right_gravity,
|
colnr_T end_col, DecorInline decor, uint16_t decor_flags, bool right_gravity,
|
||||||
bool end_right_gravity, bool no_undo, bool invalidate, bool scoped, Error *err)
|
bool end_right_gravity, bool no_undo, bool invalidate, Error *err)
|
||||||
{
|
{
|
||||||
uint32_t *ns = map_put_ref(uint32_t, uint32_t)(buf->b_extmark_ns, ns_id, NULL, NULL);
|
uint32_t *ns = map_put_ref(uint32_t, uint32_t)(buf->b_extmark_ns, ns_id, NULL, NULL);
|
||||||
uint32_t id = idp ? *idp : 0;
|
uint32_t id = idp ? *idp : 0;
|
||||||
|
|
||||||
uint16_t flags = mt_flags(right_gravity, no_undo, invalidate, decor.ext, scoped) | decor_flags;
|
uint16_t flags = mt_flags(right_gravity, no_undo, invalidate, decor.ext) | decor_flags;
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
id = ++*ns;
|
id = ++*ns;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -2286,7 +2286,7 @@ static void marktree_itr_fix_pos(MarkTree *b, MarkTreeIter *itr)
|
|||||||
void marktree_put_test(MarkTree *b, uint32_t ns, uint32_t id, int row, int col, bool right_gravity,
|
void marktree_put_test(MarkTree *b, uint32_t ns, uint32_t id, int row, int col, bool right_gravity,
|
||||||
int end_row, int end_col, bool end_right, bool meta_inline)
|
int end_row, int end_col, bool end_right, bool meta_inline)
|
||||||
{
|
{
|
||||||
uint16_t flags = mt_flags(right_gravity, false, false, false, false);
|
uint16_t flags = mt_flags(right_gravity, false, false, false);
|
||||||
// The specific choice is irrelevant here, we pick one counted decor
|
// The specific choice is irrelevant here, we pick one counted decor
|
||||||
// type to test the counting and filtering logic.
|
// type to test the counting and filtering logic.
|
||||||
flags |= meta_inline ? MT_FLAG_DECOR_VIRT_TEXT_INLINE : 0;
|
flags |= meta_inline ? MT_FLAG_DECOR_VIRT_TEXT_INLINE : 0;
|
||||||
|
@@ -35,8 +35,6 @@
|
|||||||
#define MT_FLAG_DECOR_VIRT_LINES (((uint16_t)1) << 11)
|
#define MT_FLAG_DECOR_VIRT_LINES (((uint16_t)1) << 11)
|
||||||
#define MT_FLAG_DECOR_VIRT_TEXT_INLINE (((uint16_t)1) << 12)
|
#define MT_FLAG_DECOR_VIRT_TEXT_INLINE (((uint16_t)1) << 12)
|
||||||
|
|
||||||
#define MT_FLAG_SCOPED (((uint16_t)1) << 13)
|
|
||||||
|
|
||||||
// These _must_ be last to preserve ordering of marks
|
// These _must_ be last to preserve ordering of marks
|
||||||
#define MT_FLAG_RIGHT_GRAVITY (((uint16_t)1) << 14)
|
#define MT_FLAG_RIGHT_GRAVITY (((uint16_t)1) << 14)
|
||||||
#define MT_FLAG_LAST (((uint16_t)1) << 15)
|
#define MT_FLAG_LAST (((uint16_t)1) << 15)
|
||||||
@@ -46,7 +44,7 @@
|
|||||||
| MT_FLAG_DECOR_VIRT_TEXT_INLINE)
|
| MT_FLAG_DECOR_VIRT_TEXT_INLINE)
|
||||||
|
|
||||||
#define MT_FLAG_EXTERNAL_MASK (MT_FLAG_DECOR_MASK | MT_FLAG_NO_UNDO \
|
#define MT_FLAG_EXTERNAL_MASK (MT_FLAG_DECOR_MASK | MT_FLAG_NO_UNDO \
|
||||||
| MT_FLAG_INVALIDATE | MT_FLAG_INVALID | MT_FLAG_SCOPED)
|
| MT_FLAG_INVALIDATE | MT_FLAG_INVALID)
|
||||||
|
|
||||||
// this is defined so that start and end of the same range have adjacent ids
|
// this is defined so that start and end of the same range have adjacent ids
|
||||||
#define MARKTREE_END_FLAG ((uint64_t)1)
|
#define MARKTREE_END_FLAG ((uint64_t)1)
|
||||||
@@ -110,24 +108,12 @@ static inline bool mt_decor_sign(MTKey key)
|
|||||||
return key.flags & (MT_FLAG_DECOR_SIGNTEXT | MT_FLAG_DECOR_SIGNHL);
|
return key.flags & (MT_FLAG_DECOR_SIGNTEXT | MT_FLAG_DECOR_SIGNHL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool mt_scoped(MTKey key)
|
static inline uint16_t mt_flags(bool right_gravity, bool no_undo, bool invalidate, bool decor_ext)
|
||||||
{
|
|
||||||
return key.flags & MT_FLAG_SCOPED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool mt_scoped_in_win(MTKey key, win_T *wp)
|
|
||||||
{
|
|
||||||
return !mt_scoped(key) || set_has(uint32_t, &wp->w_ns_set, key.ns);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t mt_flags(bool right_gravity, bool no_undo, bool invalidate, bool decor_ext,
|
|
||||||
bool scoped)
|
|
||||||
{
|
{
|
||||||
return (uint16_t)((right_gravity ? MT_FLAG_RIGHT_GRAVITY : 0)
|
return (uint16_t)((right_gravity ? MT_FLAG_RIGHT_GRAVITY : 0)
|
||||||
| (no_undo ? MT_FLAG_NO_UNDO : 0)
|
| (no_undo ? MT_FLAG_NO_UNDO : 0)
|
||||||
| (invalidate ? MT_FLAG_INVALIDATE : 0)
|
| (invalidate ? MT_FLAG_INVALIDATE : 0)
|
||||||
| (decor_ext ? MT_FLAG_DECOR_EXT : 0)
|
| (decor_ext ? MT_FLAG_DECOR_EXT : 0));
|
||||||
| (scoped ? MT_FLAG_SCOPED : 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline MTPair mtpair_from(MTKey start, MTKey end)
|
static inline MTPair mtpair_from(MTKey start, MTKey end)
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "nvim/api/extmark.h"
|
||||||
#include "nvim/ascii_defs.h"
|
#include "nvim/ascii_defs.h"
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
#include "nvim/buffer_defs.h"
|
#include "nvim/buffer_defs.h"
|
||||||
@@ -158,7 +159,7 @@ CharSize charsize_regular(CharsizeArg *csarg, char *const cur, colnr_T const vco
|
|||||||
break;
|
break;
|
||||||
} else if (mark.pos.col == col) {
|
} else if (mark.pos.col == col) {
|
||||||
if (!mt_end(mark) && (mark.flags & MT_FLAG_DECOR_VIRT_TEXT_INLINE)
|
if (!mt_end(mark) && (mark.flags & MT_FLAG_DECOR_VIRT_TEXT_INLINE)
|
||||||
&& mt_scoped_in_win(mark, wp)) {
|
&& ns_in_win(mark.ns, wp)) {
|
||||||
DecorInline decor = mt_decor(mark);
|
DecorInline decor = mt_decor(mark);
|
||||||
DecorVirtText *vt = decor.ext ? decor.data.ext.vt : NULL;
|
DecorVirtText *vt = decor.ext ? decor.data.ext.vt : NULL;
|
||||||
while (vt) {
|
while (vt) {
|
||||||
|
@@ -127,7 +127,7 @@ static void buf_set_sign(buf_T *buf, uint32_t *id, char *group, int prio, linenr
|
|||||||
|
|
||||||
DecorInline decor = { .ext = true, .data.ext = { .vt = NULL, .sh_idx = decor_put_sh(sign) } };
|
DecorInline decor = { .ext = true, .data.ext = { .vt = NULL, .sh_idx = decor_put_sh(sign) } };
|
||||||
extmark_set(buf, ns, id, lnum - 1, 0, -1, -1, decor, decor_flags, true,
|
extmark_set(buf, ns, id, lnum - 1, 0, -1, -1, decor, decor_flags, true,
|
||||||
false, true, true, false, NULL);
|
false, true, true, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For an existing, placed sign with "id", modify the sign, group or priority.
|
/// For an existing, placed sign with "id", modify the sign, group or priority.
|
||||||
|
@@ -4,7 +4,6 @@ local Screen = require('test.functional.ui.screen')
|
|||||||
|
|
||||||
local exec_lua = n.exec_lua
|
local exec_lua = n.exec_lua
|
||||||
local eq = t.eq
|
local eq = t.eq
|
||||||
local neq = t.neq
|
|
||||||
local eval = n.eval
|
local eval = n.eval
|
||||||
local command = n.command
|
local command = n.command
|
||||||
local clear = n.clear
|
local clear = n.clear
|
||||||
@@ -142,9 +141,11 @@ describe('vim.highlight.on_yank', function()
|
|||||||
vim.api.nvim_buf_set_mark(0,"]",1,1,{})
|
vim.api.nvim_buf_set_mark(0,"]",1,1,{})
|
||||||
vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}})
|
vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}})
|
||||||
]])
|
]])
|
||||||
neq({}, api.nvim__win_get_ns(0))
|
local ns = api.nvim_create_namespace('hlyank')
|
||||||
|
local win = api.nvim_get_current_win()
|
||||||
|
eq({ win }, api.nvim__ns_get(ns).wins)
|
||||||
command('wincmd w')
|
command('wincmd w')
|
||||||
eq({}, api.nvim__win_get_ns(0))
|
eq({ win }, api.nvim__ns_get(ns).wins)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('removes old highlight if new one is created before old one times out', function()
|
it('removes old highlight if new one is created before old one times out', function()
|
||||||
@@ -154,14 +155,17 @@ describe('vim.highlight.on_yank', function()
|
|||||||
vim.api.nvim_buf_set_mark(0,"]",1,1,{})
|
vim.api.nvim_buf_set_mark(0,"]",1,1,{})
|
||||||
vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}})
|
vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}})
|
||||||
]])
|
]])
|
||||||
neq({}, api.nvim__win_get_ns(0))
|
local ns = api.nvim_create_namespace('hlyank')
|
||||||
|
eq(api.nvim_get_current_win(), api.nvim__ns_get(ns).wins[1])
|
||||||
command('wincmd w')
|
command('wincmd w')
|
||||||
exec_lua([[
|
exec_lua([[
|
||||||
vim.api.nvim_buf_set_mark(0,"[",1,1,{})
|
vim.api.nvim_buf_set_mark(0,"[",1,1,{})
|
||||||
vim.api.nvim_buf_set_mark(0,"]",1,1,{})
|
vim.api.nvim_buf_set_mark(0,"]",1,1,{})
|
||||||
vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}})
|
vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}})
|
||||||
]])
|
]])
|
||||||
|
local win = api.nvim_get_current_win()
|
||||||
|
eq({ win }, api.nvim__ns_get(ns).wins)
|
||||||
command('wincmd w')
|
command('wincmd w')
|
||||||
eq({}, api.nvim__win_get_ns(0))
|
eq({ win }, api.nvim__ns_get(ns).wins)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@@ -5595,20 +5595,26 @@ describe('decorations: virt_text', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
describe('decorations: window scoped', function()
|
describe('decorations: window scoped', function()
|
||||||
local screen, ns
|
local screen, ns, win_other
|
||||||
local url = 'https://example.com'
|
local url = 'https://example.com'
|
||||||
before_each(function()
|
before_each(function()
|
||||||
clear()
|
clear()
|
||||||
screen = Screen.new(20, 10)
|
screen = Screen.new(20, 10)
|
||||||
screen:attach()
|
screen:attach()
|
||||||
screen:add_extra_attr_ids {
|
screen:add_extra_attr_ids {
|
||||||
[100] = { special = Screen.colors.Red, undercurl = true },
|
[100] = { special = Screen.colors.Red, undercurl = true },
|
||||||
[101] = { url = "https://example.com" },
|
[101] = { url = 'https://example.com' },
|
||||||
}
|
}
|
||||||
|
|
||||||
ns = api.nvim_create_namespace 'test'
|
ns = api.nvim_create_namespace 'test'
|
||||||
|
|
||||||
insert('12345')
|
insert('12345')
|
||||||
|
|
||||||
|
win_other = api.nvim_open_win(0, false, {
|
||||||
|
col=0,row=0,width=20,height=10,
|
||||||
|
relative = 'win',style = 'minimal',
|
||||||
|
hide = true
|
||||||
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local noextmarks = {
|
local noextmarks = {
|
||||||
@@ -5616,28 +5622,28 @@ describe('decorations: window scoped', function()
|
|||||||
1234^5 |
|
1234^5 |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
local function set_scoped_extmark(line, col, opts)
|
local function set_extmark(line, col, opts)
|
||||||
return api.nvim_buf_set_extmark(0, ns, line, col, vim.tbl_extend('error', { scoped = true }, opts))
|
return api.nvim_buf_set_extmark(0, ns, line, col, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
it('hl_group', function()
|
it('hl_group', function()
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
hl_group = 'Comment',
|
hl_group = 'Comment',
|
||||||
end_col = 3,
|
end_col = 3,
|
||||||
})
|
})
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
{18:123}4^5 |
|
{18:123}4^5 |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
@@ -5646,48 +5652,55 @@ describe('decorations: window scoped', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('virt_text', function()
|
it('virt_text', function()
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
virt_text = { { 'a', 'Comment' } },
|
virt_text = { { 'a', 'Comment' } },
|
||||||
virt_text_pos = 'eol',
|
virt_text_pos = 'eol',
|
||||||
})
|
})
|
||||||
set_scoped_extmark(0, 5, {
|
set_extmark(0, 5, {
|
||||||
virt_text = { { 'b', 'Comment' } },
|
virt_text = { { 'b', 'Comment' } },
|
||||||
virt_text_pos = 'inline',
|
virt_text_pos = 'inline',
|
||||||
})
|
})
|
||||||
set_scoped_extmark(0, 1, {
|
set_extmark(0, 1, {
|
||||||
virt_text = { { 'c', 'Comment' } },
|
virt_text = { { 'c', 'Comment' } },
|
||||||
virt_text_pos = 'overlay',
|
virt_text_pos = 'overlay',
|
||||||
})
|
})
|
||||||
set_scoped_extmark(0, 1, {
|
set_extmark(0, 1, {
|
||||||
virt_text = { { 'd', 'Comment' } },
|
virt_text = { { 'd', 'Comment' } },
|
||||||
virt_text_pos = 'right_align',
|
virt_text_pos = 'right_align',
|
||||||
})
|
})
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
1{18:c}34^5{18:b} {18:a} {18:d}|
|
1{18:c}34^5{18:b} {18:a} {18:d}|
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
screen:expect(noextmarks)
|
||||||
|
|
||||||
|
api.nvim__ns_set(ns, { wins = {} })
|
||||||
|
|
||||||
|
screen:expect {
|
||||||
|
grid = [[
|
||||||
|
1{18:c}34^5{18:b} {18:a} {18:d}|
|
||||||
|
{1:~ }|*8
|
||||||
|
|
|
||||||
|
]],
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('virt_lines', function()
|
it('virt_lines', function()
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
virt_lines = { { { 'a', 'Comment' } } },
|
virt_lines = { { { 'a', 'Comment' } } },
|
||||||
})
|
})
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
@@ -5695,7 +5708,8 @@ describe('decorations: window scoped', function()
|
|||||||
{18:a} |
|
{18:a} |
|
||||||
{1:~ }|*7
|
{1:~ }|*7
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
@@ -5704,14 +5718,12 @@ describe('decorations: window scoped', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('redraws correctly with inline virt_text and wrapping', function()
|
it('redraws correctly with inline virt_text and wrapping', function()
|
||||||
set_scoped_extmark(0, 2, {
|
set_extmark(0, 2, {
|
||||||
virt_text = {{ ('b'):rep(18), 'Comment' }},
|
virt_text = { { ('b'):rep(18), 'Comment' } },
|
||||||
virt_text_pos = 'inline'
|
virt_text_pos = 'inline',
|
||||||
})
|
})
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
@@ -5719,9 +5731,10 @@ describe('decorations: window scoped', function()
|
|||||||
34^5 |
|
34^5 |
|
||||||
{1:~ }|*7
|
{1:~ }|*7
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
api.nvim__win_del_ns(0, ns)
|
api.nvim__ns_set(ns, { wins = { win_other } })
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
screen:expect(noextmarks)
|
||||||
end)
|
end)
|
||||||
@@ -5729,21 +5742,20 @@ describe('decorations: window scoped', function()
|
|||||||
pending('sign_text', function()
|
pending('sign_text', function()
|
||||||
-- TODO(altermo): The window signcolumn width is calculated wrongly (when `signcolumn=auto`)
|
-- TODO(altermo): The window signcolumn width is calculated wrongly (when `signcolumn=auto`)
|
||||||
-- This happens in function `win_redraw_signcols` on line containing `buf_meta_total(buf, kMTMetaSignText) > 0`
|
-- This happens in function `win_redraw_signcols` on line containing `buf_meta_total(buf, kMTMetaSignText) > 0`
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
sign_text = 'a',
|
sign_text = 'a',
|
||||||
sign_hl_group = 'Comment',
|
sign_hl_group = 'Comment',
|
||||||
})
|
})
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
a 1234^5 |
|
a 1234^5 |
|
||||||
{2:~ }|*8
|
{2:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
@@ -5752,30 +5764,34 @@ describe('decorations: window scoped', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('statuscolumn hl group', function()
|
it('statuscolumn hl group', function()
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
number_hl_group='comment',
|
number_hl_group = 'comment',
|
||||||
})
|
})
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
line_hl_group='comment',
|
line_hl_group = 'comment',
|
||||||
})
|
})
|
||||||
|
|
||||||
command 'set number'
|
command 'set number'
|
||||||
|
|
||||||
|
api.nvim__ns_set(ns, { wins = { win_other } })
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
{8: 1 }1234^5 |
|
{8: 1 }1234^5 |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
{18: 1 1234^5 }|
|
{18: 1 1234^5 }|
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
@@ -5785,36 +5801,43 @@ describe('decorations: window scoped', function()
|
|||||||
{8: 1 }1234^5 |
|
{8: 1 }1234^5 |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('spell', function()
|
it('spell', function()
|
||||||
api.nvim_buf_set_lines(0,0,-1,true,{'aa'})
|
api.nvim_buf_set_lines(0, 0, -1, true, { 'aa' })
|
||||||
|
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
spell=true,
|
spell = true,
|
||||||
end_col=2,
|
end_col = 2,
|
||||||
})
|
})
|
||||||
|
|
||||||
command 'set spelloptions=noplainbuffer'
|
command 'set spelloptions=noplainbuffer'
|
||||||
command 'set spell'
|
command 'set spell'
|
||||||
command 'syntax off'
|
command 'syntax off'
|
||||||
|
|
||||||
|
screen:expect({ unchanged = true })
|
||||||
|
|
||||||
|
api.nvim__ns_set(ns, { wins = { win_other } })
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
a^a |
|
a^a |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
{100:a^a} |
|
{100:a^a} |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
@@ -5824,25 +5847,25 @@ describe('decorations: window scoped', function()
|
|||||||
a^a |
|
a^a |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('url', function()
|
it('url', function()
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
end_col=3,
|
end_col = 3,
|
||||||
url=url,
|
url = url,
|
||||||
})
|
})
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
{101:123}4^5 |
|
{101:123}4^5 |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
@@ -5850,85 +5873,72 @@ describe('decorations: window scoped', function()
|
|||||||
screen:expect(noextmarks)
|
screen:expect(noextmarks)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('change extmarks scoped option', function()
|
|
||||||
local id = set_scoped_extmark(0, 0, {
|
|
||||||
hl_group = 'Comment',
|
|
||||||
end_col = 3,
|
|
||||||
})
|
|
||||||
|
|
||||||
api.nvim__win_add_ns(0, ns)
|
|
||||||
|
|
||||||
screen:expect {
|
|
||||||
grid = [[
|
|
||||||
{18:123}4^5 |
|
|
||||||
{1:~ }|*8
|
|
||||||
|
|
|
||||||
]]}
|
|
||||||
|
|
||||||
command 'split'
|
|
||||||
command 'only'
|
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
|
||||||
|
|
||||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {
|
|
||||||
id = id,
|
|
||||||
hl_group = 'Comment',
|
|
||||||
end_col = 3,
|
|
||||||
scoped = false,
|
|
||||||
})
|
|
||||||
|
|
||||||
screen:expect {
|
|
||||||
grid = [[
|
|
||||||
{18:123}4^5 |
|
|
||||||
{1:~ }|*8
|
|
||||||
|
|
|
||||||
]]}
|
|
||||||
|
|
||||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {
|
|
||||||
id = id,
|
|
||||||
hl_group = 'Comment',
|
|
||||||
end_col = 3,
|
|
||||||
scoped = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
|
||||||
end)
|
|
||||||
|
|
||||||
it('change namespace scope', function()
|
it('change namespace scope', function()
|
||||||
set_scoped_extmark(0, 0, {
|
set_extmark(0, 0, {
|
||||||
hl_group = 'Comment',
|
hl_group = 'Comment',
|
||||||
end_col = 3,
|
end_col = 3,
|
||||||
})
|
})
|
||||||
|
|
||||||
eq(true, api.nvim__win_add_ns(0, ns))
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
eq({ ns }, api.nvim__win_get_ns(0))
|
eq({ wins={ api.nvim_get_current_win() } }, api.nvim__ns_get(ns))
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
{18:123}4^5 |
|
{18:123}4^5 |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
command 'split'
|
command 'split'
|
||||||
command 'only'
|
command 'only'
|
||||||
eq({}, api.nvim__win_get_ns(0))
|
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
screen:expect(noextmarks)
|
||||||
|
|
||||||
eq(true, api.nvim__win_add_ns(0, ns))
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
eq({ ns }, api.nvim__win_get_ns(0))
|
eq({ wins={ api.nvim_get_current_win() } }, api.nvim__ns_get(ns))
|
||||||
|
|
||||||
screen:expect {
|
screen:expect {
|
||||||
grid = [[
|
grid = [[
|
||||||
{18:123}4^5 |
|
{18:123}4^5 |
|
||||||
{1:~ }|*8
|
{1:~ }|*8
|
||||||
|
|
|
|
||||||
]]}
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
eq(true, api.nvim__win_del_ns(0, ns))
|
local win_new = api.nvim_open_win(0, false, {
|
||||||
eq({}, api.nvim__win_get_ns(0))
|
col=0,row=0,width=20,height=10,
|
||||||
|
relative = 'win',style = 'minimal',
|
||||||
|
hide = true
|
||||||
|
})
|
||||||
|
|
||||||
|
api.nvim__ns_set(ns, { wins = { win_new } })
|
||||||
|
eq({ wins={ win_new } }, api.nvim__ns_get(ns))
|
||||||
|
|
||||||
screen:expect(noextmarks)
|
screen:expect(noextmarks)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('namespace get works', function()
|
||||||
|
eq({ wins = {} }, api.nvim__ns_get(ns))
|
||||||
|
|
||||||
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
|
eq({ wins = { api.nvim_get_current_win() } }, api.nvim__ns_get(ns))
|
||||||
|
|
||||||
|
api.nvim__ns_set(ns, { wins = {} })
|
||||||
|
|
||||||
|
eq({ wins = {} }, api.nvim__ns_get(ns))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('remove window from namespace scope when deleted', function ()
|
||||||
|
api.nvim__ns_set(ns, { wins = { 0 } })
|
||||||
|
|
||||||
|
eq({ wins = { api.nvim_get_current_win() } }, api.nvim__ns_get(ns))
|
||||||
|
|
||||||
|
command 'split'
|
||||||
|
command 'only'
|
||||||
|
|
||||||
|
eq({ wins = {} }, api.nvim__ns_get(ns))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user