mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	feat(lua)!: execute Lua with "nvim -l"
Problem: Nvim has Lua but the "nvim" CLI can't easily be used to execute Lua scripts, especially scripts that take arguments or produce output. Solution: - support "nvim -l [args...]" for running scripts. closes #15749 - exit without +q - remove lua2dox_filter - remove Doxyfile. This wasn't used anyway, because the doxygen config is inlined in gen_vimdoc.py (`Doxyfile` variable). - use "nvim -l" in docs-gen CI job Examples: $ nvim -l scripts/lua2dox.lua --help Lua2DoX (0.2 20130128) ... $ echo "print(vim.inspect(_G.arg))" | nvim -l - --arg1 --arg2 $ echo 'print(vim.inspect(vim.api.nvim_buf_get_text(1,0,0,-1,-1,{})))' | nvim +"put ='text'" -l - TODO? -e executes Lua code -l loads a module -i enters REPL _after running the other arguments_.
This commit is contained in:
		
							
								
								
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -205,6 +205,8 @@ jobs: | |||||||
|     env: |     env: | ||||||
|       CC: ${{ matrix.cc }} |       CC: ${{ matrix.cc }} | ||||||
|       CI_OS_NAME: ${{ matrix.os }} |       CI_OS_NAME: ${{ matrix.os }} | ||||||
|  |       # TEST_FILE: test/functional/core/startup_spec.lua | ||||||
|  |       # TEST_FILTER: foo | ||||||
|     steps: |     steps: | ||||||
|       - uses: actions/checkout@v3 |       - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
| @@ -281,6 +283,8 @@ jobs: | |||||||
|       DEPS_BUILD_DIR: ${{ github.workspace }}/nvim-deps |       DEPS_BUILD_DIR: ${{ github.workspace }}/nvim-deps | ||||||
|       CACHE_NVIM_DEPS_DIR: ${{ github.workspace }}/nvim-deps |       CACHE_NVIM_DEPS_DIR: ${{ github.workspace }}/nvim-deps | ||||||
|       DEPS_PREFIX: ${{ github.workspace }}/nvim-deps/usr |       DEPS_PREFIX: ${{ github.workspace }}/nvim-deps/usr | ||||||
|  |       # TEST_FILE: test/functional/core/startup_spec.lua | ||||||
|  |       # TEST_FILTER: foo | ||||||
|     name: windows (MSVC_64) |     name: windows (MSVC_64) | ||||||
|     steps: |     steps: | ||||||
|       - uses: actions/checkout@v3 |       - uses: actions/checkout@v3 | ||||||
|   | |||||||
| @@ -116,10 +116,7 @@ Each pull request must pass the automated builds on [Cirrus CI] and [GitHub Acti | |||||||
|  |  | ||||||
| - CI builds are compiled with [`-Werror`][gcc-warnings], so compiler warnings | - CI builds are compiled with [`-Werror`][gcc-warnings], so compiler warnings | ||||||
|   will fail the build. |   will fail the build. | ||||||
| - If any tests fail, the build will fail. | - If any tests fail, the build will fail. See [test/README.md#running-tests][run-tests] to run tests locally. | ||||||
|   See [test/README.md#running-tests][run-tests] to run tests locally. |  | ||||||
|   Passing locally doesn't guarantee passing the CI build, because of the |  | ||||||
|   different compilers and platforms tested against. |  | ||||||
| - CI runs [ASan] and other analyzers. | - CI runs [ASan] and other analyzers. | ||||||
|     - To run valgrind locally: `VALGRIND=1 make test` |     - To run valgrind locally: `VALGRIND=1 make test` | ||||||
|     - To run Clang ASan/UBSan locally: `CC=clang make CMAKE_FLAGS="-DCLANG_ASAN_UBSAN=ON"` |     - To run Clang ASan/UBSan locally: `CC=clang make CMAKE_FLAGS="-DCLANG_ASAN_UBSAN=ON"` | ||||||
| @@ -127,6 +124,8 @@ Each pull request must pass the automated builds on [Cirrus CI] and [GitHub Acti | |||||||
|   neighbors_, to encourage incrementally updating the legacy style to meet our |   neighbors_, to encourage incrementally updating the legacy style to meet our | ||||||
|   [style](#style). (See [#3174][3174] for background.) |   [style](#style). (See [#3174][3174] for background.) | ||||||
| - CI for FreeBSD runs on [Cirrus CI]. | - CI for FreeBSD runs on [Cirrus CI]. | ||||||
|  | - To see CI results faster in your PR, you can temporarily set `TEST_FILE` in | ||||||
|  |   [ci.yml](https://github.com/neovim/neovim/blob/e35b9020b16985eee26e942f9a3f6b045bc3809b/.github/workflows/ci.yml#L205). | ||||||
|  |  | ||||||
| ### Clang scan-build | ### Clang scan-build | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,15 +21,19 @@ Nvim includes a "standard library" |lua-stdlib| for Lua.  It complements the | |||||||
| which can be used from Lua code (|lua-vimscript| |vim.api|). Together these | which can be used from Lua code (|lua-vimscript| |vim.api|). Together these | ||||||
| "namespaces" form the Nvim programming interface. | "namespaces" form the Nvim programming interface. | ||||||
|  |  | ||||||
| See the |lua-guide| for an introduction to using Lua in Neovim. | Lua plugins and user config are automatically discovered and loaded, just like | ||||||
|  | Vimscript. See |lua-guide| for practical guidance. | ||||||
|  |  | ||||||
|  | You can also run Lua scripts from your shell using the |-l| argument: > | ||||||
|  |     nvim -l foo.lua [args...] | ||||||
|  | < | ||||||
|                                                                   *lua-compat* |                                                                   *lua-compat* | ||||||
| Lua 5.1 is the permanent interface for Nvim Lua.  Plugins need only consider | Lua 5.1 is the permanent interface for Nvim Lua.  Plugins need only consider | ||||||
| Lua 5.1, not worry about forward-compatibility with future Lua versions.  If | Lua 5.1, not worry about forward-compatibility with future Lua versions.  If | ||||||
| Nvim ever ships with Lua 5.4+, a Lua 5.1 compatibility shim will be provided | Nvim ever ships with Lua 5.4+, a Lua 5.1 compatibility shim will be provided | ||||||
| so that old plugins continue to work transparently. | so that old plugins continue to work transparently. | ||||||
|  |  | ||||||
| ------------------------------------------------------------------------------ | ============================================================================== | ||||||
| LUA CONCEPTS AND IDIOMS                                         *lua-concepts* | LUA CONCEPTS AND IDIOMS                                         *lua-concepts* | ||||||
|  |  | ||||||
| Lua is very simple: this means that, while there are some quirks, once you | Lua is very simple: this means that, while there are some quirks, once you | ||||||
| @@ -73,25 +77,24 @@ In Lua, any missing arguments are passed as `nil`. Example: >lua | |||||||
| Furthermore it is not an error if extra parameters are passed, they are just | Furthermore it is not an error if extra parameters are passed, they are just | ||||||
| discarded. | discarded. | ||||||
|  |  | ||||||
| It is also allowed to omit the parentheses (only) if the function takes |                                                                       *kwargs* | ||||||
| exactly one string (`"foo"`) or table literal (`{1,2,3}`). The latter is often | When calling a function, you can omit the parentheses if the function takes | ||||||
| used to approximate the "named parameters" feature of languages like Python | exactly one string literal (`"foo"`) or table literal (`{1,2,3}`). The latter | ||||||
| ("kwargs" or "keyword args"). Example: >lua | is often used to approximate "named parameters" ("kwargs" or "keyword args") | ||||||
|  | as in languages like Python and C#. Example: >lua | ||||||
|     local func_with_opts = function(opts) |     local func_with_opts = function(opts) | ||||||
|         local will_do_foo = opts.foo |         local will_do_foo = opts.foo | ||||||
|         local filename = opts.filename |         local filename = opts.filename | ||||||
|  |  | ||||||
|         ... |         ... | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     func_with_opts { foo = true, filename = "hello.world" } |     func_with_opts { foo = true, filename = "hello.world" } | ||||||
| < | < | ||||||
| There is nothing special going on here except that parentheses are treated as | There's nothing special going on here except that parentheses are treated as | ||||||
| whitespace. But visually, this small bit of sugar gets reasonably close to | whitespace. But visually, this small bit of sugar gets reasonably close to | ||||||
| a "keyword args" interface. | a "keyword args" interface. | ||||||
|  |  | ||||||
| It is of course also valid to call the function with parentheses: >lua | It is of course also valid to call the function with parentheses: >lua | ||||||
|  |  | ||||||
|     func_with_opts({ foo = true, filename = "hello.world" }) |     func_with_opts({ foo = true, filename = "hello.world" }) | ||||||
| < | < | ||||||
| Nvim tends to prefer the keyword args style. | Nvim tends to prefer the keyword args style. | ||||||
| @@ -100,25 +103,20 @@ Nvim tends to prefer the keyword args style. | |||||||
| LUA PATTERNS                                                    *lua-patterns* | LUA PATTERNS                                                    *lua-patterns* | ||||||
|  |  | ||||||
| Lua intentionally does not support regular expressions, instead it has limited | Lua intentionally does not support regular expressions, instead it has limited | ||||||
| "patterns" which avoid the performance pitfalls of extended regex. | "patterns" |luaref-patterns| which avoid the performance pitfalls of extended | ||||||
| |luaref-patterns| | regex. Lua scripts can also use Vim regex via |vim.regex()|. | ||||||
|  |  | ||||||
| Examples using |string.match()|: >lua | These examples use |string.match()| to demonstrate Lua patterns: >lua | ||||||
|  |  | ||||||
|     print(string.match("foo123bar123", "%d+")) |     print(string.match("foo123bar123", "%d+")) | ||||||
|     -- 123 |     -- 123 | ||||||
|  |  | ||||||
|     print(string.match("foo123bar123", "[^%d]+")) |     print(string.match("foo123bar123", "[^%d]+")) | ||||||
|     -- foo |     -- foo | ||||||
|  |  | ||||||
|     print(string.match("foo123bar123", "[abc]+")) |     print(string.match("foo123bar123", "[abc]+")) | ||||||
|     -- ba |     -- ba | ||||||
|  |  | ||||||
|     print(string.match("foo.bar", "%.bar")) |     print(string.match("foo.bar", "%.bar")) | ||||||
|     -- .bar |     -- .bar | ||||||
|  |  | ||||||
| For more complex matching you can use Vim regex from Lua via |vim.regex()|. |  | ||||||
|  |  | ||||||
| ============================================================================== | ============================================================================== | ||||||
| IMPORTING LUA MODULES                                  *require()* *lua-require* | IMPORTING LUA MODULES                                  *require()* *lua-require* | ||||||
|  |  | ||||||
| @@ -389,7 +387,7 @@ For example consider the following Lua omnifunc handler: >lua | |||||||
|     vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omnifunc') |     vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omnifunc') | ||||||
|  |  | ||||||
| Note: The module ("mymod" in the above example) must either be a Lua global, | Note: The module ("mymod" in the above example) must either be a Lua global, | ||||||
| or use the require syntax as specified above to access it from a package. | or use require() as shown above to access it from a package. | ||||||
|  |  | ||||||
| Note: `v:lua` without a call is not allowed in a Vimscript expression: | Note: `v:lua` without a call is not allowed in a Vimscript expression: | ||||||
| |Funcref|s cannot represent Lua functions. The following are errors: >vim | |Funcref|s cannot represent Lua functions. The following are errors: >vim | ||||||
|   | |||||||
| @@ -57,6 +57,11 @@ The following new APIs or features were added. | |||||||
| < | < | ||||||
|   (or the Vimscript equivalent) to their |config| file. |   (or the Vimscript equivalent) to their |config| file. | ||||||
|  |  | ||||||
|  | • Run Lua scripts from your shell using |-l|. > | ||||||
|  |       nvim -l foo.lua --arg1 --arg2 | ||||||
|  | <  Also works with stdin: > | ||||||
|  |       echo "print(42)" | nvim -l - | ||||||
|  |  | ||||||
| • Added a |vim.lsp.codelens.clear()| function to clear codelenses. | • Added a |vim.lsp.codelens.clear()| function to clear codelenses. | ||||||
|  |  | ||||||
| • |vim.inspect_pos()|, |vim.show_pos()| and |:Inspect| allow a user to get or show items | • |vim.inspect_pos()|, |vim.show_pos()| and |:Inspect| allow a user to get or show items | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ Starting Vim						*starting* | |||||||
|                                       Type |gO| to see the table of contents. |                                       Type |gO| to see the table of contents. | ||||||
|  |  | ||||||
| ============================================================================== | ============================================================================== | ||||||
| Nvim arguments						*vim-arguments* | Nvim arguments						*cli-arguments* | ||||||
|  |  | ||||||
| Most often, Nvim is started to edit a single file with the command: > | Most often, Nvim is started to edit a single file with the command: > | ||||||
|  |  | ||||||
| @@ -31,8 +31,8 @@ filename	One or more file names.  The first one will be the current | |||||||
| 		To avoid a file name starting with a '-' being interpreted as | 		To avoid a file name starting with a '-' being interpreted as | ||||||
| 		an option, precede the arglist with "--", e.g.: > | 		an option, precede the arglist with "--", e.g.: > | ||||||
| 			nvim -- -filename | 			nvim -- -filename | ||||||
| <		All arguments after the "--" will be interpreted as file names, | <		All arguments after "--" are interpreted as file names, no | ||||||
| 		no other options or "+command" argument can follow. | 		other options or "+command" argument can follow. | ||||||
|  |  | ||||||
| 							*--* | 							*--* | ||||||
| `-`		Alias for stdin (standard input). | `-`		Alias for stdin (standard input). | ||||||
| @@ -143,15 +143,13 @@ argument. | |||||||
| 		these commands, independently from "-c" commands. | 		these commands, independently from "-c" commands. | ||||||
|  |  | ||||||
| 							*-S* | 							*-S* | ||||||
| -S {file}	Vimscript or Lua (".lua") {file} will be |:source|d after the | -S [file]	Vimscript or Lua (".lua") [file] will be |:source|d after the | ||||||
| 		first file has been read. Equivalent to: > | 		first file has been read or "Session.vim" if [file] is not | ||||||
|  | 		given. Equivalent to: > | ||||||
| 			-c "source {file}" | 			-c "source {file}" | ||||||
| <		Can be repeated like "-c", subject to the same limit of 10 | <		Can be repeated like "-c", subject to the same limit of 10 | ||||||
| 		"-c" arguments. {file} cannot start with a "-". | 		"-c" arguments. {file} cannot start with a "-". | ||||||
|  |  | ||||||
| -S		Works like "-S Session.vim".  Only when used as the last |  | ||||||
| 		argument or when another "-" option follows. |  | ||||||
|  |  | ||||||
| -L							*-L* *-r* | -L							*-L* *-r* | ||||||
| -r		Recovery mode.  Without a file name argument, a list of | -r		Recovery mode.  Without a file name argument, a list of | ||||||
| 		existing swap files is given.  With a file name, a swap file | 		existing swap files is given.  With a file name, a swap file | ||||||
| @@ -211,10 +209,30 @@ argument. | |||||||
| 			nvim -es +":verbose echo 'foo'" | 			nvim -es +":verbose echo 'foo'" | ||||||
| 			nvim -V1 -es +foo | 			nvim -V1 -es +foo | ||||||
|  |  | ||||||
| <		User |config| is skipped (unless given with |-u|). | <		User |config| is skipped unless |-u| was given. | ||||||
| 		Swap file is skipped (like |-n|). | 		Swap file is skipped (like |-n|). | ||||||
| 		User |shada| is loaded (unless "-i NONE" is given). | 		User |shada| is loaded (unless "-i NONE" is given). | ||||||
|  |  | ||||||
|  | 							*-l* | ||||||
|  | -l {script} [args] | ||||||
|  | 		Executes Lua {script} file and exits. All [args] (up to "--" | ||||||
|  | 		|---|) are treated as {script} args, not Nvim args: by Lua | ||||||
|  | 		convention they are set in the `_G.arg` global table.  *lua-args* | ||||||
|  | 		On {script} error, Nvim exits with code 1. | ||||||
|  |  | ||||||
|  | 		Sets 'verbose' to 1 (like "-V1"), so Lua `print()` writes to | ||||||
|  | 		output. | ||||||
|  |  | ||||||
|  | 		Any |cli-arguments| before "-l" are processed before executing | ||||||
|  | 		{script}. For example this quits before executing "foo.lua": > | ||||||
|  | 			nvim +q -l foo.lua | ||||||
|  | <		This loads Lua module "bar" before executing "foo.lua": > | ||||||
|  | 			nvim +"lua require('bar')" -l foo.lua | ||||||
|  | < | ||||||
|  | 		User |config| is skipped unless |-u| was given. | ||||||
|  | 		User |shada| is skipped unless |-i| was given. | ||||||
|  | 		Swap file is skipped (like |-n|). | ||||||
|  |  | ||||||
| 							*-b* | 							*-b* | ||||||
| -b		Binary mode.  File I/O will only recognize <NL> to separate | -b		Binary mode.  File I/O will only recognize <NL> to separate | ||||||
| 		lines.  The 'expandtab' option will be reset.  The 'textwidth' | 		lines.  The 'expandtab' option will be reset.  The 'textwidth' | ||||||
| @@ -222,9 +240,6 @@ argument. | |||||||
| 		is set.  This is done after reading the |vimrc| but before | 		is set.  This is done after reading the |vimrc| but before | ||||||
| 		reading any file in the arglist.  See also |edit-binary|. | 		reading any file in the arglist.  See also |edit-binary|. | ||||||
|  |  | ||||||
| 							*-l* |  | ||||||
| -l		Lisp mode.  Sets the 'lisp' and 'showmatch' options on. |  | ||||||
|  |  | ||||||
| 							*-A* | 							*-A* | ||||||
| -A		Arabic mode.  Sets the 'arabic' option on. | -A		Arabic mode.  Sets the 'arabic' option on. | ||||||
|  |  | ||||||
| @@ -239,10 +254,10 @@ argument. | |||||||
| 		Example: > | 		Example: > | ||||||
| 			nvim -V8 | 			nvim -V8 | ||||||
|  |  | ||||||
| -V[N]{filename} | -V[N]{file} | ||||||
| 		Like -V and set 'verbosefile' to {filename}.  Messages are not | 		Like -V and sets 'verbosefile' to {file} (must not start with | ||||||
| 		displayed; instead they are written to the file {filename}. | 		a digit).  Messages are not displayed; instead they are | ||||||
| 		{filename} must not start with a digit. | 		written to {file}. | ||||||
| 		Example: > | 		Example: > | ||||||
| 			nvim -V20vimlog | 			nvim -V20vimlog | ||||||
| < | < | ||||||
|   | |||||||
| @@ -55,11 +55,19 @@ if sys.version_info < MIN_PYTHON_VERSION: | |||||||
| doxygen_version = tuple((int(i) for i in subprocess.check_output(["doxygen", "-v"], | doxygen_version = tuple((int(i) for i in subprocess.check_output(["doxygen", "-v"], | ||||||
|                         universal_newlines=True).split()[0].split('.'))) |                         universal_newlines=True).split()[0].split('.'))) | ||||||
|  |  | ||||||
|  | # Until 0.9 is released, need this hacky way to check that "nvim -l foo.lua" works. | ||||||
|  | nvim_version = list(line for line in subprocess.check_output(['nvim', '-h'], universal_newlines=True).split('\n') | ||||||
|  |                      if '-l ' in line) | ||||||
|  |  | ||||||
| if doxygen_version < MIN_DOXYGEN_VERSION: | if doxygen_version < MIN_DOXYGEN_VERSION: | ||||||
|     print("\nRequires doxygen {}.{}.{}+".format(*MIN_DOXYGEN_VERSION)) |     print("\nRequires doxygen {}.{}.{}+".format(*MIN_DOXYGEN_VERSION)) | ||||||
|     print("Your doxygen version is {}.{}.{}\n".format(*doxygen_version)) |     print("Your doxygen version is {}.{}.{}\n".format(*doxygen_version)) | ||||||
|     sys.exit(1) |     sys.exit(1) | ||||||
|  |  | ||||||
|  | if len(nvim_version) == 0: | ||||||
|  |     print("\nRequires 'nvim -l' feature, see https://github.com/neovim/neovim/pull/18706") | ||||||
|  |     sys.exit(1) | ||||||
|  |  | ||||||
| # DEBUG = ('DEBUG' in os.environ) | # DEBUG = ('DEBUG' in os.environ) | ||||||
| INCLUDE_C_DECL = ('INCLUDE_C_DECL' in os.environ) | INCLUDE_C_DECL = ('INCLUDE_C_DECL' in os.environ) | ||||||
| INCLUDE_DEPRECATED = ('INCLUDE_DEPRECATED' in os.environ) | INCLUDE_DEPRECATED = ('INCLUDE_DEPRECATED' in os.environ) | ||||||
| @@ -79,7 +87,7 @@ base_dir = os.path.dirname(os.path.dirname(script_path)) | |||||||
| out_dir = os.path.join(base_dir, 'tmp-{target}-doc') | out_dir = os.path.join(base_dir, 'tmp-{target}-doc') | ||||||
| filter_cmd = '%s %s' % (sys.executable, script_path) | filter_cmd = '%s %s' % (sys.executable, script_path) | ||||||
| msgs = []  # Messages to show on exit. | msgs = []  # Messages to show on exit. | ||||||
| lua2dox_filter = os.path.join(base_dir, 'scripts', 'lua2dox_filter') | lua2dox = os.path.join(base_dir, 'scripts', 'lua2dox.lua') | ||||||
|  |  | ||||||
| CONFIG = { | CONFIG = { | ||||||
|     'api': { |     'api': { | ||||||
| @@ -993,7 +1001,7 @@ def delete_lines_below(filename, tokenstr): | |||||||
|         fp.writelines(lines[0:i]) |         fp.writelines(lines[0:i]) | ||||||
|  |  | ||||||
|  |  | ||||||
| def main(config, args): | def main(doxygen_config, args): | ||||||
|     """Generates: |     """Generates: | ||||||
|  |  | ||||||
|     1. Vim :help docs |     1. Vim :help docs | ||||||
| @@ -1021,7 +1029,7 @@ def main(config, args): | |||||||
|                 # runtime/lua/vim/lsp.lua:209: warning: argument 'foo' not found |                 # runtime/lua/vim/lsp.lua:209: warning: argument 'foo' not found | ||||||
|                 stderr=(subprocess.STDOUT if debug else subprocess.DEVNULL)) |                 stderr=(subprocess.STDOUT if debug else subprocess.DEVNULL)) | ||||||
|         p.communicate( |         p.communicate( | ||||||
|             config.format( |             doxygen_config.format( | ||||||
|                 input=' '.join( |                 input=' '.join( | ||||||
|                     [f'"{file}"' for file in CONFIG[target]['files']]), |                     [f'"{file}"' for file in CONFIG[target]['files']]), | ||||||
|                 output=output_dir, |                 output=output_dir, | ||||||
| @@ -1108,11 +1116,7 @@ def main(config, args): | |||||||
|                         fn_map_full.update(fn_map) |                         fn_map_full.update(fn_map) | ||||||
|  |  | ||||||
|         if len(sections) == 0: |         if len(sections) == 0: | ||||||
|             if target == 'lua': |             fail(f'no sections for target: {target} (look for errors near "Preprocessing" log lines above)') | ||||||
|                 fail(f'no sections for target: {target} (this usually means' |  | ||||||
|                      + ' "luajit" was not found by scripts/lua2dox_filter)') |  | ||||||
|             else: |  | ||||||
|                 fail(f'no sections for target: {target}') |  | ||||||
|         if len(sections) > len(CONFIG[target]['section_order']): |         if len(sections) > len(CONFIG[target]['section_order']): | ||||||
|             raise RuntimeError( |             raise RuntimeError( | ||||||
|                 'found new modules "{}"; update the "section_order" map'.format( |                 'found new modules "{}"; update the "section_order" map'.format( | ||||||
| @@ -1159,7 +1163,7 @@ def main(config, args): | |||||||
| def filter_source(filename): | def filter_source(filename): | ||||||
|     name, extension = os.path.splitext(filename) |     name, extension = os.path.splitext(filename) | ||||||
|     if extension == '.lua': |     if extension == '.lua': | ||||||
|         p = subprocess.run([lua2dox_filter, filename], stdout=subprocess.PIPE) |         p = subprocess.run(['nvim', '-l', lua2dox, filename], stdout=subprocess.PIPE) | ||||||
|         op = ('?' if 0 != p.returncode else p.stdout.decode('utf-8')) |         op = ('?' if 0 != p.returncode else p.stdout.decode('utf-8')) | ||||||
|         print(op) |         print(op) | ||||||
|     else: |     else: | ||||||
|   | |||||||
| @@ -27,14 +27,13 @@ http://search.cpan.org/~alec/Doxygen-Lua-0.02/lib/Doxygen/Lua.pm | |||||||
| Running | Running | ||||||
| ------- | ------- | ||||||
|  |  | ||||||
| This file "lua2dox.lua" gets called by "lua2dox_filter" (bash). | This script "lua2dox.lua" gets called by "gen_vimdoc.py". | ||||||
|  |  | ||||||
| Doxygen must be on your system. You can experiment like so: | Doxygen must be on your system. You can experiment like so: | ||||||
|  |  | ||||||
| - Run "doxygen -g" to create a default Doxyfile. | - Run "doxygen -g" to create a default Doxyfile. | ||||||
| - Then alter it to let it recognise lua. Add the two following lines: | - Then alter it to let it recognise lua. Add the following line: | ||||||
|     FILE_PATTERNS   = *.lua |     FILE_PATTERNS   = *.lua | ||||||
|     FILTER_PATTERNS = *.lua=lua2dox_filter |  | ||||||
| - Then run "doxygen". | - Then run "doxygen". | ||||||
|  |  | ||||||
| The core function reads the input file (filename or stdin) and outputs some pseudo C-ish language. | The core function reads the input file (filename or stdin) and outputs some pseudo C-ish language. | ||||||
| @@ -117,26 +116,6 @@ local function string_split(Str, Pattern) | |||||||
|   return splitStr |   return splitStr | ||||||
| end | end | ||||||
|  |  | ||||||
| --! \class TCore_Commandline |  | ||||||
| --! \brief reads/parses commandline |  | ||||||
| local TCore_Commandline = class() |  | ||||||
|  |  | ||||||
| --! \brief constructor |  | ||||||
| function TCore_Commandline.init(this) |  | ||||||
|   this.argv = arg |  | ||||||
|   this.parsed = {} |  | ||||||
|   this.params = {} |  | ||||||
| end |  | ||||||
|  |  | ||||||
| --! \brief get value |  | ||||||
| function TCore_Commandline.getRaw(this, Key, Default) |  | ||||||
|   local val = this.argv[Key] |  | ||||||
|   if not val then |  | ||||||
|     val = Default |  | ||||||
|   end |  | ||||||
|   return val |  | ||||||
| end |  | ||||||
|  |  | ||||||
| ------------------------------- | ------------------------------- | ||||||
| --! \brief file buffer | --! \brief file buffer | ||||||
| --! | --! | ||||||
| @@ -147,7 +126,7 @@ local TStream_Read = class() | |||||||
| --! | --! | ||||||
| --! \param Filename name of file to read (or nil == stdin) | --! \param Filename name of file to read (or nil == stdin) | ||||||
| function TStream_Read.getContents(this, Filename) | function TStream_Read.getContents(this, Filename) | ||||||
|   assert(Filename) |   assert(Filename, ('invalid file: %s'):format(Filename)) | ||||||
|   -- get lines from file |   -- get lines from file | ||||||
|   -- syphon lines to our table |   -- syphon lines to our table | ||||||
|   local filecontents = {} |   local filecontents = {} | ||||||
| @@ -548,15 +527,14 @@ end | |||||||
| local This_app = TApp() | local This_app = TApp() | ||||||
|  |  | ||||||
| --main | --main | ||||||
| local cl = TCore_Commandline() |  | ||||||
|  |  | ||||||
| local argv1 = cl:getRaw(2) | local argv1 = arg[1] | ||||||
| if argv1 == '--help' then | if argv1 == '--help' then | ||||||
|   TCore_IO_writeln(This_app:getVersion()) |   TCore_IO_writeln(This_app:getVersion()) | ||||||
|   TCore_IO_writeln(This_app:getCopyright()) |   TCore_IO_writeln(This_app:getCopyright()) | ||||||
|   TCore_IO_writeln([[ |   TCore_IO_writeln([[ | ||||||
|   run as: |   run as: | ||||||
|   lua2dox_filter <param> |   nvim -l scripts/lua2dox.lua <param> | ||||||
|   -------------- |   -------------- | ||||||
|   Param: |   Param: | ||||||
|   <filename> : interprets filename |   <filename> : interprets filename | ||||||
|   | |||||||
| @@ -1,90 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| ########################################################################### |  | ||||||
| #   Copyright (C) 2012 by Simon Dales   # |  | ||||||
| #   simon@purrsoft.co.uk   # |  | ||||||
| #                                                                         # |  | ||||||
| #   This program is free software; you can redistribute it and/or modify  # |  | ||||||
| #   it under the terms of the GNU General Public License as published by  # |  | ||||||
| #   the Free Software Foundation; either version 2 of the License, or     # |  | ||||||
| #   (at your option) any later version.                                   # |  | ||||||
| #                                                                         # |  | ||||||
| #   This program is distributed in the hope that it will be useful,       # |  | ||||||
| #   but WITHOUT ANY WARRANTY; without even the implied warranty of        # |  | ||||||
| #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         # |  | ||||||
| #   GNU General Public License for more details.                          # |  | ||||||
| #                                                                         # |  | ||||||
| #   You should have received a copy of the GNU General Public License     # |  | ||||||
| #   along with this program; if not, write to the                         # |  | ||||||
| #   Free Software Foundation, Inc.,                                       # |  | ||||||
| #   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             # |  | ||||||
| ########################################################################### |  | ||||||
| LANG="" |  | ||||||
|  |  | ||||||
| ##! \brief test executable to see if it exists |  | ||||||
| test_executable() { |  | ||||||
|   P_EXE="$1" |  | ||||||
|   ######### |  | ||||||
|   WHICH=$(which "$P_EXE") |  | ||||||
|   if test -z "${WHICH}"; then |  | ||||||
|     echo "not found \"${P_EXE}\"" |  | ||||||
|   else |  | ||||||
|     EXE="${P_EXE}" |  | ||||||
|   fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ##! \brief sets the lua interpreter |  | ||||||
| set_lua() { |  | ||||||
|   if test -z "${EXE}"; then |  | ||||||
|     test_executable '.deps/usr/bin/luajit' |  | ||||||
|   fi |  | ||||||
|  |  | ||||||
|   if test -z "${EXE}"; then |  | ||||||
|     test_executable 'luajit' |  | ||||||
|   fi |  | ||||||
|  |  | ||||||
|   if test -z "${EXE}"; then |  | ||||||
|     test_executable 'lua' |  | ||||||
|   fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ##! \brief makes canonical name of file |  | ||||||
| ##! |  | ||||||
| ##! Note that "readlink -f" doesn't work in MacOSX |  | ||||||
| ##! |  | ||||||
| do_readlink() { |  | ||||||
|   pushd . > /dev/null |  | ||||||
|   TARGET_FILE=$1 |  | ||||||
|  |  | ||||||
|   cd "$(dirname $TARGET_FILE)" |  | ||||||
|   TARGET_FILE=$(basename "$TARGET_FILE") |  | ||||||
|  |  | ||||||
|   # Iterate down a (possible) chain of symlinks |  | ||||||
|   while [ -L "$TARGET_FILE" ]; do |  | ||||||
|     TARGET_FILE=$(readlink "$TARGET_FILE") |  | ||||||
|     cd $(dirname "$TARGET_FILE") |  | ||||||
|     TARGET_FILE=$(basename "$TARGET_FILE") |  | ||||||
|   done |  | ||||||
|  |  | ||||||
|   PHYS_DIR=$(pwd -P) |  | ||||||
|   RESULT=$PHYS_DIR |  | ||||||
|   popd > /dev/null |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ##main |  | ||||||
| set_lua |  | ||||||
| if test -z "${EXE}"; then |  | ||||||
|   echo "no lua interpreter found" |  | ||||||
|   exit 1 |  | ||||||
| else |  | ||||||
|   BASENAME=$(basename "$0") |  | ||||||
|   do_readlink "$0" |  | ||||||
|   DIRNAME="${RESULT}" |  | ||||||
|  |  | ||||||
|   LUASCRIPT="${DIRNAME}/lua2dox.lua ${BASENAME}" |  | ||||||
|   #echo "lua[${LUASCRIPT}]" |  | ||||||
|  |  | ||||||
|   ${EXE} ${LUASCRIPT} $@ |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| ##eof |  | ||||||
							
								
								
									
										2566
									
								
								src/Doxyfile
									
									
									
									
									
								
							
							
						
						
									
										2566
									
								
								src/Doxyfile
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -515,7 +515,7 @@ EXTERN int allbuf_lock INIT(= 0); | |||||||
| /// not allowed then. | /// not allowed then. | ||||||
| EXTERN int sandbox INIT(= 0); | EXTERN int sandbox INIT(= 0); | ||||||
|  |  | ||||||
| /// Batch-mode: "-es" or "-Es" commandline argument was given. | /// Batch-mode: "-es", "-Es", "-l" commandline argument was given. | ||||||
| EXTERN int silent_mode INIT(= false); | EXTERN int silent_mode INIT(= false); | ||||||
|  |  | ||||||
| /// Start position of active Visual selection. | /// Start position of active Visual selection. | ||||||
|   | |||||||
| @@ -323,6 +323,34 @@ static int nlua_thr_api_nvim__get_runtime(lua_State *lstate) | |||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Copies all args into the Lua `arg` global. | ||||||
|  | /// | ||||||
|  | /// Example: | ||||||
|  | ///     nvim -l foo.lua -- -e "sin=math.sin" script a b | ||||||
|  | /// | ||||||
|  | /// @note `lua` CLI sets _negative_ `arg` indices to the arguments upto "-e". | ||||||
|  | /// | ||||||
|  | /// @see https://www.lua.org/pil/1.4.html | ||||||
|  | /// @see https://github.com/premake/premake-core/blob/1c1304637f4f5e50ba8c57aae8d1d80ec3b7aaf2/src/host/premake.c#L563-L594 | ||||||
|  | /// | ||||||
|  | /// @returns number of args (stops at "--") | ||||||
|  | int nlua_set_argv(char **argv, int argc) | ||||||
|  | { | ||||||
|  |   lua_State *const L = global_lstate; | ||||||
|  |   lua_newtable(L); | ||||||
|  |   int i = 0; | ||||||
|  |   for (; i < argc; i++) { | ||||||
|  |     if (strequal("--", argv[i])) { | ||||||
|  |       i--; | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |     lua_pushstring(L, argv[i]); | ||||||
|  |     lua_rawseti(L, -2, i + 1); | ||||||
|  |   } | ||||||
|  |   lua_setglobal(L, "arg"); | ||||||
|  |   return i + 1; | ||||||
|  | } | ||||||
|  |  | ||||||
| static void nlua_schedule_event(void **argv) | static void nlua_schedule_event(void **argv) | ||||||
| { | { | ||||||
|   LuaRef cb = (LuaRef)(ptrdiff_t)argv[0]; |   LuaRef cb = (LuaRef)(ptrdiff_t)argv[0]; | ||||||
|   | |||||||
| @@ -275,14 +275,14 @@ int main(int argc, char **argv) | |||||||
|   // Check if we have an interactive window. |   // Check if we have an interactive window. | ||||||
|   check_and_set_isatty(¶ms); |   check_and_set_isatty(¶ms); | ||||||
|  |  | ||||||
|  |   // TODO: should we try to keep param scan before this? | ||||||
|  |   nlua_init(); | ||||||
|  |   TIME_MSG("init lua interpreter"); | ||||||
|  |  | ||||||
|   // Process the command line arguments.  File names are put in the global |   // Process the command line arguments.  File names are put in the global | ||||||
|   // argument list "global_alist". |   // argument list "global_alist". | ||||||
|   command_line_scan(¶ms); |   command_line_scan(¶ms); | ||||||
|  |  | ||||||
|   nlua_init(); |  | ||||||
|  |  | ||||||
|   TIME_MSG("init lua interpreter"); |  | ||||||
|  |  | ||||||
|   if (embedded_mode) { |   if (embedded_mode) { | ||||||
|     const char *err; |     const char *err; | ||||||
|     if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) { |     if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) { | ||||||
| @@ -363,8 +363,7 @@ int main(int argc, char **argv) | |||||||
|   debug_break_level = params.use_debug_break_level; |   debug_break_level = params.use_debug_break_level; | ||||||
|  |  | ||||||
|   // Read ex-commands if invoked with "-es". |   // Read ex-commands if invoked with "-es". | ||||||
|   if (!params.input_isatty && !params.input_neverscript |   if (!params.input_isatty && !params.input_istext && silent_mode && exmode_active) { | ||||||
|       && silent_mode && exmode_active) { |  | ||||||
|     input_start(STDIN_FILENO); |     input_start(STDIN_FILENO); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -409,14 +408,12 @@ int main(int argc, char **argv) | |||||||
|   init_default_autocmds(); |   init_default_autocmds(); | ||||||
|   TIME_MSG("init default autocommands"); |   TIME_MSG("init default autocommands"); | ||||||
|  |  | ||||||
|   bool vimrc_none = params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE"); |   bool vimrc_none = strequal(params.use_vimrc, "NONE"); | ||||||
|  |  | ||||||
|   // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. |   // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. | ||||||
|   // Allows for setting 'loadplugins' there. |   // Allows for setting 'loadplugins' there. | ||||||
|   if (vimrc_none) { |   // For --clean we still want to load plugins. | ||||||
|     // When using --clean we still want to load plugins |   p_lpl = vimrc_none ? params.clean : p_lpl; | ||||||
|     p_lpl = params.clean; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Execute --cmd arguments. |   // Execute --cmd arguments. | ||||||
|   exe_pre_commands(¶ms); |   exe_pre_commands(¶ms); | ||||||
| @@ -610,6 +607,11 @@ int main(int argc, char **argv) | |||||||
|     (void)eval_has_provider("clipboard"); |     (void)eval_has_provider("clipboard"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if (params.luaf != NULL) { | ||||||
|  |     nlua_exec_file(params.luaf); | ||||||
|  |     // return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   TIME_MSG("before starting main loop"); |   TIME_MSG("before starting main loop"); | ||||||
|   ILOG("starting main loop"); |   ILOG("starting main loop"); | ||||||
|  |  | ||||||
| @@ -962,7 +964,7 @@ static bool edit_stdin(mparm_T *parmp) | |||||||
| { | { | ||||||
|   bool implicit = !headless_mode |   bool implicit = !headless_mode | ||||||
|                   && !(embedded_mode && stdin_fd <= 0) |                   && !(embedded_mode && stdin_fd <= 0) | ||||||
|                   && (!exmode_active || parmp->input_neverscript) |                   && (!exmode_active || parmp->input_istext) | ||||||
|                   && !parmp->input_isatty |                   && !parmp->input_isatty | ||||||
|                   && parmp->scriptin == NULL;  // `-s -` was not given. |                   && parmp->scriptin == NULL;  // `-s -` was not given. | ||||||
|   return parmp->had_stdin_file || implicit; |   return parmp->had_stdin_file || implicit; | ||||||
| @@ -993,9 +995,9 @@ static void command_line_scan(mparm_T *parmp) | |||||||
|       } else { |       } else { | ||||||
|         parmp->commands[parmp->n_commands++] = &(argv[0][1]); |         parmp->commands[parmp->n_commands++] = &(argv[0][1]); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       // Optional argument. |  | ||||||
|     } else if (argv[0][0] == '-' && !had_minmin) { |     } else if (argv[0][0] == '-' && !had_minmin) { | ||||||
|  |       // Optional argument. | ||||||
|  |  | ||||||
|       want_argument = false; |       want_argument = false; | ||||||
|       char c = argv[0][argv_idx++]; |       char c = argv[0][argv_idx++]; | ||||||
|       switch (c) { |       switch (c) { | ||||||
| @@ -1005,9 +1007,7 @@ static void command_line_scan(mparm_T *parmp) | |||||||
|           silent_mode = true; |           silent_mode = true; | ||||||
|           parmp->no_swap_file = true; |           parmp->no_swap_file = true; | ||||||
|         } else { |         } else { | ||||||
|           if (parmp->edit_type != EDIT_NONE |           if (parmp->edit_type > EDIT_STDIN) { | ||||||
|               && parmp->edit_type != EDIT_FILE |  | ||||||
|               && parmp->edit_type != EDIT_STDIN) { |  | ||||||
|             mainerr(err_too_many_args, argv[0]); |             mainerr(err_too_many_args, argv[0]); | ||||||
|           } |           } | ||||||
|           parmp->had_stdin_file = true; |           parmp->had_stdin_file = true; | ||||||
| @@ -1015,7 +1015,7 @@ static void command_line_scan(mparm_T *parmp) | |||||||
|         } |         } | ||||||
|         argv_idx = -1;  // skip to next argument |         argv_idx = -1;  // skip to next argument | ||||||
|         break; |         break; | ||||||
|       case '-':    // "--" don't take any more option arguments |       case '-':    // "--" No more option arguments. | ||||||
|         // "--help" give help message |         // "--help" give help message | ||||||
|         // "--version" give version message |         // "--version" give version message | ||||||
|         // "--noplugin[s]" skip plugins |         // "--noplugin[s]" skip plugins | ||||||
| @@ -1111,7 +1111,7 @@ static void command_line_scan(mparm_T *parmp) | |||||||
|         break; |         break; | ||||||
|       case 'E':    // "-E" Ex mode |       case 'E':    // "-E" Ex mode | ||||||
|         exmode_active = true; |         exmode_active = true; | ||||||
|         parmp->input_neverscript = true; |         parmp->input_istext = true; | ||||||
|         break; |         break; | ||||||
|       case 'f':    // "-f"  GUI: run in foreground. |       case 'f':    // "-f"  GUI: run in foreground. | ||||||
|         break; |         break; | ||||||
| @@ -1123,10 +1123,6 @@ static void command_line_scan(mparm_T *parmp) | |||||||
|         p_hkmap = true; |         p_hkmap = true; | ||||||
|         set_option_value_give_err("rl", 1L, NULL, 0); |         set_option_value_give_err("rl", 1L, NULL, 0); | ||||||
|         break; |         break; | ||||||
|       case 'l':    // "-l" lisp mode, 'lisp' and 'showmatch' on. |  | ||||||
|         set_option_value_give_err("lisp", 1L, NULL, 0); |  | ||||||
|         p_sm = true; |  | ||||||
|         break; |  | ||||||
|       case 'M':    // "-M"  no changes or writing of files |       case 'M':    // "-M"  no changes or writing of files | ||||||
|         reset_modifiable(); |         reset_modifiable(); | ||||||
|         FALLTHROUGH; |         FALLTHROUGH; | ||||||
| @@ -1231,6 +1227,7 @@ static void command_line_scan(mparm_T *parmp) | |||||||
|         FALLTHROUGH; |         FALLTHROUGH; | ||||||
|       case 'S':    // "-S {file}" execute Vim script |       case 'S':    // "-S {file}" execute Vim script | ||||||
|       case 'i':    // "-i {shada}" use for ShaDa file |       case 'i':    // "-i {shada}" use for ShaDa file | ||||||
|  |       case 'l':    // "-l {file}" Lua mode | ||||||
|       case 'u':    // "-u {vimrc}" vim inits file |       case 'u':    // "-u {vimrc}" vim inits file | ||||||
|       case 'U':    // "-U {gvimrc}" gvim inits file |       case 'U':    // "-U {gvimrc}" gvim inits file | ||||||
|       case 'W':    // "-W {scriptout}" overwrite |       case 'W':    // "-W {scriptout}" overwrite | ||||||
| @@ -1311,6 +1308,27 @@ static void command_line_scan(mparm_T *parmp) | |||||||
|           set_option_value_give_err("shadafile", 0L, argv[0], 0); |           set_option_value_give_err("shadafile", 0L, argv[0], 0); | ||||||
|           break; |           break; | ||||||
|  |  | ||||||
|  |         case 'l':    // "-l" Lua script: args after "-l". | ||||||
|  |           silent_mode = true; | ||||||
|  |           p_verbose = 1; | ||||||
|  |           parmp->no_swap_file = true; | ||||||
|  |           parmp->use_vimrc = parmp->use_vimrc ? parmp->use_vimrc : "NONE"; | ||||||
|  |           if (p_shadafile == NULL || *p_shadafile == NUL) { | ||||||
|  |             set_option_value_give_err("shadafile", 0L, "NONE", 0); | ||||||
|  |           } | ||||||
|  |           parmp->luaf = argv[0]; | ||||||
|  |           argc--; | ||||||
|  |           argv++; | ||||||
|  |           // Lua args after "-l <file>" (upto "--"). | ||||||
|  |           int l_argc = nlua_set_argv(argv, argc); | ||||||
|  |           assert(l_argc >= 0); | ||||||
|  |           argc = argc - l_argc; | ||||||
|  |           if (argc > 0) {  // Found "--". | ||||||
|  |             argv = argv + l_argc; | ||||||
|  |             had_minmin = true; | ||||||
|  |           } | ||||||
|  |           break; | ||||||
|  |  | ||||||
|         case 's':    // "-s {scriptin}" read from script file |         case 's':    // "-s {scriptin}" read from script file | ||||||
|           if (parmp->scriptin != NULL) { |           if (parmp->scriptin != NULL) { | ||||||
| scripterror: | scripterror: | ||||||
| @@ -1354,9 +1372,7 @@ scripterror: | |||||||
|       argv_idx = -1;  // skip to next argument |       argv_idx = -1;  // skip to next argument | ||||||
|  |  | ||||||
|       // Check for only one type of editing. |       // Check for only one type of editing. | ||||||
|       if (parmp->edit_type != EDIT_NONE |       if (parmp->edit_type > EDIT_STDIN) { | ||||||
|           && parmp->edit_type != EDIT_FILE |  | ||||||
|           && parmp->edit_type != EDIT_STDIN) { |  | ||||||
|         mainerr(err_too_many_args, argv[0]); |         mainerr(err_too_many_args, argv[0]); | ||||||
|       } |       } | ||||||
|       parmp->edit_type = EDIT_FILE; |       parmp->edit_type = EDIT_FILE; | ||||||
| @@ -1421,6 +1437,7 @@ static void init_params(mparm_T *paramp, int argc, char **argv) | |||||||
|   paramp->listen_addr = NULL; |   paramp->listen_addr = NULL; | ||||||
|   paramp->server_addr = NULL; |   paramp->server_addr = NULL; | ||||||
|   paramp->remote = 0; |   paramp->remote = 0; | ||||||
|  |   paramp->luaf = NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Initialize global startuptime file if "--startuptime" passed as an argument. | /// Initialize global startuptime file if "--startuptime" passed as an argument. | ||||||
| @@ -2154,6 +2171,7 @@ static void usage(void) | |||||||
|   os_msg(_("  +                     Start at end of file\n")); |   os_msg(_("  +                     Start at end of file\n")); | ||||||
|   os_msg(_("  --cmd <cmd>           Execute <cmd> before any config\n")); |   os_msg(_("  --cmd <cmd>           Execute <cmd> before any config\n")); | ||||||
|   os_msg(_("  +<cmd>, -c <cmd>      Execute <cmd> after config and first file\n")); |   os_msg(_("  +<cmd>, -c <cmd>      Execute <cmd> after config and first file\n")); | ||||||
|  |   os_msg(_("  -l <script> [args...] Execute Lua <script> (with optional args)\n")); | ||||||
|   os_msg("\n"); |   os_msg("\n"); | ||||||
|   os_msg(_("  -b                    Binary mode\n")); |   os_msg(_("  -b                    Binary mode\n")); | ||||||
|   os_msg(_("  -d                    Diff mode\n")); |   os_msg(_("  -d                    Diff mode\n")); | ||||||
|   | |||||||
| @@ -23,15 +23,17 @@ typedef struct { | |||||||
|   char cmds_tofree[MAX_ARG_CMDS];       // commands that need free() |   char cmds_tofree[MAX_ARG_CMDS];       // commands that need free() | ||||||
|   int n_pre_commands;                   // no. of commands from --cmd |   int n_pre_commands;                   // no. of commands from --cmd | ||||||
|   char *pre_commands[MAX_ARG_CMDS];     // commands from --cmd argument |   char *pre_commands[MAX_ARG_CMDS];     // commands from --cmd argument | ||||||
|  |   char *luaf;                           // Lua script filename from "-l" | ||||||
|  |  | ||||||
|   int edit_type;                        // type of editing to do |   int edit_type;                        // type of editing to do | ||||||
|   char *tagname;                        // tag from -t argument |   char *tagname;                        // tag from -t argument | ||||||
|   char *use_ef;                         // 'errorfile' from -q argument |   char *use_ef;                         // 'errorfile' from -q argument | ||||||
|  |  | ||||||
|   bool input_isatty;                    // stdin is a terminal |   bool input_isatty;                    // stdin is a terminal | ||||||
|  |   bool input_istext;                    // stdin is text, not executable (-E/-Es) | ||||||
|   bool output_isatty;                   // stdout is a terminal |   bool output_isatty;                   // stdout is a terminal | ||||||
|   bool err_isatty;                      // stderr is a terminal |   bool err_isatty;                      // stderr is a terminal | ||||||
|   bool input_neverscript;               // never treat stdin as script (-E/-Es) |  | ||||||
|   int no_swap_file;                     // "-n" argument used |   int no_swap_file;                     // "-n" argument used | ||||||
|   int use_debug_break_level; |   int use_debug_break_level; | ||||||
|   int window_count;                     // number of windows to use |   int window_count;                     // number of windows to use | ||||||
|   | |||||||
| @@ -962,6 +962,7 @@ endfunc | |||||||
|  |  | ||||||
| " Test for enabling the lisp mode on startup | " Test for enabling the lisp mode on startup | ||||||
| func Test_l_arg() | func Test_l_arg() | ||||||
|  |   throw 'Skipped: Nvim -l arg differs from Vim' | ||||||
|   let after =<< trim [CODE] |   let after =<< trim [CODE] | ||||||
|     let s = 'lisp=' .. &lisp .. ', showmatch=' .. &showmatch |     let s = 'lisp=' .. &lisp .. ', showmatch=' .. &showmatch | ||||||
|     call writefile([s], 'Xtestout') |     call writefile([s], 'Xtestout') | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ local write_file = helpers.write_file | |||||||
| local meths = helpers.meths | local meths = helpers.meths | ||||||
| local alter_slashes = helpers.alter_slashes | local alter_slashes = helpers.alter_slashes | ||||||
| local is_os = helpers.is_os | local is_os = helpers.is_os | ||||||
|  | local dedent = helpers.dedent | ||||||
|  |  | ||||||
| local testfile = 'Xtest_startuptime' | local testfile = 'Xtest_startuptime' | ||||||
| after_each(function() | after_each(function() | ||||||
| @@ -47,6 +48,34 @@ describe('startup', function() | |||||||
|       assert_log("require%('vim%._editor'%)", testfile, 100) |       assert_log("require%('vim%._editor'%)", testfile, 100) | ||||||
|     end) |     end) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|  |   it('-D does not hang #12647', function() | ||||||
|  |     clear() | ||||||
|  |     local screen | ||||||
|  |     screen = Screen.new(60, 7) | ||||||
|  |     screen:attach() | ||||||
|  |     command([[let g:id = termopen('"]]..nvim_prog.. | ||||||
|  |     [[" -u NONE -i NONE --cmd "set noruler" -D')]]) | ||||||
|  |     screen:expect([[ | ||||||
|  |       ^                                                            | | ||||||
|  |                                                                   | | ||||||
|  |       Entering Debug mode.  Type "cont" to continue.              | | ||||||
|  |       nvim_exec()                                                 | | ||||||
|  |       cmd: aunmenu *                                              | | ||||||
|  |       >                                                           | | ||||||
|  |                                                                   | | ||||||
|  |     ]]) | ||||||
|  |     command([[call chansend(g:id, "cont\n")]]) | ||||||
|  |     screen:expect([[ | ||||||
|  |       ^                                                            | | ||||||
|  |       ~                                                           | | ||||||
|  |       ~                                                           | | ||||||
|  |       ~                                                           | | ||||||
|  |       [No Name]                                                   | | ||||||
|  |                                                                   | | ||||||
|  |                                                                   | | ||||||
|  |     ]]) | ||||||
|  |   end) | ||||||
| end) | end) | ||||||
|  |  | ||||||
| describe('startup', function() | describe('startup', function() | ||||||
| @@ -58,6 +87,94 @@ describe('startup', function() | |||||||
|     os.remove('Xtest_startup_ttyout') |     os.remove('Xtest_startup_ttyout') | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|  |   describe('-l Lua', function() | ||||||
|  |     local function assert_l_out(expected, args_before, args_after) | ||||||
|  |       local args = { nvim_prog, '--clean' } | ||||||
|  |       vim.list_extend(args, args_before or {}) | ||||||
|  |       vim.list_extend(args, { '-l', 'test/functional/fixtures/startup.lua' }) | ||||||
|  |       vim.list_extend(args, args_after or {}) | ||||||
|  |       local out = funcs.system(args):gsub('\r\n', '\n') | ||||||
|  |       return eq(dedent(expected), out) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it('failure modes', function() | ||||||
|  |       -- nvim -l <missing file> | ||||||
|  |       matches('nvim: Argument missing after: "%-l"', funcs.system({ nvim_prog, '-l' })) | ||||||
|  |       eq(1, eval('v:shell_error')) | ||||||
|  |     end) | ||||||
|  |  | ||||||
|  |     it('os.exit() sets Nvim exitcode', function() | ||||||
|  |       -- nvim -l foo.lua -arg1 -- a b c | ||||||
|  |       assert_l_out([[ | ||||||
|  |           bufs: | ||||||
|  |           args: { "-arg1", "--exitcode", "73", "--arg2" }]], | ||||||
|  |         {}, | ||||||
|  |         { '-arg1', "--exitcode", "73", '--arg2' } | ||||||
|  |       ) | ||||||
|  |       eq(73, eval('v:shell_error')) | ||||||
|  |     end) | ||||||
|  |  | ||||||
|  |     it('sets _G.arg', function() | ||||||
|  |       -- nvim -l foo.lua -arg1 -- a b c | ||||||
|  |       assert_l_out([[ | ||||||
|  |           bufs: | ||||||
|  |           args: { "-arg1", "--arg2", "arg3" }]], | ||||||
|  |         {}, | ||||||
|  |         { '-arg1', '--arg2', 'arg3' } | ||||||
|  |       ) | ||||||
|  |       eq(0, eval('v:shell_error')) | ||||||
|  |  | ||||||
|  |       -- nvim -l foo.lua -- | ||||||
|  |       assert_l_out([[ | ||||||
|  |           bufs: | ||||||
|  |           args: {}]], | ||||||
|  |         {}, | ||||||
|  |         { '--' } | ||||||
|  |       ) | ||||||
|  |       eq(0, eval('v:shell_error')) | ||||||
|  |  | ||||||
|  |       -- nvim file1 file2 -l foo.lua -arg1 -- file3 file4 | ||||||
|  |       assert_l_out([[ | ||||||
|  |           bufs: file1 file2 file3 file4 | ||||||
|  |           args: { "-arg1", "arg 2" }]], | ||||||
|  |         { 'file1', 'file2', }, | ||||||
|  |         { '-arg1', 'arg 2', '--', 'file3', 'file4' } | ||||||
|  |       ) | ||||||
|  |       eq(0, eval('v:shell_error')) | ||||||
|  |  | ||||||
|  |       -- nvim file1 file2 -l foo.lua -arg1 -- | ||||||
|  |       assert_l_out([[ | ||||||
|  |           bufs: file1 file2 | ||||||
|  |           args: { "-arg1" }]], | ||||||
|  |         { 'file1', 'file2', }, | ||||||
|  |         { '-arg1', '--' } | ||||||
|  |       ) | ||||||
|  |       eq(0, eval('v:shell_error')) | ||||||
|  |  | ||||||
|  |       -- nvim -l foo.lua <vim args> | ||||||
|  |       assert_l_out([[ | ||||||
|  |           bufs: | ||||||
|  |           args: { "-c", "set wrap?" }]], | ||||||
|  |         {}, | ||||||
|  |         { '-c', 'set wrap?' } | ||||||
|  |       ) | ||||||
|  |       eq(0, eval('v:shell_error')) | ||||||
|  |  | ||||||
|  |       -- nvim <vim args> -l foo.lua <vim args> | ||||||
|  |       assert_l_out( | ||||||
|  |         -- luacheck: ignore 611 (Line contains only whitespaces) | ||||||
|  |         [[ | ||||||
|  |             wrap | ||||||
|  |            | ||||||
|  |           bufs: | ||||||
|  |           args: { "-c", "set wrap?" }]], | ||||||
|  |         { '-c', 'set wrap?' }, | ||||||
|  |         { '-c', 'set wrap?' } | ||||||
|  |       ) | ||||||
|  |       eq(0, eval('v:shell_error')) | ||||||
|  |     end) | ||||||
|  |   end) | ||||||
|  |  | ||||||
|   it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function() |   it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function() | ||||||
|     -- system() puts a pipe at both ends. |     -- system() puts a pipe at both ends. | ||||||
|     local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', |     local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', | ||||||
| @@ -66,6 +183,7 @@ describe('startup', function() | |||||||
|                                '+q' }) |                                '+q' }) | ||||||
|     eq('0 0', out) |     eq('0 0', out) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   it('with --embed: has("ttyin")==0 has("ttyout")==0', function() |   it('with --embed: has("ttyin")==0 has("ttyout")==0', function() | ||||||
|     local screen = Screen.new(25, 3) |     local screen = Screen.new(25, 3) | ||||||
|     -- Remote UI connected by --embed. |     -- Remote UI connected by --embed. | ||||||
| @@ -77,6 +195,7 @@ describe('startup', function() | |||||||
|       0 0                      | |       0 0                      | | ||||||
|     ]]) |     ]]) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   it('in a TTY: has("ttyin")==1 has("ttyout")==1', function() |   it('in a TTY: has("ttyin")==1 has("ttyout")==1', function() | ||||||
|     local screen = Screen.new(25, 4) |     local screen = Screen.new(25, 4) | ||||||
|     screen:attach() |     screen:attach() | ||||||
| @@ -95,6 +214,7 @@ describe('startup', function() | |||||||
|                                | |                                | | ||||||
|     ]]) |     ]]) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   it('output to pipe: has("ttyin")==1 has("ttyout")==0', function() |   it('output to pipe: has("ttyin")==1 has("ttyout")==0', function() | ||||||
|     if is_os('win') then |     if is_os('win') then | ||||||
|       command([[set shellcmdflag=/s\ /c shellxquote=\"]]) |       command([[set shellcmdflag=/s\ /c shellxquote=\"]]) | ||||||
| @@ -111,6 +231,7 @@ describe('startup', function() | |||||||
|          read_file('Xtest_startup_ttyout')) |          read_file('Xtest_startup_ttyout')) | ||||||
|     end) |     end) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   it('input from pipe: has("ttyin")==0 has("ttyout")==1', function() |   it('input from pipe: has("ttyin")==0 has("ttyout")==1', function() | ||||||
|     if is_os('win') then |     if is_os('win') then | ||||||
|       command([[set shellcmdflag=/s\ /c shellxquote=\"]]) |       command([[set shellcmdflag=/s\ /c shellxquote=\"]]) | ||||||
| @@ -128,6 +249,7 @@ describe('startup', function() | |||||||
|          read_file('Xtest_startup_ttyout')) |          read_file('Xtest_startup_ttyout')) | ||||||
|     end) |     end) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   it('input from pipe (implicit) #7679', function() |   it('input from pipe (implicit) #7679', function() | ||||||
|     local screen = Screen.new(25, 4) |     local screen = Screen.new(25, 4) | ||||||
|     screen:attach() |     screen:attach() | ||||||
| @@ -147,6 +269,7 @@ describe('startup', function() | |||||||
|                                | |                                | | ||||||
|     ]]) |     ]]) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   it('input from pipe + file args #7679', function() |   it('input from pipe + file args #7679', function() | ||||||
|     eq('ohyeah\r\n0 0 bufs=3', |     eq('ohyeah\r\n0 0 bufs=3', | ||||||
|        funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless', |        funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless', | ||||||
| @@ -532,32 +655,6 @@ describe('sysinit', function() | |||||||
|        eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')) |        eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   it('fixed hang issue with -D (#12647)', function() |  | ||||||
|     local screen |  | ||||||
|     screen = Screen.new(60, 7) |  | ||||||
|     screen:attach() |  | ||||||
|     command([[let g:id = termopen('"]]..nvim_prog.. |  | ||||||
|     [[" -u NONE -i NONE --cmd "set noruler" -D')]]) |  | ||||||
|     screen:expect([[ |  | ||||||
|       ^                                                            | |  | ||||||
|       Entering Debug mode.  Type "cont" to continue.              | |  | ||||||
|       nvim_exec()                                                 | |  | ||||||
|       cmd: aunmenu *                                              | |  | ||||||
|       >                                                           | |  | ||||||
|       <" -u NONE -i NONE --cmd "set noruler" -D 1,0-1          All| |  | ||||||
|                                                                   | |  | ||||||
|     ]]) |  | ||||||
|     command([[call chansend(g:id, "cont\n")]]) |  | ||||||
|     screen:expect([[ |  | ||||||
|       ^                                                            | |  | ||||||
|       ~                                                           | |  | ||||||
|       ~                                                           | |  | ||||||
|       [No Name]                                                   | |  | ||||||
|                                                                   | |  | ||||||
|       <" -u NONE -i NONE --cmd "set noruler" -D 1,0-1          All| |  | ||||||
|                                                                   | |  | ||||||
|     ]]) |  | ||||||
|   end) |  | ||||||
| end) | end) | ||||||
|  |  | ||||||
| describe('user config init', function() | describe('user config init', function() | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								test/functional/fixtures/startup.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								test/functional/fixtures/startup.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | -- Test "nvim -l foo.lua …" | ||||||
|  |  | ||||||
|  | local function printbufs() | ||||||
|  |   local bufs = '' | ||||||
|  |   for _, v in ipairs(vim.api.nvim_list_bufs()) do | ||||||
|  |     local b = vim.fn.bufname(v) | ||||||
|  |     if b:len() > 0 then | ||||||
|  |       bufs = ('%s %s'):format(bufs, b) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |   print(('bufs:%s'):format(bufs)) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local function parseargs(args) | ||||||
|  |   local exitcode = nil | ||||||
|  |   for i = 1, #args do | ||||||
|  |     if args[i] == '--exitcode' then | ||||||
|  |       exitcode = tonumber(args[i + 1]) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |   return exitcode | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local function main() | ||||||
|  |   printbufs() | ||||||
|  |   print('args:', vim.inspect(_G.arg)) | ||||||
|  |  | ||||||
|  |   local exitcode = parseargs(_G.arg) | ||||||
|  |   if type(exitcode) == 'number' then | ||||||
|  |     os.exit(exitcode) | ||||||
|  |   end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | main() | ||||||
		Reference in New Issue
	
	Block a user
	 Justin M. Keyes
					Justin M. Keyes