packer.nvim icon indicating copy to clipboard operation
packer.nvim copied to clipboard

callbacks passed to packer.use doesn't capture variable

Open nikonakoneko opened this issue 3 years ago • 2 comments

I'm not sure if it's a known limitation or if I'm doing something wrong.

  • nvim --version: NVIM v0.7.0 Build type: Release LuaJIT 2.1.0-beta3 Compiled by builder@e4bc05c9ff63

Features: +acl +iconv +tui See ":help feature-compile"

system vimrc file: "$VIM/sysinit.vim" fall-back for $VIM: "/data/data/com.termux/files/usr/share/nvim"

Run :checkhealth for more info

  • git --version: git version 2.36.1
  • Operating system/version: Android 11
  • Terminal name/version: Termux 0.118.0

Note: also happens on desktop computers with either Linux or MacOS

Steps to reproduce

pass to packer.use some callback that should capture a variable like this:

local packer = require("packer")

local function test(x)
    packer.init()
    packer.reset()
    packer.use({"rafamadriz/neon", config = (function()
        vim.pretty_print(x)
        return (function()
            vim.pretty_print(x)
        end)
    end)()})
    packer.compile()
    packer.install()
end

test({ a = true })

Actual behaviour

When packer.use parameter is evaluated, x get printed and has the expected value But when packer calls the config callback and x is printed it has a nil value

Expected behaviour

x should'nt be nil when packer calls config callback

packer files

packer log file
[DEBUG Tue May 24 16:59:26 2022 1.6755160604589e+15] ...p/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:324: Processing plugin specs
[DEBUG Tue May 24 16:59:26 2022 1.6755160652966e+15] ...ack/packer/start/packer.nvim/lua/packer/plugin_utils.lua:176: Updating FS state
[DEBUG Tue May 24 16:59:26 2022 1.6755160656316e+15] ...p/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:380: packer.install: requiring modules
[DEBUG Tue May 24 16:59:26 2022 1.6755160663582e+15] ...p/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:324: Processing plugin specs
[DEBUG Tue May 24 16:59:26 2022 1.6755160664079e+15] ...ack/packer/start/packer.nvim/lua/packer/plugin_utils.lua:176: Updating FS state
[DEBUG Tue May 24 16:59:27 2022 1.6755171760936e+15] ...site/pack/packer/start/packer.nvim/lua/packer/update.lua:56: Fixing plugin types
[DEBUG Tue May 24 16:59:27 2022 1.675517176173e+15] ...site/pack/packer/start/packer.nvim/lua/packer/update.lua:67: Done fixing plugin types
[INFO  Tue May 24 16:59:27 2022 1.6755171793783e+15] ...p/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:736: Finished compiling lazy-loaders!
[DEBUG Tue May 24 16:59:27 2022 1.6755171794959e+15] ...p/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:344: packer.compile: Complete
[INFO  Tue May 24 16:59:27 2022 1.6755171875225e+15] ...p/nvim/site/pack/packer/start/packer.nvim/lua/packer.lua:401: All configured plugins are installed
packer compiled file
-- Automatically generated packer.nvim plugin loader code

if vim.api.nvim_call_function('has', {'nvim-0.5'}) ~= 1 then
  vim.api.nvim_command('echohl WarningMsg | echom "Invalid Neovim version for packer.nvim! | echohl None"')
  return
end

vim.api.nvim_command('packadd packer.nvim')

