aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.lua4
-rw-r--r--src/nvim/eval/decode.c14
-rw-r--r--src/nvim/options.lua4
-rw-r--r--src/nvim/tui/tui.c47
-rw-r--r--src/nvim/ui_client.c9
5 files changed, 57 insertions, 21 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 59423808be..51cf7bb0ea 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -5735,8 +5735,7 @@ M.funcs = {
Vim value. In the following cases it will output
|msgpack-special-dict|:
1. Dictionary contains duplicate key.
- 2. Dictionary contains empty key.
- 3. String contains NUL byte. Two special dictionaries: for
+ 2. String contains NUL byte. Two special dictionaries: for
dictionary and for string will be emitted in case string
with NUL byte was a dictionary key.
@@ -7155,7 +7154,6 @@ M.funcs = {
are binary strings).
2. String with NUL byte inside.
3. Duplicate key.
- 4. Empty key.
ext |List| with two values: first is a signed integer
representing extension type. Second is
|readfile()|-style list of strings.
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index a6407693d7..64b65b42a5 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -141,9 +141,7 @@ static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack
ValuesStackItem key = kv_pop(*stack);
if (last_container.special_val == NULL) {
// These cases should have already been handled.
- assert(!(key.is_special_string
- || key.val.vval.v_string == NULL
- || *key.val.vval.v_string == NUL));
+ assert(!(key.is_special_string || key.val.vval.v_string == NULL));
dictitem_T *const obj_di = tv_dict_item_alloc(key.val.vval.v_string);
tv_clear(&key.val);
if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
@@ -170,11 +168,10 @@ static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack
tv_clear(&obj.val);
return FAIL;
}
- // Handle empty key and key represented as special dictionary
+ // Handle special dictionaries
if (last_container.special_val == NULL
&& (obj.is_special_string
|| obj.val.vval.v_string == NULL
- || *obj.val.vval.v_string == NUL
|| tv_dict_find(last_container.container.vval.v_dict, obj.val.vval.v_string, -1))) {
tv_clear(&obj.val);
@@ -404,13 +401,6 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
semsg(_("E474: Expected string end: %.*s"), (int)buf_len, buf);
goto parse_json_string_fail;
}
- if (len == 0) {
- POP(((typval_T) {
- .v_type = VAR_STRING,
- .vval = { .v_string = NULL },
- }), false);
- goto parse_json_string_ret;
- }
char *str = xmalloc(len + 1);
int fst_in_pair = 0;
char *str_end = str;
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index daaf73d241..50371b8bf3 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -8764,6 +8764,10 @@ return {
Enables 24-bit RGB color in the |TUI|. Uses "gui" |:highlight|
attributes instead of "cterm" attributes. |guifg|
Requires an ISO-8613-3 compatible terminal.
+
+ Nvim will automatically attempt to determine if the host terminal
+ supports 24-bit color and will enable this option if it does
+ (unless explicitly disabled by the user).
]=],
full_name = 'termguicolors',
redraw = { 'ui_option' },
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index c71eb633e9..d625c22c76 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -148,7 +148,8 @@ static bool cursor_style_enabled = false;
# include "tui/tui.c.generated.h"
#endif
-void tui_start(TUIData **tui_p, int *width, int *height, char **term)
+void tui_start(TUIData **tui_p, int *width, int *height, char **term, bool *rgb)
+ FUNC_ATTR_NONNULL_ALL
{
TUIData *tui = xcalloc(1, sizeof(TUIData));
tui->is_starting = true;
@@ -177,6 +178,7 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term)
*width = tui->width;
*height = tui->height;
*term = tui->term;
+ *rgb = tui->rgb;
}
void tui_set_key_encoding(TUIData *tui)
@@ -334,6 +336,9 @@ static void terminfo_start(TUIData *tui)
int konsolev = konsolev_env ? (int)strtol(konsolev_env, NULL, 10)
: (konsole ? 1 : 0);
+ // truecolor support must be checked before patching/augmenting terminfo
+ tui->rgb = term_has_truecolor(tui, colorterm);
+
patch_terminfo_bugs(tui, term, colorterm, vtev, konsolev, iterm_env, nsterm);
augment_terminfo(tui, term, vtev, konsolev, iterm_env, nsterm);
tui->can_change_scroll_region =
@@ -1439,7 +1444,7 @@ void tui_suspend(TUIData *tui)
tui_mouse_on(tui);
}
stream_set_blocking(tui->input.in_fd, false); // libuv expects this
- ui_client_attach(tui->width, tui->height, tui->term);
+ ui_client_attach(tui->width, tui->height, tui->term, tui->rgb);
#endif
}
@@ -1752,6 +1757,44 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name)
return -1;
}
+/// Determine if the terminal supports truecolor or not:
+///
+/// 1. If $COLORTERM is "24bit" or "truecolor", return true
+/// 2. Else, check terminfo for Tc, RGB, setrgbf, or setrgbb capabilities. If
+/// found, return true
+/// 3. Else, return false
+static bool term_has_truecolor(TUIData *tui, const char *colorterm)
+{
+ // Check $COLORTERM
+ if (strequal(colorterm, "truecolor") || strequal(colorterm, "24bit")) {
+ return true;
+ }
+
+ // Check for Tc and RGB
+ for (size_t i = 0; i < unibi_count_ext_bool(tui->ut); i++) {
+ const char *n = unibi_get_ext_bool_name(tui->ut, i);
+ if (n && (!strcmp(n, "Tc") || !strcmp(n, "RGB"))) {
+ return true;
+ }
+ }
+
+ // Check for setrgbf and setrgbb
+ bool setrgbf = false;
+ bool setrgbb = false;
+ for (size_t i = 0; i < unibi_count_ext_str(tui->ut) && (!setrgbf || !setrgbb); i++) {
+ const char *n = unibi_get_ext_str_name(tui->ut, i);
+ if (n) {
+ if (!setrgbf && !strcmp(n, "setrgbf")) {
+ setrgbf = true;
+ } else if (!setrgbb && !strcmp(n, "setrgbb")) {
+ setrgbb = true;
+ }
+ }
+ }
+
+ return setrgbf && setrgbb;
+}
+
/// Patches the terminfo records after loading from system or built-in db.
/// Several entries in terminfo are known to be deficient or outright wrong;
/// and several terminal emulators falsely announce incorrect terminal types.
diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c
index eb32c16881..d744560a86 100644
--- a/src/nvim/ui_client.c
+++ b/src/nvim/ui_client.c
@@ -70,14 +70,14 @@ uint64_t ui_client_start_server(int argc, char **argv)
return channel->id;
}
-void ui_client_attach(int width, int height, char *term)
+void ui_client_attach(int width, int height, char *term, bool rgb)
{
MAXSIZE_TEMP_ARRAY(args, 3);
ADD_C(args, INTEGER_OBJ(width));
ADD_C(args, INTEGER_OBJ(height));
MAXSIZE_TEMP_DICT(opts, 9);
- PUT_C(opts, "rgb", BOOLEAN_OBJ(true));
+ PUT_C(opts, "rgb", BOOLEAN_OBJ(rgb));
PUT_C(opts, "ext_linegrid", BOOLEAN_OBJ(true));
PUT_C(opts, "ext_termcolors", BOOLEAN_OBJ(true));
if (term) {
@@ -111,9 +111,10 @@ void ui_client_run(bool remote_ui)
ui_client_is_remote = remote_ui;
int width, height;
char *term;
- tui_start(&tui, &width, &height, &term);
+ bool rgb;
+ tui_start(&tui, &width, &height, &term, &rgb);
- ui_client_attach(width, height, term);
+ ui_client_attach(width, height, term, rgb);
// os_exit() will be invoked when the client channel detaches
while (true) {