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

Enable live update of flavor through Lua plugin API #988

Open
1 task
mbromell opened this issue May 1, 2024 · 6 comments
Open
1 task

Enable live update of flavor through Lua plugin API #988

mbromell opened this issue May 1, 2024 · 6 comments
Labels
feature New feature request

Comments

@mbromell
Copy link

mbromell commented May 1, 2024

Please describe the problem you're trying to solve

Currently it appears that I can not make a plugin for Yazi that would allow me to automatically change the flavor that Yazi is using. The only way to change a Yazi flavor is to update the config, then close and re-open Yazi. I would like to make a plugin in the future (or contribute a built-in feature) that can automatically switch between light and dark themes based on the system theme.

Automatically switching between light and dark themes is important for me as I try to view light mode during day time and dark mode at night. There is many eye-care and sleep benefits for this but GitHub this issue isn't the place to expand that 😃

Would you be willing to contribute this feature?

  • Yes, I'll give it a shot

Describe the solution you'd like

A Lua function that could set the flavor of Yazi and update its appearance without needing to close and re-open Yazi (live update).

The name of the function, and the name of top level Lua module (config or theme) is something that I have no strong opinion over. But it would be good to have the field names follow the general configuration file spec: Within our "config", there is a "theme.toml" file where you can set the flavor.use entry, so my suggestion would follow this terminology.

If it has not been explored yet then I would suggest something possibly generic to the config, rather than specific to flavors:

config.apply({ theme.flavor.use = 'theme-name' })

Or if you would rather something specific for updating the theme config -- then maybe we could have something like:

theme.apply({ flavor.use = 'theme-name' })

These approaches seem to be expandable to applying other config values, so this solution wouldn't be specific just to updating flavors only.

Additional context

I understand that this may be something already planned as the config section of the plugin docs is under "TODO" https://yazi-rs.github.io/docs/plugins/config. So there may be a broader discussion needed before deciding on implementing my suggested approach, as you may want to approach applying config changes to Yazi in a different way that my proposed solution wouldn't be compatible with.

@mbromell mbromell added the feature New feature request label May 1, 2024
@sxyazi
Copy link
Owner

sxyazi commented May 3, 2024

I like the idea, but I think it should be a built-in feature provided to users rather than a plugin API.

When Yazi starts up, it should send a CSI sequence request to the terminal for its colors, and based on the response color values, calculate whether the user's terminal is light or dark, and apply the corresponding flavor. Maybe we could have:

[flavor]

light = "atom-one-light"
dark  = "atom-one-dark"

@mbromell
Copy link
Author

mbromell commented May 3, 2024

I like the idea, but I think it should be a built-in feature provided to users rather than a plugin API.

Well if you are willing to add to the current flavor config spec then I like that idea more.

When Yazi starts up, it should send a CSI sequence request to the terminal for its colors, and based on the response color values, calculate whether the user's terminal is light or dark, and apply the corresponding flavor

My end goal would is swap the colors automatically while Yazi is running. If I swap the terminal colors, could Yazi listen for that event and automatically update its colors to the corresponding light or dark theme?

@sxyazi
Copy link
Owner

sxyazi commented May 3, 2024

If I swap the terminal colors, could Yazi listen for that event and automatically update its colors to the corresponding light or dark theme?

The crossterm crate (which Yazi uses) doesn't support terminal color response events, so it's not possible to detect it at runtime and I can only manually implement it before crossterm initializes during program startup.

I don't think crossterm will support it in the short term; it's currently in a state of lacking maintenance. My PR for detecting terminal size has been pending for a long time without being merged, so I've given up on directly adding it to crossterm...

@mbromell
Copy link
Author

mbromell commented May 5, 2024

The crossterm crate (which Yazi uses) doesn't support terminal color response events

I understand, that's unfortunate. Is this just the listening for a color change event? Or does crossterm not have the ability to manually update the colors of the interface while the app is running?

If it's just the event: then what I'm imagining is that we could create our own event listener that executes a simple shell command every second to check the system theme (there are various ways to do this in each OS) -- if it changes from the last call then update the colors of Yazi.

So our own make-shift event listener, then call crossterm to change the colors, would this be something that's possible?

@sxyazi
Copy link
Owner

sxyazi commented May 5, 2024

I understand, that's unfortunate. Is this just the listening for a color change event? Or does crossterm not have the ability to manually update the colors of the interface while the app is running?

crossterm does not support parsing OSI 11 responses into its internal events and does not provide the ability to extend it externally. OSI 11 is a sequence for querying terminal colors, and most terminals support it, see https://github.com/Canop/terminal-light/tree/main?tab=readme-ov-file#dynamic-colors-osc-escape-sequence-strategy for details.

then what I'm imagining is that we could create our own event listener that executes a simple shell command every second to check the system theme (there are various ways to do this in each OS)

I don't think it makes sense for the following reasons:

  • Yazi is a CLI program, not a GUI, so it should always respect the terminal environment rather than the operating system/desktop environment.
  • This would require assuming that the user's terminal supports and has enabled "follow system colors," which would make this feature unavailable to users who set colors individually for their terminals, and some older operating systems/desktop environments do not support dark mode.
  • This introduces new cross-platform issues, requiring Yazi to be adapted for at least Windows, macOS, and Linux, with Linux having multiple desktop environments, and I'm not sure if there's a simple and reliable way to implement it.
  • If it's implemented through calling other CLI commands, they would need to be added as dependencies for Yazi, further expanding the dependency list, and different systems/desktop environments require different dependencies, introducing unnecessary hassle for users.

@mbromell
Copy link
Author

mbromell commented May 5, 2024

I don't think it makes sense for the following reasons:

Yes I have noticed that all TUI's I use don't have a feature to swap themes based on the OS theme. Although some can be extended through plugins which was my original motivation, to enable the ability for such functionality to be implemented as a plugin so that Yazi can keep its hands clean of this messy stuff. I currently have Wezterm, Neovim, and Tmux responding to system theme changes, this is done through plugins or scripting 'hacks'.

So lets ditch the idea that Yazi should natively support syncing a light/dark theme with the OS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature request
Projects
None yet
Development

No branches or pull requests

2 participants