aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/command.c1
-rw-r--r--src/nvim/api/vim.c6
-rw-r--r--src/nvim/arglist.c1
-rw-r--r--src/nvim/arglist.h1
-rw-r--r--src/nvim/autocmd.c7
-rw-r--r--src/nvim/autocmd.h1
-rw-r--r--src/nvim/buffer.c6
-rw-r--r--src/nvim/buffer_defs.h14
-rw-r--r--src/nvim/bufwrite.c4
-rw-r--r--src/nvim/change.c2
-rw-r--r--src/nvim/cmdexpand.c27
-rw-r--r--src/nvim/cmdexpand.h1
-rw-r--r--src/nvim/cmdexpand_defs.h113
-rw-r--r--src/nvim/cmdhist.c1
-rw-r--r--src/nvim/cmdhist.h1
-rw-r--r--src/nvim/cursor_shape.c6
-rw-r--r--src/nvim/cursor_shape.h6
-rw-r--r--src/nvim/debugger.c1
-rw-r--r--src/nvim/diff.c6
-rw-r--r--src/nvim/drawscreen.c18
-rw-r--r--src/nvim/edit.c6
-rw-r--r--src/nvim/eval.c12
-rw-r--r--src/nvim/eval.h1
-rw-r--r--src/nvim/eval.lua6
-rw-r--r--src/nvim/eval/funcs.c3
-rw-r--r--src/nvim/eval/funcs.h1
-rw-r--r--src/nvim/eval/typval_defs.h13
-rw-r--r--src/nvim/eval/userfunc.c7
-rw-r--r--src/nvim/eval/userfunc.h1
-rw-r--r--src/nvim/ex_cmds.c56
-rw-r--r--src/nvim/ex_cmds_defs.h115
-rw-r--r--src/nvim/ex_docmd.c9
-rw-r--r--src/nvim/ex_docmd.h1
-rw-r--r--src/nvim/ex_eval_defs.h39
-rw-r--r--src/nvim/ex_getln.c27
-rw-r--r--src/nvim/ex_getln.h1
-rw-r--r--src/nvim/fileio.c12
-rw-r--r--src/nvim/fileio.h3
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua2
-rw-r--r--src/nvim/generators/gen_options.lua5
-rw-r--r--src/nvim/getchar.c10
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/grid.c16
-rw-r--r--src/nvim/highlight_group.c6
-rw-r--r--src/nvim/highlight_group.h1
-rw-r--r--src/nvim/indent.c89
-rw-r--r--src/nvim/insexpand.c1
-rw-r--r--src/nvim/lua/executor.c1
-rw-r--r--src/nvim/lua/executor.h1
-rw-r--r--src/nvim/mapping.c1
-rw-r--r--src/nvim/mapping.h1
-rw-r--r--src/nvim/mbyte.c16
-rw-r--r--src/nvim/mbyte.h1
-rw-r--r--src/nvim/memline.c264
-rw-r--r--src/nvim/menu.c7
-rw-r--r--src/nvim/menu.h1
-rw-r--r--src/nvim/menu_defs.h2
-rw-r--r--src/nvim/message.c360
-rw-r--r--src/nvim/message.h1
-rw-r--r--src/nvim/move.c2
-rw-r--r--src/nvim/normal.c4
-rw-r--r--src/nvim/normal.h2
-rw-r--r--src/nvim/ops.c57
-rw-r--r--src/nvim/option.c386
-rw-r--r--src/nvim/option.h10
-rw-r--r--src/nvim/option_defs.h51
-rw-r--r--src/nvim/option_vars.h15
-rw-r--r--src/nvim/options.lua78
-rw-r--r--src/nvim/optionstr.c827
-rw-r--r--src/nvim/optionstr.h1
-rw-r--r--src/nvim/os/env.c2
-rw-r--r--src/nvim/os/fileio.c3
-rw-r--r--src/nvim/os/fs.c8
-rw-r--r--src/nvim/os/lang.c3
-rw-r--r--src/nvim/os/lang.h1
-rw-r--r--src/nvim/os/os.h5
-rw-r--r--src/nvim/os/users.c2
-rw-r--r--src/nvim/path.c8
-rw-r--r--src/nvim/profile.c2
-rw-r--r--src/nvim/profile.h1
-rw-r--r--src/nvim/runtime.c1
-rw-r--r--src/nvim/runtime.h1
-rw-r--r--src/nvim/shada.c5
-rw-r--r--src/nvim/sign.c1
-rw-r--r--src/nvim/sign.h1
-rw-r--r--src/nvim/spellfile.c70
-rw-r--r--src/nvim/spellsuggest.c1
-rw-r--r--src/nvim/syntax.c3
-rw-r--r--src/nvim/syntax.h1
-rw-r--r--src/nvim/tag.c1
-rw-r--r--src/nvim/textformat.c2
-rw-r--r--src/nvim/types.h2
-rw-r--r--src/nvim/undo.c40
-rw-r--r--src/nvim/undo_defs.h18
-rw-r--r--src/nvim/usercmd.c1
-rw-r--r--src/nvim/usercmd.h1
-rw-r--r--src/nvim/vim.h73
97 files changed, 2008 insertions, 1006 deletions
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
index eb32f46143..f4c6f646eb 100644
--- a/src/nvim/api/command.c
+++ b/src/nvim/api/command.c
@@ -17,6 +17,7 @@
#include "nvim/ascii.h"
#include "nvim/autocmd.h"
#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/decoration.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 675aaf1006..b8e0934669 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -941,6 +941,12 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
goto fail;
}
+ // Set last_changedtick to avoid triggering a TextChanged autocommand right
+ // after it was added.
+ buf->b_last_changedtick = buf_get_changedtick(buf);
+ buf->b_last_changedtick_i = buf_get_changedtick(buf);
+ buf->b_last_changedtick_pum = buf_get_changedtick(buf);
+
// Only strictly needed for scratch, but could just as well be consistent
// and do this now. buffer is created NOW, not when it latter first happen
// to reach a window or aucmd_prepbuf() ..
diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c
index a4221a1562..fb8849541d 100644
--- a/src/nvim/arglist.c
+++ b/src/nvim/arglist.c
@@ -14,6 +14,7 @@
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/eval/window.h"
diff --git a/src/nvim/arglist.h b/src/nvim/arglist.h
index 52894b73a0..bd5cfb4a11 100644
--- a/src/nvim/arglist.h
+++ b/src/nvim/arglist.h
@@ -2,6 +2,7 @@
#define NVIM_ARGLIST_H
#include "nvim/arglist_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/types.h"
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 657760914f..a40f7d8c26 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -2213,6 +2213,13 @@ char *expand_get_event_name(expand_T *xp, int idx)
return event_names[idx - next_augroup_id].name;
}
+/// Function given to ExpandGeneric() to obtain the list of event names. Don't
+/// include groups.
+char *get_event_name_no_group(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ return event_names[idx].name;
+}
+
/// Check whether given autocommand is supported
///
/// @param[in] event Event to check.
diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h
index b3de57311e..324a31be47 100644
--- a/src/nvim/autocmd.h
+++ b/src/nvim/autocmd.h
@@ -6,6 +6,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/macros.h"
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 5025e86771..076cf63913 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -3480,8 +3480,8 @@ void get_rel_pos(win_T *wp, char *buf, int buflen)
return;
}
- long above; // number of lines above window
- long below; // number of lines below window
+ linenr_T above; // number of lines above window
+ linenr_T below; // number of lines below window
above = wp->w_topline - 1;
above += win_get_fill(wp, wp->w_topline) - wp->w_topfill;
@@ -3580,7 +3580,7 @@ void ex_buffer_all(exarg_T *eap)
bool p_ea_save;
int open_wins = 0;
int r;
- long count; // Maximum number of windows to open.
+ linenr_T count; // Maximum number of windows to open.
int all; // When true also load inactive buffers.
int had_tab = cmdmod.cmod_tab;
tabpage_T *tpnext;
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index a9ad0051ed..1a2e2fbdae 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -488,13 +488,13 @@ struct file_buffer {
u_header_T *b_u_newhead; // pointer to newest header; may not be valid
// if b_u_curhead is not NULL
u_header_T *b_u_curhead; // pointer to current header
- int b_u_numhead; // current number of headers
- bool b_u_synced; // entry lists are synced
- long b_u_seq_last; // last used undo sequence number
- long b_u_save_nr_last; // counter for last file write
- long b_u_seq_cur; // uh_seq of header below which we are now
- time_t b_u_time_cur; // uh_time of header below which we are now
- long b_u_save_nr_cur; // file write nr after which we are now
+ int b_u_numhead; // current number of headers
+ bool b_u_synced; // entry lists are synced
+ int b_u_seq_last; // last used undo sequence number
+ int b_u_save_nr_last; // counter for last file write
+ int b_u_seq_cur; // uh_seq of header below which we are now
+ time_t b_u_time_cur; // uh_time of header below which we are now
+ int b_u_save_nr_cur; // file write nr after which we are now
// variables for "U" command in undo.c
char *b_u_line_ptr; // saved line for "U" command
diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c
index db813a3ae1..2e4dda78fc 100644
--- a/src/nvim/bufwrite.c
+++ b/src/nvim/bufwrite.c
@@ -1368,7 +1368,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
}
int no_eol = false; // no end-of-line written
- long nchars;
+ int nchars;
linenr_T lnum;
int fileformat;
int checking_conversion;
@@ -1789,7 +1789,7 @@ restore_backup:
if (msg_add_fileformat(fileformat)) {
insert_space = true;
}
- msg_add_lines(insert_space, (long)lnum, nchars); // add line/char count
+ msg_add_lines(insert_space, lnum, nchars); // add line/char count
if (!shortmess(SHM_WRITE)) {
if (append) {
xstrlcat(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"), IOSIZE);
diff --git a/src/nvim/change.c b/src/nvim/change.c
index 48dc02b65b..abbfe2505e 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -1941,7 +1941,7 @@ void truncate_line(int fixpos)
/// Delete "nlines" lines at the cursor.
/// Saves the lines for undo first if "undo" is true.
-void del_lines(long nlines, bool undo)
+void del_lines(linenr_T nlines, bool undo)
{
int n;
linenr_T first = curwin->w_cursor.lnum;
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
index d733ffe6ab..c2469b6574 100644
--- a/src/nvim/cmdexpand.c
+++ b/src/nvim/cmdexpand.c
@@ -69,9 +69,6 @@
#include "nvim/vim.h"
#include "nvim/window.h"
-/// Type used by ExpandGeneric()
-typedef char *(*CompleteListItemGetter)(expand_T *, int);
-
/// Type used by call_user_expand_func
typedef void *(*user_expand_func_T)(const char *, int, typval_T *);
@@ -107,6 +104,8 @@ static bool cmdline_fuzzy_completion_supported(const expand_T *const xp)
&& xp->xp_context != EXPAND_HELP
&& xp->xp_context != EXPAND_LUA
&& xp->xp_context != EXPAND_OLD_SETTING
+ && xp->xp_context != EXPAND_STRING_SETTING
+ && xp->xp_context != EXPAND_SETTING_SUBTRACT
&& xp->xp_context != EXPAND_OWNSYNTAX
&& xp->xp_context != EXPAND_PACKADD
&& xp->xp_context != EXPAND_RUNTIME
@@ -2599,7 +2598,7 @@ static int ExpandOther(char *pat, expand_T *xp, regmatch_T *rmp, char ***matches
{ EXPAND_MENUNAMES, get_menu_names, false, true },
{ EXPAND_SYNTAX, get_syntax_name, true, true },
{ EXPAND_SYNTIME, get_syntime_arg, true, true },
- { EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, true, false },
+ { EXPAND_HIGHLIGHT, get_highlight_name, true, false },
{ EXPAND_EVENTS, expand_get_event_name, true, false },
{ EXPAND_AUGROUP, expand_get_augroup_name, true, false },
{ EXPAND_SIGN, get_sign_name, true, true },
@@ -2694,8 +2693,7 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM
return OK;
}
if (xp->xp_context == EXPAND_OLD_SETTING) {
- ExpandOldSetting(numMatches, matches);
- return OK;
+ return ExpandOldSetting(numMatches, matches);
}
if (xp->xp_context == EXPAND_BUFFERS) {
return ExpandBufnames(pat, numMatches, matches, options);
@@ -2765,6 +2763,10 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM
if (xp->xp_context == EXPAND_SETTINGS
|| xp->xp_context == EXPAND_BOOL_SETTINGS) {
ret = ExpandSettings(xp, &regmatch, pat, numMatches, matches, fuzzy);
+ } else if (xp->xp_context == EXPAND_STRING_SETTING) {
+ ret = ExpandStringSetting(xp, &regmatch, numMatches, matches);
+ } else if (xp->xp_context == EXPAND_SETTING_SUBTRACT) {
+ ret = ExpandSettingSubtract(xp, &regmatch, numMatches, matches);
} else if (xp->xp_context == EXPAND_MAPPINGS) {
ret = ExpandMappings(pat, &regmatch, numMatches, matches);
} else if (xp->xp_context == EXPAND_USER_DEFINED) {
@@ -2788,9 +2790,8 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM
/// program. Matching strings are copied into an array, which is returned.
///
/// @param func returns a string from the list
-static void ExpandGeneric(const char *const pat, expand_T *xp, regmatch_T *regmatch,
- char ***matches, int *numMatches, CompleteListItemGetter func,
- int escaped)
+void ExpandGeneric(const char *const pat, expand_T *xp, regmatch_T *regmatch, char ***matches,
+ int *numMatches, CompleteListItemGetter func, bool escaped)
{
const bool fuzzy = cmdline_fuzzy_complete(pat);
*matches = NULL;
@@ -2863,6 +2864,7 @@ static void ExpandGeneric(const char *const pat, expand_T *xp, regmatch_T *regma
// in the specified order.
const bool sort_matches = !fuzzy
&& xp->xp_context != EXPAND_MENUNAMES
+ && xp->xp_context != EXPAND_STRING_SETTING
&& xp->xp_context != EXPAND_MENUS
&& xp->xp_context != EXPAND_SCRIPTNAMES;
@@ -3076,7 +3078,7 @@ static int ExpandUserDefined(const char *const pat, expand_T *xp, regmatch_T *re
*matches = NULL;
*numMatches = 0;
- char *const retstr = call_user_expand_func((user_expand_func_T)call_func_retstr, xp);
+ char *const retstr = call_user_expand_func(call_func_retstr, xp);
if (retstr == NULL) {
return FAIL;
}
@@ -3148,7 +3150,7 @@ static int ExpandUserList(expand_T *xp, char ***matches, int *numMatches)
{
*matches = NULL;
*numMatches = 0;
- list_T *const retlist = call_user_expand_func((user_expand_func_T)call_func_retlist, xp);
+ list_T *const retlist = call_user_expand_func(call_func_retlist, xp);
if (retlist == NULL) {
return FAIL;
}
@@ -3221,8 +3223,7 @@ void globpath(char *path, char *file, garray_T *ga, int expand_options, bool dir
char **p;
int num_p = 0;
- (void)ExpandFromContext(&xpc, buf, &p, &num_p,
- WILD_SILENT | expand_options);
+ (void)ExpandFromContext(&xpc, buf, &p, &num_p, WILD_SILENT | expand_options);
if (num_p > 0) {
ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT | expand_options);
diff --git a/src/nvim/cmdexpand.h b/src/nvim/cmdexpand.h
index 32c23c5d66..81e323c97b 100644
--- a/src/nvim/cmdexpand.h
+++ b/src/nvim/cmdexpand.h
@@ -1,6 +1,7 @@
#ifndef NVIM_CMDEXPAND_H
#define NVIM_CMDEXPAND_H
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_getln.h"
#include "nvim/garray.h"
diff --git a/src/nvim/cmdexpand_defs.h b/src/nvim/cmdexpand_defs.h
new file mode 100644
index 0000000000..a302a32852
--- /dev/null
+++ b/src/nvim/cmdexpand_defs.h
@@ -0,0 +1,113 @@
+#ifndef NVIM_CMDEXPAND_DEFS_H
+#define NVIM_CMDEXPAND_DEFS_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "nvim/eval/typval_defs.h"
+#include "nvim/types.h"
+
+typedef enum {
+ XP_PREFIX_NONE, ///< prefix not used
+ XP_PREFIX_NO, ///< "no" prefix for bool option
+ XP_PREFIX_INV, ///< "inv" prefix for bool option
+} xp_prefix_T;
+
+enum { EXPAND_BUF_LEN = 256, };
+
+/// used for completion on the command line
+typedef struct expand {
+ char *xp_pattern; ///< start of item to expand
+ int xp_context; ///< type of expansion
+ size_t xp_pattern_len; ///< bytes in xp_pattern before cursor
+ xp_prefix_T xp_prefix;
+ char *xp_arg; ///< completion function
+ LuaRef xp_luaref; ///< Ref to Lua completion function
+ sctx_T xp_script_ctx; ///< SCTX for completion function
+ int xp_backslash; ///< one of the XP_BS_ values
+#ifndef BACKSLASH_IN_FILENAME
+ bool xp_shell; ///< true for a shell command, more
+ ///< characters need to be escaped
+#endif
+ int xp_numfiles; ///< number of files found by file name completion
+ int xp_col; ///< cursor position in line
+ int xp_selected; ///< selected index in completion
+ char *xp_orig; ///< originally expanded string
+ char **xp_files; ///< list of files
+ char *xp_line; ///< text being completed
+ char xp_buf[EXPAND_BUF_LEN]; ///< buffer for returned match
+} expand_T;
+
+/// values for xp_backslash
+enum {
+ XP_BS_NONE = 0, ///< nothing special for backslashes
+ XP_BS_ONE = 1, ///< uses one backslash before a space
+ XP_BS_THREE = 2, ///< uses three backslashes before a space
+};
+
+/// values for xp_context when doing command line completion
+enum {
+ EXPAND_UNSUCCESSFUL = -2,
+ EXPAND_OK = -1,
+ EXPAND_NOTHING = 0,
+ EXPAND_COMMANDS,
+ EXPAND_FILES,
+ EXPAND_DIRECTORIES,
+ EXPAND_SETTINGS,
+ EXPAND_BOOL_SETTINGS,
+ EXPAND_TAGS,
+ EXPAND_OLD_SETTING,
+ EXPAND_HELP,
+ EXPAND_BUFFERS,
+ EXPAND_EVENTS,
+ EXPAND_MENUS,
+ EXPAND_SYNTAX,
+ EXPAND_HIGHLIGHT,
+ EXPAND_AUGROUP,
+ EXPAND_USER_VARS,
+ EXPAND_MAPPINGS,
+ EXPAND_TAGS_LISTFILES,
+ EXPAND_FUNCTIONS,
+ EXPAND_USER_FUNC,
+ EXPAND_EXPRESSION,
+ EXPAND_MENUNAMES,
+ EXPAND_USER_COMMANDS,
+ EXPAND_USER_CMD_FLAGS,
+ EXPAND_USER_NARGS,
+ EXPAND_USER_COMPLETE,
+ EXPAND_ENV_VARS,
+ EXPAND_LANGUAGE,
+ EXPAND_COLORS,
+ EXPAND_COMPILER,
+ EXPAND_USER_DEFINED,
+ EXPAND_USER_LIST,
+ EXPAND_USER_LUA,
+ EXPAND_SHELLCMD,
+ EXPAND_SIGN,
+ EXPAND_PROFILE,
+ EXPAND_FILETYPE,
+ EXPAND_FILES_IN_PATH,
+ EXPAND_OWNSYNTAX,
+ EXPAND_LOCALES,
+ EXPAND_HISTORY,
+ EXPAND_USER,
+ EXPAND_SYNTIME,
+ EXPAND_USER_ADDR_TYPE,
+ EXPAND_PACKADD,
+ EXPAND_MESSAGES,
+ EXPAND_MAPCLEAR,
+ EXPAND_ARGLIST,
+ EXPAND_DIFF_BUFFERS,
+ EXPAND_BREAKPOINT,
+ EXPAND_SCRIPTNAMES,
+ EXPAND_RUNTIME,
+ EXPAND_STRING_SETTING,
+ EXPAND_SETTING_SUBTRACT,
+ EXPAND_CHECKHEALTH,
+ EXPAND_LUA,
+};
+
+/// Type used by ExpandGeneric()
+typedef char *(*CompleteListItemGetter)(expand_T *, int);
+
+#endif // NVIM_CMDEXPAND_DEFS_H
diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c
index 50bdfd892f..b0490670fe 100644
--- a/src/nvim/cmdhist.c
+++ b/src/nvim/cmdhist.c
@@ -12,6 +12,7 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cmdhist.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
diff --git a/src/nvim/cmdhist.h b/src/nvim/cmdhist.h
index a0f2ab6934..2b7e47e38e 100644
--- a/src/nvim/cmdhist.h
+++ b/src/nvim/cmdhist.h
@@ -1,6 +1,7 @@
#ifndef NVIM_CMDHIST_H
#define NVIM_CMDHIST_H
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/os/time.h"
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index fb2ca9ff8c..ba5f30c20f 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -364,9 +364,9 @@ static void clear_shape_table(void)
{
for (int idx = 0; idx < SHAPE_IDX_COUNT; idx++) {
shape_table[idx].shape = SHAPE_BLOCK;
- shape_table[idx].blinkwait = 0L;
- shape_table[idx].blinkon = 0L;
- shape_table[idx].blinkoff = 0L;
+ shape_table[idx].blinkwait = 0;
+ shape_table[idx].blinkon = 0;
+ shape_table[idx].blinkoff = 0;
shape_table[idx].id = 0;
shape_table[idx].id_lm = 0;
}
diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h
index 93bddd47c7..33d0344c2d 100644
--- a/src/nvim/cursor_shape.h
+++ b/src/nvim/cursor_shape.h
@@ -44,9 +44,9 @@ typedef struct cursor_entry {
CursorShape shape; ///< cursor shape: one of the SHAPE_ defines
int mshape; ///< mouse shape: one of the MSHAPE defines
int percentage; ///< percentage of cell for bar
- long blinkwait; ///< blinking, wait time before blinking starts
- long blinkon; ///< blinking, on time
- long blinkoff; ///< blinking, off time
+ int blinkwait; ///< blinking, wait time before blinking starts
+ int blinkon; ///< blinking, on time
+ int blinkoff; ///< blinking, off time
int id; ///< highlight group ID
int id_lm; ///< highlight group ID for :lmap mode
char *name; ///< mode short name
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index 3d5f27e76c..755579a3bc 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -12,6 +12,7 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/debugger.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 3ab1da76f4..8479675dfa 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -2467,6 +2467,7 @@ int diffopt_changed(void)
char *p = p_dip;
while (*p != NUL) {
+ // Note: Keep this in sync with p_dip_values
if (strncmp(p, "filler", 6) == 0) {
p += 6;
diff_flags_new |= DIFF_FILLER;
@@ -2513,6 +2514,7 @@ int diffopt_changed(void)
p += 8;
diff_flags_new |= DIFF_INTERNAL;
} else if (strncmp(p, "algorithm:", 10) == 0) {
+ // Note: Keep this in sync with p_dip_algorithm_values.
p += 10;
if (strncmp(p, "myers", 5) == 0) {
p += 5;
@@ -3133,7 +3135,7 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
if (added != 0) {
// Adjust marks. This will change the following entries!
- mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, added, kExtmarkNOOP);
+ mark_adjust(lnum, lnum + count - 1, MAXLNUM, added, kExtmarkNOOP);
if (curwin->w_cursor.lnum >= lnum) {
// Adjust the cursor position if it's in/after the changed
// lines.
@@ -3144,7 +3146,7 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
}
}
}
- extmark_adjust(curbuf, lnum, lnum + count - 1, (long)MAXLNUM, added, kExtmarkUndo);
+ extmark_adjust(curbuf, lnum, lnum + count - 1, MAXLNUM, added, kExtmarkUndo);
changed_lines(curbuf, lnum, 0, lnum + count, added, true);
if (did_free) {
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index cc22accf2b..a0cbc60f25 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -1519,16 +1519,12 @@ static void win_update(win_T *wp, DecorProviders *providers)
}
}
- // Force redraw when width of 'number' or 'relativenumber' column
- // changes.
- int nrwidth = (wp->w_p_nu || wp->w_p_rnu || *wp->w_p_stc) ? number_width(wp) : 0;
- if (wp->w_nrwidth != nrwidth) {
+ const int nrwidth_before = wp->w_nrwidth;
+ int nrwidth_new = (wp->w_p_nu || wp->w_p_rnu || *wp->w_p_stc) ? number_width(wp) : 0;
+ // Force redraw when width of 'number' or 'relativenumber' column changes.
+ if (wp->w_nrwidth != nrwidth_new) {
type = UPD_NOT_VALID;
- wp->w_nrwidth = nrwidth;
-
- if (buf->terminal) {
- terminal_check_size(buf->terminal);
- }
+ wp->w_nrwidth = nrwidth_new;
} else if (buf->b_mod_set
&& buf->b_mod_xlines != 0
&& wp->w_redraw_top != 0) {
@@ -2498,6 +2494,10 @@ static void win_update(win_T *wp, DecorProviders *providers)
}
}
+ if (nrwidth_before != wp->w_nrwidth && buf->terminal) {
+ terminal_check_size(buf->terminal);
+ }
+
// restore got_int, unless CTRL-C was hit while redrawing
if (!got_int) {
got_int = save_got_int;
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 7f29e615ab..58cface37f 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -73,7 +73,7 @@ typedef struct insert_state {
int cmdchar;
int cmdchar_todo; // cmdchar to handle once in init_prompt
int startln;
- long count;
+ int count;
int c;
int lastc;
int i;
@@ -1230,7 +1230,7 @@ static void insert_do_cindent(InsertState *s)
/// @param count repeat count for the command
///
/// @return true if a CTRL-O command caused the return (insert mode pending).
-bool edit(int cmdchar, bool startln, long count)
+bool edit(int cmdchar, bool startln, int count)
{
if (curbuf->terminal) {
if (ex_normal_busy) {
@@ -3394,7 +3394,7 @@ static void ins_ctrl_hat(void)
/// @param nomove when true, don't move the cursor
///
/// @return true when leaving insert mode, false when repeating the insert.
-static bool ins_esc(long *count, int cmdchar, bool nomove)
+static bool ins_esc(int *count, int cmdchar, bool nomove)
FUNC_ATTR_NONNULL_ARG(1)
{
static bool disabled_redraw = false;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 0bf26b2451..9a90e430a7 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -21,6 +21,7 @@
#include "nvim/buffer_defs.h"
#include "nvim/channel.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cmdhist.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
@@ -1225,7 +1226,7 @@ fail:
///
/// @return [allocated] NULL when calling function fails, allocated string
/// otherwise.
-char *call_func_retstr(const char *const func, int argc, typval_T *argv)
+void *call_func_retstr(const char *const func, int argc, typval_T *argv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
typval_T rettv;
@@ -8093,13 +8094,6 @@ void ex_execute(exarg_T *eap)
}
if (ret != FAIL && ga.ga_data != NULL) {
- if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr) {
- // Mark the already saved text as finishing the line, so that what
- // follows is displayed on a new line when scrolling back at the
- // more prompt.
- msg_sb_eol();
- }
-
if (eap->cmdidx == CMD_echomsg) {
msg_ext_set_kind("echomsg");
msg(ga.ga_data, echo_attr);
@@ -8296,7 +8290,7 @@ void option_last_set_msg(LastSet last_set)
msg_puts(p);
if (last_set.script_ctx.sc_lnum > 0) {
msg_puts(_(line_msg));
- msg_outnum((long)last_set.script_ctx.sc_lnum);
+ msg_outnum(last_set.script_ctx.sc_lnum);
}
if (should_free) {
xfree(p);
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index be69cd5657..38bcf8f50d 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -6,6 +6,7 @@
#include "nvim/buffer_defs.h"
#include "nvim/channel.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/event/time.h"
#include "nvim/ex_cmds_defs.h"
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 23ad3d3787..28fb9c6a5c 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -1542,6 +1542,7 @@ M.funcs = {
count = {
args = { 2, 4 },
base = 1,
+ tags = { 'E706' },
desc = [=[
Return the number of times an item with value {expr} appears
in |String|, |List| or |Dictionary| {comp}.
@@ -7381,6 +7382,7 @@ M.funcs = {
using a {n$} positional argument specifier. See |printf-$|.
+ *E1520*
The conversion specifiers and their meanings are:
*printf-d* *printf-b* *printf-B* *printf-o* *printf-x* *printf-X*
@@ -11121,8 +11123,8 @@ M.funcs = {
user user name
host host name
fname original file name
- pid PID of the Vim process that created the swap
- file
+ pid PID of the Nvim process that created the swap
+ file, or zero if not running.
mtime last modification time in seconds
inode Optional: INODE number of the file
dirty 1 if file was modified, 0 if not
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 5bfce7c272..4dd3f193e6 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -33,6 +33,7 @@
#include "nvim/channel.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/context.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
@@ -8235,7 +8236,7 @@ static void f_swapfilelist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
static void f_swapinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
tv_dict_alloc_ret(rettv);
- get_b0_dict(tv_get_string(argvars), rettv->vval.v_dict);
+ swapfile_dict(tv_get_string(argvars), rettv->vval.v_dict);
}
/// "swapname(expr)" function
diff --git a/src/nvim/eval/funcs.h b/src/nvim/eval/funcs.h
index 5dab12787b..5f6132f68c 100644
--- a/src/nvim/eval/funcs.h
+++ b/src/nvim/eval/funcs.h
@@ -6,6 +6,7 @@
#include "nvim/api/private/dispatch.h"
#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/types.h"
diff --git a/src/nvim/eval/typval_defs.h b/src/nvim/eval/typval_defs.h
index d5e8cb0109..c0b5416a05 100644
--- a/src/nvim/eval/typval_defs.h
+++ b/src/nvim/eval/typval_defs.h
@@ -115,6 +115,19 @@ typedef enum {
VAR_BLOB, ///< Blob, .v_blob is used.
} VarType;
+/// Type values for type().
+enum {
+ VAR_TYPE_NUMBER = 0,
+ VAR_TYPE_STRING = 1,
+ VAR_TYPE_FUNC = 2,
+ VAR_TYPE_LIST = 3,
+ VAR_TYPE_DICT = 4,
+ VAR_TYPE_FLOAT = 5,
+ VAR_TYPE_BOOL = 6,
+ VAR_TYPE_SPECIAL = 7,
+ VAR_TYPE_BLOB = 10,
+};
+
/// Structure that holds an internal variable value
typedef struct {
VarType v_type; ///< Variable type.
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 8d85c55e15..ca98aad6bc 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -14,6 +14,7 @@
#include "nvim/ascii.h"
#include "nvim/autocmd.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/debugger.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
@@ -1125,7 +1126,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
msg_puts(", ");
}
if (argvars[i].v_type == VAR_NUMBER) {
- msg_outnum((long)argvars[i].vval.v_number);
+ msg_outnum((int)argvars[i].vval.v_number);
} else {
// Do not want errors such as E724 here.
emsg_off++;
@@ -2262,7 +2263,7 @@ void ex_function(exarg_T *eap)
}
msg_putchar('\n');
if (!eap->forceit) {
- msg_outnum((long)j + 1);
+ msg_outnum(j + 1);
if (j < 9) {
msg_putchar(' ');
}
@@ -2490,7 +2491,7 @@ void ex_function(exarg_T *eap)
} else if (line_arg != NULL && *skipwhite(line_arg) != NUL) {
nextcmd = line_arg;
} else if (*p != NUL && *p != '"' && p_verbose > 0) {
- give_warning2(_("W22: Text found after :endfunction: %s"), p, true);
+ swmsg(true, _("W22: Text found after :endfunction: %s"), p);
}
if (nextcmd != NULL) {
// Another command follows. If the line came from "eap" we
diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h
index 562c549b4b..c3fe56d30c 100644
--- a/src/nvim/eval/userfunc.h
+++ b/src/nvim/eval/userfunc.h
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stddef.h>
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 127397d9fa..c57324d5e9 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -27,6 +27,7 @@
#include "nvim/change.h"
#include "nvim/channel.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cmdhist.h"
#include "nvim/cursor.h"
#include "nvim/decoration.h"
@@ -130,7 +131,7 @@ static const char e_non_numeric_argument_to_z[]
= N_("E144: Non-numeric argument to :z");
/// ":ascii" and "ga" implementation
-void do_ascii(const exarg_T *const eap)
+void do_ascii(exarg_T *eap)
{
char *dig;
int cc[MAX_MCO];
@@ -455,7 +456,7 @@ void ex_sort(exarg_T *eap)
regmatch_T regmatch;
int len;
linenr_T lnum;
- long maxlen = 0;
+ int maxlen = 0;
size_t count = (size_t)(eap->line2 - eap->line1) + 1;
size_t i;
char *p;
@@ -692,7 +693,7 @@ void ex_sort(exarg_T *eap)
// Adjust marks for deleted (or added) lines and prepare for displaying.
deleted = (linenr_T)count - (lnum - eap->line2);
if (deleted > 0) {
- mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted, kExtmarkNOOP);
+ mark_adjust(eap->line2 - deleted, eap->line2, MAXLNUM, -deleted, kExtmarkNOOP);
msgmore(-deleted);
} else if (deleted < 0) {
mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkNOOP);
@@ -921,7 +922,7 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
check_pos(curbuf, &VIsual);
}
- msgmore((long)count);
+ msgmore(count);
}
static char *prevcmd = NULL; // the previous command
@@ -1280,7 +1281,7 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
set_keep_msg(msg_buf, 0);
}
} else {
- msgmore((long)linecount);
+ msgmore(linecount);
}
}
} else {
@@ -3290,7 +3291,7 @@ static int check_regexp_delim(int c)
/// @param cmdpreview_ns The namespace to show 'inccommand' preview highlights.
/// If <= 0, preview shouldn't be shown.
/// @return 0, 1 or 2. See show_cmdpreview() for more information on what the return value means.
-static int do_sub(exarg_T *eap, const proftime_T timeout, const long cmdpreview_ns,
+static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_ns,
const handle_T cmdpreview_bufnr)
{
#define ADJUST_SUB_FIRSTLNUM() \
@@ -3317,7 +3318,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const long cmdpreview_
} \
} while (0)
- long i = 0;
+ int i = 0;
regmmatch_T regmatch;
static subflags_T subflags = {
.do_all = false,
@@ -3345,7 +3346,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const long cmdpreview_
PreviewLines preview_lines = { KV_INITIAL_VALUE, 0 };
static int pre_hl_id = 0;
pos_T old_cursor = curwin->w_cursor;
- long start_nsubs;
+ int start_nsubs;
bool did_save = false;
@@ -3441,7 +3442,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const long cmdpreview_
// check for a trailing count
cmd = skipwhite(cmd);
if (ascii_isdigit(*cmd)) {
- i = getdigits_long(&cmd, true, 0);
+ i = getdigits_int(&cmd, true, 0);
if (i <= 0 && !eap->skip && subflags.do_error) {
emsg(_(e_zerocount));
return 0;
@@ -3520,8 +3521,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const long cmdpreview_
&& (cmdpreview_ns <= 0 || preview_lines.lines_needed <= (linenr_T)p_cwh
|| lnum <= curwin->w_botline);
lnum++) {
- long nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
- (colnr_T)0, NULL, NULL);
+ int nmatch = (int)vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
+ (colnr_T)0, NULL, NULL);
if (nmatch) {
colnr_T copycol;
colnr_T matchcol;
@@ -3531,7 +3532,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const long cmdpreview_
char *p1;
bool did_sub = false;
int lastone;
- long nmatch_tl = 0; // nr of lines matched below lnum
+ linenr_T nmatch_tl = 0; // nr of lines matched below lnum
int do_again; // do it again after joining lines
bool skip_match = false;
linenr_T sub_firstlnum; // nr of first sub line
@@ -3804,7 +3805,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const long cmdpreview_
// Same highlight as wait_return().
smsg(HL_ATTR(HLF_R), _("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
msg_no_more = false;
- msg_scroll = (int)i;
+ msg_scroll = i;
if (!ui_has(kUIMessages)) {
ui_cursor_goto(msg_row, msg_col);
}
@@ -4086,9 +4087,9 @@ skip:
// need to replace the line first (using \zs after \n).
if (lastone
|| nmatch_tl > 0
- || (nmatch = vim_regexec_multi(&regmatch, curwin,
- curbuf, sub_firstlnum,
- matchcol, NULL, NULL)) == 0
+ || (nmatch = (int)vim_regexec_multi(&regmatch, curwin,
+ curbuf, sub_firstlnum,
+ matchcol, NULL, NULL)) == 0
|| regmatch.startpos[0].lnum > 0) {
if (new_start != NULL) {
// Copy the rest of the line, that didn't match.
@@ -4118,13 +4119,12 @@ skip:
for (i = 0; i < nmatch_tl; i++) {
ml_delete(lnum, false);
}
- mark_adjust(lnum, lnum + (linenr_T)nmatch_tl - 1,
- (long)MAXLNUM, (linenr_T)(-nmatch_tl), kExtmarkNOOP);
+ mark_adjust(lnum, lnum + nmatch_tl - 1, MAXLNUM, -nmatch_tl, kExtmarkNOOP);
if (subflags.do_ask) {
- deleted_lines(lnum, (linenr_T)nmatch_tl);
+ deleted_lines(lnum, nmatch_tl);
}
lnum--;
- line2 -= (linenr_T)nmatch_tl; // nr of lines decreases
+ line2 -= nmatch_tl; // nr of lines decreases
nmatch_tl = 0;
}
@@ -4149,8 +4149,8 @@ skip:
copycol = 0;
}
if (nmatch == -1 && !lastone) {
- nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
- sub_firstlnum, matchcol, NULL, NULL);
+ nmatch = (int)vim_regexec_multi(&regmatch, curwin, curbuf,
+ sub_firstlnum, matchcol, NULL, NULL);
}
// 5. break if there isn't another match in this line
@@ -4581,7 +4581,7 @@ bool prepare_tagpreview(bool undo_sync)
///
/// @return 1 if preview window isn't needed, 2 if preview window is needed.
static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, int hl_id,
- long cmdpreview_ns, handle_T cmdpreview_bufnr)
+ int cmdpreview_ns, handle_T cmdpreview_bufnr)
FUNC_ATTR_NONNULL_ALL
{
char *save_shm_p = xstrdup(p_shm);
@@ -4683,9 +4683,9 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
}
linenr_origbuf = match.end.lnum;
- bufhl_add_hl_pos_offset(cmdpreview_buf, (int)cmdpreview_ns, hl_id, p_start, p_end, col_width);
+ bufhl_add_hl_pos_offset(cmdpreview_buf, cmdpreview_ns, hl_id, p_start, p_end, col_width);
}
- bufhl_add_hl_pos_offset(orig_buf, (int)cmdpreview_ns, hl_id, match.start, match.end, 0);
+ bufhl_add_hl_pos_offset(orig_buf, cmdpreview_ns, hl_id, match.start, match.end, 0);
}
xfree(str);
@@ -4703,7 +4703,7 @@ void ex_substitute(exarg_T *eap)
}
/// :substitute command preview callback.
-int ex_substitute_preview(exarg_T *eap, long cmdpreview_ns, handle_T cmdpreview_bufnr)
+int ex_substitute_preview(exarg_T *eap, int cmdpreview_ns, handle_T cmdpreview_bufnr)
{
// Only preview once the pattern delimiter has been typed
if (*eap->arg && !ASCII_ISALNUM(*eap->arg)) {
@@ -4772,7 +4772,7 @@ char *skip_vimgrep_pat(char *p, char **s, int *flags)
void ex_oldfiles(exarg_T *eap)
{
list_T *l = get_vim_var_list(VV_OLDFILES);
- long nr = 0;
+ int nr = 0;
if (l == NULL) {
msg(_("No old files"), 0);
@@ -4806,7 +4806,7 @@ void ex_oldfiles(exarg_T *eap)
nr = prompt_for_number(false);
msg_starthere();
if (nr > 0 && nr <= tv_list_len(l)) {
- const char *const p = tv_list_find_str(l, (int)nr - 1);
+ const char *const p = tv_list_find_str(l, nr - 1);
if (p == NULL) {
return;
}
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index 78f880db56..e15ba673ce 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include "nvim/eval/typval_defs.h"
+#include "nvim/ex_eval_defs.h"
#include "nvim/normal.h"
#include "nvim/pos.h"
#include "nvim/regexp_defs.h"
@@ -69,20 +70,20 @@
#define EX_FILE1 (EX_FILES | EX_NOSPC) // 1 file, defaults to current file
#define EX_WORD1 (EX_EXTRA | EX_NOSPC) // one extra word allowed
-// values for cmd_addr_type
+/// values for cmd_addr_type
typedef enum {
- ADDR_LINES, // buffer line numbers
- ADDR_WINDOWS, // window number
- ADDR_ARGUMENTS, // argument number
- ADDR_LOADED_BUFFERS, // buffer number of loaded buffer
- ADDR_BUFFERS, // buffer number
- ADDR_TABS, // tab page number
- ADDR_TABS_RELATIVE, // Tab page that only relative
- ADDR_QUICKFIX_VALID, // quickfix list valid entry number
- ADDR_QUICKFIX, // quickfix list entry number
- ADDR_UNSIGNED, // positive count or zero, defaults to 1
- ADDR_OTHER, // something else, use line number for '$', '%', etc.
- ADDR_NONE, // no range used
+ ADDR_LINES, ///< buffer line numbers
+ ADDR_WINDOWS, ///< window number
+ ADDR_ARGUMENTS, ///< argument number
+ ADDR_LOADED_BUFFERS, ///< buffer number of loaded buffer
+ ADDR_BUFFERS, ///< buffer number
+ ADDR_TABS, ///< tab page number
+ ADDR_TABS_RELATIVE, ///< Tab page that only relative
+ ADDR_QUICKFIX_VALID, ///< quickfix list valid entry number
+ ADDR_QUICKFIX, ///< quickfix list entry number
+ ADDR_UNSIGNED, ///< positive count or zero, defaults to 1
+ ADDR_OTHER, ///< something else, use line number for '$', '%', etc.
+ ADDR_NONE, ///< no range used
} cmd_addr_T;
typedef struct exarg exarg_T;
@@ -93,7 +94,7 @@ typedef struct exarg exarg_T;
#define BAD_DROP (-2) // erase it
typedef void (*ex_func_T)(exarg_T *eap);
-typedef int (*ex_preview_func_T)(exarg_T *eap, long cmdpreview_ns, handle_T cmdpreview_bufnr);
+typedef int (*ex_preview_func_T)(exarg_T *eap, int cmdpreview_ns, handle_T cmdpreview_bufnr);
// NOTE: These possible could be removed and changed so that
// Callback could take a "command" style string, and simply
@@ -128,54 +129,13 @@ typedef char *(*LineGetter)(int, void *, int, bool);
/// Structure for command definition.
typedef struct cmdname {
- char *cmd_name; ///< Name of the command.
- ex_func_T cmd_func; ///< Function with implementation of this command.
- ex_preview_func_T cmd_preview_func; ///< Preview callback function of this command.
- uint32_t cmd_argt; ///< Relevant flags from the declared above.
- cmd_addr_T cmd_addr_type; ///< Flag for address type.
+ char *cmd_name; ///< Name of the command.
+ ex_func_T cmd_func; ///< Function with implementation of this command.
+ ex_preview_func_T cmd_preview_func; ///< Preview callback function of this command.
+ uint32_t cmd_argt; ///< Relevant flags from the declared above.
+ cmd_addr_T cmd_addr_type; ///< Flag for address type.
} CommandDefinition;
-// A list used for saving values of "emsg_silent". Used by ex_try() to save the
-// value of "emsg_silent" if it was non-zero. When this is done, the CSF_SILENT
-// flag below is set.
-typedef struct eslist_elem eslist_T;
-struct eslist_elem {
- int saved_emsg_silent; // saved value of "emsg_silent"
- eslist_T *next; // next element on the list
-};
-
-// For conditional commands a stack is kept of nested conditionals.
-// When cs_idx < 0, there is no conditional command.
-enum {
- CSTACK_LEN = 50,
-};
-
-typedef struct {
- int cs_flags[CSTACK_LEN]; // CSF_ flags
- char cs_pending[CSTACK_LEN]; // CSTP_: what's pending in ":finally"
- union {
- void *csp_rv[CSTACK_LEN]; // return typeval for pending return
- void *csp_ex[CSTACK_LEN]; // exception for pending throw
- } cs_pend;
- void *cs_forinfo[CSTACK_LEN]; // info used by ":for"
- int cs_line[CSTACK_LEN]; // line nr of ":while"/":for" line
- int cs_idx; // current entry, or -1 if none
- int cs_looplevel; // nr of nested ":while"s and ":for"s
- int cs_trylevel; // nr of nested ":try"s
- eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent"
- int cs_lflags; // loop flags: CSL_ flags
-} cstack_T;
-#define cs_rettv cs_pend.csp_rv
-#define cs_exception cs_pend.csp_ex
-
-// Flags for the cs_lflags item in cstack_T.
-enum {
- CSL_HAD_LOOP = 1, // just found ":while" or ":for"
- CSL_HAD_ENDLOOP = 2, // just found ":endwhile" or ":endfor"
- CSL_HAD_CONT = 4, // just found ":continue"
- CSL_HAD_FINA = 8, // just found ":finally"
-};
-
/// Arguments used for Ex commands.
struct exarg {
char *arg; ///< argument of the command
@@ -222,41 +182,6 @@ struct exarg {
#define EXFLAG_NR 0x02 // '#': number
#define EXFLAG_PRINT 0x04 // 'p': print
-typedef enum {
- XP_PREFIX_NONE, ///< prefix not used
- XP_PREFIX_NO, ///< "no" prefix for bool option
- XP_PREFIX_INV, ///< "inv" prefix for bool option
-} xp_prefix_T;
-
-// used for completion on the command line
-struct expand {
- char *xp_pattern; // start of item to expand
- int xp_context; // type of expansion
- size_t xp_pattern_len; // bytes in xp_pattern before cursor
- xp_prefix_T xp_prefix;
- char *xp_arg; // completion function
- LuaRef xp_luaref; // Ref to Lua completion function
- sctx_T xp_script_ctx; // SCTX for completion function
- int xp_backslash; // one of the XP_BS_ values
-#ifndef BACKSLASH_IN_FILENAME
- int xp_shell; // true for a shell command, more
- // characters need to be escaped
-#endif
- int xp_numfiles; // number of files found by file name completion
- int xp_col; // cursor position in line
- int xp_selected; // selected index in completion
- char *xp_orig; // originally expanded string
- char **xp_files; // list of files
- char *xp_line; // text being completed
-#define EXPAND_BUF_LEN 256
- char xp_buf[EXPAND_BUF_LEN]; // buffer for returned match
-};
-
-// values for xp_backslash
-#define XP_BS_NONE 0 // nothing special for backslashes
-#define XP_BS_ONE 1 // uses one backslash before a space
-#define XP_BS_THREE 2 // uses three backslashes before a space
-
enum {
CMOD_SANDBOX = 0x0001, ///< ":sandbox"
CMOD_SILENT = 0x0002, ///< ":silent"
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 02783e032b..eb89e0fc9d 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -22,6 +22,7 @@
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/debugger.h"
#include "nvim/digraph.h"
@@ -1629,7 +1630,7 @@ static int execute_cmd0(int *retv, exarg_T *eap, const char **errormsg, bool pre
// Call the function to execute the builtin command or the preview callback.
eap->errmsg = NULL;
if (preview) {
- *retv = (cmdnames[eap->cmdidx].cmd_preview_func)(eap, cmdpreview_get_ns(),
+ *retv = (cmdnames[eap->cmdidx].cmd_preview_func)(eap, (int)cmdpreview_get_ns(),
cmdpreview_get_bufnr());
} else {
(cmdnames[eap->cmdidx].cmd_func)(eap);
@@ -5910,7 +5911,7 @@ static void ex_submagic(exarg_T *eap)
}
/// ":smagic" and ":snomagic" preview callback.
-static int ex_submagic_preview(exarg_T *eap, long cmdpreview_ns, handle_T cmdpreview_bufnr)
+static int ex_submagic_preview(exarg_T *eap, int cmdpreview_ns, handle_T cmdpreview_bufnr)
{
const optmagic_T saved = magic_overruled;
@@ -6043,7 +6044,7 @@ static void ex_redo(exarg_T *eap)
/// ":earlier" and ":later".
static void ex_later(exarg_T *eap)
{
- long count = 0;
+ int count = 0;
bool sec = false;
bool file = false;
char *p = eap->arg;
@@ -6051,7 +6052,7 @@ static void ex_later(exarg_T *eap)
if (*p == NUL) {
count = 1;
} else if (isdigit((uint8_t)(*p))) {
- count = getdigits_long(&p, false, 0);
+ count = getdigits_int(&p, false, 0);
switch (*p) {
case 's':
p++; sec = true; break;
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index 0fd14c81d3..59f45fce88 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/getchar_defs.h"
#include "nvim/globals.h"
diff --git a/src/nvim/ex_eval_defs.h b/src/nvim/ex_eval_defs.h
index 3ad3368900..6713cdb549 100644
--- a/src/nvim/ex_eval_defs.h
+++ b/src/nvim/ex_eval_defs.h
@@ -5,6 +5,37 @@
#include "nvim/pos.h"
+/// A list used for saving values of "emsg_silent". Used by ex_try() to save the
+/// value of "emsg_silent" if it was non-zero. When this is done, the CSF_SILENT
+/// flag below is set.
+typedef struct eslist_elem eslist_T;
+struct eslist_elem {
+ int saved_emsg_silent; ///< saved value of "emsg_silent"
+ eslist_T *next; ///< next element on the list
+};
+
+/// For conditional commands a stack is kept of nested conditionals.
+/// When cs_idx < 0, there is no conditional command.
+enum { CSTACK_LEN = 50, };
+
+typedef struct {
+ int cs_flags[CSTACK_LEN]; ///< CSF_ flags
+ char cs_pending[CSTACK_LEN]; ///< CSTP_: what's pending in ":finally"
+ union {
+ void *csp_rv[CSTACK_LEN]; ///< return typeval for pending return
+ void *csp_ex[CSTACK_LEN]; ///< exception for pending throw
+ } cs_pend;
+ void *cs_forinfo[CSTACK_LEN]; ///< info used by ":for"
+ int cs_line[CSTACK_LEN]; ///< line nr of ":while"/":for" line
+ int cs_idx; ///< current entry, or -1 if none
+ int cs_looplevel; ///< nr of nested ":while"s and ":for"s
+ int cs_trylevel; ///< nr of nested ":try"s
+ eslist_T *cs_emsg_silent_list; ///< saved values of "emsg_silent"
+ int cs_lflags; ///< loop flags: CSL_ flags
+} cstack_T;
+#define cs_rettv cs_pend.csp_rv
+#define cs_exception cs_pend.csp_ex
+
/// There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if"
/// was used.
enum {
@@ -37,6 +68,14 @@ enum {
CSTP_FINISH = 32, ///< ":finish" is pending
};
+/// Flags for the cs_lflags item in cstack_T.
+enum {
+ CSL_HAD_LOOP = 1, ///< just found ":while" or ":for"
+ CSL_HAD_ENDLOOP = 2, ///< just found ":endwhile" or ":endfor"
+ CSL_HAD_CONT = 4, ///< just found ":continue"
+ CSL_HAD_FINA = 8, ///< just found ":finally"
+};
+
/// A list of error messages that can be converted to an exception. "throw_msg"
/// is only set in the first element of the list. Usually, it points to the
/// original message stored in that element, but sometimes it points to a later
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 6fa607d569..2a1dffacb7 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -71,6 +71,7 @@
#include "nvim/search.h"
#include "nvim/state.h"
#include "nvim/strings.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/usercmd.h"
@@ -141,11 +142,11 @@ typedef struct cmdpreview_undo_info {
u_header_T *save_b_u_curhead;
int save_b_u_numhead;
bool save_b_u_synced;
- long save_b_u_seq_last;
- long save_b_u_save_nr_last;
- long save_b_u_seq_cur;
+ int save_b_u_seq_last;
+ int save_b_u_save_nr_last;
+ int save_b_u_seq_cur;
time_t save_b_u_time_cur;
- long save_b_u_save_nr_cur;
+ int save_b_u_save_nr_cur;
char *save_b_u_line_ptr;
linenr_T save_b_u_line_lnum;
colnr_T save_b_u_line_colnr;
@@ -206,7 +207,7 @@ static int cedit_key = -1; ///< key value of 'cedit' option
#endif
static handle_T cmdpreview_bufnr = 0;
-static long cmdpreview_ns = 0;
+static int cmdpreview_ns = 0;
static void save_viewstate(win_T *wp, viewstate_T *vs)
FUNC_ATTR_NONNULL_ALL
@@ -1328,7 +1329,7 @@ static int command_line_execute(VimState *state, int key)
if (!cmd_silent) {
if (!ui_has(kUICmdline)) {
- cmd_cursor_goto(msg_row, 0);
+ msg_cursor_goto(msg_row, 0);
}
ui_flush();
}
@@ -2766,6 +2767,7 @@ int check_opt_wim(void)
}
for (char *p = p_wim; *p; p++) {
+ // Note: Keep this in sync with p_wim_values.
for (i = 0; ASCII_ISALPHA(p[i]); i++) {}
if (p[i] != NUL && p[i] != ',' && p[i] != ':') {
return FAIL;
@@ -3882,7 +3884,7 @@ void redrawcmd(void)
// when 'incsearch' is set there may be no command line while redrawing
if (ccline.cmdbuff == NULL) {
- cmd_cursor_goto(cmdline_row, 0);
+ msg_cursor_goto(cmdline_row, 0);
msg_clr_eos();
return;
}
@@ -3959,14 +3961,7 @@ void cursorcmd(void)
}
}
- cmd_cursor_goto(msg_row, msg_col);
-}
-
-static void cmd_cursor_goto(int row, int col)
-{
- ScreenGrid *grid = &msg_grid_adj;
- grid_adjust(&grid, &row, &col);
- ui_grid_cursor_goto(grid->handle, row, col);
+ msg_cursor_goto(msg_row, msg_col);
}
void gotocmdline(bool clr)
@@ -3983,7 +3978,7 @@ void gotocmdline(bool clr)
if (clr) { // clear the bottom line(s)
msg_clr_eos(); // will reset clear_cmdline
}
- cmd_cursor_goto(cmdline_row, 0);
+ msg_cursor_goto(cmdline_row, 0);
}
// Check the word in front of the cursor for an abbreviation.
diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h
index aaafedcb4b..61bbd5b9e1 100644
--- a/src/nvim/ex_getln.h
+++ b/src/nvim/ex_getln.h
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include "klib/kvec.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/option_defs.h"
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 4e8b7be4aa..05b48966ff 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -28,7 +28,7 @@
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
-#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_eval.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
@@ -1753,7 +1753,7 @@ failed:
c = true;
}
- msg_add_lines(c, (long)linecnt, filesize);
+ msg_add_lines(c, linecnt, filesize);
XFREE_CLEAR(keep_msg);
p = NULL;
@@ -2156,7 +2156,7 @@ bool msg_add_fileformat(int eol_type)
}
/// Append line and character count to IObuff.
-void msg_add_lines(int insert_space, long lnum, off_T nchars)
+void msg_add_lines(int insert_space, linenr_T lnum, off_T nchars)
{
char *p = IObuff + strlen(IObuff);
@@ -2700,7 +2700,7 @@ int vim_rename(const char *from, const char *to)
}
// Rename() failed, try copying the file.
- long perm = os_getperm(from);
+ int perm = os_getperm(from);
// For systems that support ACL: get the ACL from the original file.
vim_acl_T acl = os_get_acl(from);
int fd_in = os_open(from, O_RDONLY, 0);
@@ -2710,7 +2710,7 @@ int vim_rename(const char *from, const char *to)
}
// Create the new file with same permissions as the original.
- int fd_out = os_open(to, O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)perm);
+ int fd_out = os_open(to, O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, perm);
if (fd_out < 0) {
close(fd_in);
os_free_acl(acl);
@@ -2905,7 +2905,7 @@ int buf_check_timestamp(buf_T *buf)
&& (!(file_info_ok = os_fileinfo(buf->b_ffname, &file_info))
|| time_differs(&file_info, buf->b_mtime, buf->b_mtime_ns)
|| (int)file_info.stat.st_mode != buf->b_orig_mode)) {
- const long prev_b_mtime = buf->b_mtime;
+ const int prev_b_mtime = (int)buf->b_mtime;
retval = 1;
diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h
index 5eb2689233..92ea866239 100644
--- a/src/nvim/fileio.h
+++ b/src/nvim/fileio.h
@@ -3,7 +3,10 @@
#include "nvim/buffer_defs.h"
#include "nvim/eval/typval_defs.h"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/garray.h"
+#include "nvim/globals.h"
+#include "nvim/os/fs_defs.h"
#include "nvim/os/os.h"
// Values for readfile() flags
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
index b9fae7d0fe..61767583ec 100644
--- a/src/nvim/generators/gen_ex_cmds.lua
+++ b/src/nvim/generators/gen_ex_cmds.lua
@@ -102,7 +102,7 @@ for _, cmd in ipairs(defs) do
end
local preview_func
if cmd.preview_func then
- preview_func = string.format("(ex_preview_func_T)&%s", cmd.preview_func)
+ preview_func = string.format("&%s", cmd.preview_func)
else
preview_func = "NULL"
end
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua
index 0932a1357f..05def71caa 100644
--- a/src/nvim/generators/gen_options.lua
+++ b/src/nvim/generators/gen_options.lua
@@ -35,6 +35,8 @@ local redraw_flags={
local list_flags={
comma='P_COMMA',
onecomma='P_ONECOMMA',
+ commacolon='P_COMMA|P_COLON',
+ onecommacolon='P_ONECOMMA|P_COLON',
flags='P_FLAGLIST',
flagscomma='P_COMMA|P_FLAGLIST',
}
@@ -166,6 +168,9 @@ local function dump_option(i, o)
if o.cb then
w(' .opt_did_set_cb=' .. o.cb)
end
+ if o.expand_cb then
+ w(' .opt_expand_cb=' .. o.expand_cb)
+ end
if o.enable_if then
w('#else')
w(' .var=NULL')
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index b696f8ab37..7c5d39bd70 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -291,10 +291,10 @@ static void delete_buff_tail(buffheader_T *buf, int slen)
}
/// Add number "n" to buffer "buf".
-static void add_num_buff(buffheader_T *buf, long n)
+static void add_num_buff(buffheader_T *buf, int n)
{
char number[32];
- snprintf(number, sizeof(number), "%ld", n);
+ snprintf(number, sizeof(number), "%d", n);
add_buff(buf, number, -1L);
}
@@ -589,7 +589,7 @@ void AppendCharToRedobuff(int c)
}
// Append a number to the redo buffer.
-void AppendNumberToRedobuff(long n)
+void AppendNumberToRedobuff(int n)
{
if (!block_redo) {
add_num_buff(&redobuff, n);
@@ -643,7 +643,7 @@ void stuffcharReadbuff(int c)
}
// Append a number to the stuff buffer.
-void stuffnumReadbuff(long n)
+void stuffnumReadbuff(int n)
{
add_num_buff(&readbuf1, n);
}
@@ -753,7 +753,7 @@ static void copy_redo(bool old_redo)
/// CTRL-O <.> in insert mode
///
/// @return FAIL for failure, OK otherwise
-int start_redo(long count, bool old_redo)
+int start_redo(int count, bool old_redo)
{
// init the pointers; return if nothing to redo
if (read_redo(true, old_redo) == FAIL) {
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 1a7a62174d..d462c83710 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -832,7 +832,7 @@ EXTERN char no_lines_msg[] INIT(= N_("--No lines in buffer--"));
// When ":global" is used to number of substitutions and changed lines is
// accumulated until it's finished.
// Also used for ":spellrepall".
-EXTERN long sub_nsubs; // total number of substitutions
+EXTERN int sub_nsubs; // total number of substitutions
EXTERN linenr_T sub_nlines; // total number of lines changed
// table to store parsed 'wildmode'
diff --git a/src/nvim/grid.c b/src/nvim/grid.c
index 712688368b..7a707407d2 100644
--- a/src/nvim/grid.c
+++ b/src/nvim/grid.c
@@ -455,6 +455,22 @@ void grid_line_flush(void)
false, 0, false, invalid_row);
}
+/// flush grid line but only if on a valid row
+///
+/// This is a stopgap until message.c has been refactored to behave
+void grid_line_flush_if_valid_row(void)
+{
+ if (grid_line_row < 0 || grid_line_row >= grid_line_grid->rows) {
+ if (rdb_flags & RDB_INVALID) {
+ abort();
+ } else {
+ grid_line_grid = NULL;
+ return;
+ }
+ }
+ grid_line_flush();
+}
+
/// Fill the grid from "start_row" to "end_row" (exclusive), from "start_col"
/// to "end_col" (exclusive) with character "c1" in first column followed by
/// "c2" in the other columns. Use attributes "attr".
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index 09a28989e4..5cbff6e3dd 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -18,13 +18,13 @@
#include "nvim/ascii.h"
#include "nvim/autocmd.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor_shape.h"
#include "nvim/decoration_provider.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/eval/vars.h"
-#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/garray.h"
#include "nvim/gettext.h"
@@ -2291,10 +2291,10 @@ static void highlight_list_two(int cnt, int attr)
}
/// Function given to ExpandGeneric() to obtain the list of group names.
-const char *get_highlight_name(expand_T *const xp, int idx)
+char *get_highlight_name(expand_T *const xp, int idx)
FUNC_ATTR_WARN_UNUSED_RESULT
{
- return get_highlight_name_ext(xp, idx, true);
+ return (char *)get_highlight_name_ext(xp, idx, true);
}
/// Obtain a highlight group name.
diff --git a/src/nvim/highlight_group.h b/src/nvim/highlight_group.h
index 77a3684067..369864552c 100644
--- a/src/nvim/highlight_group.h
+++ b/src/nvim/highlight_group.h
@@ -3,6 +3,7 @@
#include "nvim/api/keysets.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/highlight_defs.h"
#include "nvim/types.h"
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index b7bc23cda5..d19164b24f 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -55,7 +55,7 @@
/// @return false for an error.
bool tabstop_set(char *var, colnr_T **array)
{
- long valcount = 1;
+ int valcount = 1;
int t;
char *cp;
@@ -89,7 +89,7 @@ bool tabstop_set(char *var, colnr_T **array)
return false;
}
- *array = (colnr_T *)xmalloc((unsigned)(valcount + 1) * sizeof(long));
+ *array = (colnr_T *)xmalloc((unsigned)(valcount + 1) * sizeof(int));
(*array)[0] = (colnr_T)valcount;
t = 1;
@@ -122,13 +122,13 @@ int tabstop_padding(colnr_T col, OptInt ts_arg, const colnr_T *vts)
OptInt ts = ts_arg == 0 ? 8 : ts_arg;
colnr_T tabcol = 0;
int t;
- long padding = 0;
+ int padding = 0;
if (vts == NULL || vts[0] == 0) {
return (int)(ts - (col % ts));
}
- const long tabcount = vts[0];
+ const int tabcount = vts[0];
for (t = 1; t <= tabcount; t++) {
tabcol += vts[t];
@@ -141,7 +141,7 @@ int tabstop_padding(colnr_T col, OptInt ts_arg, const colnr_T *vts)
padding = vts[tabcount] - ((col - tabcol) % vts[tabcount]);
}
- return (int)padding;
+ return padding;
}
/// Find the size of the tab that covers a particular column.
@@ -149,13 +149,13 @@ int tabstop_at(colnr_T col, OptInt ts, const colnr_T *vts)
{
colnr_T tabcol = 0;
int t;
- long tab_size = 0;
+ int tab_size = 0;
if (vts == NULL || vts[0] == 0) {
return (int)ts;
}
- const long tabcount = vts[0];
+ const int tabcount = vts[0];
for (t = 1; t <= tabcount; t++) {
tabcol += vts[t];
if (tabcol > col) {
@@ -167,20 +167,20 @@ int tabstop_at(colnr_T col, OptInt ts, const colnr_T *vts)
tab_size = vts[tabcount];
}
- return (int)tab_size;
+ return tab_size;
}
/// Find the column on which a tab starts.
-colnr_T tabstop_start(colnr_T col, long ts, colnr_T *vts)
+colnr_T tabstop_start(colnr_T col, int ts, colnr_T *vts)
{
colnr_T tabcol = 0;
int t;
if (vts == NULL || vts[0] == 0) {
- return (int)((col / ts) * ts);
+ return ((col / ts) * ts);
}
- const long tabcount = vts[0];
+ const int tabcount = vts[0];
for (t = 1; t <= tabcount; t++) {
tabcol += vts[t];
if (tabcol > col) {
@@ -194,26 +194,26 @@ colnr_T tabstop_start(colnr_T col, long ts, colnr_T *vts)
/// Find the number of tabs and spaces necessary to get from one column
/// to another.
-void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, const colnr_T *vts, int *ntabs,
+void tabstop_fromto(colnr_T start_col, colnr_T end_col, int ts_arg, const colnr_T *vts, int *ntabs,
int *nspcs)
{
int spaces = end_col - start_col;
colnr_T tabcol = 0;
- long padding = 0;
+ int padding = 0;
int t;
- long ts = ts_arg == 0 ? (long)curbuf->b_p_ts : ts_arg;
+ int ts = ts_arg == 0 ? (int)curbuf->b_p_ts : ts_arg;
assert(ts != 0); // suppress clang "Division by zero"
if (vts == NULL || vts[0] == 0) {
int tabs = 0;
- const int initspc = (int)(ts - (start_col % ts));
+ const int initspc = (ts - (start_col % ts));
if (spaces >= initspc) {
spaces -= initspc;
tabs++;
}
- tabs += (int)(spaces / ts);
- spaces -= (int)((spaces / ts) * ts);
+ tabs += (spaces / ts);
+ spaces -= ((spaces / ts) * ts);
*ntabs = tabs;
*nspcs = spaces;
@@ -221,7 +221,7 @@ void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, const colnr
}
// Find the padding needed to reach the next tabstop.
- const long tabcount = vts[0];
+ const int tabcount = vts[0];
for (t = 1; t <= tabcount; t++) {
tabcol += vts[t];
if (tabcol > start_col) {
@@ -241,7 +241,7 @@ void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, const colnr
}
*ntabs = 1;
- spaces -= (int)padding;
+ spaces -= padding;
// At least one tab has been used. See if any more will fit.
while (spaces != 0 && ++t <= tabcount) {
@@ -251,7 +251,7 @@ void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, const colnr
return;
}
*ntabs += 1;
- spaces -= (int)padding;
+ spaces -= padding;
}
*ntabs += spaces / (int)vts[tabcount];
@@ -283,21 +283,21 @@ bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2)
}
/// Copy a tabstop array, allocating space for the new array.
-int *tabstop_copy(const long *oldts)
+int *tabstop_copy(const int *oldts)
{
- long *newts;
+ int *newts;
int t;
if (oldts == 0) {
return 0;
}
- newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(long));
+ newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(int));
for (t = 0; t <= oldts[0]; t++) {
newts[t] = oldts[t];
}
- return (int *)newts;
+ return newts;
}
/// Return a count of the number of tabstops.
@@ -316,25 +316,23 @@ int tabstop_first(colnr_T *ts)
/// 'tabstop' value when 'shiftwidth' is zero.
int get_sw_value(buf_T *buf)
{
- long result = get_sw_value_col(buf, 0);
- assert(result >= 0 && result <= INT_MAX);
- return (int)result;
+ int result = get_sw_value_col(buf, 0);
+ return result;
}
/// Idem, using "pos".
-long get_sw_value_pos(buf_T *buf, pos_T *pos)
+int get_sw_value_pos(buf_T *buf, pos_T *pos)
{
pos_T save_cursor = curwin->w_cursor;
- long sw_value;
curwin->w_cursor = *pos;
- sw_value = get_sw_value_col(buf, get_nolist_virtcol());
+ int sw_value = get_sw_value_col(buf, get_nolist_virtcol());
curwin->w_cursor = save_cursor;
return sw_value;
}
/// Idem, using the first non-black in the current line.
-long get_sw_value_indent(buf_T *buf)
+int get_sw_value_indent(buf_T *buf)
{
pos_T pos = curwin->w_cursor;
@@ -343,9 +341,9 @@ long get_sw_value_indent(buf_T *buf)
}
/// Idem, using virtual column "col".
-long get_sw_value_col(buf_T *buf, colnr_T col)
+int get_sw_value_col(buf_T *buf, colnr_T col)
{
- return buf->b_p_sw ? (long)buf->b_p_sw
+ return buf->b_p_sw ? (int)buf->b_p_sw
: tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array);
}
@@ -760,6 +758,7 @@ bool briopt_check(win_T *wp)
char *p = wp->w_p_briopt;
while (*p != NUL) {
+ // Note: Keep this in sync with p_briopt_values
if (strncmp(p, "shift:", 6) == 0
&& ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6]))) {
p += 6;
@@ -939,12 +938,12 @@ void ex_retab(exarg_T *eap)
{
linenr_T lnum;
bool got_tab = false;
- long num_spaces = 0;
- long num_tabs;
- long len;
- long start_col = 0; // For start of white-space string
- long start_vcol = 0; // For start of white-space string
- long old_len;
+ int num_spaces = 0;
+ int num_tabs;
+ int len;
+ int start_col = 0; // For start of white-space string
+ int64_t start_vcol = 0; // For start of white-space string
+ int old_len;
char *new_line = (char *)1; // init to non-NULL
colnr_T *new_vts_array = NULL;
char *new_ts_str; // string value of tab argument
@@ -975,8 +974,8 @@ void ex_retab(exarg_T *eap)
}
for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) {
char *ptr = ml_get(lnum);
- long col = 0;
- long vcol = 0;
+ int col = 0;
+ int64_t vcol = 0;
bool did_undo = false; // called u_save for current line
while (true) {
if (ascii_iswhite(ptr[col])) {
@@ -995,13 +994,13 @@ void ex_retab(exarg_T *eap)
// Retabulate this string of white-space
// len is virtual length of white string
- len = num_spaces = vcol - start_vcol;
+ len = num_spaces = (int)(vcol - start_vcol);
num_tabs = 0;
if (!curbuf->b_p_et) {
int t, s;
tabstop_fromto((colnr_T)start_vcol, (colnr_T)vcol,
- (long)curbuf->b_p_ts, new_vts_array, &t, &s);
+ (int)curbuf->b_p_ts, new_vts_array, &t, &s);
num_tabs = t;
num_spaces = s;
}
@@ -1018,7 +1017,7 @@ void ex_retab(exarg_T *eap)
// len is actual number of white characters used
len = num_spaces + num_tabs;
- old_len = (long)strlen(ptr);
+ old_len = (int)strlen(ptr);
const long new_len = old_len - col + start_col + len + 1;
if (new_len <= 0 || new_len >= MAXCOL) {
emsg_text_too_long();
@@ -1030,7 +1029,7 @@ void ex_retab(exarg_T *eap)
memmove(new_line, ptr, (size_t)start_col);
}
memmove(new_line + start_col + len,
- ptr + col, (size_t)(old_len - col + 1));
+ ptr + col, (size_t)old_len - (size_t)col + 1);
ptr = new_line + start_col;
for (col = 0; col < len; col++) {
ptr[col] = (col < num_tabs) ? '\t' : ' ';
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 4a6c819015..3ada39c800 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -24,7 +24,6 @@
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 18da7af416..d6fd14cc10 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -20,6 +20,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/change.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
index b132a0d147..f3e2b6d1d0 100644
--- a/src/nvim/lua/executor.h
+++ b/src/nvim/lua/executor.h
@@ -8,6 +8,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/assert.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/func_attr.h"
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index 1fb91d85b4..2cfa264754 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -21,6 +21,7 @@
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
diff --git a/src/nvim/mapping.h b/src/nvim/mapping.h
index 405234dbd5..860bbad272 100644
--- a/src/nvim/mapping.h
+++ b/src/nvim/mapping.h
@@ -7,6 +7,7 @@
#include "nvim/api/keysets.h"
#include "nvim/api/private/defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/mapping_defs.h"
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 7b7c822b3b..a3cd569846 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -43,6 +43,7 @@
#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/drawscreen.h"
#include "nvim/eval/typval.h"
@@ -77,8 +78,8 @@ typedef struct {
} convertStruct;
struct interval {
- long first;
- long last;
+ int first;
+ int last;
};
// uncrustify:off
@@ -2830,3 +2831,14 @@ void f_charclass(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
}
rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string);
}
+
+/// Function given to ExpandGeneric() to obtain the possible arguments of the
+/// encoding options.
+char *get_encoding_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ if (idx >= (int)ARRAY_SIZE(enc_canon_table)) {
+ return NULL;
+ }
+
+ return (char *)enc_canon_table[idx].name;
+}
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index 724a16014d..01a7d0d6ae 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <string.h>
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/func_attr.h"
#include "nvim/mbyte_defs.h"
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 7bfa6db4ef..716d05e27a 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -168,17 +168,15 @@ enum {
B0_MAGIC_CHAR = 0x55,
};
-// Block zero holds all info about the swap file. This is the first block in
-// the file.
+// Block zero holds all info about the swapfile. This is the first block in the file.
//
-// NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing
-// swap files unusable!
+// NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing swapfiles unusable!
//
// If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!!
//
// This block is built up of single bytes, to make it portable across
// different machines. b0_magic_* is used to check the byte order and size of
-// variables, because the rest of the swap file is not portable.
+// variables, because the rest of the swapfile is not portable.
typedef struct {
char b0_id[2]; ///< ID for block 0: BLOCK0_ID0 and BLOCK0_ID1.
char b0_version[10]; // Vim version string
@@ -210,8 +208,7 @@ typedef struct {
// EOL_MAC + 1.
#define B0_FF_MASK 3
-// Swap file is in directory of edited file. Used to find the file from
-// different mount points.
+// Swapfile is in directory of edited file. Used to find the file from different mount points.
#define B0_SAME_DIR 4
// The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
@@ -289,14 +286,14 @@ int ml_open(buf_T *buf)
buf->b_p_swf = false;
}
- // When 'updatecount' is non-zero swap file may be opened later.
+ // When 'updatecount' is non-zero swapfile may be opened later.
if (!buf->terminal && p_uc && buf->b_p_swf) {
buf->b_may_swap = true;
} else {
buf->b_may_swap = false;
}
- // Open the memfile. No swap file is created yet.
+ // Open the memfile. No swapfile is created yet.
memfile_T *mfp = mf_open(NULL, 0);
if (mfp == NULL) {
goto error;
@@ -335,7 +332,7 @@ int ml_open(buf_T *buf)
}
// Always sync block number 0 to disk, so we can check the file name in
- // the swap file in findswapname(). Don't do this for a help files or
+ // the swapfile in findswapname(). Don't do this for a help files or
// a spell buffer though.
// Only works when there's a swapfile, otherwise it's done when the file
// is created.
@@ -386,17 +383,17 @@ error:
}
/// ml_setname() is called when the file name of "buf" has been changed.
-/// It may rename the swap file.
+/// It may rename the swapfile.
void ml_setname(buf_T *buf)
{
bool success = false;
memfile_T *mfp = buf->b_ml.ml_mfp;
- if (mfp->mf_fd < 0) { // there is no swap file yet
- // When 'updatecount' is 0 and 'noswapfile' there is no swap file.
- // For help files we will make a swap file now.
+ if (mfp->mf_fd < 0) { // there is no swapfile yet
+ // When 'updatecount' is 0 and 'noswapfile' there is no swapfile.
+ // For help files we will make a swapfile now.
if (p_uc != 0 && (cmdmod.cmod_flags & CMOD_NOSWAPFILE) == 0) {
- ml_open_file(buf); // create a swap file
+ ml_open_file(buf); // create a swapfile
}
return;
}
@@ -423,13 +420,13 @@ void ml_setname(buf_T *buf)
success = true;
break;
}
- // need to close the swap file before renaming
+ // need to close the swapfile before renaming
if (mfp->mf_fd >= 0) {
close(mfp->mf_fd);
mfp->mf_fd = -1;
}
- // try to rename the swap file
+ // try to rename the swapfile
if (vim_rename(mfp->mf_fname, fname) == 0) {
success = true;
mf_free_fnames(mfp);
@@ -440,10 +437,10 @@ void ml_setname(buf_T *buf)
xfree(fname); // this fname didn't work, try another
}
- if (mfp->mf_fd == -1) { // need to (re)open the swap file
+ if (mfp->mf_fd == -1) { // need to (re)open the swapfile
mfp->mf_fd = os_open(mfp->mf_fname, O_RDWR, 0);
if (mfp->mf_fd < 0) {
- // could not (re)open the swap file, what can we do????
+ // could not (re)open the swapfile, what can we do????
emsg(_("E301: Oops, lost the swap file!!!"));
return;
}
@@ -466,7 +463,7 @@ void ml_open_files(void)
}
}
-/// Open a swap file for an existing memfile, if there is no swap file yet.
+/// Open a swapfile for an existing memfile, if there is no swapfile yet.
/// If we are unable to find a file name, mf_fname will be NULL
/// and the memfile will be in memory only (no recovery possible).
void ml_open_file(buf_T *buf)
@@ -495,7 +492,7 @@ void ml_open_file(buf_T *buf)
if (*dirp == NUL) {
break;
}
- // There is a small chance that between choosing the swap file name
+ // There is a small chance that between choosing the swapfile name
// and creating it, another Vim creates the file. In that case the
// creation will fail and we will use another directory.
char *fname = findswapname(buf, &dirp, NULL, &found_existing_dir);
@@ -514,7 +511,7 @@ void ml_open_file(buf_T *buf)
if (mf_sync(mfp, MFS_ZERO) == OK) {
// Mark all blocks that should be in the swapfile as dirty.
// Needed for when the 'swapfile' option was reset, so that
- // the swap file was deleted, and then on again.
+ // the swapfile was deleted, and then on again.
mf_set_dirty(mfp);
break;
}
@@ -531,12 +528,12 @@ void ml_open_file(buf_T *buf)
no_wait_return--;
}
- // don't try to open a swap file again
+ // don't try to open a swapfile again
buf->b_may_swap = false;
}
-/// If still need to create a swap file, and starting to edit a not-readonly
-/// file, or reading into an existing buffer, create a swap file now.
+/// If still need to create a swapfile, and starting to edit a not-readonly
+/// file, or reading into an existing buffer, create a swapfile now.
///
/// @param newfile reading file into new buffer
void check_need_swap(bool newfile)
@@ -553,7 +550,7 @@ void check_need_swap(bool newfile)
/// Close memline for buffer 'buf'.
///
-/// @param del_file if true, delete the swap file
+/// @param del_file if true, delete the swapfile
void ml_close(buf_T *buf, int del_file)
{
if (buf->b_ml.ml_mfp == NULL) { // not open
@@ -643,7 +640,7 @@ static void ml_upd_block0(buf_T *buf, upd_block0_T what)
mf_put(mfp, hp, true, false);
}
-/// Write file name and timestamp into block 0 of a swap file.
+/// Write file name and timestamp into block 0 of a swapfile.
/// Also set buf->b_mtime.
/// Don't use NameBuff[]!!!
static void set_b0_fname(ZeroBlock *b0p, buf_T *buf)
@@ -695,7 +692,7 @@ static void set_b0_fname(ZeroBlock *b0p, buf_T *buf)
add_b0_fenc(b0p, curbuf);
}
-/// Update the B0_SAME_DIR flag of the swap file. It's set if the file and the
+/// Update the B0_SAME_DIR flag of the swapfile. It's set if the file and the
/// swapfile for "buf" are in the same directory.
/// This is fail safe: if we are not sure the directories are equal the flag is
/// not set.
@@ -724,27 +721,30 @@ static void add_b0_fenc(ZeroBlock *b0p, buf_T *buf)
}
}
-/// Return true if the process with number "b0p->b0_pid" is still running.
-/// "swap_fname" is the name of the swap file, if it's from before a reboot then
-/// the result is false;
-static bool swapfile_process_running(const ZeroBlock *b0p, const char *swap_fname)
+/// Returns the PID of the process that owns the swapfile, if it is running.
+///
+/// @param b0p swapfile data
+/// @param swap_fname Name of the swapfile. If it's from before a reboot, the result is 0.
+///
+/// @return PID, or 0 if process is not running or the swapfile is from before a reboot.
+static int swapfile_process_running(const ZeroBlock *b0p, const char *swap_fname)
{
FileInfo st;
double uptime;
- // If the system rebooted after when the swap file was written then the
+ // If the system rebooted after when the swapfile was written then the
// process can't be running now.
if (os_fileinfo(swap_fname, &st)
&& uv_uptime(&uptime) == 0
&& (Timestamp)st.stat.st_mtim.tv_sec < os_time() - (Timestamp)uptime) {
- return false;
+ return 0;
}
- return os_proc_running((int)char_to_long(b0p->b0_pid));
+ int pid = (int)char_to_long(b0p->b0_pid);
+ return os_proc_running(pid) ? pid : 0;
}
/// Try to recover curbuf from the .swp file.
///
-/// @param checkext if true, check the extension and detect whether it is a
-/// swap file.
+/// @param checkext if true, check the extension and detect whether it is a swapfile.
void ml_recover(bool checkext)
{
buf_T *buf = NULL;
@@ -766,8 +766,8 @@ void ml_recover(bool checkext)
int called_from_main = (curbuf->b_ml.ml_mfp == NULL);
int attr = HL_ATTR(HLF_E);
- // If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.
- // Otherwise a search is done to find the swap file(s).
+ // If the file name ends in ".s[a-w][a-z]" we assume this is the swapfile.
+ // Otherwise a search is done to find the swapfile(s).
char *fname = curbuf->b_fname;
if (fname == NULL) { // When there is no file name
fname = "";
@@ -782,17 +782,17 @@ void ml_recover(bool checkext)
} else {
directly = false;
- // count the number of matching swap files
+ // count the number of matching swapfiles
len = recover_names(fname, false, NULL, 0, NULL);
- if (len == 0) { // no swap files found
+ if (len == 0) { // no swapfiles found
semsg(_("E305: No swap file found for %s"), fname);
goto theend;
}
int i;
- if (len == 1) { // one swap file found, use it
+ if (len == 1) { // one swapfile found, use it
i = 1;
- } else { // several swap files found, choose
- // list the names of the swap files
+ } else { // several swapfiles found, choose
+ // list the names of the swapfiles
(void)recover_names(fname, true, NULL, 0, NULL);
msg_putchar('\n');
msg_puts(_("Enter number of swap file to use (0 to quit): "));
@@ -801,7 +801,7 @@ void ml_recover(bool checkext)
goto theend;
}
}
- // get the swap file name that will be used
+ // get the swapfile name that will be used
(void)recover_names(fname, false, NULL, i, &fname_used);
}
if (fname_used == NULL) {
@@ -812,7 +812,7 @@ void ml_recover(bool checkext)
getout(1);
}
- // Allocate a buffer structure for the swap file that is used for recovery.
+ // Allocate a buffer structure for the swapfile that is used for recovery.
// Only the memline in it is really used.
buf = xmalloc(sizeof(buf_T));
@@ -825,7 +825,7 @@ void ml_recover(bool checkext)
buf->b_ml.ml_locked = NULL; // no locked block
buf->b_ml.ml_flags = 0;
- // open the memfile from the old swap file
+ // open the memfile from the old swapfile
p = xstrdup(fname_used); // save "fname_used" for the message:
// mf_open() will consume "fname_used"!
mfp = mf_open(fname_used, O_RDONLY);
@@ -837,7 +837,7 @@ void ml_recover(bool checkext)
buf->b_ml.ml_mfp = mfp;
// The page size set in mf_open() might be different from the page size
- // used in the swap file, we must get it from block 0. But to read block
+ // used in the swapfile, we must get it from block 0. But to read block
// 0 we need a page size. Use the minimal size for block 0 here, it will
// be set to the real value below.
mfp->mf_page_size = MIN_SWAP_PAGE_SIZE;
@@ -910,7 +910,7 @@ void ml_recover(bool checkext)
b0p = hp->bh_data;
}
- // If .swp file name given directly, use name from swap file for buffer.
+ // If .swp file name given directly, use name from swapfile for buffer.
if (directly) {
expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
if (setfname(curbuf, NameBuff, NULL, true) == FAIL) {
@@ -929,7 +929,7 @@ void ml_recover(bool checkext)
smsg(0, _("Original file \"%s\""), NameBuff);
msg_putchar('\n');
- // check date of swap file and original file
+ // check date of swapfile and original file
FileInfo org_file_info;
FileInfo swp_file_info;
long mtime = char_to_long(b0p->b0_mtime);
@@ -968,7 +968,7 @@ void ml_recover(bool checkext)
0, MAXLNUM, NULL, READ_NEW, false);
}
- // Use the 'fileformat' and 'fileencoding' as stored in the swap file.
+ // Use the 'fileformat' and 'fileencoding' as stored in the swapfile.
if (b0_ff != 0) {
set_fileformat(b0_ff - 1, OPT_LOCAL);
}
@@ -1215,7 +1215,7 @@ void ml_recover(bool checkext)
// Warn there could be an active Vim on the same file, the user may
// want to kill it.
msg_puts(_("\nNote: process STILL RUNNING: "));
- msg_outnum(char_to_long(b0p->b0_pid));
+ msg_outnum((int)char_to_long(b0p->b0_pid));
}
msg_puts("\n\n");
cmdline_row = msg_row;
@@ -1231,7 +1231,7 @@ theend:
}
mf_close(mfp, false); // will also xfree(mfp->mf_fname)
}
- if (buf != NULL) { // may be NULL if swap file not found.
+ if (buf != NULL) { // may be NULL if swapfile not found.
xfree(buf->b_ml.ml_stack);
xfree(buf);
}
@@ -1243,20 +1243,20 @@ theend:
}
}
-/// Find the names of swap files in current directory and the directory given
+/// Find the names of swapfiles in current directory and the directory given
/// with the 'directory' option.
///
/// Used to:
-/// - list the swap files for "vim -r"
-/// - count the number of swap files when recovering
-/// - list the swap files when recovering
-/// - list the swap files for swapfilelist()
-/// - find the name of the n'th swap file when recovering
+/// - list the swapfiles for "vim -r"
+/// - count the number of swapfiles when recovering
+/// - list the swapfiles when recovering
+/// - list the swapfiles for swapfilelist()
+/// - find the name of the n'th swapfile when recovering
///
-/// @param fname base for swap file name
-/// @param do_list when true, list the swap file names
+/// @param fname base for swapfile name
+/// @param do_list when true, list the swapfile names
/// @param ret_list when not NULL add file names to it
-/// @param nr when non-zero, return nr'th swap file name
+/// @param nr when non-zero, return nr'th swapfile name
/// @param fname_out result when "nr" > 0
int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fname_out)
{
@@ -1273,7 +1273,7 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
if (fname != NULL) {
#ifdef HAVE_READLINK
- // Expand symlink in the file name, because the swap file is created
+ // Expand symlink in the file name, because the swapfile is created
// with the actual file instead of with the symlink.
if (resolve_symlink(fname, fname_buf) == OK) {
fname_res = fname_buf;
@@ -1342,9 +1342,9 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
num_files = 0;
}
- // When no swap file found, wildcard expansion might have failed (e.g.
+ // When no swapfile found, wildcard expansion might have failed (e.g.
// not able to execute the shell).
- // Try finding a swap file by simply adding ".swp" to the file name.
+ // Try finding a swapfile by simply adding ".swp" to the file name.
if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) {
char *swapname = modname(fname_res, ".swp", true);
if (swapname != NULL) {
@@ -1402,8 +1402,8 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
if (num_files) {
for (int i = 0; i < num_files; i++) {
- // print the swap file name
- msg_outnum((long)++file_count);
+ // print the swapfile name
+ msg_outnum(++file_count);
msg_puts(". ");
msg_puts(path_tail(files[i]));
msg_putchar('\n');
@@ -1456,12 +1456,13 @@ char *make_percent_swname(const char *dir, const char *name)
return d;
}
-static bool process_still_running;
+// PID of swapfile owner, or zero if not running.
+static int process_running;
-/// This is used by the swapinfo() function.
+/// For Vimscript "swapinfo()".
///
/// @return information found in swapfile "fname" in dictionary "d".
-void get_b0_dict(const char *fname, dict_T *d)
+void swapfile_dict(const char *fname, dict_T *d)
{
int fd;
ZeroBlock b0;
@@ -1482,7 +1483,7 @@ void get_b0_dict(const char *fname, dict_T *d)
tv_dict_add_str_len(d, S_LEN("fname"), b0.b0_fname,
B0_FNAME_SIZE_ORG);
- tv_dict_add_nr(d, S_LEN("pid"), char_to_long(b0.b0_pid));
+ tv_dict_add_nr(d, S_LEN("pid"), swapfile_process_running(&b0, fname));
tv_dict_add_nr(d, S_LEN("mtime"), char_to_long(b0.b0_mtime));
tv_dict_add_nr(d, S_LEN("dirty"), b0.b0_dirty ? 1 : 0);
tv_dict_add_nr(d, S_LEN("inode"), char_to_long(b0.b0_ino));
@@ -1496,7 +1497,7 @@ void get_b0_dict(const char *fname, dict_T *d)
}
}
-/// Give information about an existing swap file.
+/// Loads info from swapfile `fname`, and displays it to the user.
///
/// @return timestamp (0 when unknown).
static time_t swapfile_info(char *fname)
@@ -1509,7 +1510,7 @@ static time_t swapfile_info(char *fname)
char uname[B0_UNAME_SIZE];
#endif
- // print the swap file date
+ // print the swapfile date
FileInfo file_info;
if (os_fileinfo(fname, &file_info)) {
#ifdef UNIX
@@ -1566,10 +1567,9 @@ static time_t swapfile_info(char *fname)
if (char_to_long(b0.b0_pid) != 0L) {
msg_puts(_("\n process ID: "));
- msg_outnum(char_to_long(b0.b0_pid));
- if (swapfile_process_running(&b0, fname)) {
+ msg_outnum((int)char_to_long(b0.b0_pid));
+ if ((process_running = swapfile_process_running(&b0, fname))) {
msg_puts(_(" (STILL RUNNING)"));
- process_still_running = true;
}
}
@@ -1589,13 +1589,12 @@ static time_t swapfile_info(char *fname)
return x;
}
-/// @return true if the swap file looks OK and there are no changes, thus it
-/// can be safely deleted.
+/// @return true if the swapfile looks OK and there are no changes, thus it can be safely deleted.
static bool swapfile_unchanged(char *fname)
{
ZeroBlock b0;
- // Swap file must exist.
+ // Swapfile must exist.
if (!os_path_exists(fname)) {
return false;
}
@@ -1653,7 +1652,7 @@ static int recov_file_names(char **names, char *path, int prepend_dot)
{
int num_names = 0;
- // May also add the file name with a dot prepended, for swap file in same
+ // May also add the file name with a dot prepended, for swapfile in same
// dir as original file.
if (prepend_dot) {
names[num_names] = modname(path, ".sw?", true);
@@ -1663,7 +1662,7 @@ static int recov_file_names(char **names, char *path, int prepend_dot)
num_names++;
}
- // Form the normal swap file name pattern by appending ".sw?".
+ // Form the normal swapfile name pattern by appending ".sw?".
names[num_names] = concat_fnames(path, ".sw?", false);
if (num_names >= 1) { // check if we have the same name twice
char *p = names[num_names - 1];
@@ -1724,7 +1723,7 @@ void ml_sync_all(int check_file, int check_char, bool do_fsync)
/// sync one buffer, including negative blocks
///
-/// after this all the blocks are in the swap file
+/// after this all the blocks are in the swapfile
///
/// Used for the :preserve command and when the original file has been
/// changed or deleted.
@@ -3132,7 +3131,7 @@ int resolve_symlink(const char *fname, char *buf)
}
#endif
-/// Make swap file name out of the file name and a directory name.
+/// Make swapfile name out of the file name and a directory name.
///
/// @return pointer to allocated memory or NULL.
char *makeswapname(char *fname, char *ffname, buf_T *buf, char *dir_name)
@@ -3141,7 +3140,7 @@ char *makeswapname(char *fname, char *ffname, buf_T *buf, char *dir_name)
#ifdef HAVE_READLINK
char fname_buf[MAXPATHL];
- // Expand symlink in the file name, so that we put the swap file with the
+ // Expand symlink in the file name, so that we put the swapfile with the
// actual file instead of with the symlink.
if (resolve_symlink(fname, fname_buf) == OK) {
fname_res = fname_buf;
@@ -3162,7 +3161,7 @@ char *makeswapname(char *fname, char *ffname, buf_T *buf, char *dir_name)
return r;
}
- // Prepend a '.' to the swap file name for the current directory.
+ // Prepend a '.' to the swapfile name for the current directory.
char *r = modname(fname_res, ".swp",
dir_name[0] == '.' && dir_name[1] == NUL);
if (r == NULL) { // out of memory
@@ -3174,14 +3173,11 @@ char *makeswapname(char *fname, char *ffname, buf_T *buf, char *dir_name)
return s;
}
-/// Get file name to use for swap file or backup file.
-/// Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
-/// option "dname".
-/// - If "dname" is ".", return "fname" (swap file in dir of file).
-/// - If "dname" starts with "./", insert "dname" in "fname" (swap file
-/// relative to dir of file).
-/// - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
-/// dir).
+/// Get file name to use for swapfile or backup file.
+/// Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir' option "dname".
+/// - If "dname" is ".", return "fname" (swapfile in dir of file).
+/// - If "dname" starts with "./", insert "dname" in "fname" (swapfile relative to dir of file).
+/// - Otherwise, prepend "dname" to the tail of "fname" (swapfile in specific dir).
///
/// The return value is an allocated string and can be NULL.
///
@@ -3212,10 +3208,10 @@ char *get_file_in_dir(char *fname, char *dname)
return retval;
}
-/// Print the ATTENTION message: info about an existing swap file.
+/// Print the ATTENTION message: info about an existing swapfile.
///
/// @param buf buffer being edited
-/// @param fname swap file name
+/// @param fname swapfile name
static void attention_message(buf_T *buf, char *fname)
{
assert(buf->b_fname != NULL);
@@ -3299,7 +3295,7 @@ static int do_swapexists(buf_T *buf, char *fname)
return 0;
}
-/// Find out what name to use for the swap file for buffer 'buf'.
+/// Find out what name to use for the swapfile for buffer 'buf'.
///
/// Several names are tried to find one that does not exist. Last directory in
/// option is automatically created.
@@ -3308,20 +3304,20 @@ static int do_swapexists(buf_T *buf, char *fname)
/// not being able to open the swap or undo file.
/// @note May trigger SwapExists autocmd, pointers may change!
///
-/// @param[in] buf Buffer for which swap file names needs to be found.
+/// @param[in] buf Buffer for which swapfile names needs to be found.
/// @param[in,out] dirp Pointer to a list of directories. When out of memory,
/// is set to NULL. Is advanced to the next directory in
/// the list otherwise.
-/// @param[in] old_fname Allowed existing swap file name. Except for this
+/// @param[in] old_fname Allowed existing swapfile name. Except for this
/// case, name of the non-existing file is used.
/// @param[in,out] found_existing_dir If points to true, then new directory
-/// for swap file is not created. At first
+/// for swapfile is not created. At first
/// findswapname() call this argument must
/// point to false. This parameter may only
/// be set to true by this function, it is
/// never set to false.
///
-/// @return [allocated] Name of the swap file.
+/// @return [allocated] Name of the swapfile.
static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_existing_dir)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 2, 4)
{
@@ -3333,7 +3329,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
char *dir_name = xmalloc(dir_len);
(void)copy_option_part(dirp, dir_name, dir_len, ",");
- // we try different names until we find one that does not exist yet
+ // We try different swapfile names until we find one that does not exist yet.
char *fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name);
while (true) {
@@ -3346,7 +3342,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
break;
}
// check if the swapfile already exists
- // Extra security check: When a swap file is a symbolic link, this
+ // Extra security check: When a swapfile is a symbolic link, this
// is most likely a symlink attack.
FileInfo file_info;
bool file_or_link_found = os_fileinfo_link(fname, &file_info);
@@ -3365,17 +3361,17 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
// Give an error message, unless recovering, no file name, we are
// viewing a help file or when the path of the file is different
// (happens when all .swp files are in one directory).
- if (!recoverymode && buf_fname != NULL
- && !buf->b_help && !(buf->b_flags & BF_DUMMY)) {
+ if (!recoverymode && buf_fname != NULL && !buf->b_help && !(buf->b_flags & BF_DUMMY)) {
int fd;
ZeroBlock b0;
int differ = false;
- // Try to read block 0 from the swap file to get the original
- // file name (and inode number).
+ // Try to read block 0 from the swapfile to get the original file name (and inode number).
fd = os_open(fname, O_RDONLY, 0);
if (fd >= 0) {
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
+ process_running = swapfile_process_running(&b0, fname);
+
// If the swapfile has the same directory as the
// buffer don't compare the directory names, they can
// have a different mountpoint.
@@ -3393,8 +3389,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
}
}
} else {
- // The name in the swap file may be
- // "~user/path/file". Expand it first.
+ // The name in the swapfile may be "~user/path/file". Expand it first.
expand_env(b0.b0_fname, NameBuff, MAXPATHL);
if (fnamecmp_ino(buf->b_ffname, NameBuff,
char_to_long(b0.b0_ino))) {
@@ -3405,16 +3400,16 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
close(fd);
}
- // give the ATTENTION message when there is an old swap file
- // for the current file, and the buffer was not recovered.
+ // Show the ATTENTION message when:
+ // - there is an old swapfile for the current file
+ // - the buffer was not recovered
if (differ == false && !(curbuf->b_flags & BF_RECOVERED)
&& vim_strchr(p_shm, SHM_ATTENTION) == NULL) {
int choice = 0;
- process_still_running = false;
- // It's safe to delete the swap file if all these are true:
+ // It's safe to delete the swapfile if all these are true:
// - the edited file exists
- // - the swap file has no changes and looks OK
+ // - the swapfile has no changes and looks OK
if (os_path_exists(buf->b_fname) && swapfile_unchanged(fname)) {
choice = 4;
if (p_verbose > 0) {
@@ -3430,8 +3425,9 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
choice = do_swapexists(buf, fname);
}
+ process_running = 0; // Set by attention_message..swapfile_info.
if (choice == 0) {
- // Show info about the existing swap file.
+ // Show info about the existing swapfile.
attention_message(buf, fname);
// We don't want a 'q' typed at the more-prompt
@@ -3459,15 +3455,15 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
xstrlcat(name, sw_msg_2, name_len);
choice = do_dialog(VIM_WARNING, _("VIM - ATTENTION"),
name,
- process_still_running
+ process_running
? _("&Open Read-Only\n&Edit anyway\n&Recover"
"\n&Quit\n&Abort") :
_("&Open Read-Only\n&Edit anyway\n&Recover"
"\n&Delete it\n&Quit\n&Abort"),
1, NULL, false);
- if (process_still_running && choice >= 4) {
- choice++; // Skip missing "Delete it" button.
+ if (process_running && choice >= 4) {
+ choice++; // Skip missing "Delete it" button.
}
xfree(name);
@@ -3477,27 +3473,27 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
if (choice > 0) {
switch (choice) {
- case 1:
+ case 1: // "Open Read-Only"
buf->b_p_ro = true;
break;
- case 2:
+ case 2: // "Edit anyway"
break;
- case 3:
+ case 3: // "Recover"
swap_exists_action = SEA_RECOVER;
break;
- case 4:
+ case 4: // "Delete it"
os_remove(fname);
break;
- case 5:
+ case 5: // "Quit"
swap_exists_action = SEA_QUIT;
break;
- case 6:
+ case 6: // "Abort"
swap_exists_action = SEA_QUIT;
got_int = true;
break;
}
- // If the file was deleted this fname can be used.
+ // If the swapfile was deleted this `fname` can be used.
if (!os_path_exists(fname)) {
break;
}
@@ -3512,10 +3508,10 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
}
}
- // Change the ".swp" extension to find another file that can be used.
+ // Permute the ".swp" extension to find a unique swapfile name.
// First decrement the last char: ".swo", ".swn", etc.
// If that still isn't enough decrement the last but one char: ".svz"
- // Can happen when editing many "No Name" buffers.
+ // Can happen when many Nvim instances are editing the same file (including "No Name" buffers).
if (fname[n - 1] == 'a') { // ".s?a"
if (fname[n - 2] == 'a') { // ".saa": tried enough, give up
emsg(_("E326: Too many swap files found"));
@@ -3553,7 +3549,7 @@ static int b0_magic_wrong(ZeroBlock *b0p)
|| b0p->b0_magic_char != B0_MAGIC_CHAR;
}
-/// Compare current file name with file name from swap file.
+/// Compare current file name with file name from swapfile.
/// Try to use inode numbers when possible.
/// Return non-zero when files are different.
///
@@ -3563,7 +3559,7 @@ static int b0_magic_wrong(ZeroBlock *b0p)
/// because the device number cannot be used over a network.
/// - When a file does not exist yet (editing a new file) there is no inode
/// number.
-/// - The file name in a swap file may not be valid on the current host. The
+/// - The file name in a swapfile may not be valid on the current host. The
/// "~user" form is used whenever possible to avoid this.
///
/// This is getting complicated, let's make a table:
@@ -3577,7 +3573,7 @@ static int b0_magic_wrong(ZeroBlock *b0p)
/// == 0 X OK OK fname_c != fname_s
/// X == 0 OK OK fname_c != fname_s
///
-/// current file doesn't exist, file for swap file exist, file name(s) not
+/// current file doesn't exist, file for swapfile exist, file name(s) not
/// available -> probably different
/// == 0 != 0 FAIL X true
/// == 0 != 0 X FAIL true
@@ -3600,11 +3596,11 @@ static int b0_magic_wrong(ZeroBlock *b0p)
/// without making the block 0 incompatible with 32 bit versions.
///
/// @param fname_c current file name
-/// @param fname_s file name from swap file
+/// @param fname_s file name from swapfile
static bool fnamecmp_ino(char *fname_c, char *fname_s, long ino_block0)
{
uint64_t ino_c = 0; // ino of current file
- uint64_t ino_s; // ino of file from swap file
+ uint64_t ino_s; // ino of file from swapfile
char buf_c[MAXPATHL]; // full path of fname_c
char buf_s[MAXPATHL]; // full path of fname_s
int retval_c; // flag: buf_c valid
@@ -3616,7 +3612,7 @@ static bool fnamecmp_ino(char *fname_c, char *fname_s, long ino_block0)
}
// First we try to get the inode from the file name, because the inode in
- // the swap file may be outdated. If that fails (e.g. this path is not
+ // the swapfile may be outdated. If that fails (e.g. this path is not
// valid on this machine), use the inode from block 0.
if (os_fileinfo(fname_s, &file_info)) {
ino_s = os_fileinfo_inode(&file_info);
@@ -3638,7 +3634,7 @@ static bool fnamecmp_ino(char *fname_c, char *fname_s, long ino_block0)
// Can't compare inodes or file names, guess that the files are different,
// unless both appear not to exist at all, then compare with the file name
- // in the swap file.
+ // in the swapfile.
if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL) {
return strcmp(fname_c, fname_s) != 0;
}
@@ -3675,7 +3671,7 @@ static long char_to_long(const char *s_in)
return retval;
}
-/// Set the flags in the first block of the swap file:
+/// Set the flags in the first block of the swapfile:
/// - file is modified or not: buf->b_changed
/// - 'fileformat'
/// - 'fileencoding'
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 2204a0a291..4a72464527 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -12,6 +12,7 @@
#include "nvim/ascii.h"
#include "nvim/autocmd.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
@@ -365,7 +366,7 @@ static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const
menu->en_name = NULL;
menu->en_dname = NULL;
}
- menu->priority = pri_tab[pri_idx];
+ menu->priority = (int)pri_tab[pri_idx];
menu->parent = parent;
// Add after menu that has lower priority.
@@ -658,7 +659,7 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
dict_T *dict = tv_dict_alloc();
tv_dict_add_str(dict, S_LEN("name"), menu->dname);
- tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority);
+ tv_dict_add_nr(dict, S_LEN("priority"), menu->priority);
tv_dict_add_nr(dict, S_LEN("hidden"), menu_is_hidden(menu->dname));
if (menu->mnemonic) {
@@ -1846,7 +1847,7 @@ static void menuitem_getinfo(const char *menu_name, const vimmenu_T *menu, int m
if (menu->actext != NULL) {
tv_dict_add_str(dict, S_LEN("accel"), menu->actext);
}
- tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority);
+ tv_dict_add_nr(dict, S_LEN("priority"), menu->priority);
tv_dict_add_str(dict, S_LEN("modes"), get_menu_mode_str(menu->modes));
char buf[NUMBUFLEN];
diff --git a/src/nvim/menu.h b/src/nvim/menu.h
index 32959cf35f..8d7a98d270 100644
--- a/src/nvim/menu.h
+++ b/src/nvim/menu.h
@@ -3,6 +3,7 @@
#include <stdbool.h>
+#include "nvim/cmdexpand_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/menu_defs.h"
#include "nvim/types.h"
diff --git a/src/nvim/menu_defs.h b/src/nvim/menu_defs.h
index 79b267ae49..1e010c07ba 100644
--- a/src/nvim/menu_defs.h
+++ b/src/nvim/menu_defs.h
@@ -52,7 +52,7 @@ struct VimMenu {
char *en_dname; ///< NULL when "dname" untranslated
int mnemonic; ///< mnemonic key (after '&')
char *actext; ///< accelerator text (after TAB)
- long priority; ///< Menu order priority
+ int priority; ///< Menu order priority
char *strings[MENU_MODES]; ///< Mapped string for each mode
int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode
bool silent[MENU_MODES]; ///< A silent flag for each mode
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 68ea49d53b..97402276b2 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -475,7 +475,14 @@ void trunc_string(const char *s, char *buf, int room_in, int buflen)
}
}
-// Note: Caller of smsg() must check the resulting string is shorter than IOSIZE!!!
+/// Shows a printf-style message with attributes.
+///
+/// Note: Caller must check the resulting string is shorter than IOSIZE!!!
+///
+/// @see semsg
+/// @see swmsg
+///
+/// @param s printf-style format message
int smsg(int attr, const char *s, ...)
FUNC_ATTR_PRINTF(2, 3)
{
@@ -757,6 +764,8 @@ void emsg_invreg(int name)
}
/// Print an error message with unknown number of arguments
+///
+/// @return whether the message was displayed
bool semsg(const char *const fmt, ...)
FUNC_ATTR_PRINTF(1, 2)
{
@@ -1025,10 +1034,9 @@ int delete_first_msg(void)
}
/// :messages command implementation
-void ex_messages(void *const eap_p)
+void ex_messages(exarg_T *eap)
FUNC_ATTR_NONNULL_ALL
{
- const exarg_T *const eap = (const exarg_T *)eap_p;
struct msg_hist *p;
if (strcmp(eap->arg, "clear") == 0) {
@@ -1347,7 +1355,7 @@ bool messaging(void)
return !(p_lz && char_avail() && !KeyTyped) && (p_ch > 0 || ui_has(kUIMessages));
}
-void msgmore(long n)
+void msgmore(int n)
{
long pn;
@@ -1481,11 +1489,11 @@ void msg_putchar_attr(int c, int attr)
msg_puts_attr(buf, attr);
}
-void msg_outnum(long n)
+void msg_outnum(int n)
{
char buf[20];
- snprintf(buf, sizeof(buf), "%ld", n);
+ snprintf(buf, sizeof(buf), "%d", n);
msg_puts(buf);
}
@@ -1962,40 +1970,6 @@ void msg_prt_line(const char *s, int list)
msg_clr_eos();
}
-/// Use grid_puts() to output one multi-byte character.
-///
-/// @return the pointer "s" advanced to the next character.
-static const char *screen_puts_mbyte(const char *s, int l, int attr)
-{
- int cw;
- attr = hl_combine_attr(HL_ATTR(HLF_MSG), attr);
-
- msg_didout = true; // remember that line is not empty
- cw = utf_ptr2cells(s);
- if (cw > 1
- && (cmdmsg_rl ? msg_col <= 1 : msg_col == Columns - 1)) {
- // Doesn't fit, print a highlighted '>' to fill it up.
- msg_screen_putchar('>', HL_ATTR(HLF_AT));
- return s;
- }
-
- grid_puts(&msg_grid_adj, s, l, msg_row, msg_col, attr);
- if (cmdmsg_rl) {
- msg_col -= cw;
- if (msg_col == 0) {
- msg_col = Columns;
- msg_row++;
- }
- } else {
- msg_col += cw;
- if (msg_col >= Columns) {
- msg_col = 0;
- msg_row++;
- }
- }
- return s + l;
-}
-
/// Output a string to the screen at position msg_row, msg_col.
/// Update msg_row and msg_col for the next message.
void msg_puts(const char *s)
@@ -2133,14 +2107,8 @@ static void msg_ext_emit_chunk(void)
static void msg_puts_display(const char *str, int maxlen, int attr, int recurse)
{
const char *s = str;
- const char *t_s = str; // String from "t_s" to "s" is still todo.
- int t_col = 0; // Screen cells todo, 0 when "t_s" not used.
- int l;
- int cw;
const char *sb_str = str;
int sb_col = msg_col;
- int wrap;
- int did_last_char;
did_wait_return = false;
@@ -2156,175 +2124,143 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse)
return;
}
+ int print_attr = hl_combine_attr(HL_ATTR(HLF_MSG), attr);
msg_grid_validate();
cmdline_was_last_drawn = redrawing_cmdline;
- while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL) {
- // We are at the end of the screen line when:
- // - When outputting a newline.
- // - When outputting a character in the last column.
- if (!recurse && msg_row >= Rows - 1
- && (*s == '\n' || (cmdmsg_rl
- ? (msg_col <= 1
- || (*s == TAB && msg_col <= 7)
- || (utf_ptr2cells(s) > 1
- && msg_col <= 2))
- : ((*s != '\r' && msg_col + t_col >= Columns - 1)
- || (*s == TAB
- && msg_col + t_col >= ((Columns - 1) & ~7))
- || (utf_ptr2cells(s) > 1
- && msg_col + t_col >= Columns - 2))))) {
- // The screen is scrolled up when at the last row (some terminals
- // scroll automatically, some don't. To avoid problems we scroll
- // ourselves).
- if (t_col > 0) {
- // output postponed text
- t_puts(&t_col, t_s, s, attr);
- }
+ int msg_row_pending = -1;
- // When no more prompt and no more room, truncate here
+ while (true) {
+ if (cmdmsg_rl ? msg_col <= 0 : msg_col >= Columns) {
+ if (p_more && !recurse) {
+ // Store text for scrolling back.
+ store_sb_text(&sb_str, s, attr, &sb_col, true);
+ }
if (msg_no_more && lines_left == 0) {
break;
}
- // Scroll the screen up one line.
- bool has_last_char = ((uint8_t)(*s) >= ' ' && !cmdmsg_rl);
- msg_scroll_up(!has_last_char, false);
+ msg_col = cmdmsg_rl ? Columns - 1 : 0;
+ msg_row++;
+ msg_didout = false;
+ }
- msg_row = Rows - 2;
- if (msg_col >= Columns) { // can happen after screen resize
- msg_col = Columns - 1;
- }
+ if (msg_row >= Rows) {
+ msg_row = Rows - 1;
- // Display char in last column before showing more-prompt.
- if (has_last_char) {
- if (maxlen >= 0) {
- // Avoid including composing chars after the end.
- l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
- } else {
- l = utfc_ptr2len(s);
- }
- s = screen_puts_mbyte(s, l, attr);
- did_last_char = true;
- } else {
- did_last_char = false;
+ // When no more prompt and no more room, truncate here
+ if (msg_no_more && lines_left == 0) {
+ break;
}
- // Tricky: if last cell will be written, delay the throttle until
- // after the first scroll. Otherwise we would need to keep track of it.
- if (has_last_char && msg_do_throttle()) {
- if (!msg_grid.throttled) {
- msg_grid_scroll_discount++;
+ if (!recurse) {
+ if (msg_row_pending >= 0) {
+ grid_line_flush_if_valid_row();
+ msg_row_pending = -1;
}
- msg_grid.throttled = true;
- }
- if (p_more) {
- // Store text for scrolling back.
- store_sb_text(&sb_str, s, attr, &sb_col, true);
- }
-
- inc_msg_scrolled();
- need_wait_return = true; // may need wait_return() in main()
- redraw_cmdline = true;
- if (cmdline_row > 0 && !exmode_active) {
- cmdline_row--;
- }
+ // Scroll the screen up one line.
+ msg_scroll_up(true, false);
- // If screen is completely filled and 'more' is set then wait
- // for a character.
- if (lines_left > 0) {
- lines_left--;
- }
- if (p_more && lines_left == 0 && State != MODE_HITRETURN
- && !msg_no_more && !exmode_active) {
- if (do_more_prompt(NUL)) {
- s = confirm_msg_tail;
+ inc_msg_scrolled();
+ need_wait_return = true; // may need wait_return() in main()
+ redraw_cmdline = true;
+ if (cmdline_row > 0 && !exmode_active) {
+ cmdline_row--;
}
- if (quit_more) {
- return;
+
+ // If screen is completely filled and 'more' is set then wait
+ // for a character.
+ if (lines_left > 0) {
+ lines_left--;
}
- }
- // When we displayed a char in last column need to check if there
- // is still more.
- if (did_last_char) {
- continue;
+ if (p_more && lines_left == 0 && State != MODE_HITRETURN
+ && !msg_no_more && !exmode_active) {
+ if (do_more_prompt(NUL)) {
+ s = confirm_msg_tail;
+ }
+ if (quit_more) {
+ return;
+ }
+ }
}
}
- wrap = *s == '\n'
- || msg_col + t_col >= Columns
- || (utf_ptr2cells(s) > 1
- && msg_col + t_col >= Columns - 1)
- ;
- if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
- || *s == '\t' || *s == BELL)) {
- // Output any postponed text.
- t_puts(&t_col, t_s, s, attr);
+ if (!((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)) {
+ break;
}
- if (wrap && p_more && !recurse) {
- // Store text for scrolling back.
- store_sb_text(&sb_str, s, attr, &sb_col, true);
+ if (msg_row != msg_row_pending && ((uint8_t)(*s) >= 0x20 || *s == TAB)) {
+ // TODO(bfredl): this logic is messier that it has to be. What
+ // messages really want is its own private linebuf_char buffer.
+ if (msg_row_pending >= 0) {
+ grid_line_flush_if_valid_row();
+ }
+ grid_line_start(&msg_grid_adj, msg_row);
+ msg_row_pending = msg_row;
}
- if (*s == '\n') { // go to next line
- msg_didout = false; // remember that line is empty
- if (cmdmsg_rl) {
- msg_col = Columns - 1;
+ if ((uint8_t)(*s) >= 0x20) { // printable char
+ int cw = utf_ptr2cells(s);
+ // avoid including composing chars after the end
+ int l = (maxlen >= 0) ? utfc_ptr2len_len(s, (int)((str + maxlen) - s)) : utfc_ptr2len(s);
+
+ if (cw > 1 && (cmdmsg_rl ? msg_col <= 1 : msg_col == Columns - 1)) {
+ // Doesn't fit, print a highlighted '>' to fill it up.
+ grid_line_puts(msg_col, ">", 1, HL_ATTR(HLF_AT));
+ cw = 1;
} else {
- msg_col = 0;
- }
- if (++msg_row >= Rows) { // safety check
- msg_row = Rows - 1;
+ grid_line_puts(msg_col, s, l, print_attr);
+ s += l;
}
- } else if (*s == '\r') { // go to column 0
- msg_col = 0;
- } else if (*s == '\b') { // go to previous char
- if (msg_col) {
- msg_col--;
- }
- } else if (*s == TAB) { // translate Tab into spaces
- do {
- msg_screen_putchar(' ', attr);
- } while (msg_col & 7);
- } else if (*s == BELL) { // beep (from ":sh")
- vim_beep(BO_SH);
- } else if ((uint8_t)(*s) >= 0x20) { // printable char
- cw = utf_ptr2cells(s);
- if (maxlen >= 0) {
- // avoid including composing chars after the end
- l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
+ msg_didout = true; // remember that line is not empty
+ if (cmdmsg_rl) {
+ msg_col -= cw;
} else {
- l = utfc_ptr2len(s);
+ msg_col += cw;
}
- // When drawing from right to left or when a double-wide character
- // doesn't fit, draw a single character here. Otherwise collect
- // characters and draw them all at once later.
- if (cmdmsg_rl || (cw > 1 && msg_col + t_col >= Columns - 1)) {
- if (l > 1) {
- s = screen_puts_mbyte(s, l, attr) - 1;
+ } else {
+ char c = *s++;
+ if (c == '\n') { // go to next line
+ msg_didout = false; // remember that line is empty
+ if (cmdmsg_rl) {
+ msg_col = Columns - 1;
} else {
- msg_screen_putchar(*s, attr);
+ msg_col = 0;
}
- } else {
- // postpone this character until later
- if (t_col == 0) {
- t_s = s;
+ msg_row++;
+ if (p_more && !recurse) {
+ // Store text for scrolling back.
+ store_sb_text(&sb_str, s, attr, &sb_col, true);
+ }
+ } else if (c == '\r') { // go to column 0
+ msg_col = 0;
+ } else if (c == '\b') { // go to previous char
+ if (msg_col) {
+ msg_col--;
}
- t_col += cw;
- s += l - 1;
+ } else if (c == TAB) { // translate Tab into spaces
+ do {
+ grid_line_puts(msg_col, " ", 1, print_attr);
+ msg_col += cmdmsg_rl ? -1 : 1;
+
+ if (msg_col == (cmdmsg_rl ? 0 : Columns)) {
+ break;
+ }
+ } while (msg_col & 7);
+ } else if (c == BELL) { // beep (from ":sh")
+ vim_beep(BO_SH);
}
}
- s++;
}
- // Output any postponed text.
- if (t_col > 0) {
- t_puts(&t_col, t_s, s, attr);
+ if (msg_row_pending >= 0) {
+ grid_line_flush_if_valid_row();
}
+ msg_cursor_goto(msg_row, msg_col);
+
if (p_more && !recurse && !(s == sb_str + 1 && *sb_str == '\n')) {
store_sb_text(&sb_str, s, attr, &sb_col, false);
}
@@ -2332,6 +2268,13 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse)
msg_check();
}
+void msg_cursor_goto(int row, int col)
+{
+ ScreenGrid *grid = &msg_grid_adj;
+ grid_adjust(&grid, &row, &col);
+ ui_grid_cursor_goto(grid->handle, row, col);
+}
+
/// @return true when ":filter pattern" was used and "msg" does not match
/// "pattern".
bool message_filtered(const char *msg)
@@ -2508,6 +2451,9 @@ static void store_sb_text(const char **sb_str, const char *s, int attr, int *sb_
|| do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) {
clear_sb_text(do_clear_sb_text == SB_CLEAR_ALL);
msg_sb_eol(); // prevent messages from overlapping
+ if (do_clear_sb_text == SB_CLEAR_CMDLINE_DONE && s > *sb_str && **sb_str == '\n') {
+ (*sb_str)++;
+ }
do_clear_sb_text = SB_CLEAR_NONE;
}
@@ -2655,9 +2601,6 @@ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
msg_row = row;
msg_col = mp->sb_msg_col;
char *p = mp->sb_text;
- if (*p == '\n') { // don't display the line break
- p++;
- }
msg_puts_display(p, -1, mp->sb_attr, true);
if (mp->sb_eol || mp->sb_next == NULL) {
break;
@@ -2668,26 +2611,6 @@ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
return mp->sb_next;
}
-/// Output any postponed text for msg_puts_len().
-static void t_puts(int *t_col, const char *t_s, const char *s, int attr)
-{
- attr = hl_combine_attr(HL_ATTR(HLF_MSG), attr);
- // Output postponed text.
- msg_didout = true; // Remember that line is not empty.
- grid_puts(&msg_grid_adj, t_s, (int)(s - t_s), msg_row, msg_col, attr);
- msg_col += *t_col;
- *t_col = 0;
- // If the string starts with a composing character don't increment the
- // column position for it.
- if (utf_iscomposing(utf_ptr2char(t_s))) {
- msg_col--;
- }
- if (msg_col >= Columns) {
- msg_col = 0;
- msg_row++;
- }
-}
-
/// @return true when messages should be printed to stdout/stderr:
/// - "batch mode" ("silent mode", -es/-Es)
/// - no UI and not embedded
@@ -3034,26 +2957,6 @@ void os_msg(const char *str)
}
#endif // MSWIN
-/// Put a character on the screen at the current message position and advance
-/// to the next position. Only for printable ASCII!
-static void msg_screen_putchar(int c, int attr)
-{
- attr = hl_combine_attr(HL_ATTR(HLF_MSG), attr);
- msg_didout = true; // remember that line is not empty
- grid_putchar(&msg_grid_adj, c, msg_row, msg_col, attr);
- if (cmdmsg_rl) {
- if (--msg_col == 0) {
- msg_col = Columns;
- msg_row++;
- }
- } else {
- if (++msg_col >= Columns) {
- msg_col = 0;
- msg_row++;
- }
- }
-}
-
void msg_moremsg(int full)
{
int attr;
@@ -3443,9 +3346,22 @@ void give_warning(const char *message, bool hl)
no_wait_return--;
}
-void give_warning2(const char *const message, const char *const a1, bool hl)
+/// Shows a warning, with optional highlighting.
+///
+/// @param hl enable highlighting
+/// @param fmt printf-style format message
+///
+/// @see smsg
+/// @see semsg
+void swmsg(bool hl, const char *const fmt, ...)
+ FUNC_ATTR_PRINTF(2, 3)
{
- vim_snprintf(IObuff, IOSIZE, message, a1);
+ va_list args;
+
+ va_start(args, fmt);
+ vim_vsnprintf(IObuff, IOSIZE, fmt, args);
+ va_end(args);
+
give_warning(IObuff, hl);
}
diff --git a/src/nvim/message.h b/src/nvim/message.h
index 78cd5b7d0e..6fc6674cc2 100644
--- a/src/nvim/message.h
+++ b/src/nvim/message.h
@@ -7,6 +7,7 @@
#include "klib/kvec.h"
#include "nvim/api/private/defs.h"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/grid_defs.h"
#include "nvim/macros.h"
#include "nvim/types.h"
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 8efb038a55..dd9737ede2 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -2699,7 +2699,7 @@ void do_check_cursorbind(void)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
curwin = wp;
curbuf = curwin->w_buffer;
- // skip original window and windows with 'noscrollbind'
+ // skip original window and windows with 'nocursorbind'
if (curwin != old_curwin && curwin->w_p_crb) {
if (curwin->w_p_diff) {
curwin->w_cursor.lnum =
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 715b98377a..1a212661c5 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1735,13 +1735,13 @@ static void prep_redo_cmd(cmdarg_T *cap)
/// Prepare for redo of any command.
/// Note that only the last argument can be a multi-byte char.
-void prep_redo(int regname, long num, int cmd1, int cmd2, int cmd3, int cmd4, int cmd5)
+void prep_redo(int regname, int num, int cmd1, int cmd2, int cmd3, int cmd4, int cmd5)
{
prep_redo_num2(regname, num, cmd1, cmd2, 0L, cmd3, cmd4, cmd5);
}
/// Prepare for redo of any command with extra count after "cmd2".
-void prep_redo_num2(int regname, long num1, int cmd1, int cmd2, long num2, int cmd3, int cmd4,
+void prep_redo_num2(int regname, int num1, int cmd1, int cmd2, int num2, int cmd3, int cmd4,
int cmd5)
{
ResetRedobuff();
diff --git a/src/nvim/normal.h b/src/nvim/normal.h
index b9fdd21652..3d7782c05c 100644
--- a/src/nvim/normal.h
+++ b/src/nvim/normal.h
@@ -39,7 +39,7 @@ typedef struct oparg_S {
pos_T end; // end of the operator
pos_T cursor_start; // cursor position before motion for "gw"
- long line_count; // number of lines from op_start to op_end
+ linenr_T line_count; // number of lines from op_start to op_end
// (inclusive)
bool empty; // op_start and op_end the same (only used by
// op_change())
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 5d3e285e3b..348a86a0f6 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -217,7 +217,7 @@ int get_extra_op_char(int optype)
/// handle a shift operation
void op_shift(oparg_T *oap, int curs_top, int amount)
{
- long i;
+ int i;
int block_col = 0;
if (u_save((linenr_T)(oap->start.lnum - 1),
@@ -292,7 +292,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
/// @param call_changed_bytes call changed_bytes()
void shift_line(int left, int round, int amount, int call_changed_bytes)
{
- const int sw_val = (int)get_sw_value_indent(curbuf);
+ const int sw_val = get_sw_value_indent(curbuf);
int count = get_indent(); // get current indent
@@ -338,7 +338,7 @@ static void shift_block(oparg_T *oap, int amount)
const int oldstate = State;
char *newp;
const int oldcol = curwin->w_cursor.col;
- const int sw_val = (int)get_sw_value_indent(curbuf);
+ const int sw_val = get_sw_value_indent(curbuf);
const int ts_val = (int)curbuf->b_p_ts;
struct block_def bd;
int incr;
@@ -634,7 +634,7 @@ static void block_insert(oparg_T *oap, char *s, int b_insert, struct block_def *
/// Handle reindenting a block of lines.
void op_reindent(oparg_T *oap, Indenter how)
{
- long i = 0;
+ int i = 0;
linenr_T first_changed = 0;
linenr_T last_changed = 0;
linenr_T start_lnum = curwin->w_cursor.lnum;
@@ -647,8 +647,8 @@ void op_reindent(oparg_T *oap, Indenter how)
// Save for undo. Do this once for all lines, much faster than doing this
// for each line separately, especially when undoing.
- if (u_savecommon(curbuf, start_lnum - 1, start_lnum + (linenr_T)oap->line_count,
- start_lnum + (linenr_T)oap->line_count, false) == OK) {
+ if (u_savecommon(curbuf, start_lnum - 1, start_lnum + oap->line_count,
+ start_lnum + oap->line_count, false) == OK) {
char *l;
int amount;
for (i = oap->line_count - 1; i >= 0 && !got_int; i--) {
@@ -693,7 +693,7 @@ void op_reindent(oparg_T *oap, Indenter how)
// there is no change still need to remove the Visual highlighting.
if (last_changed != 0) {
changed_lines(curbuf, first_changed, 0,
- oap->is_VIsual ? start_lnum + (linenr_T)oap->line_count :
+ oap->is_VIsual ? start_lnum + oap->line_count :
last_changed + 1, 0L, true);
} else if (oap->is_VIsual) {
redraw_curbuf_later(UPD_INVERTED);
@@ -1717,8 +1717,8 @@ int op_delete(oparg_T *oap)
pos_T curpos;
// save deleted and changed lines for undo
- if (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
- (linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL) {
+ if (u_save(curwin->w_cursor.lnum - 1,
+ curwin->w_cursor.lnum + oap->line_count) == FAIL) {
return FAIL;
}
@@ -2204,7 +2204,7 @@ bool swapchar(int op_type, pos_T *pos)
/// Insert and append operators for Visual mode.
void op_insert(oparg_T *oap, long count1)
{
- long pre_textlen = 0;
+ int pre_textlen = 0;
char *firstline;
colnr_T ind_pre_col = 0;
int ind_pre_vcol = 0;
@@ -2251,7 +2251,7 @@ void op_insert(oparg_T *oap, long count1)
if (oap->op_type == OP_APPEND) {
firstline += bd.textlen;
}
- pre_textlen = (long)strlen(firstline);
+ pre_textlen = (int)strlen(firstline);
}
if (oap->op_type == OP_APPEND) {
@@ -2400,7 +2400,7 @@ void op_insert(oparg_T *oap, long count1)
} else {
firstline += add;
}
- long ins_len = (long)strlen(firstline) - pre_textlen - offset;
+ int ins_len = (int)strlen(firstline) - pre_textlen - offset;
if (pre_textlen >= 0 && ins_len > 0) {
char *ins_text = xstrnsave(firstline, (size_t)ins_len);
// block handled here
@@ -2421,8 +2421,8 @@ void op_insert(oparg_T *oap, long count1)
int op_change(oparg_T *oap)
{
int retval;
- long pre_textlen = 0;
- long pre_indent = 0;
+ int pre_textlen = 0;
+ int pre_indent = 0;
char *firstline;
struct block_def bd;
@@ -2456,8 +2456,8 @@ int op_change(oparg_T *oap)
coladvance_force(getviscol());
}
firstline = ml_get(oap->start.lnum);
- pre_textlen = (long)strlen(firstline);
- pre_indent = (long)getwhitecols(firstline);
+ pre_textlen = (int)strlen(firstline);
+ pre_indent = (int)getwhitecols(firstline);
bd.textcol = curwin->w_cursor.col;
}
@@ -2478,25 +2478,25 @@ int op_change(oparg_T *oap)
// Don't repeat the insert when Insert mode ended with CTRL-C.
if (oap->motion_type == kMTBlockWise
&& oap->start.lnum != oap->end.lnum && !got_int) {
- long ins_len;
+ int ins_len;
// Auto-indenting may have changed the indent. If the cursor was past
// the indent, exclude that indent change from the inserted text.
firstline = ml_get(oap->start.lnum);
if (bd.textcol > (colnr_T)pre_indent) {
- long new_indent = (long)getwhitecols(firstline);
+ int new_indent = (int)getwhitecols(firstline);
pre_textlen += new_indent - pre_indent;
bd.textcol += (colnr_T)(new_indent - pre_indent);
}
- ins_len = (long)strlen(firstline) - pre_textlen;
+ ins_len = (int)strlen(firstline) - pre_textlen;
if (ins_len > 0) {
long offset;
char *newp;
char *oldp;
// Subsequent calls to ml_get() flush the firstline data - take a
// copy of the inserted text.
- char *ins_text = xmalloc((size_t)(ins_len + 1));
+ char *ins_text = xmalloc((size_t)ins_len + 1);
xstrlcpy(ins_text, firstline + bd.textcol, (size_t)ins_len + 1);
for (linenr_T linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
linenr++) {
@@ -2526,7 +2526,7 @@ int op_change(oparg_T *oap)
STRMOVE(newp + offset, oldp);
ml_replace(linenr, newp, false);
extmark_splice_cols(curbuf, (int)linenr - 1, bd.textcol,
- 0, vpos.coladd + (int)ins_len, kExtmarkUndo);
+ 0, vpos.coladd + ins_len, kExtmarkUndo);
}
}
check_cursor();
@@ -2903,7 +2903,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
/// PUT_LINE force linewise put (":put")
/// PUT_BLOCK_INNER in block mode, do not add trailing spaces
/// @param dir BACKWARD for 'P', FORWARD for 'p'
-void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
+void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
{
char *ptr;
char *newp;
@@ -3320,7 +3320,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
break;
}
- totlen = (size_t)(count * (yanklen + spaces) + bd.startspaces + bd.endspaces);
+ totlen = (size_t)count * (size_t)(yanklen + spaces) + (size_t)bd.startspaces +
+ (size_t)bd.endspaces;
newp = xmalloc(totlen + oldlen + 1);
// copy part up to cursor to new line
@@ -3446,7 +3447,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
// multiplication overflow
emsg(_(e_resulting_text_too_long));
} else {
- totlen = (size_t)(count * yanklen);
+ totlen = (size_t)count * (size_t)yanklen;
do {
oldp = ml_get(lnum);
oldlen = strlen(oldp);
@@ -4166,7 +4167,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions
// have moved up (last line deleted), so the current lnum is kept in t.
t = curwin->w_cursor.lnum;
curwin->w_cursor.lnum++;
- del_lines((long)count - 1, false);
+ del_lines((int)count - 1, false);
curwin->w_cursor.lnum = t;
curbuf_splice_pending--;
curbuf->deleted_bytes2 = 0;
@@ -5569,7 +5570,7 @@ static void op_colon(oparg_T *oap)
if (oap->start.lnum == curwin->w_cursor.lnum) {
stuffcharReadbuff('.');
} else {
- stuffnumReadbuff((long)oap->start.lnum);
+ stuffnumReadbuff(oap->start.lnum);
}
// When using !! on a closed fold the range ".!" works best to operate
@@ -5590,7 +5591,7 @@ static void op_colon(oparg_T *oap)
stuffReadbuff(".+");
stuffnumReadbuff(oap->line_count - 1);
} else {
- stuffnumReadbuff((long)oap->end.lnum);
+ stuffnumReadbuff(oap->end.lnum);
}
}
}
@@ -5996,7 +5997,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
resel_VIsual_vcol = oap->end_vcol;
}
}
- resel_VIsual_line_count = (linenr_T)oap->line_count;
+ resel_VIsual_line_count = oap->line_count;
}
// can't redo yank (unless 'y' is in 'cpoptions') and ":"
diff --git a/src/nvim/option.c b/src/nvim/option.c
index eef5e66aeb..c0353e52be 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -40,6 +40,7 @@
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor_shape.h"
#include "nvim/decoration_provider.h"
#include "nvim/diff.h"
@@ -136,12 +137,12 @@ static char *p_vsts_nopaste;
#define OPTION_COUNT ARRAY_SIZE(options)
+/// :set boolean option prefix
typedef enum {
- OP_NONE = 0,
- OP_ADDING, ///< "opt+=arg"
- OP_PREPENDING, ///< "opt^=arg"
- OP_REMOVING, ///< "opt-=arg"
-} set_op_T;
+ PREFIX_NO = 0, ///< "no" prefix
+ PREFIX_NONE, ///< no prefix
+ PREFIX_INV, ///< "inv" prefix
+} set_prefix_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "option.c.generated.h"
@@ -557,7 +558,7 @@ static char *find_dup_item(char *origval, const char *newval, uint32_t flags)
/// Set the Vi-default value of a number option.
/// Used for 'lines' and 'columns'.
-void set_number_default(char *name, long val)
+void set_number_default(char *name, OptInt val)
{
int opt_idx = findoption(name);
if (opt_idx >= 0) {
@@ -752,8 +753,8 @@ void ex_set(exarg_T *eap)
(void)do_set(eap->arg, flags);
}
-static void do_set_bool(int opt_idx, int opt_flags, int prefix, int nextchar, const void *varp,
- const char **errmsg)
+static void do_set_bool(int opt_idx, int opt_flags, set_prefix_T prefix, int nextchar,
+ const void *varp, const char **errmsg)
{
varnumber_T value;
@@ -772,10 +773,12 @@ static void do_set_bool(int opt_idx, int opt_flags, int prefix, int nextchar, co
value = *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
}
} else {
- if (prefix == 2) {
- value = *(int *)varp ^ 1; // ":set invopt": invert
+ // ":set invopt": invert
+ // ":set opt" or ":set noopt": set or reset
+ if (prefix == PREFIX_INV) {
+ value = *(int *)varp ^ 1;
} else {
- value = prefix; // ":set opt" or ":set noopt": set or reset
+ value = prefix == PREFIX_NO ? 0 : 1;
}
}
@@ -797,7 +800,7 @@ static void do_set_num(int opt_idx, int opt_flags, char **argp, int nextchar, co
// other error
arg++;
if (nextchar == '&') {
- value = (long)(intptr_t)options[opt_idx].def_val;
+ value = (varnumber_T)options[opt_idx].def_val;
} else if (nextchar == '<') {
if ((OptInt *)varp == &curbuf->b_p_ul && opt_flags == OPT_LOCAL) {
// for 'undolevels' NO_LOCAL_UNDOLEVEL means using the global value
@@ -843,7 +846,7 @@ static void do_set_num(int opt_idx, int opt_flags, char **argp, int nextchar, co
if (op == OP_REMOVING) {
value = *(OptInt *)varp - value;
}
- *errmsg = set_num_option(opt_idx, (void *)varp, (long)value,
+ *errmsg = set_num_option(opt_idx, (void *)varp, value,
errbuf, errbuflen, opt_flags);
}
@@ -888,7 +891,7 @@ static char *stropt_copy_value(char *origval, char **argp, set_op_T op,
// For MS-Windows backslashes before normal file name characters
// are not removed, and keep backslash at start, for "\\machine\path",
// but do remove it for "\\\\machine\\path".
- // The reverse is found in ExpandOldSetting().
+ // The reverse is found in escape_option_str_cmdline().
while (*arg != NUL && !ascii_iswhite(*arg)) {
if (*arg == '\\' && arg[1] != NUL
#ifdef BACKSLASH_IN_FILENAME
@@ -1168,7 +1171,7 @@ static void do_set_option_string(int opt_idx, int opt_flags, char **argp, int ne
// be triggered that can cause havoc.
*errmsg = did_set_string_option(curbuf, curwin, opt_idx, (char **)varp, oldval,
errbuf, errbuflen,
- opt_flags, value_checked);
+ opt_flags, op, value_checked);
secure = secure_saved;
@@ -1204,17 +1207,17 @@ static set_op_T get_op(const char *arg)
return op;
}
-static int get_option_prefix(char **argp)
+static set_prefix_T get_option_prefix(char **argp)
{
if (strncmp(*argp, "no", 2) == 0) {
*argp += 2;
- return 0;
+ return PREFIX_NO;
} else if (strncmp(*argp, "inv", 3) == 0) {
*argp += 3;
- return 2;
+ return PREFIX_INV;
}
- return 1;
+ return PREFIX_NONE;
}
/// @param[in] arg Pointer to start option name
@@ -1273,11 +1276,11 @@ static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp)
return OK;
}
-static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t flags, int prefix,
- const char **errmsg)
+static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t flags,
+ set_prefix_T prefix, const char **errmsg)
{
// Only bools can have a prefix of 'inv' or 'no'
- if (!(flags & P_BOOL) && prefix != 1) {
+ if (!(flags & P_BOOL) && prefix != PREFIX_NONE) {
*errmsg = e_invarg;
return FAIL;
}
@@ -1325,8 +1328,8 @@ static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t fla
return OK;
}
-static void do_set_option_value(int opt_idx, int opt_flags, char **argp, int prefix, int nextchar,
- set_op_T op, uint32_t flags, void *varp, char *errbuf,
+static void do_set_option_value(int opt_idx, int opt_flags, char **argp, set_prefix_T prefix,
+ int nextchar, set_op_T op, uint32_t flags, void *varp, char *errbuf,
size_t errbuflen, const char **errmsg)
{
bool value_checked = false;
@@ -1355,7 +1358,7 @@ static void do_set_option(int opt_flags, char **argp, bool *did_show, char *errb
size_t errbuflen, const char **errmsg)
{
// 1: nothing, 0: "no", 2: "inv" in front of name
- int prefix = get_option_prefix(argp);
+ set_prefix_T prefix = get_option_prefix(argp);
char *arg = *argp;
@@ -1434,7 +1437,7 @@ static void do_set_option(int opt_flags, char **argp, bool *did_show, char *errb
// '=' character per "set" command line. grrr. (jw)
//
if (nextchar == '?'
- || (prefix == 1
+ || (prefix == PREFIX_NONE
&& vim_strchr("=:&<", nextchar) == NULL
&& !(flags & P_BOOL))) {
// print value
@@ -1976,8 +1979,8 @@ void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
}
/// Apply the OptionSet autocommand.
-static void apply_optionset_autocmd(int opt_idx, long opt_flags, OptInt oldval, OptInt oldval_g,
- long newval, const char *errmsg)
+static void apply_optionset_autocmd(int opt_idx, int opt_flags, OptInt oldval, OptInt oldval_g,
+ OptInt newval, const char *errmsg)
{
// Don't do this while starting up, failure or recursively.
if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) {
@@ -1988,7 +1991,7 @@ static void apply_optionset_autocmd(int opt_idx, long opt_flags, OptInt oldval,
vim_snprintf(buf_old, sizeof(buf_old), "%" PRId64, oldval);
vim_snprintf(buf_old_global, sizeof(buf_old_global), "%" PRId64, oldval_g);
- vim_snprintf(buf_new, sizeof(buf_new), "%ld", newval);
+ vim_snprintf(buf_new, sizeof(buf_new), "%" PRId64, newval);
vim_snprintf(buf_type, sizeof(buf_type), "%s",
(opt_flags & OPT_LOCAL) ? "local" : "global");
set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
@@ -2899,9 +2902,9 @@ static const char *set_bool_option(const int opt_idx, char *const varp, const in
options[opt_idx].flags |= P_WAS_SET;
apply_optionset_autocmd(opt_idx, opt_flags,
- (long)(old_value ? true : false),
- (long)(old_global_value ? true : false),
- (long)(value ? true : false), NULL);
+ (old_value ? true : false),
+ (old_global_value ? true : false),
+ (value ? true : false), NULL);
if (options[opt_idx].flags & P_UI_OPTION) {
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
@@ -2921,8 +2924,8 @@ static const char *set_bool_option(const int opt_idx, char *const varp, const in
}
/// Check the bounds of numeric options.
-static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, long old_Rows,
- char *errbuf, size_t errbuflen, const char *errmsg)
+static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, int old_Rows, char *errbuf,
+ size_t errbuflen, const char *errmsg)
{
// Check the (new) bounds for Rows and Columns here.
if (p_lines < min_rows() && full_screen) {
@@ -2997,9 +3000,9 @@ static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, long ol
}
/// Options that need some validation.
-static const char *validate_num_option(const OptInt *pp, long *valuep)
+static const char *validate_num_option(const OptInt *pp, OptInt *valuep)
{
- long value = *valuep;
+ OptInt value = *valuep;
// Many number options assume their value is in the signed int range.
if (value < INT_MIN || value > INT_MAX) {
@@ -3157,12 +3160,12 @@ static const char *validate_num_option(const OptInt *pp, long *valuep)
/// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE.
///
/// @return NULL on success, error message on error.
-static const char *set_num_option(int opt_idx, void *varp, long value, char *errbuf,
+static const char *set_num_option(int opt_idx, void *varp, OptInt value, char *errbuf,
size_t errbuflen, int opt_flags)
{
OptInt old_value = *(OptInt *)varp;
OptInt old_global_value = 0; // only used when setting a local and global option
- long old_Rows = Rows; // remember old Rows
+ int old_Rows = Rows; // remember old Rows
OptInt *pp = (OptInt *)varp;
// Disallow changing some options from secure mode.
@@ -3184,7 +3187,7 @@ static const char *set_num_option(int opt_idx, void *varp, long value, char *err
return errmsg;
}
- *pp = (OptInt)value;
+ *pp = value;
// Remember where the option was set.
set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
@@ -3195,7 +3198,7 @@ static const char *set_num_option(int opt_idx, void *varp, long value, char *err
.os_varp = varp,
.os_flags = opt_flags,
.os_oldval.number = old_value,
- .os_newval.number = (OptInt)value,
+ .os_newval.number = value,
.os_errbuf = NULL,
.os_errbuflen = 0,
.os_buf = curbuf,
@@ -3215,7 +3218,7 @@ static const char *set_num_option(int opt_idx, void *varp, long value, char *err
options[opt_idx].flags |= P_WAS_SET;
apply_optionset_autocmd(opt_idx, opt_flags, old_value, old_global_value,
- value, errmsg);
+ (int)value, errmsg);
if (errmsg == NULL && options[opt_idx].flags & P_UI_OPTION) {
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
@@ -3786,7 +3789,7 @@ static const char *set_option(int opt_idx, void *varp, OptVal *v, int opt_flags,
if (v->type == kOptValTypeBoolean) {
errmsg = set_bool_option(opt_idx, varp, (int)v->data.boolean, opt_flags);
} else if (v->type == kOptValTypeNumber) {
- errmsg = set_num_option(opt_idx, varp, (long)v->data.number, errbuf, errbuflen, opt_flags);
+ errmsg = set_num_option(opt_idx, varp, v->data.number, errbuf, errbuflen, opt_flags);
} else if (v->type == kOptValTypeString) {
errmsg = set_string_option(opt_idx, varp, v->data.string.data, opt_flags, &value_checked,
errbuf, errbuflen);
@@ -5305,8 +5308,10 @@ void set_imsearch_global(buf_T *buf)
}
static int expand_option_idx = -1;
+static int expand_option_start_col = 0;
static char expand_option_name[5] = { 't', '_', NUL, NUL, NUL };
static int expand_option_flags = 0;
+static bool expand_option_append = false;
/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags)
@@ -5405,7 +5410,15 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags)
}
}
// handle "-=" and "+="
+ expand_option_append = false;
+ bool expand_option_subtract = false;
if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=') {
+ if (nextchar == '-') {
+ expand_option_subtract = true;
+ }
+ if (nextchar == '+' || nextchar == '^') {
+ expand_option_append = true;
+ }
p++;
nextchar = '=';
}
@@ -5414,28 +5427,51 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags)
xp->xp_context = EXPAND_UNSUCCESSFUL;
return;
}
- if (p[1] == NUL) {
- xp->xp_context = EXPAND_OLD_SETTING;
- if (is_term_option) {
- expand_option_idx = -1;
- } else {
- expand_option_idx = opt_idx;
- }
- xp->xp_pattern = p + 1;
- return;
- }
- xp->xp_context = EXPAND_NOTHING;
- if (is_term_option || (flags & P_NUM)) {
- return;
+
+ // Below are for handling expanding a specific option's value after the '=' or ':'
+
+ if (is_term_option) {
+ expand_option_idx = -1;
+ } else {
+ expand_option_idx = opt_idx;
}
xp->xp_pattern = p + 1;
+ expand_option_start_col = (int)(p + 1 - xp->xp_line);
+ // Certain options currently have special case handling to reuse the
+ // expansion logic with other commands.
if (options[opt_idx].var == &p_syn) {
xp->xp_context = EXPAND_OWNSYNTAX;
return;
}
+ if (options[opt_idx].var == &p_ft) {
+ xp->xp_context = EXPAND_FILETYPE;
+ return;
+ }
+ // Now pick. If the option has a custom expander, use that. Otherwise, just
+ // fill with the existing option value.
+ if (expand_option_subtract) {
+ xp->xp_context = EXPAND_SETTING_SUBTRACT;
+ return;
+ } else if (expand_option_idx >= 0
+ && options[expand_option_idx].opt_expand_cb != NULL) {
+ xp->xp_context = EXPAND_STRING_SETTING;
+ } else if (*xp->xp_pattern == NUL) {
+ xp->xp_context = EXPAND_OLD_SETTING;
+ return;
+ } else {
+ xp->xp_context = EXPAND_NOTHING;
+ }
+
+ if (is_term_option || (flags & P_NUM)) {
+ return;
+ }
+
+ // Only string options below
+
+ // Options that have P_EXPAND are considered to all use file/dir expansion.
if (flags & P_EXPAND) {
p = options[opt_idx].var;
if (p == (char *)&p_bdir
@@ -5451,8 +5487,6 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags)
} else {
xp->xp_backslash = XP_BS_ONE;
}
- } else if (p == (char *)&p_ft) {
- xp->xp_context = EXPAND_FILETYPE;
} else {
xp->xp_context = EXPAND_FILES;
// for 'tags' need three backslashes for a space
@@ -5464,27 +5498,45 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags)
}
}
- // For an option that is a list of file names, find the start of the
- // last file name.
- for (p = arg + strlen(arg) - 1; p > xp->xp_pattern; p--) {
- // count number of backslashes before ' ' or ','
- if (*p == ' ' || *p == ',') {
- char *s = p;
- while (s > xp->xp_pattern && *(s - 1) == '\\') {
- s--;
- }
- if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
- || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0)) {
- xp->xp_pattern = p + 1;
- break;
+ // For an option that is a list of file names, or comma/colon-separated
+ // values, split it by the delimiter and find the start of the current
+ // pattern, while accounting for backslash-escaped space/commas/colons.
+ // Triple-backslashed escaped file names (e.g. 'path') can also be
+ // delimited by space.
+ if ((flags & P_EXPAND) || (flags & P_COMMA) || (flags & P_COLON)) {
+ for (p = arg + strlen(arg) - 1; p > xp->xp_pattern; p--) {
+ // count number of backslashes before ' ' or ','
+ if (*p == ' ' || *p == ',' || (*p == ':' && (flags & P_COLON))) {
+ char *s = p;
+ while (s > xp->xp_pattern && *(s - 1) == '\\') {
+ s--;
+ }
+ if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
+ || (*p == ',' && (flags & P_COMMA) && ((p - s) % 1) == 0)
+ || (*p == ':' && (flags & P_COLON))) {
+ xp->xp_pattern = p + 1;
+ break;
+ }
}
}
+ }
- // for 'spellsuggest' start at "file:"
- if (options[opt_idx].var == &p_sps
- && strncmp(p, "file:", 5) == 0) {
- xp->xp_pattern = p + 5;
- break;
+ // An option that is a list of single-character flags should always start
+ // at the end as we don't complete words.
+ if (flags & P_FLAGLIST) {
+ xp->xp_pattern = arg + strlen(arg);
+ }
+
+ // Some options can either be using file/dir expansions, or custom value
+ // expansion depending on what the user typed. Unfortunately we have to
+ // manually handle it here to make sure we have the correct xp_context set.
+ // for 'spellsuggest' start at "file:"
+ if (options[opt_idx].var == &p_sps) {
+ if (strncmp(xp->xp_pattern, "file:", 5) == 0) {
+ xp->xp_pattern += 5;
+ return;
+ } else if (options[expand_option_idx].opt_expand_cb != NULL) {
+ xp->xp_context = EXPAND_STRING_SETTING;
}
}
}
@@ -5609,7 +5661,33 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char *fuzzystr, int *numM
return OK;
}
-void ExpandOldSetting(int *numMatches, char ***matches)
+/// Escape an option value that can be used on the command-line with :set.
+/// Caller needs to free the returned string, unless NULL is returned.
+static char *escape_option_str_cmdline(char *var)
+{
+ // A backslash is required before some characters. This is the reverse of
+ // what happens in do_set().
+ char *buf = vim_strsave_escaped(var, escape_chars);
+
+#ifdef BACKSLASH_IN_FILENAME
+ // For MS-Windows et al. we don't double backslashes at the start and
+ // before a file name character.
+ // The reverse is found at stropt_copy_value().
+ for (var = buf; *var != NUL; MB_PTR_ADV(var)) {
+ if (var[0] == '\\' && var[1] == '\\'
+ && expand_option_idx >= 0
+ && (options[expand_option_idx].flags & P_EXPAND)
+ && vim_isfilec((uint8_t)var[2])
+ && (var[2] != '\\' || (var == buf && var[4] != '\\'))) {
+ STRMOVE(var, var + 1);
+ }
+ }
+#endif
+ return buf;
+}
+
+/// Expansion handler for :set= when we just want to fill in with the existing value.
+int ExpandOldSetting(int *numMatches, char ***matches)
{
char *var = NULL;
@@ -5629,26 +5707,149 @@ void ExpandOldSetting(int *numMatches, char ***matches)
var = "";
}
- // A backslash is required before some characters. This is the reverse of
- // what happens in do_set().
- char *buf = vim_strsave_escaped(var, escape_chars);
+ char *buf = escape_option_str_cmdline(var);
-#ifdef BACKSLASH_IN_FILENAME
- // For MS-Windows et al. we don't double backslashes at the start and
- // before a file name character.
- for (var = buf; *var != NUL; MB_PTR_ADV(var)) {
- if (var[0] == '\\' && var[1] == '\\'
- && expand_option_idx >= 0
- && (options[expand_option_idx].flags & P_EXPAND)
- && vim_isfilec((uint8_t)var[2])
- && (var[2] != '\\' || (var == buf && var[4] != '\\'))) {
- STRMOVE(var, var + 1);
+ (*matches)[0] = buf;
+ *numMatches = 1;
+ return OK;
+}
+
+/// Expansion handler for :set=/:set+= when the option has a custom expansion handler.
+int ExpandStringSetting(expand_T *xp, regmatch_T *regmatch, int *numMatches, char ***matches)
+{
+ if (expand_option_idx < 0
+ || options[expand_option_idx].opt_expand_cb == NULL) {
+ // Not supposed to reach this. This function is only for options with
+ // custom expansion callbacks.
+ return FAIL;
+ }
+
+ optexpand_T args = {
+ .oe_varp = get_varp_scope(&options[expand_option_idx], expand_option_flags),
+ .oe_append = expand_option_append,
+ .oe_regmatch = regmatch,
+ .oe_xp = xp,
+ .oe_set_arg = xp->xp_line + expand_option_start_col,
+ };
+ args.oe_include_orig_val = !expand_option_append && (*args.oe_set_arg == NUL);
+
+ // Retrieve the existing value, but escape it as a reverse of setting it.
+ // We technically only need to do this when oe_append or
+ // oe_include_orig_val is true.
+ option_value2string(&options[expand_option_idx], expand_option_flags);
+ char *var = NameBuff;
+ char *buf = escape_option_str_cmdline(var);
+ args.oe_opt_value = buf;
+
+ int num_ret = options[expand_option_idx].opt_expand_cb(&args, numMatches, matches);
+
+ xfree(buf);
+ return num_ret;
+}
+
+/// Expansion handler for :set-=
+int ExpandSettingSubtract(expand_T *xp, regmatch_T *regmatch, int *numMatches, char ***matches)
+{
+ if (expand_option_idx < 0) {
+ // term option
+ return ExpandOldSetting(numMatches, matches);
+ }
+
+ char *option_val = *(char **)get_option_varp_scope_from(expand_option_idx,
+ expand_option_flags,
+ curbuf, curwin);
+
+ uint32_t option_flags = options[expand_option_idx].flags;
+
+ if (option_flags & P_NUM) {
+ return ExpandOldSetting(numMatches, matches);
+ } else if (option_flags & P_COMMA) {
+ // Split the option by comma, then present each option to the user if
+ // it matches the pattern.
+ // This condition needs to go first, because 'whichwrap' has both
+ // P_COMMA and P_FLAGLIST.
+
+ if (*option_val == NUL) {
+ return FAIL;
}
+
+ // Make a copy as we need to inject null characters destructively.
+ char *option_copy = xstrdup(option_val);
+ char *next_val = option_copy;
+
+ garray_T ga;
+ ga_init(&ga, sizeof(char *), 10);
+
+ do {
+ char *item = next_val;
+ char *comma = vim_strchr(next_val, ',');
+ while (comma != NULL && comma != next_val && *(comma - 1) == '\\') {
+ // "\," is interpreted as a literal comma rather than option
+ // separator when reading options in copy_option_part(). Skip
+ // it.
+ comma = vim_strchr(comma + 1, ',');
+ }
+ if (comma != NULL) {
+ *comma = NUL; // null-terminate this value, required by later functions
+ next_val = comma + 1;
+ } else {
+ next_val = NULL;
+ }
+
+ if (*item == NUL) {
+ // empty value, don't add to list
+ continue;
+ }
+
+ if (!vim_regexec(regmatch, item, (colnr_T)0)) {
+ continue;
+ }
+
+ char *buf = escape_option_str_cmdline(item);
+ GA_APPEND(char *, &ga, buf);
+ } while (next_val != NULL);
+
+ xfree(option_copy);
+
+ *matches = ga.ga_data;
+ *numMatches = ga.ga_len;
+ return OK;
+ } else if (option_flags & P_FLAGLIST) {
+ // Only present the flags that are set on the option as the other flags
+ // are not meaningful to do set-= on.
+
+ if (*xp->xp_pattern != NUL) {
+ // Don't suggest anything if cmdline is non-empty. Vim's set-=
+ // behavior requires consecutive strings and it's usually
+ // unintuitive to users if ther try to subtract multiple flags at
+ // once.
+ return FAIL;
+ }
+
+ size_t num_flags = strlen(option_val);
+ if (num_flags == 0) {
+ return FAIL;
+ }
+
+ *matches = xmalloc(sizeof(char *) * (num_flags + 1));
+
+ int count = 0;
+
+ (*matches)[count++] = xstrdup(option_val);
+
+ if (num_flags > 1) {
+ // If more than one flags, split the flags up and expose each
+ // character as individual choice.
+ for (char *flag = option_val; *flag != NUL; flag++) {
+ (*matches)[count++] = xstrnsave(flag, 1);
+ }
+ }
+
+ *numMatches = count;
+ return OK;
}
-#endif
- *matches[0] = buf;
- *numMatches = 1;
+ return ExpandOldSetting(numMatches, matches);
}
/// Get the value for the numeric or string option///opp in a nice format into
@@ -5772,6 +5973,7 @@ int fill_culopt_flags(char *val, win_T *wp)
p = val;
}
while (*p != NUL) {
+ // Note: Keep this in sync with p_culopt_values.
if (strncmp(p, "line", 4) == 0) {
p += 4;
culopt_flags_new |= CULOPT_LINE;
diff --git a/src/nvim/option.h b/src/nvim/option.h
index 9e3bf25bc3..593917407a 100644
--- a/src/nvim/option.h
+++ b/src/nvim/option.h
@@ -4,9 +4,11 @@
#include <stdint.h>
#include "nvim/api/private/helpers.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/option_defs.h"
+#include "nvim/search.h"
/// The options that are local to a window or buffer have "indir" set to one of
/// these values. Special values:
@@ -45,7 +47,15 @@ typedef struct vimoption {
///< local option: indirect option index
///< callback function to invoke after an option is modified to validate and
///< apply the new value.
+
+ /// callback function to invoke after an option is modified to validate and
+ /// apply the new value.
opt_did_set_cb_T opt_did_set_cb;
+
+ /// callback function to invoke when expanding possible values on the
+ /// cmdline. Only useful for string options.
+ opt_expand_cb_T opt_expand_cb;
+
void *def_val; ///< default values for variable (neovim!!)
LastSet last_set; ///< script in which the option was last set
} vimoption_T;
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index f078f6073c..a11ed9188c 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -1,8 +1,12 @@
#ifndef NVIM_OPTION_DEFS_H
#define NVIM_OPTION_DEFS_H
+#include <stdbool.h>
+#include <stddef.h>
+
#include "nvim/api/private/defs.h"
-#include "nvim/eval/typval_defs.h"
+#include "nvim/cmdexpand_defs.h"
+#include "nvim/regexp_defs.h"
#include "nvim/types.h"
/// Option value type
@@ -25,6 +29,14 @@ typedef struct {
} data;
} OptVal;
+/// :set operator types
+typedef enum {
+ OP_NONE = 0,
+ OP_ADDING, ///< "opt+=arg"
+ OP_PREPENDING, ///< "opt^=arg"
+ OP_REMOVING, ///< "opt-=arg"
+} set_op_T;
+
/// Argument for the callback function (opt_did_set_cb_T) invoked after an
/// option value is modified.
typedef struct {
@@ -33,6 +45,7 @@ typedef struct {
void *os_varp;
int os_idx;
int os_flags;
+ set_op_T os_op;
/// old value of the option (can be a string, number or a boolean)
union {
@@ -80,4 +93,40 @@ typedef struct {
/// Otherwise returns an error message.
typedef const char *(*opt_did_set_cb_T)(optset_T *args);
+/// Argument for the callback function (opt_expand_cb_T) invoked after a string
+/// option value is expanded for cmdline completion.
+typedef struct {
+ /// Pointer to the option variable. It's always a string.
+ char *oe_varp;
+ /// The original option value, escaped.
+ char *oe_opt_value;
+
+ /// true if using set+= instead of set=
+ bool oe_append;
+ /// true if we would like to add the original option value as the first choice.
+ bool oe_include_orig_val;
+
+ /// Regex from the cmdline, for matching potential options against.
+ regmatch_T *oe_regmatch;
+ /// The expansion context.
+ expand_T *oe_xp;
+
+ /// The full argument passed to :set. For example, if the user inputs
+ /// ":set dip=icase,algorithm:my<Tab>", oe_xp->xp_pattern will only have
+ /// "my", but oe_set_arg will contain the whole "icase,algorithm:my".
+ char *oe_set_arg;
+} optexpand_T;
+
+/// Type for the callback function that is invoked when expanding possible
+/// string option values during cmdline completion.
+///
+/// Strings in returned matches will be managed and freed by caller.
+///
+/// Returns OK if the expansion succeeded (numMatches and matches have to be
+/// set). Otherwise returns FAIL.
+///
+/// Note: If returned FAIL or *numMatches is 0, *matches will NOT be freed by
+/// caller.
+typedef int (*opt_expand_cb_T)(optexpand_T *args, int *numMatches, char ***matches);
+
#endif // NVIM_OPTION_DEFS_H
diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h
index d8bbce21b3..86e7f4cee8 100644
--- a/src/nvim/option_vars.h
+++ b/src/nvim/option_vars.h
@@ -16,6 +16,7 @@
///< the same.
#define P_EXPAND 0x10U ///< environment expansion. NOTE: P_EXPAND can
///< never be used for local or hidden options
+#define P_NO_DEF_EXP 0x20U ///< do not expand default value
#define P_NODEFAULT 0x40U ///< don't set to default value
#define P_DEF_ALLOCED 0x80U ///< default value is in allocated memory, must
///< use free() when assigning new value
@@ -51,8 +52,10 @@
#define P_RWINONLY 0x10000000U ///< only redraw current window
#define P_MLE 0x20000000U ///< under control of 'modelineexpr'
#define P_FUNC 0x40000000U ///< accept a function reference or a lambda
-
-#define P_NO_DEF_EXP 0x80000000U ///< Do not expand default value.
+#define P_COLON 0x80000000U ///< values use colons to create sublists
+// Warning: Currently we have used all 32 bits for option flags, and adding more
+// flags will overflow it. Adding another flag will need to change how
+// it's stored first.
#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText,d:Directory,e:ErrorMsg," \
@@ -183,7 +186,7 @@
#define CPO_VI "aAbBcCdDeEfFiIJKlLmMnoOpPqrRsStuvWxXyZ$!%+>;_"
// characters for p_ww option:
-#define WW_ALL "bshl<>[],~"
+#define WW_ALL "bshl<>[]~"
// characters for p_mouse option:
#define MOUSE_NORMAL 'n' // use mouse in Normal mode
@@ -757,9 +760,9 @@ extern char *p_vfile; ///< 'verbosefile'
EXTERN int p_warn; ///< 'warn'
EXTERN char *p_wop; ///< 'wildoptions'
EXTERN unsigned wop_flags;
-#define WOP_TAGFILE 0x01
-#define WOP_PUM 0x02
-#define WOP_FUZZY 0x04
+#define WOP_FUZZY 0x01
+#define WOP_TAGFILE 0x02
+#define WOP_PUM 0x04
EXTERN OptInt p_window; ///< 'window'
EXTERN char *p_wak; ///< 'winaltkeys'
EXTERN char *p_wig; ///< 'wildignore'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index cd1d760836..a0b9306908 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -6,7 +6,7 @@
--- @field varname? string
--- @field pv_name? string
--- @field type 'bool'|'number'|'string'
---- @field list? 'comma'|'onecomma'|'flags'|'flagscomma'
+--- @field list? 'comma'|'onecomma'|'commacolon'|'onecommacolon'|'flags'|'flagscomma'
--- @field scope vim.option_scope[]
--- @field deny_duplicates? boolean
--- @field enable_if? string|false
@@ -25,6 +25,7 @@
--- @field alloced? true
--- @field redraw? vim.option_redraw[]
--- @field cb? string
+--- @field expand_cb? string
--- @field tags? string[]
--- @class vim.option_defaults
@@ -192,6 +193,7 @@ return {
set to one of CJK locales. See Unicode Standard Annex #11
(https://www.unicode.org/reports/tr11).
]=],
+ expand_cb = 'expand_set_ambiwidth',
full_name = 'ambiwidth',
redraw = { 'all_windows', 'ui_option' },
scope = { 'global' },
@@ -331,6 +333,7 @@ return {
option, you must load syntax.vim again to see the result. This can be
done with ":syntax on".
]=],
+ expand_cb = 'expand_set_background',
full_name = 'background',
scope = { 'global' },
short_desc = N_('"dark" or "light", used for highlight colors'),
@@ -357,6 +360,7 @@ return {
When the value is empty, Vi compatible backspacing is used, none of
the ways mentioned for the items above are possible.
]=],
+ expand_cb = 'expand_set_backspace',
full_name = 'backspace',
list = 'onecomma',
scope = { 'global' },
@@ -453,6 +457,7 @@ return {
the system may refuse to do this. In that case the "auto" value will
again not rename the file.
]=],
+ expand_cb = 'expand_set_backupcopy',
full_name = 'backupcopy',
list = 'onecomma',
scope = { 'global', 'buffer' },
@@ -621,6 +626,7 @@ return {
indicate that an error occurred. It can be silenced by adding the
"error" keyword.
]=],
+ expand_cb = 'expand_set_belloff',
full_name = 'belloff',
list = 'comma',
scope = { 'global' },
@@ -763,6 +769,7 @@ return {
added for the 'showbreak' setting.
(default: off)
]=],
+ expand_cb = 'expand_set_breakindentopt',
full_name = 'breakindentopt',
list = 'onecomma',
redraw = { 'current_buffer' },
@@ -816,6 +823,7 @@ return {
This option is used together with 'buftype' and 'swapfile' to specify
special kinds of buffers. See |special-buffers|.
]=],
+ expand_cb = 'expand_set_bufhidden',
full_name = 'bufhidden',
noglob = true,
scope = { 'buffer' },
@@ -893,6 +901,7 @@ return {
without saving. For writing there must be matching |BufWriteCmd|,
|FileWriteCmd| or |FileAppendCmd| autocommands.
]=],
+ expand_cb = 'expand_set_buftype',
full_name = 'buftype',
noglob = true,
scope = { 'buffer' },
@@ -917,6 +926,7 @@ return {
case mapping, the current locale is not effective.
This probably only matters for Turkish.
]=],
+ expand_cb = 'expand_set_casemap',
full_name = 'casemap',
list = 'onecomma',
scope = { 'global' },
@@ -1183,6 +1193,7 @@ return {
"*". See |clipboard|.
]=],
deny_duplicates = true,
+ expand_cb = 'expand_set_clipboard',
full_name = 'clipboard',
list = 'onecomma',
scope = { 'global' },
@@ -1369,6 +1380,7 @@ return {
based expansion (e.g., dictionary |i_CTRL-X_CTRL-K|, included patterns
|i_CTRL-X_CTRL-I|, tags |i_CTRL-X_CTRL-]| and normal expansions).
]=],
+ expand_cb = 'expand_set_complete',
full_name = 'complete',
list = 'onecomma',
scope = { 'buffer' },
@@ -1399,7 +1411,9 @@ return {
Keep in mind that the cursor position is not always where it's
displayed. E.g., when moving vertically it may change column.
]=],
+ expand_cb = 'expand_set_concealcursor',
full_name = 'concealcursor',
+ list = 'flags',
redraw = { 'current_window' },
scope = { 'window' },
short_desc = N_('whether concealable text is hidden in cursor line'),
@@ -1492,6 +1506,7 @@ return {
select one from the menu. Only works in combination with
"menu" or "menuone".
]=],
+ expand_cb = 'expand_set_completeopt',
full_name = 'completeopt',
list = 'onecomma',
scope = { 'global' },
@@ -1517,6 +1532,7 @@ return {
command line completion the global value is used.
]=],
enable_if = 'BACKSLASH_IN_FILENAME',
+ expand_cb = 'expand_set_completeslash',
full_name = 'completeslash',
scope = { 'buffer' },
type = 'string',
@@ -1797,6 +1813,7 @@ return {
_ When using |cw| on a word, do not include the
whitespace following the word in the motion.
]=],
+ expand_cb = 'expand_set_cpoptions',
full_name = 'cpoptions',
list = 'flags',
redraw = { 'all_windows' },
@@ -1878,6 +1895,7 @@ return {
"line" and "screenline" cannot be used together.
]=],
+ expand_cb = 'expand_set_cursorlineopt',
full_name = 'cursorlineopt',
list = 'onecomma',
redraw = { 'current_window_only' },
@@ -1900,6 +1918,7 @@ return {
"msg" and "throw" are useful for debugging 'foldexpr', 'formatexpr' or
'indentexpr'.
]=],
+ expand_cb = 'expand_set_debug',
full_name = 'debug',
scope = { 'global' },
short_desc = N_('to "msg" to see all error messages'),
@@ -2048,7 +2067,8 @@ return {
When omitted a context of six lines is used.
When using zero the context is actually one,
since folds require a line in between, also
- for a deleted line.
+ for a deleted line. Set it to a very large
+ value (999999) to disable folding completely.
See |fold-diff|.
iblank Ignore changes where lines are all blank. Adds
@@ -2140,8 +2160,9 @@ return {
:set diffopt-=internal " do NOT use the internal diff parser
<
]=],
+ expand_cb = 'expand_set_diffopt',
full_name = 'diffopt',
- list = 'onecomma',
+ list = 'onecommacolon',
redraw = { 'current_window' },
scope = { 'global' },
short_desc = N_('options for using diff mode'),
@@ -2242,6 +2263,7 @@ return {
The "@" character can be changed by setting the "lastline" item in
'fillchars'. The character is highlighted with |hl-NonText|.
]=],
+ expand_cb = 'expand_set_display',
full_name = 'display',
list = 'onecomma',
redraw = { 'all_windows' },
@@ -2260,6 +2282,7 @@ return {
hor horizontally, height of windows is not affected
both width and height of windows is affected
]=],
+ expand_cb = 'expand_set_eadirection',
full_name = 'eadirection',
scope = { 'global' },
short_desc = N_("in which direction 'equalalways' works"),
@@ -2470,6 +2493,7 @@ return {
:set ei=WinEnter,WinLeave
<
]=],
+ expand_cb = 'expand_set_eventignore',
full_name = 'eventignore',
list = 'onecomma',
scope = { 'global' },
@@ -2558,6 +2582,7 @@ return {
This option cannot be changed when 'modifiable' is off.
]=],
+ expand_cb = 'expand_set_encoding',
full_name = 'fileencoding',
no_mkrc = true,
redraw = { 'statuslines', 'current_buffer' },
@@ -2619,6 +2644,7 @@ return {
Setting this option does not have an effect until the next time a file
is read.
]=],
+ expand_cb = 'expand_set_encoding',
full_name = 'fileencodings',
list = 'onecomma',
scope = { 'global' },
@@ -2651,6 +2677,7 @@ return {
option is set, because the file would be different when written.
This option cannot be changed when 'modifiable' is off.
]=],
+ expand_cb = 'expand_set_fileformat',
full_name = 'fileformat',
no_mkrc = true,
redraw = { 'curswant', 'statuslines' },
@@ -2714,6 +2741,7 @@ return {
used.
Also see |file-formats|.
]=],
+ expand_cb = 'expand_set_fileformat',
full_name = 'fileformats',
list = 'onecomma',
scope = { 'global' },
@@ -2846,6 +2874,7 @@ return {
eob EndOfBuffer |hl-EndOfBuffer|
lastline NonText |hl-NonText|
]=],
+ expand_cb = 'expand_set_chars_option',
full_name = 'fillchars',
list = 'onecomma',
redraw = { 'current_window' },
@@ -2884,6 +2913,7 @@ return {
its level is higher than 'foldlevel'. Useful if you want folds to
automatically close when moving out of them.
]=],
+ expand_cb = 'expand_set_foldclose',
full_name = 'foldclose',
list = 'onecomma',
redraw = { 'current_window' },
@@ -2906,6 +2936,7 @@ return {
"[1-9]": to display a fixed number of columns
See |folding|.
]=],
+ expand_cb = 'expand_set_foldcolumn',
full_name = 'foldcolumn',
redraw = { 'current_window' },
scope = { 'window' },
@@ -3045,6 +3076,7 @@ return {
|fold-syntax| syntax Syntax highlighting items specify folds.
|fold-diff| diff Fold text that is not changed.
]=],
+ expand_cb = 'expand_set_foldmethod',
full_name = 'foldmethod',
redraw = { 'current_window' },
scope = { 'window' },
@@ -3122,6 +3154,7 @@ return {
To close folds you can re-apply 'foldlevel' with the |zx| command or
set the 'foldclose' option to "all".
]=],
+ expand_cb = 'expand_set_foldopen',
full_name = 'foldopen',
list = 'onecomma',
redraw = { 'curswant' },
@@ -3218,6 +3251,7 @@ return {
To avoid problems with flags that are added in the future, use the
"+=" and "-=" feature of ":set" |add-option-flags|.
]=],
+ expand_cb = 'expand_set_formatoptions',
full_name = 'formatoptions',
list = 'flags',
scope = { 'buffer' },
@@ -4050,6 +4084,7 @@ return {
'redrawtime') then 'inccommand' is automatically disabled until
|Command-line-mode| is done.
]=],
+ expand_cb = 'expand_set_inccommand',
full_name = 'inccommand',
scope = { 'global' },
short_desc = N_('Live preview of substitution'),
@@ -4451,6 +4486,7 @@ return {
|alternate-file| or using |mark-motions| try to
restore the |mark-view| in which the action occurred.
]=],
+ expand_cb = 'expand_set_jumpoptions',
full_name = 'jumpoptions',
list = 'onecomma',
scope = { 'global' },
@@ -4495,6 +4531,7 @@ return {
Special keys in this context are the cursor keys, <End>, <Home>,
<PageUp> and <PageDown>.
]=],
+ expand_cb = 'expand_set_keymodel',
full_name = 'keymodel',
list = 'onecomma',
scope = { 'global' },
@@ -4779,6 +4816,7 @@ return {
Note that when using 'indentexpr' the `=` operator indents all the
lines, otherwise the first line is not indented (Vi-compatible).
]=],
+ expand_cb = 'expand_set_lispoptions',
full_name = 'lispoptions',
list = 'onecomma',
pv_name = 'p_lop',
@@ -4933,6 +4971,7 @@ return {
"precedes". |hl-Whitespace| for "nbsp", "space", "tab", "multispace",
"lead" and "trail".
]=],
+ expand_cb = 'expand_set_chars_option',
full_name = 'listchars',
list = 'onecomma',
redraw = { 'current_window' },
@@ -5015,6 +5054,7 @@ return {
:set makeencoding=char " system locale is used
<
]=],
+ expand_cb = 'expand_set_encoding',
full_name = 'makeencoding',
scope = { 'global', 'buffer' },
short_desc = N_('Converts the output of external commands'),
@@ -5377,6 +5417,7 @@ return {
'mousehide' hide mouse pointer while typing text
'selectmode' whether to start Select mode or Visual mode
]=],
+ expand_cb = 'expand_set_mouse',
full_name = 'mouse',
list = 'flags',
scope = { 'global' },
@@ -5468,6 +5509,7 @@ return {
"g<LeftMouse>" is "<C-LeftMouse> (jump to tag under mouse click)
"g<RightMouse>" is "<C-RightMouse> ("CTRL-T")
]=],
+ expand_cb = 'expand_set_mousemodel',
full_name = 'mousemodel',
scope = { 'global' },
short_desc = N_('changes meaning of mouse buttons'),
@@ -5513,6 +5555,7 @@ return {
< Will make Nvim scroll 5 lines at a time when scrolling vertically, and
scroll 2 columns at a time when scrolling horizontally.
]=],
+ expand_cb = 'expand_set_mousescroll',
full_name = 'mousescroll',
list = 'comma',
scope = { 'global' },
@@ -5645,6 +5688,7 @@ return {
considered decimal. This also happens for numbers that are not
recognized as octal or hex.
]=],
+ expand_cb = 'expand_set_nrformats',
full_name = 'nrformats',
list = 'onecomma',
scope = { 'buffer' },
@@ -6307,6 +6351,7 @@ return {
This is useful for languages such as Hebrew, Arabic and Farsi.
The 'rightleft' option must be set for 'rightleftcmd' to take effect.
]=],
+ expand_cb = 'expand_set_rightleftcmd',
full_name = 'rightleftcmd',
redraw = { 'current_window' },
scope = { 'window' },
@@ -6634,6 +6679,7 @@ return {
When 'diff' mode is active there always is vertical scroll binding,
even when "ver" isn't there.
]=],
+ expand_cb = 'expand_set_scrollopt',
full_name = 'scrollopt',
list = 'onecomma',
scope = { 'global' },
@@ -6687,6 +6733,7 @@ return {
backwards, you cannot include the last character of a line, when
starting in Normal mode and 'virtualedit' empty.
]=],
+ expand_cb = 'expand_set_selection',
full_name = 'selection',
scope = { 'global' },
short_desc = N_('what type of selection to use'),
@@ -6707,6 +6754,7 @@ return {
cmd when using "v", "V" or CTRL-V
See |Select-mode|.
]=],
+ expand_cb = 'expand_set_selectmode',
full_name = 'selectmode',
list = 'onecomma',
scope = { 'global' },
@@ -6758,6 +6806,7 @@ return {
If you leave out "options" many things won't work well after restoring
the session.
]=],
+ expand_cb = 'expand_set_sessionoptions',
full_name = 'sessionoptions',
list = 'onecomma',
scope = { 'global' },
@@ -7292,6 +7341,7 @@ return {
shm=a Abbreviation, but no loss of information.
shm=at Abbreviation, and truncate message when necessary.
]=],
+ expand_cb = 'expand_set_shortmess',
full_name = 'shortmess',
list = 'flags',
scope = { 'global' },
@@ -7368,6 +7418,7 @@ return {
place the text. Without a custom 'statusline' or 'tabline' it will be
displayed in a convenient location.
]=],
+ expand_cb = 'expand_set_showcmdloc',
full_name = 'showcmdloc',
scope = { 'global' },
short_desc = N_('change location of partial command'),
@@ -7530,6 +7581,7 @@ return {
This is done in order for the signcolumn appearance not appear weird
during line deletion.
]=],
+ expand_cb = 'expand_set_signcolumn',
full_name = 'signcolumn',
redraw = { 'current_window' },
scope = { 'window' },
@@ -7828,6 +7880,7 @@ return {
security reasons.
]=],
expand = true,
+ expand_cb = 'expand_set_spellsuggest',
full_name = 'spellsuggest',
list = 'onecomma',
scope = { 'global' },
@@ -7852,7 +7905,7 @@ return {
designated regions of the buffer are spellchecked in
this case.
]=],
- expand = true,
+ expand_cb = 'expand_set_spelloptions',
full_name = 'spelloptions',
list = 'onecomma',
redraw = { 'current_buffer' },
@@ -7892,6 +7945,7 @@ return {
with the previous cursor position. For "screen", the text cannot always
be kept on the same screen line when 'wrap' is enabled.
]=],
+ expand_cb = 'expand_set_splitkeep',
full_name = 'splitkeep',
scope = { 'global' },
short_desc = N_('determines scroll behavior for split windows'),
@@ -8326,6 +8380,7 @@ return {
uselast If included, jump to the previously used window when
jumping to errors with |quickfix| commands.
]=],
+ expand_cb = 'expand_set_switchbuf',
full_name = 'switchbuf',
list = 'onecomma',
scope = { 'global' },
@@ -8580,6 +8635,7 @@ return {
match Match case
smart Ignore case unless an upper case letter is used
]=],
+ expand_cb = 'expand_set_tagcase',
full_name = 'tagcase',
scope = { 'global', 'buffer' },
short_desc = N_('how to handle case when searching in tags files'),
@@ -8728,6 +8784,7 @@ return {
C1 Control characters 0x80...0x9F
]=],
+ expand_cb = 'expand_set_termpastefilter',
full_name = 'termpastefilter',
list = 'onecomma',
scope = { 'global' },
@@ -9275,6 +9332,7 @@ return {
slash |deprecated| Always enabled. Uses "/" in filenames.
unix |deprecated| Always enabled. Uses "\n" line endings.
]=],
+ expand_cb = 'expand_set_sessionoptions',
full_name = 'viewoptions',
list = 'onecomma',
scope = { 'global' },
@@ -9331,6 +9389,7 @@ return {
not get a warning for it.
When combined with other words, "none" is ignored.
]=],
+ expand_cb = 'expand_set_virtualedit',
full_name = 'virtualedit',
list = 'onecomma',
redraw = { 'curswant' },
@@ -9395,6 +9454,7 @@ return {
line (not an empty line) then it will not move to the next line. This
makes "dl", "cl", "yl" etc. work normally.
]=],
+ expand_cb = 'expand_set_whichwrap',
full_name = 'whichwrap',
list = 'flagscomma',
scope = { 'global' },
@@ -9578,8 +9638,9 @@ return {
< Complete longest common string, then list alternatives.
More info here: |cmdline-completion|.
]=],
+ expand_cb = 'expand_set_wildmode',
full_name = 'wildmode',
- list = 'onecomma',
+ list = 'onecommacolon',
scope = { 'global' },
short_desc = N_("mode for 'wildchar' command-line expansion"),
type = 'string',
@@ -9609,6 +9670,7 @@ return {
d #define
f function
]=],
+ expand_cb = 'expand_set_wildoptions',
full_name = 'wildoptions',
list = 'onecomma',
scope = { 'global' },
@@ -9637,6 +9699,7 @@ return {
key is never used for the menu.
This option is not used for <F10>; on Win32.
]=],
+ expand_cb = 'expand_set_winaltkeys',
full_name = 'winaltkeys',
scope = { 'global' },
short_desc = N_('when the windows system handles ALT keys'),
@@ -9691,7 +9754,7 @@ return {
{
abbreviation = 'winhl',
alloced = true,
- cb = 'did_set_winhl',
+ cb = 'did_set_winhighlight',
defaults = { if_true = '' },
deny_duplicates = true,
desc = [=[
@@ -9713,8 +9776,9 @@ return {
set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC
<
]=],
+ expand_cb = 'expand_set_winhighlight',
full_name = 'winhighlight',
- list = 'onecomma',
+ list = 'onecommacolon',
redraw = { 'current_window' },
scope = { 'window' },
short_desc = N_('Setup window-local highlights'),
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 750941da07..6f41bba99b 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -11,6 +11,8 @@
#include "nvim/autocmd.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/cursor_shape.h"
#include "nvim/diff.h"
@@ -41,6 +43,7 @@
#include "nvim/optionstr.h"
#include "nvim/os/os.h"
#include "nvim/pos.h"
+#include "nvim/regexp.h"
#include "nvim/runtime.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
@@ -72,12 +75,25 @@ static char *(p_bkc_values[]) = { "yes", "auto", "no", "breaksymlink", "breakhar
static char *(p_bo_values[]) = { "all", "backspace", "cursor", "complete", "copy", "ctrlg", "error",
"esc", "ex", "hangul", "lang", "mess", "showmatch", "operator",
"register", "shell", "spell", "wildmode", NULL };
+// Note: Keep this in sync with briopt_check()
+static char *(p_briopt_values[]) = { "shift:", "min:", "sbr", "list:", "column:", NULL };
+// Note: Keep this in sync with diffopt_changed()
+static char *(p_dip_values[]) = { "filler", "context:", "iblank", "icase",
+ "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical",
+ "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal",
+ "indent-heuristic", "linematch:", "algorithm:", NULL };
+static char *(p_dip_algorithm_values[]) = { "myers", "minimal", "patience", "histogram", NULL };
static char *(p_nf_values[]) = { "bin", "octal", "hex", "alpha", "unsigned", NULL };
static char *(p_ff_values[]) = { FF_UNIX, FF_DOS, FF_MAC, NULL };
+static char *(p_cb_values[]) = { "unnamed", "unnamedplus", NULL };
static char *(p_cmp_values[]) = { "internal", "keepascii", NULL };
+// Note: Keep this in sync with fill_culopt_flags()
+static char *(p_culopt_values[]) = { "line", "screenline", "number", "both", NULL };
static char *(p_dy_values[]) = { "lastline", "truncate", "uhex", "msgsep", NULL };
static char *(p_fdo_values[]) = { "all", "block", "hor", "mark", "percent", "quickfix", "search",
"tag", "insert", "undo", "jump", NULL };
+// Note: Keep this in sync with spell_check_sps()
+static char *(p_sps_values[]) = { "best", "fast", "double", "expr:", "file:", "timeout:", NULL };
/// Also used for 'viewoptions'! Keep in sync with SSOP_ flags.
static char *(p_ssop_values[]) = { "buffers", "winpos", "resize", "winsize", "localoptions",
"options", "help", "blank", "globals", "slash", "unix", "sesdir",
@@ -89,7 +105,9 @@ static char *(p_swb_values[]) = { "useopen", "usetab", "split", "newtab", "vspli
static char *(p_spk_values[]) = { "cursor", "screen", "topline", NULL };
static char *(p_tc_values[]) = { "followic", "ignore", "match", "followscs", "smart", NULL };
static char *(p_ve_values[]) = { "block", "insert", "all", "onemore", "none", "NONE", NULL };
-static char *(p_wop_values[]) = { "tagfile", "pum", "fuzzy", NULL };
+// Note: Keep this in sync with check_opt_wim()
+static char *(p_wim_values[]) = { "full", "longest", "list", "lastused", NULL };
+static char *(p_wop_values[]) = { "fuzzy", "tagfile", "pum", NULL };
static char *(p_wak_values[]) = { "yes", "menu", "no", NULL };
static char *(p_mousem_values[]) = { "extend", "popup", "popup_setpos", "mac", NULL };
static char *(p_sel_values[]) = { "inclusive", "exclusive", "old", NULL };
@@ -118,7 +136,6 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2", "auto
static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2", "auto:3", "auto:4", "auto:5",
"auto:6", "auto:7", "auto:8", "auto:9", "0", "1", "2", "3", "4",
"5", "6", "7", "8", "9", NULL };
-static char *(p_cb_values[]) = { "unnamed", "unnamedplus", NULL };
static char *(p_spo_values[]) = { "camel", "noplainbuffer", NULL };
static char *(p_icm_values[]) = { "nosplit", "split", NULL };
static char *(p_jop_values[]) = { "stack", "view", NULL };
@@ -487,8 +504,9 @@ const char *set_string_option(const int opt_idx, void *varp_arg, const char *val
secure = 1;
}
- const char *const errmsg = did_set_string_option(curbuf, curwin, opt_idx, varp, oldval, errbuf,
- errbuflen, opt_flags, value_checked);
+ const char *const errmsg = did_set_string_option(curbuf, curwin, opt_idx, varp, oldval,
+ errbuf, errbuflen,
+ opt_flags, OP_NONE, value_checked);
secure = secure_saved;
@@ -659,6 +677,116 @@ static const char *did_set_option_listflag(char *val, char *flags, char *errbuf,
return NULL;
}
+/// Expand an option that accepts a list of string values.
+static int expand_set_opt_string(optexpand_T *args, char **values, size_t numValues,
+ int *numMatches, char ***matches)
+{
+ regmatch_T *regmatch = args->oe_regmatch;
+ bool include_orig_val = args->oe_include_orig_val;
+ char *option_val = args->oe_opt_value;
+
+ // Assume numValues is small since they are fixed enums, so just allocate
+ // upfront instead of needing two passes to calculate output size.
+ *matches = xmalloc(sizeof(char *) * (numValues + 1));
+
+ int count = 0;
+
+ if (include_orig_val && *option_val != NUL) {
+ (*matches)[count++] = xstrdup(option_val);
+ }
+
+ for (char **val = values; *val != NULL; val++) {
+ if (include_orig_val && *option_val != NUL) {
+ if (strcmp(*val, option_val) == 0) {
+ continue;
+ }
+ }
+ if (vim_regexec(regmatch, *val, (colnr_T)0)) {
+ (*matches)[count++] = xstrdup(*val);
+ }
+ }
+ if (count == 0) {
+ XFREE_CLEAR(*matches);
+ return FAIL;
+ }
+ *numMatches = count;
+ return OK;
+}
+
+static char *set_opt_callback_orig_option = NULL;
+static char *((*set_opt_callback_func)(expand_T *, int));
+
+/// Callback used by expand_set_opt_generic to also include the original value.
+static char *expand_set_opt_callback(expand_T *xp, int idx)
+{
+ if (idx == 0) {
+ if (set_opt_callback_orig_option != NULL) {
+ return set_opt_callback_orig_option;
+ } else {
+ return ""; // empty strings are ignored
+ }
+ }
+ return set_opt_callback_func(xp, idx - 1);
+}
+
+/// Expand an option with a callback that iterates through a list of possible names.
+static int expand_set_opt_generic(optexpand_T *args, CompleteListItemGetter func, int *numMatches,
+ char ***matches)
+{
+ set_opt_callback_orig_option = args->oe_include_orig_val ? args->oe_opt_value : NULL;
+ set_opt_callback_func = func;
+
+ // not using fuzzy as currently EXPAND_STRING_SETTING doesn't use it
+ ExpandGeneric("", args->oe_xp, args->oe_regmatch, matches, numMatches,
+ expand_set_opt_callback, false);
+
+ set_opt_callback_orig_option = NULL;
+ set_opt_callback_func = NULL;
+ return OK;
+}
+
+/// Expand an option which is a list of flags.
+static int expand_set_opt_listflag(optexpand_T *args, char *flags, int *numMatches, char ***matches)
+{
+ char *option_val = args->oe_opt_value;
+ char *cmdline_val = args->oe_set_arg;
+ bool append = args->oe_append;
+ bool include_orig_val = args->oe_include_orig_val && (*option_val != NUL);
+
+ size_t num_flags = strlen(flags);
+
+ // Assume we only have small number of flags, so just allocate max size.
+ *matches = xmalloc(sizeof(char *) * (num_flags + 1));
+
+ int count = 0;
+
+ if (include_orig_val) {
+ (*matches)[count++] = xstrdup(option_val);
+ }
+
+ for (char *flag = flags; *flag != NUL; flag++) {
+ if (append && vim_strchr(option_val, *flag) != NULL) {
+ continue;
+ }
+
+ if (vim_strchr(cmdline_val, *flag) == NULL) {
+ if (include_orig_val && option_val[1] == NUL && *flag == option_val[0]) {
+ // This value is already used as the first choice as it's the
+ // existing flag. Just skip it to avoid duplicate.
+ continue;
+ }
+ (*matches)[count++] = xstrnsave(flag, 1);
+ }
+ }
+
+ if (count == 0) {
+ XFREE_CLEAR(*matches);
+ return FAIL;
+ }
+ *numMatches = count;
+ return OK;
+}
+
/// The 'ambiwidth' option is changed.
const char *did_set_ambiwidth(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -668,6 +796,15 @@ const char *did_set_ambiwidth(optset_T *args FUNC_ATTR_UNUSED)
return check_chars_options();
}
+int expand_set_ambiwidth(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_ambw_values,
+ ARRAY_SIZE(p_ambw_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'background' option is changed.
const char *did_set_background(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -692,6 +829,15 @@ const char *did_set_background(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_background(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_bg_values,
+ ARRAY_SIZE(p_bg_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'backspace' option is changed.
const char *did_set_backspace(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -705,6 +851,15 @@ const char *did_set_backspace(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_backspace(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_bs_values,
+ ARRAY_SIZE(p_bs_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'backupcopy' option is changed.
const char *did_set_backupcopy(optset_T *args)
{
@@ -739,6 +894,15 @@ const char *did_set_backupcopy(optset_T *args)
return NULL;
}
+int expand_set_backupcopy(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_bkc_values,
+ ARRAY_SIZE(p_bkc_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'backupext' or the 'patchmode' option is changed.
const char *did_set_backupext_or_patchmode(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -756,6 +920,15 @@ const char *did_set_belloff(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_flags(p_bo, p_bo_values, &bo_flags, true);
}
+int expand_set_belloff(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_bo_values,
+ ARRAY_SIZE(p_bo_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'breakindentopt' option is changed.
const char *did_set_breakindentopt(optset_T *args)
{
@@ -771,6 +944,15 @@ const char *did_set_breakindentopt(optset_T *args)
return NULL;
}
+int expand_set_breakindentopt(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_briopt_values,
+ ARRAY_SIZE(p_briopt_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'bufhidden' option is changed.
const char *did_set_bufhidden(optset_T *args)
{
@@ -778,6 +960,15 @@ const char *did_set_bufhidden(optset_T *args)
return did_set_opt_strings(buf->b_p_bh, p_bufhidden_values, false);
}
+int expand_set_bufhidden(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_bufhidden_values,
+ ARRAY_SIZE(p_bufhidden_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'buftype' option is changed.
const char *did_set_buftype(optset_T *args)
{
@@ -798,12 +989,30 @@ const char *did_set_buftype(optset_T *args)
return NULL;
}
+int expand_set_buftype(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_buftype_values,
+ ARRAY_SIZE(p_buftype_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'casemap' option is changed.
const char *did_set_casemap(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_flags(p_cmp, p_cmp_values, &cmp_flags, true);
}
+int expand_set_casemap(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_cmp_values,
+ ARRAY_SIZE(p_cmp_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The global 'listchars' or 'fillchars' option is changed.
static const char *did_set_global_listfillchars(win_T *win, char *val, bool opt_lcs, int opt_flags)
{
@@ -867,6 +1076,17 @@ const char *did_set_chars_option(optset_T *args)
return errmsg;
}
+/// Expand 'fillchars' or 'listchars' option value.
+int expand_set_chars_option(optexpand_T *args, int *numMatches, char ***matches)
+{
+ char **varp = (char **)args->oe_varp;
+ bool is_lcs = (varp == &p_lcs || varp == &curwin->w_p_lcs);
+ return expand_set_opt_generic(args,
+ is_lcs ? get_listchars_name : get_fillchars_name,
+ numMatches,
+ matches);
+}
+
/// The 'cinoptions' option is changed.
const char *did_set_cinoptions(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -882,6 +1102,15 @@ const char *did_set_clipboard(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_flags(p_cb, p_cb_values, &cb_flags, true);
}
+int expand_set_clipboard(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_cb_values,
+ ARRAY_SIZE(p_cb_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'colorcolumn' option is changed.
const char *did_set_colorcolumn(optset_T *args)
{
@@ -972,6 +1201,18 @@ const char *did_set_complete(optset_T *args)
return NULL;
}
+int expand_set_complete(optexpand_T *args, int *numMatches, char ***matches)
+{
+ static char *(p_cpt_values[]) = {
+ ".", "w", "b", "u", "k", "kspell", "s", "i", "d", "]", "t", "U", NULL
+ };
+ return expand_set_opt_string(args,
+ p_cpt_values,
+ ARRAY_SIZE(p_cpt_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'completeopt' option is changed.
const char *did_set_completeopt(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -982,6 +1223,15 @@ const char *did_set_completeopt(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_completeopt(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_cot_values,
+ ARRAY_SIZE(p_cot_values) - 1,
+ numMatches,
+ matches);
+}
+
#ifdef BACKSLASH_IN_FILENAME
/// The 'completeslash' option is changed.
const char *did_set_completeslash(optset_T *args)
@@ -993,6 +1243,15 @@ const char *did_set_completeslash(optset_T *args)
}
return NULL;
}
+
+int expand_set_completeslash(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_csl_values,
+ ARRAY_SIZE(p_csl_values) - 1,
+ numMatches,
+ matches);
+}
#endif
/// The 'concealcursor' option is changed.
@@ -1003,6 +1262,11 @@ const char *did_set_concealcursor(optset_T *args)
return did_set_option_listflag(*varp, COCU_ALL, args->os_errbuf, args->os_errbuflen);
}
+int expand_set_concealcursor(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_listflag(args, COCU_ALL, numMatches, matches);
+}
+
/// The 'cpoptions' option is changed.
const char *did_set_cpoptions(optset_T *args)
{
@@ -1011,12 +1275,18 @@ const char *did_set_cpoptions(optset_T *args)
return did_set_option_listflag(*varp, CPO_VI, args->os_errbuf, args->os_errbuflen);
}
+int expand_set_cpoptions(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_listflag(args, CPO_VI, numMatches, matches);
+}
+
/// The 'cursorlineopt' option is changed.
const char *did_set_cursorlineopt(optset_T *args)
{
win_T *win = (win_T *)args->os_win;
char **varp = (char **)args->os_varp;
+ // This could be changed to use opt_strings_flags() instead.
if (**varp == NUL || fill_culopt_flags(*varp, win) != OK) {
return e_invarg;
}
@@ -1024,12 +1294,30 @@ const char *did_set_cursorlineopt(optset_T *args)
return NULL;
}
+int expand_set_cursorlineopt(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_culopt_values,
+ ARRAY_SIZE(p_culopt_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'debug' option is changed.
const char *did_set_debug(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_strings(p_debug, p_debug_values, false);
}
+int expand_set_debug(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_debug_values,
+ ARRAY_SIZE(p_debug_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'diffopt' option is changed.
const char *did_set_diffopt(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -1039,6 +1327,31 @@ const char *did_set_diffopt(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_diffopt(optexpand_T *args, int *numMatches, char ***matches)
+{
+ expand_T *xp = args->oe_xp;
+
+ if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern - 1) == ':') {
+ // Within "algorithm:", we have a subgroup of possible options.
+ const size_t algo_len = strlen("algorithm:");
+ if (xp->xp_pattern - args->oe_set_arg >= (int)algo_len
+ && strncmp(xp->xp_pattern - algo_len, "algorithm:", algo_len) == 0) {
+ return expand_set_opt_string(args,
+ p_dip_algorithm_values,
+ ARRAY_SIZE(p_dip_algorithm_values) - 1,
+ numMatches,
+ matches);
+ }
+ return FAIL;
+ }
+
+ return expand_set_opt_string(args,
+ p_dip_values,
+ ARRAY_SIZE(p_dip_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'display' option is changed.
const char *did_set_display(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -1050,12 +1363,30 @@ const char *did_set_display(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_display(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_dy_values,
+ ARRAY_SIZE(p_dy_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'eadirection' option is changed.
const char *did_set_eadirection(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_strings(p_ead, p_ead_values, false);
}
+int expand_set_eadirection(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_ead_values,
+ ARRAY_SIZE(p_ead_values) - 1,
+ numMatches,
+ matches);
+}
+
/// One of the 'encoding', 'fileencoding' or 'makeencoding'
/// options is changed.
const char *did_set_encoding(optset_T *args)
@@ -1098,6 +1429,11 @@ const char *did_set_encoding(optset_T *args)
return NULL;
}
+int expand_set_encoding(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_generic(args, get_encoding_name, numMatches, matches);
+}
+
/// The 'eventignore' option is changed.
const char *did_set_eventignore(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -1107,6 +1443,21 @@ const char *did_set_eventignore(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+static char *get_eventignore_name(expand_T *xp, int idx)
+{
+ // 'eventignore' allows special keyword "all" in addition to
+ // all event names.
+ if (idx == 0) {
+ return "all";
+ }
+ return get_event_name_no_group(xp, idx - 1);
+}
+
+int expand_set_eventignore(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_generic(args, get_eventignore_name, numMatches, matches);
+}
+
/// The 'fileformat' option is changed.
const char *did_set_fileformat(optset_T *args)
{
@@ -1130,6 +1481,15 @@ const char *did_set_fileformat(optset_T *args)
return NULL;
}
+int expand_set_fileformat(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_ff_values,
+ ARRAY_SIZE(p_ff_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'fileformats' option is changed.
const char *did_set_fileformats(optset_T *args)
{
@@ -1160,6 +1520,15 @@ const char *did_set_foldclose(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_strings(p_fcl, p_fcl_values, true);
}
+int expand_set_foldclose(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_fcl_values,
+ ARRAY_SIZE(p_fcl_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'foldcolumn' option is changed.
const char *did_set_foldcolumn(optset_T *args)
{
@@ -1170,6 +1539,15 @@ const char *did_set_foldcolumn(optset_T *args)
return NULL;
}
+int expand_set_foldcolumn(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_fdc_values,
+ ARRAY_SIZE(p_fdc_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'foldexpr' option is changed.
const char *did_set_foldexpr(optset_T *args)
{
@@ -1229,12 +1607,30 @@ const char *did_set_foldmethod(optset_T *args)
return NULL;
}
+int expand_set_foldmethod(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_fdm_values,
+ ARRAY_SIZE(p_fdm_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'foldopen' option is changed.
const char *did_set_foldopen(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_flags(p_fdo, p_fdo_values, &fdo_flags, true);
}
+int expand_set_foldopen(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_fdo_values,
+ ARRAY_SIZE(p_fdo_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'formatoptions' option is changed.
const char *did_set_formatoptions(optset_T *args)
{
@@ -1243,6 +1639,11 @@ const char *did_set_formatoptions(optset_T *args)
return did_set_option_listflag(*varp, FO_ALL, args->os_errbuf, args->os_errbuflen);
}
+int expand_set_formatoptions(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_listflag(args, FO_ALL, numMatches, matches);
+}
+
/// The 'guicursor' option is changed.
const char *did_set_guicursor(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -1300,6 +1701,15 @@ const char *did_set_inccommand(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_strings(p_icm, p_icm_values, false);
}
+int expand_set_inccommand(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_icm_values,
+ ARRAY_SIZE(p_icm_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'isident' or the 'iskeyword' or the 'isprint' or the 'isfname' option is
/// changed.
const char *did_set_isopt(optset_T *args)
@@ -1321,6 +1731,15 @@ const char *did_set_jumpoptions(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_flags(p_jop, p_jop_values, &jop_flags, true);
}
+int expand_set_jumpoptions(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_jop_values,
+ ARRAY_SIZE(p_jop_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'keymap' option has changed.
const char *did_set_keymap(optset_T *args)
{
@@ -1384,6 +1803,15 @@ const char *did_set_keymodel(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_keymodel(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_km_values,
+ ARRAY_SIZE(p_km_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'lispoptions' option is changed.
const char *did_set_lispoptions(optset_T *args)
{
@@ -1395,6 +1823,16 @@ const char *did_set_lispoptions(optset_T *args)
return NULL;
}
+int expand_set_lispoptions(optexpand_T *args, int *numMatches, char ***matches)
+{
+ static char *(p_lop_values[]) = { "expr:0", "expr:1", NULL };
+ return expand_set_opt_string(args,
+ p_lop_values,
+ ARRAY_SIZE(p_lop_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'matchpairs' option is changed.
const char *did_set_matchpairs(optset_T *args)
{
@@ -1439,12 +1877,26 @@ const char *did_set_mouse(optset_T *args)
return did_set_option_listflag(*varp, MOUSE_ALL, args->os_errbuf, args->os_errbuflen);
}
+int expand_set_mouse(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_listflag(args, MOUSE_ALL, numMatches, matches);
+}
+
/// The 'mousemodel' option is changed.
const char *did_set_mousemodel(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_strings(p_mousem, p_mousem_values, false);
}
+int expand_set_mousemodel(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_mousem_values,
+ ARRAY_SIZE(p_mousem_values) - 1,
+ numMatches,
+ matches);
+}
+
/// Handle setting 'mousescroll'.
/// @return error message, NULL if it's OK.
const char *did_set_mousescroll(optset_T *args FUNC_ATTR_UNUSED)
@@ -1510,6 +1962,16 @@ const char *did_set_mousescroll(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_mousescroll(optexpand_T *args, int *numMatches, char ***matches)
+{
+ static char *(p_mousescroll_values[]) = { "hor:", "ver:", NULL };
+ return expand_set_opt_string(args,
+ p_mousescroll_values,
+ ARRAY_SIZE(p_mousescroll_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'nrformats' option is changed.
const char *did_set_nrformats(optset_T *args)
{
@@ -1518,6 +1980,15 @@ const char *did_set_nrformats(optset_T *args)
return did_set_opt_strings(*varp, p_nf_values, true);
}
+int expand_set_nrformats(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_nf_values,
+ ARRAY_SIZE(p_nf_values) - 1,
+ numMatches,
+ matches);
+}
+
/// One of the '*expr' options is changed:, 'diffexpr', 'foldexpr', 'foldtext',
/// 'formatexpr', 'includeexpr', 'indentexpr', 'patchexpr' and 'charconvert'.
const char *did_set_optexpr(optset_T *args)
@@ -1553,6 +2024,16 @@ const char *did_set_rightleftcmd(optset_T *args)
return NULL;
}
+int expand_set_rightleftcmd(optexpand_T *args, int *numMatches, char ***matches)
+{
+ static char *(p_rlc_values[]) = { "search", NULL };
+ return expand_set_opt_string(args,
+ p_rlc_values,
+ ARRAY_SIZE(p_rlc_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'rulerformat' option is changed.
const char *did_set_rulerformat(optset_T *args)
{
@@ -1565,6 +2046,15 @@ const char *did_set_scrollopt(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_strings(p_sbo, p_scbopt_values, true);
}
+int expand_set_scrollopt(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_scbopt_values,
+ ARRAY_SIZE(p_scbopt_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'selection' option is changed.
const char *did_set_selection(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -1574,12 +2064,30 @@ const char *did_set_selection(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_selection(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_sel_values,
+ ARRAY_SIZE(p_sel_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'selectmode' option is changed.
const char *did_set_selectmode(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_strings(p_slm, p_slm_values, true);
}
+int expand_set_selectmode(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_slm_values,
+ ARRAY_SIZE(p_slm_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'sessionoptions' option is changed.
const char *did_set_sessionoptions(optset_T *args)
{
@@ -1595,6 +2103,15 @@ const char *did_set_sessionoptions(optset_T *args)
return NULL;
}
+int expand_set_sessionoptions(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_ssop_values,
+ ARRAY_SIZE(p_ssop_values) - 1,
+ numMatches,
+ matches);
+}
+
static const char *did_set_shada(vimoption_T **opt, int *opt_idx, bool *free_oldval, char *errbuf,
size_t errbuflen)
{
@@ -1661,6 +2178,11 @@ const char *did_set_shortmess(optset_T *args)
return did_set_option_listflag(*varp, SHM_ALL, args->os_errbuf, args->os_errbuflen);
}
+int expand_set_shortmess(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_listflag(args, SHM_ALL, numMatches, matches);
+}
+
/// The 'showbreak' option is changed.
const char *did_set_showbreak(optset_T *args)
{
@@ -1681,6 +2203,15 @@ const char *did_set_showcmdloc(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_strings(p_sloc, p_sloc_values, true);
}
+int expand_set_showcmdloc(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_sloc_values,
+ ARRAY_SIZE(p_sloc_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'signcolumn' option is changed.
const char *did_set_signcolumn(optset_T *args)
{
@@ -1700,6 +2231,15 @@ const char *did_set_signcolumn(optset_T *args)
return NULL;
}
+int expand_set_signcolumn(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_scl_values,
+ ARRAY_SIZE(p_scl_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'spellcapcheck' option is changed.
const char *did_set_spellcapcheck(optset_T *args)
{
@@ -1745,6 +2285,15 @@ const char *did_set_spelloptions(optset_T *args)
return NULL;
}
+int expand_set_spelloptions(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_spo_values,
+ ARRAY_SIZE(p_spo_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'spellsuggest' option is changed.
const char *did_set_spellsuggest(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -1754,12 +2303,30 @@ const char *did_set_spellsuggest(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_spellsuggest(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_sps_values,
+ ARRAY_SIZE(p_sps_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'splitkeep' option is changed.
const char *did_set_splitkeep(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_strings(p_spk, p_spk_values, false);
}
+int expand_set_splitkeep(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_spk_values,
+ ARRAY_SIZE(p_spk_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'statuscolumn' option is changed.
const char *did_set_statuscolumn(optset_T *args)
{
@@ -1817,6 +2384,15 @@ const char *did_set_switchbuf(optset_T *args FUNC_ATTR_UNUSED)
return did_set_opt_flags(p_swb, p_swb_values, &swb_flags, true);
}
+int expand_set_switchbuf(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_swb_values,
+ ARRAY_SIZE(p_swb_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'tabline' option is changed.
const char *did_set_tabline(optset_T *args)
{
@@ -1850,12 +2426,30 @@ const char *did_set_tagcase(optset_T *args)
return NULL;
}
+int expand_set_tagcase(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_tc_values,
+ ARRAY_SIZE(p_tc_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'termpastefilter' option is changed.
const char *did_set_termpastefilter(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_flags(p_tpf, p_tpf_values, &tpf_flags, true);
}
+int expand_set_termpastefilter(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_tpf_values,
+ ARRAY_SIZE(p_tpf_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'titlestring' or the 'iconstring' option is changed.
static const char *did_set_titleiconstring(optset_T *args, int flagval)
{
@@ -1988,12 +2582,28 @@ const char *did_set_virtualedit(optset_T *args)
return NULL;
}
+int expand_set_virtualedit(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_ve_values,
+ ARRAY_SIZE(p_ve_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'whichwrap' option is changed.
const char *did_set_whichwrap(optset_T *args)
{
char **varp = (char **)args->os_varp;
- return did_set_option_listflag(*varp, WW_ALL, args->os_errbuf, args->os_errbuflen);
+ // Add ',' to the list flags because 'whichwrap' is a flag
+ // list that is comma-separated.
+ return did_set_option_listflag(*varp, WW_ALL ",", args->os_errbuf, args->os_errbuflen);
+}
+
+int expand_set_whichwrap(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_listflag(args, WW_ALL, numMatches, matches);
}
/// The 'wildmode' option is changed.
@@ -2005,12 +2615,30 @@ const char *did_set_wildmode(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_wildmode(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_wim_values,
+ ARRAY_SIZE(p_wim_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'wildoptions' option is changed.
const char *did_set_wildoptions(optset_T *args FUNC_ATTR_UNUSED)
{
return did_set_opt_flags(p_wop, p_wop_values, &wop_flags, true);
}
+int expand_set_wildoptions(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_wop_values,
+ ARRAY_SIZE(p_wop_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'winaltkeys' option is changed.
const char *did_set_winaltkeys(optset_T *args FUNC_ATTR_UNUSED)
{
@@ -2020,13 +2648,23 @@ const char *did_set_winaltkeys(optset_T *args FUNC_ATTR_UNUSED)
return NULL;
}
+int expand_set_winaltkeys(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_string(args,
+ p_wak_values,
+ ARRAY_SIZE(p_wak_values) - 1,
+ numMatches,
+ matches);
+}
+
/// The 'winbar' option is changed.
const char *did_set_winbar(optset_T *args)
{
return did_set_statustabline_rulerformat(args, false, false);
}
-const char *did_set_winhl(optset_T *args)
+/// The 'winhighlight' option is changed.
+const char *did_set_winhighlight(optset_T *args)
{
win_T *win = (win_T *)args->os_win;
if (!parse_winhl_opt(win)) {
@@ -2035,6 +2673,11 @@ const char *did_set_winhl(optset_T *args)
return NULL;
}
+int expand_set_winhighlight(optexpand_T *args, int *numMatches, char ***matches)
+{
+ return expand_set_opt_generic(args, get_highlight_name, numMatches, matches);
+}
+
// When 'syntax' is set, load the syntax of that name
static void do_syntax_autocmd(buf_T *buf, bool value_changed)
{
@@ -2084,11 +2727,12 @@ static void do_spelllang_source(win_T *win)
/// @param errbuf buffer for errors, or NULL
/// @param errbuflen length of errors buffer
/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+/// @param op OP_ADDING/OP_PREPENDING/OP_REMOVING
/// @param value_checked value was checked to be safe, no need to set P_INSECURE
///
/// @return NULL for success, or an untranslated error message for an error
const char *did_set_string_option(buf_T *buf, win_T *win, int opt_idx, char **varp, char *oldval,
- char *errbuf, size_t errbuflen, int opt_flags,
+ char *errbuf, size_t errbuflen, int opt_flags, set_op_T op,
bool *value_checked)
{
const char *errmsg = NULL;
@@ -2102,6 +2746,7 @@ const char *did_set_string_option(buf_T *buf, win_T *win, int opt_idx, char **va
.os_varp = varp,
.os_idx = opt_idx,
.os_flags = opt_flags,
+ .os_op = op,
.os_oldval.string = oldval,
.os_newval.string = *varp,
.os_value_checked = false,
@@ -2324,15 +2969,17 @@ static const struct chars_tab fcs_tab[] = {
static lcs_chars_T lcs_chars;
static const struct chars_tab lcs_tab[] = {
- { &lcs_chars.eol, "eol", NUL, NUL },
- { &lcs_chars.ext, "extends", NUL, NUL },
- { &lcs_chars.nbsp, "nbsp", NUL, NUL },
- { &lcs_chars.prec, "precedes", NUL, NUL },
- { &lcs_chars.space, "space", NUL, NUL },
- { &lcs_chars.tab2, "tab", NUL, NUL },
- { &lcs_chars.lead, "lead", NUL, NUL },
- { &lcs_chars.trail, "trail", NUL, NUL },
- { &lcs_chars.conceal, "conceal", NUL, NUL },
+ { &lcs_chars.eol, "eol", NUL, NUL },
+ { &lcs_chars.ext, "extends", NUL, NUL },
+ { &lcs_chars.nbsp, "nbsp", NUL, NUL },
+ { &lcs_chars.prec, "precedes", NUL, NUL },
+ { &lcs_chars.space, "space", NUL, NUL },
+ { &lcs_chars.tab2, "tab", NUL, NUL },
+ { &lcs_chars.lead, "lead", NUL, NUL },
+ { &lcs_chars.trail, "trail", NUL, NUL },
+ { &lcs_chars.conceal, "conceal", NUL, NUL },
+ { NULL, "multispace", NUL, NUL },
+ { NULL, "leadmultispace", NUL, NUL },
};
/// Handle setting 'listchars' or 'fillchars'.
@@ -2403,54 +3050,13 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
int i;
for (i = 0; i < entries; i++) {
const size_t len = strlen(tab[i].name);
- if (strncmp(p, tab[i].name, len) == 0
- && p[len] == ':'
- && p[len + 1] != NUL) {
- const char *s = p + len + 1;
- int c1 = get_encoded_char_adv(&s);
- if (c1 == 0 || char2cells(c1) > 1) {
- return e_invarg;
- }
- int c2 = 0, c3 = 0;
- if (tab[i].cp == &lcs_chars.tab2) {
- if (*s == NUL) {
- return e_invarg;
- }
- c2 = get_encoded_char_adv(&s);
- if (c2 == 0 || char2cells(c2) > 1) {
- return e_invarg;
- }
- if (!(*s == ',' || *s == NUL)) {
- c3 = get_encoded_char_adv(&s);
- if (c3 == 0 || char2cells(c3) > 1) {
- return e_invarg;
- }
- }
- }
-
- if (*s == ',' || *s == NUL) {
- if (round > 0) {
- if (tab[i].cp == &lcs_chars.tab2) {
- lcs_chars.tab1 = c1;
- lcs_chars.tab2 = c2;
- lcs_chars.tab3 = c3;
- } else if (tab[i].cp != NULL) {
- *(tab[i].cp) = c1;
- }
- }
- p = s;
- break;
- }
+ if (!(strncmp(p, tab[i].name, len) == 0
+ && p[len] == ':'
+ && p[len + 1] != NUL)) {
+ continue;
}
- }
- if (i == entries) {
- const size_t len = strlen("multispace");
- const size_t len2 = strlen("leadmultispace");
- if (is_listchars
- && strncmp(p, "multispace", len) == 0
- && p[len] == ':'
- && p[len + 1] != NUL) {
+ if (is_listchars && strcmp(tab[i].name, "multispace") == 0) {
const char *s = p + len + 1;
if (round == 0) {
// Get length of lcs-multispace string in the first round
@@ -2478,11 +3084,11 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
}
p = s;
}
- } else if (is_listchars
- && strncmp(p, "leadmultispace", len2) == 0
- && p[len2] == ':'
- && p[len2 + 1] != NUL) {
- const char *s = p + len2 + 1;
+ break;
+ }
+
+ if (is_listchars && strcmp(tab[i].name, "leadmultispace") == 0) {
+ const char *s = p + len + 1;
if (round == 0) {
// get length of lcs-leadmultispace string in first round
last_lmultispace = p;
@@ -2509,9 +3115,48 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
}
p = s;
}
- } else {
+ break;
+ }
+
+ const char *s = p + len + 1;
+ int c1 = get_encoded_char_adv(&s);
+ if (c1 == 0 || char2cells(c1) > 1) {
return e_invarg;
}
+ int c2 = 0, c3 = 0;
+ if (tab[i].cp == &lcs_chars.tab2) {
+ if (*s == NUL) {
+ return e_invarg;
+ }
+ c2 = get_encoded_char_adv(&s);
+ if (c2 == 0 || char2cells(c2) > 1) {
+ return e_invarg;
+ }
+ if (!(*s == ',' || *s == NUL)) {
+ c3 = get_encoded_char_adv(&s);
+ if (c3 == 0 || char2cells(c3) > 1) {
+ return e_invarg;
+ }
+ }
+ }
+
+ if (*s == ',' || *s == NUL) {
+ if (round > 0) {
+ if (tab[i].cp == &lcs_chars.tab2) {
+ lcs_chars.tab1 = c1;
+ lcs_chars.tab2 = c2;
+ lcs_chars.tab3 = c3;
+ } else if (tab[i].cp != NULL) {
+ *(tab[i].cp) = c1;
+ }
+ }
+ p = s;
+ break;
+ }
+ }
+
+ if (i == entries) {
+ return e_invarg;
}
if (*p == ',') {
@@ -2536,6 +3181,40 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
return NULL; // no error
}
+/// Handle the new value of 'fillchars'.
+const char *set_fillchars_option(win_T *wp, char *val, bool apply)
+{
+ return set_chars_option(wp, val, false, apply);
+}
+
+/// Handle the new value of 'listchars'.
+const char *set_listchars_option(win_T *wp, char *val, bool apply)
+{
+ return set_chars_option(wp, val, true, apply);
+}
+
+/// Function given to ExpandGeneric() to obtain possible arguments of the
+/// 'fillchars' option.
+char *get_fillchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ if (idx >= (int)ARRAY_SIZE(fcs_tab)) {
+ return NULL;
+ }
+
+ return (char *)fcs_tab[idx].name;
+}
+
+/// Function given to ExpandGeneric() to obtain possible arguments of the
+/// 'listchars' option.
+char *get_listchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ if (idx >= (int)ARRAY_SIZE(lcs_tab)) {
+ return NULL;
+ }
+
+ return (char *)lcs_tab[idx].name;
+}
+
/// Check all global and local values of 'listchars' and 'fillchars'.
/// May set different defaults in case character widths change.
///
@@ -2558,15 +3237,3 @@ const char *check_chars_options(void)
}
return NULL;
}
-
-/// Handle the new value of 'fillchars'.
-const char *set_fillchars_option(win_T *wp, char *val, bool apply)
-{
- return set_chars_option(wp, val, false, apply);
-}
-
-/// Handle the new value of 'listchars'.
-const char *set_listchars_option(win_T *wp, char *val, bool apply)
-{
- return set_chars_option(wp, val, true, apply);
-}
diff --git a/src/nvim/optionstr.h b/src/nvim/optionstr.h
index 3520cc2061..a481ed1d07 100644
--- a/src/nvim/optionstr.h
+++ b/src/nvim/optionstr.h
@@ -2,6 +2,7 @@
#define NVIM_OPTIONSTR_H
#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/option_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index b03509a313..7de7168d62 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -17,7 +17,6 @@
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
#include "nvim/eval.h"
-#include "nvim/ex_cmds_defs.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
#include "nvim/log.h"
@@ -29,7 +28,6 @@
#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/strings.h"
-#include "nvim/types.h"
#include "nvim/version.h"
#include "nvim/vim.h"
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index 846219f720..119a42f074 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -282,9 +282,10 @@ static char writebuf[kRWBufferSize];
///
/// @param[in,out] rv RBuffer instance used.
/// @param[in,out] fp File to work with.
-static void file_rb_write_full_cb(RBuffer *const rv, FileDescriptor *const fp)
+static void file_rb_write_full_cb(RBuffer *const rv, void *const fp_in)
FUNC_ATTR_NONNULL_ALL
{
+ FileDescriptor *const fp = fp_in;
assert(fp->wr);
assert(rv->data == (void *)fp);
if (rbuffer_size(rv) == 0) {
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 476ede2046..2712b874bb 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -63,8 +63,6 @@
#ifdef HAVE_XATTR
static const char e_xattr_erange[]
= N_("E1506: Buffer too small to copy xattr value or key");
-static const char e_xattr_enotsup[]
- = N_("E1507: Extended attributes are not supported by the filesystem");
static const char e_xattr_e2big[]
= N_("E1508: Size of the extended attribute value is larger than the maximum size allowed");
static const char e_xattr_other[]
@@ -800,9 +798,9 @@ void os_copy_xattr(const char *from_file, const char *to_file)
case E2BIG:
errmsg = e_xattr_e2big;
goto error_exit;
- case ENOTSUP:
- errmsg = e_xattr_enotsup;
- goto error_exit;
+ case EACCES:
+ case EPERM:
+ break;
case ERANGE:
errmsg = e_xattr_erange;
goto error_exit;
diff --git a/src/nvim/os/lang.c b/src/nvim/os/lang.c
index 652b851903..c3958cb3f2 100644
--- a/src/nvim/os/lang.c
+++ b/src/nvim/os/lang.c
@@ -5,6 +5,7 @@
# define Boolean CFBoolean // Avoid conflict with API's Boolean
# define FileInfo CSFileInfo // Avoid conflict with API's Fileinfo
# include <CoreServices/CoreServices.h>
+
# undef Boolean
# undef FileInfo
#endif
@@ -17,6 +18,7 @@
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/garray.h"
@@ -30,7 +32,6 @@
#include "nvim/os/shell.h"
#include "nvim/path.h"
#include "nvim/profile.h"
-#include "nvim/types.h"
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/os/lang.h b/src/nvim/os/lang.h
index bb1ebfb721..ad64b38916 100644
--- a/src/nvim/os/lang.h
+++ b/src/nvim/os/lang.h
@@ -1,6 +1,7 @@
#ifndef NVIM_OS_LANG_H
#define NVIM_OS_LANG_H
+#include "nvim/cmdexpand_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/types.h"
diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h
index a7496130cc..006dfbfc04 100644
--- a/src/nvim/os/os.h
+++ b/src/nvim/os/os.h
@@ -4,9 +4,12 @@
#include <stdbool.h>
#include <uv.h>
+#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
+#include "nvim/garray.h"
#include "nvim/os/fs_defs.h"
#include "nvim/os/stdpaths_defs.h"
-#include "nvim/vim.h"
+#include "nvim/types.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/env.h.generated.h"
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index 411ba91fa7..b23d2b7b13 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.c
@@ -10,10 +10,10 @@
#include "auto/config.h"
#include "nvim/ascii.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/garray.h"
#include "nvim/memory.h"
#include "nvim/os/os.h"
-#include "nvim/types.h"
#include "nvim/vim.h"
#ifdef HAVE_PWD_FUNCS
# include <pwd.h>
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 21f0543756..5d991ce719 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -648,11 +648,13 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
}
s = p + 1;
} else if (path_end >= path + wildoff
+#ifdef MSWIN
+ && vim_strchr("*?[~", (uint8_t)(*path_end)) != NULL
+#else
&& (vim_strchr("*?[{~$", (uint8_t)(*path_end)) != NULL
-#ifndef MSWIN
- || (!p_fic && (flags & EW_ICASE) && mb_isalpha(utf_ptr2char(path_end)))
+ || (!p_fic && (flags & EW_ICASE) && mb_isalpha(utf_ptr2char(path_end))))
#endif
- )) { // NOLINT(whitespace/parens)
+ ) { // NOLINT(whitespace/parens)
e = p;
}
len = (size_t)(utfc_ptr2len(path_end));
diff --git a/src/nvim/profile.c b/src/nvim/profile.c
index 3162a446c0..73ad534de7 100644
--- a/src/nvim/profile.c
+++ b/src/nvim/profile.c
@@ -11,6 +11,7 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/debugger.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
@@ -30,7 +31,6 @@
#include "nvim/profile.h"
#include "nvim/runtime.h"
#include "nvim/types.h"
-#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "profile.c.generated.h"
diff --git a/src/nvim/profile.h b/src/nvim/profile.h
index 547d11185f..7450a0dfdc 100644
--- a/src/nvim/profile.h
+++ b/src/nvim/profile.h
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <time.h>
+#include "nvim/cmdexpand_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/runtime.h"
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index 12cf08636f..360088758d 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -20,6 +20,7 @@
#include "nvim/autocmd.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/debugger.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
diff --git a/src/nvim/runtime.h b/src/nvim/runtime.h
index 7308ef5f75..8286a11f89 100644
--- a/src/nvim/runtime.h
+++ b/src/nvim/runtime.h
@@ -5,6 +5,7 @@
#include "klib/kvec.h"
#include "nvim/autocmd.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_eval_defs.h"
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 14d35d9b59..cd1d016c7b 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1564,15 +1564,14 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntr
break;
}
case kSDItemVariable: {
- if (entry.data.global_var.value.v_type == VAR_TYPE_BLOB) {
+ if (entry.data.global_var.value.v_type == VAR_BLOB) {
// Strings and Blobs both pack as msgpack BINs; differentiate them by
// storing an additional VAR_TYPE_BLOB element alongside Blobs
list_T *const list = tv_list_alloc(1);
tv_list_append_number(list, VAR_TYPE_BLOB);
entry.data.global_var.additional_elements = list;
}
- const size_t arr_size = 2 + (size_t)(
- tv_list_len(entry.data.global_var.additional_elements));
+ const size_t arr_size = 2 + (size_t)(tv_list_len(entry.data.global_var.additional_elements));
msgpack_pack_array(spacker, arr_size);
const String varname = cstr_as_string(entry.data.global_var.name);
PACK_BIN(varname);
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 96af14bfc6..5d18ed393a 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -16,6 +16,7 @@
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
diff --git a/src/nvim/sign.h b/src/nvim/sign.h
index ba84cd71a4..89d765bf38 100644
--- a/src/nvim/sign.h
+++ b/src/nvim/sign.h
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/sign_defs.h"
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index f1df2e56f3..25e08abb0e 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -452,24 +452,24 @@ struct wordnode_S {
// Info used while reading the spell files.
typedef struct spellinfo_S {
wordnode_T *si_foldroot; // tree with case-folded words
- long si_foldwcount; // nr of words in si_foldroot
+ int si_foldwcount; // nr of words in si_foldroot
wordnode_T *si_keeproot; // tree with keep-case words
- long si_keepwcount; // nr of words in si_keeproot
+ int si_keepwcount; // nr of words in si_keeproot
wordnode_T *si_prefroot; // tree with postponed prefixes
- long si_sugtree; // creating the soundfolding trie
+ int si_sugtree; // creating the soundfolding trie
sblock_T *si_blocks; // memory blocks used
- long si_blocks_cnt; // memory blocks allocated
+ int si_blocks_cnt; // memory blocks allocated
int si_did_emsg; // true when ran out of memory
- long si_compress_cnt; // words to add before lowering
- // compression limit
+ int si_compress_cnt; // words to add before lowering
+ // compression limit
wordnode_T *si_first_free; // List of nodes that have been freed during
// compression, linked by "wn_child" field.
- long si_free_count; // number of nodes in si_first_free
+ int si_free_count; // number of nodes in si_first_free
#ifdef SPELL_PRINTTREE
int si_wordnode_nr; // sequence nr for nodes
#endif
@@ -1874,24 +1874,24 @@ static void spell_reload_one(char *fname, bool added_word)
// Tunable parameters for when the tree is compressed. Filled from the
// 'mkspellmem' option.
-static long compress_start = 30000; // memory / SBLOCKSIZE
-static long compress_inc = 100; // memory / SBLOCKSIZE
-static long compress_added = 500000; // word count
+static int compress_start = 30000; // memory / SBLOCKSIZE
+static int compress_inc = 100; // memory / SBLOCKSIZE
+static int compress_added = 500000; // word count
// Check the 'mkspellmem' option. Return FAIL if it's wrong.
// Sets "sps_flags".
int spell_check_msm(void)
{
char *p = p_msm;
- long start = 0;
- long incr = 0;
- long added = 0;
+ int start = 0;
+ int incr = 0;
+ int added = 0;
if (!ascii_isdigit(*p)) {
return FAIL;
}
// block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)
- start = (getdigits_long(&p, true, 0) * 10) / (SBLOCKSIZE / 102);
+ start = (getdigits_int(&p, true, 0) * 10) / (SBLOCKSIZE / 102);
if (*p != ',') {
return FAIL;
}
@@ -1899,7 +1899,7 @@ int spell_check_msm(void)
if (!ascii_isdigit(*p)) {
return FAIL;
}
- incr = (getdigits_long(&p, true, 0) * 102) / (SBLOCKSIZE / 10);
+ incr = (getdigits_int(&p, true, 0) * 102) / (SBLOCKSIZE / 10);
if (*p != ',') {
return FAIL;
}
@@ -1907,7 +1907,7 @@ int spell_check_msm(void)
if (!ascii_isdigit(*p)) {
return FAIL;
}
- added = getdigits_long(&p, true, 0) * 1024;
+ added = getdigits_int(&p, true, 0) * 1024;
if (*p != NUL) {
return FAIL;
}
@@ -3177,7 +3177,7 @@ static int spell_read_dic(spellinfo_T *spin, char *fname, afffile_T *affile)
if (os_time() > last_msg_time) {
last_msg_time = os_time();
vim_snprintf(message, sizeof(message),
- _("line %6d, word %6ld - %s"),
+ _("line %6d, word %6d - %s"),
lnum, spin->si_foldwcount + spin->si_keepwcount, w);
msg_start();
msg_outtrans_long(message, 0);
@@ -3635,7 +3635,7 @@ static int store_aff_word(spellinfo_T *spin, char *word, char *afflist, afffile_
static int spell_read_wordfile(spellinfo_T *spin, char *fname)
{
FILE *fd;
- long lnum = 0;
+ linenr_T lnum = 0;
char rline[MAXLINELEN];
char *line;
char *pc = NULL;
@@ -3682,7 +3682,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char *fname)
if (spin->si_conv.vc_type != CONV_NONE) {
pc = string_convert(&spin->si_conv, rline, NULL);
if (pc == NULL) {
- smsg(0, _("Conversion failure for word in %s line %ld: %s"),
+ smsg(0, _("Conversion failure for word in %s line %" PRIdLINENR ": %s"),
fname, lnum, rline);
continue;
}
@@ -3696,10 +3696,10 @@ static int spell_read_wordfile(spellinfo_T *spin, char *fname)
line++;
if (strncmp(line, "encoding=", 9) == 0) {
if (spin->si_conv.vc_type != CONV_NONE) {
- smsg(0, _("Duplicate /encoding= line ignored in %s line %ld: %s"),
+ smsg(0, _("Duplicate /encoding= line ignored in %s line %" PRIdLINENR ": %s"),
fname, lnum, line - 1);
} else if (did_word) {
- smsg(0, _("/encoding= line after word ignored in %s line %ld: %s"),
+ smsg(0, _("/encoding= line after word ignored in %s line %" PRIdLINENR ": %s"),
fname, lnum, line - 1);
} else {
char *enc;
@@ -3720,12 +3720,12 @@ static int spell_read_wordfile(spellinfo_T *spin, char *fname)
if (strncmp(line, "regions=", 8) == 0) {
if (spin->si_region_count > 1) {
- smsg(0, _("Duplicate /regions= line ignored in %s line %ld: %s"),
+ smsg(0, _("Duplicate /regions= line ignored in %s line %" PRIdLINENR ": %s"),
fname, lnum, line);
} else {
line += 8;
if (strlen(line) > MAXREGIONS * 2) {
- smsg(0, _("Too many regions in %s line %ld: %s"),
+ smsg(0, _("Too many regions in %s line %" PRIdLINENR ": %s"),
fname, lnum, line);
} else {
spin->si_region_count = (int)strlen(line) / 2;
@@ -3738,7 +3738,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char *fname)
continue;
}
- smsg(0, _("/ line ignored in %s line %ld: %s"),
+ smsg(0, _("/ line ignored in %s line %" PRIdLINENR ": %s"),
fname, lnum, line - 1);
continue;
}
@@ -3765,13 +3765,13 @@ static int spell_read_wordfile(spellinfo_T *spin, char *fname)
l = (uint8_t)(*p) - '0';
if (l == 0 || l > spin->si_region_count) {
- smsg(0, _("Invalid region nr in %s line %ld: %s"),
+ smsg(0, _("Invalid region nr in %s line %" PRIdLINENR ": %s"),
fname, lnum, p);
break;
}
regionmask |= 1 << (l - 1);
} else {
- smsg(0, _("Unrecognized flags in %s line %ld: %s"),
+ smsg(0, _("Unrecognized flags in %s line %" PRIdLINENR ": %s"),
fname, lnum, p);
break;
}
@@ -4168,7 +4168,7 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, const char *n
FUNC_ATTR_NONNULL_ALL
{
hashtab_T ht;
- long tot = 0;
+ int tot = 0;
long perc;
// Skip the root itself, it's not actually used. The first sibling is the
@@ -4178,7 +4178,7 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, const char *n
}
hash_init(&ht);
- const long n = node_compress(spin, root->wn_sibling, &ht, &tot);
+ const int n = node_compress(spin, root->wn_sibling, &ht, &tot);
#ifndef SPELL_PRINTTREE
if (spin->si_verbose || p_verbose > 2)
@@ -4192,7 +4192,7 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, const char *n
perc = (tot - n) * 100 / tot;
}
vim_snprintf(IObuff, IOSIZE,
- _("Compressed %s of %ld nodes; %ld (%ld%%) remaining"),
+ _("Compressed %s of %d nodes; %d (%ld%%) remaining"),
name, tot, tot - n, perc);
spell_message(spin, IObuff);
}
@@ -4206,7 +4206,7 @@ static void wordtree_compress(spellinfo_T *spin, wordnode_T *root, const char *n
/// Returns the number of compressed nodes.
///
/// @param tot total count of nodes before compressing, incremented while going through the tree
-static long node_compress(spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, long *tot)
+static int node_compress(spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, int *tot)
FUNC_ATTR_NONNULL_ALL
{
wordnode_T *np;
@@ -4216,7 +4216,7 @@ static long node_compress(spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, lo
hashitem_T *hi;
long len = 0;
unsigned nr, n;
- long compressed = 0;
+ int compressed = 0;
// Go through the list of siblings. Compress each child and then try
// finding an identical child to replace it.
@@ -4262,7 +4262,7 @@ static long node_compress(spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, lo
}
}
}
- *tot += len + 1; // add one for the node that stores the length
+ *tot += (int)len + 1; // add one for the node that stores the length
// Make a hash key for the node and its siblings, so that we can quickly
// find a lookalike node. This must be done after compressing the sibling
@@ -5559,15 +5559,15 @@ void spell_add_word(char *word, int len, SpellAddType what, int idx, bool undo)
}
if (what == SPELL_ADD_BAD || undo) {
- long fpos_next = 0;
- long fpos = 0;
+ int fpos_next = 0;
+ int fpos = 0;
// When the word appears as good word we need to remove that one,
// since its flags sort before the one with WF_BANNED.
fd = os_fopen(fname, "r");
if (fd != NULL) {
while (!vim_fgets(line, MAXWLEN * 2, fd)) {
fpos = fpos_next;
- fpos_next = ftell(fd);
+ fpos_next = (int)ftell(fd);
if (fpos_next < 0) {
break; // should never happen
}
diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c
index 2ee93b4934..7b92e69821 100644
--- a/src/nvim/spellsuggest.c
+++ b/src/nvim/spellsuggest.c
@@ -403,6 +403,7 @@ int spell_check_sps(void)
if (*s != NUL && !ascii_isdigit(*s)) {
f = -1;
}
+ // Note: Keep this in sync with p_sps_values.
} else if (strcmp(buf, "best") == 0) {
f = SPS_BEST;
} else if (strcmp(buf, "fast") == 0) {
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 9b238e6ff9..6bb841b1f8 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -15,6 +15,7 @@
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
@@ -3554,7 +3555,7 @@ static void put_pattern(const char *const s, const int c, const synpat_T *const
msg_putchar(','); // Separate with commas.
}
msg_puts(spo_name_tab[i]);
- const long n = spp->sp_offsets[i];
+ const int n = spp->sp_offsets[i];
if (i != SPO_LC_OFF) {
if (spp->sp_off_flags & mask) {
msg_putchar('s');
diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h
index 0a63392a04..c56624bc37 100644
--- a/src/nvim/syntax.h
+++ b/src/nvim/syntax.h
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include "nvim/buffer_defs.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/globals.h"
#include "nvim/macros.h"
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index 636d16d4e6..674d22ba44 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -56,7 +56,6 @@
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
-#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/vim.h"
#include "nvim/window.h"
diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c
index 0de62440f9..13e51b9a9e 100644
--- a/src/nvim/textformat.c
+++ b/src/nvim/textformat.c
@@ -822,7 +822,7 @@ void op_format(oparg_T *oap, bool keep_cursor)
saved_cursor = oap->cursor_start;
}
- format_lines((linenr_T)oap->line_count, keep_cursor);
+ format_lines(oap->line_count, keep_cursor);
// Leave the cursor at the first non-blank of the last formatted line.
// If the cursor was moved one line back (e.g. with "Q}") go to the next
diff --git a/src/nvim/types.h b/src/nvim/types.h
index c2c815a0bc..7b23fe419b 100644
--- a/src/nvim/types.h
+++ b/src/nvim/types.h
@@ -31,8 +31,6 @@ typedef union {
typedef handle_T NS;
-typedef struct expand expand_T;
-
typedef uint64_t proftime_T;
typedef enum {
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 5396bfcda2..758ee036b4 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -260,10 +260,10 @@ int u_save_buf(buf_T *buf, linenr_T top, linenr_T bot)
}
if (top + 2 == bot) {
- u_saveline(buf, (linenr_T)(top + 1));
+ u_saveline(buf, top + 1);
}
- return u_savecommon(buf, top, bot, (linenr_T)0, false);
+ return u_savecommon(buf, top, bot, 0, false);
}
/// Save the line "lnum" (used by ":s" and "~" command).
@@ -289,9 +289,9 @@ int u_inssub(linenr_T lnum)
/// becomes empty.
/// Careful: may trigger autocommands that reload the buffer.
/// Returns FAIL when lines could not be saved, OK otherwise.
-int u_savedel(linenr_T lnum, long nlines)
+int u_savedel(linenr_T lnum, linenr_T nlines)
{
- return u_savecommon(curbuf, lnum - 1, lnum + (linenr_T)nlines,
+ return u_savecommon(curbuf, lnum - 1, lnum + nlines,
nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false);
}
@@ -378,7 +378,7 @@ int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, int re
u_entry_T *uep;
u_entry_T *prev_uep;
- long size = bot - top - 1;
+ linenr_T size = bot - top - 1;
// If curbuf->b_u_synced == true make a new header.
if (buf->b_u_synced) {
@@ -1488,7 +1488,7 @@ void u_read_undo(char *name, const uint8_t *hash, const char *orig_name FUNC_ATT
time_t seq_time = undo_read_time(&bi);
// Optional header fields.
- long last_save_nr = 0;
+ int last_save_nr = 0;
while (true) {
int len = undo_read_byte(&bi);
@@ -1519,7 +1519,7 @@ void u_read_undo(char *name, const uint8_t *hash, const char *orig_name FUNC_ATT
}
}
- long num_read_uhps = 0;
+ int num_read_uhps = 0;
int c;
while ((c = undo_read_2c(&bi)) == UF_HEADER_MAGIC) {
@@ -1655,7 +1655,7 @@ void u_read_undo(char *name, const uint8_t *hash, const char *orig_name FUNC_ATT
error:
xfree(line_ptr);
if (uhp_table != NULL) {
- for (long i = 0; i < num_read_uhps; i++) {
+ for (int i = 0; i < num_read_uhps; i++) {
if (uhp_table[i] != NULL) {
u_free_uhp(uhp_table[i]);
}
@@ -1920,7 +1920,7 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
// When "file" is true use "step" as a number of file writes.
// When "absolute" is true use "step" as the sequence number to jump to.
// "sec" must be false then.
-void undo_time(long step, bool sec, bool file, bool absolute)
+void undo_time(int step, bool sec, bool file, bool absolute)
{
if (text_locked()) {
text_locked_msg();
@@ -1938,8 +1938,8 @@ void undo_time(long step, bool sec, bool file, bool absolute)
u_oldcount = -1;
}
- long target;
- long closest;
+ int target;
+ int closest;
u_header_T *uhp = NULL;
bool dosec = sec;
bool dofile = file;
@@ -1953,7 +1953,7 @@ void undo_time(long step, bool sec, bool file, bool absolute)
closest = -1;
} else {
if (dosec) {
- target = (long)(curbuf->b_u_time_cur) + step;
+ target = (int)curbuf->b_u_time_cur + step;
} else if (dofile) {
if (step < 0) {
// Going back to a previous write. If there were changes after
@@ -1998,7 +1998,7 @@ void undo_time(long step, bool sec, bool file, bool absolute)
closest = -1;
} else {
if (dosec) {
- closest = (long)(os_time() + 1);
+ closest = (int)(os_time() + 1);
} else if (dofile) {
closest = curbuf->b_u_save_nr_last + 2;
} else {
@@ -2010,7 +2010,7 @@ void undo_time(long step, bool sec, bool file, bool absolute)
}
}
long closest_start = closest;
- long closest_seq = curbuf->b_u_seq_cur;
+ int closest_seq = curbuf->b_u_seq_cur;
int mark;
int nomark = 0; // shut up compiler
@@ -2042,8 +2042,8 @@ void undo_time(long step, bool sec, bool file, bool absolute)
while (uhp != NULL) {
uhp->uh_walk = mark;
- long val = dosec ? (long)(uhp->uh_time) :
- dofile ? uhp->uh_save_nr
+ int val = dosec ? (int)(uhp->uh_time) :
+ dofile ? uhp->uh_save_nr
: uhp->uh_seq;
if (round == 1 && !(dofile && val == 0)) {
@@ -2298,7 +2298,7 @@ static void u_undoredo(int undo, bool do_buf_event)
}
linenr_T oldsize = bot - top - 1; // number of lines before undo
- linenr_T newsize = (linenr_T)uep->ue_size; // number of lines after undo
+ linenr_T newsize = uep->ue_size; // number of lines after undo
if (top < newlnum) {
// If the saved cursor is somewhere in this undo block, move it to
@@ -2676,13 +2676,13 @@ void ex_undolist(exarg_T *eap)
while (uhp != NULL) {
if (uhp->uh_prev.ptr == NULL && uhp->uh_walk != nomark
&& uhp->uh_walk != mark) {
- vim_snprintf(IObuff, IOSIZE, "%6ld %7d ", uhp->uh_seq, changes);
+ vim_snprintf(IObuff, IOSIZE, "%6d %7d ", uhp->uh_seq, changes);
undo_fmt_time(IObuff + strlen(IObuff), IOSIZE - strlen(IObuff), uhp->uh_time);
if (uhp->uh_save_nr > 0) {
while (strlen(IObuff) < 33) {
xstrlcat(IObuff, " ", IOSIZE);
}
- vim_snprintf_add(IObuff, IOSIZE, " %3ld", uhp->uh_save_nr);
+ vim_snprintf_add(IObuff, IOSIZE, " %3d", uhp->uh_save_nr);
}
GA_APPEND(char *, &ga, xstrdup(IObuff));
}
@@ -2850,7 +2850,7 @@ static void u_getbot(buf_T *buf)
// inserted (0 - deleted) since calling u_save. This is equal to the
// old line count subtracted from the current line count.
linenr_T extra = buf->b_ml.ml_line_count - uep->ue_lcount;
- uep->ue_bot = uep->ue_top + (linenr_T)uep->ue_size + 1 + extra;
+ uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
if (uep->ue_bot < 1 || uep->ue_bot > buf->b_ml.ml_line_count) {
iemsg(_(e_undo_line_missing));
uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will
diff --git a/src/nvim/undo_defs.h b/src/nvim/undo_defs.h
index 9cc2e4a52b..aa7d6e3355 100644
--- a/src/nvim/undo_defs.h
+++ b/src/nvim/undo_defs.h
@@ -26,7 +26,7 @@ struct u_entry {
linenr_T ue_bot; // number of line below undo block
linenr_T ue_lcount; // linecount when u_save called
char **ue_array; // array of lines in undo block
- long ue_size; // number of lines in ue_array
+ linenr_T ue_size; // number of lines in ue_array
#ifdef U_DEBUG
int ue_magic; // magic number to check allocation
#endif
@@ -51,19 +51,19 @@ struct u_header {
u_header_T *ptr; // pointer to previous header for alt. redo
long seq;
} uh_alt_prev;
- long uh_seq; // sequence number, higher == newer undo
+ int uh_seq; // sequence number, higher == newer undo
int uh_walk; // used by undo_time()
- u_entry_T *uh_entry; // pointer to first entry
+ u_entry_T *uh_entry; // pointer to first entry
u_entry_T *uh_getbot_entry; // pointer to where ue_bot must be set
pos_T uh_cursor; // cursor position before saving
colnr_T uh_cursor_vcol;
- int uh_flags; // see below
- fmark_T uh_namedm[NMARKS]; // marks before undo/after redo
+ int uh_flags; // see below
+ fmark_T uh_namedm[NMARKS]; // marks before undo/after redo
extmark_undo_vec_t uh_extmark; // info to move extmarks
- visualinfo_T uh_visual; // Visual areas before undo/after redo
- time_t uh_time; // timestamp when the change was made
- long uh_save_nr; // set when the file was saved after the
- // changes in this block
+ visualinfo_T uh_visual; // Visual areas before undo/after redo
+ time_t uh_time; // timestamp when the change was made
+ int uh_save_nr; // set when the file was saved after the
+ // changes in this block
#ifdef U_DEBUG
int uh_magic; // magic number to check allocation
#endif
diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c
index 131b1ce3ef..4bab3f52cd 100644
--- a/src/nvim/usercmd.c
+++ b/src/nvim/usercmd.c
@@ -16,6 +16,7 @@
#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval.h"
#include "nvim/ex_docmd.h"
#include "nvim/garray.h"
diff --git a/src/nvim/usercmd.h b/src/nvim/usercmd.h
index 0d9838abf2..34f1439b10 100644
--- a/src/nvim/usercmd.h
+++ b/src/nvim/usercmd.h
@@ -3,6 +3,7 @@
#include <stdint.h>
+#include "nvim/cmdexpand_defs.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/garray.h"
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index fc1f15b285..22db3751cd 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -96,83 +96,10 @@ typedef enum {
#define FAIL 0
#define NOTDONE 2 // not OK or FAIL but skipped
-// Type values for type().
-#define VAR_TYPE_NUMBER 0
-#define VAR_TYPE_STRING 1
-#define VAR_TYPE_FUNC 2
-#define VAR_TYPE_LIST 3
-#define VAR_TYPE_DICT 4
-#define VAR_TYPE_FLOAT 5
-#define VAR_TYPE_BOOL 6
-#define VAR_TYPE_SPECIAL 7
-#define VAR_TYPE_BLOB 10
-
-// values for xp_context when doing command line completion
-
-enum {
- EXPAND_UNSUCCESSFUL = -2,
- EXPAND_OK = -1,
- EXPAND_NOTHING = 0,
- EXPAND_COMMANDS,
- EXPAND_FILES,
- EXPAND_DIRECTORIES,
- EXPAND_SETTINGS,
- EXPAND_BOOL_SETTINGS,
- EXPAND_TAGS,
- EXPAND_OLD_SETTING,
- EXPAND_HELP,
- EXPAND_BUFFERS,
- EXPAND_EVENTS,
- EXPAND_MENUS,
- EXPAND_SYNTAX,
- EXPAND_HIGHLIGHT,
- EXPAND_AUGROUP,
- EXPAND_USER_VARS,
- EXPAND_MAPPINGS,
- EXPAND_TAGS_LISTFILES,
- EXPAND_FUNCTIONS,
- EXPAND_USER_FUNC,
- EXPAND_EXPRESSION,
- EXPAND_MENUNAMES,
- EXPAND_USER_COMMANDS,
- EXPAND_USER_CMD_FLAGS,
- EXPAND_USER_NARGS,
- EXPAND_USER_COMPLETE,
- EXPAND_ENV_VARS,
- EXPAND_LANGUAGE,
- EXPAND_COLORS,
- EXPAND_COMPILER,
- EXPAND_USER_DEFINED,
- EXPAND_USER_LIST,
- EXPAND_USER_LUA,
- EXPAND_SHELLCMD,
- EXPAND_SIGN,
- EXPAND_PROFILE,
- EXPAND_FILETYPE,
- EXPAND_FILES_IN_PATH,
- EXPAND_OWNSYNTAX,
- EXPAND_LOCALES,
- EXPAND_HISTORY,
- EXPAND_USER,
- EXPAND_SYNTIME,
- EXPAND_USER_ADDR_TYPE,
- EXPAND_PACKADD,
- EXPAND_MESSAGES,
- EXPAND_MAPCLEAR,
- EXPAND_ARGLIST,
- EXPAND_DIFF_BUFFERS,
- EXPAND_BREAKPOINT,
- EXPAND_SCRIPTNAMES,
- EXPAND_RUNTIME,
- EXPAND_CHECKHEALTH,
- EXPAND_LUA,
-};
-
// Minimal size for block 0 of a swap file.
// NOTE: This depends on size of struct block0! It's not done with a sizeof(),
// because struct block0 is defined in memline.c (Sorry).
// The maximal block size is arbitrary.
-
#define MIN_SWAP_PAGE_SIZE 1048
#define MAX_SWAP_PAGE_SIZE 50000