aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cjson/lua_cjson.c2
-rw-r--r--src/nvim/CMakeLists.txt10
-rw-r--r--src/nvim/api/keysets.lua6
-rw-r--r--src/nvim/charset.c2
-rw-r--r--src/nvim/debugger.c2
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval.c3
-rw-r--r--src/nvim/eval/funcs.c27
-rw-r--r--src/nvim/ex_docmd.c4
-rw-r--r--src/nvim/ex_eval.c2
-rw-r--r--src/nvim/getchar.c17
-rw-r--r--src/nvim/hardcopy.c3
-rw-r--r--src/nvim/hardcopy.h3
-rw-r--r--src/nvim/highlight.c20
-rw-r--r--src/nvim/highlight_defs.h4
-rw-r--r--src/nvim/lua/executor.c56
-rw-r--r--src/nvim/lua/vim.lua666
-rw-r--r--src/nvim/main.c3
-rw-r--r--src/nvim/search.c2
-rw-r--r--src/nvim/strings.c2
-rw-r--r--src/nvim/syntax.c10
-rw-r--r--src/nvim/tui/tui.c35
22 files changed, 127 insertions, 754 deletions
diff --git a/src/cjson/lua_cjson.c b/src/cjson/lua_cjson.c
index b5f97bc485..c243f93c05 100644
--- a/src/cjson/lua_cjson.c
+++ b/src/cjson/lua_cjson.c
@@ -1110,7 +1110,7 @@ static int json_is_invalid_number(json_parse_t *json)
/* Reject numbers starting with 0x, or leading zeros */
if (*p == '0') {
- int ch2 = *(p + 1);
+ char ch2 = *(p + 1);
if ((ch2 | 0x20) == 'x' || /* Hex */
('0' <= ch2 && ch2 <= '9')) /* Leading zero */
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 21150965f9..9abefbe02a 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -57,13 +57,13 @@ set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua)
set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode)
set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h)
set(VIM_MODULE_FILE ${GENERATED_DIR}/lua/vim_module.generated.h)
-set(LUA_VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/lua/vim.lua)
+set(LUA_EDITOR_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_editor.lua)
set(LUA_SHARED_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/shared.lua)
set(LUA_INSPECT_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/inspect.lua)
set(LUA_F_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/F.lua)
set(LUA_META_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_meta.lua)
set(LUA_FILETYPE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/filetype.lua)
-set(LUA_LOAD_PACKAGE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_load_package.lua)
+set(LUA_INIT_PACKAGES_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_init_packages.lua)
set(LUA_KEYMAP_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/keymap.lua)
set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
set(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json)
@@ -332,9 +332,9 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E env
"LUAC_PRG=${LUAC_PRG}"
${LUA_PRG} ${CHAR_BLOB_GENERATOR} -c ${VIM_MODULE_FILE}
- ${LUA_LOAD_PACKAGE_MODULE_SOURCE} "vim._load_package"
+ ${LUA_INIT_PACKAGES_MODULE_SOURCE} "vim._init_packages"
${LUA_INSPECT_MODULE_SOURCE} "vim.inspect"
- ${LUA_VIM_MODULE_SOURCE} "vim"
+ ${LUA_EDITOR_MODULE_SOURCE} "vim._editor"
${LUA_SHARED_MODULE_SOURCE} "vim.shared"
${LUA_F_MODULE_SOURCE} "vim.F"
${LUA_META_MODULE_SOURCE} "vim._meta"
@@ -342,7 +342,7 @@ add_custom_command(
${LUA_KEYMAP_MODULE_SOURCE} "vim.keymap"
DEPENDS
${CHAR_BLOB_GENERATOR}
- ${LUA_VIM_MODULE_SOURCE}
+ ${LUA_EDITOR_MODULE_SOURCE}
${LUA_SHARED_MODULE_SOURCE}
${LUA_INSPECT_MODULE_SOURCE}
${LUA_F_MODULE_SOURCE}
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
index 856b336a98..32d4e98822 100644
--- a/src/nvim/api/keysets.lua
+++ b/src/nvim/api/keysets.lua
@@ -88,7 +88,10 @@ return {
"standout";
"strikethrough";
"underline";
+ "underlineline";
"undercurl";
+ "underdot";
+ "underdash";
"italic";
"reverse";
"nocombine";
@@ -110,7 +113,10 @@ return {
"standout";
"strikethrough";
"underline";
+ "underlineline";
"undercurl";
+ "underdot";
+ "underdash";
"italic";
"reverse";
"nocombine";
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index f4882e57e1..97aac67627 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1500,7 +1500,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, cons
} else if ((what & (STR2NR_HEX | STR2NR_OCT | STR2NR_OOCT | STR2NR_BIN))
&& !STRING_ENDED(ptr + 1) && ptr[0] == '0' && ptr[1] != '8'
&& ptr[1] != '9') {
- pre = ptr[1];
+ pre = (char_u)ptr[1];
// Detect hexadecimal: 0x or 0X followed by hex digit.
if ((what & STR2NR_HEX)
&& !STRING_ENDED(ptr + 2)
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index 75ebf0084e..b48a3155b6 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -201,7 +201,7 @@ void do_debug(char_u *cmd)
if (last_cmd != 0) {
// Check that the tail matches.
p++;
- while (*p != NUL && *p == *tail) {
+ while (*p != NUL && *p == (char_u)(*tail)) {
p++;
tail++;
}
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 00ffa7cba1..095e082f61 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -7776,7 +7776,7 @@ int hkmap(int c)
case ';':
c = 't'; break;
default: {
- static char str[] = "zqbcxlsjphmkwonu ydafe rig";
+ static char_u str[] = "zqbcxlsjphmkwonu ydafe rig";
if (c < 'a' || c > 'z') {
return c;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index d95b9560c2..c5c03455b7 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -4858,7 +4858,6 @@ int get_option_tv(const char **const arg, typval_T *const rettv, const bool eval
long numval;
char_u *stringval;
int opt_type;
- int c;
bool working = (**arg == '+'); // has("+option")
int ret = OK;
int opt_flags;
@@ -4877,7 +4876,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv, const bool eval
return OK;
}
- c = *option_end;
+ char c = *option_end;
*option_end = NUL;
opt_type = get_option_value(*arg, &numval,
rettv == NULL ? NULL : &stringval, opt_flags);
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 49dde537c3..df1889b12d 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -8296,7 +8296,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
// Repeat until {skip} returns false.
for (;;) {
subpatnum
- = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1, options, RE_SEARCH, &sia);
+ = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1, options, RE_SEARCH, &sia);
// finding the first match again means there is no match where {skip}
// evaluates to zero.
if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
@@ -9339,7 +9339,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
{
static char *e_invact = N_("E927: Invalid action: '%s'");
const char *title = NULL;
- int action = ' ';
+ char action = ' ';
static int recursive = 0;
rettv->vval.v_number = -1;
dict_T *what = NULL;
@@ -9569,7 +9569,6 @@ static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *c
*/
static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int regname;
bool append = false;
MotionType yank_type;
long block_len;
@@ -9583,13 +9582,13 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (strregname == NULL) {
return; // Type error; errmsg already given.
}
- regname = (uint8_t)(*strregname);
+ char regname = (uint8_t)(*strregname);
if (regname == 0 || regname == '@') {
regname = '"';
}
const typval_T *regcontents = NULL;
- int pointreg = 0;
+ char pointreg = 0;
if (argvars[1].v_type == VAR_DICT) {
dict_T *const d = argvars[1].vval.v_dict;
@@ -9759,7 +9758,7 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static char *e_invact2 = N_("E962: Invalid action: '%s'");
win_T *wp;
dict_T *d;
- int action = 'r';
+ char action = 'r';
rettv->vval.v_number = -1;
@@ -11409,14 +11408,22 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
p = highlight_has_attr(id, HL_STANDOUT, modec);
}
break;
- case 'u':
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- } else { // undercurl
+ case 'u': {
+ const size_t len = STRLEN(what);
+ if (len <= 5 || (TOLOWER_ASC(what[5]) == 'l' && len <= 9)) { // underline
p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ } else if (TOLOWER_ASC(what[5]) == 'c') { // undercurl
+ p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ } else if (len > 9 && TOLOWER_ASC(what[9]) == 'l') { // underlineline
+ p = highlight_has_attr(id, HL_UNDERLINELINE, modec);
+ } else if (len > 6 && TOLOWER_ASC(what[6]) == 'o') { // underdot
+ p = highlight_has_attr(id, HL_UNDERDOT, modec);
+ } else { // underdash
+ p = highlight_has_attr(id, HL_UNDERDASH, modec);
}
break;
}
+ }
rettv->v_type = VAR_STRING;
rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p));
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index d3203bcee8..6e915d98dc 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -80,7 +80,7 @@
static char *e_no_such_user_defined_command_str = N_("E184: No such user-defined command: %s");
static char *e_no_such_user_defined_command_in_current_buffer_str
- = N_("E1237: No such user-defined command in current buffer: %s");
+ = N_("E1237: No such user-defined command in current buffer: %s");
static int quitmore = 0;
static bool ex_pressedreturn = false;
@@ -2835,7 +2835,7 @@ int modifier_len(char_u *cmd)
for (int i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) {
int j;
for (j = 0; p[j] != NUL; j++) {
- if (p[j] != cmdmods[i].name[j]) {
+ if (p[j] != (char_u)cmdmods[i].name[j]) {
break;
}
}
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 851828afcf..6395bbc70b 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -1602,7 +1602,7 @@ void ex_endtry(exarg_T *eap)
{
int idx;
bool rethrow = false;
- int pending = CSTP_NONE;
+ char pending = CSTP_NONE;
void *rettv = NULL;
cstack_T *const cstack = eap->cstack;
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 8426cdb98c..22d957d03d 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1907,9 +1907,6 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
// complete match
if (keylen >= 0 && keylen <= typebuf.tb_len) {
char_u *map_str = NULL;
- int save_m_expr;
- int save_m_noremap;
- int save_m_silent;
// Write chars to script file(s).
// Note: :lmap mappings are written *after* being applied. #5658
@@ -1946,9 +1943,9 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
// Copy the values from *mp that are used, because evaluating the
// expression may invoke a function that redefines the mapping, thereby
// making *mp invalid.
- save_m_expr = mp->m_expr;
- save_m_noremap = mp->m_noremap;
- save_m_silent = mp->m_silent;
+ char save_m_expr = mp->m_expr;
+ int save_m_noremap = mp->m_noremap;
+ char save_m_silent = mp->m_silent;
char_u *save_m_keys = NULL; // only saved when needed
char_u *save_m_str = NULL; // only saved when needed
LuaRef save_m_luaref = mp->m_luaref;
@@ -2661,9 +2658,9 @@ int fix_input_buffer(char_u *buf, int len)
/// @param[in] orig_rhs_len `strlen` of orig_rhs.
/// @param[in] cpo_flags See param docs for @ref replace_termcodes.
/// @param[out] mapargs MapArguments struct holding the replaced strings.
-void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len,
- const char_u *orig_rhs, const size_t orig_rhs_len,
- LuaRef rhs_lua, int cpo_flags, MapArguments *mapargs)
+void set_maparg_lhs_rhs(const char_u *orig_lhs, const size_t orig_lhs_len, const char_u *orig_rhs,
+ const size_t orig_rhs_len, LuaRef rhs_lua, int cpo_flags,
+ MapArguments *mapargs)
{
char_u *lhs_buf = NULL;
char_u *rhs_buf = NULL;
@@ -3988,7 +3985,7 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
/// special characters.
///
/// @param c NUL or typed character for abbreviation
-static char_u *eval_map_expr(mapblock_T *mp, int c)
+static char_u *eval_map_expr(mapblock_T *mp, int c)
{
char_u *res;
char_u *p = NULL;
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index eb10c65be9..93c8c53e33 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -420,7 +420,10 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
pattr->bold = (highlight_has_attr(hl_id, HL_BOLD, modec) != NULL);
pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL);
pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL);
+ pattr->underlineline = (highlight_has_attr(hl_id, HL_UNDERLINELINE, modec) != NULL);
pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
+ pattr->underdot = (highlight_has_attr(hl_id, HL_UNDERDOT, modec) != NULL);
+ pattr->underdash = (highlight_has_attr(hl_id, HL_UNDERDASH, modec) != NULL);
uint32_t fg_color = prt_get_color(hl_id, modec);
diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h
index eba769d342..16119c5d2d 100644
--- a/src/nvim/hardcopy.h
+++ b/src/nvim/hardcopy.h
@@ -18,6 +18,9 @@ typedef struct {
TriState italic;
TriState underline;
int undercurl;
+ int underlineline;
+ int underdot;
+ int underdash;
} prt_text_attr_T;
/*
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index e43a56086f..a01d8369ba 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -558,7 +558,7 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
cattrs = battrs;
cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_color,
fattrs.rgb_bg_color);
- if (cattrs.rgb_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)) {
+ if (cattrs.rgb_ae_attr & (HL_ANY_UNDERLINE)) {
cattrs.rgb_sp_color = rgb_blend(ratio, battrs.rgb_sp_color,
fattrs.rgb_bg_color);
} else {
@@ -576,7 +576,7 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
}
cattrs.rgb_fg_color = rgb_blend(ratio/2, battrs.rgb_fg_color,
fattrs.rgb_fg_color);
- if (cattrs.rgb_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)) {
+ if (cattrs.rgb_ae_attr & (HL_ANY_UNDERLINE)) {
cattrs.rgb_sp_color = rgb_blend(ratio/2, battrs.rgb_bg_color,
fattrs.rgb_sp_color);
} else {
@@ -743,10 +743,23 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb)
PUT(hl, "underline", BOOLEAN_OBJ(true));
}
+ if (mask & HL_UNDERLINELINE) {
+ PUT(hl, "underlineline", BOOLEAN_OBJ(true));
+ }
+
if (mask & HL_UNDERCURL) {
PUT(hl, "undercurl", BOOLEAN_OBJ(true));
}
+ if (mask & HL_UNDERDOT) {
+ PUT(hl, "underdot", BOOLEAN_OBJ(true));
+ }
+
+ if (mask & HL_UNDERDASH) {
+ PUT(hl, "underdash", BOOLEAN_OBJ(true));
+ }
+
+
if (mask & HL_ITALIC) {
PUT(hl, "italic", BOOLEAN_OBJ(true));
}
@@ -813,7 +826,10 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
CHECK_FLAG(dict, mask, bold, , HL_BOLD);
CHECK_FLAG(dict, mask, standout, , HL_STANDOUT);
CHECK_FLAG(dict, mask, underline, , HL_UNDERLINE);
+ CHECK_FLAG(dict, mask, underlineline, , HL_UNDERLINELINE);
CHECK_FLAG(dict, mask, undercurl, , HL_UNDERCURL);
+ CHECK_FLAG(dict, mask, underdot, , HL_UNDERDOT);
+ CHECK_FLAG(dict, mask, underdash, , HL_UNDERDASH);
CHECK_FLAG(dict, mask, italic, , HL_ITALIC);
CHECK_FLAG(dict, mask, reverse, , HL_INVERSE);
CHECK_FLAG(dict, mask, strikethrough, , HL_STRIKETHROUGH);
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
index 50a03e0c02..dcfb9358bb 100644
--- a/src/nvim/highlight_defs.h
+++ b/src/nvim/highlight_defs.h
@@ -24,6 +24,10 @@ typedef enum {
HL_FG_INDEXED = 0x0200,
HL_DEFAULT = 0x0400,
HL_GLOBAL = 0x0800,
+ HL_UNDERLINELINE = 0x1000,
+ HL_UNDERDOT = 0x2000,
+ HL_UNDERDASH = 0x4000,
+ HL_ANY_UNDERLINE = HL_UNDERLINE | HL_UNDERLINELINE | HL_UNDERCURL | HL_UNDERDOT | HL_UNDERDASH,
} HlAttrFlags;
/// Stores a complete highlighting entry, including colors and attributes
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index e233e0e6d0..29a3c515c2 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -525,24 +525,6 @@ static void nlua_common_vim_init(lua_State *lstate, bool is_thread)
lua_pop(lstate, 3);
}
-static void nlua_preload_modules(lua_State *lstate)
-{
- lua_getglobal(lstate, "package"); // [package]
- lua_getfield(lstate, -1, "preload"); // [package, preload]
- for (size_t i = 0; i < ARRAY_SIZE(builtin_modules); i++) {
- ModuleDef def = builtin_modules[i];
- lua_pushinteger(lstate, (long)i); // [package, preload, i]
- lua_pushcclosure(lstate, nlua_module_preloader, 1); // [package, preload, cclosure]
- lua_setfield(lstate, -2, def.name); // [package, preload]
-
- if (nlua_disable_preload && strequal(def.name, "vim")) {
- break;
- }
- }
-
- lua_pop(lstate, 2); // []
-}
-
static int nlua_module_preloader(lua_State *lstate)
{
size_t i = (size_t)lua_tointeger(lstate, lua_upvalueindex(1));
@@ -561,24 +543,29 @@ static int nlua_module_preloader(lua_State *lstate)
return 1;
}
-static bool nlua_common_package_init(lua_State *lstate)
+static bool nlua_init_packages(lua_State *lstate)
FUNC_ATTR_NONNULL_ALL
{
- nlua_preload_modules(lstate);
+ // put builtin packages in preload
+ lua_getglobal(lstate, "package"); // [package]
+ lua_getfield(lstate, -1, "preload"); // [package, preload]
+ for (size_t i = 0; i < ARRAY_SIZE(builtin_modules); i++) {
+ ModuleDef def = builtin_modules[i];
+ lua_pushinteger(lstate, (long)i); // [package, preload, i]
+ lua_pushcclosure(lstate, nlua_module_preloader, 1); // [package, preload, cclosure]
+ lua_setfield(lstate, -2, def.name); // [package, preload]
- lua_getglobal(lstate, "require");
- lua_pushstring(lstate, "vim._load_package");
- if (nlua_pcall(lstate, 1, 0)) {
- nlua_error(lstate, _("E5106: Error while creating _load_package module: %.*s\n"));
- return false;
+ if (nlua_disable_preload && strequal(def.name, "vim.inspect")) {
+ break;
+ }
}
- // TODO(bfredl): ideally all initialization should be done as a single require
- // call.
+ lua_pop(lstate, 2); // []
+
lua_getglobal(lstate, "require");
- lua_pushstring(lstate, "vim.shared");
+ lua_pushstring(lstate, "vim._init_packages");
if (nlua_pcall(lstate, 1, 0)) {
- nlua_error(lstate, _("E5106: Error while creating shared module: %.*s\n"));
+ nlua_error(lstate, _("E5106: Error while loading packages: %.*s\n"));
return false;
}
@@ -654,14 +641,7 @@ static bool nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_setglobal(lstate, "vim");
- if (!nlua_common_package_init(lstate)) {
- return false;
- }
-
- lua_getglobal(lstate, "require");
- lua_pushstring(lstate, "vim");
- if (nlua_pcall(lstate, 1, 0)) {
- nlua_error(lstate, _("E5106: Error while creating vim module: %.*s\n"));
+ if (!nlua_init_packages(lstate)) {
return false;
}
@@ -732,7 +712,7 @@ static lua_State *nlua_thread_acquire_vm(void)
lua_setglobal(lstate, "vim");
- nlua_common_package_init(lstate);
+ nlua_init_packages(lstate);
lua_getglobal(lstate, "package");
lua_getfield(lstate, -1, "loaded");
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
deleted file mode 100644
index f5f293939b..0000000000
--- a/src/nvim/lua/vim.lua
+++ /dev/null
@@ -1,666 +0,0 @@
--- Nvim-Lua stdlib: the `vim` module (:help lua-stdlib)
---
--- Lua code lives in one of three places:
--- 1. runtime/lua/vim/ (the runtime): For "nice to have" features, e.g. the
--- `inspect` and `lpeg` modules.
--- 2. runtime/lua/vim/shared.lua: Code shared between Nvim and tests.
--- (This will go away if we migrate to nvim as the test-runner.)
--- 3. src/nvim/lua/: Compiled-into Nvim itself.
---
--- Guideline: "If in doubt, put it in the runtime".
---
--- Most functions should live directly in `vim.`, not in submodules.
--- The only "forbidden" names are those claimed by legacy `if_lua`:
--- $ vim
--- :lua for k,v in pairs(vim) do print(k) end
--- buffer
--- open
--- window
--- lastline
--- firstline
--- type
--- line
--- eval
--- dict
--- beep
--- list
--- command
---
--- Reference (#6580):
--- - https://github.com/luafun/luafun
--- - https://github.com/rxi/lume
--- - http://leafo.net/lapis/reference/utilities.html
--- - https://github.com/torch/paths
--- - https://github.com/bakpakin/Fennel (pretty print, repl)
--- - https://github.com/howl-editor/howl/tree/master/lib/howl/util
-
-local vim = vim
-assert(vim)
-assert(vim.inspect)
-
--- These are for loading runtime modules lazily since they aren't available in
--- the nvim binary as specified in executor.c
-setmetatable(vim, {
- __index = function(t, key)
- if key == 'treesitter' then
- t.treesitter = require('vim.treesitter')
- return t.treesitter
- elseif key == 'filetype' then
- t.filetype = require('vim.filetype')
- return t.filetype
- elseif key == 'F' then
- t.F = require('vim.F')
- return t.F
- elseif require('vim.uri')[key] ~= nil then
- -- Expose all `vim.uri` functions on the `vim` module.
- t[key] = require('vim.uri')[key]
- return t[key]
- elseif key == 'lsp' then
- t.lsp = require('vim.lsp')
- return t.lsp
- elseif key == 'highlight' then
- t.highlight = require('vim.highlight')
- return t.highlight
- elseif key == 'diagnostic' then
- t.diagnostic = require('vim.diagnostic')
- return t.diagnostic
- elseif key == 'keymap' then
- t.keymap = require('vim.keymap')
- return t.keymap
- elseif key == 'ui' then
- t.ui = require('vim.ui')
- return t.ui
- end
- end
-})
-
-vim.log = {
- levels = {
- TRACE = 0;
- DEBUG = 1;
- INFO = 2;
- WARN = 3;
- ERROR = 4;
- }
-}
-
--- Internal-only until comments in #8107 are addressed.
--- Returns:
--- {errcode}, {output}
-function vim._system(cmd)
- local out = vim.fn.system(cmd)
- local err = vim.v.shell_error
- return err, out
-end
-
--- Gets process info from the `ps` command.
--- Used by nvim_get_proc() as a fallback.
-function vim._os_proc_info(pid)
- if pid == nil or pid <= 0 or type(pid) ~= 'number' then
- error('invalid pid')
- end
- local cmd = { 'ps', '-p', pid, '-o', 'comm=', }
- local err, name = vim._system(cmd)
- if 1 == err and vim.trim(name) == '' then
- return {} -- Process not found.
- elseif 0 ~= err then
- error('command failed: '..vim.fn.string(cmd))
- end
- local _, ppid = vim._system({ 'ps', '-p', pid, '-o', 'ppid=', })
- -- Remove trailing whitespace.
- name = vim.trim(name):gsub('^.*/', '')
- ppid = tonumber(ppid) or -1
- return {
- name = name,
- pid = pid,
- ppid = ppid,
- }
-end
-
--- Gets process children from the `pgrep` command.
--- Used by nvim_get_proc_children() as a fallback.
-function vim._os_proc_children(ppid)
- if ppid == nil or ppid <= 0 or type(ppid) ~= 'number' then
- error('invalid ppid')
- end
- local cmd = { 'pgrep', '-P', ppid, }
- local err, rv = vim._system(cmd)
- if 1 == err and vim.trim(rv) == '' then
- return {} -- Process not found.
- elseif 0 ~= err then
- error('command failed: '..vim.fn.string(cmd))
- end
- local children = {}
- for s in rv:gmatch('%S+') do
- local i = tonumber(s)
- if i ~= nil then
- table.insert(children, i)
- end
- end
- return children
-end
-
--- TODO(ZyX-I): Create compatibility layer.
-
---- Return a human-readable representation of the given object.
----
----@see https://github.com/kikito/inspect.lua
----@see https://github.com/mpeterv/vinspect
-local function inspect(object, options) -- luacheck: no unused
- error(object, options) -- Stub for gen_vimdoc.py
-end
-
-do
- local tdots, tick, got_line1 = 0, 0, false
-
- --- Paste handler, invoked by |nvim_paste()| when a conforming UI
- --- (such as the |TUI|) pastes text into the editor.
- ---
- --- Example: To remove ANSI color codes when pasting:
- --- <pre>
- --- vim.paste = (function(overridden)
- --- return function(lines, phase)
- --- for i,line in ipairs(lines) do
- --- -- Scrub ANSI color codes from paste input.
- --- lines[i] = line:gsub('\27%[[0-9;mK]+', '')
- --- end
- --- overridden(lines, phase)
- --- end
- --- end)(vim.paste)
- --- </pre>
- ---
- ---@see |paste|
- ---
- ---@param lines |readfile()|-style list of lines to paste. |channel-lines|
- ---@param phase -1: "non-streaming" paste: the call contains all lines.
- --- If paste is "streamed", `phase` indicates the stream state:
- --- - 1: starts the paste (exactly once)
- --- - 2: continues the paste (zero or more times)
- --- - 3: ends the paste (exactly once)
- ---@returns false if client should cancel the paste.
- function vim.paste(lines, phase)
- local call = vim.api.nvim_call_function
- local now = vim.loop.now()
- local mode = call('mode', {}):sub(1,1)
- if phase < 2 then -- Reset flags.
- tdots, tick, got_line1 = now, 0, false
- elseif mode ~= 'c' then
- vim.api.nvim_command('undojoin')
- end
- if mode == 'c' and not got_line1 then -- cmdline-mode: paste only 1 line.
- got_line1 = (#lines > 1)
- vim.api.nvim_set_option('paste', true) -- For nvim_input().
- local line1 = lines[1]:gsub('<', '<lt>'):gsub('[\r\n\012\027]', ' ') -- Scrub.
- vim.api.nvim_input(line1)
- vim.api.nvim_set_option('paste', false)
- elseif mode ~= 'c' then
- if phase < 2 and mode:find('^[vV\22sS\19]') then
- vim.api.nvim_command([[exe "normal! \<Del>"]])
- vim.api.nvim_put(lines, 'c', false, true)
- elseif phase < 2 and not mode:find('^[iRt]') then
- vim.api.nvim_put(lines, 'c', true, true)
- -- XXX: Normal-mode: workaround bad cursor-placement after first chunk.
- vim.api.nvim_command('normal! a')
- elseif phase < 2 and mode == 'R' then
- local nchars = 0
- for _, line in ipairs(lines) do
- nchars = nchars + line:len()
- end
- local row, col = unpack(vim.api.nvim_win_get_cursor(0))
- local bufline = vim.api.nvim_buf_get_lines(0, row-1, row, true)[1]
- local firstline = lines[1]
- firstline = bufline:sub(1, col)..firstline
- lines[1] = firstline
- lines[#lines] = lines[#lines]..bufline:sub(col + nchars + 1, bufline:len())
- vim.api.nvim_buf_set_lines(0, row-1, row, false, lines)
- else
- vim.api.nvim_put(lines, 'c', false, true)
- end
- end
- if phase ~= -1 and (now - tdots >= 100) then
- local dots = ('.'):rep(tick % 4)
- tdots = now
- tick = tick + 1
- -- Use :echo because Lua print('') is a no-op, and we want to clear the
- -- message when there are zero dots.
- vim.api.nvim_command(('echo "%s"'):format(dots))
- end
- if phase == -1 or phase == 3 then
- vim.api.nvim_command('redraw'..(tick > 1 and '|echo ""' or ''))
- end
- return true -- Paste will not continue if not returning `true`.
- end
-end
-
---- Defers callback `cb` until the Nvim API is safe to call.
----
----@see |lua-loop-callbacks|
----@see |vim.schedule()|
----@see |vim.in_fast_event()|
-function vim.schedule_wrap(cb)
- return (function (...)
- local args = vim.F.pack_len(...)
- vim.schedule(function() cb(vim.F.unpack_len(args)) end)
- end)
-end
-
---- <Docs described in |vim.empty_dict()| >
----@private
-function vim.empty_dict()
- return setmetatable({}, vim._empty_dict_mt)
-end
-
--- vim.fn.{func}(...)
-vim.fn = setmetatable({}, {
- __index = function(t, key)
- local _fn
- if vim.api[key] ~= nil then
- _fn = function()
- error(string.format("Tried to call API function with vim.fn: use vim.api.%s instead", key))
- end
- else
- _fn = function(...)
- return vim.call(key, ...)
- end
- end
- t[key] = _fn
- return _fn
- end
-})
-
-vim.funcref = function(viml_func_name)
- return vim.fn[viml_func_name]
-end
-
--- An easier alias for commands.
-vim.cmd = function(command)
- return vim.api.nvim_exec(command, false)
-end
-
--- These are the vim.env/v/g/o/bo/wo variable magic accessors.
-do
- local validate = vim.validate
-
- --@private
- local function make_dict_accessor(scope, handle)
- validate {
- scope = {scope, 's'};
- }
- local mt = {}
- function mt:__newindex(k, v)
- return vim._setvar(scope, handle or 0, k, v)
- end
- function mt:__index(k)
- if handle == nil and type(k) == 'number' then
- return make_dict_accessor(scope, k)
- end
- return vim._getvar(scope, handle or 0, k)
- end
- return setmetatable({}, mt)
- end
-
- vim.g = make_dict_accessor('g', false)
- vim.v = make_dict_accessor('v', false)
- vim.b = make_dict_accessor('b')
- vim.w = make_dict_accessor('w')
- vim.t = make_dict_accessor('t')
-end
-
---- Get a table of lines with start, end columns for a region marked by two points
----
----@param bufnr number of buffer
----@param pos1 (line, column) tuple marking beginning of region
----@param pos2 (line, column) tuple marking end of region
----@param regtype type of selection (:help setreg)
----@param inclusive boolean indicating whether the selection is end-inclusive
----@return region lua table of the form {linenr = {startcol,endcol}}
-function vim.region(bufnr, pos1, pos2, regtype, inclusive)
- if not vim.api.nvim_buf_is_loaded(bufnr) then
- vim.fn.bufload(bufnr)
- end
-
- -- check that region falls within current buffer
- local buf_line_count = vim.api.nvim_buf_line_count(bufnr)
- pos1[1] = math.min(pos1[1], buf_line_count - 1)
- pos2[1] = math.min(pos2[1], buf_line_count - 1)
-
- -- in case of block selection, columns need to be adjusted for non-ASCII characters
- -- TODO: handle double-width characters
- local bufline
- if regtype:byte() == 22 then
- bufline = vim.api.nvim_buf_get_lines(bufnr, pos1[1], pos1[1] + 1, true)[1]
- pos1[2] = vim.str_utfindex(bufline, pos1[2])
- end
-
- local region = {}
- for l = pos1[1], pos2[1] do
- local c1, c2
- if regtype:byte() == 22 then -- block selection: take width from regtype
- c1 = pos1[2]
- c2 = c1 + regtype:sub(2)
- -- and adjust for non-ASCII characters
- bufline = vim.api.nvim_buf_get_lines(bufnr, l, l + 1, true)[1]
- if c1 < #bufline then
- c1 = vim.str_byteindex(bufline, c1)
- end
- if c2 < #bufline then
- c2 = vim.str_byteindex(bufline, c2)
- end
- else
- c1 = (l == pos1[1]) and (pos1[2]) or 0
- c2 = (l == pos2[1]) and (pos2[2] + (inclusive and 1 or 0)) or -1
- end
- table.insert(region, l, {c1, c2})
- end
- return region
-end
-
---- Defers calling `fn` until `timeout` ms passes.
----
---- Use to do a one-shot timer that calls `fn`
---- Note: The {fn} is |schedule_wrap|ped automatically, so API functions are
---- safe to call.
----@param fn Callback to call once `timeout` expires
----@param timeout Number of milliseconds to wait before calling `fn`
----@return timer luv timer object
-function vim.defer_fn(fn, timeout)
- vim.validate { fn = { fn, 'c', true}; }
- local timer = vim.loop.new_timer()
- timer:start(timeout, 0, vim.schedule_wrap(function()
- timer:stop()
- timer:close()
-
- fn()
- end))
-
- return timer
-end
-
-
---- Display a notification to the user.
----
---- This function can be overridden by plugins to display notifications using a
---- custom provider (such as the system notification provider). By default,
---- writes to |:messages|.
----
----@param msg string Content of the notification to show to the user.
----@param level number|nil One of the values from |vim.log.levels|.
----@param opts table|nil Optional parameters. Unused by default.
-function vim.notify(msg, level, opts) -- luacheck: no unused args
- if level == vim.log.levels.ERROR then
- vim.api.nvim_err_writeln(msg)
- elseif level == vim.log.levels.WARN then
- vim.api.nvim_echo({{msg, 'WarningMsg'}}, true, {})
- else
- vim.api.nvim_echo({{msg}}, true, {})
- end
-end
-
-do
- local notified = {}
-
- --- Display a notification only one time.
- ---
- --- Like |vim.notify()|, but subsequent calls with the same message will not
- --- display a notification.
- ---
- ---@param msg string Content of the notification to show to the user.
- ---@param level number|nil One of the values from |vim.log.levels|.
- ---@param opts table|nil Optional parameters. Unused by default.
- function vim.notify_once(msg, level, opts) -- luacheck: no unused args
- if not notified[msg] then
- vim.notify(msg, level, opts)
- notified[msg] = true
- end
- end
-end
-
----@private
-function vim.register_keystroke_callback()
- error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key')
-end
-
-local on_key_cbs = {}
-
---- Adds Lua function {fn} with namespace id {ns_id} as a listener to every,
---- yes every, input key.
----
---- The Nvim command-line option |-w| is related but does not support callbacks
---- and cannot be toggled dynamically.
----
----@param fn function: Callback function. It should take one string argument.
---- On each key press, Nvim passes the key char to fn(). |i_CTRL-V|
---- If {fn} is nil, it removes the callback for the associated {ns_id}
----@param ns_id number? Namespace ID. If nil or 0, generates and returns a new
---- |nvim_create_namespace()| id.
----
----@return number Namespace id associated with {fn}. Or count of all callbacks
----if on_key() is called without arguments.
----
----@note {fn} will be removed if an error occurs while calling.
----@note {fn} will not be cleared by |nvim_buf_clear_namespace()|
----@note {fn} will receive the keys after mappings have been evaluated
-function vim.on_key(fn, ns_id)
- if fn == nil and ns_id == nil then
- return #on_key_cbs
- end
-
- vim.validate {
- fn = { fn, 'c', true},
- ns_id = { ns_id, 'n', true }
- }
-
- if ns_id == nil or ns_id == 0 then
- ns_id = vim.api.nvim_create_namespace('')
- end
-
- on_key_cbs[ns_id] = fn
- return ns_id
-end
-
---- Executes the on_key callbacks.
----@private
-function vim._on_key(char)
- local failed_ns_ids = {}
- local failed_messages = {}
- for k, v in pairs(on_key_cbs) do
- local ok, err_msg = pcall(v, char)
- if not ok then
- vim.on_key(nil, k)
- table.insert(failed_ns_ids, k)
- table.insert(failed_messages, err_msg)
- end
- end
-
- if failed_ns_ids[1] then
- error(string.format(
- "Error executing 'on_key' with ns_ids '%s'\n Messages: %s",
- table.concat(failed_ns_ids, ", "),
- table.concat(failed_messages, "\n")))
- end
-end
-
---- Generate a list of possible completions for the string.
---- String starts with ^ and then has the pattern.
----
---- 1. Can we get it to just return things in the global namespace with that name prefix
---- 2. Can we get it to return things from global namespace even with `print(` in front.
-function vim._expand_pat(pat, env)
- env = env or _G
-
- pat = string.sub(pat, 2, #pat)
-
- if pat == '' then
- local result = vim.tbl_keys(env)
- table.sort(result)
- return result, 0
- end
-
- -- TODO: We can handle spaces in [] ONLY.
- -- We should probably do that at some point, just for cooler completion.
- -- TODO: We can suggest the variable names to go in []
- -- This would be difficult as well.
- -- Probably just need to do a smarter match than just `:match`
-
- -- Get the last part of the pattern
- local last_part = pat:match("[%w.:_%[%]'\"]+$")
- if not last_part then return {}, 0 end
-
- local parts, search_index = vim._expand_pat_get_parts(last_part)
-
- local match_part = string.sub(last_part, search_index, #last_part)
- local prefix_match_pat = string.sub(pat, 1, #pat - #match_part) or ''
-
- local final_env = env
-
- for _, part in ipairs(parts) do
- if type(final_env) ~= 'table' then
- return {}, 0
- end
- local key
-
- -- Normally, we just have a string
- -- Just attempt to get the string directly from the environment
- if type(part) == "string" then
- key = part
- else
- -- However, sometimes you want to use a variable, and complete on it
- -- With this, you have the power.
-
- -- MY_VAR = "api"
- -- vim[MY_VAR]
- -- -> _G[MY_VAR] -> "api"
- local result_key = part[1]
- if not result_key then
- return {}, 0
- end
-
- local result = rawget(env, result_key)
-
- if result == nil then
- return {}, 0
- end
-
- key = result
- end
- local field = rawget(final_env, key)
- if field == nil then
- local mt = getmetatable(final_env)
- if mt and type(mt.__index) == "table" then
- field = rawget(mt.__index, key)
- end
- end
- final_env = field
-
- if not final_env then
- return {}, 0
- end
- end
-
- local keys = {}
- ---@private
- local function insert_keys(obj)
- for k,_ in pairs(obj) do
- if type(k) == "string" and string.sub(k,1,string.len(match_part)) == match_part then
- table.insert(keys,k)
- end
- end
- end
-
- if type(final_env) == "table" then
- insert_keys(final_env)
- end
- local mt = getmetatable(final_env)
- if mt and type(mt.__index) == "table" then
- insert_keys(mt.__index)
- end
-
- table.sort(keys)
-
- return keys, #prefix_match_pat
-end
-
-vim._expand_pat_get_parts = function(lua_string)
- local parts = {}
-
- local accumulator, search_index = '', 1
- local in_brackets, bracket_end = false, -1
- local string_char = nil
- for idx = 1, #lua_string do
- local s = lua_string:sub(idx, idx)
-
- if not in_brackets and (s == "." or s == ":") then
- table.insert(parts, accumulator)
- accumulator = ''
-
- search_index = idx + 1
- elseif s == "[" then
- in_brackets = true
-
- table.insert(parts, accumulator)
- accumulator = ''
-
- search_index = idx + 1
- elseif in_brackets then
- if idx == bracket_end then
- in_brackets = false
- search_index = idx + 1
-
- if string_char == "VAR" then
- table.insert(parts, { accumulator })
- accumulator = ''
-
- string_char = nil
- end
- elseif not string_char then
- bracket_end = string.find(lua_string, ']', idx, true)
-
- if s == '"' or s == "'" then
- string_char = s
- elseif s ~= ' ' then
- string_char = "VAR"
- accumulator = s
- end
- elseif string_char then
- if string_char ~= s then
- accumulator = accumulator .. s
- else
- table.insert(parts, accumulator)
- accumulator = ''
-
- string_char = nil
- end
- end
- else
- accumulator = accumulator .. s
- end
- end
-
- parts = vim.tbl_filter(function(val) return #val > 0 end, parts)
-
- return parts, search_index
-end
-
----Prints given arguments in human-readable format.
----Example:
----<pre>
---- -- Print highlight group Normal and store it's contents in a variable.
---- local hl_normal = vim.pretty_print(vim.api.nvim_get_hl_by_name("Normal", true))
----</pre>
----@see |vim.inspect()|
----@return given arguments.
-function vim.pretty_print(...)
- local objects = {}
- for i = 1, select('#', ...) do
- local v = select(i, ...)
- table.insert(objects, vim.inspect(v))
- end
-
- print(table.concat(objects, ' '))
- return ...
-end
-
-
-require('vim._meta')
-
-return vim
diff --git a/src/nvim/main.c b/src/nvim/main.c
index ae25ff63dd..7281809c06 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -823,7 +823,6 @@ static void command_line_scan(mparm_T *parmp)
bool had_stdin_file = false; // found explicit "-" argument
bool had_minmin = false; // found "--" argument
int want_argument; // option argument with argument
- int c;
long n;
argc--;
@@ -845,7 +844,7 @@ static void command_line_scan(mparm_T *parmp)
// Optional argument.
} else if (argv[0][0] == '-' && !had_minmin) {
want_argument = false;
- c = argv[0][argv_idx++];
+ char c = argv[0][argv_idx++];
switch (c) {
case NUL: // "nvim -" read from stdin
if (exmode_active) {
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 682fa417a9..e6b47e75b2 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -1071,7 +1071,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
* Find out the direction of the search.
*/
if (dirc == 0) {
- dirc = spats[0].off.dir;
+ dirc = (char_u)spats[0].off.dir;
} else {
spats[0].off.dir = dirc;
set_vv_searchforward();
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 291138ef23..9d4c64e4b1 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -354,7 +354,7 @@ char *strcase_save(const char *const orig, bool upper)
int l = utf_ptr2len((const char_u *)p);
if (c == 0) {
// overlong sequence, use only the first byte
- c = *p;
+ c = (char_u)(*p);
l = 1;
}
int uc = upper ? mb_toupper(c) : mb_tolower(c);
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index db10b71d38..54fce3d968 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -121,11 +121,11 @@ static int include_link = 0; // when 2 include "nvim/link" and "clear"
/// The "term", "cterm" and "gui" arguments can be any combination of the
/// following names, separated by commas (but no spaces!).
static char *(hl_name_table[]) =
-{ "bold", "standout", "underline", "undercurl",
- "italic", "reverse", "inverse", "strikethrough", "nocombine", "NONE" };
+{ "bold", "standout", "underline", "underlineline", "undercurl", "underdot",
+ "underdash", "italic", "reverse", "inverse", "strikethrough", "nocombine", "NONE" };
static int hl_attr_table[] =
-{ HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE,
- HL_INVERSE, HL_STRIKETHROUGH, HL_NOCOMBINE, 0 };
+{ HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERLINELINE, HL_UNDERCURL, HL_UNDERDOT, HL_UNDERDASH,
+ HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_STRIKETHROUGH, HL_NOCOMBINE, 0 };
static char e_illegal_arg[] = N_("E390: Illegal argument: %s");
@@ -4208,7 +4208,7 @@ static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_cha
p = flagtab[fidx].name;
int i;
for (i = 0, len = 0; p[i] != NUL; i += 2, ++len) {
- if (arg[len] != p[i] && arg[len] != p[i + 1]) {
+ if (arg[len] != (char_u)p[i] && arg[len] != (char_u)p[i + 1]) {
break;
}
}
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 58061f020d..1ad82b7290 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -528,7 +528,7 @@ static bool attrs_differ(UI *ui, int id1, int id2, bool rgb)
return a1.cterm_fg_color != a2.cterm_fg_color
|| a1.cterm_bg_color != a2.cterm_bg_color
|| a1.cterm_ae_attr != a2.cterm_ae_attr
- || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)
+ || (a1.cterm_ae_attr & HL_ANY_UNDERLINE
&& a1.rgb_sp_color != a2.rgb_sp_color);
}
}
@@ -552,15 +552,27 @@ static void update_attrs(UI *ui, int attr_id)
bool strikethrough = attr & HL_STRIKETHROUGH;
bool underline;
+ bool underlineline;
bool undercurl;
+ bool underdot;
+ bool underdash;
if (data->unibi_ext.set_underline_style != -1) {
underline = attr & HL_UNDERLINE;
+ underlineline = attr & HL_UNDERLINELINE;
undercurl = attr & HL_UNDERCURL;
+ underdash = attr & HL_UNDERDASH;
+ underdot = attr & HL_UNDERDOT;
} else {
- underline = (attr & HL_UNDERLINE) || (attr & HL_UNDERCURL);
+ underline = attr & HL_ANY_UNDERLINE;
+ underlineline = false;
undercurl = false;
+ underdot = false;
+ underdash = false;
}
+ bool has_any_underline = undercurl || underline
+ || underdot || underdash || underlineline;
+
if (unibi_get_str(data->ut, unibi_set_attributes)) {
if (bold || reverse || underline || standout) {
UNIBI_SET_NUM_VAR(data->params[0], standout);
@@ -599,11 +611,24 @@ static void update_attrs(UI *ui, int attr_id)
if (strikethrough && data->unibi_ext.enter_strikethrough_mode != -1) {
unibi_out_ext(ui, data->unibi_ext.enter_strikethrough_mode);
}
+ if (underlineline && data->unibi_ext.set_underline_style != -1) {
+ UNIBI_SET_NUM_VAR(data->params[0], 2);
+ unibi_out_ext(ui, data->unibi_ext.set_underline_style);
+ }
if (undercurl && data->unibi_ext.set_underline_style != -1) {
UNIBI_SET_NUM_VAR(data->params[0], 3);
unibi_out_ext(ui, data->unibi_ext.set_underline_style);
}
- if ((undercurl || underline) && data->unibi_ext.set_underline_color != -1) {
+ if (underdot && data->unibi_ext.set_underline_style != -1) {
+ UNIBI_SET_NUM_VAR(data->params[0], 4);
+ unibi_out_ext(ui, data->unibi_ext.set_underline_style);
+ }
+ if (underdash && data->unibi_ext.set_underline_style != -1) {
+ UNIBI_SET_NUM_VAR(data->params[0], 5);
+ unibi_out_ext(ui, data->unibi_ext.set_underline_style);
+ }
+
+ if (has_any_underline && data->unibi_ext.set_underline_color != -1) {
int color = attrs.rgb_sp_color;
if (color != -1) {
UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red
@@ -652,13 +677,13 @@ static void update_attrs(UI *ui, int attr_id)
data->default_attr = fg == -1 && bg == -1
- && !bold && !italic && !underline && !undercurl && !reverse && !standout
+ && !bold && !italic && !has_any_underline && !reverse && !standout
&& !strikethrough;
// Non-BCE terminals can't clear with non-default background color. Some BCE
// terminals don't support attributes either, so don't rely on it. But assume
// italic and bold has no effect if there is no text.
- data->can_clear_attr = !reverse && !standout && !underline && !undercurl
+ data->can_clear_attr = !reverse && !standout && !has_any_underline
&& !strikethrough && (data->bce || bg == -1);
}