mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	lua: Use automatic determining of suffixes only for package.cpath
This commit is contained in:
		@@ -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*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,15 +16,23 @@ 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
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    if key == 'path' then
 | 
				
			||||||
 | 
					      -- /?.lua and /?/init.lua
 | 
				
			||||||
 | 
					      pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      local pathtrails = {}
 | 
				
			||||||
 | 
					      for _, s in ipairs(orig) do
 | 
				
			||||||
        -- Find out path patterns. pathtrail should contain something like
 | 
					        -- Find out path patterns. pathtrail should contain something like
 | 
				
			||||||
      -- /?.so, /?/init.lua, /?.lua. This allows not to bother determining what
 | 
					        -- /?.so, \?.dll. This allows not to bother determining what correct
 | 
				
			||||||
      -- correct suffixes are.
 | 
					        -- suffixes are.
 | 
				
			||||||
        local pathtrail = s:match('[/\\][^/\\]*%?.*$')
 | 
					        local pathtrail = s:match('[/\\][^/\\]*%?.*$')
 | 
				
			||||||
        if pathtrail and not pathtrails[pathtrail] then
 | 
					        if pathtrail and not pathtrails[pathtrail] then
 | 
				
			||||||
          pathtrails[pathtrail] = true
 | 
					          pathtrails[pathtrail] = true
 | 
				
			||||||
          pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail
 | 
					          pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
    local new = {}
 | 
					    local new = {}
 | 
				
			||||||
    for _, rtp in ipairs(rtps) do
 | 
					    for _, rtp in ipairs(rtps) do
 | 
				
			||||||
      if not rtp:match(';') then
 | 
					      if not rtp:match(';') then
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 can’t 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 can’t 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'})
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user