aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-08-15 10:18:22 +0200
committerGitHub <noreply@github.com>2018-08-15 10:18:22 +0200
commit26506f14bc653a555b32e553bf458efc6402ed0b (patch)
treeab38a031422332883ecf294238714996cc412de2
parentf767cee10002afc360af1aad209676d08cc3a758 (diff)
parentbe1525d3c95db99d50c1538e73dfcbf8a4f83782 (diff)
downloadrneovim-26506f14bc653a555b32e553bf458efc6402ed0b.tar.gz
rneovim-26506f14bc653a555b32e553bf458efc6402ed0b.tar.bz2
rneovim-26506f14bc653a555b32e553bf458efc6402ed0b.zip
Merge #8856 from janlazo/vim-8.0.1209
-rw-r--r--src/nvim/buffer.c5
-rw-r--r--src/nvim/quickfix.c12
-rw-r--r--src/nvim/tag.c46
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_autocmd.vim45
-rw-r--r--src/nvim/testdir/test_join.vim35
-rw-r--r--src/nvim/testdir/test_tagjump.vim28
-rw-r--r--src/nvim/testdir/test_taglist.vim7
-rw-r--r--src/nvim/testdir/test_user_func.vim96
-rw-r--r--test/functional/legacy/packadd_spec.lua2
11 files changed, 254 insertions, 24 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 3fadcc75bf..00d472b4c8 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -296,6 +296,11 @@ open_buffer (
}
save_file_ff(curbuf); // keep this fileformat
+ // Set last_changedtick to avoid triggering a TextChanged autocommand right
+ // after it was added.
+ curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
+ curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf);
+
/* require "!" to overwrite the file, because it wasn't read completely */
if (aborting())
curbuf->b_flags |= BF_READERR;
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 4308c4e87e..a19e98725a 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -4541,11 +4541,6 @@ void ex_cbuffer(exarg_T *eap)
qf_info_T *qi = &ql_info;
const char *au_name = NULL;
- if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer
- || eap->cmdidx == CMD_laddbuffer) {
- qi = ll_get_or_alloc_list(curwin);
- }
-
switch (eap->cmdidx) {
case CMD_cbuffer:
au_name = "cbuffer";
@@ -4576,6 +4571,13 @@ void ex_cbuffer(exarg_T *eap)
}
}
+ // Must come after autocommands.
+ if (eap->cmdidx == CMD_lbuffer
+ || eap->cmdidx == CMD_lgetbuffer
+ || eap->cmdidx == CMD_laddbuffer) {
+ qi = ll_get_or_alloc_list(curwin);
+ }
+
if (*eap->arg == NUL)
buf = curbuf;
else if (*skipwhite(skipdigits(eap->arg)) == NUL)
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index c09a13edb1..2a980af2a2 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -952,12 +952,12 @@ void do_tags(exarg_T *eap)
continue;
msg_putchar('\n');
- sprintf((char *)IObuff, "%c%2d %2d %-15s %5ld ",
- i == tagstackidx ? '>' : ' ',
- i + 1,
- tagstack[i].cur_match + 1,
- tagstack[i].tagname,
- tagstack[i].fmark.mark.lnum);
+ vim_snprintf((char *)IObuff, IOSIZE, "%c%2d %2d %-15s %5ld ",
+ i == tagstackidx ? '>' : ' ',
+ i + 1,
+ tagstack[i].cur_match + 1,
+ tagstack[i].tagname,
+ tagstack[i].fmark.mark.lnum);
msg_outtrans(IObuff);
msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum
? HL_ATTR(HLF_D) : 0);
@@ -2217,6 +2217,16 @@ static bool test_for_static(tagptrs_T *tagp)
return FALSE;
}
+// Returns the length of a matching tag line.
+static size_t matching_line_len(const char_u *const lbuf)
+{
+ const char_u *p = lbuf + 1;
+
+ // does the same thing as parse_match()
+ p += STRLEN(p) + 1;
+ return (p - lbuf) + STRLEN(p);
+}
+
/*
* Parse a line from a matching tag. Does not change the line itself.
*
@@ -2300,11 +2310,10 @@ static char_u *tag_full_fname(tagptrs_T *tagp)
*
* returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
*/
-static int
-jumpto_tag (
- char_u *lbuf, /* line from the tags file for this tag */
- int forceit, /* :ta with ! */
- int keep_help /* keep help flag (FALSE for cscope) */
+static int jumpto_tag(
+ const char_u *lbuf_arg, // line from the tags file for this tag
+ int forceit, // :ta with !
+ int keep_help // keep help flag (FALSE for cscope)
)
{
int save_secure;
@@ -2312,7 +2321,6 @@ jumpto_tag (
bool save_p_ws;
int save_p_scs, save_p_ic;
linenr_T save_lnum;
- int csave = 0;
char_u *str;
char_u *pbuf; /* search pattern buffer */
char_u *pbuf_end;
@@ -2327,6 +2335,9 @@ jumpto_tag (
char_u *full_fname = NULL;
int old_KeyTyped = KeyTyped; /* getting the file may reset it */
const int l_g_do_tagpreview = g_do_tagpreview;
+ const size_t len = matching_line_len(lbuf_arg) + 1;
+ char_u *lbuf = xmalloc(len);
+ memmove(lbuf, lbuf_arg, len);
pbuf = xmalloc(LSIZE);
@@ -2336,8 +2347,7 @@ jumpto_tag (
goto erret;
}
- /* truncate the file name, so it can be used as a string */
- csave = *tagp.fname_end;
+ // truncate the file name, so it can be used as a string
*tagp.fname_end = NUL;
fname = tagp.fname;
@@ -2447,7 +2457,10 @@ jumpto_tag (
else
keep_help_flag = curbuf->b_help;
}
+
if (getfile_result == GETFILE_UNUSED) {
+ // Careful: getfile() may trigger autocommands and call jumpto_tag()
+ // recursively.
getfile_result = getfile(0, fname, NULL, true, (linenr_T)0, forceit);
}
keep_help_flag = false;
@@ -2605,9 +2618,8 @@ jumpto_tag (
}
erret:
- g_do_tagpreview = 0; /* For next time */
- if (tagp.fname_end != NULL)
- *tagp.fname_end = csave;
+ g_do_tagpreview = 0; // For next time
+ xfree(lbuf);
xfree(pbuf);
xfree(tofree_fname);
xfree(full_fname);
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 361db47fc7..1e3dc04049 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -114,6 +114,7 @@ NEW_TESTS ?= \
test_timers.res \
test_undo.res \
test_usercommands.res \
+ test_user_func.res \
test_vimscript.res \
test_visual.res \
test_winbuf_close.res \
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 238dbe8d90..ace4b377cb 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -19,6 +19,7 @@ source test_functions.vim
source test_ga.vim
source test_global.vim
source test_goto.vim
+source test_join.vim
source test_jumps.vim
source test_fileformat.vim
source test_filetype.vim
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index e4ab3ccea8..b1502eff89 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1,5 +1,7 @@
" Tests for autocommands
+source shared.vim
+
func! s:cleanup_buffers() abort
for bnr in range(1, bufnr('$'))
if bufloaded(bnr) && bufnr('%') != bnr
@@ -248,6 +250,23 @@ func Test_augroup_warning()
au! VimEnter
endfunc
+func Test_BufReadCmdHelp()
+ " This used to cause access to free memory
+ au BufReadCmd * e +h
+ help
+
+ au! BufReadCmd
+endfunc
+
+func Test_BufReadCmdHelpJump()
+ " This used to cause access to free memory
+ au BufReadCmd * e +h{
+ " } to fix highlighting
+ call assert_fails('help', 'E434:')
+
+ au! BufReadCmd
+endfunc
+
func Test_augroup_deleted()
" This caused a crash before E936 was introduced
augroup x
@@ -1165,6 +1184,13 @@ func Test_nocatch_wipe_dummy_buffer()
au!
endfunc
+func Test_wipe_cbuffer()
+ sv x
+ au * * bw
+ lb
+ au!
+endfunc
+
" Test TextChangedI and TextChangedP
func Test_ChangedP()
" Nvim does not support test_override().
@@ -1245,3 +1271,22 @@ func Test_TextChangedI_with_setline()
call test_override('starting', 0)
bwipe!
endfunc
+
+func Test_Changed_FirstTime()
+ if !has('terminal') || has('gui_running')
+ return
+ endif
+ " Prepare file for TextChanged event.
+ call writefile([''], 'Xchanged.txt')
+ let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
+ call assert_equal('running', term_getstatus(buf))
+ " It's only adding autocmd, so that no event occurs.
+ call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
+ call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
+ call WaitFor({-> term_getstatus(buf) == 'finished'})
+ call assert_equal([''], readfile('Xchanged.txt'))
+
+ " clean up
+ call delete('Xchanged.txt')
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_join.vim b/src/nvim/testdir/test_join.vim
new file mode 100644
index 0000000000..1c97414164
--- /dev/null
+++ b/src/nvim/testdir/test_join.vim
@@ -0,0 +1,35 @@
+" Test for joining lines.
+
+func Test_join_with_count()
+ new
+ call setline(1, ['one', 'two', 'three', 'four'])
+ normal J
+ call assert_equal('one two', getline(1))
+ %del
+ call setline(1, ['one', 'two', 'three', 'four'])
+ normal 10J
+ call assert_equal('one two three four', getline(1))
+ quit!
+endfunc
+
+" Tests for setting the '[,'] marks when joining lines.
+func Test_join_marks()
+ enew
+ call append(0, [
+ \ "\t\tO sodales, ludite, vos qui",
+ \ "attamen consulite per voster honur. Tua pulchra " .
+ \ "facies me fay planszer milies",
+ \ "",
+ \ "This line.",
+ \ "Should be joined with the next line",
+ \ "and with this line"])
+
+ normal gg0gqj
+ call assert_equal([0, 1, 1, 0], getpos("'["))
+ call assert_equal([0, 2, 1, 0], getpos("']"))
+
+ /^This line/;'}-join
+ call assert_equal([0, 4, 11, 0], getpos("'["))
+ call assert_equal([0, 4, 67, 0], getpos("']"))
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index 268a153077..f9bd8b5246 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -230,4 +230,32 @@ func Test_tag_file_encoding()
call delete('Xtags1')
endfunc
+func Test_tagjump_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "void foo() {}",
+ \ "int main(int argc, char **argv)",
+ \ "{",
+ \ "\tfoo();",
+ \ "\treturn 0;",
+ \ "}",
+ \ ], 'Xmain.c')
+
+ call writefile([
+ \ "\x0c",
+ \ "Xmain.c,64",
+ \ "void foo() {}\x7ffoo\x011,0",
+ \ "int main(int argc, char **argv)\x7fmain\x012,14",
+ \ ], 'Xtags')
+ set tags=Xtags
+ ta foo
+ call assert_equal('void foo() {}', getline('.'))
+
+ call delete('Xtags')
+ call delete('Xmain.c')
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim
index 2d1557ebd9..3ad2025915 100644
--- a/src/nvim/testdir/test_taglist.vim
+++ b/src/nvim/testdir/test_taglist.vim
@@ -1,4 +1,4 @@
-" test 'taglist' function
+" test 'taglist' function and :tags command
func Test_taglist()
call writefile([
@@ -56,3 +56,8 @@ func Test_taglist_ctags_etags()
call delete('Xtags')
endfunc
+
+func Test_tags_too_long()
+ call assert_fails('tag ' . repeat('x', 1020), 'E426')
+ tags
+endfunc
diff --git a/src/nvim/testdir/test_user_func.vim b/src/nvim/testdir/test_user_func.vim
new file mode 100644
index 0000000000..e7a3701386
--- /dev/null
+++ b/src/nvim/testdir/test_user_func.vim
@@ -0,0 +1,96 @@
+" Test for user functions.
+" Also test an <expr> mapping calling a function.
+" Also test that a builtin function cannot be replaced.
+" Also test for regression when calling arbitrary expression.
+
+func Table(title, ...)
+ let ret = a:title
+ let idx = 1
+ while idx <= a:0
+ exe "let ret = ret . a:" . idx
+ let idx = idx + 1
+ endwhile
+ return ret
+endfunc
+
+func Compute(n1, n2, divname)
+ if a:n2 == 0
+ return "fail"
+ endif
+ exe "let g:" . a:divname . " = ". a:n1 / a:n2
+ return "ok"
+endfunc
+
+func Expr1()
+ silent! normal! v
+ return "111"
+endfunc
+
+func Expr2()
+ call search('XX', 'b')
+ return "222"
+endfunc
+
+func ListItem()
+ let g:counter += 1
+ return g:counter . '. '
+endfunc
+
+func ListReset()
+ let g:counter = 0
+ return ''
+endfunc
+
+func FuncWithRef(a)
+ unlet g:FuncRef
+ return a:a
+endfunc
+
+func Test_user_func()
+ let g:FuncRef=function("FuncWithRef")
+ let g:counter = 0
+ inoremap <expr> ( ListItem()
+ inoremap <expr> [ ListReset()
+ imap <expr> + Expr1()
+ imap <expr> * Expr2()
+ let g:retval = "nop"
+
+ call assert_equal('xxx4asdf', Table("xxx", 4, "asdf"))
+ call assert_equal('fail', Compute(45, 0, "retval"))
+ call assert_equal('nop', g:retval)
+ call assert_equal('ok', Compute(45, 5, "retval"))
+ call assert_equal(9, g:retval)
+ call assert_equal(333, g:FuncRef(333))
+
+ enew
+
+ normal oXX+-XX
+ call assert_equal('XX111-XX', getline('.'))
+ normal o---*---
+ call assert_equal('---222---', getline('.'))
+ normal o(one
+ call assert_equal('1. one', getline('.'))
+ normal o(two
+ call assert_equal('2. two', getline('.'))
+ normal o[(one again
+ call assert_equal('1. one again', getline('.'))
+
+ call assert_equal(3, max([1, 2, 3]))
+ call assert_fails("call extend(g:, {'max': function('min')})", 'E704')
+ call assert_equal(3, max([1, 2, 3]))
+
+ " Regression: the first line below used to throw ?E110: Missing ')'?
+ " Second is here just to prove that this line is correct when not skipping
+ " rhs of &&.
+ call assert_equal(0, (0 && (function('tr'))(1, 2, 3)))
+ call assert_equal(1, (1 && (function('tr'))(1, 2, 3)))
+
+ delfunc Table
+ delfunc Compute
+ delfunc Expr1
+ delfunc Expr2
+ delfunc ListItem
+ delfunc ListReset
+ unlet g:retval g:counter
+ enew!
+endfunc
diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua
index 67f6006d1d..7c3d48317b 100644
--- a/test/functional/legacy/packadd_spec.lua
+++ b/test/functional/legacy/packadd_spec.lua
@@ -15,7 +15,7 @@ describe('packadd', function()
source([=[
func SetUp()
- let s:topdir = expand(expand('%:p:h') . '/Xdir')
+ let s:topdir = expand(getcwd() . '/Xdir')
exe 'set packpath=' . s:topdir
let s:plugdir = expand(s:topdir . '/pack/mine/opt/mytest')
endfunc