aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2017-03-21 17:07:00 +0100
committerGitHub <noreply@github.com>2017-03-21 17:07:00 +0100
commit6baa669c10518b8751904a31899feb897fb7c995 (patch)
tree3c19fb1641ee978397416dd85e95e26e9703a83d /src
parent5657bb9ea6dfdf799f4d46d8e9022bd7382765e7 (diff)
downloadrneovim-6baa669c10518b8751904a31899feb897fb7c995.tar.gz
rneovim-6baa669c10518b8751904a31899feb897fb7c995.tar.bz2
rneovim-6baa669c10518b8751904a31899feb897fb7c995.zip
vim-patch:7.4.2164 (#6326)
Problem: It is not possible to use plugins in an "after" directory to tune the behavior of a package. Solution: First load plugins from non-after directories, then packages and finally plugins in after directories. Reset 'loadplugins' before executing --cmd arguments. https://github.com/vim/vim/commit/66459b7c98c67f8a9d39de8f08e8e8f1fca0e359 vim-patch:7.4.2172 vim-patch:7.4.2169 vim-patch:7.4.2177 vim-patch:7.4.2178 vim-patch:7.4.2184 vim-patch:8.0.0050 vim-patch:8.0.0105 vim-patch:8.0.0400 vim-patch:8.0.0405 Closes #6034
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_cmds2.c16
-rw-r--r--src/nvim/main.c13
-rw-r--r--src/nvim/testdir/setup.vim3
-rw-r--r--src/nvim/testdir/shared.vim214
-rw-r--r--src/nvim/testdir/test_startup.vim200
-rw-r--r--src/nvim/version.c12
-rw-r--r--src/nvim/vim.h2
7 files changed, 449 insertions, 11 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 36f50ae7a2..9fc4ef2a02 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -2361,12 +2361,25 @@ int do_in_path(char_u *path, char_u *name, int flags,
while (*rtp != NUL && ((flags & DIP_ALL) || !did_one)) {
// Copy the path from 'runtimepath' to buf[].
copy_option_part(&rtp, buf, MAXPATHL, ",");
+ size_t buflen = STRLEN(buf);
+
+ // Skip after or non-after directories.
+ if (flags & (DIP_NOAFTER | DIP_AFTER)) {
+ bool is_after = buflen >= 5
+ && STRCMP(buf + buflen - 5, "after") == 0;
+
+ if ((is_after && (flags & DIP_NOAFTER))
+ || (!is_after && (flags & DIP_AFTER))) {
+ continue;
+ }
+ }
+
if (name == NULL) {
(*callback)(buf, (void *)&cookie);
if (!did_one) {
did_one = (cookie == NULL);
}
- } else if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL) {
+ } else if (buflen + STRLEN(name) + 2 < MAXPATHL) {
add_pathsep((char *)buf);
tail = buf + STRLEN(buf);
@@ -2597,6 +2610,7 @@ static bool did_source_packages = false;
// ":packloadall"
// Find plugins in the package directories and source them.
+// "eap" is NULL when invoked during startup.
void ex_packloadall(exarg_T *eap)
{
if (!did_source_packages || (eap != NULL && eap->forceit)) {
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 4416bd067c..7b1c912f4b 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -326,6 +326,12 @@ int main(int argc, char **argv)
do_cmdline_cmd("augroup END");
#undef PROTO
+ // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
+ // Allows for setting 'loadplugins' there.
+ if (params.use_vimrc != NULL && strcmp(params.use_vimrc, "NONE") == 0) {
+ p_lpl = false;
+ }
+
/* Execute --cmd arguments. */
exe_pre_commands(&params);
@@ -1268,11 +1274,14 @@ static void set_window_layout(mparm_T *paramp)
static void load_plugins(void)
{
if (p_lpl) {
- source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL); // NOLINT
+ source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_NOAFTER); // NOLINT
TIME_MSG("loading plugins");
ex_packloadall(NULL);
TIME_MSG("loading packages");
+
+ source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER);
+ TIME_MSG("loading after plugins");
}
}
@@ -1708,8 +1717,6 @@ static void source_startup_scripts(const mparm_T *const parmp)
if (parmp->use_vimrc != NULL) {
if (strcmp(parmp->use_vimrc, "NONE") == 0
|| strcmp(parmp->use_vimrc, "NORC") == 0) {
- if (parmp->use_vimrc[2] == 'N')
- p_lpl = false; // don't load plugins either
} else {
if (do_source((char_u *)parmp->use_vimrc, FALSE, DOSO_NONE) != OK)
EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim
index 05257d566d..06f2199214 100644
--- a/src/nvim/testdir/setup.vim
+++ b/src/nvim/testdir/setup.vim
@@ -4,8 +4,9 @@ set noruler
set noshowcmd
set belloff=
-" Make sure 'runtimepath' does not include $HOME.
+" Make sure 'runtimepath' and 'packpath' does not include $HOME.
set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after
+let &packpath = &rtp
" Make sure $HOME does not get read or written.
let $HOME = '/does/not/exist'
diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim
new file mode 100644
index 0000000000..784e4a0a02
--- /dev/null
+++ b/src/nvim/testdir/shared.vim
@@ -0,0 +1,214 @@
+" Functions shared by several tests.
+
+" Get the name of the Python executable.
+" Also keeps it in s:python.
+func PythonProg()
+ " This test requires the Python command to run the test server.
+ " This most likely only works on Unix and Windows.
+ if has('unix')
+ " We also need the job feature or the pkill command to make sure the server
+ " can be stopped.
+ if !(executable('python') && (has('job') || executable('pkill')))
+ return ''
+ endif
+ let s:python = 'python'
+ elseif has('win32')
+ " Use Python Launcher for Windows (py.exe) if available.
+ if executable('py.exe')
+ let s:python = 'py.exe'
+ elseif executable('python.exe')
+ let s:python = 'python.exe'
+ else
+ return ''
+ endif
+ else
+ return ''
+ endif
+ return s:python
+endfunc
+
+" Run "cmd". Returns the job if using a job.
+func RunCommand(cmd)
+ let job = 0
+ if has('job')
+ let job = job_start(a:cmd, {"stoponexit": "hup"})
+ call job_setoptions(job, {"stoponexit": "kill"})
+ elseif has('win32')
+ exe 'silent !start cmd /c start "test_channel" ' . a:cmd
+ else
+ exe 'silent !' . a:cmd . '&'
+ endif
+ return job
+endfunc
+
+" Read the port number from the Xportnr file.
+func GetPort()
+ let l = []
+ for i in range(200)
+ try
+ let l = readfile("Xportnr")
+ catch
+ endtry
+ if len(l) >= 1
+ break
+ endif
+ sleep 10m
+ endfor
+ call delete("Xportnr")
+
+ if len(l) == 0
+ " Can't make the connection, give up.
+ return 0
+ endif
+ return l[0]
+endfunc
+
+" Run a Python server for "cmd" and call "testfunc".
+" Always kills the server before returning.
+func RunServer(cmd, testfunc, args)
+ " The Python program writes the port number in Xportnr.
+ call delete("Xportnr")
+
+ if len(a:args) == 1
+ let arg = ' ' . a:args[0]
+ else
+ let arg = ''
+ endif
+ let pycmd = s:python . " " . a:cmd . arg
+
+ try
+ let g:currentJob = RunCommand(pycmd)
+
+ " Wait for up to 2 seconds for the port number to be there.
+ let port = GetPort()
+ if port == 0
+ call assert_false(1, "Can't start " . a:cmd)
+ return
+ endif
+
+ call call(function(a:testfunc), [port])
+ catch
+ call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
+ finally
+ call s:kill_server(a:cmd)
+ endtry
+endfunc
+
+func s:kill_server(cmd)
+ if has('job')
+ if exists('g:currentJob')
+ call job_stop(g:currentJob)
+ unlet g:currentJob
+ endif
+ elseif has('win32')
+ let cmd = substitute(a:cmd, ".py", '', '')
+ call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"')
+ else
+ call system("pkill -f " . a:cmd)
+ endif
+endfunc
+
+" Wait for up to a second for "expr" to become true.
+" Return time slept in milliseconds. With the +reltime feature this can be
+" more than the actual waiting time. Without +reltime it can also be less.
+func WaitFor(expr)
+ " using reltime() is more accurate, but not always available
+ if has('reltime')
+ let start = reltime()
+ else
+ let slept = 0
+ endif
+ for i in range(100)
+ try
+ if eval(a:expr)
+ if has('reltime')
+ return float2nr(reltimefloat(reltime(start)) * 1000)
+ endif
+ return slept
+ endif
+ catch
+ endtry
+ if !has('reltime')
+ let slept += 10
+ endif
+ sleep 10m
+ endfor
+ return 1000
+endfunc
+
+" Wait for up to a given milliseconds.
+" With the +timers feature this waits for key-input by getchar(), Resume()
+" feeds key-input and resumes process. Return time waited in milliseconds.
+" Without +timers it uses simply :sleep.
+func Standby(msec)
+ if has('timers')
+ let start = reltime()
+ let g:_standby_timer = timer_start(a:msec, function('s:feedkeys'))
+ call getchar()
+ return float2nr(reltimefloat(reltime(start)) * 1000)
+ else
+ execute 'sleep ' a:msec . 'm'
+ return a:msec
+ endif
+endfunc
+
+func Resume()
+ if exists('g:_standby_timer')
+ call timer_stop(g:_standby_timer)
+ call s:feedkeys(0)
+ unlet g:_standby_timer
+ endif
+endfunc
+
+func s:feedkeys(timer)
+ call feedkeys('x', 'nt')
+endfunc
+
+" Get the command to run Vim, with -u NONE and --headless arguments.
+" Returns an empty string on error.
+func GetVimCommand()
+ let cmd = v:progpath
+ let cmd = substitute(cmd, '-u \f\+', '-u NONE', '')
+ if cmd !~ '-u NONE'
+ let cmd = cmd . ' -u NONE'
+ endif
+ let cmd .= ' --headless -i NONE'
+ let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '')
+ return cmd
+endfunc
+
+" Run Vim, using the "vimcmd" file and "-u NORC".
+" "before" is a list of Vim commands to be executed before loading plugins.
+" "after" is a list of Vim commands to be executed after loading plugins.
+" Plugins are not loaded, unless 'loadplugins' is set in "before".
+" Return 1 if Vim could be executed.
+func RunVim(before, after, arguments)
+ return RunVimPiped(a:before, a:after, a:arguments, '')
+endfunc
+
+func RunVimPiped(before, after, arguments, pipecmd)
+ let $NVIM_LOG_FILE='Xnvim.log'
+ let cmd = GetVimCommand()
+ if cmd == ''
+ return 0
+ endif
+ let args = ''
+ if len(a:before) > 0
+ call writefile(a:before, 'Xbefore.vim')
+ let args .= ' --cmd "so Xbefore.vim"'
+ endif
+ if len(a:after) > 0
+ call writefile(a:after, 'Xafter.vim')
+ let args .= ' -S Xafter.vim'
+ endif
+
+ exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments
+
+ if len(a:before) > 0
+ call delete('Xbefore.vim')
+ endif
+ if len(a:after) > 0
+ call delete('Xafter.vim')
+ endif
+ return 1
+endfunc
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
new file mode 100644
index 0000000000..f78d92f3ff
--- /dev/null
+++ b/src/nvim/testdir/test_startup.vim
@@ -0,0 +1,200 @@
+" Tests for startup.
+
+source shared.vim
+
+" Check that loading startup.vim works.
+func Test_startup_script()
+ throw 'skipped: Nvim does not need defaults.vim'
+ set compatible
+ source $VIMRUNTIME/defaults.vim
+
+ call assert_equal(0, &compatible)
+endfunc
+
+" Verify the order in which plugins are loaded:
+" 1. plugins in non-after directories
+" 2. packages
+" 3. plugins in after directories
+func Test_after_comes_later()
+ if !has('packages')
+ return
+ endif
+ let before = [
+ \ 'set nocp viminfo+=nviminfo',
+ \ 'set guioptions+=M',
+ \ 'let $HOME = "/does/not/exist"',
+ \ 'set loadplugins',
+ \ 'set rtp=Xhere,Xafter',
+ \ 'set packpath=Xhere,Xafter',
+ \ 'set nomore',
+ \ ]
+ let after = [
+ \ 'redir! > Xtestout',
+ \ 'scriptnames',
+ \ 'redir END',
+ \ 'quit',
+ \ ]
+ call mkdir('Xhere/plugin', 'p')
+ call writefile(['let done = 1'], 'Xhere/plugin/here.vim')
+ call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
+ call writefile(['let done = 1'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
+
+ call mkdir('Xafter/plugin', 'p')
+ call writefile(['let done = 1'], 'Xafter/plugin/later.vim')
+
+ if RunVim(before, after, '')
+
+ let lines = readfile('Xtestout')
+ let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim']
+ let found = []
+ for line in lines
+ for one in expected
+ if line =~ one
+ call add(found, one)
+ endif
+ endfor
+ endfor
+ call assert_equal(expected, found)
+ endif
+
+ call delete('Xtestout')
+ call delete('Xhere', 'rf')
+ call delete('Xafter', 'rf')
+endfunc
+
+func Test_help_arg()
+ if !has('unix') && has('gui')
+ " this doesn't work with gvim on MS-Windows
+ return
+ endif
+ if RunVim([], [], '--help >Xtestout')
+ let lines = readfile('Xtestout')
+ call assert_true(len(lines) > 20)
+ call assert_match('Usage:', lines[0])
+
+ " check if couple of lines are there
+ let found = []
+ for line in lines
+ if line =~ '-R.*Readonly mode'
+ call add(found, 'Readonly mode')
+ endif
+ " Watch out for a second --version line in the Gnome version.
+ if line =~ '--version.*Print version information and exit'
+ call add(found, "--version")
+ endif
+ endfor
+ call assert_equal(['--version'], found)
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_compatible_args()
+ throw "skipped: Nvim is always 'nocompatible'"
+ let after = [
+ \ 'call writefile([string(&compatible)], "Xtestout")',
+ \ 'set viminfo+=nviminfo',
+ \ 'quit',
+ \ ]
+ if RunVim([], after, '-C')
+ let lines = readfile('Xtestout')
+ call assert_equal('1', lines[0])
+ endif
+
+ if RunVim([], after, '-N')
+ let lines = readfile('Xtestout')
+ call assert_equal('0', lines[0])
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+func Test_file_args()
+ let after = [
+ \ 'call writefile(argv(), "Xtestout")',
+ \ 'qall',
+ \ ]
+ if RunVim([], after, '')
+ let lines = readfile('Xtestout')
+ call assert_equal(0, len(lines))
+ endif
+
+ if RunVim([], after, 'one')
+ let lines = readfile('Xtestout')
+ call assert_equal(1, len(lines))
+ call assert_equal('one', lines[0])
+ endif
+
+ if RunVim([], after, 'one two three')
+ let lines = readfile('Xtestout')
+ call assert_equal(3, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('two', lines[1])
+ call assert_equal('three', lines[2])
+ endif
+
+ if RunVim([], after, 'one -c echo two')
+ let lines = readfile('Xtestout')
+ call assert_equal(2, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('two', lines[1])
+ endif
+
+ if RunVim([], after, 'one -- -c echo two')
+ let lines = readfile('Xtestout')
+ call assert_equal(4, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('-c', lines[1])
+ call assert_equal('echo', lines[2])
+ call assert_equal('two', lines[3])
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+func Test_startuptime()
+ if !has('startuptime')
+ return
+ endif
+ let after = ['qall']
+ if RunVim([], after, '--startuptime Xtestout one')
+ let lines = readfile('Xtestout')
+ let expected = ['parsing arguments', 'inits 3', 'opening buffers']
+ let found = []
+ for line in lines
+ for exp in expected
+ if line =~ exp
+ call add(found, exp)
+ endif
+ endfor
+ endfor
+ call assert_equal(expected, found)
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_read_stdin()
+ let after = [
+ \ 'write Xtestout',
+ \ 'quit!',
+ \ ]
+ if RunVimPiped([], after, '-', 'echo something | ')
+ let lines = readfile('Xtestout')
+ " MS-Windows adds a space after the word
+ call assert_equal(['something'], split(lines[0]))
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_progpath()
+ " Tests normally run with "./vim" or "../vim", these must have been expanded
+ " to a full path.
+ if has('unix')
+ call assert_equal('/', v:progpath[0])
+ elseif has('win32')
+ call assert_equal(':', v:progpath[1])
+ call assert_match('[/\\]', v:progpath[2])
+ endif
+
+ " Only expect "vim" to appear in v:progname.
+ call assert_match('vim\c', v:progname)
+endfunc
diff --git a/src/nvim/version.c b/src/nvim/version.c
index bf13e52be4..1d4239b215 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -257,27 +257,27 @@ static int included_patches[] = {
2187,
// 2186 NA
2185,
- // 2184,
+ 2184,
2183,
// 2182 NA
// 2181,
// 2180,
// 2179,
- // 2178,
- // 2177,
+ 2178,
+ 2177,
// 2176 NA
2175,
2174,
// 2173,
- // 2172,
+ 2172,
// 2171,
// 2170,
- // 2169,
+ 2169,
// 2168 NA
// 2167 NA
// 2166 NA
// 2165,
- // 2164,
+ 2164,
2163,
2162,
// 2161,
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index 458d23fcad..87e9889465 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -325,6 +325,8 @@ enum {
#define DIP_START 0x08 // also use "start" directory in 'packpath'
#define DIP_OPT 0x10 // also use "opt" directory in 'packpath'
#define DIP_NORTP 0x20 // do not use 'runtimepath'
+#define DIP_NOAFTER 0x40 // skip "after" directories
+#define DIP_AFTER 0x80 // only use "after" directories
// Lowest number used for window ID. Cannot have this many windows per tab.
#define LOWEST_WIN_ID 1000