mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
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.
66459b7c98
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
This commit is contained in:
parent
5657bb9ea6
commit
6baa669c10
@ -457,6 +457,8 @@ accordingly. Vim proceeds in this order:
|
||||
searched for the "plugin" sub-directory and all files ending in ".vim"
|
||||
will be sourced (in alphabetical order per directory), also in
|
||||
subdirectories.
|
||||
However, directories in 'runtimepath' ending in "after" are skipped
|
||||
here and only loaded after packages, see below.
|
||||
Loading plugins won't be done when:
|
||||
- The 'loadplugins' option was reset in a vimrc file.
|
||||
- The |--noplugin| command line argument is used.
|
||||
@ -464,13 +466,18 @@ accordingly. Vim proceeds in this order:
|
||||
- When Vim was compiled without the |+eval| feature.
|
||||
Note that using "-c 'set noloadplugins'" doesn't work, because the
|
||||
commands from the command line have not been executed yet. You can
|
||||
use "--cmd 'set noloadplugins'" |--cmd|.
|
||||
use "--cmd 'set noloadplugins'" or "--cmd 'set loadplugins'" |--cmd|.
|
||||
|
||||
Packages are loaded. These are plugins, as above, but found in the
|
||||
"start" directory of each entry in 'packpath'. Every plugin directory
|
||||
found is added in 'runtimepath' and then the plugins are sourced. See
|
||||
|packages|.
|
||||
|
||||
The plugins scripts are loaded, as above, but now only the directories
|
||||
ending in "after" are used. Note that 'runtimepath' will have changed
|
||||
if packages have been found, but that should not add a directory
|
||||
ending in "after".
|
||||
|
||||
7. Set 'shellpipe' and 'shellredir'
|
||||
The 'shellpipe' and 'shellredir' options are set according to the
|
||||
value of the 'shell' option, unless they have been set before.
|
||||
|
@ -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)) {
|
||||
|
@ -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(¶ms);
|
||||
|
||||
@ -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);
|
||||
|
@ -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'
|
||||
|
214
src/nvim/testdir/shared.vim
Normal file
214
src/nvim/testdir/shared.vim
Normal file
@ -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
|
200
src/nvim/testdir/test_startup.vim
Normal file
200
src/nvim/testdir/test_startup.vim
Normal file
@ -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
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user