zellij
zellij copied to clipboard
feature request: execute template tabs sequentially, rather than in parallel
I have a multi-step workflow that I want to monitor with zellij. If I could tell zellij to execute my tabs in order, rather than in parallel, I can do some interesting things, like effectively run my CI pipeline as a zellij workflow, where can I watch the steps, see the fanout as multiple panels, and so on.
Particularly, I'd like to combine this with "keep-open" or "hold" functionality so that I could go back and review the finished output from earlier steps.
I could probably coordinate this myself with sentinel files or a named pipe or something like that, but it'd be nice to have it in zellij, possibly. Alternatively, I'd understand if this were considered out of scope.
Is there a specific example? For example, when creating a tab through a layout
, does it mean that the creating of each tab is sequentially synchronized(ensure the creation of the previous tab)?
Yes. An example, I use Nix to build NixOS systems for all of my machines. I have a workflow that is:
- Update all nix inputs, commit.
- Update all our custom package inputs, with commits for each package.
- Run zellij with a layout that shows 4 panes in a grid: x86 builder, x86 htop, aarch64 builder, aarch64 top
What I'd like is:
- Tab opens - runs
./update-all-nix-inputs-script
- This script completes successfully, and the pane is held open by virtue of (some resolution to) #707
- Since the script finished successfully, the next tab is spawned, and then
./update-custom-package-inputs.sh
runs - Again, it finishes successfully
- Spawn a new tab with the grid layout (which I already am doing)
Right now, I just run the two update steps, then spawn the layout, but the layout replaces the existing terminal view, so the history of the first two steps is sort of lost.
If I took this even further, it would almost be like GitHub's CI view, where they internally emit identifiers that allow them to chunk log output and show log-output per-step even within the context of a single bash script -- while I think that's overkill, it would still be nice to leverage zellij's facilities to manage buffers of smaller script executions. I could even imagine a "sidebar" plugin that is able to show these tasks as a sort of tree and allow the user to switch between those buffers for introspection.
To answer your question further, it could even just spawn all of the tabs at once and have a message "waiting for execution for tab XYZ to continue" or some-such, if there's concern about tabs surriously appearing in an existing session mixed with other tabs. Or a common name prefix too?
Thank you for the detailed example!. It was really easy to understand 👍 After reading your explanation, I thought this would be quite useful.
For example, it would be good if there were the following options.
$ zellij --layout-path example.yaml --execute sequential # or parallel
But this is my simple concept idea.
I think this function will take quite a lot of effort. So, it's necessary to listen to other people's opinions.
I think the UX I was imagining was a new yaml config bit under each tab that has:
---
tabs:
- id: step_1
name: step 1
...
- id: step_2
name: step 2
depends_on_success: step_1
or something like this.
Hey - I really like this idea!
I'd be very happy to see this functionality in Zellij. UX-wise I don't see an issue with it. Implementation-wise, this will be a little challenging. Namely: a lot of our internal logic assumes constructing a layout is something that happens on startup.
That being said, I'd be very happy to mentor anyone through this issue if they're up for a wild ride.
The tabs currently are executed sequentially, but they fork so they don't block each other. The way it works: All the processes are started sequentially and then the panes and tabs are constructed and the processes filled in.
Your idea to add dependencies to the tabs is fantastic I think.
You can already do some small steps of your workflow, but they are not as ergonomic as we would like them to ideally be.
Tab opens - runs ./update-all-nix-inputs-script This script completes successfully, and the pane is held open by virtue of (some resolution to) https://github.com/zellij-org/zellij/issues/707
You can keep the pane open with your script, if you don't return from the script:
nix flake update
read -p "Press any key to exit."
You can also run commands that return and keep a pane open, but that is shell dependent:
- pane_name: update inputs
run:
command: {cmd: fish, args: ["-C nix flake update"]}
Also, you can bind opening panes and tabs in the configuration (currently not in the layouts yet - that change was sadly reverted due to an issue - but that should be fixed in #1036)
So for example that would be a viable configuration:
- action: [
NewTab: {
direction: Vertical,
run: {command: {cmd: "htop"}},
}
]
key: [ Char: '3',]
Sadly the yaml
makes nesting here rather tedious, but you can bind your
Run zellij with a layout that shows 4 panes in a grid: x86 builder, x86 htop, aarch64 builder, aarch64 top
to a single keybind. Or any of those steps really.
I think the actual implementation of the dependency will be rather involved, but there is one issue that would already make this quite achieveable in a fairly straight forward manner:
#413 , If we can invoke actions from the command line, we can invoke them from actions, or scripts. That way a tab could be spawned on the success of a previous tab/command/linter/etc ... .
The tabs currently are executed sequentially, but they fork so they don't block each other. The way it works: All the processes are started sequentially and then the panes and tabs are constructed and the processes filled in. ncies to the tabs is fantastic I think.
I am curious, although they are started sequentially, are the process in each pane are running in parallel?
For what it's worth, now that we overhauled our plugin system this is very much possible through plugins. I even wrote a plugin that does this (could definitely be improved upon though): https://github.com/imsnif/multitask