aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/CMakeLists.txt36
-rw-r--r--src/nvim/cursor_shape.h3
-rw-r--r--src/nvim/diff.h3
-rw-r--r--src/nvim/digraph.h3
-rw-r--r--src/nvim/edit.c4
-rw-r--r--src/nvim/eval.c23
-rw-r--r--src/nvim/eval.lua2
-rw-r--r--src/nvim/eval/decode.c24
-rw-r--r--src/nvim/eval/encode.c55
-rw-r--r--src/nvim/ex_cmds.h2
-rw-r--r--src/nvim/ex_getln.h3
-rw-r--r--src/nvim/file_search.h5
-rw-r--r--src/nvim/fold.h5
-rw-r--r--src/nvim/hardcopy.h4
-rw-r--r--src/nvim/if_cscope.h3
-rw-r--r--src/nvim/mark.h1
-rw-r--r--src/nvim/mbyte.c51
-rw-r--r--src/nvim/mbyte.h1
-rw-r--r--src/nvim/memfile_defs.h2
-rw-r--r--src/nvim/memline.h2
-rw-r--r--src/nvim/menu.h5
-rw-r--r--src/nvim/move.h2
-rw-r--r--src/nvim/ops.h2
-rw-r--r--src/nvim/os/env.c24
-rw-r--r--src/nvim/os/fs.c2
-rw-r--r--src/nvim/shada.c230
-rw-r--r--src/nvim/tag.c20
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_taglist.vim58
29 files changed, 235 insertions, 341 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 5a5ebc4415..1daa5dc3c4 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -41,7 +41,7 @@ set(LINT_SUPPRESS_URL "${LINT_SUPPRESS_URL_BASE}/errors.json")
set(LINT_PRG ${PROJECT_SOURCE_DIR}/src/clint.py)
set(DOWNLOAD_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/Download.cmake)
set(LINT_SUPPRESSES_ROOT ${PROJECT_BINARY_DIR}/errors)
-set(LINT_SUPPRESSES_URL "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/errors.tar.gz")
+set(LINT_SUPPRESSES_URL "${LINT_SUPPRESS_URL_BASE}/errors.tar.gz")
include_directories(${GENERATED_DIR})
include_directories(${CACHED_GENERATED_DIR})
@@ -424,27 +424,10 @@ function(get_test_target prefix sfile relative_path_var target_var)
endfunction()
set(NO_SINGLE_CHECK_HEADERS
- cursor_shape.h
- diff.h
- digraph.h
- ex_cmds.h
- ex_getln.h
- file_search.h
- fold.h
getchar.h
- hardcopy.h
- if_cscope.h
if_cscope_defs.h
- mark.h
- mbyte.h
- memfile_defs.h
- memline.h
- memline_defs.h
- menu.h
misc2.h
- move.h
msgpack_rpc/server.h
- ops.h
option.h
os/shell.h
os_unix.h
@@ -503,6 +486,20 @@ function(add_download output url allow_failure)
)
endfunction()
+include(ExternalProject)
+ExternalProject_Add(
+ clint-error-files
+ PREFIX "${LINT_SUPPRESSES_ROOT}"
+ URL "${LINT_SUPPRESSES_URL}"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ BUILD_IN_SOURCE 1
+ INSTALL_COMMAND
+ "${CMAKE_COMMAND}"
+ -DTARGET=${LINT_SUPPRESSES_ROOT}
+ -P "${PROJECT_SOURCE_DIR}/cmake/InstallClintErrors.cmake"
+)
+
add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL} off)
set(LINT_NVIM_REL_SOURCES)
@@ -511,14 +508,13 @@ foreach(sfile ${LINT_NVIM_SOURCES})
set(suppress_file ${LINT_SUPPRESSES_ROOT}/${suffix}.json)
set(suppress_url "${LINT_SUPPRESS_URL_BASE}/${suffix}.json")
set(rsfile src/nvim/${r})
- add_download(${suppress_file} ${suppress_url} on)
set(touch_file "${TOUCHES_DIR}/ran-clint-${suffix}")
add_custom_command(
OUTPUT ${touch_file}
COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} ${rsfile}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -E touch ${touch_file}
- DEPENDS ${LINT_PRG} ${sfile} ${suppress_file}
+ DEPENDS ${LINT_PRG} ${sfile} clint-error-files
)
list(APPEND LINT_TARGETS ${touch_file})
list(APPEND LINT_NVIM_REL_SOURCES ${rsfile})
diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h
index 0006ede31d..7cf65cba3c 100644
--- a/src/nvim/cursor_shape.h
+++ b/src/nvim/cursor_shape.h
@@ -1,6 +1,9 @@
#ifndef NVIM_CURSOR_SHAPE_H
#define NVIM_CURSOR_SHAPE_H
+#include "nvim/types.h"
+#include "nvim/api/private/defs.h"
+
/// struct to store values from 'guicursor' and 'mouseshape'
/// Indexes in shape_table[]
typedef enum {
diff --git a/src/nvim/diff.h b/src/nvim/diff.h
index f6cef1cafd..3624ce29bb 100644
--- a/src/nvim/diff.h
+++ b/src/nvim/diff.h
@@ -1,6 +1,9 @@
#ifndef NVIM_DIFF_H
#define NVIM_DIFF_H
+#include "nvim/pos.h"
+#include "nvim/ex_cmds_defs.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "diff.h.generated.h"
#endif
diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h
index b623969e08..1b73ccaf3f 100644
--- a/src/nvim/digraph.h
+++ b/src/nvim/digraph.h
@@ -1,6 +1,9 @@
#ifndef NVIM_DIGRAPH_H
#define NVIM_DIGRAPH_H
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "digraph.h.generated.h"
#endif
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index da09aed3dc..b35504908e 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -2109,7 +2109,7 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
xfree(wca);
- return ins_compl_add(IObuff, len, icase, fname, NULL, true, dir, flags,
+ return ins_compl_add(IObuff, len, icase, fname, NULL, false, dir, flags,
false);
}
return ins_compl_add(str, len, icase, fname, NULL, false, dir, flags, false);
@@ -2146,7 +2146,7 @@ static int ins_compl_add(char_u *const str, int len,
os_breakcheck();
#define FREE_CPTEXT(cptext, cptext_allocated) \
do { \
- if (cptext_allocated) { \
+ if (cptext != NULL && cptext_allocated) { \
for (size_t i = 0; i < CPT_COUNT; i++) { \
xfree(cptext[i]); \
} \
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 7ab07fe6a2..124d6acfe9 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8728,10 +8728,10 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
fold_count = foldedCount(curwin, lnum, &foldinfo);
if (fold_count > 0) {
- text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
- &foldinfo, buf);
- if (text == buf)
+ text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf);
+ if (text == buf) {
text = vim_strsave(text);
+ }
rettv->vval.v_string = text;
}
}
@@ -13416,14 +13416,12 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
q = (char *)path_tail((char_u *)p);
}
if (q > p && !path_is_absolute_path((const char_u *)buf)) {
- // Symlink is relative to directory of argument.
+ // Symlink is relative to directory of argument. Replace the
+ // symlink with the resolved name in the same directory.
const size_t p_len = strlen(p);
const size_t buf_len = strlen(buf);
- cpy = xmalloc(p_len + buf_len + 1);
- memcpy(cpy, p, p_len);
- memcpy(path_tail((char_u *)cpy), buf, buf_len + 1);
- xfree(p);
- p = cpy;
+ p = xrealloc(p, p_len + buf_len + 1);
+ memcpy(path_tail((char_u *)p), buf, buf_len + 1);
} else {
xfree(p);
p = xstrdup(buf);
@@ -16438,7 +16436,12 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- (void)get_tags(tv_list_alloc_ret(rettv), (char_u *)tag_pattern);
+ const char *fname = NULL;
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ fname = tv_get_string(&argvars[1]);
+ }
+ (void)get_tags(tv_list_alloc_ret(rettv), (char_u *)tag_pattern,
+ (char_u *)fname);
}
/*
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index e3c5981b32..6f876e2a96 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -300,7 +300,7 @@ return {
tabpagenr={args={0, 1}},
tabpagewinnr={args={1, 2}},
tagfiles={},
- taglist={args=1},
+ taglist={args={1, 2}},
tan={args=1, func="float_op_wrapper", data="&tan"},
tanh={args=1, func="float_op_wrapper", data="&tanh"},
tempname={},
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index fb31a65971..a7dc6b205d 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -222,8 +222,6 @@ static inline int json_decoder_pop(ValuesStackItem obj,
/// Parse JSON double-quoted string
///
-/// @param[in] conv Defines conversion necessary to convert UTF-8 string to
-/// &encoding.
/// @param[in] buf Buffer being converted.
/// @param[in] buf_len Length of the buffer.
/// @param[in,out] pp Pointer to the start of the string. Must point to '"'.
@@ -240,8 +238,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
/// value when decoder is restarted, otherwise unused.
///
/// @return OK in case of success, FAIL in case of error.
-static inline int parse_json_string(vimconv_T *const conv,
- const char *const buf, const size_t buf_len,
+static inline int parse_json_string(const char *const buf, const size_t buf_len,
const char **const pp,
ValuesStack *const stack,
ContainerStack *const container_stack,
@@ -416,20 +413,6 @@ static inline int parse_json_string(vimconv_T *const conv,
}
PUT_FST_IN_PAIR(fst_in_pair, str_end);
#undef PUT_FST_IN_PAIR
- if (conv->vc_type != CONV_NONE) {
- size_t str_len = (size_t) (str_end - str);
- char *const new_str = (char *) string_convert(conv, (char_u *) str,
- &str_len);
- if (new_str == NULL) {
- emsgf(_("E474: Failed to convert string \"%.*s\" from UTF-8"),
- (int) str_len, str);
- xfree(str);
- goto parse_json_string_fail;
- }
- xfree(str);
- str = new_str;
- str_end = new_str + str_len;
- }
if (hasnul) {
typval_T obj;
list_T *const list = tv_list_alloc();
@@ -626,9 +609,6 @@ int json_decode_string(const char *const buf, const size_t buf_len,
EMSG(_("E474: Attempt to decode a blank string"));
return FAIL;
}
- vimconv_T conv = { .vc_type = CONV_NONE };
- convert_setup(&conv, (char_u *) "utf-8", p_enc);
- conv.vc_fail = true;
int ret = OK;
ValuesStack stack = KV_INITIAL_VALUE;
ContainerStack container_stack = KV_INITIAL_VALUE;
@@ -774,7 +754,7 @@ json_decode_string_cycle_start:
break;
}
case '"': {
- if (parse_json_string(&conv, buf, buf_len, &p, &stack, &container_stack,
+ if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
&next_map_special, &didcomma, &didcolon)
== FAIL) {
// Error message was already given
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 26f9aaa27d..d74913a481 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -11,7 +11,7 @@
#include <math.h>
#include "nvim/eval/encode.h"
-#include "nvim/buffer_defs.h" // vimconv_T
+#include "nvim/buffer_defs.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/garray.h"
@@ -29,10 +29,6 @@
#define utf_ptr2char(b) utf_ptr2char((char_u *)b)
#define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b))
#define utf_char2len(b) ((size_t)utf_char2len(b))
-#define string_convert(a, b, c) \
- ((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
-#define convert_setup(vcp, from, to) \
- (convert_setup(vcp, (char_u *)from, (char_u *)to))
const char *const encode_special_var_names[] = {
[kSpecialVarNull] = "null",
@@ -537,17 +533,6 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
} \
} while (0)
-/// Last used p_enc value
-///
-/// Generic pointer: it is not used as a string, only pointer comparisons are
-/// performed. Must not be freed.
-static const void *last_p_enc = NULL;
-
-/// Conversion setup for converting from last_p_enc to UTF-8
-static vimconv_T p_enc_conv = {
- .vc_type = CONV_NONE,
-};
-
/// Escape sequences used in JSON
static const char escapes[][3] = {
[BS] = "\\b",
@@ -579,33 +564,15 @@ static inline int convert_to_json_string(garray_T *const gap,
} else {
size_t utf_len = len;
char *tofree = NULL;
- if (last_p_enc != (const void *) p_enc) {
- p_enc_conv.vc_type = CONV_NONE;
- convert_setup(&p_enc_conv, p_enc, "utf-8");
- p_enc_conv.vc_fail = true;
- last_p_enc = p_enc;
- }
- if (p_enc_conv.vc_type != CONV_NONE) {
- tofree = string_convert(&p_enc_conv, buf, &utf_len);
- if (tofree == NULL) {
- emsgf(_("E474: Failed to convert string \"%.*s\" to UTF-8"),
- utf_len, utf_buf);
- return FAIL;
- }
- utf_buf = tofree;
- }
size_t str_len = 0;
- // Encode character as \u0000 if
- // 1. It is an ASCII control character (0x0 .. 0x1F, 0x7F).
- // 2. &encoding is not UTF-8 and code point is above 0x7F.
- // 3. &encoding is UTF-8 and code point is not printable according to
- // utf_printable().
- // This is done to make it possible to :echo values when &encoding is not
- // UTF-8.
-#define ENCODE_RAW(p_enc_conv, ch) \
- (ch >= 0x20 && (p_enc_conv.vc_type == CONV_NONE \
- ? utf_printable(ch) \
- : ch < 0x7F))
+ // Encode character as \uNNNN if
+ // 1. It is an ASCII control character (0x0 .. 0x1F; 0x7F not
+ // utf_printable and thus not checked specially).
+ // 2. Code point is not printable according to utf_printable().
+ // This is done to make resulting values displayable on screen also not from
+ // Neovim.
+#define ENCODE_RAW(ch) \
+ (ch >= 0x20 && utf_printable(ch))
for (size_t i = 0; i < utf_len;) {
const int ch = utf_ptr2char(utf_buf + i);
const size_t shift = (ch == 0? 1: utf_ptr2len(utf_buf + i));
@@ -636,7 +603,7 @@ static inline int convert_to_json_string(garray_T *const gap,
utf_len - (i - shift), utf_buf + i - shift);
xfree(tofree);
return FAIL;
- } else if (ENCODE_RAW(p_enc_conv, ch)) {
+ } else if (ENCODE_RAW(ch)) {
str_len += shift;
} else {
str_len += ((sizeof("\\u1234") - 1)
@@ -666,7 +633,7 @@ static inline int convert_to_json_string(garray_T *const gap,
break;
}
default: {
- if (ENCODE_RAW(p_enc_conv, ch)) {
+ if (ENCODE_RAW(ch)) {
ga_concat_len(gap, utf_buf + i, shift);
} else if (ch < SURROGATE_FIRST_CHAR) {
ga_concat_len(gap, ((const char[]) {
diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h
index 65bbd8a99e..b564cde56c 100644
--- a/src/nvim/ex_cmds.h
+++ b/src/nvim/ex_cmds.h
@@ -6,6 +6,8 @@
#include "nvim/os/time.h"
#include "nvim/pos.h"
#include "nvim/eval/typval.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h"
// flags for do_ecmd()
#define ECMD_HIDE 0x01 // don't free the current buffer
diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h
index 5a1ca5213a..051564fbe1 100644
--- a/src/nvim/ex_getln.h
+++ b/src/nvim/ex_getln.h
@@ -3,6 +3,9 @@
#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/regexp_defs.h"
/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
#define WILD_FREE 1
diff --git a/src/nvim/file_search.h b/src/nvim/file_search.h
index 833a1a05ff..b128029123 100644
--- a/src/nvim/file_search.h
+++ b/src/nvim/file_search.h
@@ -1,6 +1,11 @@
#ifndef NVIM_FILE_SEARCH_H
#define NVIM_FILE_SEARCH_H
+#include <stdlib.h> // for size_t
+
+#include "nvim/types.h" // for char_u
+#include "nvim/globals.h" // for CdScope
+
/* Flags for find_file_*() functions. */
#define FINDFILE_FILE 0 /* only files */
#define FINDFILE_DIR 1 /* only directories */
diff --git a/src/nvim/fold.h b/src/nvim/fold.h
index 2ff10c0e91..f35b328fb1 100644
--- a/src/nvim/fold.h
+++ b/src/nvim/fold.h
@@ -1,7 +1,12 @@
#ifndef NVIM_FOLD_H
#define NVIM_FOLD_H
+#include <stdio.h>
+
#include "nvim/pos.h"
+#include "nvim/garray.h"
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
/*
* Info used to pass info about a fold from the fold-detection code to the
diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h
index 4ead8dd5d4..a70b20e6f5 100644
--- a/src/nvim/hardcopy.h
+++ b/src/nvim/hardcopy.h
@@ -2,6 +2,10 @@
#define NVIM_HARDCOPY_H
#include <stdint.h>
+#include <stdlib.h> // for size_t
+
+#include "nvim/types.h" // for char_u
+#include "nvim/ex_cmds_defs.h" // for exarg_T
/*
* Structure to hold printing color and font attributes.
diff --git a/src/nvim/if_cscope.h b/src/nvim/if_cscope.h
index 351d9caef6..e20462576a 100644
--- a/src/nvim/if_cscope.h
+++ b/src/nvim/if_cscope.h
@@ -1,6 +1,9 @@
#ifndef NVIM_IF_CSCOPE_H
#define NVIM_IF_CSCOPE_H
+#include "nvim/types.h" // for char_u and expand_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "if_cscope.h.generated.h"
#endif
diff --git a/src/nvim/mark.h b/src/nvim/mark.h
index efba9708db..c22a102926 100644
--- a/src/nvim/mark.h
+++ b/src/nvim/mark.h
@@ -8,6 +8,7 @@
#include "nvim/memory.h"
#include "nvim/pos.h"
#include "nvim/os/time.h"
+#include "nvim/ex_cmds_defs.h" // for exarg_T
/// Set fmark using given value
#define SET_FMARK(fmarkp_, mark_, fnum_) \
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index d96848754c..460528b85f 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -1304,6 +1304,7 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
# define CP_UTF8 65001 /* magic number from winnls.h */
#endif
+/// Reassigns `strw` to a new, allocated pointer to a UTF16 string.
int utf8_to_utf16(const char *str, WCHAR **strw)
FUNC_ATTR_NONNULL_ALL
{
@@ -1345,40 +1346,40 @@ int utf8_to_utf16(const char *str, WCHAR **strw)
return 0;
}
+/// Reassigns `str` to a new, allocated pointer to a UTF8 string.
int utf16_to_utf8(const WCHAR *strw, char **str)
FUNC_ATTR_NONNULL_ALL
{
// Compute the space required to store the string as UTF-8.
- ssize_t utf8_len = WideCharToMultiByte(CP_UTF8,
- 0,
- strw,
- -1,
- NULL,
- 0,
- NULL,
- NULL);
+ DWORD utf8_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ strw,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
if (utf8_len == 0) {
return GetLastError();
}
- ssize_t buf_sz = utf8_len * sizeof(char);
- char *buf = xmalloc(buf_sz);
- char *pos = buf;
+ *str = xmalloc(utf8_len);
- // Convert string to UTF-8.
- int r = WideCharToMultiByte(CP_UTF8,
- 0,
- strw,
- -1,
- pos,
- utf8_len,
- NULL,
- NULL);
- assert(r == utf8_len);
- if (r != utf8_len) {
- EMSG2("WideCharToMultiByte failed: %d", r);
- }
- *str = pos;
+ // Convert to UTF-8.
+ utf8_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ strw,
+ -1,
+ *str,
+ utf8_len,
+ NULL,
+ NULL);
+ if (utf8_len == 0) {
+ free(*str);
+ *str = NULL;
+ return GetLastError();
+ }
+ (*str)[utf8_len] = '\0';
return 0;
}
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index 3565202466..ad9e38004c 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -7,6 +7,7 @@
#include "nvim/iconv.h"
#include "nvim/func_attr.h"
#include "nvim/os/os_defs.h" // For WCHAR, indirect
+#include "nvim/types.h" // for char_u
/*
* Return byte length of character that starts with byte "b".
diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h
index cc71e1a7ff..b3c2f3564c 100644
--- a/src/nvim/memfile_defs.h
+++ b/src/nvim/memfile_defs.h
@@ -3,8 +3,10 @@
#include <stdint.h>
#include <stdbool.h>
+#include <stdlib.h>
#include "nvim/types.h"
+#include "nvim/pos.h"
/// A block number.
///
diff --git a/src/nvim/memline.h b/src/nvim/memline.h
index f84e86fea0..a239c6a031 100644
--- a/src/nvim/memline.h
+++ b/src/nvim/memline.h
@@ -2,6 +2,8 @@
#define NVIM_MEMLINE_H
#include "nvim/types.h"
+#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T
+#include "nvim/buffer_defs.h" // for buf_T
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "memline.h.generated.h"
diff --git a/src/nvim/menu.h b/src/nvim/menu.h
index 3266c511b4..a84b7d812e 100644
--- a/src/nvim/menu.h
+++ b/src/nvim/menu.h
@@ -1,6 +1,11 @@
#ifndef NVIM_MENU_H
#define NVIM_MENU_H
+#include <stdbool.h> // for bool
+
+#include "nvim/types.h" // for char_u and expand_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+
/* Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode */
#define MENU_INDEX_INVALID -1
#define MENU_INDEX_NORMAL 0
diff --git a/src/nvim/move.h b/src/nvim/move.h
index 3f3bf70929..00fbcc580f 100644
--- a/src/nvim/move.h
+++ b/src/nvim/move.h
@@ -2,6 +2,8 @@
#define NVIM_MOVE_H
#include <stdbool.h>
+#include "nvim/buffer_defs.h"
+#include "nvim/pos.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "move.h.generated.h"
diff --git a/src/nvim/ops.h b/src/nvim/ops.h
index 13d0142343..a8867e02ea 100644
--- a/src/nvim/ops.h
+++ b/src/nvim/ops.h
@@ -8,6 +8,8 @@
#include "nvim/types.h"
#include "nvim/eval/typval.h"
#include "nvim/os/time.h"
+#include "nvim/normal.h" // for MotionType and oparg_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
typedef int (*Indenter)(void);
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 839e0d1b51..12c2da6152 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -118,7 +118,6 @@ char *os_getenvname_at_index(size_t index)
return name;
}
-
/// Get the process ID of the Neovim process.
///
/// @return the process ID.
@@ -145,10 +144,27 @@ void os_get_hostname(char *hostname, size_t size)
} else {
xstrlcpy(hostname, vutsname.nodename, size);
}
+#elif defined(WIN32)
+ WCHAR host_utf16[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD host_wsize = sizeof(host_utf16) / sizeof(host_utf16[0]);
+ if (GetComputerNameW(host_utf16, &host_wsize) == 0) {
+ *hostname = '\0';
+ DWORD err = GetLastError();
+ EMSG2("GetComputerNameW failed: %d", err);
+ return;
+ }
+ host_utf16[host_wsize] = '\0';
+
+ char *host_utf8;
+ int conversion_result = utf16_to_utf8(host_utf16, &host_utf8);
+ if (conversion_result != 0) {
+ EMSG2("utf16_to_utf8 failed: %d", conversion_result);
+ return;
+ }
+ xstrlcpy(hostname, host_utf8, size);
+ xfree(host_utf8);
#else
- // TODO(unknown): Implement this for windows.
- // See the implementation used in vim:
- // https://code.google.com/p/vim/source/browse/src/os_win32.c?r=6b69d8dde19e32909f4ee3a6337e6a2ecfbb6f72#2899
+ EMSG("os_get_hostname failed: missing uname()");
*hostname = '\0';
#endif
}
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 3833a43f5f..c33e1140e8 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -1009,7 +1009,7 @@ char *os_resolve_shortcut(const char *fname)
WCHAR *p;
const int conversion_result = utf8_to_utf16(fname, &p);
if (conversion_result != 0) {
- EMSG2("utf8_to_utf16 failed: %s", uv_strerror(conversion_result));
+ EMSG2("utf8_to_utf16 failed: %d", conversion_result);
}
if (p != NULL) {
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index c7b95958e0..8c5d6dff65 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -73,15 +73,10 @@ KHASH_SET_INIT_STR(strset)
(vim_rename((char_u *)a, (char_u *)b))
#define mb_strnicmp(a, b, c) \
(mb_strnicmp((char_u *)a, (char_u *)b, c))
-#define has_non_ascii(a) (has_non_ascii((char_u *)a))
-#define string_convert(a, b, c) \
- ((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
#define path_shorten_fname_if_possible(b) \
((char *)path_shorten_fname_if_possible((char_u *)b))
#define buflist_new(ffname, sfname, ...) \
(buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
-#define convert_setup(vcp, from, to) \
- (convert_setup(vcp, (char_u *)from, (char_u *)to))
#define os_isdir(f) (os_isdir((char_u *) f))
#define regtilde(s, m) ((char *) regtilde((char_u *) s, m))
#define path_tail_with_sep(f) ((char *) path_tail_with_sep((char_u *)f))
@@ -413,8 +408,6 @@ typedef struct sd_read_def {
const char *error; ///< Error message in case of error.
uintmax_t fpos; ///< Current position (amount of bytes read since
///< reader structure initialization). May overflow.
- vimconv_T sd_conv; ///< Structure used for converting encodings of some
- ///< items.
} ShaDaReadDef;
struct sd_write_def;
@@ -435,8 +428,6 @@ typedef struct sd_write_def {
ShaDaWriteCloser close; ///< Close function.
void *cookie; ///< Data describing object written to.
const char *error; ///< Error message in case of error.
- vimconv_T sd_conv; ///< Structure used for converting encodings of some
- ///< items.
} ShaDaWriteDef;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -803,7 +794,7 @@ static int open_shada_file_for_reading(const char *const fname,
return error;
}
- convert_setup(&sd_reader->sd_conv, "utf-8", p_enc);
+ assert(STRCMP(p_enc, "utf-8") == 0);
return 0;
}
@@ -1899,127 +1890,24 @@ shada_pack_entry_error:
}
#undef PACK_STRING
-/// Write single ShaDa entry, converting it if needed
+/// Write single ShaDa entry and free it afterwards
///
-/// @warning Frees entry after packing.
+/// Will not free if entry could not be freed.
///
/// @param[in] packer Packer used to write entry.
-/// @param[in] sd_conv Conversion definitions.
-/// @param[in] entry Entry written. If entry.can_free_entry is false then
-/// it assumes that entry was not converted, otherwise it
-/// is assumed that entry was already converted.
+/// @param[in] entry Entry written.
/// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no
/// restrictions.
-static ShaDaWriteResult shada_pack_encoded_entry(msgpack_packer *const packer,
- const vimconv_T *const sd_conv,
- PossiblyFreedShadaEntry entry,
- const size_t max_kbyte)
- FUNC_ATTR_NONNULL_ALL
+static inline ShaDaWriteResult shada_pack_pfreed_entry(
+ msgpack_packer *const packer, PossiblyFreedShadaEntry entry,
+ const size_t max_kbyte)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
+ ret = shada_pack_entry(packer, entry.data, max_kbyte);
if (entry.can_free_entry) {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
shada_free_shada_entry(&entry.data);
- return ret;
- }
-#define RUN_WITH_CONVERTED_STRING(cstr, code) \
- do { \
- bool did_convert = false; \
- if (sd_conv->vc_type != CONV_NONE && has_non_ascii((cstr))) { \
- char *const converted_string = string_convert(sd_conv, (cstr), NULL); \
- if (converted_string != NULL) { \
- (cstr) = converted_string; \
- did_convert = true; \
- } \
- } \
- code \
- if (did_convert) { \
- xfree((cstr)); \
- } \
- } while (0)
- switch (entry.data.type) {
- case kSDItemUnknown:
- case kSDItemMissing: {
- assert(false);
- }
- case kSDItemSearchPattern: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.search_pattern.pat, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemHistoryEntry: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.history_item.string, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemSubString: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.sub_string.sub, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemVariable: {
- if (sd_conv->vc_type != CONV_NONE) {
- typval_T tgttv;
- var_item_copy(sd_conv, &entry.data.data.global_var.value, &tgttv,
- true, 0);
- tv_clear(&entry.data.data.global_var.value);
- entry.data.data.global_var.value = tgttv;
- }
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- break;
- }
- case kSDItemRegister: {
- bool did_convert = false;
- if (sd_conv->vc_type != CONV_NONE) {
- size_t first_non_ascii = 0;
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- if (has_non_ascii(entry.data.data.reg.contents[i])) {
- first_non_ascii = i;
- did_convert = true;
- break;
- }
- }
- if (did_convert) {
- entry.data.data.reg.contents =
- xmemdup(entry.data.data.reg.contents,
- (entry.data.data.reg.contents_size
- * sizeof(entry.data.data.reg.contents[0])));
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- if (i >= first_non_ascii) {
- entry.data.data.reg.contents[i] = get_converted_string(
- sd_conv,
- entry.data.data.reg.contents[i],
- strlen(entry.data.data.reg.contents[i]));
- } else {
- entry.data.data.reg.contents[i] =
- xstrdup(entry.data.data.reg.contents[i]);
- }
- }
- }
- }
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- if (did_convert) {
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- xfree(entry.data.data.reg.contents[i]);
- }
- xfree(entry.data.data.reg.contents);
- }
- break;
- }
- case kSDItemHeader:
- case kSDItemGlobalMark:
- case kSDItemJump:
- case kSDItemBufferList:
- case kSDItemLocalMark:
- case kSDItemChange: {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- break;
- }
}
-#undef RUN_WITH_CONVERTED_STRING
return ret;
}
@@ -2556,11 +2444,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
break;
}
typval_T tgttv;
- if (sd_writer->sd_conv.vc_type != CONV_NONE) {
- var_item_copy(&sd_writer->sd_conv, &vartv, &tgttv, true, 0);
- } else {
- tv_copy(&vartv, &tgttv);
- }
+ tv_copy(&vartv, &tgttv);
ShaDaWriteResult spe_ret;
if ((spe_ret = shada_pack_entry(packer, (ShadaEntry) {
.type = kSDItemVariable,
@@ -2811,9 +2695,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
do { \
for (size_t i_ = 0; i_ < ARRAY_SIZE(wms_array); i_++) { \
if (wms_array[i_].data.type != kSDItemMissing) { \
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, \
- wms_array[i_], \
- max_kbyte) == kSDWriteFailed) { \
+ if (shada_pack_pfreed_entry(packer, wms_array[i_], max_kbyte) \
+ == kSDWriteFailed) { \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
@@ -2823,8 +2706,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
PACK_WMS_ARRAY(wms->global_marks);
PACK_WMS_ARRAY(wms->registers);
for (size_t i = 0; i < wms->jumps_size; i++) {
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms->jumps[i],
- max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, wms->jumps[i], max_kbyte)
+ == kSDWriteFailed) {
ret = kSDWriteFailed;
goto shada_write_exit;
}
@@ -2832,8 +2715,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
#define PACK_WMS_ENTRY(wms_entry) \
do { \
if (wms_entry.data.type != kSDItemMissing) { \
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms_entry, \
- max_kbyte) == kSDWriteFailed) { \
+ if (shada_pack_pfreed_entry(packer, wms_entry, max_kbyte) \
+ == kSDWriteFailed) { \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
@@ -2860,9 +2743,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
for (size_t i = 0; i < file_markss_to_dump; i++) {
PACK_WMS_ARRAY(all_file_markss[i]->marks);
for (size_t j = 0; j < all_file_markss[i]->changes_size; j++) {
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv,
- all_file_markss[i]->changes[j],
- max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, all_file_markss[i]->changes[j],
+ max_kbyte) == kSDWriteFailed) {
ret = kSDWriteFailed;
goto shada_write_exit;
}
@@ -2886,8 +2768,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (dump_one_history[i]) {
hms_insert_whole_neovim_history(&wms->hms[i]);
HMS_ITER(&wms->hms[i], cur_entry, {
- if (shada_pack_encoded_entry(
- packer, &sd_writer->sd_conv, (PossiblyFreedShadaEntry) {
+ if (shada_pack_pfreed_entry(
+ packer, (PossiblyFreedShadaEntry) {
.data = cur_entry->data,
.can_free_entry = cur_entry->can_free_entry,
}, max_kbyte) == kSDWriteFailed) {
@@ -3038,8 +2920,6 @@ shada_write_file_nomerge: {}
verbose_leave();
}
- convert_setup(&sd_writer.sd_conv, p_enc, "utf-8");
-
const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge
? NULL
: &sd_reader));
@@ -3327,29 +3207,6 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
return kSDReadStatusSuccess;
}
-/// Convert or copy and return a string
-///
-/// @param[in] sd_conv Conversion definition.
-/// @param[in] str String to convert.
-/// @param[in] len String length.
-///
-/// @return [allocated] converted string or copy of the original string.
-static inline char *get_converted_string(const vimconv_T *const sd_conv,
- const char *const str,
- const size_t len)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (!has_non_ascii_len(str, len)) {
- return xmemdupz(str, len);
- }
- size_t new_len = len;
- char *const new_str = string_convert(sd_conv, str, &new_len);
- if (new_str == NULL) {
- return xmemdupz(str, len);
- }
- return new_str;
-}
-
#define READERR(entry_name, error_desc) \
RERR "Error while reading ShaDa file: " \
entry_name " entry at position %" PRIu64 " " \
@@ -3427,10 +3284,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
sizeof(*unpacked.data.via.map.ptr)); \
ad_ga.ga_len++; \
}
-#define CONVERTED(str, len) ( \
- sd_reader->sd_conv.vc_type != CONV_NONE \
- ? get_converted_string(&sd_reader->sd_conv, (str), (len)) \
- : xmemdupz((str), (len)))
+#define CONVERTED(str, len) (xmemdupz((str), (len)))
#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
#define SET_ADDITIONAL_DATA(tgt, name) \
do { \
@@ -3803,30 +3657,14 @@ shada_read_next_item_start:
(char) unpacked.data.via.array.ptr[2].via.u64;
}
size_t strsize;
- if (sd_reader->sd_conv.vc_type == CONV_NONE
- || !has_non_ascii_len(unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size)) {
-shada_read_next_item_hist_no_conv:
- strsize = (
- unpacked.data.via.array.ptr[1].via.bin.size
- + 1 // Zero byte
- + 1); // Separator character
- entry->data.history_item.string = xmalloc(strsize);
- memcpy(entry->data.history_item.string,
- unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size);
- } else {
- size_t len = unpacked.data.via.array.ptr[1].via.bin.size;
- char *const converted = string_convert(
- &sd_reader->sd_conv, unpacked.data.via.array.ptr[1].via.bin.ptr,
- &len);
- if (converted != NULL) {
- strsize = len + 2;
- entry->data.history_item.string = xrealloc(converted, strsize);
- } else {
- goto shada_read_next_item_hist_no_conv;
- }
- }
+ strsize = (
+ unpacked.data.via.array.ptr[1].via.bin.size
+ + 1 // Zero byte
+ + 1); // Separator character
+ entry->data.history_item.string = xmalloc(strsize);
+ memcpy(entry->data.history_item.string,
+ unpacked.data.via.array.ptr[1].via.bin.ptr,
+ unpacked.data.via.array.ptr[1].via.bin.size);
entry->data.history_item.string[strsize - 2] = 0;
entry->data.history_item.string[strsize - 1] =
entry->data.history_item.sep;
@@ -3859,16 +3697,6 @@ shada_read_next_item_hist_no_conv:
"be converted to the VimL value")), initial_fpos);
goto shada_read_next_item_error;
}
- if (sd_reader->sd_conv.vc_type != CONV_NONE) {
- typval_T tgttv;
- var_item_copy(&sd_reader->sd_conv,
- &entry->data.global_var.value,
- &tgttv,
- true,
- 0);
- tv_clear(&entry->data.global_var.value);
- entry->data.global_var.value = tgttv;
- }
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
entry->data.global_var.additional_elements,
"variable");
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index b812dd2ffd..f01b8b8ab1 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -1847,14 +1847,14 @@ parse_line:
}
}
} else {
-#define TAG_SEP 0x01
+#define TAG_SEP 0x02
size_t tag_fname_len = STRLEN(tag_fname);
// Save the tag in a buffer.
- // Use 0x01 to separate fields (Can't use NUL, because the
+ // Use 0x02 to separate fields (Can't use NUL, because the
// hash key is terminated by NUL).
- // Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
- // other tag: <mtt><tag_fname><NUL><NUL><lbuf>
- // without Emacs tags: <mtt><tag_fname><NUL><lbuf>
+ // Emacs tag: <mtt><tag_fname><0x02><ebuf><0x02><lbuf><NUL>
+ // other tag: <mtt><tag_fname><0x02><0x02><lbuf><NUL>
+ // without Emacs tags: <mtt><tag_fname><0x02><lbuf><NUL>
// Here <mtt> is the "mtt" value plus 1 to avoid NUL.
len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3;
mfp = xmalloc(sizeof(char_u) + len + 1);
@@ -2797,11 +2797,9 @@ add_tag_field (
return retval;
}
-/*
- * Add the tags matching the specified pattern to the list "list"
- * as a dictionary
- */
-int get_tags(list_T *list, char_u *pat)
+/// Add the tags matching the specified pattern "pat" to the list "list"
+/// as a dictionary. Use "buf_fname" for priority, unless NULL.
+int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
{
int num_matches, i, ret;
char_u **matches, *p;
@@ -2811,7 +2809,7 @@ int get_tags(list_T *list, char_u *pat)
bool is_static;
ret = find_tags(pat, &num_matches, &matches,
- TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
+ TAG_REGEXP | TAG_NOIC, (int)MAXCOL, buf_fname);
if (ret == OK && num_matches > 0) {
for (i = 0; i < num_matches; ++i) {
int parse_result = parse_match(matches[i], &tp);
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index baf49b7ff7..99d9835996 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -26,6 +26,7 @@ source test_tabline.vim
" source test_tabpage.vim
source test_tagcase.vim
source test_tagjump.vim
+source test_taglist.vim
source test_true_false.vim
source test_unlet.vim
source test_utf8.vim
diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim
new file mode 100644
index 0000000000..2d1557ebd9
--- /dev/null
+++ b/src/nvim/testdir/test_taglist.vim
@@ -0,0 +1,58 @@
+" test 'taglist' function
+
+func Test_taglist()
+ call writefile([
+ \ "FFoo\tXfoo\t1",
+ \ "FBar\tXfoo\t2",
+ \ "BFoo\tXbar\t1",
+ \ "BBar\tXbar\t2"
+ \ ], 'Xtags')
+ set tags=Xtags
+ split Xtext
+
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo"), {i, v -> v.name}))
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xtext"), {i, v -> v.name}))
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name}))
+ call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name}))
+
+ call delete('Xtags')
+ bwipe
+endfunc
+
+func Test_taglist_native_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "\x0c",
+ \ "src/os_unix.c,13491",
+ \ "set_signals(\x7f1335,32699",
+ \ "reset_signals(\x7f1407,34136",
+ \ ], 'Xtags')
+
+ set tags=Xtags
+
+ call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+ \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+ call delete('Xtags')
+endfunc
+
+func Test_taglist_ctags_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "\x0c",
+ \ "src/os_unix.c,13491",
+ \ "set_signals(void)\x7fset_signals\x011335,32699",
+ \ "reset_signals(void)\x7freset_signals\x011407,34136",
+ \ ], 'Xtags')
+
+ set tags=Xtags
+
+ call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+ \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+ call delete('Xtags')
+endfunc