From 97602371e6b00f280ede5e3f6b0e0c1144f46c72 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 23 May 2017 00:46:57 +0300 Subject: lua: Add paths from &runtimepath to package.path and package.cpath --- runtime/doc/if_lua.txt | 27 ++++++++++++++++++++++++++- runtime/doc/vim_diff.txt | 2 ++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt index 470f3bde7a..2e4d32027d 100644 --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -9,7 +9,32 @@ Lua Interface to Nvim *lua* *Lua* Type to see the table of contents. ============================================================================== -1. Commands *lua-commands* +1. Importing modules *lua-require* + +Neovim lua interface automatically adjusts `package.path` and `package.cpath` +according to effective &runtimepath value. Adjustment happens after each time +'runtimepath' is changed, `package.path` and `package.cpath` are adjusted by +prepending directories from 'runtimepath' each suffixed by `/lua` and +`?`-containing suffixes from `package.path` and `package.cpath`. I.e. when +'runtimepath' option contains `/foo` and `package.path` contains only +`./a?d/j/g.nlua;./?.lua;/bar/?.lua` the resulting `package.path` after +adjustments will look like this: > + + /foo/lua/?.lua;/foo/lua/a?d/j/g.nlua;./a?d/j/g.nlua;./?.lua;/bar/?.lua + +Note that code have taken everything starting from the last path component +from existing paths containing a question mark as a `?`-containing suffix, but +only applied unique suffixes. + +Note 2: even though adjustments happens automatically Neovim does not track +current values of `package.path` or `package.cpath`. If you happened to delete +some paths from there you need to reset 'runtimepath' to make them readded. + +Note 3: paths from 'runtimepath' which contain semicolons cannot be put into +`package.[c]path` and thus are ignored. + +============================================================================== +2. Commands *lua-commands* *:lua* :[range]lua {chunk} diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 8851ef2d4b..24410ddaac 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -244,6 +244,8 @@ Lua interface (|if_lua.txt|): while calling lua chunk: [string ""]:1: TEST” in Neovim. - Lua has direct access to Nvim |API| via `vim.api`. +- Lua package.path and package.cpath are automatically updated according to + 'runtimepath': |lua-require|. - Currently, most legacy Vim features are missing. |input()| and |inputdialog()| gained support for each other’s features (return -- cgit From 643d620164646257392fb6df65fc7560341ba088 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 23 May 2017 22:49:08 +0300 Subject: doc: Add example plugin --- runtime/doc/if_lua.txt | 81 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt index 2e4d32027d..2961e2adba 100644 --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -17,10 +17,10 @@ according to effective &runtimepath value. Adjustment happens after each time prepending directories from 'runtimepath' each suffixed by `/lua` and `?`-containing suffixes from `package.path` and `package.cpath`. I.e. when 'runtimepath' option contains `/foo` and `package.path` contains only -`./a?d/j/g.nlua;./?.lua;/bar/?.lua` the resulting `package.path` after +`./?.lua;./a?d/j/g.nlua;/bar/?.lua` the resulting `package.path` after adjustments will look like this: > - /foo/lua/?.lua;/foo/lua/a?d/j/g.nlua;./a?d/j/g.nlua;./?.lua;/bar/?.lua + /foo/lua/?.lua;/foo/lua/a?d/j/g.nlua;./?.lua;./a?d/j/g.nlua;/bar/?.lua Note that code have taken everything starting from the last path component from existing paths containing a question mark as a `?`-containing suffix, but @@ -33,6 +33,83 @@ some paths from there you need to reset 'runtimepath' to make them readded. Note 3: paths from 'runtimepath' which contain semicolons cannot be put into `package.[c]path` and thus are ignored. +------------------------------------------------------------------------------ +1.1. Example of the plugin which uses lua modules: *lua-require-example* + +The following example plugin adds a command `:MakeCharBlob` which transforms +current buffer into a long `unsigned char` array. Lua contains transformation +function in a module `lua/charblob.lua` which is imported in +`autoload/charblob.vim` (`require("charblob")`). Example plugin is supposed +to be put into any directory from 'runtimepath', e.g. `~/.config/nvim` (in +this case `lua/charblob.lua` means `~/.config/nvim/lua/charblob.lua`). + +autoload/charblob.vim: > + + function charblob#encode_buffer() + call setline(1, luaeval( + \ 'require("charblob").encode(unpack(_A))', + \ [getline(1, '$'), &textwidth, ' '])) + endfunction + +plugin/charblob.vim: > + + if exists('g:charblob_loaded') + finish + endif + let g:charblob_loaded = 1 + + command MakeCharBlob :call charblob#encode_buffer() + +lua/charblob.lua: > + + local function charblob_bytes_iter(lines) + local init_s = { + next_line_idx = 1, + next_byte_idx = 1, + lines = lines, + } + local function next(s, _) + if lines[s.next_line_idx] == nil then + return nil + end + if s.next_byte_idx > #(lines[s.next_line_idx]) then + s.next_line_idx = s.next_line_idx + 1 + s.next_byte_idx = 1 + return ('\n'):byte() + end + local ret = lines[s.next_line_idx]:byte(s.next_byte_idx) + if ret == ('\n'):byte() then + ret = 0 -- See :h NL-used-for-NUL. + end + s.next_byte_idx = s.next_byte_idx + 1 + return ret + end + return next, init_s, nil + end + + local function charblob_encode(lines, textwidth, indent) + local ret = { + 'const unsigned char blob[] = {', + indent, + } + for byte in charblob_bytes_iter(lines) do + -- .- space + number (width 3) + comma + if #(ret[#ret]) + 5 > textwidth then + ret[#ret + 1] = indent + else + ret[#ret] = ret[#ret] .. ' ' + end + ret[#ret] = ret[#ret] .. (('%3u,'):format(byte)) + end + ret[#ret + 1] = '};' + return ret + end + + return { + bytes_iter = charblob_bytes_iter, + encode = charblob_encode, + } + ============================================================================== 2. Commands *lua-commands* -- cgit From a409fa2b3f821a40a01d3919cd93384b1403156f Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 26 May 2017 00:17:36 +0300 Subject: lua: Use automatic determining of suffixes only for package.cpath --- runtime/doc/if_lua.txt | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt index 2961e2adba..d28a03e144 100644 --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -13,14 +13,17 @@ Lua Interface to Nvim *lua* *Lua* Neovim lua interface automatically adjusts `package.path` and `package.cpath` according to effective &runtimepath value. Adjustment happens after each time -'runtimepath' is changed, `package.path` and `package.cpath` are adjusted by -prepending directories from 'runtimepath' each suffixed by `/lua` and -`?`-containing suffixes from `package.path` and `package.cpath`. I.e. when -'runtimepath' option contains `/foo` and `package.path` contains only -`./?.lua;./a?d/j/g.nlua;/bar/?.lua` the resulting `package.path` after +'runtimepath' is changed. `package.path` is adjusted by simply appending +`/lua/?.lua` and `/lua/?/init.lua` to each directory from 'runtimepath' (`/` +is actually a first character from `package.config`). + +`package.cpath` is adjusted by prepending directories from 'runtimepath' each +suffixed by `/lua` and `?`-containing suffixes from existing `package.cpath`. +I.e. when 'runtimepath' option contains `/foo` and `package.cpath` contains +only `./?.so;./a?d/j/g.elf;/bar/?.so` the resulting `package.cpath` after adjustments will look like this: > - /foo/lua/?.lua;/foo/lua/a?d/j/g.nlua;./?.lua;./a?d/j/g.nlua;/bar/?.lua + /foo/lua/?.so;/foo/lua/a?d/j/g.elf;./?.so;./a?d/j/g.elf;/bar/?.so Note that code have taken everything starting from the last path component from existing paths containing a question mark as a `?`-containing suffix, but @@ -31,7 +34,8 @@ current values of `package.path` or `package.cpath`. If you happened to delete some paths from there you need to reset 'runtimepath' to make them readded. Note 3: paths from 'runtimepath' which contain semicolons cannot be put into -`package.[c]path` and thus are ignored. +`package.[c]path` for that being a semicolon-separated list and thus are +ignored. ------------------------------------------------------------------------------ 1.1. Example of the plugin which uses lua modules: *lua-require-example* -- cgit From cab3a248b2704e8f188eaf20206f2c87d1a76c0d Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 26 May 2017 01:31:02 +0300 Subject: doc: Clarify documentation --- runtime/doc/if_lua.txt | 74 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 20 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt index d28a03e144..c4efd57b45 100644 --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -12,30 +12,64 @@ Lua Interface to Nvim *lua* *Lua* 1. Importing modules *lua-require* Neovim lua interface automatically adjusts `package.path` and `package.cpath` -according to effective &runtimepath value. Adjustment happens after each time +according to effective &runtimepath value. Adjustment happens after 'runtimepath' is changed. `package.path` is adjusted by simply appending `/lua/?.lua` and `/lua/?/init.lua` to each directory from 'runtimepath' (`/` -is actually a first character from `package.config`). - -`package.cpath` is adjusted by prepending directories from 'runtimepath' each -suffixed by `/lua` and `?`-containing suffixes from existing `package.cpath`. -I.e. when 'runtimepath' option contains `/foo` and `package.cpath` contains -only `./?.so;./a?d/j/g.elf;/bar/?.so` the resulting `package.cpath` after -adjustments will look like this: > - - /foo/lua/?.so;/foo/lua/a?d/j/g.elf;./?.so;./a?d/j/g.elf;/bar/?.so - -Note that code have taken everything starting from the last path component -from existing paths containing a question mark as a `?`-containing suffix, but -only applied unique suffixes. +is actually the first character of `package.config`). + +Similarly to `package.path`, modified directories from `runtimepath` are also +added to `package.cpath`. In this case, instead of appending `/lua/?.lua` and +`/lua/?/init.lua` to each runtimepath, all unique `?`-containing suffixes of +the existing `package.cpath` are used. Here is an example: + +1. Given that + - 'runtimepath' contains `/foo/bar,/xxx;yyy/baz,/abc`; + - initial (defined at compile time or derived from + `$LUA_CPATH`/`$LUA_INIT`) `package.cpath` contains + `./?.so;/def/ghi/a?d/j/g.elf;/def/?.so`. +2. It finds `?`-containing suffixes `/?.so`, `/a?d/j/g.elf` and `/?.so`, in + order: parts of the path starting from the first path component containing + question mark and preceding path separator. +3. The suffix of `/def/?.so`, namely `/?.so` is not unique, as it’s the same + as the suffix of the first path from `package.path` (i.e. `./?.so`). Which + leaves `/?.so` and `/a?d/j/g.elf`, in this order. +4. 'runtimepath' has three paths: `/foo/bar`, `/xxx;yyy/baz` and `/abc`. The + second one contains semicolon which is a paths separator so it is out, + leaving only `/foo/bar` and `/abc`, in order. +5. The cartesian product of paths from 4. and suffixes from 3. is taken, + giving four variants. In each variant `/lua` path segment is inserted + between path and suffix, leaving + + - `/foo/bar/lua/?.so` + - `/foo/bar/lua/a?d/j/g.elf` + - `/abc/lua/?.so` + - `/abc/lua/a?d/j/g.elf` + +6. New paths are prepended to the original `package.cpath`. + +The result will look like this: + + `/foo/bar,/xxx;yyy/baz,/abc` ('runtimepath') + × `./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` (`package.cpath`) + + = `/foo/bar/lua/?.so;/foo/bar/lua/a?d/j/g.elf;/abc/lua/?.so;/abc/lua/a?d/j/g.elf;./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` + +Note: to keep up with 'runtimepath' updates paths added at previous update are +remembered and removed at the next update, while all paths derived from the +new 'runtimepath' are prepended as described above. This allows removing +paths when path is removed from 'runtimepath', adding paths when they are +added and reordering `package.path`/`package.cpath` content if 'runtimepath' +was reordered. Note 2: even though adjustments happens automatically Neovim does not track -current values of `package.path` or `package.cpath`. If you happened to delete -some paths from there you need to reset 'runtimepath' to make them readded. - -Note 3: paths from 'runtimepath' which contain semicolons cannot be put into -`package.[c]path` for that being a semicolon-separated list and thus are -ignored. +current values of `package.path` or `package.cpath`. If you happened to +delete some paths from there you need to reset 'runtimepath' to make them +readded. Just running `let &runtimepath = &runtimepath` should work. + +Note 3: skipping paths from 'runtimepath' which contain semicolons applies +both to `package.path` and `package.cpath`. Given that there is a number of +badly written plugins using shell which will not work with paths containing +semicolons it is better to not have them in 'runtimepath' at all. ------------------------------------------------------------------------------ 1.1. Example of the plugin which uses lua modules: *lua-require-example* -- cgit