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

Idea for the future: Support only cable channels and stdin #253

Open
xosxos opened this issue Jan 8, 2025 · 7 comments
Open

Idea for the future: Support only cable channels and stdin #253

xosxos opened this issue Jan 8, 2025 · 7 comments
Labels
enhancement New feature or request

Comments

@xosxos
Copy link
Contributor

xosxos commented Jan 8, 2025

Hey,

I am proposing a major change so this is a long one....

I have been absolutely awestruck how good the idea of custom channels, with a custom preview and custom run options is. I feel TUI applications are often cumbersome to use and not good for customization. So, shell functions combined with pipes and aliases and all the unix stuff is the daily driver for me.

However, the way this apllication is designed actually invites all the unix love into a TUI. I can create countless applications for countless use cases (git, docker, ps) in the same general framework of television. And I think that's the kicker here. I believe television should take a more frameworky approach.

What I am suggesting is to ditch the hard coded channels and concentrate on the cable channels via a config. This would greatly reduce code complexity and code duplication both in the channels and previews section. I think it would also eliminate the need for the procedural macros written to hide this complexity in TelevisionChannel. This would be beneficial because generative code is much harder to reason about in relation to normal code.

The thought came up when I was creating a shitty implementation of #16 and I realized I have to either support all the hard-coded variants currently present and FUTURE ones as well. Which would mean more code complexity. That's when I tried implementing the hard-coded channels via the config file and I could do a 1-to-1 replication of many of them (but not all, and colors don't work!).

[[cable_channel]]
name = "my_repos"
source_command = 'fd git ~/ --type d --no-ignore --hidden | rg "\.git/"'
preview_delimiter = ":"
preview_command = "cd {} && git log -n 200 --pretty=medium --all --graph --color"

[[cable_channel]]
name = "my_envs"
source_command = "printenv | sort | sed \"s/=/: /g\""
preview_delimiter = ":"
preview_command = "echo {1}"

[[cable_channel]]
name = "my_alias"
source_command = "fish -c alias"
preview_delimiter = ":"
preview_command = "echo {0}"

So, I think it would be good to have a single very customizable Previewer, which would support cable_channels and stdin with full feature parity. Meaning, all options in the config would be available as parameters for the clap app. This would solve #190 as well, because instead of implementing it on the application side (by adding more code), it can, and I think should be, implemented OUTSIDE the application:

[[cable_channel]]
name = "my_hidden_files"

# DONT SHOW HIDDEN FILES (here using fd-find, but can be done with GNU find)
# source_command = "fd . --type f"

# SHOW HIDDEN FILES
source_command = "fd . --type f --hidden"

preview_delimiter = ":"
preview_command = "bat {0}"

What I am envisioning is for example creating a program manager under the television framework:

[[cable_channel]]
name = "manager"
source = "ps -ax -o pid,command | sed 's/^ * //g' | sed -r 's/ +/;/'"
delimiter = ";"
preview = "echo {0}"
run = [
  "kill {1}",
  "kill -9 {1}",
  "tail -f /proc/{1}/fd/1"
]
deduplicate = false

However,

  1. I don't know what this means for windows support, as it might not have such standard software available as unix does.
  2. I don't know what this approach would mean for transitions and how they could be defined via the config.
  3. Hunders of potential other problems unforeseen here

That's my two cents, and it might not align with the future planned for this project, but thanks for writing an inspiring application!
Any general thoughts on this @alexpasmantier ?

@xosxos xosxos added the enhancement New feature or request label Jan 8, 2025
@alexpasmantier
Copy link
Owner

@xosxos I agree with most of your points, and am pretty much on board with the overall idea but need to put a bit of thinking into it before I come up with a more detailed response.

Thanks for sharing this 🙏🏻

@alexpasmantier
Copy link
Owner

alexpasmantier commented Jan 9, 2025

The way I see this:

  • I agree the overall vision is a desirable goal
  • I think the builtin previewers are important to keep (as they provide robust defaults such as the builtin :files: syntax highlighting one)
  • I feel like a more generic approach to transitions could solve the cable channel transitions problem (i.e. systematically allowing to send to any channel the currently shortlisted entries and allowing to customize what gets passed via the config in a way similar to how the preview command picks and choses bits from entries using that format syntax). That would allow people to optionally define custom transitions in their config between cable channels using something like:
[[cable_channel]]
name = "channel_A"
# ...

[[cable_channel]]
name = "channel_B"
# ...
transitions_into = {
    channel_A = {
        format_entry = "{0}",
        delimiter = "\t"
    }
}
  • since 0.9.1 people can now override builtin channels with a cable channel which I believe is a first step in the right direction (it allows to eventually smoothly transition to a cable-only world)

If we're heading that way, I feel like the best route to get there would be to work our way towards feature parity between builtin and cable channels before anything else (and work on "commands to run on selection" on the way there).
That would include, among other things:

  • transitions for cable channels (see above)
  • parsing ansi formatting in entries and applying that formatting to the results list
  • bulking up the default cable channels list to still provide a nice batteries-included default user experience

@xosxos
Copy link
Contributor Author

xosxos commented Jan 10, 2025

