Skip to content

Proper multi file plugin support #2781

@Grauly

Description

@Grauly

yazi --debug output

Yazi
    Version: 25.4.8 (Nixpkgs 2025-04-08)
    Debug  : false
    Triple : x86_64-unknown-linux-gnu (linux-x86_64)
    Rustc  : 1.86.0 (05f9846f 2025-03-31)

Ya
    Version: 25.4.8 (Nixpkgs 2025-04-08)

Emulator
    TERM                : Some("xterm-kitty")
    TERM_PROGRAM        : None
    TERM_PROGRAM_VERSION: None
    Brand.from_env      : Some(Kitty)
    Emulator.detect     : Emulator { kind: Left(Kitty), light: false, cell_size: Some((9, 20)) }

Adapter
    Adapter.matches    : Kgp
    Dimension.available: WindowSize { rows: 24, columns: 78, width: 702, height: 480 }

Desktop
    XDG_SESSION_TYPE           : Some("wayland")
    WAYLAND_DISPLAY            : Some("wayland-1")
    DISPLAY                    : Some(":0")
    SWAYSOCK                   : Some("/run/user/1000/sway-ipc.1000.2379.sock")
    HYPRLAND_INSTANCE_SIGNATURE: None
    WAYFIRE_SOCKET             : None

SSH
    shared.in_ssh_connection: false

WSL
    WSL: false

Variables
    SHELL           : Some("/run/current-system/sw/bin/zsh")
    EDITOR          : Some("nvim")
    VISUAL          : None
    YAZI_FILE_ONE   : None
    YAZI_CONFIG_HOME: None
    YAZI_ZOXIDE_OPTS: None
    FZF_DEFAULT_OPTS: None

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

Multiplexers
    TMUX               : false
    tmux version       : No such file or directory (os error 2)
    tmux build flags   : enable-sixel=Unknown
    ZELLIJ_SESSION_NAME: None
    Zellij version     : No such file or directory (os error 2)

Dependencies
    file          : 5.46
    ueberzugpp    : No such file or directory (os error 2)
    ffmpeg/ffprobe: 7.1.1 / 7.1.1
    pdftoppm      : 25.05.0
    magick        : 7.1.1-47
    fzf           : 0.62.0
    fd/fdfind     : 10.2.0 / No such file or directory (os error 2)
    rg            : 14.1.1
    chafa         : 1.14.5
    zoxide        : 0.9.7
    7zz/7z        : 24.09 / No such file or directory (os error 2)
    jq            : 1.7.1

Clipboard
    wl-copy/paste: 2.2.1 / 2.2.1
    xclip        : No such file or directory (os error 2)
    xsel         : No such file or directory (os error 2)

Routine
    `file -bL --mime-type`: text/plain


See https://yazi-rs.github.io/docs/plugins/overview#debugging on how to enable logging or debug runtime errors.

Please describe the problem you're trying to solve

Writing (especially complex) plugins gets annoying after some time, because you have to stuff everything into one file, main.lua.
All current known ways to load extra files are require hardcoding of certain aspects, or the creation of plugin shaped non-plugins.

Would you be willing to contribute this feature?

  • Yes, I'll give it a shot

Describe the solution you'd like

A way to import files relative to the current file, without having to specify the entire path through the users home directory, without having to include the plugins own name in the path and without having to resort to creating dummy "plugins" to hold such code.

Ideally, the solution would entail:

  • returning the require function to its base lua status
  • replacing the current usage of require to something more indicative of plugins loading, such as loadplugin

I do however recognize that that is basically impossible, due to backwards compatibility.
As such, alternate solutions could:

  • create a replacement for require (maybe import)
  • get dofile to be able to search at the current file (as supposed to be possible in #1811)
  • mention in the documentation that require is fully replaced and cannot be used for loading files in the lua way
  • make the current plugins directory location easily accessible to easily use dofile

The replacement for require could limit the search for files to the current plugins directory to avoid the problem mentioned in #2714

Additional context

So far, I have looked at: #1811 which suggest to use dofile(./thatfile.lua), that however does not work as of my latest attempt at it.
#2718 explains why exactly the require function is unusable for this purpose (being used for plugin loading). It also highlights that dofile should be used for similar purposes, however it uses a unnecessary long path in the dofile call, which both requires hardcoding the path form the users home to the plugin directory (possibly causing incompatibility between linux and windows, which can be adressed by checking against ya.family()), and inclusion of the plugins own name on the disk, which are both sub-optimal to do.
#1916 shows a slightly altered way of doing it, but still has the same pain points as above.

A imperfect workaround is to mimic the plugin folders structure inside of the plugin like this:

myplugin.yazi
├── include.yazi
│   └── main.lua
└── main.lua

and call require("myplugin.yazi/include") which again requires hardcoding of the plugin name (in fact, having access to the current plugins name would be useful for notifications as well), and that the nested main.lua is of a plugin format itself (otherwise the plugin crashes there).

Do note that using a fully absolute path or a home directory based path using . does work with dofile, but is as mentioned above inelegant.

My personal favorite solution would be a function (again, maybe import) that would be able to just load files from the current plugins directory.
The minimum solution would give access the the plugins name on disk, to allow for piecing together a path to the plugins directory.
This would just be fully made easy if a path to the current plugin would be directly available.

Checklist

  • I have searched the existing issues/discussions
  • The latest nightly build doesn't already have this feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions