sxyazi / yazi

πŸ’₯ Blazing fast terminal file manager written in Rust, based on async I/O.
https://yazi-rs.github.io
MIT License
16.93k stars 395 forks source link

[Lua] unable to import #1811

Closed f3fora closed 1 month ago

f3fora commented 1 month ago

What system are you running Yazi on?

Linux X11

What terminal are you running Yazi in?

wezterm 20240203-110809-5046fc22

yazi --debug output

Yazi
    Version: 0.3.3
    Debug  : false
    OS     : linux-x86_64 (unix)

Ya
    Version: 0.3.3

Emulator
    Emulator.via_env: ("xterm-256color", "WezTerm")
    Emulator.via_csi: Ok(WezTerm)
    Emulator.detect : WezTerm

Adapter
    Adapter.matches: Iterm2

Desktop
    XDG_SESSION_TYPE           : Some("tty")
    WAYLAND_DISPLAY            : None
    DISPLAY                    : Some(":0")
    SWAYSOCK                   : None
    HYPRLAND_INSTANCE_SIGNATURE: None
    WAYFIRE_SOCKET             : None

SSH
    shared.in_ssh_connection: false

WSL
    WSL: false

Variables
    SHELL              : Some("/bin/bash")
    EDITOR             : Some("/usr/bin/vi")
    VISUAL             : Some("/usr/bin/vi")
    YAZI_FILE_ONE      : None
    YAZI_CONFIG_HOME   : None

Text Opener
    default: Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })
    block  : Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })

Multiplexers
    TMUX               : false
    tmux version       : No such file or directory (os error 2)
    ZELLIJ_SESSION_NAME: None
    Zellij version     : 0.40.1

Dependencies
    file             : 5.45
    ueberzugpp       : No such file or directory (os error 2)
    ffmpegthumbnailer: 2.2.3
    magick           : 7.1.1-39
    fzf              : 0.55.0
    fd               : 10.2.0
    rg               : 14.1.1
    chafa            : No such file or directory (os error 2)
    zoxide           : 0.9.6
    7z               : No such file or directory (os error 2)
    7zz              : No such file or directory (os error 2)
    jq               : 1.7.1

Did you try the latest nightly build to see if the problem got fixed?

No, and I'll explain why below

Describe the bug

Unable to import package or module in any lua file.

As an example I report a plugin ab.yazi, which try to include a package under the same directory. Of course, the packages installed system-wide are not available either.

Printing package.path and package.cpath shows an acceptable result, i,e, the path includes the wanted string. Thus, I have no idea why it doesn't work.

Minimal reproducer

ξ—Ώ .
β”œβ”€β”€ ξ—Ώ flavors
β”œβ”€β”€ ξ˜• keymap.toml
β”œβ”€β”€ ξ˜• package.toml
β”œβ”€β”€ ξ—Ώ plugins
β”‚  └── ξ—Ώ ab.yazi
β”‚     β”œβ”€β”€  cd.lua
β”‚     └──  init.lua
β”œβ”€β”€ ξ˜• theme.toml
└── ξ˜• yazi.toml
-- init.lua
local cd = require("cd")
return {
  event = {
    ya.notify(cd)
  },
}
-- cd.lua
return {
  title = "12",
  content = "12",
  level = "error",
  timeout = 12,
}
# keymap.toml
[[manager.prepend_keymap]]
on   = [";", "a", "b"]
run  = 'plugin ab'
desc = "ab plugin"

Anything else?

I haven't try nightly since the version bump happened very recently and there is no commit that seems to address this issue.

sxyazi commented 1 month ago

This is by design - require() is used to import a Yazi module, which is a directory structured as described in https://yazi-rs.github.io/docs/plugins/overview. If you inspect the logs, you'll find an error like:

failed to load plugin from "/Users/test/.config/yazi/plugins/cd.yazi/init.lua"
stack traceback:
    [C]: in local 'poll'
    [string "?"]:4: in function 'require'
    [string "test"]:3: in function <[string "test"]:2>

This means that you need to place the cd.lua as a directory in the plugins directory.

If you really want to import a single file from the current directory, use dofile():

local cd = dofile("./cd.lua")
ya.err(cd)

Doc : https://www.lua.org/manual/5.4/manual.html#pdf-dofile

Closing as it's expected behavior

f3fora commented 1 month ago

What if I want to use a package from Luarocks?

sxyazi commented 1 month ago

Can you be more specific? What kind of Luarocks package do you want to use?

Generally, if the package offers common functionality, I'll include it in the Yazi API, as this provides better performance than including external Lua files.

Yazi creates a separate Lua runtime for each async plugin, so it's assumed that user plugins won't be too large. If a plugin is big enough, it likely means it's complex, and I usually recommend breaking it into two independent plugins with full functionalities.

f3fora commented 1 month ago

My idea was to use lgi to access udisks2 API to manage external resources.

See #927

sxyazi commented 1 month ago

Why not just use the udisksctl command-line tool? It's simpler and more convenient than introducing a Luarocks package.

Users don't need to install it through Luarocks and compile any C code, and their systems probably already have udisksctl β€” I just tested it, and it's available in my freshly installed Manjaro VM.

You can use the Command API provided by Yazi to call it: https://yazi-rs.github.io/docs/plugins/utils#command, and Ranger's ranger_udisk_menu plugin is a great example you can reference to

f3fora commented 1 month ago

From udisksctl man:

This program does not assume that the caller is the super user - it is intended to be used by unprivileged users and authorizations are checked by the udisks daemon using polkit(8). Additionally, this program is not intended to be used by scripts or other programs - options/commands may change in incompatible ways in the future even in maintenance releases. See the β€œAPI STABILITY” section of udisks(8) for more information.

Eventually, one can install lua-lgi if you are in Arch-based distribution, without needing luarocks.

sxyazi commented 3 weeks ago

Ah that's true. It seems that ranger_udisk_menu uses lsblk and udisks2 together, since lsblk is also mentioned in the README. Is this approach feasible?

Getting Yazi to support Luarocks might not be easy because Yazi's require() isn't a standard Lua function.

Instead, the imported modules are returned as a wrapper table to keep track of the currently running modules, which is necessary for supporting ya.sync(). But I haven't actually used Luarocks myself, I could be wrong.

Also, Yazi uses the latest Lua 5.4, which doesn't have a ffi module like Luajit. Are you sure that udisks2 supports Lua 5.4?