diff options
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 |