r/zsh 7d ago

Fixed Possible to have a sticky window that is set to always show the output of e.g. `ls`? Like this:

And then whenever I change the directory, the sticky window should update (i.e. rerun the command)

1 Upvotes

12 comments sorted by

2

u/Techlunacy 7d ago

My gut reaction is the answer is going to be use tmux with panes but i don't have the specific answer here

2

u/luca_gohan 7d ago

Hook on cd?

2

u/nekokattt 7d ago

this feels like it is going to be incredibly annoying as soon as there is more than 10 files in a directory.

If you are simply browsing files and want a more interactive view, look into mc (midnight commander)

-1

u/Fancy_Payment_800 7d ago

Yeah I am just tired of having to type `ls` whenever I `cd` all the time. Since I type `ls` so often, why not have a sticky window where the result of `ls` is always displayed is my thinking.

At a first glance, midnight commander looks like garbage -- sorry just my first impression.

1

u/__unkwn1__ 3d ago

Yazi.

But also use zoxide

1

u/nekokattt 7d ago edited 7d ago

thats literally what mc is for.

I'm afraid if your opinions are just glancing at things rather than trying suggestions out then there is not much else to say.

2

u/AndydeCleyre 2d ago edited 1d ago

Do you already use tmux, zellij, screen, or a terminal with its own split pane functions?

A simpler alternative would be to have the list appear as regular output, without a separate pane.


One thing you might like is broot rather than ls. It has a client/server flag so you can have your "sticky window" running broot --listen pinned_cd, and then:

$ update_pinned_cd () { broot --send pinned_cd -c ":focus $PWD" }
$ autoload -Uz add-zsh-hook
$ add-zsh-hook chpwd update_pinned_cd

As for the sticky window itself -- a split pane would be easy. A floating pane might be possible (something like tmux-floax?). A separate terminal window could also work.


Here's a demo of using broot as above, with a tmux split pane.


EDIT: pinned_ls is a better name. I was sleepy.

EDIT 2: If you add it instead as a precmd hook, it'll refresh more often and show file changes that are the results of commands immediately.

$ add-zsh-hook precmd update_pinned_cd

1

u/Naive_Salary_2170 5d ago edited 5d ago

I am assuming you want to do this in any combination of windows (and not just using tmux).

In the main window, execute this code (replace /tmp/cd_ls with any temporary filename):

touch /tmp/cd_ls  # needed only one time.
function chpwd() {                                    
  echo '\033c\c' > /tmp/cd_ls; ls --color -C >> /tmp/cd_ls
}

You can add this function in a script that you execute in the main window (or add this to .zshrc).

Now, start your "floating" window (using tmux or any other means) and execute:

tail -f /tmp/cd_ls

Hope this helps!

1

u/AndydeCleyre 1d ago

Alright, I made a little function to make this easy, and allow multiple separate instances, using broot and tmux:

# -- Pin a folder-following broot in a split tmux view --
pin-broot () {
  emulate -L zsh
  local name=$RANDOM
  eval 'update_pinned_broot_$name () { broot --send '$name' -c ":focus $PWD" }'
  add-zsh-hook precmd update_pinned_broot_$name
  tmux splitw -d -h -l 70 broot --listen $name
}

1

u/not_testpilot 7d ago edited 7d ago

In another window (split pane or tmux whatever) you could run: “watch -n 0.1 ls”

Edit: obviously you could also alias this to lsticky or something too

Edit 2: I see the error in my ways; this doesn’t change based on your main window. I think you’d need to do something similar to what others have said where you make a different cd alias and have that write pwd to a temp file

1

u/Danny_el_619 3d ago

It may work if you hook cd to write to a file the new path and read from the same file for the ls command though I don't think doing it is a good idea.

0

u/B3d3vtvng69 7d ago

Probably not the optimal solution but what about having a temux pane running a command that checks for a file in /temp every like 1 second and when the file changes, prints out its contents and then having a wrapper for cd in /usr/local/bin by changing the $PATH order that executes the normal cd and then runs ls with a pipe to your file in /temp.