Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment Variable $EDITOR Not Being Properly Resolved #2261

Open
3 tasks done
evpeople opened this issue Jan 29, 2025 · 7 comments
Open
3 tasks done

Environment Variable $EDITOR Not Being Properly Resolved #2261

evpeople opened this issue Jan 29, 2025 · 7 comments
Labels
bug Something isn't working

Comments

@evpeople
Copy link
Contributor

What system are you running Yazi on?

macOS

What terminal are you running Yazi in?

wezterm 20240203-110809-5046fc22

yazi --debug output

./yazi --debug

Yazi
    Version: 0.4.3 (ef3f16be 2025-01-29)
    Debug  : true
    Triple : aarch64-apple-darwin (macos-aarch64)
    Rustc  : 1.84.0 (9fc6b431 2025-01-07)

Ya
    Version: 0.4.2 (Homebrew 2024-12-20)

Emulator
    TERM                : Some("xterm-256color")
    TERM_PROGRAM        : Some("WezTerm")
    TERM_PROGRAM_VERSION: Some("20240203-110809-5046fc22")
    Brand.from_env      : Some(WezTerm)
    Emulator.detect     : Emulator { kind: Left(WezTerm), light: false, cell_size: Some((16, 31)) }
    Emulator.detect_full: Ok(Emulator { kind: Left(WezTerm), light: false, cell_size: Some((16, 31)) })

Adapter
    Adapter.matches: Iip

Desktop
    XDG_SESSION_TYPE           : None
    WAYLAND_DISPLAY            : None
    DISPLAY                    : None
    SWAYSOCK                   : None
    HYPRLAND_INSTANCE_SIGNATURE: None
    WAYFIRE_SOCKET             : None

SSH
    shared.in_ssh_connection: false

WSL
    WSL: false

Neovim
    NVIM          : false
    Neovim version: 0.10.3

Variables
    SHELL           : Some("/bin/zsh")
    EDITOR          : Some("lvim")
    VISUAL          : None
    YAZI_FILE_ONE   : None
    YAZI_CONFIG_HOME: None
    YAZI_ZOXIDE_OPTS: None
    FZF_DEFAULT_OPTS: None

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

Multiplexers
    TMUX               : false
    tmux version       : tmux 3.5a
    tmux build flags   : enable-sixel=Unknown
    ZELLIJ_SESSION_NAME: None
    Zellij version     : 0.41.2

Dependencies
    file          : 5.41
    ueberzugpp    : No such file or directory (os error 2)
    ffmpeg/ffprobe: 7.1 / 7.1
    pdftoppm      : 25.01.0
    magick        : 7.1.1-43
    fzf           : 0.58.0
    fd/fdfind     : 10.2.0 / No such file or directory (os error 2)
    rg            : 14.1.1
    chafa         : No such file or directory (os error 2)
    zoxide        : 0.9.6
    7zz/7z        : 24.09 / No such file or directory (os error 2)
    jq            : 1.7.1

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

Describe the bug

When using Yazi's batch rename feature with $EDITOR environment variable in the configuration, it fails with exit code 127 without meaningful error messages in the log. However, explicitly specifying the full command works as expected.

Minimal reproducer

  1. Environment setup:
$ echo $EDITOR
lvim
$ which lvim
lvim: aliased to NVIM_APPNAME="nvim-lazyvim" nvim
  1. Steps to reproduce:
  • Start Yazi by running yazi command
  • Navigate to any file
  • Press Enter to open the file
  • Observe that the file fails to open with exit code 127
  1. Configuration that fails (default configuration):
{ run = '${EDITOR:-vi} "$@"', desc = "$EDITOR", block = true, for = "unix" }
    1. Configuration that works :
{ run = 'NVIM_APPNAME="nvim-lazyvim" nvim "$@"', desc = "$EDITOR", block = true, for = "unix" }

Anything else?

No response

Checklist

  • I tried the latest nightly build, and the issue is still reproducible
  • I updated the debug information (yazi --debug) input box to the nightly that I tried
  • I can reproduce it after disabling all custom configs/plugins (mv ~/.config/yazi ~/.config/yazi-backup)