local no_errors, error_msg = pcall(function()

  local time
  local profile_info
  local should_profile = false
  if should_profile then
    local hrtime = vim.loop.hrtime
    profile_info = {}
    time = function(chunk, start)
      if start then
        profile_info[chunk] = hrtime()
      else
        profile_info[chunk] = (hrtime() - profile_info[chunk]) / 1e6
      end
    end
  else
    time = function(chunk, start) end
  end
  
local function save_profiles(threshold)
  local sorted_times = {}
  for chunk_name, time_taken in pairs(profile_info) do
    sorted_times[#sorted_times + 1] = {chunk_name, time_taken}
  end
  table.sort(sorted_times, function(a, b) return a[2] > b[2] end)
  local results = {}
  for i, elem in ipairs(sorted_times) do
    if not threshold or threshold and elem[2] > threshold then
      results[i] = elem[1] .. ' took ' .. elem[2] .. 'ms'
    end
  end

  _G._packer = _G._packer or {}
  _G._packer.profile_output = results
end

time([[Luarocks path setup]], true)
local package_path_str = "/data/data/com.termux/files/home/.cache/nvim/packer_hererocks/2.1.0-beta3/share/lua/5.1/?.lua;/data/data/com.termux/files/home/.cache/nvim/packer_hererocks/2.1.0-beta3/share/lua/5.1/?/init.lua;/data/data/com.termux/files/home/.cache/nvim/packer_hererocks/2.1.0-beta3/lib/luarocks/rocks-5.1/?.lua;/data/data/com.termux/files/home/.cache/nvim/packer_hererocks/2.1.0-beta3/lib/luarocks/rocks-5.1/?/init.lua"
local install_cpath_pattern = "/data/data/com.termux/files/home/.cache/nvim/packer_hererocks/2.1.0-beta3/lib/lua/5.1/?.so"
if not string.find(package.path, package_path_str, 1, true) then
  package.path = package.path .. ';' .. package_path_str
end

if not string.find(package.cpath, install_cpath_pattern, 1, true) then
  package.cpath = package.cpath .. ';' .. install_cpath_pattern
end

time([[Luarocks path setup]], false)
time([[try_loadstring definition]], true)
local function try_loadstring(s, component, name)
  local success, result = pcall(loadstring(s), name, _G.packer_plugins[name])
  if not success then
    vim.schedule(function()
      vim.api.nvim_notify('packer.nvim: Error running ' .. component .. ' for ' .. name .. ': ' .. result, vim.log.levels.ERROR, {})
    end)
  end
  return result
end

time([[try_loadstring definition]], false)
time([[Defining packer_plugins]], true)
_G.packer_plugins = {
  neon = {
    config = { "\27LJ\2\n.\0\0\3\1\2\0\0056\0\0\0009\0\1\0-\2\0\0B\0\2\1K\0\1\0\0\0\17pretty_print\bvim\0" },
    loaded = true,
    path = "/data/data/com.termux/files/home/src/neovim-conf/tmp/nvim/site/pack/packer/start/neon",
    url = "https://github.com/rafamadriz/neon"
  }
}

time([[Defining packer_plugins]], false)
-- Config for: neon
time([[Config for neon]], true)
try_loadstring("\27LJ\2\n.\0\0\3\1\2\0\0056\0\0\0009\0\1\0-\2\0\0B\0\2\1K\0\1\0\0\0\17pretty_print\bvim\0", "config", "neon")
time([[Config for neon]], false)
if should_profile then save_profiles() end

end)

if not no_errors then
  error_msg = error_msg:gsub('"', '\\"')
  vim.api.nvim_command('echohl ErrorMsg | echom "Error in packer_compiled: '..error_msg..'" | echom "Please check your config for correctness" | echohl None')
end

nikonakoneko avatar May 24 '22 15:05 nikonakoneko

I tried to do something similar and also experienced this "weird" behaviour. I just took a quick look at the "packer/compile.lua" file in the packer plugin folder. As far as i can see Packer first converts the function to a string in "packer/compile.lua" on line 272. And later executes the string on line 118 with "loadstring".

According to the README "config" can be either a string or function, i guess thats why loadstring is used. Unfortunately "loadstring" doesn't work with variables in a different file because it just directly executes the provided string as lua code.

Edit: This has actually been reported some time ago and is alreads being worked on. #443

johanneshorner avatar Jun 25 '22 16:06 johanneshorner

I am also facing this issue , and this design decision looks extremely weird to me, why would you bake the config like that is beyond me but this basically does not allow you to capture any viable information at runtime its bad.

asmodeus812 avatar Oct 08 '22 18:10 asmodeus812