aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval/funcs.c
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
committerJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
commit308e1940dcd64aa6c344c403d4f9e0dda58d9c5c (patch)
tree35fe43e01755e0f312650667004487a44d6b7941 /src/nvim/eval/funcs.c
parent96a00c7c588b2f38a2424aeeb4ea3581d370bf2d (diff)
parente8c94697bcbe23a5c7b07c292b90a6b70aadfa87 (diff)
downloadrneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.gz
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.bz2
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.zip
Merge remote-tracking branch 'upstream/master' into rahm
Diffstat (limited to 'src/nvim/eval/funcs.c')
-rw-r--r--src/nvim/eval/funcs.c3312
1 files changed, 1254 insertions, 2058 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 875655d0b3..7bed21e99b 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -16,27 +16,31 @@
#include "nvim/context.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
+#include "nvim/digraph.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/decode.h"
#include "nvim/eval/encode.h"
#include "nvim/eval/executor.h"
#include "nvim/eval/funcs.h"
+#include "nvim/eval/typval.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/globals.h"
+#include "nvim/highlight_group.h"
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/input.h"
#include "nvim/lua/executor.h"
#include "nvim/macros.h"
+#include "nvim/mapping.h"
#include "nvim/mark.h"
+#include "nvim/match.h"
#include "nvim/math.h"
#include "nvim/memline.h"
#include "nvim/mouse.h"
@@ -61,11 +65,12 @@
#include "nvim/state.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
+#include "nvim/testing.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/vim.h"
-
+#include "nvim/window.h"
/// Describe data to return from find_some_match()
typedef enum {
@@ -76,9 +81,6 @@ typedef enum {
kSomeMatchStrPos, ///< Data for matchstrpos().
} SomeMatchType;
-KHASH_MAP_INIT_STR(functions, VimLFuncDef)
-
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/funcs.c.generated.h"
@@ -96,10 +98,9 @@ PRAGMA_DIAG_POP
PRAGMA_DIAG_POP
#endif
-
-static char *e_listarg = N_("E686: Argument of %s must be a List");
static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
static char *e_invalwindow = N_("E957: Invalid window number");
+static char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value");
/// Dummy va_list for passing to vim_snprintf
///
@@ -109,10 +110,9 @@ static char *e_invalwindow = N_("E957: Invalid window number");
/// - using va_start() to initialize it gives "function with fixed args" error
static va_list dummy_ap;
-
/// Function given to ExpandGeneric() to obtain the list of internal
/// or user defined function names.
-char_u *get_function_name(expand_T *xp, int idx)
+char *get_function_name(expand_T *xp, int idx)
{
static int intidx = -1;
char_u *name;
@@ -121,24 +121,20 @@ char_u *get_function_name(expand_T *xp, int idx)
intidx = -1;
}
if (intidx < 0) {
- name = get_user_func_name(xp, idx);
+ name = (char_u *)get_user_func_name(xp, idx);
if (name != NULL) {
if (*name != NUL && *name != '<'
&& STRNCMP("g:", xp->xp_pattern, 2) == 0) {
- return cat_prefix_varname('g', name);
+ return cat_prefix_varname('g', (char *)name);
}
- return name;
+ return (char *)name;
}
}
- while ((size_t)++intidx < ARRAY_SIZE(functions)
- && functions[intidx].name[0] == '\0') {
- }
- if ((size_t)intidx >= ARRAY_SIZE(functions)) {
+ const char *const key = functions[++intidx].name;
+ if (!key) {
return NULL;
}
-
- const char *const key = functions[intidx].name;
const size_t key_len = strlen(key);
memcpy(IObuff, key, key_len);
IObuff[key_len] = '(';
@@ -148,12 +144,12 @@ char_u *get_function_name(expand_T *xp, int idx)
} else {
IObuff[key_len + 1] = NUL;
}
- return IObuff;
+ return (char *)IObuff;
}
/// Function given to ExpandGeneric() to obtain the list of internal or
/// user defined variable or function names.
-char_u *get_expr_name(expand_T *xp, int idx)
+char *get_expr_name(expand_T *xp, int idx)
{
static int intidx = -1;
char_u *name;
@@ -162,9 +158,9 @@ char_u *get_expr_name(expand_T *xp, int idx)
intidx = -1;
}
if (intidx < 0) {
- name = get_function_name(xp, idx);
+ name = (char_u *)get_function_name(xp, idx);
if (name != NULL) {
- return name;
+ return (char *)name;
}
}
return get_user_var_name(xp, ++intidx);
@@ -174,19 +170,20 @@ char_u *get_expr_name(expand_T *xp, int idx)
///
/// @param[in] name Name of the function.
///
-/// Returns pointer to the function definition or NULL if not found.
-const VimLFuncDef *find_internal_func(const char *const name)
+/// @return pointer to the function definition or NULL if not found.
+const EvalFuncDef *find_internal_func(const char *const name)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL
{
size_t len = strlen(name);
- return find_internal_func_gperf(name, len);
+ int index = find_internal_func_hash(name, len);
+ return index >= 0 ? &functions[index] : NULL;
}
int call_internal_func(const char_u *const fname, const int argcount, typval_T *const argvars,
typval_T *const rettv)
FUNC_ATTR_NONNULL_ALL
{
- const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ const EvalFuncDef *const fdef = find_internal_func((const char *)fname);
if (fdef == NULL) {
return ERROR_UNKNOWN;
} else if (argcount < fdef->min_argc) {
@@ -204,7 +201,7 @@ int call_internal_method(const char_u *const fname, const int argcount, typval_T
typval_T *const rettv, typval_T *const basetv)
FUNC_ATTR_NONNULL_ALL
{
- const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ const EvalFuncDef *const fdef = find_internal_func((const char *)fname);
if (fdef == NULL) {
return ERROR_UNKNOWN;
} else if (fdef->base_arg == BASE_NONE) {
@@ -228,9 +225,7 @@ int call_internal_method(const char_u *const fname, const int argcount, typval_T
return ERROR_NONE;
}
-/*
- * Return TRUE for a non-zero Number and a non-empty String.
- */
+/// @return TRUE for a non-zero Number and a non-empty String.
static int non_zero_arg(typval_T *argvars)
{
return ((argvars[0].v_type == VAR_NUMBER
@@ -242,11 +237,11 @@ static int non_zero_arg(typval_T *argvars)
&& *argvars[0].vval.v_string != NUL));
}
-// Apply a floating point C function on a typval with one float_T.
-//
-// Some versions of glibc on i386 have an optimization that makes it harder to
-// call math functions indirectly from inside an inlined function, causing
-// compile-time errors. Avoid `inline` in that case. #3072
+/// Apply a floating point C function on a typval with one float_T.
+///
+/// Some versions of glibc on i386 have an optimization that makes it harder to
+/// call math functions indirectly from inside an inlined function, causing
+/// compile-time errors. Avoid `inline` in that case. #3072
static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
@@ -292,9 +287,7 @@ end:
api_clear_error(&err);
}
-/*
- * "abs(expr)" function
- */
+/// "abs(expr)" function
static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type == VAR_FLOAT) {
@@ -314,9 +307,7 @@ static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "add(list, item)" function
- */
+/// "add(list, item)" function
static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 1; // Default: failed.
@@ -344,16 +335,13 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "and(expr, expr)" function
- */
+/// "and(expr, expr)" function
static void f_and(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
& tv_get_number_chk(&argvars[1], NULL);
}
-
/// "api_info()" function
static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -362,7 +350,7 @@ static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
api_free_dictionary(metadata);
}
-// "append(lnum, string/list)" function
+/// "append(lnum, string/list)" function
static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(&argvars[0]);
@@ -370,7 +358,7 @@ static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_buffer_lines(curbuf, lnum, true, &argvars[1], rettv);
}
-// "appendbufline(buf, lnum, string/list)" function
+/// "appendbufline(buf, lnum, string/list)" function
static void f_appendbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *const buf = tv_get_buf(&argvars[0], false);
@@ -402,9 +390,7 @@ static void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "argidx()" function
- */
+/// "argidx()" function
static void f_argidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = curwin->w_arg_idx;
@@ -420,9 +406,7 @@ static void f_arglistid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "argv(nr)" function
- */
+/// "argv(nr)" function
static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
aentry_T *arglist = NULL;
@@ -448,7 +432,7 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = NULL;
int idx = tv_get_number_chk(&argvars[0], NULL);
if (arglist != NULL && idx >= 0 && idx < argcount) {
- rettv->vval.v_string = (char_u *)xstrdup((const char *)alist_name(&arglist[idx]));
+ rettv->vval.v_string = xstrdup((const char *)alist_name(&arglist[idx]));
} else if (idx == -1) {
get_arglist_as_rettv(arglist, argcount, rettv);
}
@@ -457,93 +441,7 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "assert_beeps(cmd [, error])" function
-static void f_assert_beeps(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_beeps(argvars, false);
-}
-
-// "assert_nobeep(cmd [, error])" function
-static void f_assert_nobeep(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_beeps(argvars, true);
-}
-
-// "assert_equal(expected, actual[, msg])" function
-static void f_assert_equal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
-}
-
-// "assert_equalfile(fname-one, fname-two[, msg])" function
-static void f_assert_equalfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_equalfile(argvars);
-}
-
-// "assert_notequal(expected, actual[, msg])" function
-static void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
-}
-
-/// "assert_report(msg)
-static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- garray_T ga;
-
- prepare_assert_error(&ga);
- ga_concat(&ga, tv_get_string(&argvars[0]));
- assert_error(&ga);
- ga_clear(&ga);
- rettv->vval.v_number = 1;
-}
-
-/// "assert_exception(string[, msg])" function
-static void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_exception(argvars);
-}
-
-/// "assert_fails(cmd [, error [, msg]])" function
-static void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_fails(argvars);
-}
-
-// "assert_false(actual[, msg])" function
-static void f_assert_false(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_bool(argvars, false);
-}
-
-/// "assert_inrange(lower, upper[, msg])" function
-static void f_assert_inrange(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_inrange(argvars);
-}
-
-/// "assert_match(pattern, actual[, msg])" function
-static void f_assert_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
-}
-
-/// "assert_notmatch(pattern, actual[, msg])" function
-static void f_assert_notmatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
-}
-
-// "assert_true(actual[, msg])" function
-static void f_assert_true(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = assert_bool(argvars, true);
-}
-
-/*
- * "atan2()" function
- */
+/// "atan2()" function
static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T fx;
@@ -557,27 +455,20 @@ static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "browse(save, title, initdir, default)" function
- */
+/// "browse(save, title, initdir, default)" function
static void f_browse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
}
-/*
- * "browsedir(title, initdir)" function
- */
+/// "browsedir(title, initdir)" function
static void f_browsedir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
f_browse(argvars, rettv, NULL);
}
-
-/*
- * Find a buffer by number or exact name.
- */
+/// Find a buffer by number or exact name.
static buf_T *find_buffer(typval_T *avar)
{
buf_T *buf = NULL;
@@ -591,9 +482,7 @@ static buf_T *find_buffer(typval_T *avar)
* buffer, these don't use the full path. */
FOR_ALL_BUFFERS(bp) {
if (bp->b_fname != NULL
- && (path_with_url((char *)bp->b_fname)
- || bt_nofile(bp)
- )
+ && (path_with_url(bp->b_fname) || bt_nofilename(bp))
&& STRCMP(bp->b_fname, avar->vval.v_string) == 0) {
buf = bp;
break;
@@ -604,25 +493,21 @@ static buf_T *find_buffer(typval_T *avar)
return buf;
}
-// "bufadd(expr)" function
+/// "bufadd(expr)" function
static void f_bufadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *name = (char_u *)tv_get_string(&argvars[0]);
- rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0);
+ rettv->vval.v_number = buflist_add(*name == NUL ? NULL : (char *)name, 0);
}
-/*
- * "bufexists(expr)" function
- */
+/// "bufexists(expr)" function
static void f_bufexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
}
-/*
- * "buflisted(expr)" function
- */
+/// "buflisted(expr)" function
static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -631,7 +516,7 @@ static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
}
-// "bufload(expr)" function
+/// "bufload(expr)" function
static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr)
{
buf_T *buf = get_buf_arg(&argvars[0]);
@@ -646,9 +531,7 @@ static void f_bufload(typval_T *argvars, typval_T *unused, FunPtr fptr)
}
}
-/*
- * "bufloaded(expr)" function
- */
+/// "bufloaded(expr)" function
static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -657,9 +540,7 @@ static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
}
-/*
- * "bufname(expr)" function
- */
+/// "bufname(expr)" function
static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const buf_T *buf;
@@ -671,13 +552,11 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
buf = tv_get_buf_from_arg(&argvars[0]);
}
if (buf != NULL && buf->b_fname != NULL) {
- rettv->vval.v_string = (char_u *)xstrdup((char *)buf->b_fname);
+ rettv->vval.v_string = xstrdup(buf->b_fname);
}
}
-/*
- * "bufnr(expr)" function
- */
+/// "bufnr(expr)" function
static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const buf_T *buf;
@@ -707,7 +586,7 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
&& tv_get_number_chk(&argvars[1], &error) != 0
&& !error
&& (name = tv_get_string_chk(&argvars[0])) != NULL) {
- buf = buflist_new((char_u *)name, NULL, 1, 0);
+ buf = buflist_new((char *)name, NULL, 1, 0);
}
if (buf != NULL) {
@@ -749,14 +628,12 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
buf_win_common(argvars, rettv, true);
}
-/*
- * Get buffer by number or pattern.
- */
+/// Get buffer by number or pattern.
buf_T *tv_get_buf(typval_T *tv, int curtab_only)
{
- char_u *name = tv->vval.v_string;
+ char_u *name = (char_u *)tv->vval.v_string;
int save_magic;
- char_u *save_cpo;
+ char *save_cpo;
buf_T *buf;
if (tv->v_type == VAR_NUMBER) {
@@ -776,9 +653,9 @@ buf_T *tv_get_buf(typval_T *tv, int curtab_only)
save_magic = p_magic;
p_magic = TRUE;
save_cpo = p_cpo;
- p_cpo = (char_u *)"";
+ p_cpo = "";
- buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
+ buf = buflist_findnr(buflist_findpat((char *)name, (char *)name + STRLEN(name),
true, false, curtab_only));
p_magic = save_magic;
@@ -819,9 +696,7 @@ buf_T *get_buf_arg(typval_T *arg)
return buf;
}
-/*
- * "byte2line(byte)" function
- */
+/// "byte2line(byte)" function
static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long boff = tv_get_number(&argvars[0]) - 1;
@@ -848,25 +723,21 @@ static void byteidx(typval_T *argvars, typval_T *rettv, int comp)
return;
}
if (comp) {
- t += utf_ptr2len((const char_u *)t);
+ t += utf_ptr2len(t);
} else {
- t += utfc_ptr2len((const char_u *)t);
+ t += utfc_ptr2len(t);
}
}
rettv->vval.v_number = (varnumber_T)(t - str);
}
-/*
- * "byteidx()" function
- */
+/// "byteidx()" function
static void f_byteidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
byteidx(argvars, rettv, FALSE);
}
-/*
- * "byteidxcomp()" function
- */
+/// "byteidxcomp()" function
static void f_byteidxcomp(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
byteidx(argvars, rettv, TRUE);
@@ -888,11 +759,12 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
partial_T *partial = NULL;
dict_T *selfdict = NULL;
if (argvars[0].v_type == VAR_FUNC) {
- func = argvars[0].vval.v_string;
+ func = (char_u *)argvars[0].vval.v_string;
} else if (argvars[0].v_type == VAR_PARTIAL) {
partial = argvars[0].vval.v_partial;
- func = partial_name(partial);
+ func = (char_u *)partial_name(partial);
} else if (nlua_is_table_from_lua(&argvars[0])) {
+ // TODO(tjdevries): UnifiedCallback
func = nlua_register_table_as_callable(&argvars[0]);
owned = true;
} else {
@@ -906,6 +778,9 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[2].v_type != VAR_UNKNOWN) {
if (argvars[2].v_type != VAR_DICT) {
emsg(_(e_dictreq));
+ if (owned) {
+ func_unref(func);
+ }
return;
}
selfdict = argvars[2].vval.v_dict;
@@ -917,15 +792,13 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "changenr()" function
- */
+/// "changenr()" function
static void f_changenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = curbuf->b_u_seq_cur;
}
-// "chanclose(id[, stream])" function
+/// "chanclose(id[, stream])" function
static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -943,7 +816,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ChannelPart part = kChannelPartAll;
if (argvars[1].v_type == VAR_STRING) {
- char *stream = (char *)argvars[1].vval.v_string;
+ char *stream = argvars[1].vval.v_string;
if (!strcmp(stream, "stdin")) {
part = kChannelPartStdin;
} else if (!strcmp(stream, "stdout")) {
@@ -964,7 +837,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "chansend(id, data)" function
+/// "chansend(id, data)" function
static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -1005,9 +878,7 @@ static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "char2nr(string)" function
- */
+/// "char2nr(string)" function
static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -1016,10 +887,54 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- rettv->vval.v_number = utf_ptr2char((const char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_number = utf_ptr2char(tv_get_string(&argvars[0]));
}
-// "charidx()" function
+/// Get the current cursor column and store it in 'rettv'.
+///
+/// @return the character index of the column if 'charcol' is true,
+/// otherwise the byte index of the column.
+static void get_col(typval_T *argvars, typval_T *rettv, bool charcol)
+{
+ colnr_T col = 0;
+ pos_T *fp;
+ int fnum = curbuf->b_fnum;
+
+ fp = var2fpos(&argvars[0], false, &fnum, charcol);
+ if (fp != NULL && fnum == curbuf->b_fnum) {
+ if (fp->col == MAXCOL) {
+ // '> can be MAXCOL, get the length of the line then
+ if (fp->lnum <= curbuf->b_ml.ml_line_count) {
+ col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
+ } else {
+ col = MAXCOL;
+ }
+ } else {
+ col = fp->col + 1;
+ // col(".") when the cursor is on the NUL at the end of the line
+ // because of "coladd" can be seen as an extra column.
+ if (virtual_active() && fp == &curwin->w_cursor) {
+ char_u *p = get_cursor_pos_ptr();
+ if (curwin->w_cursor.coladd >=
+ (colnr_T)win_chartabsize(curwin, p, curwin->w_virtcol - curwin->w_cursor.coladd)) {
+ int l;
+ if (*p != NUL && p[(l = utfc_ptr2len((char *)p))] == NUL) {
+ col += l;
+ }
+ }
+ }
+ }
+ }
+ rettv->vval.v_number = col;
+}
+
+/// "charcol()" function
+static void f_charcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ get_col(argvars, rettv, true);
+}
+
+/// "charidx()" function
static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -1046,7 +961,7 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- int (*ptr2len)(const char_u *);
+ int (*ptr2len)(const char *);
if (countcc) {
ptr2len = utf_ptr2len;
} else {
@@ -1059,13 +974,13 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (*p == NUL) {
return;
}
- p += ptr2len((const char_u *)p);
+ p += ptr2len(p);
}
rettv->vval.v_number = len > 0 ? len - 1 : 0;
}
-// "chdir(dir)" function
+/// "chdir(dir)" function
static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *cwd;
@@ -1086,7 +1001,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(cwd);
#endif
- rettv->vval.v_string = vim_strsave(cwd);
+ rettv->vval.v_string = (char *)vim_strsave(cwd);
}
xfree(cwd);
@@ -1102,9 +1017,7 @@ static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "cindent(lnum)" function
- */
+/// "cindent(lnum)" function
static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T pos;
@@ -1121,7 +1034,7 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-static win_T *get_optional_window(typval_T *argvars, int idx)
+win_T *get_optional_window(typval_T *argvars, int idx)
{
win_T *win = curwin;
@@ -1135,65 +1048,16 @@ static win_T *get_optional_window(typval_T *argvars, int idx)
return win;
}
-/*
- * "clearmatches()" function
- */
-static void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- win_T *win = get_optional_window(argvars, 0);
-
- if (win != NULL) {
- clear_matches(win);
- }
-}
-
-/*
- * "col(string)" function
- */
+/// "col(string)" function
static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- colnr_T col = 0;
- pos_T *fp;
- int fnum = curbuf->b_fnum;
-
- fp = var2fpos(&argvars[0], FALSE, &fnum);
- if (fp != NULL && fnum == curbuf->b_fnum) {
- if (fp->col == MAXCOL) {
- // '> can be MAXCOL, get the length of the line then
- if (fp->lnum <= curbuf->b_ml.ml_line_count) {
- col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
- } else {
- col = MAXCOL;
- }
- } else {
- col = fp->col + 1;
- // col(".") when the cursor is on the NUL at the end of the line
- // because of "coladd" can be seen as an extra column.
- if (virtual_active() && fp == &curwin->w_cursor) {
- char_u *p = get_cursor_pos_ptr();
-
- if (curwin->w_cursor.coladd
- >= (colnr_T)win_chartabsize(curwin, p,
- (curwin->w_virtcol
- - curwin->w_cursor.coladd))) {
- int l;
-
- if (*p != NUL && p[(l = utfc_ptr2len(p))] == NUL) {
- col += l;
- }
- }
- }
- }
- }
- rettv->vval.v_number = col;
+ get_col(argvars, rettv, false);
}
-/*
- * "complete()" function
- */
+/// "complete()" function
static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if ((State & INSERT) == 0) {
+ if ((State & MODE_INSERT) == 0) {
emsg(_("E785: complete() can only be used in Insert mode"));
return;
}
@@ -1206,28 +1070,21 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[1].v_type != VAR_LIST) {
emsg(_(e_invarg));
- return;
- }
-
- const colnr_T startcol = tv_get_number_chk(&argvars[0], NULL);
- if (startcol <= 0) {
- return;
+ } else {
+ const colnr_T startcol = tv_get_number_chk(&argvars[0], NULL);
+ if (startcol > 0) {
+ set_completion(startcol - 1, argvars[1].vval.v_list);
+ }
}
-
- set_completion(startcol - 1, argvars[1].vval.v_list);
}
-/*
- * "complete_add()" function
- */
+/// "complete_add()" function
static void f_complete_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0, false);
}
-/*
- * "complete_check()" function
- */
+/// "complete_check()" function
static void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int saved = RedrawingDisabled;
@@ -1238,7 +1095,7 @@ static void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr)
RedrawingDisabled = saved;
}
-// "complete_info()" function
+/// "complete_info()" function
static void f_complete_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
@@ -1255,9 +1112,7 @@ static void f_complete_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_complete_info(what_list, rettv->vval.v_dict);
}
-/*
- * "confirm(message, buttons[, default [, type]])" function
- */
+/// "confirm(message, buttons[, default [, type]])" function
static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
@@ -1312,17 +1167,13 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "copy()" function
- */
+/// "copy()" function
static void f_copy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
var_item_copy(NULL, &argvars[0], rettv, false, 0);
}
-/*
- * "count()" function
- */
+/// "count()" function
static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long n = 0;
@@ -1335,7 +1186,7 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[0].v_type == VAR_STRING) {
const char_u *expr = (char_u *)tv_get_string_chk(&argvars[1]);
- const char_u *p = argvars[0].vval.v_string;
+ const char_u *p = (char_u *)argvars[0].vval.v_string;
if (!error && expr != NULL && *expr != NUL && p != NULL) {
if (ic) {
@@ -1413,11 +1264,9 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
- *
- * Checks the existence of a cscope connection.
- */
+/// "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
+///
+/// Checks the existence of a cscope connection.
static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int num = 0;
@@ -1548,24 +1397,21 @@ static void f_ctxsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = ctx_size();
}
-/// "cursor(lnum, col)" function, or
-/// "cursor(list)"
-///
-/// Moves the cursor to the specified line and column.
-///
-/// @returns 0 when the position could be set, -1 otherwise.
-static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+/// Set the cursor position.
+/// If 'charcol' is true, then use the column number as a character offset.
+/// Otherwise use the column number as a byte offset.
+static void set_cursorpos(typval_T *argvars, typval_T *rettv, bool charcol)
{
long line, col;
long coladd = 0;
bool set_curswant = true;
rettv->vval.v_number = -1;
- if (argvars[1].v_type == VAR_UNKNOWN) {
+ if (argvars[0].v_type == VAR_LIST) {
pos_T pos;
colnr_T curswant = -1;
- if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL) {
+ if (list2fpos(argvars, &pos, NULL, &curswant, charcol) == FAIL) {
emsg(_(e_invarg));
return;
}
@@ -1577,16 +1423,22 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
curwin->w_curswant = curswant - 1;
set_curswant = false;
}
- } else {
+ } else if ((argvars[0].v_type == VAR_NUMBER || argvars[0].v_type == VAR_STRING)
+ && (argvars[1].v_type == VAR_NUMBER || argvars[1].v_type == VAR_STRING)) {
line = tv_get_lnum(argvars);
col = (long)tv_get_number_chk(&argvars[1], NULL);
+ if (charcol) {
+ col = buf_charidx_to_byteidx(curbuf, line, col) + 1;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
coladd = (long)tv_get_number_chk(&argvars[2], NULL);
}
+ } else {
+ emsg(_(e_invarg));
+ return;
}
- if (line < 0 || col < 0
- || coladd < 0) {
- return; // type error; errmsg already given
+ if (line < 0 || col < 0 || coladd < 0) {
+ return; // type error; errmsg already given
}
if (line > 0) {
curwin->w_cursor.lnum = line;
@@ -1605,7 +1457,18 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 0;
}
-// "debugbreak()" function
+/// "cursor(lnum, col)" function, or
+/// "cursor(list)"
+///
+/// Moves the cursor to the specified line and column.
+///
+/// @return 0 when the position could be set, -1 otherwise.
+static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ set_cursorpos(argvars, rettv, false);
+}
+
+/// "debugbreak()" function
static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int pid;
@@ -1629,7 +1492,7 @@ static void f_debugbreak(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "deepcopy()" function
+/// "deepcopy()" function
static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int noref = 0;
@@ -1646,7 +1509,7 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "delete()" function
+/// "delete()" function
static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -1682,7 +1545,7 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// dictwatcheradd(dict, key, funcref) function
+/// dictwatcheradd(dict, key, funcref) function
static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -1720,7 +1583,7 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
callback);
}
-// dictwatcherdel(dict, key, funcref) function
+/// dictwatcherdel(dict, key, funcref) function
static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -1768,6 +1631,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
const bool is_curbuf = buf == curbuf;
+ const bool save_VIsual_active = VIsual_active;
const linenr_T first = tv_get_lnum_buf(&argvars[1], buf);
if (argvars[2].v_type != VAR_UNKNOWN) {
@@ -1783,6 +1647,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (!is_curbuf) {
+ VIsual_active = false;
curbuf_save = curbuf;
curwin_save = curwin;
curbuf = buf;
@@ -1826,28 +1691,23 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!is_curbuf) {
curbuf = curbuf_save;
curwin = curwin_save;
+ VIsual_active = save_VIsual_active;
}
}
-/*
- * "did_filetype()" function
- */
+/// "did_filetype()" function
static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = did_filetype;
}
-/*
- * "diff_filler()" function
- */
+/// "diff_filler()" function
static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = MAX(0, diff_check(curwin, tv_get_lnum(argvars)));
}
-/*
- * "diff_hlID()" function
- */
+/// "diff_hlID()" function
static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = tv_get_lnum(argvars);
@@ -1899,9 +1759,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)(hlID + 1);
}
-/*
- * "empty({expr})" function
- */
+/// "empty({expr})" function
static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool n = true;
@@ -1998,15 +1856,14 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
os_free_fullenv(env);
}
-/*
- * "escape({string}, {chars})" function
- */
+/// "escape({string}, {chars})" function
static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
- rettv->vval.v_string = vim_strsave_escaped((const char_u *)tv_get_string(&argvars[0]),
- (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ rettv->vval.v_string = (char *)vim_strsave_escaped((const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1],
+ buf));
rettv->v_type = VAR_STRING;
}
@@ -2020,22 +1877,20 @@ static void f_getenv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_special = kSpecialVarNull;
return;
}
- rettv->vval.v_string = p;
+ rettv->vval.v_string = (char *)p;
rettv->v_type = VAR_STRING;
}
-/*
- * "eval()" function
- */
+/// "eval()" function
static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *s = tv_get_string_chk(&argvars[0]);
if (s != NULL) {
- s = (const char *)skipwhite((const char_u *)s);
+ s = (const char *)skipwhite(s);
}
const char *const expr_start = s;
- if (s == NULL || eval1((char_u **)&s, rettv, true) == FAIL) {
+ if (s == NULL || eval1((char **)&s, rettv, true) == FAIL) {
if (expr_start != NULL && !aborting()) {
semsg(_(e_invexpr2), expr_start);
}
@@ -2047,17 +1902,13 @@ static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "eventhandler()" function
- */
+/// "eventhandler()" function
static void f_eventhandler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = vgetc_busy;
}
-/*
- * "executable()" function
- */
+/// "executable()" function
static void f_executable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (tv_check_for_string(&argvars[0]) == FAIL) {
@@ -2073,7 +1924,7 @@ typedef struct {
const listitem_T *li;
} GetListLineCookie;
-static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
+static char *get_list_line(int c, void *cookie, int indent, bool do_concat)
{
GetListLineCookie *const p = (GetListLineCookie *)cookie;
@@ -2084,7 +1935,7 @@ static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
char buf[NUMBUFLEN];
const char *const s = tv_get_string_buf_chk(TV_LIST_ITEM_TV(item), buf);
p->li = TV_LIST_ITEM_NEXT(p->l, item);
- return (char_u *)(s == NULL ? NULL : xstrdup(s));
+ return s == NULL ? NULL : xstrdup(s);
}
static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int arg_off)
@@ -2165,36 +2016,24 @@ static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr, int
capture_ga = save_capture_ga;
}
-// "execute(command)" function
+/// "execute(command)" function
static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
execute_common(argvars, rettv, fptr, 0);
}
-// "win_execute(win_id, command)" function
+/// "win_execute(win_id, command)" function
static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- tabpage_T *tp;
- win_T *wp = win_id2wp_tp(argvars, &tp);
- win_T *save_curwin;
- tabpage_T *save_curtab;
// Return an empty string if something fails.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ int id = tv_get_number(argvars);
+ tabpage_T *tp;
+ win_T *wp = win_id2wp_tp(id, &tp);
if (wp != NULL && tp != NULL) {
- pos_T curpos = wp->w_cursor;
- if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, true) ==
- OK) {
- check_cursor();
- execute_common(argvars, rettv, fptr, 1);
- }
- restore_win_noblock(save_curwin, save_curtab, true);
-
- // Update the status line if the cursor moved.
- if (win_valid(wp) && !equalpos(curpos, wp->w_cursor)) {
- wp->w_redr_status = true;
- }
+ WIN_EXECUTE(wp, tp, execute_common(argvars, rettv, fptr, 1));
}
}
@@ -2209,13 +2048,17 @@ static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
(void)os_can_exe(tv_get_string(&argvars[0]), &path, true);
+#ifdef BACKSLASH_IN_FILENAME
+ if (path != NULL) {
+ slash_adjust((char_u *)path);
+ }
+#endif
+
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)path;
+ rettv->vval.v_string = path;
}
-/*
- * "exists()" function
- */
+/// "exists()" function
static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = false;
@@ -2227,7 +2070,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = true;
} else {
// Try expanding things like $VIM and ${HOME}.
- char_u *const exp = expand_env_save((char_u *)p);
+ char *const exp = expand_env_save((char *)p);
if (exp != NULL && *exp != '$') {
n = true;
}
@@ -2235,7 +2078,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else if (*p == '&' || *p == '+') { // Option.
n = (get_option_tv(&p, NULL, true) == OK);
- if (*skipwhite((const char_u *)p) != NUL) {
+ if (*skipwhite(p) != NUL) {
n = false; // Trailing garbage.
}
} else if (*p == '*') { // Internal or user defined function.
@@ -2255,9 +2098,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "expand()" function
- */
+/// "expand()" function
static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
size_t len;
@@ -2293,7 +2134,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
XFREE_CLEAR(result);
} else {
- rettv->vval.v_string = result;
+ rettv->vval.v_string = (char *)result;
}
} else {
// When the optional second argument is non-zero, don't remove matches
@@ -2309,8 +2150,8 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
options += WILD_ICASE;
}
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = ExpandOne(&xpc, (char_u *)s, NULL, options,
- WILD_ALL);
+ rettv->vval.v_string = (char *)ExpandOne(&xpc, (char_u *)s, NULL, options,
+ WILD_ALL);
} else {
ExpandOne(&xpc, (char_u *)s, NULL, options, WILD_ALL_KEEP);
tv_list_alloc_ret(rettv, xpc.xp_numfiles);
@@ -2329,7 +2170,6 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#endif
}
-
/// "menu_get(path [, modes])" function
static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -2339,11 +2179,11 @@ static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *const strmodes = tv_get_string(&argvars[1]);
modes = get_menu_cmd_modes(strmodes, false, NULL, NULL);
}
- menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
+ menu_get((char *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
}
-// "expandcmd()" function
-// Expand all the special characters in a command string.
+/// "expandcmd()" function
+/// Expand all the special characters in a command string.
static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char *errormsg = NULL;
@@ -2352,8 +2192,8 @@ static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char_u *cmdstr = (char_u *)xstrdup(tv_get_string(&argvars[0]));
exarg_T eap = {
- .cmd = cmdstr,
- .arg = cmdstr,
+ .cmd = (char *)cmdstr,
+ .arg = (char *)cmdstr,
.usefilter = false,
.nextcmd = NULL,
.cmdidx = CMD_USER,
@@ -2364,10 +2204,9 @@ static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (errormsg != NULL && *errormsg != NUL) {
emsg(errormsg);
}
- rettv->vval.v_string = cmdstr;
+ rettv->vval.v_string = (char *)cmdstr;
}
-
/// "flatten(list[, {maxdepth}])" function
static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -2403,10 +2242,8 @@ static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "extend(list, list [, idx])" function
- * "extend(dict, dict [, action])" function
- */
+/// "extend(list, list [, idx])" function
+/// "extend(dict, dict [, action])" function
static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const arg_errmsg = N_("extend() argument");
@@ -2483,9 +2320,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "feedkeys()" function
- */
+/// "feedkeys()" function
static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
// This is not allowed in the sandbox. If the commands would still be
@@ -2514,17 +2349,15 @@ static void f_filereadable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
(*p && !os_isdir((const char_u *)p) && os_file_is_readable(p));
}
-/*
- * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
- * rights to write into.
- */
+/// @return 0 for not writable
+/// 1 for writable file
+/// 2 for a dir which we have rights to write into.
static void f_filewritable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *filename = tv_get_string(&argvars[0]);
rettv->vval.v_number = os_file_is_writable(filename);
}
-
static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
{
char_u *fresult = NULL;
@@ -2566,7 +2399,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
fresult = find_file_in_path_option(first ? (char_u *)fname : NULL,
first ? strlen(fname) : 0,
0, first, path,
- find_what, curbuf->b_ffname,
+ find_what, (char_u *)curbuf->b_ffname,
(find_what == FINDFILE_DIR
? (char_u *)""
: curbuf->b_p_sua));
@@ -2579,44 +2412,35 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
}
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = fresult;
+ rettv->vval.v_string = (char *)fresult;
}
}
-
-/*
- * "filter()" function
- */
+/// "filter()" function
static void f_filter(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
filter_map(argvars, rettv, FALSE);
}
-/*
- * "finddir({fname}[, {path}[, {count}]])" function
- */
+/// "finddir({fname}[, {path}[, {count}]])" function
static void f_finddir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
findfilendir(argvars, rettv, FINDFILE_DIR);
}
-/*
- * "findfile({fname}[, {path}[, {count}]])" function
- */
+/// "findfile({fname}[, {path}[, {count}]])" function
static void f_findfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
findfilendir(argvars, rettv, FINDFILE_FILE);
}
-/*
- * "float2nr({float})" function
- */
+/// "float2nr({float})" function
static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
if (tv_get_float_chk(argvars, &f)) {
- if (f <= (float_T)-VARNUMBER_MAX + DBL_EPSILON) {
+ if (f <= (float_T) - VARNUMBER_MAX + DBL_EPSILON) {
rettv->vval.v_number = -VARNUMBER_MAX;
} else if (f >= (float_T)VARNUMBER_MAX - DBL_EPSILON) {
rettv->vval.v_number = VARNUMBER_MAX;
@@ -2626,9 +2450,7 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "fmod()" function
- */
+/// "fmod()" function
static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T fx;
@@ -2642,18 +2464,14 @@ static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "fnameescape({string})" function
- */
+/// "fnameescape({string})" function
static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(tv_get_string(&argvars[0]), false);
+ rettv->vval.v_string = vim_strsave_fnameescape(tv_get_string(&argvars[0]), VSE_NONE);
rettv->v_type = VAR_STRING;
}
-/*
- * "fnamemodify({fname}, {mods})" function
- */
+/// "fnamemodify({fname}, {mods})" function
static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *fbuf = NULL;
@@ -2667,8 +2485,8 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
len = strlen(fname);
if (*mods != NUL) {
size_t usedlen = 0;
- (void)modify_fname((char_u *)mods, false, &usedlen,
- (char_u **)&fname, &fbuf, &len);
+ (void)modify_fname((char *)mods, false, &usedlen,
+ (char **)&fname, (char **)&fbuf, &len);
}
}
@@ -2676,15 +2494,12 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (fname == NULL) {
rettv->vval.v_string = NULL;
} else {
- rettv->vval.v_string = (char_u *)xmemdupz(fname, len);
+ rettv->vval.v_string = xmemdupz(fname, len);
}
xfree(fbuf);
}
-
-/*
- * "foldclosed()" function
- */
+/// "foldclosed()" function
static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -2703,25 +2518,19 @@ static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
rettv->vval.v_number = -1;
}
-/*
- * "foldclosed()" function
- */
+/// "foldclosed()" function
static void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, FALSE);
}
-/*
- * "foldclosedend()" function
- */
+/// "foldclosedend()" function
static void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, TRUE);
}
-/*
- * "foldlevel()" function
- */
+/// "foldlevel()" function
static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -2730,9 +2539,7 @@ static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "foldtext()" function
- */
+/// "foldtext()" function
static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T foldstart;
@@ -2749,7 +2556,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART);
foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
- dashes = get_vim_var_str(VV_FOLDDASHES);
+ dashes = (char_u *)get_vim_var_str(VV_FOLDDASHES);
if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) {
// Find first non-empty line in the fold.
for (lnum = foldstart; lnum < foldend; lnum++) {
@@ -2759,18 +2566,18 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// Find interesting text in this line.
- s = skipwhite(ml_get(lnum));
+ s = (char_u *)skipwhite((char *)ml_get(lnum));
// skip C comment-start
if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) {
- s = skipwhite(s + 2);
- if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
- s = skipwhite(ml_get(lnum + 1));
+ s = (char_u *)skipwhite((char *)s + 2);
+ if (*skipwhite((char *)s) == NUL && lnum + 1 < foldend) {
+ s = (char_u *)skipwhite((char *)ml_get(lnum + 1));
if (*s == '*') {
- s = skipwhite(s + 1);
+ s = (char_u *)skipwhite((char *)s + 1);
}
}
}
- unsigned long count = (unsigned long)(foldend - foldstart + 1);
+ unsigned long count = (unsigned long)foldend - foldstart + 1;
txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
r = xmalloc(STRLEN(txt)
+ STRLEN(dashes) // for %s
@@ -2781,13 +2588,11 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
STRCAT(r, s);
// remove 'foldmarker' and 'commentstring'
foldtext_cleanup(r + len);
- rettv->vval.v_string = r;
+ rettv->vval.v_string = (char *)r;
}
}
-/*
- * "foldtextresult(lnum)" function
- */
+/// "foldtextresult(lnum)" function
static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *text;
@@ -2812,18 +2617,15 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (text == buf) {
text = vim_strsave(text);
}
- rettv->vval.v_string = text;
+ rettv->vval.v_string = (char *)text;
}
entered = false;
}
-/*
- * "foreground()" function
- */
+/// "foreground()" function
static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
-}
+{}
static void f_funcref(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -2847,9 +2649,7 @@ static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "get()" function
- */
+/// "get()" function
static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
listitem_T *li;
@@ -2899,7 +2699,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
pt = argvars[0].vval.v_partial;
} else {
memset(&fref_pt, 0, sizeof(fref_pt));
- fref_pt.pt_name = argvars[0].vval.v_string;
+ fref_pt.pt_name = (char_u *)argvars[0].vval.v_string;
pt = &fref_pt;
}
@@ -2910,9 +2710,9 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING);
const char *const n = (const char *)partial_name(pt);
assert(n != NULL);
- rettv->vval.v_string = (char_u *)xstrdup(n);
+ rettv->vval.v_string = xstrdup(n);
if (rettv->v_type == VAR_FUNC) {
- func_ref(rettv->vval.v_string);
+ func_ref((char_u *)rettv->vval.v_string);
}
} else if (strcmp(what, "dict") == 0) {
what_is_dict = true;
@@ -3009,12 +2809,12 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * Get line or list of lines from buffer "buf" into "rettv".
- * Return a range (from start to end) of lines in rettv from the specified
- * buffer.
- * If 'retlist' is TRUE, then the lines are returned as a Vim List.
- */
+/// Get line or list of lines from buffer "buf" into "rettv".
+///
+/// @param retlist if TRUE, then the lines are returned as a Vim List.
+///
+/// @return range (from start to end) of lines in rettv from the specified
+/// buffer.
static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)
{
rettv->v_type = (retlist ? VAR_LIST : VAR_STRING);
@@ -3041,15 +2841,13 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli
}
} else {
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = ((start >= 1 && start <= buf->b_ml.ml_line_count)
- ? vim_strsave(ml_get_buf(buf, start, false))
- : NULL);
+ rettv->vval.v_string =
+ (char *)((start >= 1 && start <= buf->b_ml.ml_line_count)
+ ? vim_strsave(ml_get_buf(buf, start, false)) : NULL);
}
}
-/*
- * "getbufline()" function
- */
+/// "getbufline()" function
static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *const buf = tv_get_buf_from_arg(&argvars[0]);
@@ -3062,9 +2860,7 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_buffer_lines(buf, lnum, end, true, rettv);
}
-/*
- * "getbufvar()" function
- */
+/// "getbufvar()" function
static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool done = false;
@@ -3124,7 +2920,7 @@ f_getbufvar_end:
}
}
-// "getchangelist()" function
+/// "getchangelist()" function
static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
@@ -3164,7 +2960,7 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "getchar()" and "getcharstr()" functions
+/// "getchar()" and "getcharstr()" functions
static void getchar_common(typval_T *argvars, typval_T *rettv)
FUNC_ATTR_NONNULL_ALL
{
@@ -3172,6 +2968,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
bool error = false;
no_mapping++;
+ allow_keys++;
for (;;) {
// Position the cursor. Needed after a message that ends in a space,
// or if event processing caused a redraw.
@@ -3180,7 +2977,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
if (argvars[0].v_type == VAR_UNKNOWN) {
// getchar(): blocking wait.
// TODO(bfredl): deduplicate shared logic with state_enter ?
- if (!(char_avail() || using_script() || input_available())) {
+ if (!char_avail()) {
(void)os_inchar(NULL, 0, -1, 0, main_loop.events);
if (!multiqueue_empty(main_loop.events)) {
state_handle_k_event();
@@ -3209,6 +3006,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
break;
}
no_mapping--;
+ allow_keys--;
set_vim_var_nr(VV_MOUSE_WIN, 0);
set_vim_var_nr(VV_MOUSE_WINID, 0);
@@ -3216,7 +3014,7 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
set_vim_var_nr(VV_MOUSE_COL, 0);
rettv->vval.v_number = n;
- if (IS_SPECIAL(n) || mod_mask != 0) {
+ if (n != 0 && (IS_SPECIAL(n) || mod_mask != 0)) {
char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1
int i = 0;
@@ -3231,12 +3029,12 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
temp[i++] = K_SECOND(n);
temp[i++] = K_THIRD(n);
} else {
- i += utf_char2bytes(n, temp + i);
+ i += utf_char2bytes(n, (char *)temp + i);
}
assert(i < 10);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(temp);
+ rettv->vval.v_string = (char *)vim_strsave(temp);
if (is_mouse_key(n)) {
int row = mouse_row;
@@ -3266,43 +3064,100 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
}
}
-// "getchar()" function
+/// "getchar()" function
static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getchar_common(argvars, rettv);
}
-// "getcharstr()" function
+/// "getcharstr()" function
static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getchar_common(argvars, rettv);
if (rettv->v_type == VAR_NUMBER) {
- char_u temp[7]; // mbyte-char: 6, NUL: 1
+ char temp[7]; // mbyte-char: 6, NUL: 1
const varnumber_T n = rettv->vval.v_number;
int i = 0;
if (n != 0) {
- i += utf_char2bytes(n, temp);
+ i += utf_char2bytes(n, (char *)temp);
}
assert(i < 7);
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(temp);
+ rettv->vval.v_string = xstrdup(temp);
}
}
-/*
- * "getcharmod()" function
- */
+/// "getcharmod()" function
static void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = mod_mask;
}
-/*
- * "getcharsearch()" function
- */
+static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos, bool charcol)
+{
+ pos_T *fp = NULL;
+ pos_T pos;
+ win_T *wp = curwin;
+ int fnum = -1;
+
+ if (getcurpos) {
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp != NULL) {
+ fp = &wp->w_cursor;
+ }
+ } else {
+ fp = &curwin->w_cursor;
+ }
+ if (fp != NULL && charcol) {
+ pos = *fp;
+ pos.col = buf_byteidx_to_charidx(wp->w_buffer, pos.lnum, pos.col);
+ fp = &pos;
+ }
+ } else {
+ fp = var2fpos(&argvars[0], true, &fnum, charcol);
+ }
+
+ list_T *const l = tv_list_alloc_ret(rettv, 4 + getcurpos);
+ tv_list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
+ tv_list_append_number(l, ((fp != NULL) ? (varnumber_T)fp->lnum : (varnumber_T)0));
+ tv_list_append_number(l, ((fp != NULL)
+ ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
+ : (varnumber_T)0));
+ tv_list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
+ if (getcurpos) {
+ const int save_set_curswant = curwin->w_set_curswant;
+ const colnr_T save_curswant = curwin->w_curswant;
+ const colnr_T save_virtcol = curwin->w_virtcol;
+
+ if (wp == curwin) {
+ update_curswant();
+ }
+ tv_list_append_number(l, (wp == NULL) ? 0 : ((wp->w_curswant == MAXCOL)
+ ? (varnumber_T)MAXCOL
+ : (varnumber_T)wp->w_curswant + 1));
+
+ // Do not change "curswant", as it is unexpected that a get
+ // function has a side effect.
+ if (wp == curwin && save_set_curswant) {
+ curwin->w_set_curswant = save_set_curswant;
+ curwin->w_curswant = save_curswant;
+ curwin->w_virtcol = save_virtcol;
+ curwin->w_valid &= ~VALID_VIRTCOL;
+ }
+ }
+}
+
+/// "getcharpos()" function
+static void f_getcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ getpos_both(argvars, rettv, false, true);
+}
+
+/// "getcharsearch()" function
static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
@@ -3314,26 +3169,33 @@ static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(dict, S_LEN("until"), last_csearch_until());
}
-/*
- * "getcmdline()" function
- */
+/// "getcmdcompltype()" function
+static void f_getcmdcompltype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = (char *)get_cmdline_completion();
+}
+
+/// "getcmdline()" function
static void f_getcmdline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = get_cmdline_str();
+ rettv->vval.v_string = (char *)get_cmdline_str();
}
-/*
- * "getcmdpos()" function
- */
+/// "getcmdpos()" function
static void f_getcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = get_cmdline_pos() + 1;
}
-/*
- * "getcmdtype()" function
- */
+/// "getcmdscreenpos()" function
+static void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->vval.v_number = get_cmdline_screen_pos() + 1;
+}
+
+/// "getcmdtype()" function
static void f_getcmdtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -3341,9 +3203,7 @@ static void f_getcmdtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string[0] = get_cmdline_type();
}
-/*
- * "getcmdwintype()" function
- */
+/// "getcmdwintype()" function
static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -3352,7 +3212,7 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string[0] = cmdwin_type;
}
-// "getcompletion()" function
+/// "getcompletion()" function
static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *pat;
@@ -3394,7 +3254,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
ExpandInit(&xpc);
- xpc.xp_pattern = (char_u *)pattern;
+ xpc.xp_pattern = (char *)pattern;
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
xpc.xp_context = cmdcomplete_str_to_type(type);
if (xpc.xp_context == EXPAND_NOTHING) {
@@ -3413,12 +3273,12 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (xpc.xp_context == EXPAND_SIGN) {
- set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
+ set_context_in_sign_cmd(&xpc, (char_u *)xpc.xp_pattern);
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
}
theend:
- pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
+ pat = addstar((char_u *)xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
ExpandOne(&xpc, pat, NULL, options, WILD_ALL_KEEP);
tv_list_alloc_ret(rettv, xpc.xp_numfiles);
@@ -3451,8 +3311,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
[kCdScopeTabpage] = 0, // Number of tab to look at.
};
- char_u *cwd = NULL; // Current working directory to print
- char_u *from = NULL; // The original string to copy
+ char *cwd = NULL; // Current working directory to print
+ char *from = NULL; // The original string to copy
tabpage_T *tp = curtab; // The tabpage to look at.
win_T *win = curwin; // The window to look at.
@@ -3534,8 +3394,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
FALLTHROUGH; // In global directory, just need to get OS CWD.
case kCdScopeInvalid: // If called without any arguments, get OS CWD.
- if (os_dirname(cwd, MAXPATHL) == FAIL) {
- from = (char_u *)""; // Return empty string on failure.
+ if (os_dirname((char_u *)cwd, MAXPATHL) == FAIL) {
+ from = ""; // Return empty string on failure.
}
}
@@ -3543,7 +3403,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
STRLCPY(cwd, from, MAXPATHL);
}
- rettv->vval.v_string = vim_strsave(cwd);
+ rettv->vval.v_string = xstrdup(cwd);
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(rettv->vval.v_string);
#endif
@@ -3551,18 +3411,14 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(cwd);
}
-/*
- * "getfontname()" function
- */
+/// "getfontname()" function
static void f_getfontname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
}
-/*
- * "getfperm({fname})" function
- */
+/// "getfperm({fname})" function
static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char *perm = NULL;
@@ -3579,12 +3435,10 @@ static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)perm;
+ rettv->vval.v_string = perm;
}
-/*
- * "getfsize({fname})" function
- */
+/// "getfsize({fname})" function
static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *fname = tv_get_string(&argvars[0]);
@@ -3609,9 +3463,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "getftime({fname})" function
- */
+/// "getftime({fname})" function
static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *fname = tv_get_string(&argvars[0]);
@@ -3624,9 +3476,7 @@ static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "getftype({fname})" function
- */
+/// "getftype({fname})" function
static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *type = NULL;
@@ -3657,10 +3507,10 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
type = vim_strsave((char_u *)t);
}
- rettv->vval.v_string = type;
+ rettv->vval.v_string = (char *)type;
}
-// "getjumplist()" function
+/// "getjumplist()" function
static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, kListLenMayKnow);
@@ -3686,14 +3536,12 @@ static void f_getjumplist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(d, S_LEN("coladd"), wp->w_jumplist[i].fmark.mark.coladd);
tv_dict_add_nr(d, S_LEN("bufnr"), wp->w_jumplist[i].fmark.fnum);
if (wp->w_jumplist[i].fname != NULL) {
- tv_dict_add_str(d, S_LEN("filename"), (char *)wp->w_jumplist[i].fname);
+ tv_dict_add_str(d, S_LEN("filename"), wp->w_jumplist[i].fname);
}
}
}
-/*
- * "getline(lnum, [end])" function
- */
+/// "getline(lnum, [end])" function
static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T end;
@@ -3718,7 +3566,6 @@ static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_qf_loc_list(false, wp, &argvars[1], rettv);
}
-
/// "getmarklist()" function
static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -3737,65 +3584,8 @@ static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_buf_local_marks(buf, rettv->vval.v_list);
}
-/*
- * "getmatches()" function
- */
-static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- matchitem_T *cur;
- int i;
- win_T *win = get_optional_window(argvars, 0);
-
- if (win == NULL) {
- return;
- }
-
- tv_list_alloc_ret(rettv, kListLenMayKnow);
- cur = win->w_match_head;
- while (cur != NULL) {
- dict_T *dict = tv_dict_alloc();
- if (cur->match.regprog == NULL) {
- // match added with matchaddpos()
- for (i = 0; i < MAXPOSMATCH; i++) {
- llpos_T *llpos;
- char buf[30]; // use 30 to avoid compiler warning
-
- llpos = &cur->pos.pos[i];
- if (llpos->lnum == 0) {
- break;
- }
- list_T *const l = tv_list_alloc(1 + (llpos->col > 0 ? 2 : 0));
- tv_list_append_number(l, (varnumber_T)llpos->lnum);
- if (llpos->col > 0) {
- tv_list_append_number(l, (varnumber_T)llpos->col);
- tv_list_append_number(l, (varnumber_T)llpos->len);
- }
- int len = snprintf(buf, sizeof(buf), "pos%d", i + 1);
- assert((size_t)len < sizeof(buf));
- tv_dict_add_list(dict, buf, (size_t)len, l);
- }
- } else {
- tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cur->pattern);
- }
- tv_dict_add_str(dict, S_LEN("group"),
- (const char *)syn_id2name(cur->hlg_id));
- tv_dict_add_nr(dict, S_LEN("priority"), (varnumber_T)cur->priority);
- tv_dict_add_nr(dict, S_LEN("id"), (varnumber_T)cur->id);
-
- if (cur->conceal_char) {
- char buf[MB_MAXBYTES + 1];
-
- buf[utf_char2bytes(cur->conceal_char, (char_u *)buf)] = NUL;
- tv_dict_add_str(dict, S_LEN("conceal"), buf);
- }
-
- tv_list_append_dict(rettv->vval.v_list, dict);
- cur = cur->next;
- }
-}
-
-// "getmousepos()" function
-void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+/// "getmousepos()" function
+static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *d;
win_T *wp;
@@ -3805,7 +3595,7 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
varnumber_T winid = 0;
varnumber_T winrow = 0;
varnumber_T wincol = 0;
- linenr_T line = 0;
+ linenr_T lnum = 0;
varnumber_T column = 0;
tv_dict_alloc_ret(rettv);
@@ -3816,26 +3606,16 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
wp = mouse_find_win(&grid, &row, &col);
if (wp != NULL) {
- int height = wp->w_height + wp->w_status_height;
+ int height = wp->w_height + wp->w_hsep_height + wp->w_status_height;
// The height is adjusted by 1 when there is a bottom border. This is not
// necessary for a top border since `row` starts at -1 in that case.
if (row < height + wp->w_border_adj[2]) {
winid = wp->handle;
- winrow = row + 1 + wp->w_border_adj[0]; // Adjust by 1 for top border
- wincol = col + 1 + wp->w_border_adj[3]; // Adjust by 1 for left border
+ winrow = row + 1 + wp->w_winrow_off; // Adjust by 1 for top border
+ wincol = col + 1 + wp->w_wincol_off; // Adjust by 1 for left border
if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) {
- char_u *p;
- int count;
-
- mouse_comp_pos(wp, &row, &col, &line);
-
- // limit to text length plus one
- p = ml_get_buf(wp->w_buffer, line, false);
- count = (int)STRLEN(p);
- if (col > count) {
- col = count;
- }
-
+ (void)mouse_comp_pos(wp, &row, &col, &lnum);
+ col = vcol2col(wp, lnum, col);
column = col + 1;
}
}
@@ -3843,73 +3623,31 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(d, S_LEN("winid"), winid);
tv_dict_add_nr(d, S_LEN("winrow"), winrow);
tv_dict_add_nr(d, S_LEN("wincol"), wincol);
- tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)line);
+ tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)lnum);
tv_dict_add_nr(d, S_LEN("column"), column);
}
-/*
- * "getpid()" function
- */
+/// "getpid()" function
static void f_getpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = os_get_pid();
}
-static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos)
+/// "getcurpos(string)" function
+static void f_getcurpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T *fp;
- int fnum = -1;
-
- if (getcurpos) {
- fp = &curwin->w_cursor;
- } else {
- fp = var2fpos(&argvars[0], true, &fnum);
- }
-
- list_T *const l = tv_list_alloc_ret(rettv, 4 + (!!getcurpos));
- tv_list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
- tv_list_append_number(l, ((fp != NULL)
- ? (varnumber_T)fp->lnum
- : (varnumber_T)0));
- tv_list_append_number(l, ((fp != NULL)
- ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
- : (varnumber_T)0));
- tv_list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
- if (getcurpos) {
- const int save_set_curswant = curwin->w_set_curswant;
- const colnr_T save_curswant = curwin->w_curswant;
- const colnr_T save_virtcol = curwin->w_virtcol;
-
- update_curswant();
- tv_list_append_number(l, (curwin->w_curswant == MAXCOL
- ? (varnumber_T)MAXCOL
- : (varnumber_T)curwin->w_curswant + 1));
-
- // Do not change "curswant", as it is unexpected that a get
- // function has a side effect.
- if (save_set_curswant) {
- curwin->w_set_curswant = save_set_curswant;
- curwin->w_curswant = save_curswant;
- curwin->w_virtcol = save_virtcol;
- curwin->w_valid &= ~VALID_VIRTCOL;
- }
- }
+ getpos_both(argvars, rettv, true, false);
}
-/*
- * "getcurpos(string)" function
- */
-static void f_getcurpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static void f_getcursorcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- getpos_both(argvars, rettv, true);
+ getpos_both(argvars, rettv, true, true);
}
-/*
- * "getpos(string)" function
- */
+/// "getpos(string)" function
static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- getpos_both(argvars, rettv, false);
+ getpos_both(argvars, rettv, false, false);
}
/// "getqflist()" functions
@@ -3932,7 +3670,7 @@ static int getreg_get_regname(typval_T *argvars)
}
} else {
// Default to v:register
- strregname = get_vim_var_str(VV_REG);
+ strregname = (char_u *)get_vim_var_str(VV_REG);
}
return *strregname == 0 ? '"' : *strregname;
@@ -3991,7 +3729,7 @@ static void f_getregtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
MotionType reg_type = get_reg_type(regname, &reglen);
format_reg_type(reg_type, reglen, buf, ARRAY_SIZE(buf));
- rettv->vval.v_string = (char_u *)xstrdup(buf);
+ rettv->vval.v_string = xstrdup(buf);
}
/// "gettabinfo()" function
@@ -4026,13 +3764,9 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "gettabvar()" function
- */
+/// "gettabvar()" function
static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- win_T *oldcurwin;
- tabpage_T *oldtabpage;
bool done = false;
rettv->v_type = VAR_STRING;
@@ -4046,7 +3780,8 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
win_T *const window = tp == curtab || tp->tp_firstwin == NULL
? firstwin
: tp->tp_firstwin;
- if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
+ switchwin_T switchwin;
+ if (switch_win(&switchwin, window, tp, true) == OK) {
// look up the variable
// Let gettabvar({nr}, "") return the "t:" dictionary.
const dictitem_T *const v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
@@ -4059,7 +3794,7 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// restore previous notion of curwin
- restore_win(oldcurwin, oldtabpage, true);
+ restore_win(&switchwin, true);
}
if (!done && argvars[2].v_type != VAR_UNKNOWN) {
@@ -4067,15 +3802,13 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "gettabwinvar()" function
- */
+/// "gettabwinvar()" function
static void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getwinvar(argvars, rettv, 1);
}
-// "gettagstack()" function
+/// "gettagstack()" function
static void f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp = curwin; // default is current window
@@ -4100,7 +3833,7 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_alloc_ret(rettv, kListLenMayKnow);
if (argvars[0].v_type != VAR_UNKNOWN) {
- wparg = win_id2wp(argvars);
+ wparg = win_id2wp(tv_get_number(&argvars[0]));
if (wparg == NULL) {
return;
}
@@ -4127,12 +3860,11 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// Dummy timer callback. Used by f_wait().
+/// Dummy timer callback. Used by f_wait().
static void dummy_timer_due_cb(TimeWatcher *tw, void *data)
-{
-}
+{}
-// Dummy timer close callback. Used by f_wait().
+/// Dummy timer close callback. Used by f_wait().
static void dummy_timer_close_cb(TimeWatcher *tw, void *data)
{
xfree(tw);
@@ -4170,15 +3902,14 @@ static void f_wait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
typval_T argv = TV_INITIAL_VALUE;
typval_T exprval = TV_INITIAL_VALUE;
bool error = false;
- int save_called_emsg = called_emsg;
- called_emsg = false;
+ const int called_emsg_before = called_emsg;
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, timeout,
eval_expr_typval(&expr, &argv, 0, &exprval) != OK
|| tv_get_number_chk(&exprval, &error)
- || called_emsg || error || got_int);
+ || called_emsg > called_emsg_before || error || got_int);
- if (called_emsg || error) {
+ if (called_emsg > called_emsg_before || error) {
rettv->vval.v_number = -3;
} else if (got_int) {
got_int = false;
@@ -4188,14 +3919,12 @@ static void f_wait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 0;
}
- called_emsg = save_called_emsg;
-
// Stop dummy timer
time_watcher_stop(tw);
time_watcher_close(tw, dummy_timer_close_cb);
}
-// "win_screenpos()" function
+/// "win_screenpos()" function
static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
@@ -4204,16 +3933,14 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
}
-//
-// Move the window wp into a new split of targetwin in a given direction
-//
+/// Move the window wp into a new split of targetwin in a given direction
static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags)
{
int dir;
int height = wp->w_height;
win_T *oldwin = curwin;
- if (wp == targetwin) {
+ if (wp == targetwin || wp == aucmd_win) {
return;
}
@@ -4244,7 +3971,7 @@ static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags
}
}
-// "win_splitmove()" function
+/// "win_splitmove()" function
static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp;
@@ -4284,7 +4011,7 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
win_move_into_split(wp, targetwin, size, flags);
}
-// "getwinpos({timeout})" function
+/// "getwinpos({timeout})" function
static void f_getwinpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, 2);
@@ -4292,17 +4019,13 @@ static void f_getwinpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, -1);
}
-/*
- * "getwinposx()" function
- */
+/// "getwinposx()" function
static void f_getwinposx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
}
-/*
- * "getwinposy()" function
- */
+/// "getwinposy()" function
static void f_getwinposy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -4314,9 +4037,7 @@ static void f_getwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
getwinvar(argvars, rettv, 0);
}
-/*
- * "glob()" function
- */
+/// "glob()" function
static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int options = WILD_SILENT|WILD_USE_NL;
@@ -4347,8 +4068,9 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
options += WILD_ICASE;
}
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
- WILD_ALL);
+ rettv->vval.v_string = (char *)ExpandOne(&xpc, (char_u *)
+ tv_get_string(&argvars[0]), NULL, options,
+ WILD_ALL);
} else {
ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
WILD_ALL_KEEP);
@@ -4399,7 +4121,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags);
if (rettv->v_type == VAR_STRING) {
- rettv->vval.v_string = (char_u *)ga_concat_strings_sep(&ga, "\n");
+ rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n");
} else {
tv_list_alloc_ret(rettv, ga.ga_len);
for (int i = 0; i < ga.ga_len; i++) {
@@ -4414,16 +4136,13 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "glob2regpat()" function
+/// "glob2regpat()" function
static void f_glob2regpat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const pat = tv_get_string_chk(&argvars[0]); // NULL on type error
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = ((pat == NULL)
- ? NULL
- : file_pat_to_reg_pat((char_u *)pat, NULL, NULL,
- false));
+ rettv->vval.v_string = (pat == NULL) ? NULL : file_pat_to_reg_pat(pat, NULL, NULL, false);
}
/// "has()" function
@@ -4433,6 +4152,12 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#if defined(BSD) && !defined(__APPLE__)
"bsd",
#endif
+#ifdef __linux__
+ "linux",
+#endif
+#ifdef SUN_SYSTEM
+ "sun",
+#endif
#ifdef UNIX
"unix",
#endif
@@ -4504,6 +4229,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"mouse",
"multi_byte",
"multi_lang",
+ "nanotime",
"num64",
"packages",
"path_extra",
@@ -4555,6 +4281,8 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"userreg",
};
+ // XXX: eval_has_provider() may shell out :(
+ const int save_shell_error = get_vim_var_nr(VV_SHELL_ERROR);
bool n = false;
const char *const name = tv_get_string(&argvars[0]);
for (size_t i = 0; i < ARRAY_SIZE(has_list); i++) {
@@ -4611,6 +4339,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = true;
}
+ set_vim_var_nr(VV_SHELL_ERROR, save_shell_error);
rettv->vval.v_number = n;
}
@@ -4746,34 +4475,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "hasmapto()" function
- */
-static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *mode;
- const char *const name = tv_get_string(&argvars[0]);
- bool abbr = false;
- char buf[NUMBUFLEN];
- if (argvars[1].v_type == VAR_UNKNOWN) {
- mode = "nvo";
- } else {
- mode = tv_get_string_buf(&argvars[1], buf);
- if (argvars[2].v_type != VAR_UNKNOWN) {
- abbr = tv_get_number(&argvars[2]);
- }
- }
-
- if (map_to_exists(name, mode, abbr)) {
- rettv->vval.v_number = true;
- } else {
- rettv->vval.v_number = false;
- }
-}
-
-/*
- * "histadd()" function
- */
+/// "histadd()" function
static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType histype;
@@ -4796,9 +4498,7 @@ static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "histdel()" function
- */
+/// "histdel()" function
static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n;
@@ -4821,9 +4521,7 @@ static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "histget()" function
- */
+/// "histget()" function
static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType type;
@@ -4840,14 +4538,12 @@ static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
idx = (int)tv_get_number_chk(&argvars[1], NULL);
}
// -1 on type error
- rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
+ rettv->vval.v_string = (char *)vim_strsave(get_history_entry(type, idx));
}
rettv->v_type = VAR_STRING;
}
-/*
- * "histnr()" function
- */
+/// "histnr()" function
static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const history = tv_get_string_chk(&argvars[0]);
@@ -4860,37 +4556,29 @@ static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = i;
}
-/*
- * "highlightID(name)" function
- */
+/// "highlightID(name)" function
static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = syn_name2id(tv_get_string(&argvars[0]));
}
-/*
- * "highlight_exists()" function
- */
+/// "highlight_exists()" function
static void f_hlexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = highlight_exists(tv_get_string(&argvars[0]));
}
-/*
- * "hostname()" function
- */
+/// "hostname()" function
static void f_hostname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char hostname[256];
os_get_hostname(hostname, 256);
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave((char_u *)hostname);
+ rettv->vval.v_string = (char *)vim_strsave((char_u *)hostname);
}
-/*
- * iconv() function
- */
+/// iconv() function
static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
vimconv_T vimconv;
@@ -4908,9 +4596,9 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// If the encodings are equal, no conversion needed.
if (vimconv.vc_type == CONV_NONE) {
- rettv->vval.v_string = (char_u *)xstrdup(str);
+ rettv->vval.v_string = xstrdup(str);
} else {
- rettv->vval.v_string = string_convert(&vimconv, (char_u *)str, NULL);
+ rettv->vval.v_string = (char *)string_convert(&vimconv, (char_u *)str, NULL);
}
convert_setup(&vimconv, NULL, NULL);
@@ -4918,9 +4606,7 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(to);
}
-/*
- * "indent()" function
- */
+/// "indent()" function
static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -4931,9 +4617,7 @@ static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "index()" function
- */
+/// "index()" function
static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long idx = 0;
@@ -5007,26 +4691,20 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static bool inputsecret_flag = false;
-/*
- * "input()" function
- * Also handles inputsecret() when inputsecret is set.
- */
+/// "input()" function
+/// Also handles inputsecret() when inputsecret is set.
static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_user_input(argvars, rettv, FALSE, inputsecret_flag);
}
-/*
- * "inputdialog()" function
- */
+/// "inputdialog()" function
static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_user_input(argvars, rettv, TRUE, inputsecret_flag);
}
-/*
- * "inputlist()" function
- */
+/// "inputlist()" function
static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int selected;
@@ -5057,7 +4735,6 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = selected;
}
-
static garray_T ga_userinput = { 0, 0, sizeof(tasave_T), 4, NULL };
/// "inputrestore()" function
@@ -5092,9 +4769,7 @@ static void f_inputsecret(typval_T *argvars, typval_T *rettv, FunPtr fptr)
inputsecret_flag = false;
}
-/*
- * "insert()" function
- */
+/// "insert()" function
static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
list_T *l;
@@ -5166,43 +4841,37 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "interrupt()" function
+/// "interrupt()" function
static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED, typval_T *rettv FUNC_ATTR_UNUSED,
FunPtr fptr FUNC_ATTR_UNUSED)
{
got_int = true;
}
-/*
- * "invert(expr)" function
- */
+/// "invert(expr)" function
static void f_invert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ~tv_get_number_chk(&argvars[0], NULL);
}
-/*
- * "isdirectory()" function
- */
+/// "isdirectory()" function
static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = os_isdir((const char_u *)tv_get_string(&argvars[0]));
}
-/*
- * "islocked()" function
- */
+/// "islocked()" function
static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
lval_T lv;
dictitem_T *di;
rettv->vval.v_number = -1;
- const char_u *const end = get_lval((char_u *)tv_get_string(&argvars[0]),
- NULL,
- &lv, false, false,
- GLV_NO_AUTOLOAD|GLV_READ_ONLY,
- FNE_CHECK_START);
+ const char_u *const end = (char_u *)get_lval((char *)tv_get_string(&argvars[0]),
+ NULL,
+ &lv, false, false,
+ GLV_NO_AUTOLOAD|GLV_READ_ONLY,
+ FNE_CHECK_START);
if (end != NULL && lv.ll_name != NULL) {
if (*end != NUL) {
emsg(_(e_trailing));
@@ -5234,7 +4903,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
clear_lval(&lv);
}
-// "isinf()" function
+/// "isinf()" function
static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type == VAR_FLOAT
@@ -5243,7 +4912,7 @@ static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "isnan()" function
+/// "isnan()" function
static void f_isnan(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
@@ -5257,19 +4926,16 @@ static void f_id(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const int len = vim_vsnprintf_typval(NULL, 0, "%p", dummy_ap, argvars);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = xmalloc(len + 1);
- vim_vsnprintf_typval((char *)rettv->vval.v_string, len + 1, "%p",
- dummy_ap, argvars);
+ vim_vsnprintf_typval(rettv->vval.v_string, len + 1, "%p", dummy_ap, argvars);
}
-/*
- * "items(dict)" function
- */
+/// "items(dict)" function
static void f_items(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 2);
}
-// "jobpid(id)" function
+/// "jobpid(id)" function
static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5293,7 +4959,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = proc->pid;
}
-// "jobresize(job, width, height)" function
+/// "jobresize(job, width, height)" function
static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5310,7 +4976,6 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-
Channel *data = find_job(argvars[0].vval.v_number, true);
if (!data) {
return;
@@ -5402,6 +5067,16 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
tv_dict_add_str(env, S_LEN("TERM"), pty_term_name);
}
+ // Set $NVIM (in the child process) to v:servername. #3118
+ char *nvim_addr = get_vim_var_str(VV_SEND_SERVER);
+ if (nvim_addr[0] != '\0') {
+ dictitem_T *dv = tv_dict_find(env, S_LEN("NVIM"));
+ if (dv) {
+ tv_dict_item_remove(env, dv);
+ }
+ tv_dict_add_str(env, S_LEN("NVIM"), nvim_addr);
+ }
+
if (job_env) {
#ifdef WIN32
TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, {
@@ -5440,7 +5115,7 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
return env;
}
-// "jobstart()" function
+/// "jobstart()" function
static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5465,7 +5140,6 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-
dict_T *job_opts = NULL;
bool detach = false;
bool rpc = false;
@@ -5561,7 +5235,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "jobstop()" function
+/// "jobstop()" function
static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5594,7 +5268,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "jobwait(ids[, timeout])" function
+/// "jobwait(ids[, timeout])" function
static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -5693,9 +5367,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_list = rv;
}
-/*
- * "join()" function
- */
+/// "join()" function
static void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type != VAR_LIST) {
@@ -5713,7 +5385,7 @@ static void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ga_init(&ga, (int)sizeof(char), 80);
tv_list_join(&ga, argvars[0].vval.v_list, sep);
ga_append(&ga, NUL);
- rettv->vval.v_string = (char_u *)ga.ga_data;
+ rettv->vval.v_string = ga.ga_data;
} else {
rettv->vval.v_string = NULL;
}
@@ -5757,20 +5429,16 @@ static void f_json_decode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_json_encode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)encode_tv2json(&argvars[0], NULL);
+ rettv->vval.v_string = encode_tv2json(&argvars[0], NULL);
}
-/*
- * "keys()" function
- */
+/// "keys()" function
static void f_keys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 0);
}
-/*
- * "last_buffer_nr()" function.
- */
+/// "last_buffer_nr()" function.
static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = 0;
@@ -5784,9 +5452,7 @@ static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "len()" function
- */
+/// "len()" function
static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
switch (argvars[0].v_type) {
@@ -5830,19 +5496,17 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
return;
}
- const char *libname = (char *)argvars[0].vval.v_string;
- const char *funcname = (char *)argvars[1].vval.v_string;
+ const char *libname = argvars[0].vval.v_string;
+ const char *funcname = argvars[1].vval.v_string;
VarType in_type = argvars[2].v_type;
// input variables
- char *str_in = (in_type == VAR_STRING)
- ? (char *)argvars[2].vval.v_string : NULL;
+ char *str_in = (in_type == VAR_STRING) ? argvars[2].vval.v_string : NULL;
int int_in = argvars[2].vval.v_number;
// output variables
- char **str_out = (out_type == VAR_STRING)
- ? (char **)&rettv->vval.v_string : NULL;
+ char **str_out = (out_type == VAR_STRING) ? &rettv->vval.v_string : NULL;
int int_out = 0;
bool success = os_libcall(libname, funcname,
@@ -5859,23 +5523,19 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
}
}
-/*
- * "libcall()" function
- */
+/// "libcall()" function
static void f_libcall(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
libcall_common(argvars, rettv, VAR_STRING);
}
-/*
- * "libcallnr()" function
- */
+/// "libcallnr()" function
static void f_libcallnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
libcall_common(argvars, rettv, VAR_NUMBER);
}
-// "line(string, [winid])" function
+/// "line(string, [winid])" function
static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = 0;
@@ -5883,23 +5543,21 @@ static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int fnum;
if (argvars[1].v_type != VAR_UNKNOWN) {
- tabpage_T *tp;
- win_T *save_curwin;
- tabpage_T *save_curtab;
-
// use window specified in the second argument
- win_T *wp = win_id2wp_tp(&argvars[1], &tp);
+ int id = (int)tv_get_number(&argvars[1]);
+ tabpage_T *tp;
+ win_T *wp = win_id2wp_tp(id, &tp);
if (wp != NULL && tp != NULL) {
- if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, true)
- == OK) {
+ switchwin_T switchwin;
+ if (switch_win_noblock(&switchwin, wp, tp, true) == OK) {
check_cursor();
- fp = var2fpos(&argvars[0], true, &fnum);
+ fp = var2fpos(&argvars[0], true, &fnum, false);
}
- restore_win_noblock(save_curwin, save_curtab, true);
+ restore_win_noblock(&switchwin, true);
}
} else {
// use current window
- fp = var2fpos(&argvars[0], true, &fnum);
+ fp = var2fpos(&argvars[0], true, &fnum, false);
}
if (fp != NULL) {
@@ -5908,9 +5566,7 @@ static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = lnum;
}
-/*
- * "line2byte(lnum)" function
- */
+/// "line2byte(lnum)" function
static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
@@ -5924,9 +5580,7 @@ static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "lispindent(lnum)" function
- */
+/// "lispindent(lnum)" function
static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const pos_T pos = curwin->w_cursor;
@@ -5940,7 +5594,7 @@ static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "list2str()" function
+/// "list2str()" function
static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
garray_T ga;
@@ -5958,10 +5612,10 @@ static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
ga_init(&ga, 1, 80);
- char_u buf[MB_MAXBYTES + 1];
+ char buf[MB_MAXBYTES + 1];
TV_LIST_ITER_CONST(l, li, {
- buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), buf)] = NUL;
+ buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), (char *)buf)] = NUL;
ga_concat(&ga, (char *)buf);
});
ga_append(&ga, NUL);
@@ -5969,82 +5623,12 @@ static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = ga.ga_data;
}
-/*
- * "localtime()" function
- */
+/// "localtime()" function
static void f_localtime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (varnumber_T)time(NULL);
}
-
-static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
-{
- char_u *keys_buf = NULL;
- char_u *rhs;
- LuaRef rhs_lua;
- int mode;
- int abbr = FALSE;
- int get_dict = FALSE;
- mapblock_T *mp;
- int buffer_local;
-
- // Return empty string for failure.
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = NULL;
-
- char_u *keys = (char_u *)tv_get_string(&argvars[0]);
- if (*keys == NUL) {
- return;
- }
-
- char buf[NUMBUFLEN];
- const char *which;
- if (argvars[1].v_type != VAR_UNKNOWN) {
- which = tv_get_string_buf_chk(&argvars[1], buf);
- if (argvars[2].v_type != VAR_UNKNOWN) {
- abbr = tv_get_number(&argvars[2]);
- if (argvars[3].v_type != VAR_UNKNOWN) {
- get_dict = tv_get_number(&argvars[3]);
- }
- }
- } else {
- which = "";
- }
- if (which == NULL) {
- return;
- }
-
- mode = get_map_mode((char_u **)&which, 0);
-
- keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
- CPO_TO_CPO_FLAGS);
- rhs = check_map(keys, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua);
- xfree(keys_buf);
-
- if (!get_dict) {
- // Return a string.
- if (rhs != NULL) {
- if (*rhs == NUL) {
- rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
- } else {
- rettv->vval.v_string = (char_u *)str2special_save((char *)rhs, false, false);
- }
- } else if (rhs_lua != LUA_NOREF) {
- size_t msglen = 100;
- char *msg = (char *)xmalloc(msglen);
- snprintf(msg, msglen, "<Lua function %d>", mp->m_luaref);
- rettv->vval.v_string = (char_u *)msg;
- }
- } else {
- tv_dict_alloc_ret(rettv);
- if (mp != NULL && (rhs != NULL || rhs_lua != LUA_NOREF)) {
- // Return a dictionary.
- mapblock_fill_dict(rettv->vval.v_dict, mp, buffer_local, true);
- }
- }
-}
-
/// luaeval() function implementation
static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
@@ -6057,31 +5641,12 @@ static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
nlua_typval_eval(cstr_as_string((char *)str), &argvars[1], rettv);
}
-/*
- * "map()" function
- */
+/// "map()" function
static void f_map(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
filter_map(argvars, rettv, TRUE);
}
-/*
- * "maparg()" function
- */
-static void f_maparg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- get_maparg(argvars, rettv, TRUE);
-}
-
-/*
- * "mapcheck()" function
- */
-static void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- get_maparg(argvars, rettv, FALSE);
-}
-
-
static void find_some_match(typval_T *const argvars, typval_T *const rettv,
const SomeMatchType type)
{
@@ -6089,7 +5654,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
long len = 0;
char_u *expr = NULL;
regmatch_T regmatch;
- char_u *save_cpo;
+ char *save_cpo;
long start = 0;
long nth = 1;
colnr_T startcol = 0;
@@ -6101,7 +5666,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
// Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
- p_cpo = (char_u *)"";
+ p_cpo = "";
rettv->vval.v_number = -1;
switch (type) {
@@ -6182,7 +5747,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
}
}
- regmatch.regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING);
+ regmatch.regprog = vim_regcomp((char *)pat, RE_MAGIC + RE_STRING);
if (regmatch.regprog != NULL) {
regmatch.rm_ic = p_ic;
@@ -6215,7 +5780,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
idx++;
} else {
startcol = (colnr_T)(regmatch.startp[0]
- + utfc_ptr2len(regmatch.startp[0]) - str);
+ + utfc_ptr2len((char *)regmatch.startp[0]) - str);
if (startcol > (colnr_T)len || str + startcol <= regmatch.startp[0]) {
match = false;
break;
@@ -6261,9 +5826,9 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
if (l != NULL) {
tv_copy(TV_LIST_ITEM_TV(li), rettv);
} else {
- rettv->vval.v_string = (char_u *)xmemdupz((const char *)regmatch.startp[0],
- (size_t)(regmatch.endp[0] -
- regmatch.startp[0]));
+ rettv->vval.v_string = xmemdupz((const char *)regmatch.startp[0],
+ (size_t)(regmatch.endp[0] -
+ regmatch.startp[0]));
}
break;
case kSomeMatch:
@@ -6297,166 +5862,25 @@ theend:
p_cpo = save_cpo;
}
-/*
- * "match()" function
- */
+/// "match()" function
static void f_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatch);
}
-/*
- * "matchadd()" function
- */
-static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- char grpbuf[NUMBUFLEN];
- char patbuf[NUMBUFLEN];
- // group
- const char *const grp = tv_get_string_buf_chk(&argvars[0], grpbuf);
- // pattern
- const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
- // default priority
- int prio = 10;
- int id = -1;
- bool error = false;
- const char *conceal_char = NULL;
- win_T *win = curwin;
-
- rettv->vval.v_number = -1;
-
- if (grp == NULL || pat == NULL) {
- return;
- }
- if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = tv_get_number_chk(&argvars[2], &error);
- if (argvars[3].v_type != VAR_UNKNOWN) {
- id = tv_get_number_chk(&argvars[3], &error);
- if (argvars[4].v_type != VAR_UNKNOWN
- && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL) {
- return;
- }
- }
- }
- if (error) {
- return;
- }
- if (id >= 1 && id <= 3) {
- semsg(_("E798: ID is reserved for \":match\": %" PRId64), (int64_t)id);
- return;
- }
-
- rettv->vval.v_number = match_add(win, grp, pat, prio, id, NULL, conceal_char);
-}
-
-static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- rettv->vval.v_number = -1;
-
- char buf[NUMBUFLEN];
- const char *const group = tv_get_string_buf_chk(&argvars[0], buf);
- if (group == NULL) {
- return;
- }
-
- if (argvars[1].v_type != VAR_LIST) {
- semsg(_(e_listarg), "matchaddpos()");
- return;
- }
-
- list_T *l;
- l = argvars[1].vval.v_list;
- if (l == NULL) {
- return;
- }
-
- bool error = false;
- int prio = 10;
- int id = -1;
- const char *conceal_char = NULL;
- win_T *win = curwin;
-
- if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = tv_get_number_chk(&argvars[2], &error);
- if (argvars[3].v_type != VAR_UNKNOWN) {
- id = tv_get_number_chk(&argvars[3], &error);
- if (argvars[4].v_type != VAR_UNKNOWN
- && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL) {
- return;
- }
- }
- }
- if (error == true) {
- return;
- }
-
- // id == 3 is ok because matchaddpos() is supposed to substitute :3match
- if (id == 1 || id == 2) {
- semsg(_("E798: ID is reserved for \"match\": %" PRId64), (int64_t)id);
- return;
- }
-
- rettv->vval.v_number = match_add(win, group, NULL, prio, id, l, conceal_char);
-}
-
-/*
- * "matcharg()" function
- */
-static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const int id = tv_get_number(&argvars[0]);
-
- tv_list_alloc_ret(rettv, (id >= 1 && id <= 3
- ? 2
- : 0));
-
- if (id >= 1 && id <= 3) {
- matchitem_T *const m = get_match(curwin, id);
-
- if (m != NULL) {
- tv_list_append_string(rettv->vval.v_list,
- (const char *)syn_id2name(m->hlg_id), -1);
- tv_list_append_string(rettv->vval.v_list, (const char *)m->pattern, -1);
- } else {
- tv_list_append_string(rettv->vval.v_list, NULL, 0);
- tv_list_append_string(rettv->vval.v_list, NULL, 0);
- }
- }
-}
-
-/*
- * "matchdelete()" function
- */
-static void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- win_T *win = get_optional_window(argvars, 1);
- if (win == NULL) {
- rettv->vval.v_number = -1;
- } else {
- rettv->vval.v_number = match_delete(win,
- (int)tv_get_number(&argvars[0]), true);
- }
-}
-
-/*
- * "matchend()" function
- */
+/// "matchend()" function
static void f_matchend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatchEnd);
}
-/*
- * "matchlist()" function
- */
+/// "matchlist()" function
static void f_matchlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatchList);
}
-/*
- * "matchstr()" function
- */
+/// "matchstr()" function
static void f_matchstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
find_some_match(argvars, rettv, kSomeMatchStr);
@@ -6517,25 +5941,19 @@ static void max_min(const typval_T *const tv, typval_T *const rettv, const bool
rettv->vval.v_number = n;
}
-/*
- * "max()" function
- */
+/// "max()" function
static void f_max(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
max_min(argvars, rettv, TRUE);
}
-/*
- * "min()" function
- */
+/// "min()" function
static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
max_min(argvars, rettv, FALSE);
}
-/*
- * "mkdir()" function
- */
+/// "mkdir()" function
static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int prot = 0755; // -V536
@@ -6551,9 +5969,9 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- if (*path_tail((char_u *)dir) == NUL) {
+ if (*path_tail(dir) == NUL) {
// Remove trailing slashes.
- *path_tail_with_sep((char_u *)dir) = NUL;
+ *path_tail_with_sep((char *)dir) = NUL;
}
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -6583,15 +6001,17 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "mode()" function
static void f_mode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char *mode = get_mode();
+ char buf[MODE_MAX_LENGTH];
+
+ get_mode(buf);
// Clear out the minor mode when the argument is not a non-zero number or
// non-empty string.
if (!non_zero_arg(&argvars[0])) {
- mode[1] = NUL;
+ buf[1] = NUL;
}
- rettv->vval.v_string = (char_u *)mode;
+ rettv->vval.v_string = xstrdup(buf);
rettv->v_type = VAR_STRING;
}
@@ -6750,9 +6170,7 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "nextnonblank()" function
- */
+/// "nextnonblank()" function
static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum;
@@ -6762,16 +6180,14 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
lnum = 0;
break;
}
- if (*skipwhite(ml_get(lnum)) != NUL) {
+ if (*skipwhite((char *)ml_get(lnum)) != NUL) {
break;
}
}
rettv->vval.v_number = lnum;
}
-/*
- * "nr2char()" function
- */
+/// "nr2char()" function
static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -6796,37 +6212,42 @@ static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
char buf[MB_MAXBYTES];
- const int len = utf_char2bytes((int)num, (char_u *)buf);
+ const int len = utf_char2bytes((int)num, buf);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = xmemdupz(buf, (size_t)len);
}
-/*
- * "or(expr, expr)" function
- */
+/// "or(expr, expr)" function
static void f_or(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
| tv_get_number_chk(&argvars[1], NULL);
}
-/*
- * "pathshorten()" function
- */
+/// "pathshorten()" function
static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
+ int trim_len = 1;
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ trim_len = (int)tv_get_number(&argvars[1]);
+ if (trim_len < 1) {
+ trim_len = 1;
+ }
+ }
+
rettv->v_type = VAR_STRING;
- const char *const s = tv_get_string_chk(&argvars[0]);
- if (!s) {
- return;
+ const char_u *p = (char_u *)tv_get_string_chk(&argvars[0]);
+ if (p == NULL) {
+ rettv->vval.v_string = NULL;
+ } else {
+ rettv->vval.v_string = (char *)vim_strsave(p);
+ shorten_dir_len((char_u *)rettv->vval.v_string, trim_len);
}
- rettv->vval.v_string = shorten_dir((char_u *)xstrdup(s));
}
-/*
- * "pow()" function
- */
+/// "pow()" function
static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T fx;
@@ -6840,25 +6261,21 @@ static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "prevnonblank()" function
- */
+/// "prevnonblank()" function
static void f_prevnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = tv_get_lnum(argvars);
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
lnum = 0;
} else {
- while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) {
+ while (lnum >= 1 && *skipwhite((char *)ml_get(lnum)) == NUL) {
lnum--;
}
}
rettv->vval.v_number = lnum;
}
-/*
- * "printf()" function
- */
+/// "printf()" function
static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -6874,14 +6291,14 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
len = vim_vsnprintf_typval(NULL, 0, fmt, dummy_ap, argvars + 1);
if (!did_emsg) {
char *s = xmalloc(len + 1);
- rettv->vval.v_string = (char_u *)s;
+ rettv->vval.v_string = s;
(void)vim_vsnprintf_typval(s, len + 1, fmt, dummy_ap, argvars + 1);
}
did_emsg |= saved_did_emsg;
}
}
-// "prompt_setcallback({buffer}, {callback})" function
+/// "prompt_setcallback({buffer}, {callback})" function
static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -6905,7 +6322,7 @@ static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv, FunPtr fptr
buf->b_prompt_callback = prompt_callback;
}
-// "prompt_setinterrupt({buffer}, {callback})" function
+/// "prompt_setinterrupt({buffer}, {callback})" function
static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -6930,7 +6347,7 @@ static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv, FunPtr fpt
}
/// "prompt_getprompt({buffer})" function
-void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
// return an empty string by default, e.g. it's not a prompt buffer
@@ -6946,38 +6363,33 @@ void f_prompt_getprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- rettv->vval.v_string = vim_strsave(buf_prompt_text(buf));
+ rettv->vval.v_string = (char *)vim_strsave(buf_prompt_text(buf));
}
-// "prompt_setprompt({buffer}, {text})" function
+/// "prompt_setprompt({buffer}, {text})" function
static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- const char_u *text;
-
if (check_secure()) {
return;
}
- buf = tv_get_buf(&argvars[0], false);
+ buf_T *buf = tv_get_buf(&argvars[0], false);
if (buf == NULL) {
return;
}
- text = (const char_u *)tv_get_string(&argvars[1]);
+ const char *text = tv_get_string(&argvars[1]);
xfree(buf->b_prompt_text);
- buf->b_prompt_text = vim_strsave(text);
+ buf->b_prompt_text = xstrdup(text);
}
-// "pum_getpos()" function
+/// "pum_getpos()" function
static void f_pum_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
pum_set_event_info(rettv->vval.v_dict);
}
-/*
- * "pumvisible()" function
- */
+/// "pumvisible()" function
static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (pum_visible()) {
@@ -6985,50 +6397,183 @@ static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "pyeval()" function
- */
-static void f_pyeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+/// "py3eval()" and "pyxeval()" functions (always python3)
+static void f_py3eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- script_host_eval("python", argvars, rettv);
+ script_host_eval("python3", argvars, rettv);
}
-/*
- * "py3eval()" function
- */
-static void f_py3eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static void init_srand(uint32_t *const x)
+ FUNC_ATTR_NONNULL_ALL
{
- script_host_eval("python3", argvars, rettv);
+#ifndef MSWIN
+ static int dev_urandom_state = NOTDONE; // FAIL or OK once tried
+
+ if (dev_urandom_state != FAIL) {
+ const int fd = os_open("/dev/urandom", O_RDONLY, 0);
+ struct {
+ union {
+ uint32_t number;
+ char bytes[sizeof(uint32_t)];
+ } contents;
+ } buf;
+
+ // Attempt reading /dev/urandom.
+ if (fd == -1) {
+ dev_urandom_state = FAIL;
+ } else {
+ buf.contents.number = 0;
+ if (read(fd, buf.contents.bytes, sizeof(uint32_t)) != sizeof(uint32_t)) {
+ dev_urandom_state = FAIL;
+ } else {
+ dev_urandom_state = OK;
+ *x = buf.contents.number;
+ }
+ os_close(fd);
+ }
+ }
+ if (dev_urandom_state != OK) {
+ // Reading /dev/urandom doesn't work, fall back to time().
+#endif
+ // uncrustify:off
+ *x = time(NULL);
+#ifndef MSWIN
+ }
+#endif
+ // uncrustify:on
}
-// "pyxeval()" function
-static void f_pyxeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static inline uint32_t splitmix32(uint32_t *const x)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
- init_pyxversion();
- if (p_pyx == 2) {
- f_pyeval(argvars, rettv, NULL);
+ uint32_t z = (*x += 0x9e3779b9);
+ z = (z ^ (z >> 16)) * 0x85ebca6b;
+ z = (z ^ (z >> 13)) * 0xc2b2ae35;
+ return z ^ (z >> 16);
+}
+
+static inline uint32_t shuffle_xoshiro128starstar(uint32_t *const x, uint32_t *const y,
+ uint32_t *const z, uint32_t *const w)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
+{
+#define ROTL(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+ const uint32_t result = ROTL(*y * 5, 7) * 9;
+ const uint32_t t = *y << 9;
+ *z ^= *x;
+ *w ^= *y;
+ *y ^= *z;
+ *x ^= *w;
+ *z ^= t;
+ *w = ROTL(*w, 11);
+#undef ROTL
+ return result;
+}
+
+/// "rand()" function
+static void f_rand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ uint32_t result;
+
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ static uint32_t gx, gy, gz, gw;
+ static bool initialized = false;
+
+ // When no argument is given use the global seed list.
+ if (!initialized) {
+ // Initialize the global seed list.
+ uint32_t x;
+ init_srand(&x);
+
+ gx = splitmix32(&x);
+ gy = splitmix32(&x);
+ gz = splitmix32(&x);
+ gw = splitmix32(&x);
+ initialized = true;
+ }
+
+ result = shuffle_xoshiro128starstar(&gx, &gy, &gz, &gw);
+ } else if (argvars[0].v_type == VAR_LIST) {
+ list_T *const l = argvars[0].vval.v_list;
+ if (tv_list_len(l) != 4) {
+ goto theend;
+ }
+
+ typval_T *const tvx = TV_LIST_ITEM_TV(tv_list_find(l, 0L));
+ typval_T *const tvy = TV_LIST_ITEM_TV(tv_list_find(l, 1L));
+ typval_T *const tvz = TV_LIST_ITEM_TV(tv_list_find(l, 2L));
+ typval_T *const tvw = TV_LIST_ITEM_TV(tv_list_find(l, 3L));
+ if (tvx->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ if (tvy->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ if (tvz->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ if (tvw->v_type != VAR_NUMBER) {
+ goto theend;
+ }
+ uint32_t x = tvx->vval.v_number;
+ uint32_t y = tvy->vval.v_number;
+ uint32_t z = tvz->vval.v_number;
+ uint32_t w = tvw->vval.v_number;
+
+ result = shuffle_xoshiro128starstar(&x, &y, &z, &w);
+
+ tvx->vval.v_number = (varnumber_T)x;
+ tvy->vval.v_number = (varnumber_T)y;
+ tvz->vval.v_number = (varnumber_T)z;
+ tvw->vval.v_number = (varnumber_T)w;
} else {
- f_py3eval(argvars, rettv, NULL);
+ goto theend;
}
+
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = (varnumber_T)result;
+ return;
+
+theend:
+ semsg(_(e_invarg2), tv_get_string(&argvars[0]));
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = -1;
+}
+
+/// "srand()" function
+static void f_srand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ uint32_t x = 0;
+
+ tv_list_alloc_ret(rettv, 4);
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ init_srand(&x);
+ } else {
+ bool error = false;
+ x = tv_get_number_chk(&argvars[0], &error);
+ if (error) {
+ return;
+ }
+ }
+
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)splitmix32(&x));
}
-///
/// "perleval()" function
-///
static void f_perleval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
script_host_eval("perl", argvars, rettv);
}
-// "rubyeval()" function
+/// "rubyeval()" function
static void f_rubyeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
script_host_eval("ruby", argvars, rettv);
}
-/*
- * "range()" function
- */
+/// "range()" function
static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
varnumber_T start;
@@ -7063,19 +6608,25 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// Evaluate "expr" for readdir().
-static varnumber_T readdir_checkitem(typval_T *expr, const char *name)
+/// Evaluate "expr" (= "context") for readdir().
+static varnumber_T readdir_checkitem(void *context, const char *name)
+ FUNC_ATTR_NONNULL_ALL
{
+ typval_T *expr = (typval_T *)context;
typval_T save_val;
typval_T rettv;
typval_T argv[2];
varnumber_T retval = 0;
bool error = false;
+ if (expr->v_type == VAR_UNKNOWN) {
+ return 1;
+ }
+
prepare_vimvar(VV_VAL, &save_val);
set_vim_var_string(VV_VAL, name, -1);
argv[0].v_type = VAR_STRING;
- argv[0].vval.v_string = (char_u *)name;
+ argv[0].vval.v_string = (char *)name;
if (eval_expr_typval(expr, argv, 1, &rettv) == FAIL) {
goto theend;
@@ -7094,65 +6645,25 @@ theend:
return retval;
}
-// "readdir()" function
+/// "readdir()" function
static void f_readdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- typval_T *expr;
- const char *path;
- garray_T ga;
- Directory dir;
-
tv_list_alloc_ret(rettv, kListLenUnknown);
- path = tv_get_string(&argvars[0]);
- expr = &argvars[1];
- ga_init(&ga, (int)sizeof(char *), 20);
- if (!os_scandir(&dir, path)) {
- smsg(_(e_notopen), path);
- } else {
- for (;;) {
- bool ignore;
-
- path = os_scandir_next(&dir);
- if (path == NULL) {
- break;
- }
-
- ignore = (path[0] == '.'
- && (path[1] == NUL || (path[1] == '.' && path[2] == NUL)));
- if (!ignore && expr->v_type != VAR_UNKNOWN) {
- varnumber_T r = readdir_checkitem(expr, path);
-
- if (r < 0) {
- break;
- }
- if (r == 0) {
- ignore = true;
- }
- }
-
- if (!ignore) {
- ga_grow(&ga, 1);
- ((char **)ga.ga_data)[ga.ga_len++] = xstrdup(path);
- }
- }
-
- os_closedir(&dir);
- }
-
- if (rettv->vval.v_list != NULL && ga.ga_len > 0) {
- sort_strings((char_u **)ga.ga_data, ga.ga_len);
+ const char *path = tv_get_string(&argvars[0]);
+ typval_T *expr = &argvars[1];
+ garray_T ga;
+ int ret = readdir_core(&ga, path, (void *)expr, readdir_checkitem);
+ if (ret == OK && ga.ga_len > 0) {
for (int i = 0; i < ga.ga_len; i++) {
- path = ((const char **)ga.ga_data)[i];
- tv_list_append_string(rettv->vval.v_list, path, -1);
+ const char *p = ((const char **)ga.ga_data)[i];
+ tv_list_append_string(rettv->vval.v_list, p, -1);
}
}
ga_clear_strings(&ga);
}
-/*
- * "readfile()" function
- */
+/// "readfile()" function
static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool binary = false;
@@ -7250,7 +6761,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_owned_tv(l, (typval_T) {
.v_type = VAR_STRING,
.v_lock = VAR_UNLOCKED,
- .vval.v_string = s,
+ .vval.v_string = (char *)s,
});
start = p + 1; // Step over newline.
@@ -7386,13 +6897,13 @@ static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "reg_executing()" function
+/// "reg_executing()" function
static void f_reg_executing(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
return_register(reg_executing, rettv);
}
-// "reg_recording()" function
+/// "reg_recording()" function
static void f_reg_recording(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
return_register(reg_recording, rettv);
@@ -7490,13 +7001,11 @@ static void f_reltimestr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (list2proftime(&argvars[0], &tm) == OK) {
- rettv->vval.v_string = (char_u *)xstrdup(profile_msg(tm));
+ rettv->vval.v_string = xstrdup(profile_msg(tm));
}
}
-/*
- * "remove()" function
- */
+/// "remove()" function
static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
list_T *l;
@@ -7630,9 +7139,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "rename({from}, {to})" function
- */
+/// "rename({from}, {to})" function
static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -7644,9 +7151,7 @@ static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "repeat()" function
- */
+/// "repeat()" function
static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
varnumber_T n = tv_get_number(&argvars[1]);
@@ -7679,13 +7184,11 @@ static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
memmove(r + i * slen, p, slen);
}
- rettv->vval.v_string = (char_u *)r;
+ rettv->vval.v_string = r;
}
}
-/*
- * "resolve()" function
- */
+/// "resolve()" function
static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -7765,11 +7268,11 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
q[-1] = NUL;
}
- q = (char *)path_tail((char_u *)p);
+ q = path_tail(p);
if (q > p && *q == NUL) {
// Ignore trailing path separator.
q[-1] = NUL;
- q = (char *)path_tail((char_u *)p);
+ q = path_tail(p);
}
if (q > p && !path_is_absolute((const char_u *)buf)) {
// Symlink is relative to directory of argument. Replace the
@@ -7777,7 +7280,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const size_t p_len = strlen(p);
const size_t buf_len = strlen(buf);
p = xrealloc(p, p_len + buf_len + 1);
- memcpy(path_tail((char_u *)p), buf, buf_len + 1);
+ memcpy(path_tail(p), buf, buf_len + 1);
} else {
xfree(p);
p = xstrdup(buf);
@@ -7838,11 +7341,11 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!has_trailing_pathsep) {
q = p + strlen(p);
if (after_pathsep(p, q)) {
- *path_tail_with_sep((char_u *)p) = NUL;
+ *path_tail_with_sep(p) = NUL;
}
}
- rettv->vval.v_string = (char_u *)p;
+ rettv->vval.v_string = p;
xfree(buf);
}
# else
@@ -7851,12 +7354,10 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
# endif
#endif
- simplify_filename(rettv->vval.v_string);
+ simplify_filename((char_u *)rettv->vval.v_string);
}
-/*
- * "reverse({list})" function
- */
+/// "reverse({list})" function
static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type == VAR_BLOB) {
@@ -7881,6 +7382,102 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+/// "reduce(list, { accumulator, element -> value } [, initial])" function
+static void f_reduce(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) {
+ emsg(_(e_listblobreq));
+ return;
+ }
+
+ const char *func_name;
+ partial_T *partial = NULL;
+ if (argvars[1].v_type == VAR_FUNC) {
+ func_name = argvars[1].vval.v_string;
+ } else if (argvars[1].v_type == VAR_PARTIAL) {
+ partial = argvars[1].vval.v_partial;
+ func_name = partial_name(partial);
+ } else {
+ func_name = tv_get_string(&argvars[1]);
+ }
+ if (*func_name == NUL) {
+ return; // type error or empty name
+ }
+
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.evaluate = true;
+ funcexe.partial = partial;
+
+ typval_T initial;
+ typval_T argv[3];
+ if (argvars[0].v_type == VAR_LIST) {
+ list_T *const l = argvars[0].vval.v_list;
+ const listitem_T *li;
+
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ if (tv_list_len(l) == 0) {
+ semsg(_(e_reduceempty), "List");
+ return;
+ }
+ const listitem_T *const first = tv_list_first(l);
+ initial = *TV_LIST_ITEM_TV(first);
+ li = TV_LIST_ITEM_NEXT(l, first);
+ } else {
+ initial = argvars[2];
+ li = tv_list_first(l);
+ }
+
+ tv_copy(&initial, rettv);
+
+ if (l != NULL) {
+ const VarLockStatus prev_locked = tv_list_locked(l);
+ const int called_emsg_start = called_emsg;
+
+ tv_list_set_lock(l, VAR_FIXED); // disallow the list changing here
+ for (; li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) {
+ argv[0] = *rettv;
+ argv[1] = *TV_LIST_ITEM_TV(li);
+ rettv->v_type = VAR_UNKNOWN;
+ const int r = call_func((char *)func_name, -1, rettv, 2, argv, &funcexe);
+ tv_clear(&argv[0]);
+ if (r == FAIL || called_emsg != called_emsg_start) {
+ break;
+ }
+ }
+ tv_list_set_lock(l, prev_locked);
+ }
+ } else {
+ const blob_T *const b = argvars[0].vval.v_blob;
+ int i;
+
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ if (tv_blob_len(b) == 0) {
+ semsg(_(e_reduceempty), "Blob");
+ return;
+ }
+ initial.v_type = VAR_NUMBER;
+ initial.vval.v_number = tv_blob_get(b, 0);
+ i = 1;
+ } else if (argvars[2].v_type != VAR_NUMBER) {
+ emsg(_(e_number_exp));
+ return;
+ } else {
+ initial = argvars[2];
+ i = 0;
+ }
+
+ tv_copy(&initial, rettv);
+ for (; i < tv_blob_len(b); i++) {
+ argv[0] = *rettv;
+ argv[1].v_type = VAR_NUMBER;
+ argv[1].vval.v_number = tv_blob_get(b, i);
+ if (call_func((char *)func_name, -1, rettv, 2, argv, &funcexe) == FAIL) {
+ return;
+ }
+ }
+ }
+}
+
#define SP_NOMOVE 0x01 ///< don't move cursor
#define SP_REPEAT 0x02 ///< repeat to find outer pair
#define SP_RETCOUNT 0x04 ///< return matchcount
@@ -7890,11 +7487,10 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#define SP_END 0x40 ///< leave cursor at end of match
#define SP_COLUMN 0x80 ///< start at cursor column
-/*
- * Get flags for a search function.
- * Possibly sets "p_ws".
- * Returns BACKWARD, FORWARD or zero (for an error).
- */
+/// Get flags for a search function.
+/// Possibly sets "p_ws".
+///
+/// @return BACKWARD, FORWARD or zero (for an error).
static int get_search_arg(typval_T *varp, int *flagsp)
{
int dir = FORWARD;
@@ -7952,7 +7548,7 @@ static int get_search_arg(typval_T *varp, int *flagsp)
return dir;
}
-// Shared by search() and searchpos() functions.
+/// Shared by search() and searchpos() functions.
static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
{
int flags;
@@ -7967,6 +7563,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
int options = SEARCH_KEEP;
int subpatnum;
searchit_arg_T sia;
+ bool use_skip = false;
const char *const pat = tv_get_string(&argvars[0]);
dir = get_search_arg(&argvars[1], flagsp); // May set p_ws.
@@ -7984,7 +7581,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
options |= SEARCH_COL;
}
- // Optional arguments: line number to stop searching and timeout.
+ // Optional arguments: line number to stop searching, timeout and skip.
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[2], NULL);
if (lnum_stop < 0) {
@@ -7995,6 +7592,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
if (time_limit < 0) {
goto theend;
}
+ use_skip = eval_expr_valid_arg(&argvars[4]);
}
}
@@ -8014,11 +7612,49 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
}
pos = save_cursor = curwin->w_cursor;
+ pos_T firstpos = { 0 };
memset(&sia, 0, sizeof(sia));
sia.sa_stop_lnum = (linenr_T)lnum_stop;
sia.sa_tm = &tm;
- subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1,
- options, RE_SEARCH, &sia);
+
+ // Repeat until {skip} returns false.
+ for (;;) {
+ subpatnum
+ = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1, options, RE_SEARCH, &sia);
+ // finding the first match again means there is no match where {skip}
+ // evaluates to zero.
+ if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
+ subpatnum = FAIL;
+ }
+
+ if (subpatnum == FAIL || !use_skip) {
+ // didn't find it or no skip argument
+ break;
+ }
+ firstpos = pos;
+
+ // If the skip expression matches, ignore this match.
+ {
+ const pos_T save_pos = curwin->w_cursor;
+
+ curwin->w_cursor = pos;
+ bool err = false;
+ const bool do_skip = eval_expr_to_bool(&argvars[4], &err);
+ curwin->w_cursor = save_pos;
+ if (err) {
+ // Evaluating {skip} caused an error, break here.
+ subpatnum = FAIL;
+ break;
+ }
+ if (!do_skip) {
+ break;
+ }
+ }
+
+ // clear the start flag to avoid getting stuck here
+ options &= ~SEARCH_START;
+ }
+
if (subpatnum != FAIL) {
if (flags & SP_SUBPAT) {
retval = subpatnum;
@@ -8051,7 +7687,7 @@ theend:
return retval;
}
-// "rpcnotify()" function
+/// "rpcnotify()" function
static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8086,7 +7722,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 1;
}
-// "rpcrequest()" function
+/// "rpcrequest()" function
static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8114,7 +7750,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
sctx_T save_current_sctx;
- uint8_t *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
+ char *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
linenr_T save_sourcing_lnum;
int save_autocmd_bufnr;
funccal_entry_T funccal_entry;
@@ -8139,13 +7775,13 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_current_funccal((funccall_T *)(provider_caller_scope.funccalp));
}
-
Error err = ERROR_INIT;
uint64_t chan_id = (uint64_t)argvars[0].vval.v_number;
const char *method = tv_get_string(&argvars[1]);
- Object result = rpc_send_call(chan_id, method, args, &err);
+ ArenaMem res_mem = NULL;
+ Object result = rpc_send_call(chan_id, method, args, &res_mem, &err);
if (l_provider_call_nesting) {
current_sctx = save_current_sctx;
@@ -8180,11 +7816,11 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
end:
- api_free_object(result);
+ arena_mem_free(res_mem, NULL);
api_clear_error(&err);
}
-// "rpcstart()" function (DEPRECATED)
+/// "rpcstart()" function (DEPRECATED)
static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8228,7 +7864,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char **argv = xmalloc(sizeof(char_u *) * argvl);
// Copy program name
- argv[0] = xstrdup((char *)argvars[0].vval.v_string);
+ argv[0] = xstrdup(argvars[0].vval.v_string);
int i = 1;
// Copy arguments to the vector
@@ -8251,7 +7887,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "rpcstop()" function
+/// "rpcstop()" function
static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
@@ -8281,54 +7917,57 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "screenattr()" function
+/// "screenattr()" function
static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int c;
+ ScreenGrid *grid;
int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
c = -1;
} else {
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
c = grid->attrs[grid->line_offset[row] + col];
}
rettv->vval.v_number = c;
}
-// "screenchar()" function
+/// "screenchar()" function
static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int c;
+ ScreenGrid *grid;
int row = tv_get_number_chk(&argvars[0], NULL) - 1;
int col = tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
c = -1;
} else {
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
- c = utf_ptr2char(grid->chars[grid->line_offset[row] + col]);
+ c = utf_ptr2char((char *)grid->chars[grid->line_offset[row] + col]);
}
rettv->vval.v_number = c;
}
-// "screenchars()" function
+/// "screenchars()" function
static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
+ ScreenGrid *grid;
int row = tv_get_number_chk(&argvars[0], NULL) - 1;
int col = tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
tv_list_alloc_ret(rettv, 0);
return;
}
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
int pcc[MAX_MCO];
int c = utfc_ptr2char(grid->chars[grid->line_offset[row] + col], pcc);
int composing_len = 0;
@@ -8342,9 +7981,9 @@ static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "screencol()" function
-//
-// First column is 1 to be consistent with virtcol().
+/// "screencol()" function
+///
+/// First column is 1 to be consistent with virtcol().
static void f_screencol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_col() + 1;
@@ -8376,29 +8015,32 @@ static void f_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(dict, S_LEN("endcol"), ecol);
}
-// "screenrow()" function
+/// "screenrow()" function
static void f_screenrow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_row() + 1;
}
-// "screenstring()" function
+/// "screenstring()" function
static void f_screenstring(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
+
+ ScreenGrid *grid;
int row = tv_get_number_chk(&argvars[0], NULL) - 1;
int col = tv_get_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= default_grid.Rows
- || col < 0 || col >= default_grid.Columns) {
+
+ screenchar_adjust(&grid, &row, &col);
+
+ if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
return;
}
- ScreenGrid *grid = &default_grid;
- screenchar_adjust_grid(&grid, &row, &col);
- rettv->vval.v_string = vim_strsave(grid->chars[grid->line_offset[row] + col]);
+
+ rettv->vval.v_string = (char *)vim_strsave(grid->chars[grid->line_offset[row] + col]);
}
-// "search()" function
+/// "search()" function
static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int flags = 0;
@@ -8406,9 +8048,7 @@ static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = search_cmn(argvars, NULL, &flags);
}
-/*
- * "searchdecl()" function
- */
+/// "searchdecl()" function
static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int locally = 1;
@@ -8430,9 +8070,7 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * Used by searchpair() and searchpairpos()
- */
+/// Used by searchpair() and searchpairpos()
static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
{
bool save_p_ws = p_ws;
@@ -8478,13 +8116,9 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
|| argvars[4].v_type == VAR_UNKNOWN) {
skip = NULL;
} else {
+ // Type is checked later.
skip = &argvars[4];
- if (skip->v_type != VAR_FUNC
- && skip->v_type != VAR_PARTIAL
- && skip->v_type != VAR_STRING) {
- semsg(_(e_invarg2), tv_get_string(&argvars[4]));
- goto theend; // Type error.
- }
+
if (argvars[5].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[5], NULL);
if (lnum_stop < 0) {
@@ -8510,17 +8144,13 @@ theend:
return retval;
}
-/*
- * "searchpair()" function
- */
+/// "searchpair()" function
static void f_searchpair(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = searchpair_cmn(argvars, NULL);
}
-/*
- * "searchpairpos()" function
- */
+/// "searchpairpos()" function
static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T match_pos;
@@ -8556,7 +8186,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
long time_limit)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
- char_u *save_cpo;
+ char *save_cpo;
char_u *pat, *pat2 = NULL, *pat3 = NULL;
long retval = 0;
pos_T pos;
@@ -8572,7 +8202,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
// Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
- p_cpo = empty_option;
+ p_cpo = (char *)empty_option;
// Set the time limit, if there is one.
tm = profile_setlimit(time_limit);
@@ -8595,10 +8225,7 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
}
if (skip != NULL) {
- // Empty string means to not use the skip expression.
- if (skip->v_type == VAR_STRING || skip->v_type == VAR_FUNC) {
- use_skip = skip->vval.v_string != NULL && *skip->vval.v_string != NUL;
- }
+ use_skip = eval_expr_valid_arg(skip);
}
save_cursor = curwin->w_cursor;
@@ -8699,19 +8326,17 @@ long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir
xfree(pat2);
xfree(pat3);
- if (p_cpo == empty_option) {
+ if ((char_u *)p_cpo == empty_option) {
p_cpo = save_cpo;
} else {
// Darn, evaluating the {skip} expression changed the value.
- free_string_option(save_cpo);
+ free_string_option((char_u *)save_cpo);
}
return retval;
}
-/*
- * "searchpos()" function
- */
+/// "searchpos()" function
static void f_searchpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T match_pos;
@@ -8765,7 +8390,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
address = xstrdup(tv_get_string(argvars));
}
} else {
- address = server_address_new();
+ address = server_address_new(NULL);
}
int result = server_start(address);
@@ -8781,7 +8406,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "localhost:" will now have a port), return the final value to the user.
size_t n;
char **addrs = server_address_list(&n);
- rettv->vval.v_string = (char_u *)addrs[n - 1];
+ rettv->vval.v_string = addrs[n - 1];
n--;
for (size_t i = 0; i < n; i++) {
@@ -8805,7 +8430,7 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (argvars[0].vval.v_string) {
- bool rv = server_stop((char *)argvars[0].vval.v_string);
+ bool rv = server_stop(argvars[0].vval.v_string);
rettv->vval.v_number = (rv ? 1 : 0);
}
}
@@ -8825,9 +8450,7 @@ static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setbufvar()" function
- */
+/// "setbufvar()" function
static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()
@@ -8871,6 +8494,49 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+/// Set the cursor or mark position.
+/// If 'charpos' is TRUE, then use the column number as a character offset.
+/// Otherwise use the column number as a byte offset.
+static void set_position(typval_T *argvars, typval_T *rettv, bool charpos)
+{
+ pos_T pos;
+ int fnum;
+ colnr_T curswant = -1;
+
+ rettv->vval.v_number = -1;
+ const char *const name = tv_get_string_chk(argvars);
+ if (name != NULL) {
+ if (list2fpos(&argvars[1], &pos, &fnum, &curswant, charpos) == OK) {
+ if (pos.col != MAXCOL && --pos.col < 0) {
+ pos.col = 0;
+ }
+ if (name[0] == '.' && name[1] == NUL) {
+ // set cursor; "fnum" is ignored
+ curwin->w_cursor = pos;
+ if (curswant >= 0) {
+ curwin->w_curswant = curswant - 1;
+ curwin->w_set_curswant = false;
+ }
+ check_cursor();
+ rettv->vval.v_number = 0;
+ } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
+ // set mark
+ if (setmark_pos((uint8_t)name[1], &pos, fnum, NULL) == OK) {
+ rettv->vval.v_number = 0;
+ }
+ } else {
+ emsg(_(e_invarg));
+ }
+ }
+ }
+}
+
+/// "setcharpos()" function
+static void f_setcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ set_position(argvars, rettv, true);
+}
+
static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *d;
@@ -8886,7 +8552,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (csearch != NULL) {
int pcc[MAX_MCO];
const int c = utfc_ptr2char(csearch, pcc);
- set_last_csearch(c, csearch, utfc_ptr2len(csearch));
+ set_last_csearch(c, csearch, utfc_ptr2len((char *)csearch));
}
di = tv_dict_find(d, S_LEN("forward"));
@@ -8901,9 +8567,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setcmdpos()" function
- */
+/// "setcmdpos()" function
static void f_setcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const int pos = (int)tv_get_number(&argvars[0]) - 1;
@@ -8913,6 +8577,12 @@ static void f_setcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+/// "setcursorcharpos" function
+static void f_setcursorcharpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ set_cursorpos(argvars, rettv, true);
+}
+
/// "setenv()" function
static void f_setenv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -8959,9 +8629,7 @@ static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = os_setperm(fname, mode) == OK;
}
-/*
- * "setline()" function
- */
+/// "setline()" function
static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = tv_get_lnum(&argvars[0]);
@@ -8988,7 +8656,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
{
static char *e_invact = N_("E927: Invalid action: '%s'");
const char *title = NULL;
- int action = ' ';
+ char action = ' ';
static int recursive = 0;
rettv->vval.v_number = -1;
dict_T *what = NULL;
@@ -9043,15 +8711,13 @@ skip_args:
recursive++;
list_T *const l = list_arg->vval.v_list;
- if (set_errorlist(wp, l, action, (char_u *)title, what) == OK) {
+ if (set_errorlist(wp, l, action, (char *)title, what) == OK) {
rettv->vval.v_number = 0;
}
recursive--;
}
-/*
- * "setloclist()" function
- */
+/// "setloclist()" function
static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *win;
@@ -9064,151 +8730,13 @@ static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setmatches()" function
- */
-static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- dict_T *d;
- list_T *s = NULL;
- win_T *win = get_optional_window(argvars, 1);
-
- rettv->vval.v_number = -1;
- if (argvars[0].v_type != VAR_LIST) {
- emsg(_(e_listreq));
- return;
- }
- if (win == NULL) {
- return;
- }
-
- list_T *const l = argvars[0].vval.v_list;
- // To some extent make sure that we are dealing with a list from
- // "getmatches()".
- int li_idx = 0;
- TV_LIST_ITER_CONST(l, li, {
- if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT
- || (d = TV_LIST_ITEM_TV(li)->vval.v_dict) == NULL) {
- semsg(_("E474: List item %d is either not a dictionary "
- "or an empty one"), li_idx);
- return;
- }
- if (!(tv_dict_find(d, S_LEN("group")) != NULL
- && (tv_dict_find(d, S_LEN("pattern")) != NULL
- || tv_dict_find(d, S_LEN("pos1")) != NULL)
- && tv_dict_find(d, S_LEN("priority")) != NULL
- && tv_dict_find(d, S_LEN("id")) != NULL)) {
- semsg(_("E474: List item %d is missing one of the required keys"),
- li_idx);
- return;
- }
- li_idx++;
- });
-
- clear_matches(win);
- bool match_add_failed = false;
- TV_LIST_ITER_CONST(l, li, {
- int i = 0;
-
- d = TV_LIST_ITEM_TV(li)->vval.v_dict;
- dictitem_T *const di = tv_dict_find(d, S_LEN("pattern"));
- if (di == NULL) {
- if (s == NULL) {
- s = tv_list_alloc(9);
- }
-
- // match from matchaddpos()
- for (i = 1; i < 9; i++) {
- char buf[30]; // use 30 to avoid compiler warning
- snprintf(buf, sizeof(buf), "pos%d", i);
- dictitem_T *const pos_di = tv_dict_find(d, buf, -1);
- if (pos_di != NULL) {
- if (pos_di->di_tv.v_type != VAR_LIST) {
- return;
- }
-
- tv_list_append_tv(s, &pos_di->di_tv);
- tv_list_ref(s);
- } else {
- break;
- }
- }
- }
-
- // Note: there are three number buffers involved:
- // - group_buf below.
- // - numbuf in tv_dict_get_string().
- // - mybuf in tv_get_string().
- //
- // If you change this code make sure that buffers will not get
- // accidentally reused.
- char group_buf[NUMBUFLEN];
- const char *const group = tv_dict_get_string_buf(d, "group", group_buf);
- const int priority = (int)tv_dict_get_number(d, "priority");
- const int id = (int)tv_dict_get_number(d, "id");
- dictitem_T *const conceal_di = tv_dict_find(d, S_LEN("conceal"));
- const char *const conceal = (conceal_di != NULL
- ? tv_get_string(&conceal_di->di_tv)
- : NULL);
- if (i == 0) {
- if (match_add(win, group,
- tv_dict_get_string(d, "pattern", false),
- priority, id, NULL, conceal) != id) {
- match_add_failed = true;
- }
- } else {
- if (match_add(win, group, NULL, priority, id, s, conceal) != id) {
- match_add_failed = true;
- }
- tv_list_unref(s);
- s = NULL;
- }
- });
- if (!match_add_failed) {
- rettv->vval.v_number = 0;
- }
-}
-
-/*
- * "setpos()" function
- */
+/// "setpos()" function
static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T pos;
- int fnum;
- colnr_T curswant = -1;
-
- rettv->vval.v_number = -1;
- const char *const name = tv_get_string_chk(argvars);
- if (name != NULL) {
- if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK) {
- if (pos.col != MAXCOL && --pos.col < 0) {
- pos.col = 0;
- }
- if (name[0] == '.' && name[1] == NUL) {
- // set cursor; "fnum" is ignored
- curwin->w_cursor = pos;
- if (curswant >= 0) {
- curwin->w_curswant = curswant - 1;
- curwin->w_set_curswant = false;
- }
- check_cursor();
- rettv->vval.v_number = 0;
- } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
- // set mark
- if (setmark_pos((uint8_t)name[1], &pos, fnum) == OK) {
- rettv->vval.v_number = 0;
- }
- } else {
- emsg(_(e_invarg));
- }
- }
- }
+ set_position(argvars, rettv, false);
}
-/*
- * "setqflist()" function
- */
+/// "setqflist()" function
static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
set_qf_ll_list(NULL, argvars, rettv);
@@ -9244,12 +8772,9 @@ static int get_yank_type(char_u **const pp, MotionType *const yank_type, long *c
return OK;
}
-/*
- * "setreg()" function
- */
+/// "setreg()" function
static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int regname;
bool append = false;
MotionType yank_type;
long block_len;
@@ -9263,13 +8788,13 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (strregname == NULL) {
return; // Type error; errmsg already given.
}
- regname = (uint8_t)(*strregname);
+ char regname = (uint8_t)(*strregname);
if (regname == 0 || regname == '@') {
regname = '"';
}
const typval_T *regcontents = NULL;
- int pointreg = 0;
+ char pointreg = 0;
if (argvars[1].v_type == VAR_DICT) {
dict_T *const d = argvars[1].vval.v_dict;
@@ -9387,14 +8912,11 @@ free_lstval:
if (set_unnamed) {
// Discard the result. We already handle the error case.
- if (op_reg_set_previous(regname)) {
- }
+ op_reg_set_previous(regname);
}
}
-/*
- * "settabvar()" function
- */
+/// "settabvar()" function
static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
@@ -9425,21 +8947,19 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "settabwinvar()" function
- */
+/// "settabwinvar()" function
static void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
setwinvar(argvars, rettv, 1);
}
-// "settagstack()" function
+/// "settagstack()" function
static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
static char *e_invact2 = N_("E962: Invalid action: '%s'");
win_T *wp;
dict_T *d;
- int action = 'r';
+ char action = 'r';
rettv->vval.v_number = -1;
@@ -9486,9 +9006,7 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "setwinvar()" function
- */
+/// "setwinvar()" function
static void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
setwinvar(argvars, rettv, 0);
@@ -9501,26 +9019,22 @@ static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr)
const char *hash = sha256_bytes((const uint8_t *)p, strlen(p), NULL, 0);
// make a copy of the hash (sha256_bytes returns a static buffer)
- rettv->vval.v_string = (char_u *)xstrdup(hash);
+ rettv->vval.v_string = xstrdup(hash);
rettv->v_type = VAR_STRING;
}
-/*
- * "shellescape({string})" function
- */
+/// "shellescape({string})" function
static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const bool do_special = non_zero_arg(&argvars[1]);
- rettv->vval.v_string = vim_strsave_shellescape((const char_u *)tv_get_string(
- &argvars[0]), do_special,
- do_special);
+ rettv->vval.v_string =
+ (char *)vim_strsave_shellescape((const char_u *)tv_get_string(&argvars[0]), do_special,
+ do_special);
rettv->v_type = VAR_STRING;
}
-/*
- * shiftwidth() function
- */
+/// shiftwidth() function
static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
@@ -9538,280 +9052,12 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = get_sw_value(curbuf);
}
-/// "sign_define()" function
-static void f_sign_define(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *name;
-
- if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) {
- // Define multiple signs
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- sign_define_multiple(argvars[0].vval.v_list, rettv->vval.v_list);
- return;
- }
-
- // Define a single sign
- rettv->vval.v_number = -1;
-
- name = tv_get_string_chk(&argvars[0]);
- if (name == NULL) {
- return;
- }
-
- if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_DICT) {
- emsg(_(e_dictreq));
- return;
- }
-
- rettv->vval.v_number = sign_define_from_dict(name,
- argvars[1].v_type ==
- VAR_DICT ? argvars[1].vval.v_dict : NULL);
-}
-
-/// "sign_getdefined()" function
-static void f_sign_getdefined(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *name = NULL;
-
- tv_list_alloc_ret(rettv, 0);
-
- if (argvars[0].v_type != VAR_UNKNOWN) {
- name = tv_get_string(&argvars[0]);
- }
-
- sign_getlist((const char_u *)name, rettv->vval.v_list);
-}
-
-/// "sign_getplaced()" function
-static void f_sign_getplaced(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- buf_T *buf = NULL;
- dict_T *dict;
- dictitem_T *di;
- linenr_T lnum = 0;
- int sign_id = 0;
- const char *group = NULL;
- bool notanum = false;
-
- tv_list_alloc_ret(rettv, 0);
-
- if (argvars[0].v_type != VAR_UNKNOWN) {
- // get signs placed in the specified buffer
- buf = get_buf_arg(&argvars[0]);
- if (buf == NULL) {
- return;
- }
-
- if (argvars[1].v_type != VAR_UNKNOWN) {
- if (argvars[1].v_type != VAR_DICT
- || ((dict = argvars[1].vval.v_dict) == NULL)) {
- emsg(_(e_dictreq));
- return;
- }
- if ((di = tv_dict_find(dict, "lnum", -1)) != NULL) {
- // get signs placed at this line
- lnum = (linenr_T)tv_get_number_chk(&di->di_tv, &notanum);
- if (notanum) {
- return;
- }
- (void)lnum;
- lnum = tv_get_lnum(&di->di_tv);
- }
- if ((di = tv_dict_find(dict, "id", -1)) != NULL) {
- // get sign placed with this identifier
- sign_id = (int)tv_get_number_chk(&di->di_tv, &notanum);
- if (notanum) {
- return;
- }
- }
- if ((di = tv_dict_find(dict, "group", -1)) != NULL) {
- group = tv_get_string_chk(&di->di_tv);
- if (group == NULL) {
- return;
- }
- if (*group == '\0') { // empty string means global group
- group = NULL;
- }
- }
- }
- }
-
- sign_get_placed(buf, lnum, sign_id, (const char_u *)group,
- rettv->vval.v_list);
-}
-
-/// "sign_jump()" function
-static void f_sign_jump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- int sign_id;
- char *sign_group = NULL;
- buf_T *buf;
- bool notanum = false;
-
- rettv->vval.v_number = -1;
-
- // Sign identifier
- sign_id = (int)tv_get_number_chk(&argvars[0], &notanum);
- if (notanum) {
- return;
- }
- if (sign_id <= 0) {
- emsg(_(e_invarg));
- return;
- }
-
- // Sign group
- const char *sign_group_chk = tv_get_string_chk(&argvars[1]);
- if (sign_group_chk == NULL) {
- return;
- }
- if (sign_group_chk[0] == '\0') {
- sign_group = NULL; // global sign group
- } else {
- sign_group = xstrdup(sign_group_chk);
- }
-
- // Buffer to place the sign
- buf = get_buf_arg(&argvars[2]);
- if (buf == NULL) {
- goto cleanup;
- }
-
- rettv->vval.v_number = sign_jump(sign_id, (char_u *)sign_group, buf);
-
-cleanup:
- xfree(sign_group);
-}
-
-/// "sign_place()" function
-static void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- dict_T *dict = NULL;
-
- rettv->vval.v_number = -1;
-
- if (argvars[4].v_type != VAR_UNKNOWN
- && (argvars[4].v_type != VAR_DICT
- || ((dict = argvars[4].vval.v_dict) == NULL))) {
- emsg(_(e_dictreq));
- return;
- }
-
- rettv->vval.v_number = sign_place_from_dict(&argvars[0], &argvars[1], &argvars[2], &argvars[3],
- dict);
-}
-
-/// "sign_placelist()" function. Place multiple signs.
-static void f_sign_placelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- int sign_id;
-
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- if (argvars[0].v_type != VAR_LIST) {
- emsg(_(e_listreq));
- return;
- }
-
- // Process the List of sign attributes
- TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
- sign_id = -1;
- if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- sign_id = sign_place_from_dict(NULL, NULL, NULL, NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
- } else {
- emsg(_(e_dictreq));
- }
- tv_list_append_number(rettv->vval.v_list, sign_id);
- });
-}
-
-/// "sign_undefine()" function
-static void f_sign_undefine(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- const char *name;
-
- if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) {
- // Undefine multiple signs
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- sign_undefine_multiple(argvars[0].vval.v_list, rettv->vval.v_list);
- return;
- }
-
- rettv->vval.v_number = -1;
-
- if (argvars[0].v_type == VAR_UNKNOWN) {
- // Free all the signs
- free_signs();
- rettv->vval.v_number = 0;
- } else {
- // Free only the specified sign
- name = tv_get_string_chk(&argvars[0]);
- if (name == NULL) {
- return;
- }
-
- if (sign_undefine_by_name((const char_u *)name) == OK) {
- rettv->vval.v_number = 0;
- }
- }
-}
-
-/// "sign_unplace()" function
-static void f_sign_unplace(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- dict_T *dict = NULL;
-
- rettv->vval.v_number = -1;
-
- if (argvars[0].v_type != VAR_STRING) {
- emsg(_(e_invarg));
- return;
- }
-
- if (argvars[1].v_type != VAR_UNKNOWN) {
- if (argvars[1].v_type != VAR_DICT) {
- emsg(_(e_dictreq));
- return;
- }
- dict = argvars[1].vval.v_dict;
- }
-
- rettv->vval.v_number = sign_unplace_from_dict(&argvars[0], dict);
-}
-
-/// "sign_unplacelist()" function
-static void f_sign_unplacelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- int retval;
-
- tv_list_alloc_ret(rettv, kListLenMayKnow);
-
- if (argvars[0].v_type != VAR_LIST) {
- emsg(_(e_listreq));
- return;
- }
-
- TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
- retval = -1;
- if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) {
- retval = sign_unplace_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict);
- } else {
- emsg(_(e_dictreq));
- }
- tv_list_append_number(rettv->vval.v_list, retval);
- });
-}
-
-/*
- * "simplify()" function
- */
+/// "simplify()" function
static void f_simplify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const p = tv_get_string(&argvars[0]);
- rettv->vval.v_string = (char_u *)xstrdup(p);
- simplify_filename(rettv->vval.v_string); // Simplify in place.
+ rettv->vval.v_string = xstrdup(p);
+ simplify_filename((char_u *)rettv->vval.v_string); // Simplify in place.
rettv->v_type = VAR_STRING;
}
@@ -9883,9 +9129,7 @@ static sortinfo_T *sortinfo = NULL;
#define ITEM_COMPARE_FAIL 999
-/*
- * Compare functions for f_sort() and f_uniq() below.
- */
+/// Compare functions for f_sort() and f_uniq() below.
static int item_compare(const void *s1, const void *s2, bool keep_zero)
{
ListSortItem *const si1 = (ListSortItem *)s1;
@@ -9924,7 +9168,7 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero)
if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
p1 = "'";
} else {
- p1 = (char *)tv1->vval.v_string;
+ p1 = tv1->vval.v_string;
}
} else {
tofree1 = p1 = encode_tv2string(tv1, NULL);
@@ -9933,7 +9177,7 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero)
if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
p2 = "'";
} else {
- p2 = (char *)tv2->vval.v_string;
+ p2 = tv2->vval.v_string;
}
} else {
tofree2 = p2 = encode_tv2string(tv2, NULL);
@@ -10014,7 +9258,7 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
funcexe.evaluate = true;
funcexe.partial = partial;
funcexe.selfdict = sortinfo->item_compare_selfdict;
- res = call_func((const char_u *)func_name, -1, &rettv, 2, argv, &funcexe);
+ res = call_func(func_name, -1, &rettv, 2, argv, &funcexe);
tv_clear(&argv[0]);
tv_clear(&argv[1]);
@@ -10022,6 +9266,11 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
res = ITEM_COMPARE_FAIL;
} else {
res = tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err);
+ if (res > 0) {
+ res = 1;
+ } else if (res < 0) {
+ res = -1;
+ }
}
if (sortinfo->item_compare_func_err) {
res = ITEM_COMPARE_FAIL; // return value has wrong type
@@ -10049,9 +9298,7 @@ static int item_compare2_not_keeping_zero(const void *s1, const void *s2)
return item_compare2(s1, s2, false);
}
-/*
- * "sort({list})" function
- */
+/// "sort({list})" function
static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
{
ListSortItem *ptrs;
@@ -10209,7 +9456,6 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-
bool rpc = false;
CallbackReader on_stdin = CALLBACK_READER_INIT;
dict_T *opts = argvars[0].vval.v_dict;
@@ -10218,6 +9464,10 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!tv_dict_get_callback(opts, S_LEN("on_stdin"), &on_stdin.cb)) {
return;
}
+ if (!tv_dict_get_callback(opts, S_LEN("on_print"), &on_print)) {
+ return;
+ }
+
on_stdin.buffered = tv_dict_get_number(opts, "stdin_buffered");
if (on_stdin.buffered && on_stdin.cb.type == kCallbackNone) {
on_stdin.self = opts;
@@ -10229,7 +9479,6 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
semsg(e_stdiochan2, error);
}
-
rettv->vval.v_number = (varnumber_T)id;
rettv->v_type = VAR_NUMBER;
}
@@ -10240,7 +9489,7 @@ static void f_uniq(typval_T *argvars, typval_T *rettv, FunPtr fptr)
do_sort_uniq(argvars, rettv, false);
}
-// "reltimefloat()" function
+/// "reltimefloat()" function
static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
@@ -10253,19 +9502,15 @@ static void f_reltimefloat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "soundfold({word})" function
- */
+/// "soundfold({word})" function
static void f_soundfold(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
const char *const s = tv_get_string(&argvars[0]);
- rettv->vval.v_string = (char_u *)eval_soundfold(s);
+ rettv->vval.v_string = eval_soundfold(s);
}
-/*
- * "spellbadword()" function
- */
+/// "spellbadword()" function
static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *word = "";
@@ -10324,9 +9569,7 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
NULL), -1);
}
-/*
- * "spellsuggest()" function
- */
+/// "spellsuggest()" function
static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool typeerr = false;
@@ -10346,26 +9589,24 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- if (*curwin->w_s->b_p_spl != NUL) {
- const char *const str = tv_get_string(&argvars[0]);
- if (argvars[1].v_type != VAR_UNKNOWN) {
- maxcount = tv_get_number_chk(&argvars[1], &typeerr);
- if (maxcount <= 0) {
+ const char *const str = tv_get_string(&argvars[0]);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ maxcount = tv_get_number_chk(&argvars[1], &typeerr);
+ if (maxcount <= 0) {
+ goto f_spellsuggest_return;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ need_capital = tv_get_number_chk(&argvars[2], &typeerr);
+ if (typeerr) {
goto f_spellsuggest_return;
}
- if (argvars[2].v_type != VAR_UNKNOWN) {
- need_capital = tv_get_number_chk(&argvars[2], &typeerr);
- if (typeerr) {
- goto f_spellsuggest_return;
- }
- }
- } else {
- maxcount = 25;
}
-
- spell_suggest_list(&ga, (char_u *)str, maxcount, need_capital, false);
+ } else {
+ maxcount = 25;
}
+ spell_suggest_list(&ga, (char_u *)str, maxcount, need_capital, false);
+
f_spellsuggest_return:
tv_list_alloc_ret(rettv, (ptrdiff_t)ga.ga_len);
for (int i = 0; i < ga.ga_len; i++) {
@@ -10378,7 +9619,7 @@ f_spellsuggest_return:
static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *save_cpo;
+ char *save_cpo;
int match;
colnr_T col = 0;
bool keepempty = false;
@@ -10386,7 +9627,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
- p_cpo = (char_u *)"";
+ p_cpo = "";
const char *str = tv_get_string(&argvars[0]);
const char *pat = NULL;
@@ -10411,7 +9652,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
regmatch_T regmatch = {
- .regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING),
+ .regprog = vim_regcomp((char *)pat, RE_MAGIC + RE_STRING),
.startp = { NULL },
.endp = { NULL },
.rm_ic = false,
@@ -10443,7 +9684,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
col = 0;
} else {
// Don't get stuck at the same match.
- col = utfc_ptr2len(regmatch.endp[0]);
+ col = utfc_ptr2len((char *)regmatch.endp[0]);
}
str = (const char *)regmatch.endp[0];
}
@@ -10467,11 +9708,17 @@ static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (strequal(p, "config")) {
- rettv->vval.v_string = (char_u *)get_xdg_home(kXDGConfigHome);
+ rettv->vval.v_string = get_xdg_home(kXDGConfigHome);
} else if (strequal(p, "data")) {
- rettv->vval.v_string = (char_u *)get_xdg_home(kXDGDataHome);
+ rettv->vval.v_string = get_xdg_home(kXDGDataHome);
} else if (strequal(p, "cache")) {
- rettv->vval.v_string = (char_u *)get_xdg_home(kXDGCacheHome);
+ rettv->vval.v_string = get_xdg_home(kXDGCacheHome);
+ } else if (strequal(p, "state")) {
+ rettv->vval.v_string = get_xdg_home(kXDGStateHome);
+ } else if (strequal(p, "log")) {
+ rettv->vval.v_string = get_xdg_home(kXDGStateHome);
+ } else if (strequal(p, "run")) {
+ rettv->vval.v_string = stdpaths_get_xdg_var(kXDGRuntimeDir);
} else if (strequal(p, "config_dirs")) {
get_xdg_var_list(kXDGConfigDirs, rettv);
} else if (strequal(p, "data_dirs")) {
@@ -10481,36 +9728,34 @@ static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "str2float()" function
- */
+/// "str2float()" function
static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ char *p = skipwhite(tv_get_string(&argvars[0]));
bool isneg = (*p == '-');
if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
}
- (void)string2float((char *)p, &rettv->vval.v_float);
+ (void)string2float(p, &rettv->vval.v_float);
if (isneg) {
rettv->vval.v_float *= -1;
}
rettv->v_type = VAR_FLOAT;
}
-// "str2list()" function
+/// "str2list()" function
static void f_str2list(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_alloc_ret(rettv, kListLenUnknown);
const char_u *p = (const char_u *)tv_get_string(&argvars[0]);
- for (; *p != NUL; p += utf_ptr2len(p)) {
- tv_list_append_number(rettv->vval.v_list, utf_ptr2char(p));
+ for (; *p != NUL; p += utf_ptr2len((char *)p)) {
+ tv_list_append_number(rettv->vval.v_list, utf_ptr2char((char *)p));
}
}
-// "str2nr()" function
+/// "str2nr()" function
static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int base = 10;
@@ -10528,10 +9773,10 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ char_u *p = (char_u *)skipwhite(tv_get_string(&argvars[0]));
bool isneg = (*p == '-');
if (*p == '+' || *p == '-') {
- p = skipwhite(p + 1);
+ p = (char_u *)skipwhite((char *)p + 1);
}
switch (base) {
case 2:
@@ -10553,9 +9798,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "strftime({format}[, {time}])" function
- */
+/// "strftime({format}[, {time}])" function
static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
time_t seconds;
@@ -10573,7 +9816,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime);
// MSVC returns NULL for an invalid value of seconds.
if (curtime_ptr == NULL) {
- rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
+ rettv->vval.v_string = xstrdup(_("(Invalid)"));
} else {
vimconv_T conv;
char_u *enc;
@@ -10596,9 +9839,9 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
convert_setup(&conv, enc, p_enc);
if (conv.vc_type != CONV_NONE) {
- rettv->vval.v_string = string_convert(&conv, (char_u *)result_buf, NULL);
+ rettv->vval.v_string = (char *)string_convert(&conv, (char_u *)result_buf, NULL);
} else {
- rettv->vval.v_string = (char_u *)xstrdup(result_buf);
+ rettv->vval.v_string = xstrdup(result_buf);
}
// Release conversion descriptors.
@@ -10607,7 +9850,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "strgetchar()" function
+/// "strgetchar()" function
static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -10627,17 +9870,15 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
while (charidx >= 0 && byteidx < len) {
if (charidx == 0) {
- rettv->vval.v_number = utf_ptr2char((const char_u *)str + byteidx);
+ rettv->vval.v_number = utf_ptr2char(str + byteidx);
break;
}
charidx--;
- byteidx += utf_ptr2len((const char_u *)str + byteidx);
+ byteidx += utf_ptr2len(str + byteidx);
}
}
-/*
- * "stridx()" function
- */
+/// "stridx()" function
static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
@@ -10669,26 +9910,20 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "string()" function
- */
-void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+/// "string()" function
+static void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)encode_tv2string(&argvars[0], NULL);
+ rettv->vval.v_string = encode_tv2string(&argvars[0], NULL);
}
-/*
- * "strlen()" function
- */
+/// "strlen()" function
static void f_strlen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0]));
}
-/*
- * "strchars()" function
- */
+/// "strchars()" function
static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *s = tv_get_string(&argvars[0]);
@@ -10711,9 +9946,7 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "strdisplaywidth()" function
- */
+/// "strdisplaywidth()" function
static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const s = tv_get_string(&argvars[0]);
@@ -10726,17 +9959,15 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char_u *)s) - col);
}
-/*
- * "strwidth()" function
- */
+/// "strwidth()" function
static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const s = tv_get_string(&argvars[0]);
- rettv->vval.v_number = (varnumber_T)mb_string2cells((const char_u *)s);
+ rettv->vval.v_number = (varnumber_T)mb_string2cells(s);
}
-// "strcharpart()" function
+/// "strcharpart()" function
static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const p = tv_get_string(&argvars[0]);
@@ -10748,7 +9979,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (!error) {
if (nchar > 0) {
while (nchar > 0 && (size_t)nbyte < slen) {
- nbyte += utf_ptr2len((const char_u *)p + nbyte);
+ nbyte += utf_ptr2len(p + nbyte);
nchar--;
}
} else {
@@ -10764,7 +9995,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (off < 0) {
len += 1;
} else {
- len += utf_ptr2len((const char_u *)p + off);
+ len += utf_ptr2len(p + off);
}
charlen--;
}
@@ -10787,12 +10018,10 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)xstrndup(p + nbyte, (size_t)len);
+ rettv->vval.v_string = xstrndup(p + nbyte, (size_t)len);
}
-/*
- * "strpart()" function
- */
+/// "strpart()" function
static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool error = false;
@@ -10829,16 +10058,16 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// length in characters
for (off = n; off < (int)slen && len > 0; len--) {
- off += utfc_ptr2len((char_u *)p + off);
+ off += utfc_ptr2len(p + off);
}
len = off - n;
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len);
+ rettv->vval.v_string = xmemdupz(p + n, (size_t)len);
}
-// "strptime({format}, {timestring})" function
+/// "strptime({format}, {timestring})" function
static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char fmt_buf[NUMBUFLEN];
@@ -10870,9 +10099,7 @@ static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(enc);
}
-/*
- * "strridx()" function
- */
+/// "strridx()" function
static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
@@ -10915,18 +10142,14 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "strtrans()" function
- */
+/// "strtrans()" function
static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]), true);
+ rettv->vval.v_string = transstr(tv_get_string(&argvars[0]), true);
}
-/*
- * "submatch()" function
- */
+/// "submatch()" function
static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool error = false;
@@ -10950,16 +10173,14 @@ static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (retList == 0) {
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = reg_submatch(no);
+ rettv->vval.v_string = (char *)reg_submatch(no);
} else {
rettv->v_type = VAR_LIST;
rettv->vval.v_list = reg_submatch_list(no);
}
}
-/*
- * "substitute()" function
- */
+/// "substitute()" function
static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char patbuf[NUMBUFLEN];
@@ -10983,8 +10204,8 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|| flg == NULL) {
rettv->vval.v_string = NULL;
} else {
- rettv->vval.v_string = do_string_sub((char_u *)str, (char_u *)pat,
- (char_u *)sub, expr, (char_u *)flg);
+ rettv->vval.v_string = do_string_sub((char *)str, (char *)pat,
+ (char *)sub, expr, (char *)flg);
}
}
@@ -11005,7 +10226,7 @@ static void f_swapname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|| buf->b_ml.ml_mfp->mf_fname == NULL) {
rettv->vval.v_string = NULL;
} else {
- rettv->vval.v_string = vim_strsave(buf->b_ml.ml_mfp->mf_fname);
+ rettv->vval.v_string = (char *)vim_strsave(buf->b_ml.ml_mfp->mf_fname);
}
}
@@ -11028,9 +10249,7 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = id;
}
-/*
- * "synIDattr(id, what [, mode])" function
- */
+/// "synIDattr(id, what [, mode])" function
static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const int id = (int)tv_get_number(&argvars[0]);
@@ -11049,7 +10268,6 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
modec = 'c';
}
-
const char *p = NULL;
switch (TOLOWER_ASC(what[0])) {
case 'b':
@@ -11086,21 +10304,35 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
break;
case 'u':
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- } else { // undercurl
- p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ if (STRLEN(what) >= 9) {
+ if (TOLOWER_ASC(what[5]) == 'l') {
+ // underline
+ p = highlight_has_attr(id, HL_UNDERLINE, modec);
+ } else if (TOLOWER_ASC(what[5]) != 'd') {
+ // undercurl
+ p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ } else if (TOLOWER_ASC(what[6]) != 'o') {
+ // underdashed
+ p = highlight_has_attr(id, HL_UNDERDASHED, modec);
+ } else if (TOLOWER_ASC(what[7]) == 'u') {
+ // underdouble
+ p = highlight_has_attr(id, HL_UNDERDOUBLE, modec);
+ } else {
+ // underdotted
+ p = highlight_has_attr(id, HL_UNDERDOTTED, modec);
+ }
+ } else {
+ // ul
+ p = highlight_color(id, what, modec);
}
break;
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p));
+ rettv->vval.v_string = (char *)(p == NULL ? p : xstrdup(p));
}
-/*
- * "synIDtrans(id)" function
- */
+/// "synIDtrans(id)" function
static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int id = tv_get_number(&argvars[0]);
@@ -11114,9 +10346,7 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = id;
}
-/*
- * "synconcealed(lnum, col)" function
- */
+/// "synconcealed(lnum, col)" function
static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int syntax_flags = 0;
@@ -11146,7 +10376,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
: curwin->w_p_lcs_chars.conceal;
}
if (cchar != NUL) {
- utf_char2bytes(cchar, str);
+ utf_char2bytes(cchar, (char *)str);
}
}
}
@@ -11158,9 +10388,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, matchid);
}
-/*
- * "synstack(lnum, col)" function
- */
+/// "synstack(lnum, col)" function
static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_list_set_ret(rettv, NULL);
@@ -11195,10 +10423,7 @@ static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_system_output_as_rettv(argvars, rettv, true);
}
-
-/*
- * "tabpagebuflist()" function
- */
+/// "tabpagebuflist()" function
static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp = NULL;
@@ -11220,9 +10445,7 @@ static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "tabpagenr()" function
- */
+/// "tabpagenr()" function
static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
@@ -11234,9 +10457,7 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (strcmp(arg, "$") == 0) {
nr = tabpage_index(NULL) - 1;
} else if (strcmp(arg, "#") == 0) {
- nr = valid_tabpage(lastused_tabpage)
- ? tabpage_index(lastused_tabpage)
- : nr;
+ nr = valid_tabpage(lastused_tabpage) ? tabpage_index(lastused_tabpage) : 0;
} else {
semsg(_(e_invexpr2), arg);
}
@@ -11247,10 +10468,7 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = nr;
}
-
-/*
- * Common code for tabpagewinnr() and winnr().
- */
+/// Common code for tabpagewinnr() and winnr().
static int get_winnr(tabpage_T *tp, typval_T *argvar)
{
win_T *twin;
@@ -11315,9 +10533,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
return nr;
}
-/*
- * "tabpagewinnr()" function
- */
+/// "tabpagewinnr()" function
static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
@@ -11330,9 +10546,7 @@ static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = nr;
}
-/*
- * "tagfiles()" function
- */
+/// "tagfiles()" function
static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char *fname;
@@ -11351,9 +10565,7 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(fname);
}
-/*
- * "taglist()" function
- */
+/// "taglist()" function
static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const char *const tag_pattern = tv_get_string(&argvars[0]);
@@ -11371,16 +10583,14 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
(char_u *)tag_pattern, (char_u *)fname);
}
-/*
- * "tempname()" function
- */
+/// "tempname()" function
static void f_tempname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_tempname();
+ rettv->vval.v_string = (char *)vim_tempname();
}
-// "termopen(cmd[, cwd])" function
+/// "termopen(cmd[, cwd])" function
static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_secure()) {
@@ -11466,19 +10676,25 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "./…" => "/home/foo/…"
vim_FullName(cwd, (char *)NameBuff, sizeof(NameBuff), false);
// "/home/foo/…" => "~/…"
- size_t len = home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true);
+ size_t len = home_replace(NULL, (char *)NameBuff, (char *)IObuff, sizeof(IObuff), true);
// Trim slash.
- if (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/') {
+ if (len != 1 && (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/')) {
IObuff[len - 1] = '\0';
}
+ if (len == 1 && IObuff[0] == '/') {
+ // Avoid ambiguity in the URI when CWD is root directory.
+ IObuff[1] = '.';
+ IObuff[2] = '\0';
+ }
+
// Terminal URI: "term://$CWD//$PID:$CMD"
snprintf((char *)NameBuff, sizeof(NameBuff), "term://%s//%d:%s",
(char *)IObuff, pid, cmd);
// at this point the buffer has no terminal instance associated yet, so unset
// the 'swapfile' option to ensure no swap file will be created
curbuf->b_p_swf = false;
- (void)setfname(curbuf, NameBuff, NULL, true);
+ (void)setfname(curbuf, (char *)NameBuff, NULL, true);
// Save the job id and pid in b:terminal_job_{id,pid}
Error err = ERROR_INIT;
// deprecated: use 'channel' buffer option
@@ -11493,24 +10709,6 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
channel_create_event(chan, NULL);
}
-// "test_garbagecollect_now()" function
-static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- // This is dangerous, any Lists and Dicts used internally may be freed
- // while still in use.
- garbage_collect(true);
-}
-
-// "test_write_list_log()" function
-static void f_test_write_list_log(typval_T *const argvars, typval_T *const rettv, FunPtr fptr)
-{
- const char *const fname = tv_get_string_chk(&argvars[0]);
- if (fname == NULL) {
- return;
- }
- list_write_log(fname);
-}
-
/// "timer_info([timer])" function
static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -11583,8 +10781,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer_start(tv_get_number(&argvars[0]), repeat, &callback);
}
-
-// "timer_stop(timerid)" function
+/// "timer_stop(timerid)" function
static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type != VAR_NUMBER) {
@@ -11605,29 +10802,21 @@ static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr)
timer_stop_all();
}
-/*
- * "tolower(string)" function
- */
+/// "tolower(string)" function
static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
- false);
+ rettv->vval.v_string = strcase_save(tv_get_string(&argvars[0]), false);
}
-/*
- * "toupper(string)" function
- */
+/// "toupper(string)" function
static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
- true);
+ rettv->vval.v_string = strcase_save(tv_get_string(&argvars[0]), true);
}
-/*
- * "tr(string, fromstr, tostr)" function
- */
+/// "tr(string, fromstr, tostr)" function
static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf[NUMBUFLEN];
@@ -11650,16 +10839,16 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool first = true;
while (*in_str != NUL) {
const char *cpstr = in_str;
- const int inlen = utfc_ptr2len((const char_u *)in_str);
+ const int inlen = utfc_ptr2len(in_str);
int cplen = inlen;
int idx = 0;
int fromlen;
for (const char *p = fromstr; *p != NUL; p += fromlen) {
- fromlen = utfc_ptr2len((const char_u *)p);
+ fromlen = utfc_ptr2len(p);
if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) {
int tolen;
for (p = tostr; *p != NUL; p += tolen) {
- tolen = utfc_ptr2len((const char_u *)p);
+ tolen = utfc_ptr2len(p);
if (idx-- == 0) {
cplen = tolen;
cpstr = (char *)p;
@@ -11681,7 +10870,7 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
first = false;
int tolen;
for (const char *p = tostr; *p != NUL; p += tolen) {
- tolen = utfc_ptr2len((const char_u *)p);
+ tolen = utfc_ptr2len(p);
idx--;
}
if (idx != 0) {
@@ -11704,10 +10893,9 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
error:
semsg(_(e_invarg2), fromstr);
ga_clear(&ga);
- return;
}
-// "trim({expr})" function
+/// "trim({expr})" function
static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char buf1[NUMBUFLEN];
@@ -11745,14 +10933,14 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (dir == 0 || dir == 1) {
// Trim leading characters
while (*head != NUL) {
- c1 = utf_ptr2char(head);
+ c1 = utf_ptr2char((char *)head);
if (mask == NULL) {
if (c1 > ' ' && c1 != 0xa0) {
break;
}
} else {
for (p = mask; *p != NUL; MB_PTR_ADV(p)) {
- if (c1 == utf_ptr2char(p)) {
+ if (c1 == utf_ptr2char((char *)p)) {
break;
}
}
@@ -11770,14 +10958,14 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
for (; tail > head; tail = prev) {
prev = tail;
MB_PTR_BACK(head, prev);
- c1 = utf_ptr2char(prev);
+ c1 = utf_ptr2char((char *)prev);
if (mask == NULL) {
if (c1 > ' ' && c1 != 0xa0) {
break;
}
} else {
for (p = mask; *p != NUL; MB_PTR_ADV(p)) {
- if (c1 == utf_ptr2char(p)) {
+ if (c1 == utf_ptr2char((char *)p)) {
break;
}
}
@@ -11787,12 +10975,10 @@ static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
- rettv->vval.v_string = vim_strnsave(head, tail - head);
+ rettv->vval.v_string = (char *)vim_strnsave(head, tail - head);
}
-/*
- * "type(expr)" function
- */
+/// "type(expr)" function
static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = -1;
@@ -11824,9 +11010,7 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
}
-/*
- * "undofile(name)" function
- */
+/// "undofile(name)" function
static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
@@ -11839,15 +11023,13 @@ static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char *ffname = FullName_save(fname, true);
if (ffname != NULL) {
- rettv->vval.v_string = (char_u *)u_get_undo_file_name(ffname, false);
+ rettv->vval.v_string = u_get_undo_file_name(ffname, false);
}
xfree(ffname);
}
}
-/*
- * "undotree()" function
- */
+/// "undotree()" function
static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tv_dict_alloc_ret(rettv);
@@ -11865,24 +11047,20 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_list(dict, S_LEN("entries"), u_eval_tree(curbuf->b_u_oldhead));
}
-/*
- * "values(dict)" function
- */
+/// "values(dict)" function
static void f_values(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 1);
}
-/*
- * "virtcol(string)" function
- */
+/// "virtcol(string)" function
static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T vcol = 0;
pos_T *fp;
int fnum = curbuf->b_fnum;
- fp = var2fpos(&argvars[0], FALSE, &fnum);
+ fp = var2fpos(&argvars[0], false, &fnum, false);
if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
&& fnum == curbuf->b_fnum) {
// Limit the column to a valid value, getvvcol() doesn't check.
@@ -11901,9 +11079,7 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = vcol;
}
-/*
- * "visualmode()" function
- */
+/// "visualmode()" function
static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u str[2];
@@ -11911,7 +11087,7 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
str[0] = curbuf->b_visual_mode_eval;
str[1] = NUL;
- rettv->vval.v_string = vim_strsave(str);
+ rettv->vval.v_string = (char *)vim_strsave(str);
// A non-zero number or non-empty string argument: reset mode.
if (non_zero_arg(&argvars[0])) {
@@ -11919,12 +11095,10 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "wildmenumode()" function
- */
+/// "wildmenumode()" function
static void f_wildmenumode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (wild_menu_showing || ((State & CMDLINE) && pum_visible())) {
+ if (wild_menu_showing || ((State & MODE_CMDLINE) && pum_visible())) {
rettv->vval.v_number = 1;
}
}
@@ -11952,21 +11126,20 @@ static void f_win_gettype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[0].v_type != VAR_UNKNOWN) {
wp = find_win_by_nr_or_id(&argvars[0]);
if (wp == NULL) {
- rettv->vval.v_string = vim_strsave((char_u *)"unknown");
+ rettv->vval.v_string = (char *)vim_strsave((char_u *)"unknown");
return;
}
}
if (wp == aucmd_win) {
- rettv->vval.v_string = vim_strsave((char_u *)"autocmd");
+ rettv->vval.v_string = xstrdup("autocmd");
} else if (wp->w_p_pvw) {
- rettv->vval.v_string = vim_strsave((char_u *)"preview");
+ rettv->vval.v_string = xstrdup("preview");
} else if (wp->w_floating) {
- rettv->vval.v_string = vim_strsave((char_u *)"popup");
+ rettv->vval.v_string = xstrdup("popup");
} else if (wp == curwin && cmdwin_type != 0) {
- rettv->vval.v_string = vim_strsave((char_u *)"command");
+ rettv->vval.v_string = xstrdup("command");
} else if (bt_quickfix(wp->w_buffer)) {
- rettv->vval.v_string = vim_strsave((char_u *)(wp->w_llist_ref != NULL ?
- "loclist" : "quickfix"));
+ rettv->vval.v_string = xstrdup((wp->w_llist_ref != NULL ? "loclist" : "quickfix"));
}
}
@@ -11988,6 +11161,42 @@ static void f_win_id2win(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = win_id2win(argvars);
}
+/// "win_move_separator()" function
+static void f_win_move_separator(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ win_T *wp;
+ int offset;
+
+ rettv->vval.v_number = false;
+
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL || wp->w_floating) {
+ return;
+ }
+
+ offset = (int)tv_get_number(&argvars[1]);
+ win_drag_vsep_line(wp, offset);
+ rettv->vval.v_number = true;
+}
+
+/// "win_move_statusline()" function
+static void f_win_move_statusline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ win_T *wp;
+ int offset;
+
+ rettv->vval.v_number = false;
+
+ wp = find_win_by_nr_or_id(&argvars[0]);
+ if (wp == NULL || wp->w_floating) {
+ return;
+ }
+
+ offset = (int)tv_get_number(&argvars[1]);
+ win_drag_status_line(wp, offset);
+ rettv->vval.v_number = true;
+}
+
/// "winbufnr(nr)" function
static void f_winbufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -11999,9 +11208,7 @@ static void f_winbufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "wincol()" function
- */
+/// "wincol()" function
static void f_wincol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
validate_cursor();
@@ -12019,7 +11226,7 @@ static void f_winheight(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "winlayout()" function
+/// "winlayout()" function
static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tabpage_T *tp;
@@ -12038,18 +11245,14 @@ static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr)
get_framelayout(tp->tp_topframe, rettv->vval.v_list, true);
}
-/*
- * "winline()" function
- */
+/// "winline()" function
static void f_winline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
validate_cursor();
rettv->vval.v_number = curwin->w_wrow + 1;
}
-/*
- * "winnr()" function
- */
+/// "winnr()" function
static void f_winnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
@@ -12058,9 +11261,7 @@ static void f_winnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = nr;
}
-/*
- * "winrestcmd()" function
- */
+/// "winrestcmd()" function
static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
garray_T ga;
@@ -12087,9 +11288,7 @@ static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
}
-/*
- * "winrestview()" function
- */
+/// "winrestview()" function
static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *dict;
@@ -12140,9 +11339,7 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "winsaveview()" function
- */
+/// "winsaveview()" function
static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *dict;
@@ -12173,11 +11370,11 @@ static void f_winwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-// "windowsversion()" function
+/// "windowsversion()" function
static void f_windowsversion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (char_u *)xstrdup(windowsVersion);
+ rettv->vval.v_string = xstrdup(windowsVersion);
}
/// "wordcount()" function
@@ -12264,9 +11461,8 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
-/*
- * "xor(expr, expr)" function
- */
+
+/// "xor(expr, expr)" function
static void f_xor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)