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 insert_final_newline = true
charset = utf_8 charset = utf_8
[runtime/doc/*.txt]
indent_style = tab
indent_size = 8
[Makefile] [Makefile]
indent_style = tab indent_style = tab
tab_width = 4 tab_width = 4

1
.gitignore vendored
View File

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

View File

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

View File

@@ -46,6 +46,7 @@ check_c_source_compiles("
int main(int argc, char** argv) { int main(int argc, char** argv) {
gettext(\"foo\"); gettext(\"foo\");
ngettext(\"foo\", \"bar\", 1);
bindtextdomain(\"foo\", \"bar\"); bindtextdomain(\"foo\", \"bar\");
bind_textdomain_codeset(\"foo\", \"bar\"); bind_textdomain_codeset(\"foo\", \"bar\");
textdomain(\"foo\"); 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. when part of a command has been typed.
*'title'* *'notitle'* *'title'* *'notitle'*
'title' boolean (default off, on when title can be restored) 'title' boolean (default off)
global global
When on, the title of the window will be set to the value of When on, the title of the window will be set to the value of
'titlestring' (if it is not empty), or to: 'titlestring' (if it is not empty), or to:
filename [+=-] (path) - VIM filename [+=-] (path) - NVIM
Where: Where:
filename the name of the file being edited filename the name of the file being edited
- indicates the file cannot be modified, 'ma' off - 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
=+ indicates the file is read-only and modified =+ indicates the file is read-only and modified
(path) is the path of the file being edited (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'*
'titlelen' number (default 85) '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. 'titlelen' is also used for the 'titlestring' option.
*'titleold'* *'titleold'*
'titleold' string (default "Thanks for flying Vim") 'titleold' string (default "")
global global
This option will be used for the window title when exiting Vim if the If not empty, this option will be used to set the window title when
original title cannot be restored. Only happens if 'title' is on or exiting. Only if 'title' is enabled.
'titlestring' is not empty.
This option cannot be set from a |modeline| or in the |sandbox|, for This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons. security reasons.
*'titlestring'* *'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'*
'winhighlight' 'winhl' string (default empty) 'winhighlight' 'winhl' string (default empty)
local to window local to window
Window-local highlights. Comma-delimited list of |group-name| pairs Window-local highlights. Comma-delimited list of highlight
"{hl-builtin}:{hl-group},..." where each {hl-builtin} is a group (from |group-name| pairs "{hl-builtin}:{hl},..." where each {hl-builtin} is
|highlight-groups|) to be overridden by {hl-group} in the window where a built-in |highlight-groups| item to be overridden by {hl} group in
this option was set. Only builting ui highlights are supported, not the window. Only built-in |highlight-groups| are supported, not
syntax highlighting. For that purpose, use |:ownsyntax|. 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 Highlights of vertical separators are determined by the window to the
left of the separator. The highlight of a tabpage in |tabline| is 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 the popupmenu are determined by the current window. Highlights in the
message area are not overridable. Example for overriding the message area cannot be overridden.
backgrond color: >
Example: show a different color for non-current windows: >
set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC
< <
*'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'* *'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'*

View File

@@ -280,6 +280,10 @@ other arguments if used).
|input()| and |inputdialog()| support user-defined cmdline highlighting. |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* 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 vimUserFunc Normal
hi def link vimVar Identifier hi def link vimVar Identifier
hi def link vimWarn WarningMsg 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 endif
" Current Syntax Variable: {{{2 " Current Syntax Variable: {{{2

View File

@@ -133,7 +133,7 @@ preprocess_patch() {
# Remove *.proto, Make*, gui_*, some if_* # 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' 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" ' +w +q "$file"
# Remove channel.txt, netbeans.txt, os_*.txt, term.txt, todo.txt, version*.txt, tags # 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) static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
{ {
Array args = ARRAY_DICT_INIT; Array args = ARRAY_DICT_INIT;
Dictionary hl = ARRAY_DICT_INIT; Dictionary hl = hlattrs2dict(attrs);
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));
}
ADD(args, DICTIONARY_OBJ(hl)); ADD(args, DICTIONARY_OBJ(hl));
push_call(ui, "highlight_set", args); push_call(ui, "highlight_set", args);

View File

@@ -55,6 +55,47 @@ void nvim_command(String command, Error *err)
try_end(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. /// Passes input keys to Nvim.
/// On VimL error: Does not fail, but updates v:errmsg. /// 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 /// Set current window title
void resettitle(void) void resettitle(void)
{ {
ui_call_set_title(cstr_as_string((char *)lasttitle));
ui_call_set_icon(cstr_as_string((char *)lasticon)); ui_call_set_icon(cstr_as_string((char *)lasticon));
ui_call_set_title(cstr_as_string((char *)lasttitle));
ui_flush(); ui_flush();
} }

View File

@@ -762,7 +762,7 @@ bool vim_isIDc(int c)
} }
/// Check that "c" is a keyword character: /// 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). /// For multi-byte characters mb_get_class() is used (builtin rules).
/// ///
/// @param c character to check /// @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. // Fill "gap" with information about an assert error.
static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
char_u *exp_str, typval_T *exp_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 "); ga_concat(gap, (char_u *)"Expected ");
} }
if (exp_str == NULL) { if (exp_str == NULL) {
tofree = (char_u *) encode_tv2string(exp_tv, NULL); tofree = (char_u *)encode_tv2string(exp_tv, NULL);
ga_concat(gap, tofree); ga_concat_esc(gap, tofree);
xfree(tofree); xfree(tofree);
} else { } else {
ga_concat(gap, exp_str); ga_concat_esc(gap, exp_str);
} }
if (atype != ASSERT_NOTEQUAL) { if (atype != ASSERT_NOTEQUAL) {
if (atype == ASSERT_MATCH) { 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 "); ga_concat(gap, (char_u *)" but got ");
} }
tofree = (char_u *)encode_tv2string(got_tv, NULL); tofree = (char_u *)encode_tv2string(got_tv, NULL);
ga_concat(gap, tofree); ga_concat_esc(gap, tofree);
xfree(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); 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 fp File to write to.
/// @param[in] list List to write. /// @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); 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) { 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; typebuf.tb_off -= addlen;
memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen); memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
} } else {
/* // Need to allocate a new buffer.
* Need to allocate a new buffer. // In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
* 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
* characters. We add some extra room to avoid having to allocate too // often.
* often.
*/
else {
newoff = MAXMAPLEN + 4; newoff = MAXMAPLEN + 4;
newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4); newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
if (newlen < 0) { /* string is getting too long */ if (newlen < 0) { /* string is getting too long */
@@ -1663,10 +1658,10 @@ static int vgetorpeek(int advance)
} }
if (c != NUL && !got_int) { if (c != NUL && !got_int) {
if (advance) { if (advance) {
/* KeyTyped = FALSE; When the command that stuffed something // KeyTyped = FALSE; When the command that stuffed something
* was typed, behave like the stuffed command was typed. // was typed, behave like the stuffed command was typed.
* needed for CTRL-W CTRl-] to open a fold, for example. */ // needed for CTRL-W CTRL-] to open a fold, for example.
KeyStuffed = TRUE; KeyStuffed = true;
} }
if (typebuf.tb_no_abbr_cnt == 0) if (typebuf.tb_no_abbr_cnt == 0)
typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */ typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */

View File

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

View File

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

View File

@@ -649,6 +649,11 @@ void getout(int exitval)
/* Position the cursor again, the autocommands may have moved it */ /* Position the cursor again, the autocommands may have moved it */
ui_cursor_goto((int)Rows - 1, 0); 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) #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
iconv_end(); iconv_end();
#endif #endif

View File

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

View File

@@ -2501,7 +2501,7 @@ return {
no_mkrc=true, no_mkrc=true,
vi_def=true, vi_def=true,
varname='p_titleold', varname='p_titleold',
defaults={if_true={vi=N_("Thanks for flying Vim")}} defaults={if_true={vi=N_("")}}
}, },
{ {
full_name='titlestring', 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)) { if (strlen(fname) > (len - 1)) {
xstrlcpy(buf, fname, len); // truncate xstrlcpy(buf, fname, len); // truncate
#ifdef WIN32
slash_adjust(buf);
#endif
return FAIL; return FAIL;
} }
@@ -1702,6 +1705,9 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force)
if (rv == FAIL) { if (rv == FAIL) {
xstrlcpy(buf, fname, len); // something failed; use the filename xstrlcpy(buf, fname, len); // something failed; use the filename
} }
#ifdef WIN32
slash_adjust(buf);
#endif
return rv; 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 // expand it if forced or not an absolute path
if (force || !path_is_absolute_path(fname)) { if (force || !path_is_absolute_path(fname)) {
if ((p = vim_strrchr(fname, '/')) != NULL) { if ((p = vim_strrchr(fname, PATHSEP)) != NULL) {
// relative to root // relative to root
if (p == fname) { if (p == fname) {
// only one path component // only one path component
relative_directory[0] = '/'; relative_directory[0] = PATHSEP;
relative_directory[1] = NUL; relative_directory[1] = NUL;
} else { } else {
assert(p >= fname); assert(p >= fname);

View File

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

View File

@@ -42,6 +42,7 @@
#include "nvim/ui.h" #include "nvim/ui.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/os/time.h" #include "nvim/os/time.h"
#include "nvim/api/private/helpers.h"
static bool did_syntax_onoff = false; static bool did_syntax_onoff = false;
@@ -5567,8 +5568,10 @@ bool syntax_present(win_T *win)
static enum { static enum {
EXP_SUBCMD, /* expand ":syn" sub-commands */ EXP_SUBCMD, // expand ":syn" sub-commands
EXP_CASE /* expand ":syn case" arguments */ EXP_CASE, // expand ":syn case" arguments
EXP_SPELL, // expand ":syn spell" arguments
EXP_SYNC // expand ":syn sync" arguments
} expand_what; } expand_what;
/* /*
@@ -5612,6 +5615,10 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg)
xp->xp_context = EXPAND_NOTHING; xp->xp_context = EXPAND_NOTHING;
} else if (STRNICMP(arg, "case", p - arg) == 0) { } else if (STRNICMP(arg, "case", p - arg) == 0) {
expand_what = EXP_CASE; 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 } else if (STRNICMP(arg, "keyword", p - arg) == 0
|| STRNICMP(arg, "region", p - arg) == 0 || STRNICMP(arg, "region", p - arg) == 0
|| STRNICMP(arg, "match", 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 * Function given to ExpandGeneric() to obtain the list syntax names for
* expansion. * expansion.
*/ */
char_u *get_syntax_name(expand_T *xp, int idx) 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; return (char_u *)subcommands[idx].name;
case EXP_CASE: {
static char *case_args[] = { "match", "ignore", NULL };
return (char_u *)case_args[idx]; 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(); syn_unadd_group();
} else { } else {
if (is_normal_group) { if (is_normal_group) {
HL_TABLE()[idx].sg_attr = 0;
// Need to update all groups, because they might be using "bg" and/or // Need to update all groups, because they might be using "bg" and/or
// "fg", which have been changed now. // "fg", which have been changed now.
highlight_attr_set_all(); highlight_attr_set_all();
@@ -6825,8 +6847,6 @@ int hl_combine_attr(int char_attr, int prim_attr)
if (char_aep != NULL) { if (char_aep != NULL) {
// Copy all attributes from char_aep to the new entry // Copy all attributes from char_aep to the new entry
new_en = *char_aep; new_en = *char_aep;
} else {
memset(&new_en, 0, sizeof(new_en));
} }
spell_aep = syn_cterm_attr2entry(prim_attr); 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 /// \note this function does not apply exclusively to cterm attr contrary
/// to what its name implies /// 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) attrentry_T *syn_cterm_attr2entry(int attr)
{ {
attr -= ATTR_OFF; attr -= ATTR_OFF;
@@ -7103,22 +7124,14 @@ syn_list_header(int did_header, int outlen, int id)
return newline; return newline;
} }
/* /// Set the attribute numbers for a highlight group.
* Set the attribute numbers for a highlight group. /// Called after one of the attributes has changed.
* Called after one of the attributes has changed. /// @param idx corrected highlight index
*/ static void set_hl_attr(int idx)
static void
set_hl_attr (
int idx /* index in array */
)
{ {
attrentry_T at_en = ATTRENTRY_INIT; attrentry_T at_en = ATTRENTRY_INIT;
struct hl_group *sgp = HL_TABLE() + idx; 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_ae_attr = sgp->sg_cterm;
at_en.cterm_fg_color = sgp->sg_cterm_fg; at_en.cterm_fg_color = sgp->sg_cterm_fg;
@@ -8227,6 +8240,30 @@ RgbValue name_to_color(const uint8_t *name)
return -1; 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 * * End of Highlighting stuff *
**************************************/ **************************************/

View File

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

View File

@@ -76,3 +76,11 @@ func Test_syntax_after_reload()
call assert_true(exists('g:gotit')) call assert_true(exists('g:gotit'))
call delete('Xsomefile') call delete('Xsomefile')
endfunc 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) static void tui_terminal_start(UI *ui)
{ {
TUIData *data = ui->data; TUIData *data = ui->data;
data->print_attrs = EMPTY_ATTRS; data->print_attrs = HLATTRS_INIT;
ugrid_init(&data->grid); ugrid_init(&data->grid);
terminfo_start(ui); terminfo_start(ui);
update_size(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) { if (grid->bg == -1 && right == ui->width -1) {
// Background is set to the default color and the right edge matches the // 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. // 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.foreground = grid->fg;
clear_attrs.background = grid->bg; clear_attrs.background = grid->bg;
update_attrs(ui, clear_attrs); update_attrs(ui, clear_attrs);
@@ -926,7 +926,7 @@ static void tui_scroll(UI *ui, Integer count)
cursor_goto(ui, grid->top, grid->left); cursor_goto(ui, grid->top, grid->left);
// also set default color attributes or some terminals can become funny // also set default color attributes or some terminals can become funny
if (scroll_clears_to_current_colour) { if (scroll_clears_to_current_colour) {
HlAttrs clear_attrs = EMPTY_ATTRS; HlAttrs clear_attrs = HLATTRS_INIT;
clear_attrs.foreground = grid->fg; clear_attrs.foreground = grid->fg;
clear_attrs.background = grid->bg; clear_attrs.background = grid->bg;
update_attrs(ui, clear_attrs); update_attrs(ui, clear_attrs);

View File

@@ -16,7 +16,7 @@
void ugrid_init(UGrid *grid) void ugrid_init(UGrid *grid)
{ {
grid->attrs = EMPTY_ATTRS; grid->attrs = HLATTRS_INIT;
grid->fg = grid->bg = -1; grid->fg = grid->bg = -1;
grid->cells = NULL; 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) 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.foreground = grid->fg;
clear_attrs.background = grid->bg; clear_attrs.background = grid->bg;
UGRID_FOREACH_CELL(grid, top, bot, left, right, { UGRID_FOREACH_CELL(grid, top, bot, left, right, {

View File

@@ -21,8 +21,6 @@ struct ugrid {
UCell **cells; UCell **cells;
}; };
#define EMPTY_ATTRS ((HlAttrs){ false, false, false, false, false, -1, -1, -1 })
#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \ #define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \
do { \ do { \
for (int row = top; row <= bot; row++) { \ 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) void ui_refresh(void)
{ {
if (!ui_active()) { if (!ui_active()) {
@@ -405,54 +489,20 @@ void ui_flush(void)
static void set_highlight_args(int attr_code) 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; HlAttrs cterm_attrs = rgb_attrs;
if (attr_code == HL_NORMAL) { if (attr_code == HL_NORMAL) {
goto end; goto end;
} }
int rgb_mask = 0;
int cterm_mask = 0;
attrentry_T *aep = syn_cterm_attr2entry(attr_code); attrentry_T *aep = syn_cterm_attr2entry(attr_code);
if (!aep) { if (!aep) {
goto end; goto end;
} }
rgb_mask = aep->rgb_ae_attr; rgb_attrs = attrentry2hlattrs(aep, true);
cterm_mask = aep->cterm_ae_attr; cterm_attrs = attrentry2hlattrs(aep, false);
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;
}
end: end:
UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs)); UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs));

View File

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

View File

@@ -939,14 +939,14 @@ static const int included_patches[] = {
167, 167,
// 166, // 166,
165, 165,
// 164, 164,
// 163 NA // 163 NA
// 162 NA // 162 NA
// 161 NA // 161 NA
// 160, // 160,
159, 159,
158, 158,
// 157, 157,
156, 156,
// 155, // 155,
// 154, // 154,
@@ -955,13 +955,13 @@ static const int included_patches[] = {
// 151, // 151,
150, 150,
149, 149,
// 148, 148,
147, 147,
146, 146,
// 145 NA // 145 NA
// 144 NA // 144 NA
143, 143,
// 142, 142,
// 141, // 141,
// 140, // 140,
// 139 NA // 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 JSEND
]=]) ]=])
end) 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) 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 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() describe('ShaDa forward compatibility support code', function()
before_each(reset) before_each(reset)
after_each(function() after_each(function()
@@ -114,14 +121,14 @@ describe('ShaDa forward compatibility support code', function()
funcs.garbagecollect(1) funcs.garbagecollect(1)
end) end)
for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006/a/b/c\161nA'}, 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/a/b/c\161l\002'}, {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/a/b/c\161na'}, {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/a/b/c'}, {name='change', mpack='\011\001\015\130\162mX\195\161f\196\006' .. mock_file_path .. 'c'},
}) do }) do
it('works with ' .. v.name .. ' item with BOOL unknown (mX) key value', function() it('works with ' .. v.name .. ' item with BOOL unknown (mX) key value', function()
nvim_command('silent noautocmd edit /a/b/c') nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c')
eq('/a/b/c', funcs.bufname('%')) eq('' .. mock_file_path .. 'c', funcs.bufname('%'))
funcs.setline('.', {'1', '2', '3'}) funcs.setline('.', {'1', '2', '3'})
wshada(v.mpack) wshada(v.mpack)
eq(0, exc_exec(sdrcmd(true))) 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 if v.name == 'global mark' or v.name == 'local mark' then
it('works with ' .. v.name .. ' item with <C-a> name', function() it('works with ' .. v.name .. ' item with <C-a> name', function()
nvim_command('silent noautocmd edit /a/b/c') nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c')
eq('/a/b/c', funcs.bufname('%')) eq('' .. mock_file_path .. 'c', funcs.bufname('%'))
funcs.setline('.', {'1', '2', '3'}) funcs.setline('.', {'1', '2', '3'})
wshada(v.mpack:gsub('n.$', 'n\001') wshada(v.mpack:gsub('n.$', 'n\001')
.. v.mpack:gsub('n.$', 'n\002') .. 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))) eq(0, exc_exec(sdrcmd(true)))
nvim_command('wshada ' .. shada_fname) nvim_command('wshada ' .. shada_fname)
local found = 0 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() it('works with buffer list item with BOOL unknown (bX) key', function()
nvim_command('set shada+=%') 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(0, exc_exec(sdrcmd()))
eq(2, funcs.bufnr('$')) eq(2, funcs.bufnr('$'))
eq('/a/b/c', funcs.bufname(2)) eq('' .. mock_file_path .. 'c', funcs.bufname(2))
os.remove(shada_fname) os.remove(shada_fname)
nvim_command('wshada ' .. shada_fname) nvim_command('wshada ' .. shada_fname)
local found = false local found = false

View File

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

View File

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

View File

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

View File

@@ -481,6 +481,20 @@ describe('path.c', function()
eq('/tmp', ffi.string(buffer)) eq('/tmp', ffi.string(buffer))
eq(OK, result) eq(OK, result)
end) 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) end)
describe('path_fix_case', function() describe('path_fix_case', function()