Merge branch 'master' of github.com:ckelsel/neovim into vim-8.0.0101

This commit is contained in:
ckelsel
2017-10-09 21:17:15 +08:00
38 changed files with 723 additions and 326 deletions

View File

@@ -7,6 +7,10 @@ end_of_line = lf
insert_final_newline = true
charset = utf_8
[runtime/doc/*.txt]
indent_style = tab
indent_size = 8
[Makefile]
indent_style = tab
tab_width = 4

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
# Build/deps dir
/build/
/cmake-build-debug/
/dist/
/.deps/
/tmp/

View File

@@ -1,4 +1,6 @@
version: '{build}'
environment:
APPVEYOR_CACHE_ENTRY_ZIP_ARGS: "-t7z -m0=lzma -mx=9"
configuration:
- MINGW_64
- MINGW_32

View File

@@ -46,6 +46,7 @@ check_c_source_compiles("
int main(int argc, char** argv) {
gettext(\"foo\");
ngettext(\"foo\", \"bar\", 1);
bindtextdomain(\"foo\", \"bar\");
bind_textdomain_codeset(\"foo\", \"bar\");
textdomain(\"foo\");

View File

@@ -6267,11 +6267,11 @@ A jump table for the options with a short description can be found at |Q_op|.
when part of a command has been typed.
*'title'* *'notitle'*
'title' boolean (default off, on when title can be restored)
'title' boolean (default off)
global
When on, the title of the window will be set to the value of
'titlestring' (if it is not empty), or to:
filename [+=-] (path) - VIM
filename [+=-] (path) - NVIM
Where:
filename the name of the file being edited
- indicates the file cannot be modified, 'ma' off
@@ -6279,7 +6279,7 @@ A jump table for the options with a short description can be found at |Q_op|.
= indicates the file is read-only
=+ indicates the file is read-only and modified
(path) is the path of the file being edited
- VIM the server name |v:servername| or "VIM"
- NVIM the server name |v:servername| or "NVIM"
*'titlelen'*
'titlelen' number (default 85)
@@ -6295,11 +6295,10 @@ A jump table for the options with a short description can be found at |Q_op|.
'titlelen' is also used for the 'titlestring' option.
*'titleold'*
'titleold' string (default "Thanks for flying Vim")
'titleold' string (default "")
global
This option will be used for the window title when exiting Vim if the
original title cannot be restored. Only happens if 'title' is on or
'titlestring' is not empty.
If not empty, this option will be used to set the window title when
exiting. Only if 'title' is enabled.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'titlestring'*
@@ -6748,19 +6747,19 @@ A jump table for the options with a short description can be found at |Q_op|.
*'winhighlight'* *'winhl'*
'winhighlight' 'winhl' string (default empty)
local to window
Window-local highlights. Comma-delimited list of |group-name| pairs
"{hl-builtin}:{hl-group},..." where each {hl-builtin} is a group (from
|highlight-groups|) to be overridden by {hl-group} in the window where
this option was set. Only builting ui highlights are supported, not
syntax highlighting. For that purpose, use |:ownsyntax|.
Window-local highlights. Comma-delimited list of highlight
|group-name| pairs "{hl-builtin}:{hl},..." where each {hl-builtin} is
a built-in |highlight-groups| item to be overridden by {hl} group in
the window. Only built-in |highlight-groups| are supported, not
syntax highlighting (use |:ownsyntax| for that).
Most highlights occuring within the frame of a window are supported.
Highlights of vertical separators are determined by the window to the
left of the separator. The highlight of a tabpage in |tabline| is
determined by the last focused window in the tabpage. Highlights of
determine by the last-focused window of the tabpage. Highlights of
the popupmenu are determined by the current window. Highlights in the
message area are not overridable. Example for overriding the
backgrond color: >
message area cannot be overridden.
Example: show a different color for non-current windows: >
set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC
<
*'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'*

View File

@@ -280,6 +280,10 @@ other arguments if used).
|input()| and |inputdialog()| support user-defined cmdline highlighting.
Highlight groups:
|hl-ColorColumn|, |hl-CursorColumn|, |hl-CursorLine| are lower priority than
(overridden by) most other highlight groups.
==============================================================================
5. Missing legacy features *nvim-features-missing*

View File

@@ -939,6 +939,11 @@ if !exists("skip_vim_syntax_inits")
hi def link vimUserFunc Normal
hi def link vimVar Identifier
hi def link vimWarn WarningMsg
hi def link nvimAutoEvent vimAutoEvent
hi def link nvimHLGroup vimHLGroup
hi def link nvimMap vimMap
hi def link nvimUnmap vimUnmap
endif
" Current Syntax Variable: {{{2

View File

@@ -133,7 +133,7 @@ preprocess_patch() {
# Remove *.proto, Make*, gui_*, some if_*
local na_src='proto\|Make*\|gui_*\|if_lua\|if_mzsch\|if_olepp\|if_ole\|if_perl\|if_py\|if_ruby\|if_tcl\|if_xcmdsrv'
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%('${na_src}'\)@norm! d/\v(^diff)|%$
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%(testdir/\)\@<!\%('${na_src}'\)@norm! d/\v(^diff)|%$
' +w +q "$file"
# Remove channel.txt, netbeans.txt, os_*.txt, term.txt, todo.txt, version*.txt, tags

View File

@@ -242,39 +242,7 @@ static void push_call(UI *ui, char *name, Array args)
static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
{
Array args = ARRAY_DICT_INIT;
Dictionary hl = ARRAY_DICT_INIT;
if (attrs.bold) {
PUT(hl, "bold", BOOLEAN_OBJ(true));
}
if (attrs.underline) {
PUT(hl, "underline", BOOLEAN_OBJ(true));
}
if (attrs.undercurl) {
PUT(hl, "undercurl", BOOLEAN_OBJ(true));
}
if (attrs.italic) {
PUT(hl, "italic", BOOLEAN_OBJ(true));
}
if (attrs.reverse) {
PUT(hl, "reverse", BOOLEAN_OBJ(true));
}
if (attrs.foreground != -1) {
PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground));
}
if (attrs.background != -1) {
PUT(hl, "background", INTEGER_OBJ(attrs.background));
}
if (attrs.special != -1) {
PUT(hl, "special", INTEGER_OBJ(attrs.special));
}
Dictionary hl = hlattrs2dict(attrs);
ADD(args, DICTIONARY_OBJ(hl));
push_call(ui, "highlight_set", args);

View File

@@ -55,6 +55,47 @@ void nvim_command(String command, Error *err)
try_end(err);
}
/// Gets a highlight definition by name.
///
/// @param name Highlight group name
/// @param rgb Export RGB colors
/// @param[out] err Error details, if any
/// @return Highlight definition map
/// @see nvim_get_hl_by_id
Dictionary nvim_get_hl_by_name(String name, Boolean rgb, Error *err)
FUNC_API_SINCE(3)
{
Dictionary result = ARRAY_DICT_INIT;
int id = syn_name2id((const char_u *)name.data);
if (id == 0) {
api_set_error(err, kErrorTypeException, "Invalid highlight name: %s",
name.data);
return result;
}
result = nvim_get_hl_by_id(id, rgb, err);
return result;
}
/// Gets a highlight definition by id. |hlID()|
///
/// @param hl_id Highlight id as returned by |hlID()|
/// @param rgb Export RGB colors
/// @param[out] err Error details, if any
/// @return Highlight definition map
/// @see nvim_get_hl_by_name
Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Error *err)
FUNC_API_SINCE(3)
{
Dictionary dic = ARRAY_DICT_INIT;
if (syn_get_final_id((int)hl_id) == 0) {
api_set_error(err, kErrorTypeException, "Invalid highlight id: %d", hl_id);
return dic;
}
int attrcode = syn_id2attr((int)hl_id);
return hl_get_attr_by_id(attrcode, rgb, err);
}
/// Passes input keys to Nvim.
/// On VimL error: Does not fail, but updates v:errmsg.
///

View File

@@ -3069,8 +3069,8 @@ static bool ti_change(char_u *str, char_u **last)
/// Set current window title
void resettitle(void)
{
ui_call_set_title(cstr_as_string((char *)lasttitle));
ui_call_set_icon(cstr_as_string((char *)lasticon));
ui_call_set_title(cstr_as_string((char *)lasttitle));
ui_flush();
}

View File

@@ -762,7 +762,7 @@ bool vim_isIDc(int c)
}
/// Check that "c" is a keyword character:
/// Letters and characters from 'iskeyword' option for current buffer.
/// Letters and characters from 'iskeyword' option for the current buffer.
/// For multi-byte characters mb_get_class() is used (builtin rules).
///
/// @param c character to check

View File

@@ -6733,6 +6733,39 @@ static void prepare_assert_error(garray_T *gap)
}
}
// Append "str" to "gap", escaping unprintable characters.
// Changes NL to \n, CR to \r, etc.
static void ga_concat_esc(garray_T *gap, char_u *str)
{
char_u *p;
char_u buf[NUMBUFLEN];
if (str == NULL) {
ga_concat(gap, (char_u *)"NULL");
return;
}
for (p = str; *p != NUL; p++) {
switch (*p) {
case BS: ga_concat(gap, (char_u *)"\\b"); break;
case ESC: ga_concat(gap, (char_u *)"\\e"); break;
case FF: ga_concat(gap, (char_u *)"\\f"); break;
case NL: ga_concat(gap, (char_u *)"\\n"); break;
case TAB: ga_concat(gap, (char_u *)"\\t"); break;
case CAR: ga_concat(gap, (char_u *)"\\r"); break;
case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
default:
if (*p < ' ') {
vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
ga_concat(gap, buf);
} else {
ga_append(gap, *p);
}
break;
}
}
}
// Fill "gap" with information about an assert error.
static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
char_u *exp_str, typval_T *exp_tv,
@@ -6753,11 +6786,11 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
ga_concat(gap, (char_u *)"Expected ");
}
if (exp_str == NULL) {
tofree = (char_u *) encode_tv2string(exp_tv, NULL);
ga_concat(gap, tofree);
tofree = (char_u *)encode_tv2string(exp_tv, NULL);
ga_concat_esc(gap, tofree);
xfree(tofree);
} else {
ga_concat(gap, exp_str);
ga_concat_esc(gap, exp_str);
}
if (atype != ASSERT_NOTEQUAL) {
if (atype == ASSERT_MATCH) {
@@ -6768,7 +6801,7 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
ga_concat(gap, (char_u *)" but got ");
}
tofree = (char_u *)encode_tv2string(got_tv, NULL);
ga_concat(gap, tofree);
ga_concat_esc(gap, tofree);
xfree(tofree);
}
}
@@ -17495,7 +17528,7 @@ static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_dict_add_nr(dict, S_LEN("skipcol"), (varnumber_T)curwin->w_skipcol);
}
/// Writes list of strings to file
/// Write "list" of strings to file "fd".
///
/// @param fp File to write to.
/// @param[in] list List to write.

View File

@@ -868,20 +868,15 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, bool silent)
addlen = (int)STRLEN(str);
/*
* Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
*/
if (offset == 0 && addlen <= typebuf.tb_off) {
// Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
typebuf.tb_off -= addlen;
memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
}
/*
* Need to allocate a new buffer.
* In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
* characters. We add some extra room to avoid having to allocate too
* often.
*/
else {
} else {
// Need to allocate a new buffer.
// In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
// characters. We add some extra room to avoid having to allocate too
// often.
newoff = MAXMAPLEN + 4;
newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
if (newlen < 0) { /* string is getting too long */
@@ -1663,10 +1658,10 @@ static int vgetorpeek(int advance)
}
if (c != NUL && !got_int) {
if (advance) {
/* KeyTyped = FALSE; When the command that stuffed something
* was typed, behave like the stuffed command was typed.
* needed for CTRL-W CTRl-] to open a fold, for example. */
KeyStuffed = TRUE;
// KeyTyped = FALSE; When the command that stuffed something
// was typed, behave like the stuffed command was typed.
// needed for CTRL-W CTRL-] to open a fold, for example.
KeyStuffed = true;
}
if (typebuf.tb_no_abbr_cnt == 0)
typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */

View File

@@ -13,6 +13,7 @@
#else
# define _(x) ((char *)(x))
# define N_(x) x
# define ngettext(x, xs, n) ((n) == 1 ? (x) : (xs))
# define bindtextdomain(x, y) // empty
# define bind_textdomain_codeset(x, y) // empty
# define textdomain(x) // empty

View File

@@ -734,16 +734,20 @@ static int cin_ispreproc(char_u *s)
return FALSE;
}
/*
* Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
* continuation line of a preprocessor statement. Decrease "*lnump" to the
* start and return the line in "*pp".
*/
static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
/// Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
/// continuation line of a preprocessor statement. Decrease "*lnump" to the
/// start and return the line in "*pp".
/// Put the amount of indent in "*amount".
static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
{
char_u *line = *pp;
linenr_T lnum = *lnump;
int retval = FALSE;
int retval = false;
int candidate_amount = *amount;
if (*line != NUL && line[STRLEN(line) - 1] == '\\') {
candidate_amount = get_indent_lnum(lnum);
}
for (;; ) {
if (cin_ispreproc(line)) {
@@ -758,8 +762,12 @@ static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
break;
}
if (lnum != *lnump)
if (lnum != *lnump) {
*pp = ml_get(*lnump);
}
if (retval) {
*amount = candidate_amount;
}
return retval;
}
@@ -1994,10 +2002,12 @@ int get_c_indent(void)
amount = -1;
for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum) {
l = skipwhite(ml_get(lnum));
if (cin_nocode(l)) /* skip comment lines */
if (cin_nocode(l)) { // skip comment lines
continue;
if (cin_ispreproc_cont(&l, &lnum))
continue; /* ignore #define, #if, etc. */
}
if (cin_ispreproc_cont(&l, &lnum, &amount)) {
continue; // ignore #define, #if, etc.
}
curwin->w_cursor.lnum = lnum;
/* Skip a comment or raw string. XXX */
@@ -2353,15 +2363,14 @@ int get_c_indent(void)
* up with it.
*/
if (curwin->w_cursor.lnum <= ourscope) {
/* we reached end of scope:
* if looking for an enum or structure initialization
* go further back:
* if it is an initializer (enum xxx or xxx =), then
* don't add ind_continuation, otherwise it is a variable
* declaration:
* int x,
* here; <-- add ind_continuation
*/
// We reached end of scope:
// If looking for a enum or structure initialization
// go further back:
// If it is an initializer (enum xxx or xxx =), then
// don't add ind_continuation, otherwise it is a variable
// declaration:
// int x,
// here; <-- add ind_continuation
if (lookfor == LOOKFOR_ENUM_OR_INIT) {
if (curwin->w_cursor.lnum == 0
|| curwin->w_cursor.lnum
@@ -2389,11 +2398,12 @@ int get_c_indent(void)
continue;
}
/*
* Skip preprocessor directives and blank lines.
*/
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
//
// Skip preprocessor directives and blank lines.
//
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) {
continue;
}
if (cin_nocode(l))
continue;
@@ -2497,9 +2507,10 @@ int get_c_indent(void)
continue;
}
/* Skip preprocessor directives and blank lines. */
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
// Skip preprocessor directives and blank lines.
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) {
continue;
}
/* Finally the actual check for "namespace". */
if (cin_is_cpp_namespace(l)) {
@@ -2662,9 +2673,10 @@ int get_c_indent(void)
* unlocked it)
*/
l = get_cursor_line_ptr();
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)
|| cin_nocode(l))
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)
|| cin_nocode(l)) {
continue;
}
/*
* Are we at the start of a cpp base class declaration or
@@ -3309,11 +3321,12 @@ term_again:
break;
}
/*
* Skip preprocessor directives and blank lines.
*/
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
//
// Skip preprocessor directives and blank lines.
//
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) {
continue;
}
if (cin_nocode(l))
continue;
@@ -3405,10 +3418,11 @@ term_again:
while (curwin->w_cursor.lnum > 1) {
look = ml_get(--curwin->w_cursor.lnum);
if (!(cin_nocode(look) || cin_ispreproc_cont(
&look, &curwin->w_cursor.lnum)))
if (!(cin_nocode(look)
|| cin_ispreproc_cont(&look, &curwin->w_cursor.lnum, &amount))) {
break;
}
}
if (curwin->w_cursor.lnum > 0
&& cin_ends_in(look, (char_u *)"}", NULL))
break;

View File

@@ -649,6 +649,11 @@ void getout(int exitval)
/* Position the cursor again, the autocommands may have moved it */
ui_cursor_goto((int)Rows - 1, 0);
// Apply 'titleold'.
if (p_title && *p_titleold != NUL) {
ui_call_set_title(cstr_as_string((char *)p_titleold));
}
#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
iconv_end();
#endif

View File

@@ -2456,8 +2456,8 @@ did_set_string_option (
&& (options[opt_idx].flags & P_SECURE)) {
errmsg = e_secure;
} else if (((options[opt_idx].flags & P_NFNAME)
&& vim_strpbrk(*varp, (char_u *)(secure
? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
&& vim_strpbrk(*varp, (char_u *)(secure ? "/\\*?[|;&<>\r\n"
: "/\\*?[<>\r\n")) != NULL)
|| ((options[opt_idx].flags & P_NDNAME)
&& vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) {
// Check for a "normal" directory or file name in some options. Disallow a

View File

@@ -2501,7 +2501,7 @@ return {
no_mkrc=true,
vi_def=true,
varname='p_titleold',
defaults={if_true={vi=N_("Thanks for flying Vim")}}
defaults={if_true={vi=N_("")}}
},
{
full_name='titlestring',

View File

@@ -1690,6 +1690,9 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force)
if (strlen(fname) > (len - 1)) {
xstrlcpy(buf, fname, len); // truncate
#ifdef WIN32
slash_adjust(buf);
#endif
return FAIL;
}
@@ -1702,6 +1705,9 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force)
if (rv == FAIL) {
xstrlcpy(buf, fname, len); // something failed; use the filename
}
#ifdef WIN32
slash_adjust(buf);
#endif
return rv;
}
@@ -2196,11 +2202,11 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf,
// expand it if forced or not an absolute path
if (force || !path_is_absolute_path(fname)) {
if ((p = vim_strrchr(fname, '/')) != NULL) {
if ((p = vim_strrchr(fname, PATHSEP)) != NULL) {
// relative to root
if (p == fname) {
// only one path component
relative_directory[0] = '/';
relative_directory[0] = PATHSEP;
relative_directory[1] = NUL;
} else {
assert(p >= fname);

View File

@@ -2201,16 +2201,17 @@ win_line (
int change_end = -1; /* last col of changed area */
colnr_T trailcol = MAXCOL; /* start of trailing spaces */
int need_showbreak = false; // overlong line, skip first x chars
int line_attr = 0; /* attribute for the whole line */
matchitem_T *cur; /* points to the match list */
match_T *shl; /* points to search_hl or a match */
int shl_flag; /* flag to indicate whether search_hl
has been processed or not */
int prevcol_hl_flag; /* flag to indicate whether prevcol
equals startcol of search_hl or one
of the matches */
int prev_c = 0; /* previous Arabic character */
int prev_c1 = 0; /* first composing char for prev_c */
int line_attr = 0; // attribute for the whole line
int line_attr_low_priority = 0; // current line, lowest priority
matchitem_T *cur; // points to the match list
match_T *shl; // points to search_hl or a match
int shl_flag; // flag to indicate whether search_hl
// has been processed or not
int prevcol_hl_flag; // flag to indicate whether prevcol
// equals startcol of search_hl or one
// of the matches
int prev_c = 0; // previous Arabic character
int prev_c1 = 0; // first composing char for prev_c
int did_line_attr = 0;
bool search_attr_from_match = false; // if search_attr is from :match
@@ -2427,10 +2428,17 @@ win_line (
filler_lines = wp->w_topfill;
filler_todo = filler_lines;
/* If this line has a sign with line highlighting set line_attr. */
// 'cursorline' highlighting for the current window. Not when Visual mode is
// active, because it's not clear what is selected then.
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
&& !(wp == curwin && VIsual_active)) {
line_attr_low_priority = win_hl_attr(wp, HLF_CUL);
}
v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL);
if (v != 0)
line_attr = sign_get_attr((int)v, TRUE);
if (v != 0) {
line_attr = sign_get_attr((int)v, true);
}
// Highlight the current line in the quickfix window.
if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) {
@@ -2441,7 +2449,7 @@ win_line (
line_attr = hl_combine_attr(wp->w_hl_attr_normal, line_attr);
}
if (line_attr != 0) {
if (line_attr_low_priority || line_attr) {
area_highlighting = true;
}
@@ -2663,20 +2671,6 @@ win_line (
cur = cur->next;
}
/* Cursor line highlighting for 'cursorline' in the current window. Not
* when Visual mode is active, because it's not clear what is selected
* then. */
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
&& !(wp == curwin && VIsual_active)) {
if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer)
&& qf_current_entry(wp) == lnum) {
line_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), line_attr);
} else {
line_attr = win_hl_attr(wp, HLF_CUL);
}
area_highlighting = true;
}
off = (unsigned)(current_ScreenLine - ScreenLines);
col = 0;
if (wp->w_p_rl) {
@@ -3594,15 +3588,15 @@ win_line (
&& lcs_eol_one > 0) {
// Display a '$' after the line or highlight an extra
// character if the line break is included.
// For a diff line the highlighting continues after the
// "$".
if (diff_hlf == (hlf_T)0 && line_attr == 0) {
/* In virtualedit, visual selections may extend
* beyond end of line. */
// For a diff line the highlighting continues after the "$".
if (diff_hlf == (hlf_T)0
&& line_attr == 0
&& line_attr_low_priority == 0) {
// In virtualedit, visual selections may extend beyond end of line.
if (area_highlighting && virtual_active()
&& tocol != MAXCOL && vcol < tocol)
&& tocol != MAXCOL && vcol < tocol) {
n_extra = 0;
else {
} else {
p_extra = at_end_str;
n_extra = 1;
c_extra = NUL;
@@ -3661,7 +3655,7 @@ win_line (
(col < wp->w_width))) {
c = ' ';
ptr--; // put it back at the NUL
} else if ((diff_hlf != (hlf_T)0 || line_attr != 0)
} else if ((diff_hlf != (hlf_T)0 || line_attr_low_priority || line_attr)
&& (wp->w_p_rl
? (col >= 0)
: (col - boguscols < wp->w_width))) {
@@ -3673,7 +3667,8 @@ win_line (
did_line_attr++;
// don't do search HL for the rest of the line
if (line_attr != 0 && char_attr == search_attr && col > 0) {
if ((line_attr_low_priority || line_attr)
&& char_attr == search_attr && col > 0) {
char_attr = line_attr;
}
if (diff_hlf == HLF_TXD) {
@@ -4035,13 +4030,16 @@ win_line (
if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol
&& lnum != wp->w_cursor.lnum) {
vcol_save_attr = char_attr;
char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUC));
char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUC), char_attr);
} else if (draw_color_col && VCOL_HLC == *color_cols) {
vcol_save_attr = char_attr;
char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_MC));
char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), char_attr);
}
}
// Apply `line_attr_low_priority` now, so that everthing can override it.
char_attr = hl_combine_attr(line_attr_low_priority, char_attr);
/*
* Store character to be displayed.
* Skip characters that are left of the screen for 'nowrap'.

View File

@@ -42,6 +42,7 @@
#include "nvim/ui.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/api/private/helpers.h"
static bool did_syntax_onoff = false;
@@ -5567,8 +5568,10 @@ bool syntax_present(win_T *win)
static enum {
EXP_SUBCMD, /* expand ":syn" sub-commands */
EXP_CASE /* expand ":syn case" arguments */
EXP_SUBCMD, // expand ":syn" sub-commands
EXP_CASE, // expand ":syn case" arguments
EXP_SPELL, // expand ":syn spell" arguments
EXP_SYNC // expand ":syn sync" arguments
} expand_what;
/*
@@ -5612,6 +5615,10 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg)
xp->xp_context = EXPAND_NOTHING;
} else if (STRNICMP(arg, "case", p - arg) == 0) {
expand_what = EXP_CASE;
} else if (STRNICMP(arg, "spell", p - arg) == 0) {
expand_what = EXP_SPELL;
} else if (STRNICMP(arg, "sync", p - arg) == 0) {
expand_what = EXP_SYNC;
} else if (STRNICMP(arg, "keyword", p - arg) == 0
|| STRNICMP(arg, "region", p - arg) == 0
|| STRNICMP(arg, "match", p - arg) == 0
@@ -5624,17 +5631,33 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg)
}
}
static char *(case_args[]) = {"match", "ignore", NULL};
/*
* Function given to ExpandGeneric() to obtain the list syntax names for
* expansion.
*/
char_u *get_syntax_name(expand_T *xp, int idx)
{
if (expand_what == EXP_SUBCMD)
switch (expand_what) {
case EXP_SUBCMD:
return (char_u *)subcommands[idx].name;
case EXP_CASE: {
static char *case_args[] = { "match", "ignore", NULL };
return (char_u *)case_args[idx];
}
case EXP_SPELL: {
static char *spell_args[] =
{ "toplevel", "notoplevel", "default", NULL };
return (char_u *)spell_args[idx];
}
case EXP_SYNC: {
static char *sync_args[] =
{ "ccomment", "clear", "fromstart",
"linebreaks=", "linecont", "lines=", "match",
"maxlines=", "minlines=", "region", NULL };
return (char_u *)sync_args[idx];
}
}
return NULL;
}
@@ -6622,7 +6645,6 @@ do_highlight(char_u *line, int forceit, int init) {
syn_unadd_group();
} else {
if (is_normal_group) {
HL_TABLE()[idx].sg_attr = 0;
// Need to update all groups, because they might be using "bg" and/or
// "fg", which have been changed now.
highlight_attr_set_all();
@@ -6825,8 +6847,6 @@ int hl_combine_attr(int char_attr, int prim_attr)
if (char_aep != NULL) {
// Copy all attributes from char_aep to the new entry
new_en = *char_aep;
} else {
memset(&new_en, 0, sizeof(new_en));
}
spell_aep = syn_cterm_attr2entry(prim_attr);
@@ -6859,6 +6879,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
/// \note this function does not apply exclusively to cterm attr contrary
/// to what its name implies
/// \warn don't call it with attr 0 (i.e., the null attribute)
attrentry_T *syn_cterm_attr2entry(int attr)
{
attr -= ATTR_OFF;
@@ -7103,22 +7124,14 @@ syn_list_header(int did_header, int outlen, int id)
return newline;
}
/*
* Set the attribute numbers for a highlight group.
* Called after one of the attributes has changed.
*/
static void
set_hl_attr (
int idx /* index in array */
)
/// Set the attribute numbers for a highlight group.
/// Called after one of the attributes has changed.
/// @param idx corrected highlight index
static void set_hl_attr(int idx)
{
attrentry_T at_en = ATTRENTRY_INIT;
struct hl_group *sgp = HL_TABLE() + idx;
// The "Normal" group doesn't need an attribute number
if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) {
return;
}
at_en.cterm_ae_attr = sgp->sg_cterm;
at_en.cterm_fg_color = sgp->sg_cterm_fg;
@@ -8227,6 +8240,30 @@ RgbValue name_to_color(const uint8_t *name)
return -1;
}
/// Gets highlight description for id `attr_id` as a map.
Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err)
{
HlAttrs attrs = HLATTRS_INIT;
Dictionary dic = ARRAY_DICT_INIT;
if (attr_id == 0) {
goto end;
}
attrentry_T *aep = syn_cterm_attr2entry((int)attr_id);
if (!aep) {
api_set_error(err, kErrorTypeException,
"Invalid attribute id: %d", attr_id);
return dic;
}
attrs = attrentry2hlattrs(aep, rgb);
end:
return hlattrs2dict(attrs);
}
/**************************************
* End of Highlighting stuff *
**************************************/