Glad to hear you think this could be a way forward!

For now I forked, refactored things and turned this into a mono repo (not saying its desirable). Compilation dependencies went down to ~260. I don´t think I removed any major dependency either so it´s probably an issue with the workspace not resolving dependencies optimally. I will continue to see how lean this can get while maintaining feature parity.

I also implemented in application logging but I´ll get back to you when I have solid code. I plan on working on bits and pieces until I have what I want, and then, if some refactors and implementations make sense for television, pieces can be merged in. After I have a full understanding of the code I can do patches for the main as well.

  • I think the builtin previewers are important to keep (as they provide robust defaults such as the builtin :files: syntax highlighting one)

I agree on the previewers. I think the implementation however could be a single struct. Then in the config, the :files: syntax would just initiate the previewer with the appropriate settings.

  • I feel like a more generic approach to transitions could solve the cable channel transitions problem.

The config draft makes sense. I don't quite understand the transitions as I haven´t used them. It´s something my brain might not be able to handle while working. I.e. take these files, then search for this string. I would just construct a pipe for this. But I feel there is potential I cannot quite grasp yet. Especially if a single channel with a preview and run commands is considered a single "application", then the transitions could be considered as dynamic piping. If you would add transition commands separately (in relation to run commands), it would be like dynamic piping on steroids I suppose.

  • transitions for cable channels (see above)
  • parsing ansi formatting in entries and applying that formatting to the results list
  • bulking up the default cable channels list to still provide a nice batteries-included default user experience

Fully agree on all points. And the default channels would probably have to be running GNU applications which kinda sucks in the year 2025, but what can you do.

All in all, I guess the features that would make me happy are:

  1. Run commands
  2. Cable transitions
  3. Cable channel can be constructed identically from both stdin and config file
  4. Feature parity between the built-in channels and the config based replacements
  5. Bonus: Transition commands
  6. Bonus: Simple in application logging for dev builds

And on the code side:

  1. A single channel (not sure if stdin requires its own), i.e. cable-only refactor.
  2. A single very configurable Previewer struct with quality presets to be used in the config
  3. Refactoring out the procedural macros (we'll see how this works out, as the remote also uses them). For now, I just switched to enum_dispatch crate to forward the OnAir trait in the same way as it´s done now.

@freeo
Copy link

freeo commented Jan 20, 2025

First of all, the idea is great but the rust performance and possibilities are currently way better. I stumbled upon this myself while writing a custom_channel.

But I have an idea how we could close this gap.

I use fd -H . /home/$USER to list my files. About 4 million without further filtering. Ofc. this is too much and shouldn't be a desirable goal, but it still made me think:

tv can only start reading when the source_command is done. But what if tv had support for async streaming?

If would be great if source_command would have a generic sink, which applications can stream into and tv would read them just in time. Currently my custom fd command takes ~3 seconds, which is bearable, but not as snappy as the native tv files which doesn't have support for hidden files yet (and probably never will considering this ticket here). This could be implemented using named pipes or sockets or some rust library for cross-platform support.

Either way, first class support would increase the overall snappiness for bigger inputs and would almost be a requirement to keep the blazingly fast label.

Watcha y'all think?

@alexpasmantier
Copy link
Owner

alexpasmantier commented Jan 20, 2025

tv can only start reading when the source_command is done. But what if tv had support for async streaming?

This is already the case, or did I just misunderstand your point?

[[cable_channel]]
name = "long-running"
source_command = 'for i in {1..1000}; do echo "This is line number $i"; sleep .5; done'
preview_command = "echo {}"
async_tv.mp4

@xosxos
Copy link
Contributor Author

xosxos commented Jan 21, 2025

Hey, I went through the code in fork. I managed to conserve most of the functionality and got the dependencies down to 172 (starting from over 400?) by merging into a single crate structure and clearing out some dependencies.

I played around refactoring to a more model-view-controller file structure, removed the builtin channels and refactored the keybindings and layout to end up with around 7,3 kLOC, starting from around 11k I think.

I implemented an option to include several commands for three categories: transitions, run commands and preview commands. For example, ctrl-p would trigger keybindings for Preview allowing one to toggle between different commands for different views.

For run commands, the command could either be set to exit the application, or to not exit. For example, in tv dirs I might want to tar -cvf a_file and not exit, but I might also want to cd to some dir and exit. I also added a refresh option to then refresh the entries, because if the command creates a new file, it would be nice to immediately see it in the files feed.

I created a simple file browser using channels which can transition between dirs and files and is able to zip files etc. Next, I'll try to create something like gitui using this framework.

I also added a rudimentary logger view to ease with the debugging.

It's not all 100% functional nor beautiful yet, but maybe you could check the fork out to maybe in the future incorporate some of the changes into television to tighten up the core code, scale down dependencies and merge in some of the added features (if it suits the future of this project)?

@alexpasmantier
Copy link
Owner

I actually stumbled upon your fork yesterday and took a look at it. Plenty of interesting things and looking forward to integrate some of them.

Will take a deeper look in the days to come.

Great work!

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

No branches or pull requests

4 participants
@freeo @xosxos @alexpasmantier and others