lua: Use automatic determining of suffixes only for package.cpath

This commit is contained in:
ZyX
2017-05-26 00:17:36 +03:00
parent 58f6ef50a8
commit a409fa2b3f
3 changed files with 42 additions and 28 deletions

View File

@@ -13,14 +13,17 @@ Lua Interface to Nvim *lua* *Lua*
Neovim lua interface automatically adjusts `package.path` and `package.cpath` 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 each time
'runtimepath' is changed, `package.path` and `package.cpath` are adjusted by 'runtimepath' is changed. `package.path` is adjusted by simply appending
prepending directories from 'runtimepath' each suffixed by `/lua` and `/lua/?.lua` and `/lua/?/init.lua` to each directory from 'runtimepath' (`/`
`?`-containing suffixes from `package.path` and `package.cpath`. I.e. when is actually a first character from `package.config`).
'runtimepath' option contains `/foo` and `package.path` contains only
`./?.lua;./a?d/j/g.nlua;/bar/?.lua` the resulting `package.path` after `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: > 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 Note that code have taken everything starting from the last path component
from existing paths containing a question mark as a `?`-containing suffix, but 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. 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 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* 1.1. Example of the plugin which uses lua modules: *lua-require-example*

View File

@@ -9,7 +9,6 @@ local function _update_package_paths()
local sep = package.config:sub(1, 1) local sep = package.config:sub(1, 1)
for _, key in ipairs({'path', 'cpath'}) do for _, key in ipairs({'path', 'cpath'}) do
local orig_str = package[key] .. ';' local orig_str = package[key] .. ';'
local pathtrails = {}
local pathtrails_ordered = {} local pathtrails_ordered = {}
local orig = {} local orig = {}
-- Note: ignores trailing item without trailing `;`. Not using something -- Note: ignores trailing item without trailing `;`. Not using something
@@ -17,13 +16,21 @@ local function _update_package_paths()
for s in orig_str:gmatch('[^;]*;') do for s in orig_str:gmatch('[^;]*;') do
s = s:sub(1, -2) -- Strip trailing semicolon s = s:sub(1, -2) -- Strip trailing semicolon
orig[#orig + 1] = s orig[#orig + 1] = s
-- Find out path patterns. pathtrail should contain something like end
-- /?.so, /?/init.lua, /?.lua. This allows not to bother determining what if key == 'path' then
-- correct suffixes are. -- /?.lua and /?/init.lua
local pathtrail = s:match('[/\\][^/\\]*%?.*$') pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}
if pathtrail and not pathtrails[pathtrail] then else
pathtrails[pathtrail] = true local pathtrails = {}
pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail for _, s in ipairs(orig) do
-- Find out path patterns. pathtrail should contain something like
-- /?.so, \?.dll. This allows not to bother determining what correct
-- suffixes are.
local pathtrail = s:match('[/\\][^/\\]*%?.*$')
if pathtrail and not pathtrails[pathtrail] then
pathtrails[pathtrail] = true
pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail
end
end end
end end
local new = {} local new = {}

View File

@@ -183,9 +183,10 @@ describe('package.path/package.cpath', function()
local function get_new_paths(sufs, runtimepaths) local function get_new_paths(sufs, runtimepaths)
runtimepaths = runtimepaths or meths.list_runtime_paths() runtimepaths = runtimepaths or meths.list_runtime_paths()
local new_paths = {} local new_paths = {}
local sep = package.config:sub(1, 1)
for _, v in ipairs(runtimepaths) do for _, v in ipairs(runtimepaths) do
for _, suf in ipairs(sufs) do for _, suf in ipairs(sufs) do
new_paths[#new_paths + 1] = v .. suf:sub(1, 1) .. 'lua' .. suf new_paths[#new_paths + 1] = v .. sep .. 'lua' .. suf
end end
end end
return new_paths return new_paths
@@ -225,23 +226,23 @@ describe('package.path/package.cpath', function()
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str)) eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
end) end)
it('understands uncommon suffixes', function() it('understands uncommon suffixes', function()
set_path('path', './?/foo/bar/baz/x.nlua') set_path('cpath', './?/foo/bar/baz/x.nlua')
meths.set_option('runtimepath', 'a') meths.set_option('runtimepath', 'a')
local new_paths = get_new_paths({'/?/foo/bar/baz/x.nlua'}, {'a'}) local new_paths = get_new_paths({'/?/foo/bar/baz/x.nlua'}, {'a'})
local new_paths_str = table.concat(new_paths, ';') local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str)) eq(new_paths_str, eval_lua('package.cpath'):sub(1, #new_paths_str))
set_path('path', './yyy?zzz/x') set_path('cpath', './yyy?zzz/x')
meths.set_option('runtimepath', 'b') meths.set_option('runtimepath', 'b')
new_paths = get_new_paths({'/yyy?zzz/x'}, {'b'}) new_paths = get_new_paths({'/yyy?zzz/x'}, {'b'})
new_paths_str = table.concat(new_paths, ';') new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str)) eq(new_paths_str, eval_lua('package.cpath'):sub(1, #new_paths_str))
set_path('path', './yyy?zzz/123?ghi/x') set_path('cpath', './yyy?zzz/123?ghi/x')
meths.set_option('runtimepath', 'b') meths.set_option('runtimepath', 'b')
new_paths = get_new_paths({'/yyy?zzz/123?ghi/x'}, {'b'}) new_paths = get_new_paths({'/yyy?zzz/123?ghi/x'}, {'b'})
new_paths_str = table.concat(new_paths, ';') new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str)) eq(new_paths_str, eval_lua('package.cpath'):sub(1, #new_paths_str))
end) end)
it('preserves empty items', function() it('preserves empty items', function()
local many_empty_path = ';;;;;;' local many_empty_path = ';;;;;;'
@@ -249,17 +250,19 @@ describe('package.path/package.cpath', function()
set_path('path', many_empty_path) set_path('path', many_empty_path)
set_path('cpath', many_empty_cpath) set_path('cpath', many_empty_cpath)
meths.set_option('runtimepath', 'a') meths.set_option('runtimepath', 'a')
-- No suffixes known, so cant add anything local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {'a'})
eq(many_empty_path, eval_lua('package.path'))
local new_paths = get_new_paths({'/?.luaso'}, {'a'})
local new_paths_str = table.concat(new_paths, ';') local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str .. ';' .. many_empty_cpath, eval_lua('package.cpath')) eq(new_paths_str .. ';' .. many_empty_path, eval_lua('package.path'))
local new_cpaths = get_new_paths({'/?.luaso'}, {'a'})
local new_cpaths_str = table.concat(new_cpaths, ';')
eq(new_cpaths_str .. ';' .. many_empty_cpath, eval_lua('package.cpath'))
end) end)
it('preserves empty value', function() it('preserves empty value', function()
set_path('path', '') set_path('path', '')
meths.set_option('runtimepath', 'a') meths.set_option('runtimepath', 'a')
-- No suffixes known, so cant add anything local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {'a'})
eq('', eval_lua('package.path')) local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str .. ';', eval_lua('package.path'))
end) end)
it('purges out all additions if runtimepath is set to empty', function() it('purges out all additions if runtimepath is set to empty', function()
local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}) local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'})