View File

@@ -59,6 +59,7 @@ NEW_TESTS ?= \
test_matchadd_conceal.res \
test_matchadd_conceal_utf8.res \
test_mksession.res \
test_mksession_utf8.res \
test_nested_function.res \
test_normal.res \
test_quickfix.res \

View File

@@ -76,3 +76,11 @@ func Test_syntax_after_reload()
call assert_true(exists('g:gotit'))
call delete('Xsomefile')
endfunc
func Test_syntax_completion()
call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"syn spell default notoplevel toplevel', @:)
call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:)
endfunc

View File

@@ -288,7 +288,7 @@ static void terminfo_stop(UI *ui)
static void tui_terminal_start(UI *ui)
{
TUIData *data = ui->data;
data->print_attrs = EMPTY_ATTRS;
data->print_attrs = HLATTRS_INIT;
ugrid_init(&data->grid);
terminfo_start(ui);
update_size(ui);
@@ -628,7 +628,7 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
if (grid->bg == -1 && right == ui->width -1) {
// Background is set to the default color and the right edge matches the
// screen end, try to use terminal codes for clearing the requested area.
HlAttrs clear_attrs = EMPTY_ATTRS;
HlAttrs clear_attrs = HLATTRS_INIT;
clear_attrs.foreground = grid->fg;
clear_attrs.background = grid->bg;
update_attrs(ui, clear_attrs);
@@ -926,7 +926,7 @@ static void tui_scroll(UI *ui, Integer count)
cursor_goto(ui, grid->top, grid->left);
// also set default color attributes or some terminals can become funny
if (scroll_clears_to_current_colour) {
HlAttrs clear_attrs = EMPTY_ATTRS;
HlAttrs clear_attrs = HLATTRS_INIT;
clear_attrs.foreground = grid->fg;
clear_attrs.background = grid->bg;
update_attrs(ui, clear_attrs);

View File

@@ -16,7 +16,7 @@
void ugrid_init(UGrid *grid)
{
grid->attrs = EMPTY_ATTRS;
grid->attrs = HLATTRS_INIT;
grid->fg = grid->bg = -1;
grid->cells = NULL;
}
@@ -118,7 +118,7 @@ UCell *ugrid_put(UGrid *grid, uint8_t *text, size_t size)
static void clear_region(UGrid *grid, int top, int bot, int left, int right)
{
HlAttrs clear_attrs = EMPTY_ATTRS;
HlAttrs clear_attrs = HLATTRS_INIT;
clear_attrs.foreground = grid->fg;
clear_attrs.background = grid->bg;
UGRID_FOREACH_CELL(grid, top, bot, left, right, {

View File

@@ -21,8 +21,6 @@ struct ugrid {
UCell **cells;
};
#define EMPTY_ATTRS ((HlAttrs){ false, false, false, false, false, -1, -1, -1 })
#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \
do { \
for (int row = top; row <= bot; row++) { \

View File

@@ -166,6 +166,90 @@ void ui_event(char *name, Array args)
}
}
/// Converts an attrentry_T into an HlAttrs
///
/// @param[in] aep data to convert
/// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*'
HlAttrs attrentry2hlattrs(const attrentry_T *aep, bool use_rgb)
{
assert(aep);
HlAttrs attrs = HLATTRS_INIT;
int mask = 0;
mask = use_rgb ? aep->rgb_ae_attr : aep->cterm_ae_attr;
attrs.bold = mask & HL_BOLD;
attrs.underline = mask & HL_UNDERLINE;
attrs.undercurl = mask & HL_UNDERCURL;
attrs.italic = mask & HL_ITALIC;
attrs.reverse = mask & (HL_INVERSE | HL_STANDOUT);
if (use_rgb) {
if (aep->rgb_fg_color != -1) {
attrs.foreground = aep->rgb_fg_color;
}
if (aep->rgb_bg_color != -1) {
attrs.background = aep->rgb_bg_color;
}
if (aep->rgb_sp_color != -1) {
attrs.special = aep->rgb_sp_color;
}
} else {
if (cterm_normal_fg_color != aep->cterm_fg_color) {
attrs.foreground = aep->cterm_fg_color - 1;
}
if (cterm_normal_bg_color != aep->cterm_bg_color) {
attrs.background = aep->cterm_bg_color - 1;
}
}
return attrs;
}
Dictionary hlattrs2dict(HlAttrs attrs)
{
Dictionary hl = ARRAY_DICT_INIT;
if (attrs.bold) {
PUT(hl, "bold", BOOLEAN_OBJ(true));
}
if (attrs.underline) {
PUT(hl, "underline", BOOLEAN_OBJ(true));
}
if (attrs.undercurl) {
PUT(hl, "undercurl", BOOLEAN_OBJ(true));
}
if (attrs.italic) {
PUT(hl, "italic", BOOLEAN_OBJ(true));
}
if (attrs.reverse) {
PUT(hl, "reverse", BOOLEAN_OBJ(true));
}
if (attrs.foreground != -1) {
PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground));
}
if (attrs.background != -1) {
PUT(hl, "background", INTEGER_OBJ(attrs.background));
}
if (attrs.special != -1) {
PUT(hl, "special", INTEGER_OBJ(attrs.special));
}
return hl;
}
void ui_refresh(void)
{
if (!ui_active()) {
@@ -405,54 +489,20 @@ void ui_flush(void)
static void set_highlight_args(int attr_code)
{
HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1, -1 };
HlAttrs rgb_attrs = HLATTRS_INIT;
HlAttrs cterm_attrs = rgb_attrs;
if (attr_code == HL_NORMAL) {
goto end;
}
int rgb_mask = 0;
int cterm_mask = 0;
attrentry_T *aep = syn_cterm_attr2entry(attr_code);
if (!aep) {
goto end;
}
rgb_mask = aep->rgb_ae_attr;
cterm_mask = aep->cterm_ae_attr;
rgb_attrs.bold = rgb_mask & HL_BOLD;
rgb_attrs.underline = rgb_mask & HL_UNDERLINE;
rgb_attrs.undercurl = rgb_mask & HL_UNDERCURL;
rgb_attrs.italic = rgb_mask & HL_ITALIC;
rgb_attrs.reverse = rgb_mask & (HL_INVERSE | HL_STANDOUT);
cterm_attrs.bold = cterm_mask & HL_BOLD;
cterm_attrs.underline = cterm_mask & HL_UNDERLINE;
cterm_attrs.undercurl = cterm_mask & HL_UNDERCURL;
cterm_attrs.italic = cterm_mask & HL_ITALIC;
cterm_attrs.reverse = cterm_mask & (HL_INVERSE | HL_STANDOUT);
if (aep->rgb_fg_color != normal_fg) {
rgb_attrs.foreground = aep->rgb_fg_color;
}
if (aep->rgb_bg_color != normal_bg) {
rgb_attrs.background = aep->rgb_bg_color;
}
if (aep->rgb_sp_color != normal_sp) {
rgb_attrs.special = aep->rgb_sp_color;
}
if (cterm_normal_fg_color != aep->cterm_fg_color) {
cterm_attrs.foreground = aep->cterm_fg_color - 1;
}
if (cterm_normal_bg_color != aep->cterm_bg_color) {
cterm_attrs.background = aep->cterm_bg_color - 1;
}
rgb_attrs = attrentry2hlattrs(aep, true);
cterm_attrs = attrentry2hlattrs(aep, false);
end:
UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs));

View File

@@ -21,6 +21,9 @@ typedef struct {
int foreground, background, special;
} HlAttrs;
#define HLATTRS_INIT \
((HlAttrs){ false, false, false, false, false, -1, -1, -1 })
typedef struct ui_t UI;
struct ui_t {

View File

@@ -939,14 +939,14 @@ static const int included_patches[] = {
167,
// 166,
165,
// 164,
164,
// 163 NA
// 162 NA
// 161 NA
// 160,
159,
158,
// 157,
157,
156,
// 155,
// 154,
@@ -955,13 +955,13 @@ static const int included_patches[] = {
// 151,
150,
149,
// 148,
148,
147,
146,
// 145 NA
// 144 NA
143,
// 142,
142,
// 141,
// 140,
// 139 NA

View File

@@ -0,0 +1,103 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, nvim = helpers.clear, helpers.nvim
local Screen = require('test.functional.ui.screen')
local eq, eval = helpers.eq, helpers.eval
local command = helpers.command
local meths = helpers.meths
describe('highlight api',function()
local expected_rgb = {
background = Screen.colors.Yellow,
foreground = Screen.colors.Red,
special = Screen.colors.Blue,
bold = true,
}
local expected_cterm = {
background = 10,
underline = true,
}
local expected_rgb2 = {
background = Screen.colors.Yellow,
foreground = Screen.colors.Red,
special = Screen.colors.Blue,
bold = true,
italic = true,
reverse = true,
undercurl = true,
underline = true,
}
before_each(function()
clear()
command("hi NewHighlight cterm=underline ctermbg=green guifg=red guibg=yellow guisp=blue gui=bold")
end)
it("nvim_get_hl_by_id", function()
local hl_id = eval("hlID('NewHighlight')")
eq(expected_cterm, nvim("get_hl_by_id", hl_id, false))
hl_id = eval("hlID('NewHighlight')")
-- Test valid id.
eq(expected_rgb, nvim("get_hl_by_id", hl_id, true))
-- Test invalid id.
local err, emsg = pcall(meths.get_hl_by_id, 30000, false)
eq(false, err)
eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*'))
-- Test all highlight properties.
command('hi NewHighlight gui=underline,bold,undercurl,italic,reverse')
eq(expected_rgb2, nvim("get_hl_by_id", hl_id, true))
-- Test nil argument.
err, emsg = pcall(meths.get_hl_by_id, { nil }, false)
eq(false, err)
eq('Wrong type for argument 1, expecting Integer',
string.match(emsg, 'Wrong.*'))
-- Test 0 argument.
err, emsg = pcall(meths.get_hl_by_id, 0, false)
eq(false, err)
eq('Invalid highlight id: 0',
string.match(emsg, 'Invalid.*'))
-- Test -1 argument.
err, emsg = pcall(meths.get_hl_by_id, -1, false)
eq(false, err)
eq('Invalid highlight id: -1',
string.match(emsg, 'Invalid.*'))
end)
it("nvim_get_hl_by_name", function()
local expected_normal = { background = Screen.colors.Yellow,
foreground = Screen.colors.Red }
-- Test `Normal` default values.
eq({}, nvim("get_hl_by_name", 'Normal', true))
eq(expected_cterm, nvim("get_hl_by_name", 'NewHighlight', false))
eq(expected_rgb, nvim("get_hl_by_name", 'NewHighlight', true))
-- Test `Normal` modified values.
command('hi Normal guifg=red guibg=yellow')
eq(expected_normal, nvim("get_hl_by_name", 'Normal', true))
-- Test invalid name.
local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight', false)
eq(false, err)
eq('Invalid highlight name: unknown_highlight',
string.match(emsg, 'Invalid.*'))
-- Test nil argument.
err, emsg = pcall(meths.get_hl_by_name , { nil }, false)
eq(false, err)
eq('Wrong type for argument 1, expecting String',
string.match(emsg, 'Wrong.*'))
-- Test empty string argument.
err, emsg = pcall(meths.get_hl_by_name , '', false)
eq(false, err)
eq('Invalid highlight name: ',
string.match(emsg, 'Invalid.*'))
end)
end)

View File

@@ -0,0 +1,56 @@
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
local command = helpers.command
local iswin = helpers.iswin
describe('path collapse', function()
local targetdir
local expected_path
local function join_path(...)
local pathsep = (iswin() and '\\' or '/')
return table.concat({...}, pathsep)
end
before_each(function()
targetdir = join_path('test', 'functional', 'fixtures')
clear()
command('edit '..join_path(targetdir, 'tty-test.c'))
expected_path = eval('expand("%:p")')
end)
it('with /./ segment #7117', function()
command('edit '..join_path(targetdir, '.', 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ./ prefix #7117', function()
command('edit '..join_path('.', targetdir, 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ./ prefix, after directory change #7117', function()
command('edit '..join_path('.', targetdir, 'tty-test.c'))
command('cd test')
eq(expected_path, eval('expand("%:p")'))
end)
it('with /../ segment #7117', function()
command('edit '..join_path(targetdir, '..', 'fixtures', 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ../ and different starting directory #7117', function()
command('cd test')
command('edit '..join_path('..', targetdir, 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ./../ and different starting directory #7117', function()
command('cd test')
command('edit '..join_path('.', '..', targetdir, 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
end)

View File

@@ -4718,4 +4718,38 @@ describe('cindent', function()
JSEND
]=])
end)
it('line continuations in macros / vim-patch 8.0.0148', function()
insert_([=[
/* start of define */
{
}
#define AAA \
BBB\
CCC
#define CNT \
1 + \
2 + \
4
/* end of define */]=])
feed_command('set cino&')
feed_command('/start of define')
feed('=/end of define<cr>')
expect([=[
/* start of define */
{
}
#define AAA \
BBB\
CCC
#define CNT \
1 + \
2 + \
4
/* end of define */]=])
end)
end)

View File

@@ -10,6 +10,13 @@ local read_shada_file = shada_helpers.read_shada_file
local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compatibility.shada')
local mock_file_path = '/a/b/'
local mock_file_path2 = '/d/e/'
if helpers.iswin() then
mock_file_path = 'C:/a/'
mock_file_path2 = 'C:/d/'
end
describe('ShaDa forward compatibility support code', function()
before_each(reset)
after_each(function()
@@ -114,14 +121,14 @@ describe('ShaDa forward compatibility support code', function()
funcs.garbagecollect(1)
end)
for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006/a/b/c\161nA'},
{name='jump', mpack='\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002'},
{name='local mark', mpack='\010\001\018\131\162mX\195\161f\196\006/a/b/c\161na'},
{name='change', mpack='\011\001\015\130\162mX\195\161f\196\006/a/b/c'},
for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161nA'},
{name='jump', mpack='\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'},
{name='local mark', mpack='\010\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161na'},
{name='change', mpack='\011\001\015\130\162mX\195\161f\196\006' .. mock_file_path .. 'c'},
}) do
it('works with ' .. v.name .. ' item with BOOL unknown (mX) key value', function()
nvim_command('silent noautocmd edit /a/b/c')
eq('/a/b/c', funcs.bufname('%'))
nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c')
eq('' .. mock_file_path .. 'c', funcs.bufname('%'))
funcs.setline('.', {'1', '2', '3'})
wshada(v.mpack)
eq(0, exc_exec(sdrcmd(true)))
@@ -159,12 +166,12 @@ describe('ShaDa forward compatibility support code', function()
if v.name == 'global mark' or v.name == 'local mark' then
it('works with ' .. v.name .. ' item with <C-a> name', function()
nvim_command('silent noautocmd edit /a/b/c')
eq('/a/b/c', funcs.bufname('%'))
nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c')
eq('' .. mock_file_path .. 'c', funcs.bufname('%'))
funcs.setline('.', {'1', '2', '3'})
wshada(v.mpack:gsub('n.$', 'n\001')
.. v.mpack:gsub('n.$', 'n\002')
.. v.mpack:gsub('n.$', 'n\003'):gsub('/a/b/c', '/d/e/f'))
.. v.mpack:gsub('n.$', 'n\003'):gsub('' .. mock_file_path .. 'c', '' .. mock_file_path2 .. 'f'))
eq(0, exc_exec(sdrcmd(true)))
nvim_command('wshada ' .. shada_fname)
local found = 0
@@ -307,10 +314,10 @@ describe('ShaDa forward compatibility support code', function()
it('works with buffer list item with BOOL unknown (bX) key', function()
nvim_command('set shada+=%')
wshada('\009\000\016\145\130\161f\196\006/a/b/c\162bX\195')
wshada('\009\000\016\145\130\161f\196\006' .. mock_file_path .. 'c\162bX\195')
eq(0, exc_exec(sdrcmd()))
eq(2, funcs.bufnr('$'))
eq('/a/b/c', funcs.bufname(2))
eq('' .. mock_file_path .. 'c', funcs.bufname(2))
os.remove(shada_fname)
nvim_command('wshada ' .. shada_fname)
local found = false

View File

@@ -13,6 +13,11 @@ local read_shada_file = shada_helpers.read_shada_file
local wshada, sdrcmd, shada_fname =
get_shada_rw('Xtest-functional-shada-merging.shada')
local mock_file_path = '/a/b/'
if helpers.iswin() then
mock_file_path = 'C:/a/'
end
describe('ShaDa history merging code', function()
before_each(reset)
after_each(function()
@@ -512,9 +517,9 @@ describe('ShaDa marks support code', function()
it('uses last A mark with gt timestamp from instance when reading',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA')
wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
eq(0, exc_exec(sdrcmd()))
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
@@ -522,9 +527,9 @@ describe('ShaDa marks support code', function()
it('uses last A mark with gt timestamp from file when reading with !',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA')
wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
eq(0, exc_exec(sdrcmd(true)))
nvim_command('normal! `A')
eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
@@ -532,9 +537,9 @@ describe('ShaDa marks support code', function()
it('uses last A mark with eq timestamp from instance when reading',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/?\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
eq(0, exc_exec(sdrcmd()))
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
@@ -542,9 +547,9 @@ describe('ShaDa marks support code', function()
it('uses last A mark with gt timestamp from file when reading',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\002\018\131\162mX\195\161f\196\006/a/b/?\161nA')
wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
eq(0, exc_exec(sdrcmd()))
nvim_command('normal! `A')
eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
@@ -552,15 +557,15 @@ describe('ShaDa marks support code', function()
it('uses last A mark with gt timestamp from instance when writing',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA')
wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
eq(0, exc_exec('wshada ' .. shada_fname))
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 7 and v.value.f == '/a/b/-' then
if v.type == 7 and v.value.f == '' .. mock_file_path .. '-' then
found = found + 1
end
end
@@ -569,15 +574,15 @@ describe('ShaDa marks support code', function()
it('uses last A mark with eq timestamp from instance when writing',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/?\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
eq(0, exc_exec('wshada ' .. shada_fname))
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 7 and v.value.f == '/a/b/-' then
if v.type == 7 and v.value.f == mock_file_path .. '-' then
found = found + 1
end
end
@@ -586,15 +591,15 @@ describe('ShaDa marks support code', function()
it('uses last A mark with gt timestamp from file when writing',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA')
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\002\018\131\162mX\195\161f\196\006/a/b/?\161nA')
wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
eq(0, exc_exec('wshada ' .. shada_fname))
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 7 and v.value.f == '/a/b/?' then
if v.type == 7 and v.value.f == '' .. mock_file_path .. '?' then
found = found + 1
end
end
@@ -603,11 +608,11 @@ describe('ShaDa marks support code', function()
it('uses last a mark with gt timestamp from instance when reading',
function()
nvim_command('edit /a/b/-')
nvim_command('edit ' .. mock_file_path .. '-')
funcs.setline(1, {'-', '?'})
wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na')
wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
nvim_command('normal! `a')
eq('-', funcs.getline('.'))
@@ -615,11 +620,11 @@ describe('ShaDa marks support code', function()
it('uses last a mark with gt timestamp from file when reading with !',
function()
nvim_command('edit /a/b/-')
nvim_command('edit ' .. mock_file_path .. '-')
funcs.setline(1, {'-', '?'})
wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na')
wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd(true)))
nvim_command('normal! `a')
eq('?', funcs.getline('.'))
@@ -627,11 +632,11 @@ describe('ShaDa marks support code', function()
it('uses last a mark with eq timestamp from instance when reading',
function()
nvim_command('edit /a/b/-')
nvim_command('edit ' .. mock_file_path .. '-')
funcs.setline(1, {'-', '?'})
wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
wshada('\010\001\017\131\161l\002\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
nvim_command('normal! `a')
eq('-', funcs.getline('.'))
@@ -639,11 +644,11 @@ describe('ShaDa marks support code', function()
it('uses last a mark with gt timestamp from file when reading',
function()
nvim_command('edit /a/b/-')
nvim_command('edit ' .. mock_file_path .. '-')
funcs.setline(1, {'-', '?'})
wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
wshada('\010\002\017\131\161l\002\161f\196\006/a/b/-\161na')
wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
nvim_command('normal! `a')
eq('?', funcs.getline('.'))
@@ -651,17 +656,17 @@ describe('ShaDa marks support code', function()
it('uses last a mark with gt timestamp from instance when writing',
function()
nvim_command('edit /a/b/-')
nvim_command('edit ' .. mock_file_path .. '-')
funcs.setline(1, {'-', '?'})
wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na')
wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
nvim_command('normal! `a')
eq('-', funcs.getline('.'))
eq(0, exc_exec('wshada ' .. shada_fname))
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then
if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then
eq(true, v.value.l == 1 or v.value.l == nil)
found = found + 1
end
@@ -671,17 +676,17 @@ describe('ShaDa marks support code', function()
it('uses last a mark with eq timestamp from instance when writing',
function()
nvim_command('edit /a/b/-')
nvim_command('edit ' .. mock_file_path .. '-')
funcs.setline(1, {'-', '?'})
wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
wshada('\010\001\017\131\161l\002\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
nvim_command('normal! `a')
eq('-', funcs.getline('.'))
eq(0, exc_exec('wshada ' .. shada_fname))
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then
if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then
eq(true, v.value.l == 1 or v.value.l == nil)
found = found + 1
end
@@ -691,17 +696,17 @@ describe('ShaDa marks support code', function()
it('uses last a mark with gt timestamp from file when writing',
function()
nvim_command('edit /a/b/-')
nvim_command('edit ' .. mock_file_path .. '-')
funcs.setline(1, {'-', '?'})
wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na')
wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na')
eq(0, exc_exec(sdrcmd()))
wshada('\010\002\017\131\161l\002\161f\196\006/a/b/-\161na')
wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na')
nvim_command('normal! `a')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
eq(0, exc_exec('wshada ' .. shada_fname))
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then
if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then
eq(2, v.value.l)
found = found + 1
end
@@ -813,41 +818,41 @@ describe('ShaDa jumps support code', function()
end)
it('merges jumps when reading', function()
wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\002'
.. '\008\007\018\131\162mX\195\161f\196\006/a/b/e\161l\002')
wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002'
.. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002')
eq(0, exc_exec(sdrcmd()))
wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\003'
.. '\008\007\018\131\162mX\195\161f\196\006/a/b/f\161l\002')
wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003'
.. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002')
eq(0, exc_exec(sdrcmd()))
eq('', curbufmeths.get_name())
eq('\n'
.. ' jump line col file/text\n'
.. ' 6 2 0 /a/b/c\n'
.. ' 5 2 0 /a/b/d\n'
.. ' 4 3 0 /a/b/d\n'
.. ' 3 2 0 /a/b/e\n'
.. ' 2 2 0 /a/b/f\n'
.. ' 6 2 0 ' .. mock_file_path .. 'c\n'
.. ' 5 2 0 ' .. mock_file_path .. 'd\n'
.. ' 4 3 0 ' .. mock_file_path .. 'd\n'
.. ' 3 2 0 ' .. mock_file_path .. 'e\n'
.. ' 2 2 0 ' .. mock_file_path .. 'f\n'
.. ' 1 1 0 \n'
.. '>', redir_exec('jumps'))
end)
it('merges jumps when writing', function()
wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\002'
.. '\008\007\018\131\162mX\195\161f\196\006/a/b/e\161l\002')
wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002'
.. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002')
eq(0, exc_exec(sdrcmd()))
wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\003'
.. '\008\007\018\131\162mX\195\161f\196\006/a/b/f\161l\002')
wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'
.. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003'
.. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002')
eq(0, exc_exec('wshada ' .. shada_fname))
local jumps = {
{file='/a/b/c', line=2},
{file='/a/b/d', line=2},
{file='/a/b/d', line=3},
{file='/a/b/e', line=2},
{file='/a/b/f', line=2},
{file='' .. mock_file_path .. 'c', line=2},
{file='' .. mock_file_path .. 'd', line=2},
{file='' .. mock_file_path .. 'd', line=3},
{file='' .. mock_file_path .. 'e', line=2},
{file='' .. mock_file_path .. 'f', line=2},
}
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
@@ -864,9 +869,9 @@ describe('ShaDa jumps support code', function()
local jumps = {}
local shada = ''
for i = 1,100 do
shada = shada .. ('\008%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c'
shada = shada .. ('\008%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'
):format(i, i)
jumps[i] = {file='/a/b/c', line=i}
jumps[i] = {file='' .. mock_file_path .. 'c', line=i}
end
wshada(shada)
eq(0, exc_exec(sdrcmd()))
@@ -874,9 +879,9 @@ describe('ShaDa jumps support code', function()
for i = 1,101 do
local t = i * 2
shada = shada .. (
'\008\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c'
'\008\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'
):format(t, t)
jumps[(t > #jumps + 1) and (#jumps + 1) or t] = {file='/a/b/c', line=t}
jumps[(t > #jumps + 1) and (#jumps + 1) or t] = {file='' .. mock_file_path .. 'c', line=t}
end
wshada(shada)
eq(0, exc_exec('wshada ' .. shada_fname))
@@ -904,15 +909,15 @@ describe('ShaDa changes support code', function()
end)
it('merges changes when reading', function()
nvim_command('edit /a/b/c')
nvim_command('edit ' .. mock_file_path .. 'c')
nvim_command('keepjumps call setline(1, range(7))')
wshada('\011\001\018\131\162mX\195\161f\196\006/a/b/c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\002'
.. '\011\007\018\131\162mX\195\161f\196\006/a/b/c\161l\003')
wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'
.. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003')
eq(0, exc_exec(sdrcmd()))
wshada('\011\001\018\131\162mX\194\161f\196\006/a/b/c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\005'
.. '\011\008\018\131\162mX\195\161f\196\006/a/b/c\161l\004')
wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005'
.. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004')
eq(0, exc_exec(sdrcmd()))
eq('\n'
.. 'change line col text\n'
@@ -925,15 +930,15 @@ describe('ShaDa changes support code', function()
end)
it('merges changes when writing', function()
nvim_command('edit /a/b/c')
nvim_command('edit ' .. mock_file_path .. 'c')
nvim_command('keepjumps call setline(1, range(7))')
wshada('\011\001\018\131\162mX\195\161f\196\006/a/b/c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\002'
.. '\011\007\018\131\162mX\195\161f\196\006/a/b/c\161l\003')
wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'
.. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003')
eq(0, exc_exec(sdrcmd()))
wshada('\011\001\018\131\162mX\194\161f\196\006/a/b/c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\005'
.. '\011\008\018\131\162mX\195\161f\196\006/a/b/c\161l\004')
wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001'
.. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005'
.. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004')
eq(0, exc_exec('wshada ' .. shada_fname))
local changes = {
{line=1},
@@ -944,7 +949,7 @@ describe('ShaDa changes support code', function()
}
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 11 and v.value.f == '/a/b/c' then
if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then
found = found + 1
eq(changes[found].line, v.value.l or 1)
end
@@ -953,12 +958,12 @@ describe('ShaDa changes support code', function()
end)
it('merges JUMPLISTSIZE changes when writing', function()
nvim_command('edit /a/b/c')
nvim_command('edit ' .. mock_file_path .. 'c')
nvim_command('keepjumps call setline(1, range(202))')
local changes = {}
local shada = ''
for i = 1,100 do
shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c'
shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'
):format(i, i)
changes[i] = {line=i}
end
@@ -968,7 +973,7 @@ describe('ShaDa changes support code', function()
for i = 1,101 do
local t = i * 2
shada = shada .. (
'\011\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c'
'\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'
):format(t, t)
changes[(t > #changes + 1) and (#changes + 1) or t] = {line=t}
end
@@ -980,7 +985,7 @@ describe('ShaDa changes support code', function()
end
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 11 and v.value.f == '/a/b/c' then
if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then
found = found + 1
eq(changes[found].line, v.value.l)
end
@@ -990,20 +995,20 @@ describe('ShaDa changes support code', function()
it('merges JUMPLISTSIZE changes when writing, with new items between old',
function()
nvim_command('edit /a/b/c')
nvim_command('edit ' .. mock_file_path .. 'c')
nvim_command('keepjumps call setline(1, range(202))')
local shada = ''
for i = 1,101 do
local t = i * 2
shada = shada .. (
'\011\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c'
'\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'
):format(t, t)
end
wshada(shada)
eq(0, exc_exec(sdrcmd()))
shada = ''
for i = 1,100 do
shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c'
shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'
):format(i, i)
end
local changes = {}
@@ -1022,7 +1027,7 @@ describe('ShaDa changes support code', function()
end
local found = 0
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 11 and v.value.f == '/a/b/c' then
if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then
found = found + 1
eq(changes[found].line, v.value.l)
end
@@ -1030,3 +1035,5 @@ describe('ShaDa changes support code', function()
eq(found, 100)
end)
end)
-- vim: ts=2 sw=2

View File

@@ -518,7 +518,7 @@ describe("'listchars' highlight", function()
]])
feed_command('set cursorline')
screen:expect([[
{2:^>-------.}{1:abcd}{2:.}{1:Lorem}{4:>}|
{2:^>-------.}{1:abcd}{2:.}{1:Lorem}{3:>}|
{5:>-------.}abcd{5:*}{4:¬} |
{4:¬} |
{4:~ }|
@@ -526,7 +526,7 @@ describe("'listchars' highlight", function()
]])
feed('$')
screen:expect([[
{4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
{3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
{4:<} |
{4:<} |
{4:~ }|
@@ -607,7 +607,7 @@ describe("'listchars' highlight", function()
feed('<esc>$')
screen:expect([[
{4:<} |
{4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
{3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
{4:<} |
{4:~ }|
|

View File

@@ -5,6 +5,7 @@ local feed, command = helpers.feed, helpers.command
local insert = helpers.insert
local eq = helpers.eq
local eval = helpers.eval
local iswin = helpers.iswin
describe('screen', function()
local screen
@@ -119,9 +120,10 @@ describe('Screen', function()
end)
it('has correct default title with named file', function()
local expected = 'myfile (/mydir) - NVIM'
local expected = (iswin() and 'myfile (C:\\mydir) - NVIM'
or 'myfile (/mydir) - NVIM')
command('set title')
command('file /mydir/myfile')
command(iswin() and 'file C:\\mydir\\myfile' or 'file /mydir/myfile')
screen:expect(function()
eq(expected, screen.title)
end)

View File

@@ -481,6 +481,20 @@ describe('path.c', function()
eq('/tmp', ffi.string(buffer))
eq(OK, result)
end)
itp('expands "./" to the current directory #7117', function()
local force_expansion = 1
local result = vim_FullName('./unit-test-directory/test.file', buffer, length, force_expansion)
eq(OK, result)
eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
end)
itp('collapses "foo/../foo" to "foo" #7117', function()
local force_expansion = 1
local result = vim_FullName('unit-test-directory/../unit-test-directory/test.file', buffer, length, force_expansion)
eq(OK, result)
eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
end)
end)
describe('path_fix_case', function()