aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-04-06 17:38:16 +0200
committerGitHub <noreply@github.com>2023-04-06 17:38:16 +0200
commitdd80ee0ca948bb548a8af804523ea7ea29c18279 (patch)
tree25160427c07459cdc4b9a12a4672af62c5830ab8
parente29bc03c046b3a137c2e36b4d34c119b277d62b2 (diff)
parent0f42aa1f2a860ce6d72a825b397fe09c875613b5 (diff)
downloadrneovim-dd80ee0ca948bb548a8af804523ea7ea29c18279.tar.gz
rneovim-dd80ee0ca948bb548a8af804523ea7ea29c18279.tar.bz2
rneovim-dd80ee0ca948bb548a8af804523ea7ea29c18279.zip
Merge pull request #22910 from bfredl/nonormal
fix(highlight): use winhl=Foo:Bar even when Bar is empty
-rw-r--r--src/nvim/api/options.c4
-rw-r--r--src/nvim/api/private/validate.h9
-rw-r--r--src/nvim/highlight.c2
-rw-r--r--src/nvim/highlight_group.c35
-rw-r--r--test/functional/ui/float_spec.lua47
-rw-r--r--test/functional/ui/highlight_spec.lua17
6 files changed, 100 insertions, 14 deletions
diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c
index 3e7f7e8781..467a4720a6 100644
--- a/src/nvim/api/options.c
+++ b/src/nvim/api/options.c
@@ -53,7 +53,7 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t
}
if (HAS_KEY(opts->win)) {
- VALIDATE_T("win", kObjectTypeInteger, opts->win.type, {
+ VALIDATE_T_HANDLE("win", kObjectTypeWindow, opts->win.type, {
return FAIL;
});
@@ -65,7 +65,7 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t
}
if (HAS_KEY(opts->buf)) {
- VALIDATE_T("buf", kObjectTypeInteger, opts->buf.type, {
+ VALIDATE_T_HANDLE("buf", kObjectTypeBuffer, opts->buf.type, {
return FAIL;
});
diff --git a/src/nvim/api/private/validate.h b/src/nvim/api/private/validate.h
index 91a92c2762..a3e77ea838 100644
--- a/src/nvim/api/private/validate.h
+++ b/src/nvim/api/private/validate.h
@@ -67,6 +67,15 @@
} \
} while (0)
+/// Checks that actual_t is either the correct handle type or a type erased handle (integer)
+#define VALIDATE_T_HANDLE(name, expected_t, actual_t, code) \
+ do { \
+ if (expected_t != actual_t && kObjectTypeInteger != actual_t) { \
+ api_err_exp(err, name, api_typename(expected_t), api_typename(actual_t)); \
+ code; \
+ } \
+ } while (0)
+
#define VALIDATE_RANGE(cond, name, code) \
do { \
if (!(cond)) { \
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 36da057ddc..f4d851cfec 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -303,7 +303,7 @@ int hl_get_ui_attr(int ns_id, int idx, int final_id, bool optional)
bool available = false;
if (final_id > 0) {
- int syn_attr = syn_ns_id2attr(ns_id, final_id, optional);
+ int syn_attr = syn_ns_id2attr(ns_id, final_id, &optional);
if (syn_attr > 0) {
attrs = syn_attr2entry(syn_attr);
available = true;
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index a954c14924..5d9148e992 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -1988,18 +1988,23 @@ static int syn_add_group(const char *name, size_t len)
/// @see syn_attr2entry
int syn_id2attr(int hl_id)
{
- return syn_ns_id2attr(-1, hl_id, false);
+ bool optional = false;
+ return syn_ns_id2attr(-1, hl_id, &optional);
}
-int syn_ns_id2attr(int ns_id, int hl_id, bool optional)
+int syn_ns_id2attr(int ns_id, int hl_id, bool *optional)
+ FUNC_ATTR_NONNULL_ALL
{
- hl_id = syn_ns_get_final_id(&ns_id, hl_id);
+ if (syn_ns_get_final_id(&ns_id, &hl_id)) {
+ // If the namespace explicitly defines a group to be empty, it is not optional
+ *optional = false;
+ }
HlGroup *sgp = &hl_table[hl_id - 1]; // index is ID minus one
int attr = ns_get_hl(&ns_id, hl_id, false, sgp->sg_set);
// if a highlight group is optional, don't use the global value
- if (attr >= 0 || (optional && ns_id > 0)) {
+ if (attr >= 0 || (*optional && ns_id > 0)) {
return attr;
}
return sgp->sg_attr;
@@ -2008,16 +2013,20 @@ int syn_ns_id2attr(int ns_id, int hl_id, bool optional)
/// Translate a group ID to the final group ID (following links).
int syn_get_final_id(int hl_id)
{
- int id = curwin->w_ns_hl_active;
- return syn_ns_get_final_id(&id, hl_id);
+ int ns_id = curwin->w_ns_hl_active;
+ syn_ns_get_final_id(&ns_id, &hl_id);
+ return hl_id;
}
-int syn_ns_get_final_id(int *ns_id, int hl_id)
+bool syn_ns_get_final_id(int *ns_id, int *hl_idp)
{
int count;
+ int hl_id = *hl_idp;
+ bool used = false;
if (hl_id > highlight_ga.ga_len || hl_id < 1) {
- return 0; // Can be called from eval!!
+ *hl_idp = 0;
+ return false; // Can be called from eval!!
}
// Follow links until there is no more.
@@ -2030,8 +2039,10 @@ int syn_ns_get_final_id(int *ns_id, int hl_id)
// syn_id2attr time
int check = ns_get_hl(ns_id, hl_id, true, sgp->sg_set);
if (check == 0) {
- return hl_id; // how dare! it broke the link!
+ *hl_idp = hl_id;
+ return true; // how dare! it broke the link!
} else if (check > 0) {
+ used = true;
hl_id = check;
continue;
}
@@ -2045,7 +2056,8 @@ int syn_ns_get_final_id(int *ns_id, int hl_id)
}
}
- return hl_id;
+ *hl_idp = hl_id;
+ return used;
}
/// Refresh the color attributes of all highlight groups.
@@ -2128,7 +2140,8 @@ void highlight_changed(void)
abort();
}
int ns_id = -1;
- int final_id = syn_ns_get_final_id(&ns_id, id);
+ int final_id = id;
+ syn_ns_get_final_id(&ns_id, &final_id);
if (hlf == HLF_SNC) {
id_SNC = final_id;
} else if (hlf == HLF_S) {
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 4612ffe56f..f88954c16b 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -4935,6 +4935,53 @@ describe('float window', function()
end)
end)
+ it("can use Normal as background", function()
+ local buf = meths.create_buf(false,false)
+ meths.buf_set_lines(buf,0,-1,true,{"here", "float"})
+ local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5})
+ meths.set_option_value('winhl', 'Normal:Normal', {win=win})
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ here |
+ float |
+ ]], float_pos={
+ [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50};
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
+ [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0};
+ }}
+ else
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }here {0: }|
+ {0:~ }float {0: }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]]}
+ end
+ end)
+
describe("handles :wincmd", function()
local win
local expected_pos
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index dce886ac91..fedfaca7ba 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -2432,6 +2432,23 @@ describe("'winhighlight' highlight", function()
|
]]}
end)
+
+ it('can link to empty highlight group', function()
+ command 'hi NormalNC guibg=Red' -- czerwone time
+ command 'set winhl=NormalNC:Normal'
+ command 'split'
+
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {3:[No Name] }|
+ |
+ {0:~ }|
+ {4:[No Name] }|
+ |
+ ]]}
+ end)
end)
describe('highlight namespaces', function()