dj95 / zjstatus

A configurable statusbar plugin for zellij
MIT License
358 stars 6 forks source link

OS Widget #52

Closed noirbizarre closed 1 month ago

noirbizarre commented 2 months ago

Is your feature request related to a problem? Please describe. No

Describe the solution you'd like

I'd like to have an OS Widget like I have in starship:

I'd like to have the same configuration (and be able to use NerdFont icons I chose instead of text)

Additional context I might be able to craft and submit the change but I'm not a strong rust developper.

Starship implementation relies on os_info crate, would it be OK to add it as a dependency ?

By the way, Starship might be a good source of idea for possible widgets to add.

dj95 commented 2 months ago

Hi and thanks for your suggestion! I like the idea of the widget and really appreciate that you linked the sources.

Taking a look into the os_info crate reveals, that the OS is detected by either running commands or reading the content of some files. Unfortunately this cannot be implemented in this way, since zjstatus runs in a WASM sandbox. As a result, zjstatus has no access to the complete filesystem and commands can only be invoked by calling the through the zellij rpc.

Maybe we can get around that by re-implementing some of the logic from the os_info crate in zjstatus, that just utilises running some commands. But this method would have a huge disadvantage in terms of performance.


Edit maybe we can invoke starship in a way, that it only outputs certain modules? This would not only enable us to use the OS info, but like you mentioned every possible combination.

noirbizarre commented 2 months ago

That's actually a really good idea because, even if it's not the official documentation, there is a starship module command doing just that 👌🏼

$ starship module --help
Prints a specific prompt module

Usage: starship module [OPTIONS] [NAME]

Arguments:
  [NAME]  The name of the module to be printed

Options:
  -l, --list
          List out all supported modules
  -s, --status <STATUS_CODE>
          The status code of the previously run command as an unsigned or signed 32bit integer
      --pipestatus <PIPESTATUS>
          Bash, Fish and Zsh support returning codes for each process in a pipeline
  -w, --terminal-width <TERMINAL_WIDTH>
          The width of the current interactive terminal [default: 320]
  -p, --path <PATH>
          The path that the prompt should render for
  -P, --logical-path <LOGICAL_PATH>
          The logical path that the prompt should render for. This path should be a virtual/logical representation of the PATH argument
  -d, --cmd-duration <CMD_DURATION>
          The execution duration of the last command, in milliseconds
  -k, --keymap <KEYMAP>
          The keymap of fish/zsh/cmd [default: viins]
  -j, --jobs <JOBS>
          The number of currently running jobs [default: 0]
  -h, --help
          Print help

So instead I might be submitting an example on how to use starship module as a provider using the command widget

noirbizarre commented 2 months ago

For anyone wanting to use any starship module from zjstatus, this is quite easy:

Here's an example rendering the os module:

// Call any module, here the OS module
command_os_command  "starship module os"
// Wrap with your own style
command_os_format "#[fg=#003543, bg=white]{stdout}"
// Strip any ASNI escape sequence (aka. all starship formatting)
command_os_rendermode "raw"

Note that it will be executed with your default config.

The command widget might benefit from:

dj95 commented 2 months ago

That's awesome! Would you mind adding this to the examples section?

To your suggestions for the command widget:

Setting environment variables will be tough, since the config is just using single key values, so there's no nesting. Currently I'm not sure how to add it properly. There are also some questions, how to handle the environment in general, if you set environment variables. As a quick mitigation, you could use a bash script and set the environment variables in a controlled way before running the starship command. I think this is a more streamlined approach, since zellij won't call the commands from the command widgets within a shell, but directly. Maybe I could also extend the documentation of the command widget to make it more clear, how it works.

Setting the interval to 0 for running the command one time is a neat idea! I'll pick this up in one of the next releases. However, I'd not like to set it as a default value, since this would impose a breaking change. With the current implementation it default to 1, which users could rely on.

Setting the cwd would not really work (or at least very limited, which could cause confusion). As mentioned before, zellij starts plugins within a WASM sandbox. Plugins have /data, /host and /tmp in their directory tree. /data is a store between multiple plugins instances. /tmp a directory for temporary files. /host gives the plugin access to the directory, where zellij was started (or the plugin was launched). Therefore you could only set relative paths within the current working directory, which would be kinda complicated and not really transparent how it works. Also the benefit would be quite minimal, since you can only access directories within the cwd.

E.g.

.github/
src/

With /host/src you would navigate into the src/ directory. But ~/.config/starship won't work because zjstatus is started within the sandbox.

dj95 commented 1 month ago

With the latest commit, I found a way to configure the cwd and env. Here's an example:

command_git_branch_command   "bash -c \"echo $FOO\""
command_git_branch_cwd       "/Users/daniel"
command_git_branch_env       {
    FOO "1"
    BAR "foo"
}
command_git_branch_format    "#[fg=red] {stdout} "
command_git_branch_interval  "2"
dj95 commented 1 month ago

All three suggestions are now implemented with the latest commit.

dj95 commented 1 month ago

As the os widget is possible with starship and the command widget now features all three suggestions, that makes starships usage easier, I'll close the issue.

Feel free to comment if I missed something.