rktjmp / hotpot.nvim

:stew: Carl Weathers #1 Neovim Plugin.
MIT License
359 stars 9 forks source link

Cannot require cljlib from a macro file #29

Closed datwaft closed 3 years ago

datwaft commented 3 years ago

Hello! It's me again with another issue.

A few minutes ago, I happily began to work on migrating my configuration from aniseed to hotpot; but, while trying to implement a few macros for packer, I found that I cannot require cljlib from the macro file without an error saying io global not found.

Here is the full error:

Click to expand ```error ^I.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:133: in function <.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:122> ^I[C]: at 0x7fc3d2943490 ^I[builtin#25]: at 0x7fc3d2944eb0 ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim.hotpot/init.lua:10: in main chunk ^I[C]: in function 'dofile' ^I/home/datwaft/.config/nvim/lua/cheovim/loader.lua:246: in function 'create_plugin_symlink' ^I/home/datwaft/.config/nvim/lua/cheovim.lua:14: in main chunk ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim/init.lua:1: in main chunk (import-macros {} :core.macro.pack) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Try looking to see if there's a typo. * Try using the _G table instead, eg. _G.io * Try looking to see if there's a typo. * Try using the _G table instead, eg. _G.io if you really want a global. * Try moving this code to somewhere that io is in scope. * Try binding io as a local in the scope of this code. stack traceback: ^I[C]: in function 'error' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:3282: in function 'assert-compile' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2208: in function 'assert_compile' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2373: in function 'symbol_to_expression' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2716: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1551: in function 'special' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2635: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1002: in function 'special' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2635: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1356: in function 'compile_body' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1370: in function 'special' ^I... ^I.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:133: in function <.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:122> ^I[C]: at 0x7fc3d2943490 ^I[builtin#25]: at 0x7fc3d2944eb0 ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim.hotpot/init.lua:10: in main chunk ^I[C]: in function 'dofile' ^I/home/datwaft/.config/nvim/lua/cheovim/loader.lua:246: in function 'create_plugin_symlink' ^I/home/datwaft/.config/nvim/lua/cheovim.lua:14: in main chunk ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim/init.lua:1: in main chunk if you really want a global. * Try moving this code to somewhere that io * Try looking to see if there's a typo. * Try using the _G table instead, eg. _G.io if you really want a global. * Try moving this code to somewhere that io is in scope. * Try binding io as a local in the scope of this code. stack traceback: ^I[C]: in function 'error' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:3282: in function 'assert-compile' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2208: in function 'assert_compile' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2373: in function 'symbol_to_expression' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2716: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1551: in function 'special' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2635: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1002: in function 'special' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2635: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1356: in function 'compile_body' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1370: in function 'special' ^I... ^I.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:133: in function <.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:122> ^I[C]: at 0x7fc3d2943490 ^I[builtin#25]: at 0x7fc3d2944eb0 ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim.hotpot/init.lua:10: in main chunk ^I[C]: in function 'dofile' ^I/home/datwaft/.config/nvim/lua/cheovim/loader.lua:246: in function 'create_plugin_symlink' ^I/home/datwaft/.config/nvim/lua/cheovim.lua:14: in main chunk ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim/init.lua:1: in main chunk is in scope. * Try binding io * Try looking to see if there's a typo. * Try using the _G table instead, eg. _G.io if you really want a global. * Try moving this code to somewhere that io is in scope. * Try binding io as a local in the scope of this code. stack traceback: ^I[C]: in function 'error' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:3282: in function 'assert-compile' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2208: in function 'assert_compile' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2373: in function 'symbol_to_expression' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2716: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1551: in function 'special' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2635: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1002: in function 'special' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:2635: in function 'compile1' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1356: in function 'compile_body' ^I...site/pack/packer/start/hotpot.nvim/lua/hotpot/fennel.lua:1370: in function 'special' ^I... ^I.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:133: in function <.../hotpot/start/hotpot.nvim/fnl/hotpot/searcher/module.lua:122> ^I[C]: at 0x7fc3d2943490 ^I[builtin#25]: at 0x7fc3d2944eb0 ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim.hotpot/init.lua:10: in main chunk ^I[C]: in function 'dofile' ^I/home/datwaft/.config/nvim/lua/cheovim/loader.lua:246: in function 'create_plugin_symlink' ^I/home/datwaft/.config/nvim/lua/cheovim.lua:14: in main chunk ^I[C]: in function 'require' ^I/home/datwaft/.config/nvim/init.lua:1: in main chunk as a local in the scope of this code. ```

While searching for uses of the io lua module inside cljlib I found these:

; init.fnl
439:                   (do (io.stderr:write
462:                   (do (io.stderr:write
; init-macros.fnl
129:                  (io.stderr:write "WARNING: utf8 module unavailable, seq function will not work for non-unicode strings\n")

My suspicions are that fennel is not finding the io module on compilation time.

rktjmp commented 3 years ago

I am not sure the error is due to cljlib, but that your macro is accessing io at compile time.

Prior Art: https://github.com/rktjmp/hotpot.nvim/issues/19 https://github.com/rktjmp/hotpot.nvim/issues/22 https://github.com/rktjmp/hotpot.nvim/issues/16

Fennel has some strict rules around accessing globals at compile time.

23 will expose configuration options but that branch actually wont have an effect until the next fennel release which includes a bugfix re: actually passing those options to the compiler.

As is now, try _G.io in your macros as the error says, you will still get a warning but it's pumped to stderr and doesn't effect anything functionally.

datwaft commented 3 years ago

I forgot to say, the macro file is almost empty:

(require :lib.cljlib)
{}

It is only that.

That was one of the first things I tested.

rktjmp commented 3 years ago

Post a reproduction via that docker setup if you can

datwaft commented 3 years ago

Here is the reproduction: https://github.com/datwaft/hotpot-issue_29

datwaft commented 3 years ago

Using what you told me about using _G.io instead of io I created a fix branch with this change. It seems to work using this patch, but it's another patch more to the list of patches you need to use cljlib with hotpot.

Edit: Here are the sed commands used for the patch (for if you want to document the patch or someone in the future sees this thread):

sed -i 's/(io\./(_G.io./g' config/fnl/lib/cljlib/init-macros.fnl
sed -i 's/(io\./(_G.io./g' config/fnl/lib/cljlib/init.fnl
rktjmp commented 3 years ago

Thanks for the repro. Setup takes compiler options now, see :h hotpot-setup or the readme for configuration guide and the fennel-lang.org site for options.

I use these settings to fix the issue:

  require("hotpot").setup({
    compiler = {
      macros = {
        env = "_COMPILER",
        compilerEnv = _G,
        allowedGlobals = false,
      }
    }
  })

Note you will still technically see errors in stderr until this commit is released in the next fennel release which fixes a bug in Fennel not actually propagating the options down to the compiler. Also allowedGlobals might change in the next Fennel release, I'm not sure.

Also once https://github.com/rktjmp/hotpot.nvim/pull/30 is merged you shouldn't need to patch the require :fennel calls either.

datwaft commented 3 years ago

Also once #30 is merged you shouldn't need to patch the require :fennel calls either.

Nice!


I tested your solution using this branch, it seems to work properly! 😄