Canop / broot

A new way to see and navigate directory trees : https://dystroy.org/broot
MIT License
10.48k stars 228 forks source link

zsh: cd into folder name including brackets fails to match a supposed pattern #595

Open AndydeCleyre opened 1 year ago

AndydeCleyre commented 1 year ago
$ podman run -it -e TERM=$TERM --rm docker.io/library/alpine:edge
# apk add broot zsh
# broot --version
broot 1.14.2
# broot --print-shell-function zsh >>~/.zshrc
# exec zsh
# mkdir '[notapattern]'
# br

In broot, use verb cd on the folder named [notapattern]

New Configuration files written in "/root/.config/broot".
You should have a look at them.
(eval):1: no matches found: /[notapattern]
Canop commented 1 year ago

I confirm that this looks like a zsh specific problem:

AndydeCleyre commented 1 year ago

I'm not sure what the generated outcmd looks like. Is it generated specifically depending on the shell, or is the same outcmd used regardless of shell? And I really don't know how the filename gets formatted/inserted...

If it's shell-aware, for zsh it might be a good idea to:

Canop commented 1 year ago

The function used for zsh is defined here: https://github.com/Canop/broot/blob/master/src/shell_install/bash.rs#L31

If you're willing to investigate and try a better general solution, go ahead, I'm a little too busy atm.

AndydeCleyre commented 1 year ago

Thanks, I'll look around. But I'm not so much wondering about the br function as the outcmd generation.

EDIT: found cmd_result_exec_from_parent_shell, will take a closer look.

EDIT: even more relevant: shell_exec_string

AndydeCleyre commented 1 year ago

Can you replace the Zsh-specific cd command with noglob cd?

$ mkdir '[nopat]'
$ cd [nopat]
zsh: no matches found: [nopat]
$ noglob cd [nopat]
$ pwd
/home/andy/[nopat]

If broot's cd verb always operates on a literal path, it should never need a glob, so it seems safe enough.

Canop commented 1 year ago

@AndydeCleyre Would that entry in verbs.hjson solve the problem for zsh users ?

    {
        key: alt-enter
        external: "noglob cd {file}"
        from_shell: true
    }
AndydeCleyre commented 1 year ago

That verb works, yes.

But I don't use a shortcut and rely on typing :cd. I currently override the :cd behavior for files so that it works on that file's parent:

{
  apply_to: "file"
  cmd: ":focus;:cd"
  shortcut: cd
}

But reviewing the docs and this conversation, it seems I can replace that with:

{
  external: "noglob cd {directory}"
  invocation: cd
  from_shell: true
}

And it all seems to work. Thanks!

Canop commented 1 year ago

Now the question is how to make this verb discoverable by zsh users...

{
  external: "noglob cd {directory}"
  key: alt-enter
  invocation: cd
  from_shell: true
}
AndydeCleyre commented 5 months ago

This problem can now (>1.33.1) also be avoided by using the following verb:

{
  key: alt-enter
  invocation: cd
  cmd: ":write_output {directory};:quit"
}

with the following launcher function (Zsh):

zmodload zsh/mapfile

# -- Run broot, cd into pathfile if successful --
# Depends: zmapfile
br () {  # [<broot-opt>...]
  emulate -L zsh

  local pathfile=$(mktemp)
  trap "rm ${(q-)pathfile}" EXIT INT QUIT
  if { broot --verb-output "$pathfile" $@ } {
    if [[ -r $pathfile ]] {
      local folder=${mapfile[$pathfile]}
      if [[ $folder ]]  cd $folder
    }
  } else {
    return
  }
}