@evpeople evpeople added the bug Something isn't working label Jan 29, 2025
@evpeople
Copy link
Contributor Author

I have been diving into the code to understand how it works. I noticed that there might be an opportunity to use the shellexpand crate to handle environment variable expansion. Specifically, I think it could be useful around line 293 in yazi-scheduler/src/scheduler.rs.
I’m not sure how the process is actually spawned to run the editor, but I suspect that the issue might be related to environment variable expansion. If this is the right place to make changes, I’d love to hear your thoughts on whether shellexpand could be a good fit here.

@sxyazi
Copy link
Owner

sxyazi commented Jan 29, 2025

What does sh -c 'echo $EDITOR' say?

@sxyazi sxyazi added the waiting on op Waiting for more information from the original poster label Jan 29, 2025
@evpeople
Copy link
Contributor Author

like this

sh -c 'echo $EDITOR'
lvim

@github-actions github-actions bot removed the waiting on op Waiting for more information from the original poster label Jan 30, 2025
@evpeople
Copy link
Contributor Author

My .zshrc file is configured as follows:

alias lvim='NVIM_APPNAME="nvim-lazyvim" nvim'
alias vim='lvim'
alias v='lvim'
export EDITOR='lvim'

@sxyazi
Copy link
Owner

sxyazi commented Jan 30, 2025

This is a bit strange. Yazi relies on sh -c to parse and run user shell commands, and sh automatically resolves those environment variables:

Command::new("sh")
.arg("-c")
.stdin(opt.stdio())
.stdout(opt.stdio())
.stderr(opt.stdio())
.arg(opt.cmd)
.args(opt.args)
.current_dir(opt.cwd)
.kill_on_drop(!opt.orphan)
.pre_exec(move || {
if opt.orphan && libc::setpgid(0, 0) < 0 {
return Err(std::io::Error::last_os_error());
}
Ok(())
})
.spawn()?

I don't think this needs to be handled separately in Yazi, because that would mean we'd have to write a shell parser ourselves and deal with all sorts of edge cases, like nested shells. For example, in sh -c 'sh -c "echo \$0" $1' 1 2, the value should be 2, not 1.

@sxyazi sxyazi added the waiting on op Waiting for more information from the original poster label Jan 30, 2025
@evpeople
Copy link
Contributor Author

Thank you for pointing out the specific execution location. I now have a starting point for troubleshooting, and I will try some other configurations to confirm the actual issue.

@github-actions github-actions bot removed the waiting on op Waiting for more information from the original poster label Jan 31, 2025
@sxyazi sxyazi added the waiting on op Waiting for more information from the original poster label Feb 2, 2025
@evpeople
Copy link
Contributor Author

evpeople commented Feb 5, 2025

I have identified two primary issues

  1. Alias Not Effective Outside Interactive Shell: The alias command only becomes effective within an interactive shell session. Although sh inherits the environment variable setting, it does not recognize that lvim is aliased to NVIM_APPNAME="nvim-lazyvim" nvim. This causes operations relying on this alias to fail.

  2. Environment Variable Assignment Misinterpretation by Shell: Even modifying the configuration to export EDITOR='NVIM_APPNAME="nvim-lazyvim" nvim' does not resolve the issue. The problem persists because the shell interprets the preceding environment variable assignment (NVIM_APPNAME="nvim-lazyvim") as part of the command to execute rather than setting the environment variable before executing the command. This misinterpretation leads to failures when attempting to use $EDITOR.

A viable workaround involves exporting the variables separately:

export NVIM_APPNAME="nvim-lazyvim"
export EDITOR="nvim"

This approach works correctly. Another attempted solution involved using eval to execute $EDITOR from within the source code. However, I am concerned about whether this method might introduce security risks. Additionally, my initial implementation (.arg(format!("eval {:?}; exec \"$@\"", opt.cmd))) successfully opened and allowed editing of the file but also generated errors such as Permission denied and cannot execute: Undefined error: 0. These errors appear to be due to the system attempting to execute the file I intended to edit.

@github-actions github-actions bot removed the waiting on op Waiting for more information from the original poster label Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants