aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/provider/python.vim6
-rw-r--r--runtime/autoload/remote/define.vim (renamed from runtime/autoload/rpc/define.vim)36
-rw-r--r--runtime/autoload/remote/host.vim (renamed from runtime/autoload/rpc/host.vim)47
-rw-r--r--runtime/doc/Makefile4
-rw-r--r--runtime/doc/external_plugin.txt104
-rw-r--r--runtime/doc/msgpack_rpc.txt4
-rw-r--r--runtime/doc/nvim_intro.txt2
-rw-r--r--runtime/doc/remote_plugin.txt136
-rw-r--r--runtime/plugin/external_plugins.vim5
-rw-r--r--runtime/plugin/rplugin.vim5
-rw-r--r--src/nvim/edit.c12
-rw-r--r--src/nvim/ex_getln.c14
-rw-r--r--src/nvim/getchar.c1
-rw-r--r--src/nvim/message.c6
-rw-r--r--src/nvim/normal.c14
-rw-r--r--src/nvim/os/event.c20
-rw-r--r--src/nvim/os/input.c38
-rw-r--r--src/nvim/testdir/test101.in45
-rw-r--r--src/nvim/testdir/test101.ok11
-rw-r--r--src/nvim/testdir/test104.in30
-rw-r--r--src/nvim/testdir/test104.ok13
-rw-r--r--src/nvim/testdir/test105.in45
-rw-r--r--src/nvim/testdir/test105.ok29
-rw-r--r--src/nvim/testdir/test21.in19
-rw-r--r--src/nvim/testdir/test21.ok2
-rw-r--r--src/nvim/testdir/test25.in31
-rw-r--r--src/nvim/testdir/test25.ok1
-rw-r--r--src/nvim/testdir/test26.in44
-rw-r--r--src/nvim/testdir/test26.ok10
-rw-r--r--src/nvim/testdir/test33.in34
-rw-r--r--src/nvim/testdir/test33.ok23
-rw-r--r--src/nvim/testdir/test43.in34
-rw-r--r--src/nvim/testdir/test43.ok11
-rw-r--r--src/nvim/testdir/test5.in29
-rw-r--r--src/nvim/testdir/test5.ok9
-rw-r--r--src/nvim/testdir/test51.in36
-rw-r--r--src/nvim/testdir/test51.ok20
-rw-r--r--src/nvim/testdir/test66.in33
-rw-r--r--src/nvim/testdir/test66.ok16
-rw-r--r--src/nvim/testdir/test67.in33
-rw-r--r--src/nvim/testdir/test67.ok10
-rw-r--r--src/nvim/testdir/test75.in41
-rw-r--r--src/nvim/testdir/test75.ok7
-rw-r--r--test/functional/fixtures/autoload/Test104.vim (renamed from src/nvim/testdir/sautest/autoload/Test104.vim)0
-rw-r--r--test/functional/helpers.lua61
-rw-r--r--test/functional/job/job_spec.lua11
-rw-r--r--test/functional/legacy/004_bufenter_with_modelines_spec.lua4
-rw-r--r--test/functional/legacy/005_bufleave_delete_buffer.lua71
-rw-r--r--test/functional/legacy/025_jump_tag_hidden_spec.lua50
-rw-r--r--test/functional/legacy/026_execute_while_if_spec.lua66
-rw-r--r--test/functional/legacy/033_lisp_indent_spec.lua73
-rw-r--r--test/functional/legacy/043_magic_settings_spec.lua61
-rw-r--r--test/functional/legacy/051_highlight_spec.lua70
-rw-r--r--test/functional/legacy/066_visual_block_tab_spec.lua64
-rw-r--r--test/functional/legacy/067_augroup_exists_spec.lua46
-rw-r--r--test/functional/legacy/075_maparg_spec.lua58
-rw-r--r--test/functional/legacy/101_hlsearch_spec.lua63
-rw-r--r--test/functional/legacy/104_let_assignment.lua54
-rw-r--r--test/functional/legacy/105_filename_modifiers_spec.lua79
-rw-r--r--test/functional/runtime/autoload/remote/define_spec.lua (renamed from test/functional/runtime/autoload/rpc/define_spec.lua)26
-rw-r--r--test/functional/shell/viml_system_spec.lua1
61 files changed, 1067 insertions, 861 deletions
diff --git a/runtime/autoload/provider/python.vim b/runtime/autoload/provider/python.vim
index 9ca81c35f4..53b984dfe2 100644
--- a/runtime/autoload/provider/python.vim
+++ b/runtime/autoload/provider/python.vim
@@ -11,11 +11,11 @@ let s:loaded_python_provider = 1
let s:plugin_path = expand('<sfile>:p:h').'/script_host.py'
" The python provider plugin will run in a separate instance of the python
" host.
-call rpc#host#RegisterClone('legacy-python-provider', 'python')
-call rpc#host#RegisterPlugin('legacy-python-provider', s:plugin_path, [])
+call remote#host#RegisterClone('legacy-python-provider', 'python')
+call remote#host#RegisterPlugin('legacy-python-provider', s:plugin_path, [])
" Ensure that we can load the python host before bootstrapping
try
- let s:host = rpc#host#Require('legacy-python-provider')
+ let s:host = remote#host#Require('legacy-python-provider')
catch
echomsg v:exception
finish
diff --git a/runtime/autoload/rpc/define.vim b/runtime/autoload/remote/define.vim
index e7817c5fac..dd2482998d 100644
--- a/runtime/autoload/rpc/define.vim
+++ b/runtime/autoload/remote/define.vim
@@ -1,4 +1,4 @@
-function! rpc#define#CommandOnHost(host, method, sync, name, opts)
+function! remote#define#CommandOnHost(host, method, sync, name, opts)
let prefix = ''
if has_key(a:opts, 'range')
@@ -28,7 +28,7 @@ function! rpc#define#CommandOnHost(host, method, sync, name, opts)
endif
exe s:GetCommandPrefix(a:name, a:opts)
- \ .' call rpc#define#CommandBootstrap("'.a:host.'"'
+ \ .' call remote#define#CommandBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"'
@@ -38,11 +38,11 @@ function! rpc#define#CommandOnHost(host, method, sync, name, opts)
endfunction
-function! rpc#define#CommandBootstrap(host, method, sync, name, opts, forward)
- let channel = rpc#host#Require(a:host)
+function! remote#define#CommandBootstrap(host, method, sync, name, opts, forward)
+ let channel = remote#host#Require(a:host)
if channel
- call rpc#define#CommandOnChannel(channel, a:method, a:sync, a:name, a:opts)
+ call remote#define#CommandOnChannel(channel, a:method, a:sync, a:name, a:opts)
exe a:forward
else
exe 'delcommand '.a:name
@@ -51,7 +51,7 @@ function! rpc#define#CommandBootstrap(host, method, sync, name, opts, forward)
endfunction
-function! rpc#define#CommandOnChannel(channel, method, sync, name, opts)
+function! remote#define#CommandOnChannel(channel, method, sync, name, opts)
let rpcargs = [a:channel, '"'.a:method.'"']
if has_key(a:opts, 'nargs')
" -nargs, pass arguments in a list
@@ -87,12 +87,12 @@ function! rpc#define#CommandOnChannel(channel, method, sync, name, opts)
endfunction
-function! rpc#define#AutocmdOnHost(host, method, sync, name, opts)
+function! remote#define#AutocmdOnHost(host, method, sync, name, opts)
let group = s:GetNextAutocmdGroup()
let forward = '"doau '.group.' '.a:name.' ".'.'expand("<amatch>")'
let a:opts.group = group
let bootstrap_def = s:GetAutocmdPrefix(a:name, a:opts)
- \ .' call rpc#define#AutocmdBootstrap("'.a:host.'"'
+ \ .' call remote#define#AutocmdBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"'
@@ -103,12 +103,12 @@ function! rpc#define#AutocmdOnHost(host, method, sync, name, opts)
endfunction
-function! rpc#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
- let channel = rpc#host#Require(a:host)
+function! remote#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
+ let channel = remote#host#Require(a:host)
exe 'autocmd! '.a:opts.group
if channel
- call rpc#define#AutocmdOnChannel(channel, a:method, a:sync, a:name,
+ call remote#define#AutocmdOnChannel(channel, a:method, a:sync, a:name,
\ a:opts)
exe eval(a:forward)
else
@@ -118,7 +118,7 @@ function! rpc#define#AutocmdBootstrap(host, method, sync, name, opts, forward)
endfunction
-function! rpc#define#AutocmdOnChannel(channel, method, sync, name, opts)
+function! remote#define#AutocmdOnChannel(channel, method, sync, name, opts)
let rpcargs = [a:channel, '"'.a:method.'"']
call s:AddEval(rpcargs, a:opts)
@@ -128,10 +128,10 @@ function! rpc#define#AutocmdOnChannel(channel, method, sync, name, opts)
endfunction
-function! rpc#define#FunctionOnHost(host, method, sync, name, opts)
+function! remote#define#FunctionOnHost(host, method, sync, name, opts)
let group = s:GetNextAutocmdGroup()
exe 'autocmd! '.group.' FuncUndefined '.a:name
- \ .' call rpc#define#FunctionBootstrap("'.a:host.'"'
+ \ .' call remote#define#FunctionBootstrap("'.a:host.'"'
\ . ', "'.a:method.'"'
\ . ', "'.a:sync.'"'
\ . ', "'.a:name.'"'
@@ -141,13 +141,13 @@ function! rpc#define#FunctionOnHost(host, method, sync, name, opts)
endfunction
-function! rpc#define#FunctionBootstrap(host, method, sync, name, opts, group)
- let channel = rpc#host#Require(a:host)
+function! remote#define#FunctionBootstrap(host, method, sync, name, opts, group)
+ let channel = remote#host#Require(a:host)
exe 'autocmd! '.a:group
exe 'augroup! '.a:group
if channel
- call rpc#define#FunctionOnChannel(channel, a:method, a:sync, a:name,
+ call remote#define#FunctionOnChannel(channel, a:method, a:sync, a:name,
\ a:opts)
else
echoerr 'Host "'a:host.'" for "'.a:name.'" function is not available'
@@ -155,7 +155,7 @@ function! rpc#define#FunctionBootstrap(host, method, sync, name, opts, group)
endfunction
-function! rpc#define#FunctionOnChannel(channel, method, sync, name, opts)
+function! remote#define#FunctionOnChannel(channel, method, sync, name, opts)
let rpcargs = [a:channel, '"'.a:method.'"', 'a:000']
call s:AddEval(rpcargs, a:opts)
diff --git a/runtime/autoload/rpc/host.vim b/runtime/autoload/remote/host.vim
index 177d816df0..54a8bb3c41 100644
--- a/runtime/autoload/rpc/host.vim
+++ b/runtime/autoload/remote/host.vim
@@ -2,11 +2,12 @@ let s:hosts = {}
let s:plugin_patterns = {
\ 'python': '*.py'
\ }
-let s:external_plugins = fnamemodify($MYVIMRC, ':p:h').'/.external_plugins~'
+let s:remote_plugins_manifest = fnamemodify($MYVIMRC, ':p:h')
+ \.'/.'.fnamemodify($MYVIMRC, ':t').'-rplugin~'
" Register a host by associating it with a factory(funcref)
-function! rpc#host#Register(name, factory)
+function! remote#host#Register(name, factory)
let s:hosts[a:name] = {'factory': a:factory, 'channel': 0, 'initialized': 0}
if type(a:factory) == type(1) && a:factory
" Passed a channel directly
@@ -19,7 +20,7 @@ endfunction
" as `source`, but it will run as a different process. This can be used by
" plugins that should run isolated from other plugins created for the same host
" type
-function! rpc#host#RegisterClone(name, orig_name)
+function! remote#host#RegisterClone(name, orig_name)
if !has_key(s:hosts, a:orig_name)
throw 'No host named "'.a:orig_name.'" is registered'
endif
@@ -29,7 +30,7 @@ endfunction
" Get a host channel, bootstrapping it if necessary
-function! rpc#host#Require(name)
+function! remote#host#Require(name)
if !has_key(s:hosts, a:name)
throw 'No host named "'.a:name.'" is registered'
endif
@@ -42,7 +43,7 @@ function! rpc#host#Require(name)
endfunction
-function! rpc#host#IsRunning(name)
+function! remote#host#IsRunning(name)
if !has_key(s:hosts, a:name)
throw 'No host named "'.a:name.'" is registered'
endif
@@ -54,7 +55,7 @@ endfunction
" autocmd(async) and one function(sync):
"
" let s:plugin_path = expand('<sfile>:p:h').'/nvim_plugin.py'
-" call rpc#host#RegisterPlugin('python', s:plugin_path, [
+" call remote#host#RegisterPlugin('python', s:plugin_path, [
" \ {'type': 'command', 'name': 'PyCmd', 'sync': 1, 'opts': {}},
" \ {'type': 'command', 'name': 'PyAsyncCmd', 'sync': 0, 'opts': {'eval': 'cursor()'}},
" \ {'type': 'autocmd', 'name': 'BufEnter', 'sync': 0, 'opts': {'eval': 'expand("<afile>")'}},
@@ -63,7 +64,7 @@ endfunction
"
" The third item in a declaration is a boolean: non zero means the command,
" autocommand or function will be executed synchronously with rpcrequest.
-function! rpc#host#RegisterPlugin(host, path, specs)
+function! remote#host#RegisterPlugin(host, path, specs)
let plugins = s:PluginsForHost(a:host)
for plugin in plugins
@@ -72,7 +73,7 @@ function! rpc#host#RegisterPlugin(host, path, specs)
endif
endfor
- if rpc#host#IsRunning(a:host)
+ if remote#host#IsRunning(a:host)
" For now we won't allow registration of plugins when the host is already
" running.
throw 'Host "'.a:host.'" is already running'
@@ -86,7 +87,7 @@ function! rpc#host#RegisterPlugin(host, path, specs)
let rpc_method = a:path
if type == 'command'
let rpc_method .= ':command:'.name
- call rpc#define#CommandOnHost(a:host, rpc_method, sync, name, opts)
+ call remote#define#CommandOnHost(a:host, rpc_method, sync, name, opts)
elseif type == 'autocmd'
" Since multiple handlers can be attached to the same autocmd event by a
" single plugin, we need a way to uniquely identify the rpc method to
@@ -94,10 +95,10 @@ function! rpc#host#RegisterPlugin(host, path, specs)
" name(This still has a limit: one handler per event/pattern combo, but
" there's no need to allow plugins define multiple handlers in that case)
let rpc_method .= ':autocmd:'.name.':'.get(opts, 'pattern', '*')
- call rpc#define#AutocmdOnHost(a:host, rpc_method, sync, name, opts)
+ call remote#define#AutocmdOnHost(a:host, rpc_method, sync, name, opts)
elseif type == 'function'
let rpc_method .= ':function:'.name
- call rpc#define#FunctionOnHost(a:host, rpc_method, sync, name, opts)
+ call remote#define#FunctionOnHost(a:host, rpc_method, sync, name, opts)
else
echoerr 'Invalid declaration type: '.type
endif
@@ -107,9 +108,9 @@ function! rpc#host#RegisterPlugin(host, path, specs)
endfunction
-function! rpc#host#LoadExternalPlugins()
- if filereadable(s:external_plugins)
- exe 'source '.s:external_plugins
+function! remote#host#LoadRemotePlugins()
+ if filereadable(s:remote_plugins_manifest)
+ exe 'source '.s:remote_plugins_manifest
endif
endfunction
@@ -117,17 +118,17 @@ endfunction
function! s:RegistrationCommands(host)
" Register a temporary host clone for discovering specs
let host_id = a:host.'-registration-clone'
- call rpc#host#RegisterClone(host_id, a:host)
+ call remote#host#RegisterClone(host_id, a:host)
let pattern = s:plugin_patterns[a:host]
- let paths = globpath(&rtp, 'plugin/external/'.a:host.'/'.pattern, 0, 1)
+ let paths = globpath(&rtp, 'rplugin/'.a:host.'/'.pattern, 0, 1)
for path in paths
- call rpc#host#RegisterPlugin(host_id, path, [])
+ call remote#host#RegisterPlugin(host_id, path, [])
endfor
- let channel = rpc#host#Require(host_id)
+ let channel = remote#host#Require(host_id)
let lines = []
for path in paths
let specs = rpcrequest(channel, 'specs', path)
- call add(lines, "call rpc#host#RegisterPlugin('".a:host
+ call add(lines, "call remote#host#RegisterPlugin('".a:host
\ ."', '".path."', [")
for spec in specs
call add(lines, " \\ ".string(spec).",")
@@ -142,7 +143,7 @@ function! s:RegistrationCommands(host)
endfunction
-function! s:UpdateExternalPlugins()
+function! s:UpdateRemotePlugins()
let commands = []
let hosts = keys(s:hosts)
for host in hosts
@@ -153,11 +154,11 @@ function! s:UpdateExternalPlugins()
\ + ['', '']
endif
endfor
- call writefile(commands, s:external_plugins)
+ call writefile(commands, s:remote_plugins_manifest)
endfunction
-command! UpdateExternalPlugins call s:UpdateExternalPlugins()
+command! UpdateRemotePlugins call s:UpdateRemotePlugins()
let s:plugins_for_host = {}
@@ -238,5 +239,5 @@ function! s:RequirePythonHost(name)
throw 'Failed to load python host'
endfunction
-call rpc#host#Register('python', function('s:RequirePythonHost'))
+call remote#host#Register('python', function('s:RequirePythonHost'))
" }}}
diff --git a/runtime/doc/Makefile b/runtime/doc/Makefile
index 48674a773f..82fd921038 100644
--- a/runtime/doc/Makefile
+++ b/runtime/doc/Makefile
@@ -21,6 +21,7 @@ DOCS = \
digraph.txt \
editing.txt \
eval.txt \
+ remote_plugin.txt \
farsi.txt \
filetype.txt \
fold.txt \
@@ -53,6 +54,7 @@ DOCS = \
msgpack_rpc.txt \
nvim_clipboard.txt \
nvim_intro.txt \
+ nvim_provider.txt \
nvim_python.txt \
options.txt \
os_dos.txt \
@@ -140,6 +142,7 @@ HTMLS = \
digraph.html \
editing.html \
eval.html \
+ remote_plugin.html \
farsi.html \
filetype.html \
fold.html \
@@ -171,6 +174,7 @@ HTMLS = \
msgpack_rpc.html \
nvim_clipboard.html \
nvim_intro.html \
+ nvim_provider.html \
nvim_python.html \
options.html \
os_dos.html \
diff --git a/runtime/doc/external_plugin.txt b/runtime/doc/external_plugin.txt
deleted file mode 100644
index 3f7772c906..0000000000
--- a/runtime/doc/external_plugin.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-*external_plugin.txt* For Nvim. {Nvim}
-
-
- NVIM REFERENCE MANUAL by Thiago de Arruda
-
-
-Nvim support for external plugins *external-plugin*
-
-1. Introduction |external-plugin-intro|
-2. Plugin Hosts |external-plugin-hosts|
-3. Example |external-plugin-example|
-
-==============================================================================
-1. Introduction *external-plugin-intro*
-
-A big Nvim goal is to allow extensibility in arbitrary programming languages
-without requiring direct support from the editor. This is achieved with
-external plugins, coprocesses that have a direct communication channel(via
-|msgpack-rpc|) with the Nvim process.
-
-Even though these plugins are running in separate processes, they can call, be
-called, and receive events just as if the code was being executed in the main
-process.
-
-==============================================================================
-2. Plugin Hosts *external-plugin-hosts*
-
-While plugins can be implemented as arbitrary programs that communicate
-directly with Nvim API and are called via |rpcrequest()| and |rpcnotify()|,
-that is not the best approach available. Instead, developers should first
-check if a plugin host implementation is available for their favorite
-programming language.
-
-Plugin hosts are programs that provide a high level environment for plugins,
-and also take care of most boilerplate involved in defining commands, autocmds
-and functions that are implemented over msgpack-rpc connections. They are
-loaded the first time one of it's registered plugins are required, keeping
-Nvim startup as fast a possible despite the number of installed plugins/hosts.
-
-==============================================================================
-3. Example *external-plugin-example*
-
-The best way to learn how to create external plugins is with an example, so
-let's see how to implement a very useless python plugin that exports a
-command, a function and an autocmd(requires configuration detailed in
-|nvim-python| to work).
-
-The plugin is called 'Limit', and all it does is limit the number of "calls"
-made to it. Here's the plugin source code:
->
- import neovim
-
- @neovim.plugin
- class Limit(object):
- def __init__(self, vim):
- self.vim = vim
- self.calls = 0
-
- @neovim.command('Cmd', range='', nargs='*', sync=True)
- def command_handler(self, args, range):
- self._increment_calls()
- self.vim.current.line = (
- 'Command: Called %d times, args: %s, range: %s' % (self.calls,
- args,
- range))
-
- @neovim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")',
- sync=True)
- def autocmd_handler(self, filename):
- self._increment_calls()
- self.vim.current.line = (
- 'Autocmd: Called %s times, file: %s' % (self.calls, filename))
-
- @neovim.function('Func')
- def function_handler(self, args):
- self._increment_calls()
- self.vim.current.line = (
- 'Function: Called %d times, args: %s' % (self.calls, args))
-
- def _increment_calls(self):
- if self.calls == 5:
- raise Exception('Too many calls!')
- self.calls += 1
-<
-
-This code needs to be saved to "external/python/limit.py" in a runtime
-directory(~/.nvim/plugin/external/python/limit.py for example).
-
-As can be seen, the plugin is implemented using pure python idioms(classes,
-methods and decorators). It is the host's responsibility to translate
-language-specific idioms to vimscript entities. Notice that the exported
-command and autocmd are defined with the "sync" flag, which tells Nvim to call
-it using |rpcrequest()|. Since the "Func" doesn't set "sync", it will be
-called using |rpcnotify()|.
-
-Just installing the plugin to ~/.nvim/plugin/external/python/limit.py won't
-make Nvim load it at startup. That is because external plugins are loaded
-only when required, and for that Nvim must be fed with information about
-installed external plugins with the `:UpdateExternalPlugins` command(must be
-called whenever plugins are updated, this is analogous to the |:helptags|
-command but for external plugins).
-
-==============================================================================
- vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/msgpack_rpc.txt b/runtime/doc/msgpack_rpc.txt
index 41f387b452..8e53241775 100644
--- a/runtime/doc/msgpack_rpc.txt
+++ b/runtime/doc/msgpack_rpc.txt
@@ -113,7 +113,9 @@ string 'hello world!' on the current nvim instance:
A better way is to use the python REPL with the `neovim` package, where API
functions can be called interactively:
>
- >>> import neovim; nvim = neovim.connect('[address]')
+ >>> from neovim import socket_session, Nvim
+ >>> session = socket_session('[address]')
+ >>> nvim = Nvim.from_session(session)
>>> nvim.command('echo "hello world!"')
<
==============================================================================
diff --git a/runtime/doc/nvim_intro.txt b/runtime/doc/nvim_intro.txt
index 177c906db6..8a82a09890 100644
--- a/runtime/doc/nvim_intro.txt
+++ b/runtime/doc/nvim_intro.txt
@@ -17,7 +17,7 @@ differentiate Nvim from Vim:
2. Job control |job-control|
3. Python plugins |nvim-python|
4. Clipboard integration |nvim-clipboard|
-5. External plugins |external-plugin|
+5. Remote plugins |remote-plugin|
6. Provider infrastructure |nvim-provider|
==============================================================================
diff --git a/runtime/doc/remote_plugin.txt b/runtime/doc/remote_plugin.txt
new file mode 100644
index 0000000000..ca7e763d1b
--- /dev/null
+++ b/runtime/doc/remote_plugin.txt
@@ -0,0 +1,136 @@
+*remote_plugin.txt* For Nvim. {Nvim}
+
+
+ NVIM REFERENCE MANUAL by Thiago de Arruda
+
+
+Nvim support for remote plugins *remote-plugin*
+
+1. Introduction |remote-plugin-intro|
+2. Plugin hosts |remote-plugin-hosts|
+3. Example |remote-plugin-example|
+4. Plugin manifest |remote-plugin-manifest|
+
+==============================================================================
+1. Introduction *remote-plugin-intro*
+
+A big Nvim goal is to allow extensibility in arbitrary programming languages
+without requiring direct support from the editor. This is achieved with
+remote plugins, coprocesses that have a direct communication channel(via
+|msgpack-rpc|) with the Nvim process.
+
+Even though these plugins are running in separate processes, they can call, be
+called, and receive events just as if the code was being executed in the main
+process.
+
+==============================================================================
+2. Plugin hosts *remote-plugin-hosts*
+
+While plugins can be implemented as arbitrary programs that communicate
+directly with Nvim API and are called via |rpcrequest()| and |rpcnotify()|,
+that is not the best approach available. Instead, developers should first
+check if a plugin host implementation is available for their favorite
+programming language.
+
+Plugin hosts are programs that provide a high level environment for plugins,
+and also take care of most boilerplate involved in defining commands, autocmds
+and functions that are implemented over msgpack-rpc connections. They are
+loaded the first time one of its registered plugins are required, keeping
+Nvim startup as fast a possible despite the number of installed plugins/hosts.
+
+==============================================================================
+3. Example *remote-plugin-example*
+
+The best way to learn about remote plugins is with an example, so let's see
+how a very useless python plugin looks like. This plugin exports a command, a
+function and an autocmd. The plugin is called 'Limit', and all it does is
+limit the number of requests made to it. Here's the plugin source code:
+>
+ import neovim
+
+ @neovim.plugin
+ class Limit(object):
+ def __init__(self, vim):
+ self.vim = vim
+ self.calls = 0
+
+ @neovim.command('Cmd', range='', nargs='*', sync=True)
+ def command_handler(self, args, range):
+ self._increment_calls()
+ self.vim.current.line = (
+ 'Command: Called %d times, args: %s, range: %s' % (self.calls,
+ args,
+ range))
+
+ @neovim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")',
+ sync=True)
+ def autocmd_handler(self, filename):
+ self._increment_calls()
+ self.vim.current.line = (
+ 'Autocmd: Called %s times, file: %s' % (self.calls, filename))
+
+ @neovim.function('Func')
+ def function_handler(self, args):
+ self._increment_calls()
+ self.vim.current.line = (
+ 'Function: Called %d times, args: %s' % (self.calls, args))
+
+ def _increment_calls(self):
+ if self.calls == 5:
+ raise Exception('Too many calls!')
+ self.calls += 1
+<
+
+As can be seen, the plugin is implemented using pure python idioms(classes,
+methods and decorators), the translation between these language-specific
+idioms to vimscript occurs while the plugin manifest is being generated(see
+below).
+
+Notice that the exported command and autocmd are defined with the "sync" flag,
+which affects how Nvim calls the plugin: with "sync" the |rpcrequest()|
+function is used, which will block Nvim until the handler function returns a
+value. Without the "sync" flag, the call is made using a fire and forget
+approach with |rpcnotify()|(return values or exceptions raised in the handler
+function are ignored)
+
+To test the above plugin, it must be saved in "rplugin/python" in a
+'runtimepath' directory(~/.nvim/rplugin/python/limit.py for example).
+Then, the remote plugin manifest must be generated with
+`:UpdateRemotePlugins`.
+
+==============================================================================
+4. remote plugin manifest *remote-plugin-manifest*
+
+Just installing remote plugins to "rplugin/{host}" isn't enough to
+load them at startup. The `:UpdateRemotePlugins` command must be executed
+every time a remote plugin is installed, updated, or deleted.
+
+`:UpdateRemotePlugins` will generate the remote plugin manifest, a special
+vimscript file containing declarations for all vimscript entities
+(commands/autocommands/functions) defined by all remote plugins, with each
+entity associated with the host and plugin path. The manifest can be seen as a
+generated extension to the user's vimrc(it even has the vimrc filename
+prepended).
+
+The manifest declarations are nothing but calls to the remote#host#RegisterPlugin
+function, which will take care of bootstrapping the host as soon as the
+declared command, autocommand or function is used for the first time.
+
+The manifest generation step is necessary to keep editor startup fast in
+situations where a user has remote plugins with different hosts. For
+example, imagine a user that has three plugins, for python, java and .NET
+hosts respectively, if we were to load all three plugins at startup, then
+three language runtimes would also be spawned which could take seconds!
+
+With the manifest, each host will only be loaded when required. Continuing
+with the example, imagine the java plugin is a semantic completion engine for
+java files, if it defines an BufEnter *.java autocommand then the java host
+will only be spawned when java source files are loaded.
+
+If the explicit call to `:UpdateRemotePlugins` seems incovenient, try
+to see it like this: Its a way to give IDE-like capabilities to nvim while
+still keeping it a fast/lightweight editor for general use. It can also be
+seen as an analogous to the |:helptags| facility.
+
+==============================================================================
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/plugin/external_plugins.vim b/runtime/plugin/external_plugins.vim
deleted file mode 100644
index 1c5fa1ab8e..0000000000
--- a/runtime/plugin/external_plugins.vim
+++ /dev/null
@@ -1,5 +0,0 @@
-if exists('loaded_external_plugins') || &cp
- finish
-endif
-let loaded_external_plugins = 1
-call rpc#host#LoadExternalPlugins()
diff --git a/runtime/plugin/rplugin.vim b/runtime/plugin/rplugin.vim
new file mode 100644
index 0000000000..2b2d333738
--- /dev/null
+++ b/runtime/plugin/rplugin.vim
@@ -0,0 +1,5 @@
+if exists('loaded_remote_plugins') || &cp
+ finish
+endif
+let loaded_remote_plugins = 1
+call remote#host#LoadRemotePlugins()
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index d7910347fc..b9ecbc71fe 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -593,9 +593,17 @@ edit (
* Get a character for Insert mode. Ignore K_IGNORE.
*/
lastc = c; /* remember previous char for CTRL-D */
+ event_enable_deferred();
do {
c = safe_vgetc();
} while (c == K_IGNORE);
+ event_disable_deferred();
+
+ if (c == K_EVENT) {
+ c = lastc;
+ event_process();
+ continue;
+ }
/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
did_cursorhold = TRUE;
@@ -943,10 +951,6 @@ doESCkey:
did_cursorhold = TRUE;
break;
- case K_EVENT:
- event_process();
- break;
-
case K_HOME: /* <Home> */
case K_KHOME:
case K_S_HOME:
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 5feff4d456..2be3757821 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -311,9 +311,16 @@ getcmdline (
/* Get a character. Ignore K_IGNORE, it should not do anything, such
* as stop completion. */
+ event_enable_deferred();
do {
c = safe_vgetc();
} while (c == K_IGNORE);
+ event_disable_deferred();
+
+ if (c == K_EVENT) {
+ event_process();
+ continue;
+ }
if (KeyTyped) {
some_key_typed = TRUE;
@@ -769,11 +776,6 @@ getcmdline (
* Big switch for a typed command line character.
*/
switch (c) {
- case K_EVENT:
- event_process();
- // Force a redraw even though the command line didn't change
- shell_resized();
- goto cmdline_not_changed;
case K_BS:
case Ctrl_H:
case K_DEL:
@@ -1885,8 +1887,6 @@ redraw:
}
if (IS_SPECIAL(c1)) {
- // Process deferred events
- event_process();
// Ignore other special key codes
continue;
}
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index fd60664b7b..1bec0fa1bb 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -2481,7 +2481,6 @@ inchar (
char_u dum[DUM_LEN + 1];
for (;; ) {
- event_process();
len = ui_inchar(dum, DUM_LEN, 0L, 0);
if (len == 0 || (len == 1 && dum[0] == 3))
break;
diff --git a/src/nvim/message.c b/src/nvim/message.c
index ee83fd371e..23feeab173 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -44,7 +44,6 @@
#include "nvim/term.h"
#include "nvim/ui.h"
#include "nvim/os/os.h"
-#include "nvim/os/event.h"
/*
* To be able to scroll back at the "more" and "hit-enter" prompts we need to
@@ -2076,9 +2075,6 @@ static int do_more_prompt(int typed_char)
toscroll = 0;
switch (c) {
- case K_EVENT:
- event_process();
- break;
case BS: /* scroll one line back */
case K_BS:
case 'k':
@@ -2738,8 +2734,6 @@ do_dialog (
break;
default: /* Could be a hotkey? */
if (c < 0) { /* special keys are ignored here */
- // drain event queue to prevent infinite loop
- event_process();
continue;
}
if (c == ':' && ex_cmd) {
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 29070ff188..f58e044c2c 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -312,7 +312,6 @@ static const struct nv_cmd {
{K_F8, farsi_fkey, 0, 0},
{K_F9, farsi_fkey, 0, 0},
{K_CURSORHOLD, nv_cursorhold, NV_KEEPREG, 0},
- {K_EVENT, nv_event, NV_KEEPREG, 0},
};
/* Number of commands in nv_cmds[]. */
@@ -483,7 +482,15 @@ normal_cmd (
/*
* Get the command character from the user.
*/
+ event_enable_deferred();
c = safe_vgetc();
+ event_disable_deferred();
+
+ if (c == K_EVENT) {
+ event_process();
+ return;
+ }
+
LANGMAP_ADJUST(c, true);
/*
@@ -7373,8 +7380,3 @@ static void nv_cursorhold(cmdarg_T *cap)
did_cursorhold = true;
cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
}
-
-static void nv_event(cmdarg_T *cap)
-{
- event_process();
-}
diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c
index 1477072f4f..34560610bd 100644
--- a/src/nvim/os/event.c
+++ b/src/nvim/os/event.c
@@ -18,6 +18,8 @@
#include "nvim/vim.h"
#include "nvim/memory.h"
#include "nvim/misc2.h"
+#include "nvim/term.h"
+#include "nvim/screen.h"
#include "nvim/lib/klist.h"
@@ -39,6 +41,7 @@ typedef struct {
// loop(to avoid recursion), but before returning from
// `event_poll`
static klist_t(Event) *deferred_events = NULL, *immediate_events = NULL;
+static int deferred_events_allowed = 0;
void event_init(void)
{
@@ -134,7 +137,17 @@ void event_poll(int ms)
bool event_has_deferred(void)
{
- return !kl_empty(deferred_events);
+ return deferred_events_allowed && !kl_empty(deferred_events);
+}
+
+void event_enable_deferred(void)
+{
+ ++deferred_events_allowed;
+}
+
+void event_disable_deferred(void)
+{
+ --deferred_events_allowed;
}
// Queue an event
@@ -146,6 +159,11 @@ void event_push(Event event, bool deferred)
void event_process(void)
{
process_events_from(deferred_events);
+
+ if (must_redraw) {
+ update_screen(0);
+ out_flush();
+ }
}
static void process_events_from(klist_t(Event) *queue)
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 3ebfb3f12b..d10d20b20e 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -84,13 +84,11 @@ void input_stop(void)
// Low level input function.
int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
{
- InbufPollResult result;
-
- if (event_has_deferred()) {
- // Return pending event bytes
- return push_event_key(buf, maxlen);
+ if (rbuffer_pending(input_buffer)) {
+ return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
}
+ InbufPollResult result;
if (ms >= 0) {
if ((result = inbuf_poll(ms)) == kInputNone) {
return 0;
@@ -110,24 +108,27 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
}
}
- // If there are deferred events, return the keys directly
- if (event_has_deferred()) {
- return push_event_key(buf, maxlen);
- }
-
// If input was put directly in typeahead buffer bail out here.
if (typebuf_changed(tb_change_cnt)) {
return 0;
}
+ if (rbuffer_pending(input_buffer)) {
+ // Safe to convert rbuffer_read to int, it will never overflow since we use
+ // relatively small buffers.
+ return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
+ }
+
+ // If there are deferred events, return the keys directly
+ if (event_has_deferred()) {
+ return push_event_key(buf, maxlen);
+ }
+
if (result == kInputEof) {
read_error_exit();
- return 0;
}
- // Safe to convert rbuffer_read to int, it will never overflow since
- // we use relatively small buffers.
- return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
+ return 0;
}
// Check if a character is available for reading
@@ -319,10 +320,9 @@ static int push_event_key(uint8_t *buf, int maxlen)
// Check if there's pending input
static bool input_ready(void)
{
- return typebuf_was_filled || // API call filled typeahead
- event_has_deferred() || // Events must be processed
- (!embedded_mode && (
- rbuffer_pending(input_buffer) > 0 || // Stdin input
- eof)); // Stdin closed
+ return typebuf_was_filled || // API call filled typeahead
+ rbuffer_pending(input_buffer) > 0 || // Stdin input
+ event_has_deferred() || // Events must be processed
+ (!embedded_mode && eof); // Stdin closed
}
diff --git a/src/nvim/testdir/test101.in b/src/nvim/testdir/test101.in
deleted file mode 100644
index 04c934f2c5..0000000000
--- a/src/nvim/testdir/test101.in
+++ /dev/null
@@ -1,45 +0,0 @@
-Test for v:hlsearch vim: set ft=vim :
-
-STARTTEST
-:" Last abc: Q
-:so small.vim
-:new
-:call setline(1, repeat(['aaa'], 10))
-:set hlsearch nolazyredraw
-:let r=[]
-:command -nargs=0 -bar AddR :call add(r, [screenattr(1, 1), v:hlsearch])
-/aaa
-:AddR
-:nohlsearch
-:AddR
-:let v:hlsearch=1
-:AddR
-:let v:hlsearch=0
-:AddR
-:set hlsearch
-:AddR
-:let v:hlsearch=0
-:AddR
-n:AddR
-:let v:hlsearch=0
-:AddR
-/
-:AddR
-:let r1=r[0][0]
-:" I guess it is not guaranteed that screenattr outputs always the same character
-:call map(r, 'v:val[1].":".(v:val[0]==r1?"highlighted":"not highlighted")')
-:try
-: let v:hlsearch=[]
-:catch
-: call add(r, matchstr(v:exception,'^Vim(let):E\d\+:'))
-:endtry
-:bwipeout!
-:$put=r
-:call garbagecollect(1)
-:"
-:/^start:/,$wq! test.out
-:" vim: et ts=4 isk-=\:
-:call getchar()
-ENDTEST
-
-start:
diff --git a/src/nvim/testdir/test101.ok b/src/nvim/testdir/test101.ok
deleted file mode 100644
index 3ed7436cf7..0000000000
--- a/src/nvim/testdir/test101.ok
+++ /dev/null
@@ -1,11 +0,0 @@
-start:
-1:highlighted
-0:not highlighted
-1:highlighted
-0:not highlighted
-1:highlighted
-0:not highlighted
-1:highlighted
-0:not highlighted
-1:highlighted
-Vim(let):E706:
diff --git a/src/nvim/testdir/test104.in b/src/nvim/testdir/test104.in
deleted file mode 100644
index fd847131e9..0000000000
--- a/src/nvim/testdir/test104.in
+++ /dev/null
@@ -1,30 +0,0 @@
-Tests for :let. vim: set ft=vim ts=8 :
-
-STARTTEST
-:so small.vim
-:set runtimepath+=./sautest
-:" Test to not autoload when assigning. It causes internal error.
-:try
-: let Test104#numvar = function('tr')
-: $put ='OK: ' . string(Test104#numvar)
-:catch
-: $put ='FAIL: ' . v:exception
-:endtry
-:let a = 1
-:let b = 2
-:for letargs in ['a b', '{0 == 1 ? "a" : "b"}', '{0 == 1 ? "a" : "b"} a', 'a {0 == 1 ? "a" : "b"}']
-: try
-: redir => messages
-: execute 'let' letargs
-: redir END
-: $put ='OK:'
-: $put =split(substitute(messages, '\n', '\0 ', 'g'), '\n')
-: catch
-: $put ='FAIL: ' . v:exception
-: redir END
-: endtry
-:endfor
-:/^Results/,$wq! test.out
-ENDTEST
-
-Results of test104:
diff --git a/src/nvim/testdir/test104.ok b/src/nvim/testdir/test104.ok
deleted file mode 100644
index 5fb20945c3..0000000000
--- a/src/nvim/testdir/test104.ok
+++ /dev/null
@@ -1,13 +0,0 @@
-Results of test104:
-OK: function('tr')
-OK:
- a #1
- b #2
-OK:
- b #2
-OK:
- b #2
- a #1
-OK:
- a #1
- b #2
diff --git a/src/nvim/testdir/test105.in b/src/nvim/testdir/test105.in
deleted file mode 100644
index bfb4b65fbb..0000000000
--- a/src/nvim/testdir/test105.in
+++ /dev/null
@@ -1,45 +0,0 @@
-Test filename modifiers vim: set ft=vim :
-
-STARTTEST
-:source small.vim
-:%delete _
-:set shell=sh
-:set shellslash
-:let tab="\t"
-:command -nargs=1 Put :let expr=<q-args> | $put =expr.tab.strtrans(string(eval(expr)))
-:let $HOME=fnamemodify('.', ':p:h:h:h')
-:Put fnamemodify('.', ':p' )[-1:]
-:Put fnamemodify('.', ':p:h' )[-1:]
-:Put fnamemodify('test.out', ':p' )[-1:]
-:Put fnamemodify('test.out', ':.' )
-:Put fnamemodify('../testdir/a', ':.' )
-:Put fnamemodify('test.out', ':~' )
-:Put fnamemodify('../testdir/a', ':~' )
-:Put fnamemodify('../testdir/a', ':t' )
-:Put fnamemodify('.', ':p:t' )
-:Put fnamemodify('test.out', ':p:t' )
-:Put fnamemodify('test.out', ':p:e' )
-:Put fnamemodify('test.out', ':p:t:e' )
-:Put fnamemodify('abc.fb2.tar.gz', ':r' )
-:Put fnamemodify('abc.fb2.tar.gz', ':r:r' )
-:Put fnamemodify('abc.fb2.tar.gz', ':r:r:r' )
-:Put substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(nvim/testdir/.*\)', '\1', '')
-:Put fnamemodify('abc.fb2.tar.gz', ':e' )
-:Put fnamemodify('abc.fb2.tar.gz', ':e:e' )
-:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e' )
-:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e:e')
-:Put fnamemodify('abc.fb2.tar.gz', ':e:e:r' )
-:Put fnamemodify('abc def', ':S' )
-:Put fnamemodify('abc" "def', ':S' )
-:Put fnamemodify('abc"%"def', ':S' )
-:Put fnamemodify('abc'' ''def', ':S' )
-:Put fnamemodify('abc''%''def', ':S' )
-:Put fnamemodify("abc\ndef", ':S' )
-:set shell=tcsh
-:Put fnamemodify("abc\ndef", ':S' )
-:$put ='vim: ts=8'
-:1 delete _
-:w! test.out
-:qa!
-ENDTEST
-
diff --git a/src/nvim/testdir/test105.ok b/src/nvim/testdir/test105.ok
deleted file mode 100644
index 0b30ee4281..0000000000
--- a/src/nvim/testdir/test105.ok
+++ /dev/null
@@ -1,29 +0,0 @@
-fnamemodify('.', ':p' )[-1:] '/'
-fnamemodify('.', ':p:h' )[-1:] 'r'
-fnamemodify('test.out', ':p' )[-1:] 't'
-fnamemodify('test.out', ':.' ) 'test.out'
-fnamemodify('../testdir/a', ':.' ) 'a'
-fnamemodify('test.out', ':~' ) '~/nvim/testdir/test.out'
-fnamemodify('../testdir/a', ':~' ) '~/nvim/testdir/a'
-fnamemodify('../testdir/a', ':t' ) 'a'
-fnamemodify('.', ':p:t' ) ''
-fnamemodify('test.out', ':p:t' ) 'test.out'
-fnamemodify('test.out', ':p:e' ) 'out'
-fnamemodify('test.out', ':p:t:e' ) 'out'
-fnamemodify('abc.fb2.tar.gz', ':r' ) 'abc.fb2.tar'
-fnamemodify('abc.fb2.tar.gz', ':r:r' ) 'abc.fb2'
-fnamemodify('abc.fb2.tar.gz', ':r:r:r' ) 'abc'
-substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(nvim/testdir/.*\)', '\1', '') 'nvim/testdir/abc.fb2'
-fnamemodify('abc.fb2.tar.gz', ':e' ) 'gz'
-fnamemodify('abc.fb2.tar.gz', ':e:e' ) 'tar.gz'
-fnamemodify('abc.fb2.tar.gz', ':e:e:e' ) 'fb2.tar.gz'
-fnamemodify('abc.fb2.tar.gz', ':e:e:e:e') 'fb2.tar.gz'
-fnamemodify('abc.fb2.tar.gz', ':e:e:r' ) 'tar'
-fnamemodify('abc def', ':S' ) '''abc def'''
-fnamemodify('abc" "def', ':S' ) '''abc" "def'''
-fnamemodify('abc"%"def', ':S' ) '''abc"%"def'''
-fnamemodify('abc'' ''def', ':S' ) '''abc''\'''' ''\''''def'''
-fnamemodify('abc''%''def', ':S' ) '''abc''\''''%''\''''def'''
-fnamemodify("abc\ndef", ':S' ) '''abc^@def'''
-fnamemodify("abc\ndef", ':S' ) '''abc\^@def'''
-vim: ts=8
diff --git a/src/nvim/testdir/test21.in b/src/nvim/testdir/test21.in
deleted file mode 100644
index 491b9f7404..0000000000
--- a/src/nvim/testdir/test21.in
+++ /dev/null
@@ -1,19 +0,0 @@
-Tests for [ CTRL-I with a count and CTRL-W CTRL-I with a count
-
-STARTTEST
-:so small.vim
-/start
-6[ :.w! test.out
-?start here
-6 :.w >>test.out
-:qa!
-ENDTEST
-
-#include test21.in
-
-/* test text test tex start here
- some text
- test text
- start OK if found this line
- start found wrong line
-test text
diff --git a/src/nvim/testdir/test21.ok b/src/nvim/testdir/test21.ok
deleted file mode 100644
index d9f1b759ce..0000000000
--- a/src/nvim/testdir/test21.ok
+++ /dev/null
@@ -1,2 +0,0 @@
- start OK if found this line
- start OK if found this line
diff --git a/src/nvim/testdir/test25.in b/src/nvim/testdir/test25.in
deleted file mode 100644
index 4139865daf..0000000000
--- a/src/nvim/testdir/test25.in
+++ /dev/null
@@ -1,31 +0,0 @@
-Test for jumping to a tag with 'hidden' set, with symbolic link in path of tag.
-This only works for Unix, because of the symbolic link.
-
-STARTTEST
-:so small.vim
-:set hidden
-:" Create a link from test25.dir to the current directory.
-:!rm -f test25.dir
-:!ln -s . test25.dir
-:" Create tags.text, with the current directory name inserted.
-/tags line
-:r !pwd
-d$/test
-hP:.w! tags.test
-:" Try jumping to a tag in the current file, but with a path that contains a
-:" symbolic link. When wrong, this will give the ATTENTION message. The next
-:" space will then be eaten by hit-return, instead of moving the cursor to 'd'.
-:set tags=tags.test
-G x:.w! test.out
-:!rm -f test25.dir tags.test
-:qa!
-ENDTEST
-
-tags line:
-SECTION_OFF /test25.dir/test25.in /^#define SECTION_OFF 3$/
-
-/*tx.c*/
-#define SECTION_OFF 3
-#define NUM_SECTIONS 3
-
-SECTION_OFF
diff --git a/src/nvim/testdir/test25.ok b/src/nvim/testdir/test25.ok
deleted file mode 100644
index 08fc070b7b..0000000000
--- a/src/nvim/testdir/test25.ok
+++ /dev/null
@@ -1 +0,0 @@
-#efine SECTION_OFF 3
diff --git a/src/nvim/testdir/test26.in b/src/nvim/testdir/test26.in
deleted file mode 100644
index e7cd757661..0000000000
--- a/src/nvim/testdir/test26.in
+++ /dev/null
@@ -1,44 +0,0 @@
-Test for :execute, :while and :if
-
-STARTTEST
-:so small.vim
-mt:let i = 0
-:while i < 12
-: let i = i + 1
-: if has("ebcdic")
-: execute "normal o" . i . "\047"
-: else
-: execute "normal o" . i . "\033"
-: endif
-: if i % 2
-: normal Ax
-: if i == 9
-: break
-: endif
-: if i == 5
-: continue
-: else
-: let j = 9
-: while j > 0
-: if has("ebcdic")
-: execute "normal" j . "a" . j . "\x27"
-: else
-: execute "normal" j . "a" . j . "\x1b"
-: endif
-: let j = j - 1
-: endwhile
-: endif
-: endif
-: if i == 9
-: if has("ebcdic")
-: execute "normal Az\047"
-: else
-: execute "normal Az\033"
-: endif
-: endif
-:endwhile
-:unlet i j
-:'t,$w! test.out
-:qa!
-ENDTEST
-
diff --git a/src/nvim/testdir/test26.ok b/src/nvim/testdir/test26.ok
deleted file mode 100644
index bc44761187..0000000000
--- a/src/nvim/testdir/test26.ok
+++ /dev/null
@@ -1,10 +0,0 @@
-
-1x999999999888888887777777666666555554444333221
-2
-3x999999999888888887777777666666555554444333221
-4
-5x
-6
-7x999999999888888887777777666666555554444333221
-8
-9x
diff --git a/src/nvim/testdir/test33.in b/src/nvim/testdir/test33.in
deleted file mode 100644
index 5644760402..0000000000
--- a/src/nvim/testdir/test33.in
+++ /dev/null
@@ -1,34 +0,0 @@
-Test for 'lisp'
-If the lisp feature is not enabled, this will fail!
-
-STARTTEST
-:so small.vim
-:set lisp
-/^(defun
-=G:/^(defun/,$w! test.out
-:q!
-ENDTEST
-
-(defun html-file (base)
-(format nil "~(~A~).html" base))
-
-(defmacro page (name title &rest body)
-(let ((ti (gensym)))
-`(with-open-file (*standard-output*
-(html-file ,name)
-:direction :output
-:if-exists :supersede)
-(let ((,ti ,title))
-(as title ,ti)
-(with center
-(as h2 (string-upcase ,ti)))
-(brs 3)
-,@body))))
-
-;;; Utilities for generating links
-
-(defmacro with-link (dest &rest body)
-`(progn
-(format t "<a href=\"~A\">" (html-file ,dest))
-,@body
-(princ "</a>")))
diff --git a/src/nvim/testdir/test33.ok b/src/nvim/testdir/test33.ok
deleted file mode 100644
index cd1d87a14b..0000000000
--- a/src/nvim/testdir/test33.ok
+++ /dev/null
@@ -1,23 +0,0 @@
-(defun html-file (base)
- (format nil "~(~A~).html" base))
-
-(defmacro page (name title &rest body)
- (let ((ti (gensym)))
- `(with-open-file (*standard-output*
- (html-file ,name)
- :direction :output
- :if-exists :supersede)
- (let ((,ti ,title))
- (as title ,ti)
- (with center
- (as h2 (string-upcase ,ti)))
- (brs 3)
- ,@body))))
-
-;;; Utilities for generating links
-
-(defmacro with-link (dest &rest body)
- `(progn
- (format t "<a href=\"~A\">" (html-file ,dest))
- ,@body
- (princ "</a>")))
diff --git a/src/nvim/testdir/test43.in b/src/nvim/testdir/test43.in
deleted file mode 100644
index 7c545073da..0000000000
--- a/src/nvim/testdir/test43.in
+++ /dev/null
@@ -1,34 +0,0 @@
-Tests for regexp with various magic settings.
-
-STARTTEST
-:so small.vim
-:set nocompatible viminfo+=nviminfo
-/^1
-/a*b\{2}c\+/e
-x/\Md\*e\{2}f\+/e
-x:set nomagic
-/g\*h\{2}i\+/e
-x/\mj*k\{2}l\+/e
-x/\vm*n{2}o+/e
-x/\V^aa$
-x:set magic
-/\v(a)(b)\2\1\1/e
-x/\V[ab]\(\[xy]\)\1
-x:$
-:set undolevels=100
-dv?bar?
-Yup:"
-:?^1?,$w! test.out
-:qa!
-ENDTEST
-
-1 a aa abb abbccc
-2 d dd dee deefff
-3 g gg ghh ghhiii
-4 j jj jkk jkklll
-5 m mm mnn mnnooo
-6 x ^aa$ x
-7 (a)(b) abbaa
-8 axx [ab]xx
-9 foobar
-
diff --git a/src/nvim/testdir/test43.ok b/src/nvim/testdir/test43.ok
deleted file mode 100644
index 0b37a6a61e..0000000000
--- a/src/nvim/testdir/test43.ok
+++ /dev/null
@@ -1,11 +0,0 @@
-1 a aa abb abbcc
-2 d dd dee deeff
-3 g gg ghh ghhii
-4 j jj jkk jkkll
-5 m mm mnn mnnoo
-6 x aa$ x
-7 (a)(b) abba
-8 axx ab]xx
-9 foobar
-9 foo
-
diff --git a/src/nvim/testdir/test5.in b/src/nvim/testdir/test5.in
deleted file mode 100644
index e19e20d59b..0000000000
--- a/src/nvim/testdir/test5.in
+++ /dev/null
@@ -1,29 +0,0 @@
-Test for autocommand that deletes the current buffer on BufLeave event.
-Also test deleting the last buffer, should give a new, empty buffer.
-
-STARTTEST
-:so small.vim
-:au BufLeave Xxx bwipe
-/start of
-:.,/end of/w! Xxx " write test file Xxx
-:sp Xxx " split to Xxx
-:bwipe " delete buffer Xxx, now we're back here
-G?this is a
-othis is some more text
-: " Append some text to this file
-:?start?,$w! test.out " Write current file contents
-:bwipe test.out " delete alternate buffer
-:au bufleave test5.in bwipe
-:bwipe! " delete current buffer, get an empty one
-ithis is another test line:w >>test.out
-: " append an extra line to the output file
-:qa!
-ENDTEST
-
-start of test file Xxx
-vim: set noai :
- this is a test
- this is a test
- this is a test
- this is a test
-end of test file Xxx
diff --git a/src/nvim/testdir/test5.ok b/src/nvim/testdir/test5.ok
deleted file mode 100644
index 6743060794..0000000000
--- a/src/nvim/testdir/test5.ok
+++ /dev/null
@@ -1,9 +0,0 @@
-start of test file Xxx
-vim: set noai :
- this is a test
- this is a test
- this is a test
- this is a test
-this is some more text
-end of test file Xxx
-this is another test line
diff --git a/src/nvim/testdir/test51.in b/src/nvim/testdir/test51.in
deleted file mode 100644
index b4f45d1f75..0000000000
--- a/src/nvim/testdir/test51.in
+++ /dev/null
@@ -1,36 +0,0 @@
-Tests for ":highlight". vim: set ft=vim :
-
-STARTTEST
-:so small.vim
-:" basic test if ":highlight" doesn't crash
-:highlight
-:hi Search
-:" test setting colors.
-:" test clearing one color and all doesn't generate error or warning
-:hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
-:hi Group2 term= cterm=
-:hi Group3 term=underline cterm=bold
-:redir! >test.out
-:hi NewGroup
-:hi Group2
-:hi Group3
-:hi clear NewGroup
-:hi NewGroup
-:hi Group2
-:hi Group2 NONE
-:hi Group2
-:hi clear
-:hi Group3
-:hi Crash term='asdf
-:redir END
-:" filter ctermfg and ctermbg, the numbers depend on the terminal
-:e test.out
-:%s/ctermfg=\d*/ctermfg=2/
-:%s/ctermbg=\d*/ctermbg=3/
-:" filter out possibly translated error message
-:%s/E475: [^:]*:/E475:/
-:" fix the fileformat
-:set ff&
-:wq!
-ENDTEST
-
diff --git a/src/nvim/testdir/test51.ok b/src/nvim/testdir/test51.ok
deleted file mode 100644
index be9ff7862c..0000000000
--- a/src/nvim/testdir/test51.ok
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-NewGroup xxx term=bold cterm=italic ctermfg=2 ctermbg=3
-
-Group2 xxx cleared
-
-Group3 xxx term=underline cterm=bold
-
-
-NewGroup xxx cleared
-
-Group2 xxx cleared
-
-
-Group2 xxx cleared
-
-
-Group3 xxx cleared
-
-E475: term='asdf
diff --git a/src/nvim/testdir/test66.in b/src/nvim/testdir/test66.in
deleted file mode 100644
index f1fdce3792..0000000000
--- a/src/nvim/testdir/test66.in
+++ /dev/null
@@ -1,33 +0,0 @@
-
-Test for visual block shift and tab characters.
-
-STARTTEST
-:so small.vim
-/^one
-fe4jRugvr1:'<,'>w! test.out
-/^abcdefgh
-4jI j<<11|D
-7|a 
-7|a 
-7|a 4k13|4j<
-:$-5,$w >> test.out
-:$-4,$s/\s\+//g
-4kI j<<
-7|a 
-7|a 
-7|a 4k13|4j3<
-:$-4,$w >> test.out
-:qa!
-ENDTEST
-
-one two three
-one two three
-one two three
-one two three
-one two three
-
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
diff --git a/src/nvim/testdir/test66.ok b/src/nvim/testdir/test66.ok
deleted file mode 100644
index 4c3ab0fb56..0000000000
--- a/src/nvim/testdir/test66.ok
+++ /dev/null
@@ -1,16 +0,0 @@
-on1 two three
-on1 two three
-on1 two three
-on1 two three
-on1 two three
-
- abcdefghijklmnopqrstuvwxyz
-abcdefghij
- abc defghijklmnopqrstuvwxyz
- abc defghijklmnopqrstuvwxyz
- abc defghijklmnopqrstuvwxyz
- abcdefghijklmnopqrstuvwxyz
-abcdefghij
- abc defghijklmnopqrstuvwxyz
- abc defghijklmnopqrstuvwxyz
- abc defghijklmnopqrstuvwxyz
diff --git a/src/nvim/testdir/test67.in b/src/nvim/testdir/test67.in
deleted file mode 100644
index 08b4e3701f..0000000000
--- a/src/nvim/testdir/test67.in
+++ /dev/null
@@ -1,33 +0,0 @@
-Test that groups and patterns are tested correctly when calling exists() for
-autocommands.
-
-STARTTEST
-:so small.vim
-:let results=[]
-:augroup auexists
-:augroup END
-:call add(results, "##BufEnter: " . exists("##BufEnter"))
-:call add(results, "#BufEnter: " . exists("#BufEnter"))
-:au BufEnter * let g:entered=1
-:call add(results, "#BufEnter: " . exists("#BufEnter"))
-:call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter"))
-:augroup auexists
-:au BufEnter * let g:entered=1
-:augroup END
-:call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter"))
-:call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test"))
-:au BufEnter *.test let g:entered=1
-:call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test"))
-:edit testfile.test
-:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))
-:au BufEnter <buffer> let g:entered=1
-:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))
-:edit testfile2.test
-:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))
-:e test.out
-:call append(0, results)
-:$d
-:w
-:qa!
-ENDTEST
-
diff --git a/src/nvim/testdir/test67.ok b/src/nvim/testdir/test67.ok
deleted file mode 100644
index 51188e5afd..0000000000
--- a/src/nvim/testdir/test67.ok
+++ /dev/null
@@ -1,10 +0,0 @@
-##BufEnter: 1
-#BufEnter: 0
-#BufEnter: 1
-#auexists#BufEnter: 0
-#auexists#BufEnter: 1
-#BufEnter#*.test: 0
-#BufEnter#*.test: 1
-#BufEnter#<buffer>: 0
-#BufEnter#<buffer>: 1
-#BufEnter#<buffer>: 0
diff --git a/src/nvim/testdir/test75.in b/src/nvim/testdir/test75.in
deleted file mode 100644
index 8fabccdf52..0000000000
--- a/src/nvim/testdir/test75.in
+++ /dev/null
@@ -1,41 +0,0 @@
-Tests for maparg().
-Also test utf8 map with a 0x80 byte.
-
-STARTTEST
-:so small.vim
-:so mbyte.vim
-:set cpo-=<
-:set encoding=utf8
-:" Test maparg() with a string result
-:map foo<C-V> is<F4>foo
-:vnoremap <script> <buffer> <expr> <silent> bar isbar
-:call append('$', maparg('foo<C-V>'))
-:call append('$', string(maparg('foo<C-V>', '', 0, 1)))
-:call append('$', string(maparg('bar', '', 0, 1)))
-:map <buffer> <nowait> foo bar
-:call append('$', string(maparg('foo', '', 0, 1)))
-:"
-:map abc x<char-114>x
-:call append('$', maparg('abc'))
-:map abc y<S-char-114>y
-:call append('$', maparg('abc'))
-:"
-Go:"
-:" Outside of the range, minimum
-:inoremap <Char-0x1040> a
-:execute "normal a\u1040\<Esc>"
-:" Inside of the range, minimum
-:inoremap <Char-0x103f> b
-:execute "normal a\u103f\<Esc>"
-:" Inside of the range, maximum
-:inoremap <Char-0xf03f> c
-:execute "normal a\uf03f\<Esc>"
-:" Outside of the range, maximum
-:inoremap <Char-0xf040> d
-:execute "normal a\uf040\<Esc>"
-:"
-:/^eof/+1,$w! test.out
-:qa!
-ENDTEST
-
-eof
diff --git a/src/nvim/testdir/test75.ok b/src/nvim/testdir/test75.ok
deleted file mode 100644
index a2c5c5ac3d..0000000000
--- a/src/nvim/testdir/test75.ok
+++ /dev/null
@@ -1,7 +0,0 @@
-is<F4>foo
-{'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
-{'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
-{'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1}
-xrx
-yRy
-abcd
diff --git a/src/nvim/testdir/sautest/autoload/Test104.vim b/test/functional/fixtures/autoload/Test104.vim
index d1e0e17a3b..d1e0e17a3b 100644
--- a/src/nvim/testdir/sautest/autoload/Test104.vim
+++ b/test/functional/fixtures/autoload/Test104.vim
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 6c3f5190c9..4a98056104 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -42,7 +42,6 @@ local function request(method, ...)
if not loop_stopped then
-- Except when the loop has been stopped by a notification triggered
-- by the initial request, for example.
- session:request('vim_eval', '1')
end
return rv
end
@@ -99,25 +98,20 @@ local function nvim_eval(expr)
return request('vim_eval', expr)
end
-local function nvim_feed(input, mode)
- mode = mode or ''
- request('vim_feedkeys', input, mode)
-end
-
-local function buffer_slice(start, stop, buffer_idx)
- local include_end = false
- if not stop then
- stop = -1
- include_end = true
+local function nvim_feed(input)
+ while #input > 0 do
+ local written = request('vim_input', input)
+ input = input:sub(written + 1)
end
- local buffer = request('vim_get_buffers')[buffer_idx or 1]
- local slice = request('buffer_get_line_slice', buffer, start or 0, stop,
- true, include_end)
- return table.concat(slice, '\n')
end
local function nvim_replace_termcodes(input)
- return request('vim_replace_termcodes', input, false, true, true)
+ -- small hack to stop <C-@> from being replaced by the internal
+ -- representation(which is different and won't work for vim_input)
+ local temp_replacement = 'CCCCCCCCC@@@@@@@@@@'
+ input = input:gsub('<[Cc][-]@>', temp_replacement)
+ local rv = request('vim_replace_termcodes', input, false, true, true)
+ return rv:gsub(temp_replacement, '\000')
end
local function dedent(str)
@@ -150,7 +144,7 @@ end
local function rawfeed(...)
for _, v in ipairs({...}) do
- nvim_feed(dedent(v), 'nt')
+ nvim_feed(dedent(v))
end
end
@@ -166,22 +160,32 @@ local function clear()
end
local function insert(...)
- nvim_feed('i', 'nt')
+ nvim_feed('i')
rawfeed(...)
- nvim_feed(nvim_replace_termcodes('<ESC>'), 'nt')
+ nvim_feed(nvim_replace_termcodes('<ESC>'))
end
local function execute(...)
for _, v in ipairs({...}) do
if v:sub(1, 1) ~= '/' then
-- not a search command, prefix with colon
- nvim_feed(':', 'nt')
+ nvim_feed(':')
end
- nvim_feed(v, 'nt')
- nvim_feed(nvim_replace_termcodes('<CR>'), 'nt')
+ nvim_feed(v)
+ nvim_feed(nvim_replace_termcodes('<CR>'))
end
end
+local function source(code)
+ local tmpname = os.tmpname()
+ local tmpfile = io.open(tmpname, "w")
+ tmpfile:write(code)
+ tmpfile:flush()
+ tmpfile:close()
+ nvim_command('source '..tmpname)
+ os.remove(tmpname)
+end
+
local function eq(expected, actual)
return assert.are.same(expected, actual)
end
@@ -190,10 +194,6 @@ local function neq(expected, actual)
return assert.are_not.same(expected, actual)
end
-local function expect(contents, first, last, buffer_index)
- return eq(dedent(contents), buffer_slice(first, last, buffer_index))
-end
-
local function ok(expr)
assert.is_true(expr)
end
@@ -223,6 +223,10 @@ local function curbuf(method, ...)
end
local function curbuf_contents()
+ -- Before inspecting the buffer, execute 'vim_eval' to wait until all
+ -- previously sent keys are processed(vim_eval is a deferred function, and
+ -- only processed after all input)
+ session:request('vim_eval', '1')
return table.concat(curbuf('get_line_slice', 0, -1, true, true), '\n')
end
@@ -242,11 +246,16 @@ local function curtab(method, ...)
return tabpage(method, tab, ...)
end
+local function expect(contents)
+ return eq(dedent(contents), curbuf_contents())
+end
+
clear()
return {
clear = clear,
dedent = dedent,
+ source = source,
rawfeed = rawfeed,
insert = insert,
feed = feed,
diff --git a/test/functional/job/job_spec.lua b/test/functional/job/job_spec.lua
index 85a1e92e38..07ca0c0058 100644
--- a/test/functional/job/job_spec.lua
+++ b/test/functional/job/job_spec.lua
@@ -37,7 +37,7 @@ describe('jobs', function()
end)
it('allows interactive commands', function()
- nvim('command', notify_str('v:job_data[1]', 'v:job_data[2]'))
+ nvim('command', notify_str('v:job_data[1]', 'get(v:job_data, 2)'))
nvim('command', "let j = jobstart('xxx', 'cat', ['-'])")
neq(0, eval('j'))
nvim('command', 'call jobsend(j, "abc\\n")')
@@ -46,9 +46,8 @@ describe('jobs', function()
eq({'notification', 'stdout', {{'123', 'xyz'}}}, next_message())
nvim('command', 'call jobsend(j, [123, "xyz"])')
eq({'notification', 'stdout', {{'123', 'xyz'}}}, next_message())
- nvim('command', notify_str('v:job_data[1])'))
nvim('command', "call jobstop(j)")
- eq({'notification', 'exit', {}}, next_message())
+ eq({'notification', 'exit', {0}}, next_message())
end)
it('preserves NULs', function()
@@ -59,9 +58,10 @@ describe('jobs', function()
file:close()
-- v:job_data preserves NULs.
- nvim('command', notify_str('v:job_data[1]', 'v:job_data[2]'))
+ nvim('command', notify_str('v:job_data[1]', 'get(v:job_data, 2)'))
nvim('command', "let j = jobstart('xxx', 'cat', ['"..filename.."'])")
eq({'notification', 'stdout', {{'abc\ndef'}}}, next_message())
+ eq({'notification', 'exit', {0}}, next_message())
os.remove(filename)
-- jobsend() preserves NULs.
@@ -72,12 +72,13 @@ describe('jobs', function()
end)
it('will hold data if it does not end in a newline', function()
- nvim('command', notify_str('v:job_data[1]', 'v:job_data[2]'))
+ nvim('command', notify_str('v:job_data[1]', 'get(v:job_data, 2)'))
nvim('command', "let j = jobstart('xxx', 'cat', ['-'])")
nvim('command', 'call jobsend(j, "abc\\nxyz")')
eq({'notification', 'stdout', {{'abc'}}}, next_message())
nvim('command', "call jobstop(j)")
eq({'notification', 'stdout', {{'xyz'}}}, next_message())
+ eq({'notification', 'exit', {0}}, next_message())
end)
it('will not allow jobsend/stop on a non-existent job', function()
diff --git a/test/functional/legacy/004_bufenter_with_modelines_spec.lua b/test/functional/legacy/004_bufenter_with_modelines_spec.lua
index f1222700a7..6f009b52dd 100644
--- a/test/functional/legacy/004_bufenter_with_modelines_spec.lua
+++ b/test/functional/legacy/004_bufenter_with_modelines_spec.lua
@@ -31,7 +31,7 @@ describe('BufEnter with modelines', function()
execute('sp Xxx')
-- Append text with autoindent to this file
- feed('G?this is a<Esc>')
+ feed('G?this is a<CR>')
feed('othis should be auto-indented<Esc>')
-- Go to Xxx, no autocmd anymore
@@ -39,7 +39,7 @@ describe('BufEnter with modelines', function()
execute('buf Xxx')
-- Append text without autoindent to Xxx
- feed('G?this is a<Esc>')
+ feed('G?this is a<CR>')
feed('othis should be in column 1<Esc>')
execute('wq')
diff --git a/test/functional/legacy/005_bufleave_delete_buffer.lua b/test/functional/legacy/005_bufleave_delete_buffer.lua
new file mode 100644
index 0000000000..e8459ad4a7
--- /dev/null
+++ b/test/functional/legacy/005_bufleave_delete_buffer.lua
@@ -0,0 +1,71 @@
+-- Test for autocommand that deletes the current buffer on BufLeave event.
+-- Also test deleting the last buffer, should give a new, empty buffer.
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('test5', function()
+ setup(clear)
+
+ it('is working', function()
+ insert([[
+ start of test file Xxx
+ vim: set noai :
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+ end of test file Xxx]])
+
+ execute('w! Xxx0')
+ execute('au BufLeave Xxx bwipe')
+ execute('/start of')
+
+ -- Write test file Xxx.
+ execute('.,/end of/w! Xxx')
+
+ -- Split to Xxx.
+ execute('sp Xxx')
+
+ -- Delete buffer Xxx, now we're back here.
+ execute('bwipe')
+ feed('G?this is a<cr>')
+ feed('othis is some more text<esc>')
+
+ -- Append some text to this file.
+
+ -- Write current file contents.
+ execute('?start?,$yank A')
+
+ -- Delete alternate buffer.
+ execute('bwipe test.out')
+ execute('au bufleave test5.in bwipe')
+
+ -- Delete current buffer, get an empty one.
+ execute('bwipe!')
+ feed('ithis is another test line<esc>:yank A<cr>')
+
+ -- Output results
+ execute('%d')
+ execute('0put a')
+ execute('1d | $d')
+
+ -- Assert buffer contents.
+ expect([[
+ start of test file Xxx
+ vim: set noai :
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+ this is some more text
+ end of test file Xxx
+ this is another test line]])
+ end)
+
+ teardown(function()
+ os.remove('Xxx')
+ os.remove('Xxx0')
+ end)
+end)
diff --git a/test/functional/legacy/025_jump_tag_hidden_spec.lua b/test/functional/legacy/025_jump_tag_hidden_spec.lua
new file mode 100644
index 0000000000..bd434c013c
--- /dev/null
+++ b/test/functional/legacy/025_jump_tag_hidden_spec.lua
@@ -0,0 +1,50 @@
+-- Test for jumping to a tag with 'hidden' set, with symbolic link in path of tag.
+-- This only works for Unix, because of the symbolic link.
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('jump to a tag with hidden set', function()
+ setup(clear)
+
+ it('is working', function()
+ insert([[
+ tags line:
+ SECTION_OFF /test25.dir/Xxx /^#define SECTION_OFF 3$/
+
+ /*tx.c*/
+ #define SECTION_OFF 3
+ #define NUM_SECTIONS 3
+
+ SECTION_OFF]])
+
+ execute('w! Xxx')
+ execute('set hidden')
+
+ -- Create a link from test25.dir to the current directory.
+ execute('!rm -f test25.dir')
+ execute('!ln -s . test25.dir')
+
+ -- Create tags.text, with the current directory name inserted.
+ execute('/tags line')
+ execute('r !pwd')
+ feed('d$/test<cr>')
+ feed('hP:.w! tags.test<cr>')
+
+ -- Try jumping to a tag in the current file, but with a path that contains a
+ -- symbolic link. When wrong, this will give the ATTENTION message. The next
+ -- space will then be eaten by hit-return, instead of moving the cursor to 'd'.
+ execute('set tags=tags.test')
+ feed('G<C-]> x:yank a<cr>')
+ execute('!rm -f Xxx test25.dir tags.test')
+
+ -- Put @a and remove empty line
+ execute('%d')
+ execute('0put a')
+ execute('$d')
+
+ -- Assert buffer contents.
+ expect("#efine SECTION_OFF 3")
+ end)
+end)
diff --git a/test/functional/legacy/026_execute_while_if_spec.lua b/test/functional/legacy/026_execute_while_if_spec.lua
new file mode 100644
index 0000000000..9acbf76673
--- /dev/null
+++ b/test/functional/legacy/026_execute_while_if_spec.lua
@@ -0,0 +1,66 @@
+-- Test for :execute, :while and :if
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+local source = helpers.source
+
+describe(':execute, :while and :if', function()
+ setup(clear)
+
+ it('is working', function()
+ source([[
+ let i = 0
+ while i < 12
+ let i = i + 1
+ if has("ebcdic")
+ execute "normal o" . i . "\047"
+ else
+ execute "normal o" . i . "\033"
+ endif
+ if i % 2
+ normal Ax
+ if i == 9
+ break
+ endif
+ if i == 5
+ continue
+ else
+ let j = 9
+ while j > 0
+ if has("ebcdic")
+ execute "normal" j . "a" . j . "\x27"
+ else
+ execute "normal" j . "a" . j . "\x1b"
+ endif
+ let j = j - 1
+ endwhile
+ endif
+ endif
+ if i == 9
+ if has("ebcdic")
+ execute "normal Az\047"
+ else
+ execute "normal Az\033"
+ endif
+ endif
+ endwhile
+ unlet i j
+ ]])
+
+ -- Remove empty line
+ execute('1d')
+
+ -- Assert buffer contents.
+ expect([[
+ 1x999999999888888887777777666666555554444333221
+ 2
+ 3x999999999888888887777777666666555554444333221
+ 4
+ 5x
+ 6
+ 7x999999999888888887777777666666555554444333221
+ 8
+ 9x]])
+ end)
+end)
diff --git a/test/functional/legacy/033_lisp_indent_spec.lua b/test/functional/legacy/033_lisp_indent_spec.lua
new file mode 100644
index 0000000000..3ee248815d
--- /dev/null
+++ b/test/functional/legacy/033_lisp_indent_spec.lua
@@ -0,0 +1,73 @@
+-- vim: set foldmethod=marker foldmarker=[[,]] :
+-- Test for 'lisp'
+-- If the lisp feature is not enabled, this will fail!
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('lisp indent', function()
+ setup(clear)
+
+ it('is working', function()
+ insert([[
+ (defun html-file (base)
+ (format nil "~(~A~).html" base))
+
+ (defmacro page (name title &rest body)
+ (let ((ti (gensym)))
+ `(with-open-file (*standard-output*
+ (html-file ,name)
+ :direction :output
+ :if-exists :supersede)
+ (let ((,ti ,title))
+ (as title ,ti)
+ (with center
+ (as h2 (string-upcase ,ti)))
+ (brs 3)
+ ,@body))))
+
+ ;;; Utilities for generating links
+
+ (defmacro with-link (dest &rest body)
+ `(progn
+ (format t "<a href=\"~A\">" (html-file ,dest))
+ ,@body
+ (princ "</a>")))]])
+
+ execute('set lisp expandtab')
+ execute('/^(defun')
+ feed('=G:/^(defun/,$yank A<cr>')
+
+ -- Put @a and clean empty line
+ execute('%d')
+ execute('0put a')
+ execute('$d')
+
+ -- Assert buffer contents.
+ expect([[
+ (defun html-file (base)
+ (format nil "~(~A~).html" base))
+
+ (defmacro page (name title &rest body)
+ (let ((ti (gensym)))
+ `(with-open-file (*standard-output*
+ (html-file ,name)
+ :direction :output
+ :if-exists :supersede)
+ (let ((,ti ,title))
+ (as title ,ti)
+ (with center
+ (as h2 (string-upcase ,ti)))
+ (brs 3)
+ ,@body))))
+
+ ;;; Utilities for generating links
+
+ (defmacro with-link (dest &rest body)
+ `(progn
+ (format t "<a href=\"~A\">" (html-file ,dest))
+ ,@body
+ (princ "</a>")))]])
+ end)
+end)
diff --git a/test/functional/legacy/043_magic_settings_spec.lua b/test/functional/legacy/043_magic_settings_spec.lua
new file mode 100644
index 0000000000..ccef298cdd
--- /dev/null
+++ b/test/functional/legacy/043_magic_settings_spec.lua
@@ -0,0 +1,61 @@
+-- vim: set foldmethod=marker foldmarker=[[,]] :
+-- Tests for regexp with various magic settings.
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('regexp with magic settings', function()
+ setup(clear)
+
+ it('is working', function()
+ insert([[
+ 1 a aa abb abbccc
+ 2 d dd dee deefff
+ 3 g gg ghh ghhiii
+ 4 j jj jkk jkklll
+ 5 m mm mnn mnnooo
+ 6 x ^aa$ x
+ 7 (a)(b) abbaa
+ 8 axx [ab]xx
+ 9 foobar
+ ]])
+
+ execute('set nocompatible viminfo+=nviminfo')
+ execute('/^1')
+ execute([[/a*b\{2}c\+/e]])
+ feed([[x/\Md\*e\{2}f\+/e<cr>]])
+ feed('x:set nomagic<cr>')
+ execute([[/g\*h\{2}i\+/e]])
+ feed([[x/\mj*k\{2}l\+/e<cr>]])
+ feed([[x/\vm*n{2}o+/e<cr>]])
+ feed([[x/\V^aa$<cr>]])
+ feed('x:set magic<cr>')
+ execute([[/\v(a)(b)\2\1\1/e]])
+ feed([[x/\V[ab]\(\[xy]\)\1<cr>]])
+ feed('x:$<cr>')
+ execute('set undolevels=100')
+ feed('dv?bar?<cr>')
+ feed('Yup:<cr>')
+ execute('?^1?,$yank A')
+
+ -- Put @a and clean empty line
+ execute('%d')
+ execute('0put a')
+ execute('$d')
+
+ -- Assert buffer contents.
+ expect([[
+ 1 a aa abb abbcc
+ 2 d dd dee deeff
+ 3 g gg ghh ghhii
+ 4 j jj jkk jkkll
+ 5 m mm mnn mnnoo
+ 6 x aa$ x
+ 7 (a)(b) abba
+ 8 axx ab]xx
+ 9 foobar
+ 9 foo
+ ]])
+ end)
+end)
diff --git a/test/functional/legacy/051_highlight_spec.lua b/test/functional/legacy/051_highlight_spec.lua
new file mode 100644
index 0000000000..f35b70f93f
--- /dev/null
+++ b/test/functional/legacy/051_highlight_spec.lua
@@ -0,0 +1,70 @@
+-- vim: set foldmethod=marker foldmarker=[[,]] :
+-- Tests for ":highlight".
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe(':highlight', function()
+ setup(clear)
+
+ it('is working', function()
+ -- Basic test if ":highlight" doesn't crash
+ execute('highlight')
+ execute('hi Search')
+
+ -- Test setting colors.
+ -- Test clearing one color and all doesn't generate error or warning
+ execute('hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan')
+ execute('hi Group2 term= cterm=')
+ execute('hi Group3 term=underline cterm=bold')
+ execute('redir! @a')
+ execute('hi NewGroup')
+ execute('hi Group2')
+ execute('hi Group3')
+ execute('hi clear NewGroup')
+ execute('hi NewGroup')
+ execute('hi Group2')
+ execute('hi Group2 NONE')
+ execute('hi Group2')
+ execute('hi clear')
+ execute('hi Group3')
+ execute([[hi Crash term='asdf]])
+ execute('redir END')
+
+ -- Filter ctermfg and ctermbg, the numbers depend on the terminal
+ execute('0put a')
+ execute([[%s/ctermfg=\d*/ctermfg=2/]])
+ execute([[%s/ctermbg=\d*/ctermbg=3/]])
+
+ -- Filter out possibly translated error message
+ execute('%s/E475: [^:]*:/E475:/')
+
+ -- Fix the fileformat
+ execute('set ff&')
+ execute('$d')
+
+ -- Assert buffer contents.
+ expect([[
+
+
+ NewGroup xxx term=bold cterm=italic ctermfg=2 ctermbg=3
+
+ Group2 xxx cleared
+
+ Group3 xxx term=underline cterm=bold
+
+
+ NewGroup xxx cleared
+
+ Group2 xxx cleared
+
+
+ Group2 xxx cleared
+
+
+ Group3 xxx cleared
+
+ E475: term='asdf]])
+ end)
+end)
diff --git a/test/functional/legacy/066_visual_block_tab_spec.lua b/test/functional/legacy/066_visual_block_tab_spec.lua
new file mode 100644
index 0000000000..cd283e6746
--- /dev/null
+++ b/test/functional/legacy/066_visual_block_tab_spec.lua
@@ -0,0 +1,64 @@
+-- vim: set foldmethod=marker foldmarker=[[,]] :
+-- Test for visual block shift and tab characters.
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('visual block shift and tab characters', function()
+ setup(clear)
+
+ it('is working', function()
+ insert([[
+ one two three
+ one two three
+ one two three
+ one two three
+ one two three
+
+ abcdefghijklmnopqrstuvwxyz
+ abcdefghijklmnopqrstuvwxyz
+ abcdefghijklmnopqrstuvwxyz
+ abcdefghijklmnopqrstuvwxyz
+ abcdefghijklmnopqrstuvwxyz]])
+
+ feed('gg')
+ feed([[fe<C-v>4jR<esc>ugvr1:'<,'>yank A<cr>]])
+ execute('/^abcdefgh')
+ feed('<C-v>4jI <esc>j<<11|D')
+ feed('j7|a <esc>')
+ feed('j7|a <esc>')
+ feed('j7|a <esc>4k13|<C-v>4j<')
+ execute('$-5,$yank A')
+ execute([[$-4,$s/\s\+//g]])
+ feed('<C-v>4kI <esc>j<<')
+ feed('j7|a <esc>')
+ feed('j7|a <esc>')
+ feed('j7|a <esc>4k13|<C-v>4j3<')
+ execute('$-4,$yank A')
+
+ -- Put @a and clean empty lines
+ execute('%d')
+ execute('0put a')
+ execute('$d')
+
+ -- Assert buffer contents.
+ expect([[
+ on1 two three
+ on1 two three
+ on1 two three
+ on1 two three
+ on1 two three
+
+ abcdefghijklmnopqrstuvwxyz
+ abcdefghij
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz
+ abcdefghijklmnopqrstuvwxyz
+ abcdefghij
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz]])
+ end)
+end)
diff --git a/test/functional/legacy/067_augroup_exists_spec.lua b/test/functional/legacy/067_augroup_exists_spec.lua
new file mode 100644
index 0000000000..6d89ad6d55
--- /dev/null
+++ b/test/functional/legacy/067_augroup_exists_spec.lua
@@ -0,0 +1,46 @@
+-- Test that groups and patterns are tested correctly when calling exists() for
+-- autocommands.
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('augroup when calling exists()', function()
+ setup(clear)
+
+ it('is working', function()
+ execute('let results=[]')
+ execute('call add(results, "##BufEnter: " . exists("##BufEnter"))')
+ execute('call add(results, "#BufEnter: " . exists("#BufEnter"))')
+ execute('au BufEnter * let g:entered=1')
+ execute('call add(results, "#BufEnter: " . exists("#BufEnter"))')
+ execute('call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter"))')
+ execute('augroup auexists', 'au BufEnter * let g:entered=1', 'augroup END')
+ execute('call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter"))')
+ execute('call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test"))')
+ execute('au BufEnter *.test let g:entered=1')
+ execute('call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test"))')
+ execute('edit testfile.test')
+ execute('call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))')
+ execute('au BufEnter <buffer> let g:entered=1')
+ execute('call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))')
+ execute('edit testfile2.test')
+ execute('call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))')
+ execute('bf')
+ execute('call append(0, results)')
+ execute('$d')
+
+ -- Assert buffer contents.
+ expect([[
+ ##BufEnter: 1
+ #BufEnter: 0
+ #BufEnter: 1
+ #auexists#BufEnter: 0
+ #auexists#BufEnter: 1
+ #BufEnter#*.test: 0
+ #BufEnter#*.test: 1
+ #BufEnter#<buffer>: 0
+ #BufEnter#<buffer>: 1
+ #BufEnter#<buffer>: 0]])
+ end)
+end)
diff --git a/test/functional/legacy/075_maparg_spec.lua b/test/functional/legacy/075_maparg_spec.lua
new file mode 100644
index 0000000000..dac8940314
--- /dev/null
+++ b/test/functional/legacy/075_maparg_spec.lua
@@ -0,0 +1,58 @@
+-- Tests for maparg().
+-- Also test utf8 map with a 0x80 byte.
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('maparg()', function()
+ setup(clear)
+
+ it('is working', function()
+ execute('set cpo-=<')
+ execute('set encoding=utf8')
+
+ -- Test maparg() with a string result
+ execute('map foo<C-V> is<F4>foo')
+ execute('vnoremap <script> <buffer> <expr> <silent> bar isbar')
+ execute([[call append('$', maparg('foo<C-V>'))]])
+ execute([[call append('$', string(maparg('foo<C-V>', '', 0, 1)))]])
+ execute([[call append('$', string(maparg('bar', '', 0, 1)))]])
+ execute('map <buffer> <nowait> foo bar')
+ execute([[call append('$', string(maparg('foo', '', 0, 1)))]])
+ execute('map abc x<char-114>x')
+ execute([[call append('$', maparg('abc'))]])
+ execute('map abc y<S-char-114>y')
+ execute([[call append('$', maparg('abc'))]])
+ feed('Go<esc>:<cr>')
+
+ -- Outside of the range, minimum
+ execute('inoremap <Char-0x1040> a')
+ execute([[execute "normal a\u1040\<Esc>"]])
+
+ -- Inside of the range, minimum
+ execute('inoremap <Char-0x103f> b')
+ execute([[execute "normal a\u103f\<Esc>"]])
+
+ -- Inside of the range, maximum
+ execute('inoremap <Char-0xf03f> c')
+ execute([[execute "normal a\uf03f\<Esc>"]])
+
+ -- Outside of the range, maximum
+ execute('inoremap <Char-0xf040> d')
+ execute([[execute "normal a\uf040\<Esc>"]])
+
+ -- Remove empty line
+ execute('1d')
+
+ -- Assert buffer contents.
+ expect([[
+ is<F4>foo
+ {'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
+ {'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
+ {'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1}
+ xrx
+ yRy
+ abcd]])
+ end)
+end)
diff --git a/test/functional/legacy/101_hlsearch_spec.lua b/test/functional/legacy/101_hlsearch_spec.lua
new file mode 100644
index 0000000000..3c44f02edb
--- /dev/null
+++ b/test/functional/legacy/101_hlsearch_spec.lua
@@ -0,0 +1,63 @@
+-- Test for v:hlsearch
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+local eval = helpers.eval
+
+describe('v:hlsearch', function()
+ setup(clear)
+
+ it('is working', function()
+ -- Last abc: Q
+ execute('new')
+ execute([[call setline(1, repeat(['aaa'], 10))]])
+ execute('set hlsearch nolazyredraw')
+ execute('let r=[]')
+ execute('command -nargs=0 -bar AddR :call add(r, [screenattr(1, 1), v:hlsearch])')
+ execute('/aaa')
+ execute('AddR')
+ execute('nohlsearch')
+ execute('AddR')
+ execute('let v:hlsearch=1')
+ execute('AddR')
+ execute('let v:hlsearch=0')
+ execute('AddR')
+ execute('set hlsearch')
+ execute('AddR')
+ execute('let v:hlsearch=0')
+ execute('AddR')
+ feed('n:AddR<cr>')
+ execute('let v:hlsearch=0')
+ execute('AddR')
+ execute('/')
+ execute('AddR')
+ execute('let r1=r[0][0]')
+
+ -- I guess it is not guaranteed that screenattr outputs always the same character
+ execute([[call map(r, 'v:val[1].":".(v:val[0]==r1?"highlighted":"not highlighted")')]])
+ execute('try')
+ execute(' let v:hlsearch=[]')
+ execute('catch')
+ execute([[ call add(r, matchstr(v:exception,'^Vim(let):E\d\+:'))]])
+ execute('endtry')
+ execute('bwipeout!')
+ execute('$put=r')
+ execute('call garbagecollect(1)')
+ execute('call getchar()')
+ execute('1d', '1d')
+
+ -- Assert buffer contents.
+ expect([[
+ 1:highlighted
+ 0:not highlighted
+ 1:highlighted
+ 0:not highlighted
+ 1:highlighted
+ 0:not highlighted
+ 1:highlighted
+ 0:not highlighted
+ 1:highlighted
+ Vim(let):E706:]])
+ end)
+end)
diff --git a/test/functional/legacy/104_let_assignment.lua b/test/functional/legacy/104_let_assignment.lua
new file mode 100644
index 0000000000..a2431da835
--- /dev/null
+++ b/test/functional/legacy/104_let_assignment.lua
@@ -0,0 +1,54 @@
+-- Tests for :let.
+
+local helpers = require('test.functional.helpers')
+local clear, source = helpers.clear, helpers.source
+local execute, expect = helpers.execute, helpers.expect
+
+describe(':let', function()
+ setup(clear)
+
+ it('is working', function()
+ execute('set runtimepath+=test/functional/fixtures')
+
+ -- Test to not autoload when assigning. It causes internal error.
+ source([[
+ try
+ let Test104#numvar = function('tr')
+ $put ='OK: ' . string(Test104#numvar)
+ catch
+ $put ='FAIL: ' . v:exception
+ endtry
+ let a = 1
+ let b = 2
+ for letargs in ['a b', '{0 == 1 ? "a" : "b"}', '{0 == 1 ? "a" : "b"} a', 'a {0 == 1 ? "a" : "b"}']
+ try
+ redir => messages
+ execute 'let' letargs
+ redir END
+ $put ='OK:'
+ $put =split(substitute(messages, '\n', '\0 ', 'g'), '\n')
+ catch
+ $put ='FAIL: ' . v:exception
+ redir END
+ endtry
+ endfor]])
+
+ -- Remove empty line
+ execute('1d')
+
+ -- Assert buffer contents.
+ expect([[
+ OK: function('tr')
+ OK:
+ a #1
+ b #2
+ OK:
+ b #2
+ OK:
+ b #2
+ a #1
+ OK:
+ a #1
+ b #2]])
+ end)
+end)
diff --git a/test/functional/legacy/105_filename_modifiers_spec.lua b/test/functional/legacy/105_filename_modifiers_spec.lua
new file mode 100644
index 0000000000..32fa6ac7eb
--- /dev/null
+++ b/test/functional/legacy/105_filename_modifiers_spec.lua
@@ -0,0 +1,79 @@
+-- Test filename modifiers.
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('filename modifiers', function()
+ setup(clear)
+
+ it('is working', function()
+ execute('cd /tmp')
+ execute([=[set shell=sh]=])
+ execute([=[set shellslash]=])
+ execute([=[let tab="\t"]=])
+ execute([=[command -nargs=1 Put :let expr=<q-args> | $put =expr.tab.strtrans(string(eval(expr)))]=])
+ execute([=[let $HOME=fnamemodify('.', ':p:h:h:h')]=])
+ execute([=[Put fnamemodify('.', ':p' )[-1:]]=])
+ execute([=[Put fnamemodify('.', ':p:h' )[-1:]]=])
+ execute([=[Put fnamemodify('test.out', ':p' )[-1:]]=])
+ execute([=[Put fnamemodify('test.out', ':.' )]=])
+ execute([=[Put fnamemodify('../testdir/a', ':.' )]=])
+ execute([=[Put fnamemodify('test.out', ':~' )]=])
+ execute([=[Put fnamemodify('../testdir/a', ':~' )]=])
+ execute([=[Put fnamemodify('../testdir/a', ':t' )]=])
+ execute([=[Put fnamemodify('.', ':p:t' )]=])
+ execute([=[Put fnamemodify('test.out', ':p:t' )]=])
+ execute([=[Put fnamemodify('test.out', ':p:e' )]=])
+ execute([=[Put fnamemodify('test.out', ':p:t:e' )]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':r' )]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':r:r' )]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':r:r:r' )]=])
+ execute([=[Put substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(nvim/testdir/.*\)', '\1', '')]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':e' )]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':e:e' )]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':e:e:e' )]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':e:e:e:e')]=])
+ execute([=[Put fnamemodify('abc.fb2.tar.gz', ':e:e:r' )]=])
+ execute([=[Put fnamemodify('abc def', ':S' )]=])
+ execute([=[Put fnamemodify('abc" "def', ':S' )]=])
+ execute([=[Put fnamemodify('abc"%"def', ':S' )]=])
+ execute([=[Put fnamemodify('abc'' ''def', ':S' )]=])
+ execute([=[Put fnamemodify('abc''%''def', ':S' )]=])
+ execute([=[Put fnamemodify("abc\ndef", ':S' )]=])
+ execute([=[set shell=tcsh]=])
+ execute([=[Put fnamemodify("abc\ndef", ':S' )]=])
+ execute([=[1 delete _]=])
+
+ -- Assert buffer contents.
+ expect([=[
+ fnamemodify('.', ':p' )[-1:] '/'
+ fnamemodify('.', ':p:h' )[-1:] 'p'
+ fnamemodify('test.out', ':p' )[-1:] 't'
+ fnamemodify('test.out', ':.' ) 'test.out'
+ fnamemodify('../testdir/a', ':.' ) '../testdir/a'
+ fnamemodify('test.out', ':~' ) 'test.out'
+ fnamemodify('../testdir/a', ':~' ) '../testdir/a'
+ fnamemodify('../testdir/a', ':t' ) 'a'
+ fnamemodify('.', ':p:t' ) ''
+ fnamemodify('test.out', ':p:t' ) 'test.out'
+ fnamemodify('test.out', ':p:e' ) 'out'
+ fnamemodify('test.out', ':p:t:e' ) 'out'
+ fnamemodify('abc.fb2.tar.gz', ':r' ) 'abc.fb2.tar'
+ fnamemodify('abc.fb2.tar.gz', ':r:r' ) 'abc.fb2'
+ fnamemodify('abc.fb2.tar.gz', ':r:r:r' ) 'abc'
+ substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(nvim/testdir/.*\)', '\1', '') '/tmp/abc.fb2'
+ fnamemodify('abc.fb2.tar.gz', ':e' ) 'gz'
+ fnamemodify('abc.fb2.tar.gz', ':e:e' ) 'tar.gz'
+ fnamemodify('abc.fb2.tar.gz', ':e:e:e' ) 'fb2.tar.gz'
+ fnamemodify('abc.fb2.tar.gz', ':e:e:e:e') 'fb2.tar.gz'
+ fnamemodify('abc.fb2.tar.gz', ':e:e:r' ) 'tar'
+ fnamemodify('abc def', ':S' ) '''abc def'''
+ fnamemodify('abc" "def', ':S' ) '''abc" "def'''
+ fnamemodify('abc"%"def', ':S' ) '''abc"%"def'''
+ fnamemodify('abc'' ''def', ':S' ) '''abc''\'''' ''\''''def'''
+ fnamemodify('abc''%''def', ':S' ) '''abc''\''''%''\''''def'''
+ fnamemodify("abc\ndef", ':S' ) '''abc^@def'''
+ fnamemodify("abc\ndef", ':S' ) '''abc\^@def''']=])
+ end)
+end)
diff --git a/test/functional/runtime/autoload/rpc/define_spec.lua b/test/functional/runtime/autoload/remote/define_spec.lua
index a85ba4d37b..53da47243c 100644
--- a/test/functional/runtime/autoload/rpc/define_spec.lua
+++ b/test/functional/runtime/autoload/remote/define_spec.lua
@@ -346,20 +346,20 @@ local function host()
end
local function register()
- eval('rpc#host#Register("busted", '..channel()..')')
+ eval('remote#host#Register("busted", '..channel()..')')
end
-command_specs_for('rpc#define#CommandOnChannel', true, channel)
-command_specs_for('rpc#define#CommandOnChannel', false, channel)
-command_specs_for('rpc#define#CommandOnHost', true, host, register)
-command_specs_for('rpc#define#CommandOnHost', false, host, register)
+command_specs_for('remote#define#CommandOnChannel', true, channel)
+command_specs_for('remote#define#CommandOnChannel', false, channel)
+command_specs_for('remote#define#CommandOnHost', true, host, register)
+command_specs_for('remote#define#CommandOnHost', false, host, register)
-autocmd_specs_for('rpc#define#AutocmdOnChannel', true, channel)
-autocmd_specs_for('rpc#define#AutocmdOnChannel', false, channel)
-autocmd_specs_for('rpc#define#AutocmdOnHost', true, host, register)
-autocmd_specs_for('rpc#define#AutocmdOnHost', false, host, register)
+autocmd_specs_for('remote#define#AutocmdOnChannel', true, channel)
+autocmd_specs_for('remote#define#AutocmdOnChannel', false, channel)
+autocmd_specs_for('remote#define#AutocmdOnHost', true, host, register)
+autocmd_specs_for('remote#define#AutocmdOnHost', false, host, register)
-function_specs_for('rpc#define#FunctionOnChannel', true, channel)
-function_specs_for('rpc#define#FunctionOnChannel', false, channel)
-function_specs_for('rpc#define#FunctionOnHost', true, host, register)
-function_specs_for('rpc#define#FunctionOnHost', false, host, register)
+function_specs_for('remote#define#FunctionOnChannel', true, channel)
+function_specs_for('remote#define#FunctionOnChannel', false, channel)
+function_specs_for('remote#define#FunctionOnHost', true, host, register)
+function_specs_for('remote#define#FunctionOnHost', false, host, register)
diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua
index 91e115aedf..84c8765b48 100644
--- a/test/functional/shell/viml_system_spec.lua
+++ b/test/functional/shell/viml_system_spec.lua
@@ -10,6 +10,7 @@ local eq, clear, eval, feed, nvim =
local function create_file_with_nuls(name)
return function()
feed('ipart1<C-V>000part2<C-V>000part3<ESC>:w '..name..'<CR>')
+ eval('1') -- wait for the file to be created
end
end