aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2021-02-14 11:36:12 -0500
committerGitHub <noreply@github.com>2021-02-14 11:36:12 -0500
commitdc3ca16a99ec05c88df1b1fe6a3cfbe97ea34227 (patch)
treee193cb9ffc5ee85682e13c8fa82848140f6ef949
parent96ca0e2142d4256e7d12f63e4e0ea1474ea28922 (diff)
parent147d40f2a0306df7617812ae83f7225a1b86ad1d (diff)
downloadrneovim-dc3ca16a99ec05c88df1b1fe6a3cfbe97ea34227.tar.gz
rneovim-dc3ca16a99ec05c88df1b1fe6a3cfbe97ea34227.tar.bz2
rneovim-dc3ca16a99ec05c88df1b1fe6a3cfbe97ea34227.zip
Merge pull request #13930 from janlazo/vim-8.2.1902
vim-patch:8.2.{54,64,576,925,1056,1058,1902,1903,1904}
-rw-r--r--runtime/doc/eval.txt14
-rw-r--r--src/nvim/buffer.c61
-rw-r--r--src/nvim/buffer.h3
-rw-r--r--src/nvim/eval/funcs.c15
-rw-r--r--src/nvim/ex_cmds.c8
-rw-r--r--src/nvim/ex_docmd.c12
-rw-r--r--src/nvim/ex_getln.c6
-rw-r--r--src/nvim/ex_getln.h1
-rw-r--r--src/nvim/screen.c60
-rw-r--r--src/nvim/testdir/test_buffer.vim23
-rw-r--r--src/nvim/testdir/test_cmdline.vim1
-rw-r--r--src/nvim/testdir/test_conceal.vim282
-rw-r--r--src/nvim/testdir/test_diffmode.vim69
-rw-r--r--src/nvim/testdir/test_digraph.vim2
-rw-r--r--src/nvim/testdir/test_expr.vim6
-rw-r--r--src/nvim/testdir/test_matchadd_conceal.vim91
-rw-r--r--src/nvim/testdir/test_messages.vim2
-rw-r--r--src/nvim/vim.h1
18 files changed, 578 insertions, 79 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 0343998fe8..b96fc4ac01 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4449,11 +4449,12 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
augroup autocmd groups
buffer buffer names
behave :behave suboptions
- cmdline |cmdline-completion|
+ cmdline |cmdline-completion| result
color color schemes
command Ex command (and arguments)
compiler compilers
cscope |:cscope| suboptions
+ diff_buffer |:diffget| and |:diffput| completion
dir directory names
environment environment variable names
event autocommand events
@@ -4481,14 +4482,19 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
user user names
var user variables
- If {pat} is an empty string then all matches are returned.
- Otherwise only items matching {pat} are returned. See
- |wildcards| for the use of special characters in {pat}.
+ If {pat} is an empty string, then all the matches are
+ returned. Otherwise only items matching {pat} are returned.
+ See |wildcards| for the use of special characters in {pat}.
If the optional {filtered} flag is set to 1, then 'wildignore'
is applied to filter the results. Otherwise all the matches
are returned. The 'wildignorecase' option always applies.
+ If {type} is "cmdline", then the |cmdline-completion| result is
+ returned. For example, to complete the possible values after
+ a ":call" command: >
+ echo getcompletion('call ', 'cmdline')
+<
If there are no matches, an empty list is returned. An
invalid value for {type} produces an error.
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 139981b7e1..c42a0e2dad 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1726,7 +1726,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum,
file_id_valid)) != NULL) {
xfree(ffname);
if (lnum != 0) {
- buflist_setfpos(buf, curwin, lnum, (colnr_T)0, false);
+ buflist_setfpos(buf, (flags & BLN_NOCURWIN) ? NULL : curwin,
+ lnum, (colnr_T)0, false);
}
if ((flags & BLN_NOOPT) == 0) {
// Copy the options now, if 'cpo' doesn't have 's' and not done already.
@@ -2308,6 +2309,10 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
*num_file = 0; // return values in case of FAIL
*file = NULL;
+ if ((options & BUF_DIFF_FILTER) && !curwin->w_p_diff) {
+ return FAIL;
+ }
+
// Make a copy of "pat" and change "^" to "\(^\|[\/]\)".
if (*pat == '^') {
patc = xmalloc(STRLEN(pat) + 11);
@@ -2344,6 +2349,13 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
if (!buf->b_p_bl) { // skip unlisted buffers
continue;
}
+ if (options & BUF_DIFF_FILTER) {
+ // Skip buffers not suitable for
+ // :diffget or :diffput completion.
+ if (buf == curbuf || !diff_mode_buf(buf)) {
+ continue;
+ }
+ }
p = buflist_match(&regmatch, buf, p_wic);
if (p != NULL) {
if (round == 1) {
@@ -2486,6 +2498,7 @@ buflist_nr2name(
///
/// @param[in,out] buf Buffer for which line and column are set.
/// @param[in,out] win Window for which line and column are set.
+/// May be NULL when using :badd.
/// @param[in] lnum Line number to be set. If it is zero then only
/// options are touched.
/// @param[in] col Column number to be set.
@@ -2493,7 +2506,7 @@ buflist_nr2name(
void buflist_setfpos(buf_T *const buf, win_T *const win,
linenr_T lnum, colnr_T col,
bool copy_options)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ARG(1)
{
wininfo_T *wip;
@@ -2528,7 +2541,7 @@ void buflist_setfpos(buf_T *const buf, win_T *const win,
wip->wi_fpos.lnum = lnum;
wip->wi_fpos.col = col;
}
- if (copy_options) {
+ if (copy_options && win != NULL) {
// Save the window-specific option values.
copy_winopt(&win->w_onebuf_opt, &wip->wi_opt);
wip->wi_fold_manual = win->w_fold_manual;
@@ -2566,29 +2579,39 @@ static bool wininfo_other_tab_diff(wininfo_T *wip)
return false;
}
-/*
- * Find info for the current window in buffer "buf".
- * If not found, return the info for the most recently used window.
- * When "skip_diff_buffer" is true avoid windows with 'diff' set that is in
- * another tab page.
- * Returns NULL when there isn't any info.
- */
-static wininfo_T *find_wininfo(buf_T *buf, int skip_diff_buffer)
+// Find info for the current window in buffer "buf".
+// If not found, return the info for the most recently used window.
+// When "need_options" is true skip entries where wi_optset is false.
+// When "skip_diff_buffer" is true avoid windows with 'diff' set that is in
+// another tab page.
+// Returns NULL when there isn't any info.
+static wininfo_T *find_wininfo(buf_T *buf, bool need_options,
+ bool skip_diff_buffer)
+ FUNC_ATTR_NONNULL_ALL
{
wininfo_T *wip;
- for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+ for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
if (wip->wi_win == curwin
&& (!skip_diff_buffer || !wininfo_other_tab_diff(wip))
- )
+ && (!need_options || wip->wi_optset)) {
break;
+ }
+ }
- /* If no wininfo for curwin, use the first in the list (that doesn't have
- * 'diff' set and is in another tab page). */
+ // If no wininfo for curwin, use the first in the list (that doesn't have
+ // 'diff' set and is in another tab page).
+ // If "need_options" is true skip entries that don't have options set,
+ // unless the window is editing "buf", so we can copy from the window
+ // itself.
if (wip == NULL) {
if (skip_diff_buffer) {
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
- if (!wininfo_other_tab_diff(wip)) {
+ if (!wininfo_other_tab_diff(wip)
+ && (!need_options
+ || wip->wi_optset
+ || (wip->wi_win != NULL
+ && wip->wi_win->w_buffer == buf))) {
break;
}
}
@@ -2607,12 +2630,10 @@ static wininfo_T *find_wininfo(buf_T *buf, int skip_diff_buffer)
*/
void get_winopts(buf_T *buf)
{
- wininfo_T *wip;
-
clear_winopt(&curwin->w_onebuf_opt);
clearFolding(curwin);
- wip = find_wininfo(buf, true);
+ wininfo_T *const wip = find_wininfo(buf, true, true);
if (wip != NULL && wip->wi_win != curwin && wip->wi_win != NULL
&& wip->wi_win->w_buffer == buf) {
win_T *wp = wip->wi_win;
@@ -2649,7 +2670,7 @@ pos_T *buflist_findfpos(buf_T *buf)
{
static pos_T no_position = { 1, 0, 0 };
- wininfo_T *wip = find_wininfo(buf, false);
+ wininfo_T *const wip = find_wininfo(buf, false, false);
return (wip == NULL) ? &no_position : &(wip->wi_fpos);
}
diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h
index ee3fda5f6d..ac7ead5f92 100644
--- a/src/nvim/buffer.h
+++ b/src/nvim/buffer.h
@@ -33,6 +33,9 @@ enum bln_values {
BLN_DUMMY = 4, // Allocating dummy buffer
BLN_NEW = 8, // create a new buffer
BLN_NOOPT = 16, // Don't copy options to existing buffer
+ // BLN_DUMMY_OK = 32, // also find an existing dummy buffer
+ // BLN_REUSE = 64, // may re-use number from buf_reuse
+ BLN_NOCURWIN = 128, // buffer is not associated with curwin
};
// Values for action argument for do_buffer()
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 3cc71a39f6..d54e49bbd4 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -3134,6 +3134,12 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
| WILD_NO_BEEP;
+ if (argvars[1].v_type != VAR_STRING) {
+ EMSG2(_(e_invarg2), "type must be a string");
+ return;
+ }
+ const char *const type = tv_get_string(&argvars[1]);
+
if (argvars[2].v_type != VAR_UNKNOWN) {
filtered = (bool)tv_get_number_chk(&argvars[2], NULL);
}
@@ -3147,12 +3153,12 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
options |= WILD_KEEP_ALL;
}
- if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_STRING) {
+ if (argvars[0].v_type != VAR_STRING) {
EMSG(_(e_invarg));
return;
}
- if (strcmp(tv_get_string(&argvars[1]), "cmdline") == 0) {
+ if (strcmp(type, "cmdline") == 0) {
set_one_cmd_context(&xpc, tv_get_string(&argvars[0]));
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
goto theend;
@@ -3161,10 +3167,9 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ExpandInit(&xpc);
xpc.xp_pattern = (char_u *)tv_get_string(&argvars[0]);
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
- xpc.xp_context = cmdcomplete_str_to_type(
- (char_u *)tv_get_string(&argvars[1]));
+ xpc.xp_context = cmdcomplete_str_to_type(type);
if (xpc.xp_context == EXPAND_NOTHING) {
- EMSG2(_(e_invarg2), argvars[1].vval.v_string);
+ EMSG2(_(e_invarg2), type);
return;
}
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index a994d0d8c3..b220b034dd 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2324,15 +2324,19 @@ int do_ecmd(
buf = buflist_findnr(fnum);
} else {
if (flags & (ECMD_ADDBUF | ECMD_ALTBUF)) {
- linenr_T tlnum = 1L;
+ // Default the line number to zero to avoid that a wininfo item
+ // is added for the current window.
+ linenr_T tlnum = 0;
if (command != NULL) {
tlnum = atol((char *)command);
if (tlnum <= 0)
tlnum = 1L;
}
+ // Add BLN_NOCURWIN to avoid a new wininfo items are associated
+ // with the current window.
const buf_T *const newbuf
- = buflist_new(ffname, sfname, tlnum, BLN_LISTED);
+ = buflist_new(ffname, sfname, tlnum, BLN_LISTED | BLN_NOCURWIN);
if (newbuf != NULL && (flags & ECMD_ALTBUF)) {
curwin->w_alt_fnum = newbuf->b_fnum;
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index ef11107779..bc3d29a03f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -3512,6 +3512,13 @@ const char * set_one_cmd_context(
xp->xp_context = EXPAND_BUFFERS;
xp->xp_pattern = (char_u *)arg;
break;
+ case CMD_diffget:
+ case CMD_diffput:
+ // If current buffer is in diff mode, complete buffer names
+ // which are in diff mode, and different than current buffer.
+ xp->xp_context = EXPAND_DIFF_BUFFERS;
+ xp->xp_pattern = (char_u *)arg;
+ break;
case CMD_USER:
case CMD_USER_BUF:
if (context != EXPAND_NOTHING) {
@@ -5174,6 +5181,7 @@ static const char *command_complete[] =
[EXPAND_CSCOPE] = "cscope",
[EXPAND_USER_DEFINED] = "custom",
[EXPAND_USER_LIST] = "customlist",
+ [EXPAND_DIFF_BUFFERS] = "diff_buffer",
[EXPAND_DIRECTORIES] = "dir",
[EXPAND_ENV_VARS] = "environment",
[EXPAND_EVENTS] = "event",
@@ -6274,14 +6282,14 @@ int parse_compl_arg(const char_u *value, int vallen, int *complp,
return OK;
}
-int cmdcomplete_str_to_type(char_u *complete_str)
+int cmdcomplete_str_to_type(const char *complete_str)
{
for (int i = 0; i < (int)(ARRAY_SIZE(command_complete)); i++) {
char *cmd_compl = get_command_complete(i);
if (cmd_compl == NULL) {
continue;
}
- if (STRCMP(complete_str, command_complete[i]) == 0) {
+ if (strcmp(complete_str, command_complete[i]) == 0) {
return i;
}
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 4d1fd9b33f..c66ae13f53 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -5084,9 +5084,13 @@ ExpandFromContext (
}
if (xp->xp_context == EXPAND_BUFFERS)
return ExpandBufnames(pat, num_file, file, options);
+ if (xp->xp_context == EXPAND_DIFF_BUFFERS) {
+ return ExpandBufnames(pat, num_file, file, options | BUF_DIFF_FILTER);
+ }
if (xp->xp_context == EXPAND_TAGS
- || xp->xp_context == EXPAND_TAGS_LISTFILES)
+ || xp->xp_context == EXPAND_TAGS_LISTFILES) {
return expand_tags(xp->xp_context == EXPAND_TAGS, pat, num_file, file);
+ }
if (xp->xp_context == EXPAND_COLORS) {
char *directories[] = { "colors", NULL };
return ExpandRTDir(pat, DIP_START + DIP_OPT, num_file, file, directories);
diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h
index dc4395e081..3727aa5e62 100644
--- a/src/nvim/ex_getln.h
+++ b/src/nvim/ex_getln.h
@@ -32,6 +32,7 @@
#define WILD_IGNORE_COMPLETESLASH 0x400
#define WILD_NOERROR 0x800 // sets EW_NOERROR
#define WILD_BUFLASTUSED 0x1000
+#define BUF_DIFF_FILTER 0x2000
/// Present history tables
typedef enum {
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 6b6c51d836..c16fe46955 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -2082,7 +2082,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
int line_attr_lowprio = 0; // low-priority attribute for the 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
+ bool shl_flag; // flag to indicate whether search_hl
// has been processed or not
bool prevcol_hl_flag; // flag to indicate whether prevcol
// equals startcol of search_hl or one
@@ -2950,16 +2950,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
*/
v = (long)(ptr - line);
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE
- && ((cur != NULL
- && cur->priority > SEARCH_HL_PRIORITY)
- || cur == NULL)) {
+ shl_flag = false;
+ while (cur != NULL || !shl_flag) {
+ if (!shl_flag
+ && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
+ shl_flag = true;
+ } else {
shl = &cur->hl;
+ }
if (cur != NULL) {
cur->pos.cur = 0;
}
@@ -2984,7 +2983,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
has_match_conc = v == (long)shl->startcol ? 2 : 1;
match_conc = cur->conceal_char;
} else {
- has_match_conc = match_conc = 0;
+ has_match_conc = 0;
}
} else if (v == (long)shl->endcol) {
shl->attr_cur = 0;
@@ -3026,16 +3025,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
search_attr_from_match = false;
search_attr = search_hl.attr_cur;
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE
- && ((cur != NULL
- && cur->priority > SEARCH_HL_PRIORITY)
- || cur == NULL)) {
+ shl_flag = false;
+ while (cur != NULL || !shl_flag) {
+ if (!shl_flag
+ && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
+ shl_flag = true;
+ } else {
shl = &cur->hl;
+ }
if (shl->attr_cur != 0) {
search_attr = shl->attr_cur;
search_attr_from_match = shl != &search_hl;
@@ -3048,6 +3046,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
&& (wp->w_p_list && lcs_eol_one == -1)) {
search_attr = 0;
}
+
+ // Do not allow a conceal over EOL otherwise EOL will be missed
+ // and bad things happen.
+ if (*ptr == NUL) {
+ has_match_conc = 0;
+ }
}
if (diff_hlf != (hlf_T)0) {
@@ -3672,12 +3676,13 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
&& vim_strchr(wp->w_p_cocu, 'v') == NULL)) {
char_attr = conceal_attr;
if ((prev_syntax_id != syntax_seqnr || has_match_conc > 1)
- && (syn_get_sub_char() != NUL || match_conc
+ && (syn_get_sub_char() != NUL
+ || (has_match_conc && match_conc)
|| wp->w_p_cole == 1)
&& wp->w_p_cole != 3) {
// First time at this concealed item: display one
// character.
- if (match_conc) {
+ if (has_match_conc && match_conc) {
c = match_conc;
} else if (syn_get_sub_char() != NUL) {
c = syn_get_sub_char();
@@ -3837,16 +3842,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// 'search_hl' and the match list.
char_attr = search_hl.attr;
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE
- && ((cur != NULL
- && cur->priority > SEARCH_HL_PRIORITY)
- || cur == NULL)) {
+ shl_flag = false;
+ while (cur != NULL || !shl_flag) {
+ if (!shl_flag
+ && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
+ shl_flag = true;
+ } else {
shl = &cur->hl;
+ }
if ((ptr - line) - 1 == (long)shl->startcol
&& (shl == &search_hl || !shl->is_addpos)) {
char_attr = shl->attr;
diff --git a/src/nvim/testdir/test_buffer.vim b/src/nvim/testdir/test_buffer.vim
index f455b6911f..40111fdf06 100644
--- a/src/nvim/testdir/test_buffer.vim
+++ b/src/nvim/testdir/test_buffer.vim
@@ -1,5 +1,28 @@
" Tests for Vim buffer
+func Test_buffer_error()
+ new foo1
+ new foo2
+
+ call assert_fails('buffer foo', 'E93:')
+ call assert_fails('buffer bar', 'E94:')
+ call assert_fails('buffer 0', 'E939:')
+
+ %bwipe
+endfunc
+
+func Test_badd_options()
+ new SomeNewBuffer
+ setlocal numberwidth=3
+ wincmd p
+ badd +1 SomeNewBuffer
+ new SomeNewBuffer
+ call assert_equal(3, &numberwidth)
+ close
+ close
+ bwipe! SomeNewBuffer
+endfunc
+
func Test_balt()
new SomeNewBuffer
balt +3 OtherBuffer
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 39f865144a..a66aee5e02 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -442,6 +442,7 @@ func Test_getcompletion()
set tags&
call assert_fails('call getcompletion("", "burp")', 'E475:')
+ call assert_fails('call getcompletion("abc", [])', 'E475:')
endfunc
func Test_shellcmd_completion()
diff --git a/src/nvim/testdir/test_conceal.vim b/src/nvim/testdir/test_conceal.vim
new file mode 100644
index 0000000000..1306dbe5cf
--- /dev/null
+++ b/src/nvim/testdir/test_conceal.vim
@@ -0,0 +1,282 @@
+" Tests for 'conceal'.
+
+source check.vim
+CheckFeature conceal
+
+source screendump.vim
+" CheckScreendump
+
+func Test_conceal_two_windows()
+ CheckScreendump
+ let code =<< trim [CODE]
+ let lines = ["one one one one one", "two |hidden| here", "three |hidden| three"]
+ call setline(1, lines)
+ syntax match test /|hidden|/ conceal
+ set conceallevel=2
+ set concealcursor=
+ exe "normal /here\r"
+ new
+ call setline(1, lines)
+ call setline(4, "Second window")
+ syntax match test /|hidden|/ conceal
+ set conceallevel=2
+ set concealcursor=nc
+ exe "normal /here\r"
+ [CODE]
+
+ call writefile(code, 'XTest_conceal')
+ " Check that cursor line is concealed
+ let buf = RunVimInTerminal('-S XTest_conceal', {})
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_01', {})
+
+ " Check that with concealed text vertical cursor movement is correct.
+ call term_sendkeys(buf, "k")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_02', {})
+
+ " Check that with cursor line is not concealed
+ call term_sendkeys(buf, "j")
+ call term_sendkeys(buf, ":set concealcursor=\r")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_03', {})
+
+ " Check that with cursor line is not concealed when moving cursor down
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_04', {})
+
+ " Check that with cursor line is not concealed when switching windows
+ call term_sendkeys(buf, "\<C-W>\<C-W>")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_05', {})
+
+ " Check that with cursor line is only concealed in Normal mode
+ call term_sendkeys(buf, ":set concealcursor=n\r")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_06n', {})
+ call term_sendkeys(buf, "a")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_06i', {})
+ call term_sendkeys(buf, "\<Esc>/e")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_06c', {})
+ call term_sendkeys(buf, "\<Esc>v")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_06v', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Check that with cursor line is only concealed in Insert mode
+ call term_sendkeys(buf, ":set concealcursor=i\r")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_07n', {})
+ call term_sendkeys(buf, "a")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_07i', {})
+ call term_sendkeys(buf, "\<Esc>/e")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_07c', {})
+ call term_sendkeys(buf, "\<Esc>v")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_07v', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Check that with cursor line is only concealed in Command mode
+ call term_sendkeys(buf, ":set concealcursor=c\r")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_08n', {})
+ call term_sendkeys(buf, "a")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_08i', {})
+ call term_sendkeys(buf, "\<Esc>/e")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_08c', {})
+ call term_sendkeys(buf, "\<Esc>v")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_08v', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Check that with cursor line is only concealed in Visual mode
+ call term_sendkeys(buf, ":set concealcursor=v\r")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_09n', {})
+ call term_sendkeys(buf, "a")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_09i', {})
+ call term_sendkeys(buf, "\<Esc>/e")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_09c', {})
+ call term_sendkeys(buf, "\<Esc>v")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_09v', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Check moving the cursor while in insert mode.
+ call term_sendkeys(buf, ":set concealcursor=\r")
+ call term_sendkeys(buf, "a")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_10', {})
+ call term_sendkeys(buf, "\<Down>")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_11', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Check the "o" command
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_12', {})
+ call term_sendkeys(buf, "o")
+ call VerifyScreenDump(buf, 'Test_conceal_two_windows_13', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('XTest_conceal')
+endfunc
+
+func Test_conceal_with_cursorline()
+ CheckScreendump
+ " Opens a help window, where 'conceal' is set, switches to the other window
+ " where 'cursorline' needs to be updated when the cursor moves.
+ let code =<< trim [CODE]
+ set cursorline
+ normal othis is a test
+ new
+ call setline(1, ["one", "two", "three", "four", "five"])
+ set ft=help
+ normal M
+ [CODE]
+
+ call writefile(code, 'XTest_conceal_cul')
+ let buf = RunVimInTerminal('-S XTest_conceal_cul', {})
+ call VerifyScreenDump(buf, 'Test_conceal_cul_01', {})
+
+ call term_sendkeys(buf, ":wincmd w\r")
+ call VerifyScreenDump(buf, 'Test_conceal_cul_02', {})
+
+ call term_sendkeys(buf, "k")
+ call VerifyScreenDump(buf, 'Test_conceal_cul_03', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('XTest_conceal_cul')
+endfunc
+
+func Test_conceal_resize_term()
+ CheckScreendump
+ let code =<< trim [CODE]
+ call setline(1, '`one` `two` `three` `four` `five`, the backticks should be concealed')
+ setl cocu=n cole=3
+ syn region CommentCodeSpan matchgroup=Comment start=/`/ end=/`/ concealends
+ normal fb
+ [CODE]
+ call writefile(code, 'XTest_conceal_resize')
+ let buf = RunVimInTerminal('-S XTest_conceal_resize', {'rows': 6})
+ call VerifyScreenDump(buf, 'Test_conceal_resize_01', {})
+
+ call win_execute(buf->win_findbuf()[0], 'wincmd +')
+ call TermWait(buf)
+ call VerifyScreenDump(buf, 'Test_conceal_resize_02', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('XTest_conceal_resize')
+endfunc
+
+" Tests for correct display (cursor column position) with +conceal and
+" tabulators. Need to run this test in a separate Vim instance. Otherwise the
+" screen is not updated (lazy redraw) and the cursor position is wrong.
+func Test_conceal_cursor_pos()
+ let code =<< trim [CODE]
+ :let l = ['start:', '.concealed. text', "|concealed|\ttext"]
+ :let l += ['', "\t.concealed.\ttext", "\t|concealed|\ttext", '']
+ :let l += [".a.\t.b.\t.c.\t.d.", "|a|\t|b|\t|c|\t|d|"]
+ :call append(0, l)
+ :call cursor(1, 1)
+ :" Conceal settings.
+ :set conceallevel=2
+ :set concealcursor=nc
+ :syntax match test /|/ conceal
+ :" Save current cursor position. Only works in <expr> mode, can't be used
+ :" with :normal because it moves the cursor to the command line. Thanks
+ :" to ZyX <zyx.vim@gmail.com> for the idea to use an <expr> mapping.
+ :let curpos = []
+ :nnoremap <expr> GG ":let curpos += ['".screenrow().":".screencol()."']\n"
+ :normal ztj
+ GGk
+ :" We should end up in the same column when running these commands on the
+ :" two lines.
+ :normal ft
+ GGk
+ :normal $
+ GGk
+ :normal 0j
+ GGk
+ :normal ft
+ GGk
+ :normal $
+ GGk
+ :normal 0j0j
+ GGk
+ :" Same for next test block.
+ :normal ft
+ GGk
+ :normal $
+ GGk
+ :normal 0j
+ GGk
+ :normal ft
+ GGk
+ :normal $
+ GGk
+ :normal 0j0j
+ GGk
+ :" And check W with multiple tabs and conceals in a line.
+ :normal W
+ GGk
+ :normal W
+ GGk
+ :normal W
+ GGk
+ :normal $
+ GGk
+ :normal 0j
+ GGk
+ :normal W
+ GGk
+ :normal W
+ GGk
+ :normal W
+ GGk
+ :normal $
+ GGk
+ :set lbr
+ :normal $
+ GGk
+ :set list listchars=tab:>-
+ :normal 0
+ GGk
+ :normal W
+ GGk
+ :normal W
+ GGk
+ :normal W
+ GGk
+ :normal $
+ GGk
+ :call writefile(curpos, 'Xconceal_curpos.out')
+ :q!
+
+ [CODE]
+ call writefile(code, 'XTest_conceal_curpos')
+
+ if RunVim([], [], '-s XTest_conceal_curpos')
+ call assert_equal([
+ \ '2:1', '2:17', '2:20', '3:1', '3:17', '3:20', '5:8', '5:25',
+ \ '5:28', '6:8', '6:25', '6:28', '8:1', '8:9', '8:17', '8:25',
+ \ '8:27', '9:1', '9:9', '9:17', '9:25', '9:26', '9:26', '9:1',
+ \ '9:9', '9:17', '9:25', '9:26'], readfile('Xconceal_curpos.out'))
+ endif
+
+ call delete('Xconceal_curpos.out')
+ call delete('XTest_conceal_curpos')
+endfunc
+
+func Test_conceal_eol()
+ new!
+ setlocal concealcursor=n conceallevel=1
+ call setline(1, ["x", ""])
+ call matchaddpos('Conceal', [[2, 1, 1]], 2, -1, {'conceal': 1})
+ redraw!
+
+ call assert_notequal(screenchar(1, 1), screenchar(2, 2))
+ call assert_equal(screenattr(1, 1), screenattr(1, 2))
+ call assert_equal(screenattr(1, 2), screenattr(2, 2))
+ call assert_equal(screenattr(2, 1), screenattr(2, 2))
+
+ set list
+ redraw!
+
+ call assert_equal(screenattr(1, 1), screenattr(2, 2))
+ call assert_notequal(screenattr(1, 1), screenattr(1, 2))
+ call assert_notequal(screenattr(1, 2), screenattr(2, 1))
+
+ set nolist
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
index 640de1bdc6..21c1f98283 100644
--- a/src/nvim/testdir/test_diffmode.vim
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -242,6 +242,63 @@ func Test_diffput_two()
bwipe! b
endfunc
+" :diffput and :diffget completes names of buffers which
+" are in diff mode and which are different then current buffer.
+" No completion when the current window is not in diff mode.
+func Test_diffget_diffput_completion()
+ e Xdiff1 | diffthis
+ botright new Xdiff2
+ botright new Xdiff3 | split | diffthis
+ botright new Xdiff4 | diffthis
+
+ wincmd t
+ call assert_equal('Xdiff1', bufname('%'))
+ call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffput Xdiff3 Xdiff4', @:)
+ call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffget Xdiff3 Xdiff4', @:)
+ call assert_equal(['Xdiff3', 'Xdiff4'], getcompletion('', 'diff_buffer'))
+
+ " Xdiff2 is not in diff mode, so no completion for :diffput, :diffget
+ wincmd j
+ call assert_equal('Xdiff2', bufname('%'))
+ call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffput ', @:)
+ call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffget ', @:)
+ call assert_equal([], getcompletion('', 'diff_buffer'))
+
+ " Xdiff3 is split in 2 windows, only the top one is in diff mode.
+ " So completion of :diffput :diffget only happens in the top window.
+ wincmd j
+ call assert_equal('Xdiff3', bufname('%'))
+ call assert_equal(1, &diff)
+ call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffput Xdiff1 Xdiff4', @:)
+ call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffget Xdiff1 Xdiff4', @:)
+ call assert_equal(['Xdiff1', 'Xdiff4'], getcompletion('', 'diff_buffer'))
+
+ wincmd j
+ call assert_equal('Xdiff3', bufname('%'))
+ call assert_equal(0, &diff)
+ call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffput ', @:)
+ call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffget ', @:)
+ call assert_equal([], getcompletion('', 'diff_buffer'))
+
+ wincmd j
+ call assert_equal('Xdiff4', bufname('%'))
+ call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffput Xdiff1 Xdiff3', @:)
+ call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"diffget Xdiff1 Xdiff3', @:)
+ call assert_equal(['Xdiff1', 'Xdiff3'], getcompletion('', 'diff_buffer'))
+
+ %bwipe
+endfunc
+
func Test_dp_do_buffer()
e! one
let bn1=bufnr('%')
@@ -1007,6 +1064,18 @@ func Test_diff_rnu()
call delete('Xtest_diff_rnu')
endfunc
+func Test_diff_multilineconceal()
+ new
+ diffthis
+
+ new
+ call matchadd('Conceal', 'a\nb', 9, -1, {'conceal': 'Y'})
+ set cole=2 cocu=n
+ call setline(1, ["a", "b"])
+ diffthis
+ redraw
+endfunc
+
func Test_diff_and_scroll()
" this was causing an ml_get error
set ls=2
diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim
index b6d9687560..d23748a3e3 100644
--- a/src/nvim/testdir/test_digraph.vim
+++ b/src/nvim/testdir/test_digraph.vim
@@ -211,6 +211,8 @@ func Test_digraphs()
call Put_Dig("00")
call Put_Dig("el")
call assert_equal(['␀', 'ü', '∞', 'l'], getline(line('.')-3,line('.')))
+ call assert_fails('digraph xy z', 'E39:')
+ call assert_fails('digraph x', 'E474:')
bw!
endfunc
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index 7b90ba56e0..09d79979ce 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -399,7 +399,11 @@ function Test_printf_errors()
call assert_fails('echo printf("%d", [])', 'E745:')
call assert_fails('echo printf("%d", 1, 2)', 'E767:')
call assert_fails('echo printf("%*d", 1)', 'E766:')
- call assert_fails('echo printf("%d", 1.2)', 'E805:')
+ call assert_fails('echo printf("%s")', 'E766:')
+ if has('float')
+ call assert_fails('echo printf("%d", 1.2)', 'E805:')
+ call assert_fails('echo printf("%f")')
+ endif
endfunc
function Test_max_min_errors()
diff --git a/src/nvim/testdir/test_matchadd_conceal.vim b/src/nvim/testdir/test_matchadd_conceal.vim
index f9e40a9b43..2cbaf5cb76 100644
--- a/src/nvim/testdir/test_matchadd_conceal.vim
+++ b/src/nvim/testdir/test_matchadd_conceal.vim
@@ -59,9 +59,9 @@ func Test_matchadd_and_conceallevel_3()
setlocal filetype=conf
syntax on
- 1put='# This is a Test'
- " 1234567890123456
- let expect = '#ThisisaTest'
+ 1put='# This is a Test $'
+ " 1234567890123
+ let expect = '#ThisisaTest$'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
@@ -69,22 +69,25 @@ func Test_matchadd_and_conceallevel_3()
let lnum = 2
call assert_equal(expect, Screenline(lnum))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2))
- call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
- call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
- call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 13))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 14))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 16))
" more matchadd()
- " 1234567890123456
- let expect = '#Thisisa Test'
+ " 12345678901234
+ let expect = '#Thisisa Test$'
call matchadd('ErrorMsg', '\%2l Test', 20, -1, {'conceal': 'X'})
redraw!
call assert_equal(expect, Screenline(lnum))
call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 2))
- call assert_equal(screenattr(lnum, 2) , screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 7))
call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 10))
- call assert_equal(screenattr(lnum, 10), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 10), screenattr(lnum, 13))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 14))
call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 16))
call assert_notequal(screenattr(lnum, 10), screenattr(lnum, 16))
@@ -132,15 +135,29 @@ func Test_syn_and_match_conceal()
new
setlocal concealcursor=n conceallevel=1
- 1put='# This is a Test'
- " 1234567890123456
- let expect = '#ZThisZisZaZTest'
+ 1put='# This is a Test '
+ let lnum = 2
call cursor(1, 1)
+
+ " 123456789012345678
+ let expect = '#ZThisZisZaZTestZZ'
call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
+ syntax match MyConceal /\%2l / conceal containedin=ALL
+ hi MyConceal ctermbg=4 ctermfg=2
+ redraw!
+
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ syntax clear MyConceal
syntax match MyConceal /\%2l / conceal containedin=ALL cchar=*
redraw!
- let lnum = 2
+
call assert_equal(expect, Screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
@@ -148,8 +165,8 @@ func Test_syn_and_match_conceal()
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
- " 1234567890123456
- let expect = '#*This*is*a*Test'
+ " 123456789012345678
+ let expect = '#*This*is*a*Test**'
call clearmatches()
redraw!
@@ -160,6 +177,48 @@ func Test_syn_and_match_conceal()
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+ " 123456789012345678
+ let expect = '#*ThisXis*a*Test**'
+ call matchadd('Conceal', '\%2l\%7c ', 10, -1, {'conceal': 'X'})
+ redraw!
+
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ " 123456789012345678
+ let expect = '#*ThisXis*a*Test**'
+ call matchadd('ErrorMsg', '\%2l Test', 20, -1)
+ redraw!
+
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_notequal(screenattr(lnum, 12), screenattr(lnum, 13))
+ call assert_equal(screenattr(lnum, 13), screenattr(lnum, 16))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 17))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 18))
+ call assert_notequal(screenattr(lnum, 18), screenattr(lnum, 19))
+
+ " 123456789012345678
+ let expect = '# ThisXis a Test'
+ syntax clear MyConceal
+ syntax match MyConceal /\%2l / conceal containedin=ALL
+ redraw!
+
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 12))
+ call assert_notequal(screenattr(lnum, 12), screenattr(lnum, 13))
+ call assert_equal(screenattr(lnum, 13), screenattr(lnum, 16))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 17))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 18))
+ call assert_notequal(screenattr(lnum, 18), screenattr(lnum, 19))
+
syntax off
quit!
endfunc
diff --git a/src/nvim/testdir/test_messages.vim b/src/nvim/testdir/test_messages.vim
index 30239a90c2..3ebd048f46 100644
--- a/src/nvim/testdir/test_messages.vim
+++ b/src/nvim/testdir/test_messages.vim
@@ -31,6 +31,8 @@ func Test_messages()
finally
let &more = oldmore
endtry
+
+ call assert_fails('message 1', 'E474:')
endfunc
" Patch 7.4.1696 defined the "clearmode()" command for clearing the mode
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index e70749795b..0245c472ef 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -158,6 +158,7 @@ enum {
EXPAND_MESSAGES,
EXPAND_MAPCLEAR,
EXPAND_ARGLIST,
+ EXPAND_DIFF_BUFFERS,
EXPAND_CHECKHEALTH,
EXPAND_LUA,
};