aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mpack/lmpack.c3
-rw-r--r--src/nvim/api/vim.c14
-rw-r--r--src/nvim/eval/funcs.c10
-rw-r--r--src/nvim/ex_docmd.c5
-rw-r--r--src/nvim/file_search.c15
-rw-r--r--src/nvim/option.c27
-rw-r--r--src/nvim/option.h1
-rw-r--r--src/nvim/popupmnu.c43
-rw-r--r--src/nvim/screen.c9
-rw-r--r--src/nvim/sign.c3
-rw-r--r--src/nvim/testdir/test_filetype.vim1
-rw-r--r--src/nvim/testdir/test_signs.vim25
12 files changed, 97 insertions, 59 deletions
diff --git a/src/mpack/lmpack.c b/src/mpack/lmpack.c
index 87acf46592..126f2f3824 100644
--- a/src/mpack/lmpack.c
+++ b/src/mpack/lmpack.c
@@ -595,6 +595,7 @@ static void lmpack_unparse_enter(mpack_parser_t *parser, mpack_node_t *node)
/* push the pair */
result = lua_next(L, -2);
assert(result); /* should not be here if the map was fully processed */
+ (void)result; /* ignore unused warning */
if (parent->key_visited) {
/* release the current key */
lmpack_unref(L, packer->reg, (int)parent->data[1].i);
@@ -1010,6 +1011,7 @@ static int lmpack_session_reply(lua_State *L)
"invalid request id");
result = mpack_rpc_reply(session->session, &b, &bl, (mpack_uint32_t)id);
assert(result == MPACK_OK);
+ (void)result; /* ignore unused warning */
lua_pushlstring(L, buf, sizeof(buf) - bl);
return 1;
}
@@ -1027,6 +1029,7 @@ static int lmpack_session_notify(lua_State *L)
session = lmpack_check_session(L, 1);
result = mpack_rpc_notify(session->session, &b, &bl);
assert(result == MPACK_OK);
+ (void)result; /* ignore unused warning */
lua_pushlstring(L, buf, sizeof(buf) - bl);
return 1;
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 4f7c320129..f81cdf9deb 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -696,7 +696,17 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
rv = INTEGER_OBJ(numval);
break;
case 2:
- rv = BOOLEAN_OBJ(!!numval);
+ switch (numval) {
+ case 0:
+ case 1:
+ rv = BOOLEAN_OBJ(numval);
+ break;
+ default:
+ // Boolean options that return something other than 0 or 1 should return nil. Currently this
+ // only applies to 'autoread' which uses -1 as a local value to indicate "unset"
+ rv = NIL;
+ break;
+ }
break;
default:
api_set_error(err, kErrorTypeValidation, "unknown option '%s'", name.data);
@@ -749,7 +759,7 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error
stringval = value.data.string.data;
break;
case kObjectTypeNil:
- // Do nothing
+ scope |= OPT_CLEAR;
break;
default:
api_set_error(err, kErrorTypeValidation, "invalid value for option");
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index d43eeb4a15..4d6ed56164 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -1082,15 +1082,13 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Return the current directory
cwd = xmalloc(MAXPATHL);
- if (cwd != NULL) {
- if (os_dirname(cwd, MAXPATHL) != FAIL) {
+ if (os_dirname(cwd, MAXPATHL) != FAIL) {
#ifdef BACKSLASH_IN_FILENAME
- slash_adjust(cwd);
+ slash_adjust(cwd);
#endif
- rettv->vval.v_string = vim_strsave(cwd);
- }
- xfree(cwd);
+ rettv->vval.v_string = vim_strsave(cwd);
}
+ xfree(cwd);
if (curwin->w_localdir != NULL) {
scope = kCdScopeWindow;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 9f0f8d93a3..ee7946fe3e 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7816,8 +7816,9 @@ bool changedir_func(char_u *new_dir, CdScope scope)
}
#endif
- if (vim_chdir(new_dir) == 0) {
- bool dir_differs = pdir == NULL || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
+ bool dir_differs = new_dir == NULL || pdir == NULL
+ || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
+ if (new_dir != NULL && (!dir_differs || vim_chdir(new_dir) == 0)) {
post_chdir(scope, dir_differs);
retval = true;
} else {
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index d31021b3ef..1884dd49c5 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1667,14 +1667,19 @@ int vim_chdirfile(char_u *fname, CdCause cause)
NameBuff[0] = NUL;
}
- if (os_chdir(dir) == 0) {
- if (cause != kCdCauseOther && pathcmp(dir, (char *)NameBuff, -1) != 0) {
- do_autocmd_dirchanged(dir, kCdScopeWindow, cause);
- }
- } else {
+ if (pathcmp(dir, (char *)NameBuff, -1) == 0) {
+ // nothing to do
+ return OK;
+ }
+
+ if (os_chdir(dir) != 0) {
return FAIL;
}
+ if (cause != kCdCauseOther) {
+ do_autocmd_dirchanged(dir, kCdScopeWindow, cause);
+ }
+
return OK;
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 2ceb1bd992..02e7aeb98b 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -2991,7 +2991,7 @@ ambw_end:
}
} else if (varp == &curwin->w_p_fdc || varp == &curwin->w_allbuf_opt.wo_fdc) {
// 'foldcolumn'
- if (check_opt_strings(*varp, p_fdc_values, false) != OK) {
+ if (**varp == NUL || check_opt_strings(*varp, p_fdc_values, false) != OK) {
errmsg = e_invarg;
}
} else if (varp == &p_pt) {
@@ -3370,6 +3370,9 @@ static int int_cmp(const void *a, const void *b)
/// @return OK when the value is valid, FAIL otherwise
int check_signcolumn(char_u *val)
{
+ if (*val == NUL) {
+ return FAIL;
+ }
// check for basic match
if (check_opt_strings(val, p_scl_values, false) == OK) {
return OK;
@@ -5059,6 +5062,9 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
/// @param[in] number New value for the number or boolean option.
/// @param[in] string New value for string option.
/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both).
+/// If OPT_CLEAR is set, the value of the option
+/// is cleared (the exact semantics of this depend
+/// on the option).
///
/// @return NULL on success, error message on error.
char *set_option_value(const char *const name, const long number, const char *const string,
@@ -5084,7 +5090,7 @@ char *set_option_value(const char *const name, const long number, const char *co
}
if (flags & P_STRING) {
const char *s = string;
- if (s == NULL) {
+ if (s == NULL || opt_flags & OPT_CLEAR) {
s = "";
}
return set_string_option(opt_idx, s, opt_flags);
@@ -5106,10 +5112,23 @@ char *set_option_value(const char *const name, const long number, const char *co
return NULL; // do nothing as we hit an error
}
}
+ long numval = number;
+ if (opt_flags & OPT_CLEAR) {
+ if ((int *)varp == &curbuf->b_p_ar) {
+ numval = -1;
+ } else if ((long *)varp == &curbuf->b_p_ul) {
+ numval = NO_LOCAL_UNDOLEVEL;
+ } else if ((long *)varp == &curwin->w_p_so || (long *)varp == &curwin->w_p_siso) {
+ numval = -1;
+ } else {
+ char *s = NULL;
+ (void)get_option_value(name, &numval, (char_u **)&s, OPT_GLOBAL);
+ }
+ }
if (flags & P_NUM) {
- return set_num_option(opt_idx, varp, number, NULL, 0, opt_flags);
+ return set_num_option(opt_idx, varp, numval, NULL, 0, opt_flags);
} else {
- return set_bool_option(opt_idx, varp, (int)number, opt_flags);
+ return set_bool_option(opt_idx, varp, (int)numval, opt_flags);
}
}
}
diff --git a/src/nvim/option.h b/src/nvim/option.h
index 452494172f..f7dbaafeec 100644
--- a/src/nvim/option.h
+++ b/src/nvim/option.h
@@ -22,6 +22,7 @@ typedef enum {
OPT_ONECOLUMN = 64, ///< list options one per line
OPT_NO_REDRAW = 128, ///< ignore redraw flags on option
OPT_SKIPRTP = 256, ///< "skiprtp" in 'sessionoptions'
+ OPT_CLEAR = 512, ///< Clear local value of an option.
} OptionFlags;
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 606c03f838..da2ada791f 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -386,7 +386,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
void pum_redraw(void)
{
int row = 0;
- int col;
+ int grid_col;
int attr_norm = win_hl_attr(curwin, HLF_PNI);
int attr_select = win_hl_attr(curwin, HLF_PSI);
int attr_scroll = win_hl_attr(curwin, HLF_PSB);
@@ -479,7 +479,7 @@ void pum_redraw(void)
// Display each entry, use two spaces for a Tab.
// Do this 3 times: For the main text, kind and extra info
- col = col_off;
+ grid_col = col_off;
totwidth = 0;
for (round = 1; round <= 3; ++round) {
@@ -537,24 +537,15 @@ void pum_redraw(void)
}
}
grid_puts_len(&pum_grid, rt, (int)STRLEN(rt), row,
- col - size + 1, attr);
+ grid_col - size + 1, attr);
xfree(rt_start);
xfree(st);
- col -= width;
+ grid_col -= width;
} else {
- int size = (int)STRLEN(st);
- int cells = (int)mb_string2cells(st);
-
- // only draw the text that fits
- while (size > 0 && col + cells > pum_width + pum_col) {
- size--;
- size -= utf_head_off(st, st + size);
- cells -= utf_ptr2cells(st + size);
- }
-
- grid_puts_len(&pum_grid, st, size, row, col, attr);
+ // use grid_puts_len() to truncate the text
+ grid_puts(&pum_grid, st, row, grid_col, attr);
xfree(st);
- col += width;
+ grid_col += width;
}
if (*p != TAB) {
@@ -563,12 +554,12 @@ void pum_redraw(void)
// Display two spaces for a Tab.
if (pum_rl) {
- grid_puts_len(&pum_grid, (char_u *)" ", 2, row, col - 1,
+ grid_puts_len(&pum_grid, (char_u *)" ", 2, row, grid_col - 1,
attr);
- col -= 2;
+ grid_col -= 2;
} else {
- grid_puts_len(&pum_grid, (char_u *)" ", 2, row, col, attr);
- col += 2;
+ grid_puts_len(&pum_grid, (char_u *)" ", 2, row, grid_col, attr);
+ grid_col += 2;
}
totwidth += 2;
// start text at next char
@@ -599,21 +590,21 @@ void pum_redraw(void)
if (pum_rl) {
grid_fill(&pum_grid, row, row + 1, col_off - pum_base_width - n + 1,
- col + 1, ' ', ' ', attr);
- col = col_off - pum_base_width - n + 1;
+ grid_col + 1, ' ', ' ', attr);
+ grid_col = col_off - pum_base_width - n + 1;
} else {
- grid_fill(&pum_grid, row, row + 1, col,
+ grid_fill(&pum_grid, row, row + 1, grid_col,
col_off + pum_base_width + n, ' ', ' ', attr);
- col = col_off + pum_base_width + n;
+ grid_col = col_off + pum_base_width + n;
}
totwidth = pum_base_width + n;
}
if (pum_rl) {
- grid_fill(&pum_grid, row, row + 1, col_off - pum_width + 1, col + 1,
+ grid_fill(&pum_grid, row, row + 1, col_off - pum_width + 1, grid_col + 1,
' ', ' ', attr);
} else {
- grid_fill(&pum_grid, row, row + 1, col, col_off + pum_width, ' ', ' ',
+ grid_fill(&pum_grid, row, row + 1, grid_col, col_off + pum_width, ' ', ' ',
attr);
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index a938a3b062..e62e3ca7bc 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -5933,6 +5933,8 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col
// Only 1 cell left, but character requires 2 cells:
// display a '>' in the last column to avoid wrapping. */
c = '>';
+ u8c = '>';
+ u8cc[0] = 0;
mbyte_cells = 1;
}
@@ -5963,6 +5965,13 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col
clear_next_cell = true;
}
+ // When at the start of the text and overwriting the right half of a
+ // two-cell character in the same grid, truncate that into a '>'.
+ if (ptr == text && col > 0 && grid->chars[off][0] == 0) {
+ grid->chars[off - 1][0] = '>';
+ grid->chars[off - 1][1] = 0;
+ }
+
schar_copy(grid->chars[off], buf);
grid->attrs[off] = attr;
if (mbyte_cells == 2) {
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 32be714184..a308df07d1 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -1740,7 +1740,7 @@ char_u *get_sign_name(expand_T *xp, int idx)
case EXP_SUBCMD:
return (char_u *)cmds[idx];
case EXP_DEFINE: {
- char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=",
+ char *define_arg[] = { "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=",
NULL };
return (char_u *)define_arg[idx];
}
@@ -1849,6 +1849,7 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
case SIGNCMD_DEFINE:
if (STRNCMP(last, "texthl", 6) == 0
|| STRNCMP(last, "linehl", 6) == 0
+ || STRNCMP(last, "culhl", 5) == 0
|| STRNCMP(last, "numhl", 5) == 0) {
xp->xp_context = EXPAND_HIGHLIGHT;
} else if (STRNCMP(last, "icon", 4) == 0) {
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index dbe0cd8388..dba7226119 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -204,6 +204,7 @@ let s:filename_checks = {
\ 'gnash': ['gnashrc', '.gnashrc', 'gnashpluginrc', '.gnashpluginrc'],
\ 'gnuplot': ['file.gpi'],
\ 'go': ['file.go'],
+ \ 'gomod': ['go.mod'],
\ 'gp': ['file.gp', '.gprc'],
\ 'gpg': ['/.gnupg/options', '/.gnupg/gpg.conf', '/usr/any/gnupg/options.skel', 'any/.gnupg/gpg.conf', 'any/.gnupg/options', 'any/usr/any/gnupg/options.skel'],
\ 'grads': ['file.gs'],
diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim
index 799e6cb57b..ff9ba3d8ed 100644
--- a/src/nvim/testdir/test_signs.vim
+++ b/src/nvim/testdir/test_signs.vim
@@ -218,15 +218,13 @@ func Test_sign_completion()
call assert_equal('"sign define jump list place undefine unplace', @:)
call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"sign define Sign icon= linehl= numhl= text= texthl=', @:)
+ call assert_equal('"sign define Sign culhl= icon= linehl= numhl= text= texthl=', @:)
- call feedkeys(":sign define Sign linehl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"sign define Sign linehl=SpellBad SpellCap ' .
- \ 'SpellLocal SpellRare', @:)
-
- call feedkeys(":sign define Sign texthl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"sign define Sign texthl=SpellBad SpellCap ' .
- \ 'SpellLocal SpellRare', @:)
+ for hl in ['culhl', 'linehl', 'numhl', 'texthl']
+ call feedkeys(":sign define Sign "..hl.."=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign define Sign '..hl..'=SpellBad SpellCap ' .
+ \ 'SpellLocal SpellRare', @:)
+ endfor
call writefile(repeat(["Sun is shining"], 30), "XsignOne")
call writefile(repeat(["Sky is blue"], 30), "XsignTwo")
@@ -417,20 +415,21 @@ func Test_sign_funcs()
" Tests for sign_define()
let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error',
- \ 'culhl': 'Visual'}
+ \ 'culhl': 'Visual', 'numhl': 'Number'}
call assert_equal(0, "sign1"->sign_define(attr))
- call assert_equal([{'name' : 'sign1', 'texthl' : 'Error',
- \ 'linehl' : 'Search', 'culhl': 'Visual', 'text' : '=>'}],
+ call assert_equal([{'name' : 'sign1', 'texthl' : 'Error', 'linehl': 'Search',
+ \ 'culhl': 'Visual', 'numhl': 'Number', 'text' : '=>'}],
\ sign_getdefined())
" Define a new sign without attributes and then update it
call sign_define("sign2")
let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange',
- \ 'culhl': 'DiffDelete', 'icon' : 'sign2.ico'}
+ \ 'culhl': 'DiffDelete', 'numhl': 'Number', 'icon' : 'sign2.ico'}
call Sign_define_ignore_error("sign2", attr)
call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange',
\ 'linehl' : 'DiffAdd', 'culhl' : 'DiffDelete', 'text' : '!!',
- \ 'icon' : 'sign2.ico'}], "sign2"->sign_getdefined())
+ \ 'numhl': 'Number', 'icon' : 'sign2.ico'}],
+ \ "sign2"->sign_getdefined())
" Test for a sign name with digits
call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'}))