chore: flatten workspace into a single crate (#306)

This commit is contained in:
Alex Pasmantier 2025-01-25 00:44:34 +01:00 committed by GitHub
parent 37b71b7a88
commit 3970f65946
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
99 changed files with 545 additions and 805 deletions

View File

@ -227,7 +227,8 @@ All notable changes to this project will be documented in this file.
### 🐛 Bug Fixes ### 🐛 Bug Fixes
- *(channels)* Use the number of actual bytes read and not the sample buffer size when calculating the proportion of printable ASCII characters (#174) - *(channels)* Use the number of actual bytes read and not the sample buffer size when calculating the proportion of
printable ASCII characters (#174)
- *(ux)* Make DeletePrevWord trigger channel update (#175) - *(ux)* Make DeletePrevWord trigger channel update (#175)
### 📚 Documentation ### 📚 Documentation

View File

@ -3,11 +3,14 @@
First of all, thanks for considering contributing to this project. All contributions are welcome, whether they are bug First of all, thanks for considering contributing to this project. All contributions are welcome, whether they are bug
reports, documentation improvements, feature requests, or pull requests. reports, documentation improvements, feature requests, or pull requests.
Please make sure to read and follow our [Code of Conduct](CODE_OF_CONDUCT.md) to ensure a positive experience for everyone involved. Please make sure to read and follow our [Code of Conduct](CODE_OF_CONDUCT.md) to ensure a positive experience for
everyone involved.
If you're not sure where to start, take a look at the [Hot Topics](#hot-topics) section for some ideas on what you could work on. If you're not sure where to start, take a look at the [Hot Topics](#hot-topics) section for some ideas on what you could
work on.
## Table of Contents ## Table of Contents
- [Getting started](#getting-started) - [Getting started](#getting-started)
- [Prerequisites](#prerequisites) - [Prerequisites](#prerequisites)
- [Forking the repository and setting up the project](#forking-the-repository-and-setting-up-the-project) - [Forking the repository and setting up the project](#forking-the-repository-and-setting-up-the-project)
@ -17,12 +20,17 @@ If you're not sure where to start, take a look at the [Hot Topics](#hot-topics)
- [Hot Topics](#hot-topics) - [Hot Topics](#hot-topics)
## Getting started ## Getting started
### Prerequisites ### Prerequisites
These are pretty much the only things you need to have installed on your machine to get started with contributing to this project:
These are pretty much the only things you need to have installed on your machine to get started with contributing to
this project:
- the [Rust](https://www.rust-lang.org/tools/install) toolchain installed on your machine - the [Rust](https://www.rust-lang.org/tools/install) toolchain installed on your machine
- any working version of [Git](https://git-scm.com/downloads) - any working version of [Git](https://git-scm.com/downloads)
### Forking the repository and setting up the project ### Forking the repository and setting up the project
1. Click on the `Fork` button at the top right corner of the repository page to create a copy of the repository to your 1. Click on the `Fork` button at the top right corner of the repository page to create a copy of the repository to your
GitHub account. GitHub account.
2. Clone the forked repository to your local machine by running the following command in your terminal: 2. Clone the forked repository to your local machine by running the following command in your terminal:
@ -51,15 +59,19 @@ These are pretty much the only things you need to have installed on your machine
```shell ```shell
git push origin <branch-name> git push origin <branch-name>
``` ```
8. If not done automatically, create a pull request by navigating to the original repository and clicking on the `New pull request` button. 8. If not done automatically, create a pull request by navigating to the original repository and clicking on the
`New pull request` button.
### Building the project ### Building the project
Before anything else: Before anything else:
```shell ```shell
make setup make setup
``` ```
To run the application in debug mode while developing, with the ability to see logs and debug information: To run the application in debug mode while developing, with the ability to see logs and debug information:
```shell ```shell
make run make run
``` ```
@ -75,58 +87,72 @@ configuration:
| Windows | `{FOLDERID_LocalAppData}\television\television.log` | | Windows | `{FOLDERID_LocalAppData}\television\television.log` |
To build the project in debug mode, run the following command in the project directory: To build the project in debug mode, run the following command in the project directory:
```shell ```shell
make make
``` ```
or or
```shell ```shell
make build make build
``` ```
To build the project in release mode, run the following command in the project directory: To build the project in release mode, run the following command in the project directory:
```shell ```shell
make release make release
``` ```
Formatting the code Formatting the code
```shell ```shell
make format make format
``` ```
Linting the code Linting the code
```shell ```shell
make lint make lint
``` ```
Running the tests Running the tests
```shell ```shell
make test make test
``` ```
### Project structure ### Project structure
The project is laid out in several rust crates that are organized in the following way:
- `television`: the main binary crate that contains the CLI application
- `television_channels`: a library crate that contains the channel implementations
- `television_derive`: a library crate that contains the derive macros used in the project
- `television_fuzzy`: a library crate that contains the fuzzy matcher
- `television_previewers`: a library crate that contains the previewer implementations
- `television_utils`: a library crate that contains utility functions and types used in the project
The project is laid out in several rust crates that are organized in the following way:
- `television`: the main binary crate that contains the CLI application
- `television_derive`: a library crate that contains the derive macros used in the project
### Contributing a new channel ### Contributing a new channel
`television` is built around the concept of _channels_. `television` is built around the concept of _channels_.
From a technical standpoint, channels are structs that implement the `OnAir` trait defined in `crates/television-channels/src/channels.rs`. From a technical standpoint, channels are structs that implement the `OnAir` trait defined in
`television/channels/mod.rs`.
They can be anything that can respond to a user query and return a result under the form of a list of entries. This means channels can be anything from conventional data sources you might want to search through (like files, git repositories, remote filesystems, environment variables etc.) to more exotic implementations that might include a REPL, a calculator, a web browser, search through your spotify library, your email, etc. They can be anything that can respond to a user query and return a result under the form of a list of entries. This
means channels can be anything from conventional data sources you might want to search through (like files, git
repositories, remote filesystems, environment variables etc.) to more exotic implementations that might include a REPL,
a calculator, a web browser, search through your spotify library, your email, etc.
As mentioned in [Project structure](#project-structure) `television` uses [crates](https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html) for its different subcomponents (_previewers_, _channels_, _utils_, etc). As mentioned in [Project structure](#project-structure) `television`
uses [crates](https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html) for its different subcomponents (
_previewers_, _channels_, _utils_, etc).
When contributing a new channel, you should create a new module in the `television_channels` crate with a new struct for When contributing a new channel, you should create a new module in the `crate::channels` crate with a new struct for
your channel and ensure that it implements the `OnAir` trait defined in [crates/television-channels/src/channels.rs](crates/television-channels/src/channels.rs) your channel and ensure that it implements the `OnAir` trait defined
in [crates/television-channels/src/channels.rs](crates/television-channels/src/channels.rs)
```rust ```rust
// crates/television-channels/src/channels/my_new_channel.rs // crates/television-channels/src/channels/my_new_channel.rs
use television_channels::channels::OnAir; use crate::channels::OnAir;
pub struct MyNewChannel; pub struct MyNewChannel;
@ -135,12 +161,10 @@ impl OnAir for MyNewChannel {
} }
``` ```
You should also add your channel to the `TelevisionChannel` enum in the `television_channels` crate. You should also add your channel to the `TelevisionChannel` enum in the `crate::channels` crate.
```rust ```rust
// crates/television-channels/src/channels.rs // crates/television-channels/src/mod
#[derive(ToUnitChannel, ToCliChannel, Broadcast)] #[derive(ToUnitChannel, ToCliChannel, Broadcast)]
pub enum TelevisionChannel { pub enum TelevisionChannel {
@ -149,13 +173,15 @@ pub enum TelevisionChannel {
} }
``` ```
☝️ There are built-in channels in `television` that you might want to draw inspiration from if need be, they're located at [crates/television-channels/src/channels](crates/television-channels/src/channels). ☝️ There are built-in channels in `television` that you might want to draw inspiration from if need be, they're located
at [crates/television-channels/src/channels](crates/television-channels/src/channels).
**TODO**: document transitions between channels and previewers **TODO**: document transitions between channels and previewers
## Hot Topics ## Hot Topics
### Current hot topics: ### Current hot topics:
- shell integration (autocomplete, keybindings) - shell integration (autocomplete, keybindings)
- packaging for various linux package managers (apt, dnf, ...) - packaging for various linux package managers (apt, dnf, ...)
- configuring custom actions for each channel - configuring custom actions for each channel
@ -165,38 +191,39 @@ pub enum TelevisionChannel {
See the [todo list](./TODO.md) for ideas. See the [todo list](./TODO.md) for ideas.
- `Customization`: - `Customization`:
- allow users to further customize the behavior of the application (e.g. the default channel, fuzzy matching constants, channel heuristics, etc.) - allow users to further customize the behavior of the application (e.g. the default channel, fuzzy matching
constants, channel heuristics, etc.)
- `Channels`: - `Channels`:
- new channel ideas (builtin or cable): - new channel ideas (builtin or cable):
- shell history - shell history
- directories - directories
- git (commits, branches, status, diff, ...) - git (commits, branches, status, diff, ...)
- remote filesystems (s3, ...) - remote filesystems (s3, ...)
- kubernetes resources (jobs, pods, deployments, services, ...) - kubernetes resources (jobs, pods, deployments, services, ...)
- recent directories - recent directories
- makefile commands - makefile commands
- etc. - etc.
- add more tests for existing channels - add more tests for existing channels
- `Previewers`: - `Previewers`:
- new previewer ideas: - new previewer ideas:
- previewing text in documents (pdfs, archives, ...) - previewing text in documents (pdfs, archives, ...)
- previewing images (actually already implemented but commented out) - previewing images (actually already implemented but commented out)
- remote files (s3, ...) - remote files (s3, ...)
- etc. - etc.
- more tests for existing previewers - more tests for existing previewers
- `Documentation`: - `Documentation`:
- add more technical documentation to the project - add more technical documentation to the project
- general design of the TUI application - general design of the TUI application
- design of channels, previewers, transitions, etc. - design of channels, previewers, transitions, etc.
- how to contribute a new channel, previewer, etc. - how to contribute a new channel, previewer, etc.
- more docstrings - more docstrings
- `Performance/Refactoring`: - `Performance/Refactoring`:
- working on reducing coupling between the different crates in the project - working on reducing coupling between the different crates in the project
- working on reducing the number of allocations and copies in the code - working on reducing the number of allocations and copies in the code
- writing benchmarks for different parts of the application - writing benchmarks for different parts of the application
- `Project`: - `Project`:
- polish project configuration: - polish project configuration:
- CI/CD - CI/CD

122
Cargo.lock generated
View File

@ -426,10 +426,8 @@ version = "4.5.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
dependencies = [ dependencies = [
"anstream",
"anstyle", "anstyle",
"clap_lex", "clap_lex",
"strsim",
] ]
[[package]] [[package]]
@ -2054,12 +2052,6 @@ dependencies = [
"redox_syscall", "redox_syscall",
] ]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.15" version = "0.4.15"
@ -3074,20 +3066,19 @@ dependencies = [
"fnv", "fnv",
"once_cell", "once_cell",
"onig", "onig",
"plist",
"regex-syntax 0.8.5", "regex-syntax 0.8.5",
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"thiserror 1.0.69", "thiserror 1.0.69",
"walkdir", "walkdir",
"yaml-rust",
] ]
[[package]] [[package]]
name = "television" name = "television"
version = "0.9.4" version = "0.9.4"
dependencies = [ dependencies = [
"bat",
"better-panic", "better-panic",
"clap", "clap",
"color-eyre", "color-eyre",
@ -3097,47 +3088,31 @@ dependencies = [
"crossterm", "crossterm",
"devicons", "devicons",
"directories", "directories",
"gag",
"human-panic", "human-panic",
"ignore",
"lazy_static", "lazy_static",
"nom",
"nucleo",
"parking_lot",
"ratatui", "ratatui",
"regex",
"rustc-hash", "rustc-hash",
"serde", "serde",
"signal-hook", "signal-hook",
"simdutf8",
"smallvec",
"strum",
"syntect", "syntect",
"television-channels",
"television-derive", "television-derive",
"television-fuzzy", "thiserror 1.0.69",
"television-previewers",
"television-screen",
"television-utils",
"tokio", "tokio",
"toml", "toml",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"unicode-width 0.2.0", "unicode-width 0.2.0",
"vergen-gix", "vergen-gix",
] "winapi-util",
[[package]]
name = "television-channels"
version = "0.0.23"
dependencies = [
"clap",
"color-eyre",
"devicons",
"directories",
"ignore",
"lazy_static",
"regex",
"rustc-hash",
"serde",
"strum",
"television-derive",
"television-fuzzy",
"television-utils",
"tokio",
"toml",
"tracing",
] ]
[[package]] [[package]]
@ -3149,70 +3124,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "television-fuzzy"
version = "0.0.23"
dependencies = [
"nucleo",
"parking_lot",
]
[[package]]
name = "television-previewers"
version = "0.0.23"
dependencies = [
"color-eyre",
"devicons",
"lazy_static",
"nom",
"parking_lot",
"ratatui",
"regex",
"rustc-hash",
"simdutf8",
"smallvec",
"syntect",
"television-channels",
"television-utils",
"thiserror 1.0.69",
"tokio",
"tracing",
]
[[package]]
name = "television-screen"
version = "0.0.23"
dependencies = [
"color-eyre",
"devicons",
"ratatui",
"rustc-hash",
"serde",
"syntect",
"television-channels",
"television-previewers",
"television-utils",
"tracing",
]
[[package]]
name = "television-utils"
version = "0.0.23"
dependencies = [
"bat",
"color-eyre",
"directories",
"gag",
"ignore",
"lazy_static",
"rustc-hash",
"syntect",
"tokio",
"tracing",
"unicode-width 0.2.0",
"winapi-util",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.15.0" version = "3.15.0"
@ -4068,15 +3979,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]] [[package]]
name = "yaml-rust2" name = "yaml-rust2"
version = "0.8.1" version = "0.8.1"

View File

@ -10,106 +10,78 @@ repository = "https://github.com/alexpasmantier/television"
homepage = "https://github.com/alexpasmantier/television" homepage = "https://github.com/alexpasmantier/television"
keywords = ["search", "fuzzy", "preview", "tui", "terminal"] keywords = ["search", "fuzzy", "preview", "tui", "terminal"]
categories = [ categories = [
"command-line-utilities", "command-line-utilities",
"command-line-interface", "command-line-interface",
"concurrency", "concurrency",
"development-tools", "development-tools",
] ]
include = [ include = [
"LICENSE", "LICENSE",
"README.md", "README.md",
"themes/**/*.toml", "themes/**/*.toml",
"crates/television/**/*.rs", "television/**",
"build.rs", "build.rs",
".config/config.toml", ".config/config.toml",
"cable", "cable",
] ]
rust-version = "1.81" rust-version = "1.81"
[workspace] [lib]
resolver = "2" path = "television/lib.rs"
members = ["crates/television-*"]
[workspace.package]
edition = "2021"
description = "The revolution will be televised."
license = "MIT"
authors = ["Alexandre Pasmantier <alex.pasmant@gmail.com>"]
repository = "https://github.com/alexpasmantier/television"
homepage = "https://github.com/alexpasmantier/television"
keywords = ["search", "fuzzy", "preview", "tui", "terminal"]
categories = [
"command-line-utilities",
"command-line-interface",
"concurrency",
"development-tools",
]
include = [
"LICENSE",
"README.md",
"crates/television/**/*.rs",
"build.rs",
"shell/**/*.sh",
]
rust-version = "1.81"
readme = "README.md"
[workspace.dependencies]
directories = "5.0.1"
devicons = "0.6.11"
color-eyre = "0.6.3"
lazy_static = "1.5.0"
tokio = { version = "1.41.1", features = ["full"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
rustc-hash = "2.1.0"
syntect = { version = "5.2.0" }
unicode-width = "0.2.0"
clap = { version = "4.5.20", features = ["derive", "cargo", "string"] }
serde = { version = "1.0.214", features = ["derive"] }
toml = "0.8.19"
ratatui = { version = "0.29.0", features = ["serde", "macros"] }
[dependencies] [dependencies]
# local dependencies television-derive = { path = "television-derive", version = "0.0.23" }
television-fuzzy = { path = "crates/television-fuzzy", version = "0.0.23" }
television-derive = { path = "crates/television-derive", version = "0.0.23" }
television-screen = { path = "crates/television-screen", version = "0.0.23" }
television-channels = { path = "crates/television-channels", version = "0.0.23" }
television-previewers = { path = "crates/television-previewers", version = "0.0.23" }
television-utils = { path = "crates/television-utils", version = "0.0.23" }
# workspace dependencies directories = "5.0"
directories = { workspace = true } devicons = "0.6"
color-eyre = { workspace = true } color-eyre = { version = "0.6" }
lazy_static = { workspace = true } lazy_static = "1.5"
tokio = { workspace = true, features = ["full"] } tokio = { version = "1.43", features = ["full"] }
tracing = { workspace = true } tracing = "0.1"
tracing-subscriber = { workspace = true, features = ["env-filter", "serde"] } tracing-subscriber = { version = "0.3", features = ["env-filter", "serde"] }
rustc-hash = { workspace = true } rustc-hash = "2.1"
syntect = { workspace = true } syntect = { version = "5.2", default-features = false }
unicode-width = { workspace = true } unicode-width = "0.2"
clap = { workspace = true, features = ["derive", "cargo", "string"] } clap = { version = "4.5", default-features = false, features = [
serde = { workspace = true, features = ["derive"] } "std",
toml = { workspace = true } "derive",
ratatui = { workspace = true, features = ["serde", "macros"] } "cargo",
"string",
] }
serde = { version = "1.0", features = ["derive"] }
ratatui = { version = "0.29", features = ["serde", "macros"] }
better-panic = "0.3"
config = "0.14"
signal-hook = "0.3"
human-panic = "2.0"
copypasta = "0.10"
ignore = "0.4"
strum = { version = "0.26", features = ["derive"] }
regex = "1.11"
parking_lot = "0.12"
nom = "7.1"
thiserror = "1.0"
simdutf8 = { version = "0.1", optional = true }
smallvec = { version = "1.13", features = ["const_generics"] }
bat = { version = "0.24", default-features = false, features = ["regex-onig"] }
gag = "1.0"
nucleo = "0.5"
toml = "0.8"
# external dependencies [target.'cfg(windows)'.dependencies]
better-panic = "0.3.0" winapi-util = "0.1.9"
config = "0.14.0"
crossterm = { version = "0.28.1", features = ["serde"] }
signal-hook = "0.3.17"
human-panic = "2.0.2"
copypasta = "0.10.1"
[dev-dependencies] [dev-dependencies]
criterion = "0.5.1" criterion = "0.5.1"
devicons = { workspace = true }
[features]
simd = ["dep:simdutf8"]
zero-copy = []
default = ["zero-copy", "simd"]
[[bin]] [[bin]]
bench = false bench = false
path = "crates/television/main.rs" path = "television/main.rs"
name = "tv" name = "tv"
[[bench]] [[bench]]
@ -117,11 +89,13 @@ name = "results_list_benchmark"
harness = false harness = false
[build-dependencies] [build-dependencies]
vergen-gix = { version = "1.0.0", features = ["build", "cargo", "rustc"] } vergen-gix = { version = "1.0", features = ["build", "cargo", "rustc"] }
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
crossterm = { version = "0.28.1", features = ["serde", "use-dev-tty"] } crossterm = { version = "0.28.1", features = ["serde", "use-dev-tty"] }
[target.'cfg(not(target_os = "macos"))'.dependencies]
crossterm = { version = "0.28", features = ["serde"] }
[profile.staging] [profile.staging]
inherits = "dev" inherits = "dev"

View File

@ -5,10 +5,10 @@ use ratatui::prelude::{Line, Style};
use ratatui::style::Color; use ratatui::style::Color;
use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding}; use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use television_channels::entry::merge_ranges; use television::channels::entry::merge_ranges;
use television_channels::entry::{Entry, PreviewType}; use television::channels::entry::{Entry, PreviewType};
use television_screen::colors::ResultsColorscheme; use television::screen::colors::ResultsColorscheme;
use television_screen::results::build_results_list; use television::screen::results::build_results_list;
pub fn results_list_benchmark(c: &mut Criterion) { pub fn results_list_benchmark(c: &mut Criterion) {
let mut icon_color_cache = FxHashMap::default(); let mut icon_color_cache = FxHashMap::default();

View File

@ -1,36 +0,0 @@
[package]
name = "television-channels"
version = "0.0.23"
description.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
readme.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
television-fuzzy = { path = "../television-fuzzy", version = "0.0.23" }
television-utils = { path = "../television-utils", version = "0.0.23" }
television-derive = { path = "../television-derive", version = "0.0.23" }
tracing = { workspace = true }
tokio = { workspace = true, features = ["rt"] }
clap = { workspace = true, features = ["derive"] }
devicons = { workspace = true }
directories = { workspace = true }
color-eyre = { workspace = true }
serde = { workspace = true }
lazy_static = { workspace = true }
toml = { workspace = true }
rustc-hash = { workspace = true }
ignore = "0.4.23"
strum = { version = "0.26.3", features = ["derive"] }
regex = "1.11.1"
[lints]
workspace = true

View File

@ -1,38 +0,0 @@
use rustc_hash::FxHashMap;
use std::{
fmt::{self, Display, Formatter},
ops::Deref,
};
#[derive(Clone, Debug, serde::Deserialize, PartialEq)]
pub struct CableChannelPrototype {
pub name: String,
pub source_command: String,
pub preview_command: Option<String>,
#[serde(default = "default_delimiter")]
pub preview_delimiter: Option<String>,
}
pub const DEFAULT_DELIMITER: &str = " ";
#[allow(clippy::unnecessary_wraps)]
fn default_delimiter() -> Option<String> {
Some(DEFAULT_DELIMITER.to_string())
}
impl Display for CableChannelPrototype {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
}
#[derive(Debug, serde::Deserialize, Default)]
pub struct CableChannels(pub FxHashMap<String, CableChannelPrototype>);
impl Deref for CableChannels {
type Target = FxHashMap<String, CableChannelPrototype>;
fn deref(&self) -> &Self::Target {
&self.0
}
}

View File

@ -1,3 +0,0 @@
pub mod cable;
pub mod channels;
pub mod entry;

View File

@ -1,25 +0,0 @@
[package]
name = "television-derive"
version = "0.0.23"
description.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
readme.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
proc-macro2 = "1.0.87"
quote = "1.0.37"
syn = "2.0.79"
[lib]
proc-macro = true
[lints]
workspace = true

View File

@ -1,20 +0,0 @@
[package]
name = "television-fuzzy"
version = "0.0.23"
description.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
readme.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
nucleo = "0.5.0"
parking_lot = "0.12.3"
[lints]
workspace = true

View File

@ -1,3 +0,0 @@
pub mod matcher;
pub use matcher::Matcher;

View File

@ -1,41 +0,0 @@
[package]
name = "television-previewers"
version = "0.0.23"
description.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
readme.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
television-channels = { path = "../television-channels", version = "0.0.23" }
television-utils = { path = "../television-utils", version = "0.0.23" }
syntect = { workspace = true }
devicons = { workspace = true }
tracing = { workspace = true }
tokio = { workspace = true }
color-eyre = { workspace = true }
lazy_static = { workspace = true }
rustc-hash = { workspace = true }
parking_lot = "0.12.3"
regex = "1.11.1"
nom = "7.1"
tui = { version = "0.29", default-features = false, package = "ratatui" }
thiserror = "1.0"
simdutf8 = { version = "0.1", optional = true }
smallvec = { version = "1.10.0", features = ["const_generics"] }
[features]
simd = ["dep:simdutf8"]
zero-copy = []
default = ["zero-copy", "simd"]
[lints]
workspace = true

View File

@ -1,2 +0,0 @@
pub mod ansi;
pub mod previewers;

View File

@ -1,29 +0,0 @@
[package]
name = "television-screen"
version = "0.0.23"
description.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
readme.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
television-utils = { path = "../television-utils", version = "0.0.23" }
television-channels = { path = "../television-channels", version = "0.0.23" }
television-previewers = { path = "../television-previewers", version = "0.0.23" }
ratatui = { workspace = true }
serde = { workspace = true }
color-eyre = { workspace = true }
syntect = { workspace = true }
rustc-hash = { workspace = true }
tracing = { workspace = true }
devicons = { workspace = true }
[lints]
workspace = true

View File

@ -1,35 +0,0 @@
[package]
name = "television-utils"
version = "0.0.23"
description.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
readme.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
lazy_static = { workspace = true }
tracing = { workspace = true }
color-eyre = { workspace = true }
directories = { workspace = true }
syntect = { workspace = true }
unicode-width = { workspace = true }
rustc-hash = { workspace = true }
tokio = { workspace = true }
ignore = "0.4.23"
bat = { version = "0.24.0", default-features = false, features = [
"regex-onig",
] }
gag = "1.0.0"
[target.'cfg(windows)'.dependencies]
winapi-util = "0.1.9"
[lints]
workspace = true

View File

@ -1,46 +0,0 @@
use rustc_hash::FxHashMap;
use lazy_static::lazy_static;
lazy_static! {
pub static ref BUILTIN_THEMES: FxHashMap<&'static str, &'static str> = {
let mut m = FxHashMap::default();
m.insert("default", include_str!("../../../../themes/default.toml"));
m.insert(
"television",
include_str!("../../../../themes/television.toml"),
);
m.insert(
"gruvbox-dark",
include_str!("../../../../themes/gruvbox-dark.toml"),
);
m.insert(
"gruvbox-light",
include_str!("../../../../themes/gruvbox-light.toml"),
);
m.insert(
"catppuccin",
include_str!("../../../../themes/catppuccin.toml"),
);
m.insert(
"nord-dark",
include_str!("../../../../themes/nord-dark.toml"),
);
m.insert(
"solarized-dark",
include_str!("../../../../themes/solarized-dark.toml"),
);
m.insert(
"solarized-light",
include_str!("../../../../themes/solarized-light.toml"),
);
m.insert("dracula", include_str!("../../../../themes/dracula.toml"));
m.insert("monokai", include_str!("../../../../themes/monokai.toml"));
m.insert("onedark", include_str!("../../../../themes/onedark.toml"));
m.insert(
"tokyonight",
include_str!("../../../../themes/tokyonight.toml"),
);
m
};
}

View File

@ -0,0 +1,26 @@
[package]
name = "television-derive"
version = "0.0.23"
edition = "2021"
description = "The revolution will be televised."
license = "MIT"
authors = ["Alexandre Pasmantier <alex.pasmant@gmail.com>"]
repository = "https://github.com/alexpasmantier/television"
homepage = "https://github.com/alexpasmantier/television"
keywords = ["search", "fuzzy", "preview", "tui", "terminal"]
categories = [
"command-line-utilities",
"command-line-interface",
"concurrency",
"development-tools",
]
rust-version = "1.81"
[dependencies]
proc-macro2 = "1.0.87"
quote = "1.0.37"
syn = "2.0.79"
[lib]
proc-macro = true

View File

@ -5,9 +5,9 @@ use quote::quote;
/// to convert into a `TelevisionChannel` member: /// to convert into a `TelevisionChannel` member:
/// ///
/// ```ignore /// ```ignore
/// use crate::channels::{TelevisionChannel, OnAir}; /// use television::channels::{TelevisionChannel, OnAir};
/// use television-derive::ToCliChannel; /// use television-derive::ToCliChannel;
/// use crate::channels::{files, text}; /// use television::channels::{files, text};
/// ///
/// #[derive(ToCliChannel)] /// #[derive(ToCliChannel)]
/// enum TelevisionChannel { /// enum TelevisionChannel {
@ -132,8 +132,8 @@ fn impl_cli_channel(ast: &syn::DeriveInput) -> TokenStream {
/// Example: /// Example:
/// ```ignore /// ```ignore
/// use television-derive::Broadcast; /// use television-derive::Broadcast;
/// use crate::channels::{TelevisionChannel, OnAir}; /// use television::channels::{TelevisionChannel, OnAir};
/// use crate::channels::{files, text}; /// use television::channels::{files, text};
/// ///
/// #[derive(Broadcast)] /// #[derive(Broadcast)]
/// enum TelevisionChannel { /// enum TelevisionChannel {

View File

@ -1,11 +1,13 @@
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use std::sync::Arc; use std::sync::Arc;
use crate::screen::mode::Mode;
use color_eyre::Result; use color_eyre::Result;
use television_screen::mode::Mode;
use tokio::sync::{mpsc, Mutex}; use tokio::sync::{mpsc, Mutex};
use tracing::{debug, info}; use tracing::{debug, info};
use crate::channels::entry::Entry;
use crate::channels::TelevisionChannel;
use crate::config::{parse_key, Config}; use crate::config::{parse_key, Config};
use crate::keymap::Keymap; use crate::keymap::Keymap;
use crate::television::Television; use crate::television::Television;
@ -14,8 +16,6 @@ use crate::{
event::{Event, EventLoop, Key}, event::{Event, EventLoop, Key},
render::{render, RenderingTask}, render::{render, RenderingTask},
}; };
use television_channels::channels::TelevisionChannel;
use television_channels::entry::Entry;
/// The main application struct that holds the state of the application. /// The main application struct that holds the state of the application.
pub struct App { pub struct App {

View File

@ -2,8 +2,8 @@ use std::path::PathBuf;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::channels::cable::{CableChannelPrototype, CableChannels};
use color_eyre::Result; use color_eyre::Result;
use television_channels::cable::{CableChannelPrototype, CableChannels};
use tracing::{debug, error}; use tracing::{debug, error};
use crate::config::get_config_dir; use crate::config::get_config_dir;
@ -20,11 +20,11 @@ const CABLE_FILE_FORMAT: &str = "toml";
#[cfg(unix)] #[cfg(unix)]
const DEFAULT_CABLE_CHANNELS: &str = const DEFAULT_CABLE_CHANNELS: &str =
include_str!("../../cable/unix-channels.toml"); include_str!("../cable/unix-channels.toml");
#[cfg(not(unix))] #[cfg(not(unix))]
const DEFAULT_CABLE_CHANNELS: &str = const DEFAULT_CABLE_CHANNELS: &str =
include_str!("../../cable/windows-channels.toml"); include_str!("../cable/windows-channels.toml");
const DEFAULT_CABLE_CHANNELS_FILE_NAME: &str = "default_channels.toml"; const DEFAULT_CABLE_CHANNELS_FILE_NAME: &str = "default_channels.toml";
@ -34,7 +34,7 @@ const DEFAULT_CABLE_CHANNELS_FILE_NAME: &str = "default_channels.toml";
/// pattern in the config directory: `*channels.toml`. /// pattern in the config directory: `*channels.toml`.
/// ///
/// # Example: /// # Example:
/// ``` /// ```ignore
/// config_folder/ /// config_folder/
/// ├── cable_channels.toml /// ├── cable_channels.toml
/// ├── my_channels.toml /// ├── my_channels.toml

View File

@ -1,13 +1,13 @@
use std::collections::HashSet; use std::collections::HashSet;
use crate::channels::entry::Entry;
use crate::channels::entry::PreviewType;
use crate::channels::OnAir; use crate::channels::OnAir;
use crate::entry::Entry; use crate::matcher::{config::Config, injector::Injector, Matcher};
use crate::entry::PreviewType; use crate::utils::indices::sep_name_and_value_indices;
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::FxBuildHasher; use rustc_hash::FxBuildHasher;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
use television_utils::indices::sep_name_and_value_indices;
use tracing::debug; use tracing::debug;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -170,8 +170,8 @@ async fn load_aliases(injector: Injector<Alias>) {
None None
}) })
.for_each(|alias| { .for_each(|alias| {
let () = injector.push(alias.clone(), |_, cols| { let () = injector.push(alias.clone(), |e, cols| {
cols[0] = (alias.name.clone() + &alias.value).into(); cols[0] = (e.name.clone() + &e.value).into();
}); });
}); });
} }

View File

@ -1,3 +1,9 @@
use rustc_hash::FxHashMap;
use std::{
fmt::{self, Display, Formatter},
ops::Deref,
};
use std::collections::HashSet; use std::collections::HashSet;
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
use std::process::Stdio; use std::process::Stdio;
@ -8,14 +14,11 @@ use regex::Regex;
use rustc_hash::{FxBuildHasher, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashSet};
use tracing::debug; use tracing::debug;
use crate::cable::{CableChannelPrototype, DEFAULT_DELIMITER}; use crate::channels::entry::{Entry, PreviewCommand, PreviewType};
use crate::channels::OnAir; use crate::channels::OnAir;
use crate::entry::{Entry, PreviewCommand, PreviewType}; use crate::matcher::Matcher;
use television_fuzzy::{ use crate::matcher::{config::Config, injector::Injector};
matcher::{config::Config, injector::Injector}, use crate::utils::command::shell_command;
Matcher,
};
use television_utils::command::shell_command;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum PreviewKind { enum PreviewKind {
@ -214,3 +217,36 @@ impl OnAir for Channel {
fn shutdown(&self) {} fn shutdown(&self) {}
} }
#[derive(Clone, Debug, serde::Deserialize, PartialEq)]
pub struct CableChannelPrototype {
pub name: String,
pub source_command: String,
pub preview_command: Option<String>,
#[serde(default = "default_delimiter")]
pub preview_delimiter: Option<String>,
}
pub const DEFAULT_DELIMITER: &str = " ";
#[allow(clippy::unnecessary_wraps)]
fn default_delimiter() -> Option<String> {
Some(DEFAULT_DELIMITER.to_string())
}
impl Display for CableChannelPrototype {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
}
#[derive(Debug, serde::Deserialize, Default)]
pub struct CableChannels(pub FxHashMap<String, CableChannelPrototype>);
impl Deref for CableChannels {
type Target = FxHashMap<String, CableChannelPrototype>;
fn deref(&self) -> &Self::Target {
&self.0
}
}

View File

@ -1,11 +1,11 @@
use crate::channels::entry::{Entry, PreviewCommand, PreviewType};
use crate::channels::{OnAir, TelevisionChannel}; use crate::channels::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewCommand, PreviewType}; use crate::matcher::{config::Config, injector::Injector, Matcher};
use crate::utils::files::{walk_builder, DEFAULT_NUM_THREADS};
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
use std::path::PathBuf; use std::path::PathBuf;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
pub struct Channel { pub struct Channel {
matcher: Matcher<String>, matcher: Matcher<String>,
@ -172,7 +172,7 @@ async fn load_dirs(paths: Vec<PathBuf>, injector: Injector<String>) {
return ignore::WalkState::Continue; return ignore::WalkState::Continue;
} }
let () = injector.push(dir_path.to_string(), |e, cols| { let () = injector.push(dir_path.to_string(), |e, cols| {
cols[0] = e.clone().into(); cols[0] = e.to_string().into();
}); });
} }
} }

View File

@ -80,7 +80,7 @@ impl Entry {
/// ///
/// Additional fields can be set using the builder pattern. /// Additional fields can be set using the builder pattern.
/// ``` /// ```
/// use television_channels::entry::{Entry, PreviewType}; /// use television::channels::entry::{Entry, PreviewType};
/// use devicons::FileIcon; /// use devicons::FileIcon;
/// ///
/// let entry = Entry::new("name".to_string(), PreviewType::EnvVar) /// let entry = Entry::new("name".to_string(), PreviewType::EnvVar)

View File

@ -4,9 +4,9 @@ use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashSet};
use super::OnAir; use super::OnAir;
use crate::entry::{Entry, PreviewType}; use crate::channels::entry::{Entry, PreviewType};
use television_fuzzy::matcher::{config::Config, Matcher}; use crate::matcher::{config::Config, Matcher};
use television_utils::indices::sep_name_and_value_indices; use crate::utils::indices::sep_name_and_value_indices;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct EnvVar { struct EnvVar {
@ -29,9 +29,15 @@ impl Channel {
let matcher = Matcher::new(Config::default().n_threads(NUM_THREADS)); let matcher = Matcher::new(Config::default().n_threads(NUM_THREADS));
let injector = matcher.injector(); let injector = matcher.injector();
for (name, value) in std::env::vars() { for (name, value) in std::env::vars() {
let () = injector.push(EnvVar { name, value }, |e, cols| { let () = injector.push(
cols[0] = (e.name.clone() + &e.value).into(); EnvVar {
}); name: name.clone(),
value: value.clone(),
},
|e, cols| {
cols[0] = (e.name.clone() + &e.value).into();
},
);
} }
Channel { Channel {
matcher, matcher,

View File

@ -1,11 +1,11 @@
use crate::channels::entry::{Entry, PreviewType};
use crate::channels::{OnAir, TelevisionChannel}; use crate::channels::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewType}; use crate::matcher::{config::Config, injector::Injector, Matcher};
use crate::utils::files::{walk_builder, DEFAULT_NUM_THREADS};
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
use std::path::PathBuf; use std::path::PathBuf;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
pub struct Channel { pub struct Channel {
matcher: Matcher<String>, matcher: Matcher<String>,
@ -176,7 +176,7 @@ async fn load_files(paths: Vec<PathBuf>, injector: Injector<String>) {
.to_string_lossy(); .to_string_lossy();
let () = let () =
injector.push(file_path.to_string(), |e, cols| { injector.push(file_path.to_string(), |e, cols| {
cols[0] = e.clone().into(); cols[0] = e.to_string().into();
}); });
} }
} }

View File

@ -8,10 +8,10 @@ use std::path::PathBuf;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tracing::debug; use tracing::debug;
use crate::channels::entry::{Entry, PreviewCommand, PreviewType};
use crate::channels::OnAir; use crate::channels::OnAir;
use crate::entry::{Entry, PreviewCommand, PreviewType}; use crate::matcher::{config::Config, injector::Injector, Matcher};
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher}; use crate::utils::files::{walk_builder, DEFAULT_NUM_THREADS};
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
pub struct Channel { pub struct Channel {
matcher: Matcher<String>, matcher: Matcher<String>,

View File

@ -1,17 +1,18 @@
use crate::entry::Entry; use crate::channels::entry::Entry;
use color_eyre::Result; use color_eyre::Result;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use television_derive::{Broadcast, ToCliChannel, ToUnitChannel}; use television_derive::{Broadcast, ToCliChannel, ToUnitChannel};
mod alias; pub mod alias;
mod cable; pub mod cable;
mod dirs; pub mod dirs;
mod env; pub mod entry;
mod files; pub mod env;
mod git_repos; pub mod files;
pub mod git_repos;
pub mod remote_control; pub mod remote_control;
pub mod stdin; pub mod stdin;
mod text; pub mod text;
/// The interface that all television channels must implement. /// The interface that all television channels must implement.
/// ///

View File

@ -1,14 +1,14 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::fmt::Display; use std::fmt::Display;
use crate::cable::{CableChannelPrototype, CableChannels}; use crate::channels::cable::{CableChannelPrototype, CableChannels};
use crate::channels::entry::{Entry, PreviewType};
use crate::channels::{CliTvChannel, OnAir, TelevisionChannel, UnitChannel}; use crate::channels::{CliTvChannel, OnAir, TelevisionChannel, UnitChannel};
use crate::entry::{Entry, PreviewType}; use crate::matcher::{config::Config, Matcher};
use clap::ValueEnum; use clap::ValueEnum;
use color_eyre::Result; use color_eyre::Result;
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashSet};
use television_fuzzy::matcher::{config::Config, Matcher};
use super::cable; use super::cable;
@ -56,7 +56,7 @@ impl RemoteControl {
); );
for button in buttons { for button in buttons {
let () = injector.push(button.clone(), |e, cols| { let () = injector.push(button.clone(), |e, cols| {
cols[0] = e.to_string().clone().into(); cols[0] = e.to_string().into();
}); });
} }
RemoteControl { RemoteControl {
@ -154,13 +154,6 @@ impl OnAir for RemoteControl {
.collect() .collect()
} }
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}
#[allow(unused_variables)]
fn toggle_selection(&mut self, entry: &Entry) {}
fn get_result(&self, index: u32) -> Option<Entry> { fn get_result(&self, index: u32) -> Option<Entry> {
self.matcher.get_result(index).map(|item| { self.matcher.get_result(index).map(|item| {
let path = item.matched_string; let path = item.matched_string;
@ -168,6 +161,13 @@ impl OnAir for RemoteControl {
}) })
} }
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}
#[allow(unused_variables)]
fn toggle_selection(&mut self, entry: &Entry) {}
fn result_count(&self) -> u32 { fn result_count(&self) -> u32 {
self.matcher.matched_item_count self.matcher.matched_item_count
} }

View File

@ -8,8 +8,8 @@ use rustc_hash::{FxBuildHasher, FxHashSet};
use tracing::debug; use tracing::debug;
use super::OnAir; use super::OnAir;
use crate::entry::{Entry, PreviewType}; use crate::channels::entry::{Entry, PreviewType};
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher}; use crate::matcher::{config::Config, injector::Injector, Matcher};
pub struct Channel { pub struct Channel {
matcher: Matcher<String>, matcher: Matcher<String>,
@ -48,9 +48,10 @@ fn stream_from_stdin(injector: &Injector<String>) {
loop { loop {
match stdin.read_line(&mut buffer) { match stdin.read_line(&mut buffer) {
Ok(c) if c > 0 => { Ok(c) if c > 0 => {
if !buffer.trim().is_empty() { let buf = buffer.trim();
injector.push(buffer.trim().to_string(), |e, cols| { if !buf.is_empty() {
cols[0] = e.clone().into(); injector.push(buf.to_string(), |e, cols| {
cols[0] = e.to_string().into();
}); });
} }
buffer.clear(); buffer.clear();

View File

@ -1,5 +1,10 @@
use super::{OnAir, TelevisionChannel}; use super::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewType}; use crate::channels::entry::{Entry, PreviewType};
use crate::matcher::{config::Config, injector::Injector, Matcher};
use crate::utils::files::{walk_builder, DEFAULT_NUM_THREADS};
use crate::utils::strings::{
proportion_of_printable_ascii_characters, PRINTABLE_ASCII_THRESHOLD,
};
use devicons::FileIcon; use devicons::FileIcon;
use ignore::WalkState; use ignore::WalkState;
use rustc_hash::{FxBuildHasher, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashSet};
@ -10,11 +15,6 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::{atomic::AtomicUsize, Arc}, sync::{atomic::AtomicUsize, Arc},
}; };
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
use television_utils::strings::{
proportion_of_printable_ascii_characters, PRINTABLE_ASCII_THRESHOLD,
};
use tracing::{debug, trace, warn}; use tracing::{debug, trace, warn};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -86,14 +86,15 @@ impl Channel {
let injector = matcher.injector(); let injector = matcher.injector();
let load_handle = tokio::spawn(async move { let load_handle = tokio::spawn(async move {
for entry in entries.into_iter().take(MAX_LINES_IN_MEM) { for entry in entries.into_iter().take(MAX_LINES_IN_MEM) {
let v = entry.value.unwrap();
injector.push( injector.push(
CandidateLine::new( CandidateLine::new(
entry.name.into(), entry.name.into(),
entry.value.unwrap(), v,
entry.line_number.unwrap(), entry.line_number.unwrap(),
), ),
|c, cols| { |e, cols| {
cols[0] = c.line.clone().into(); cols[0] = e.line.clone().into();
}, },
); );
} }
@ -358,11 +359,11 @@ fn try_inject_lines(
path.strip_prefix(current_dir) path.strip_prefix(current_dir)
.unwrap_or(path) .unwrap_or(path)
.to_path_buf(), .to_path_buf(),
l, l.clone(),
line_number, line_number,
); );
let () = injector.push(candidate, |c, cols| { let () = injector.push(candidate, |e, cols| {
cols[0] = c.line.clone().into(); cols[0] = e.line.clone().into();
}); });
injected_lines += 1; injected_lines += 1;
} }

View File

@ -5,15 +5,14 @@ use clap::{Parser, Subcommand, ValueEnum};
use color_eyre::{eyre::eyre, Result}; use color_eyre::{eyre::eyre, Result};
use tracing::debug; use tracing::debug;
use crate::channels::{
cable::CableChannelPrototype, entry::PreviewCommand, CliTvChannel,
};
use crate::utils::shell::Shell as UtilShell;
use crate::{ use crate::{
cable, cable,
config::{get_config_dir, get_data_dir}, config::{get_config_dir, get_data_dir},
}; };
use television_channels::{
cable::CableChannelPrototype, channels::CliTvChannel,
entry::PreviewCommand,
};
use television_utils::shell::Shell as UtilShell;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author, version = version(), about)] #[command(author, version = version(), about)]
@ -224,7 +223,11 @@ pub fn list_channels() {
/// if no match is found, throw an error /// if no match is found, throw an error
/// ///
/// ## Example: /// ## Example:
/// ``` /// ```ignore
/// use television::channels::CliTvChannel;
/// use television::cli::ParsedCliChannel;
/// use television::cli::guess_channel_from_prompt;
///
/// let prompt = "ls -l"; /// let prompt = "ls -l";
/// let command_mapping = hashmap! { /// let command_mapping = hashmap! {
/// "ls".to_string() => "files".to_string(), /// "ls".to_string() => "files".to_string(),
@ -246,12 +249,10 @@ pub fn guess_channel_from_prompt(
// git checkout -qf // git checkout -qf
// --- -------- --- <--------- // --- -------- --- <---------
if prompt.trim().is_empty() { if prompt.trim().is_empty() {
match command_mapping.get("") { return match command_mapping.get("") {
Some(channel) => return parse_channel(channel), Some(channel) => parse_channel(channel),
None => { None => Err(eyre!("No channel found for prompt: {}", prompt)),
return Err(eyre!("No channel found for prompt: {}", prompt)) };
}
}
} }
let rev_prompt_words = prompt.split_whitespace().rev(); let rev_prompt_words = prompt.split_whitespace().rev();
let mut stack = Vec::new(); let mut stack = Vec::new();

View File

@ -20,7 +20,7 @@ mod styles;
mod themes; mod themes;
mod ui; mod ui;
const CONFIG: &str = include_str!("../../.config/config.toml"); const CONFIG: &str = include_str!("../.config/config.toml");
#[allow(dead_code, clippy::module_name_repetitions)] #[allow(dead_code, clippy::module_name_repetitions)]
#[derive(Clone, Debug, Deserialize, Default)] #[derive(Clone, Debug, Deserialize, Default)]

View File

@ -1,11 +1,11 @@
use crate::action::Action; use crate::action::Action;
use crate::event::{convert_raw_event_to_key, Key}; use crate::event::{convert_raw_event_to_key, Key};
use crate::screen::mode::Mode;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::fmt::Display; use std::fmt::Display;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use television_screen::mode::Mode;
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
pub enum Binding { pub enum Binding {

View File

@ -1,9 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::preview::{previewers, PreviewerConfig};
use config::ValueKind; use config::ValueKind;
use serde::Deserialize; use serde::Deserialize;
use television_previewers::previewers;
use television_previewers::previewers::PreviewerConfig;
#[derive(Clone, Debug, Deserialize, Default)] #[derive(Clone, Debug, Deserialize, Default)]
pub struct PreviewersConfig { pub struct PreviewersConfig {
@ -17,7 +16,7 @@ pub struct PreviewersConfig {
impl From<PreviewersConfig> for PreviewerConfig { impl From<PreviewersConfig> for PreviewerConfig {
fn from(val: PreviewersConfig) -> Self { fn from(val: PreviewersConfig) -> Self {
PreviewerConfig::default() PreviewerConfig::default()
.file(previewers::FilePreviewerConfig::new(val.file.theme)) .file(previewers::files::FilePreviewerConfig::new(val.file.theme))
} }
} }

View File

@ -1,8 +1,8 @@
use crate::screen::mode::Mode;
use ratatui::prelude::{Color, Modifier, Style}; use ratatui::prelude::{Color, Modifier, Style};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use television_screen::mode::Mode;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Styles(pub FxHashMap<Mode, FxHashMap<String, Style>>); pub struct Styles(pub FxHashMap<Mode, FxHashMap<String, Style>>);

View File

@ -1,12 +1,12 @@
use color_eyre::Result; use color_eyre::Result;
use std::path::PathBuf; use std::path::PathBuf;
use ratatui::style::Color as RatatuiColor; use crate::screen::colors::{
use serde::Deserialize;
use television_screen::colors::{
Colorscheme, GeneralColorscheme, HelpColorscheme, InputColorscheme, Colorscheme, GeneralColorscheme, HelpColorscheme, InputColorscheme,
ModeColorscheme, PreviewColorscheme, ResultsColorscheme, ModeColorscheme, PreviewColorscheme, ResultsColorscheme,
}; };
use ratatui::style::Color as RatatuiColor;
use serde::Deserialize;
use super::get_config_dir; use super::get_config_dir;
@ -149,7 +149,7 @@ pub const DEFAULT_THEME: &str = "default";
impl Default for Theme { impl Default for Theme {
fn default() -> Self { fn default() -> Self {
let theme_content = include_str!("../../../themes/default.toml"); let theme_content = include_str!("../../themes/default.toml");
toml::from_str(theme_content).unwrap() toml::from_str(theme_content).unwrap()
} }
} }

View File

@ -0,0 +1,43 @@
use rustc_hash::FxHashMap;
use lazy_static::lazy_static;
lazy_static! {
pub static ref BUILTIN_THEMES: FxHashMap<&'static str, &'static str> = {
let mut m = FxHashMap::default();
m.insert("default", include_str!("../../../themes/default.toml"));
m.insert(
"television",
include_str!("../../../themes/television.toml"),
);
m.insert(
"gruvbox-dark",
include_str!("../../../themes/gruvbox-dark.toml"),
);
m.insert(
"gruvbox-light",
include_str!("../../../themes/gruvbox-light.toml"),
);
m.insert(
"catppuccin",
include_str!("../../../themes/catppuccin.toml"),
);
m.insert("nord-dark", include_str!("../../../themes/nord-dark.toml"));
m.insert(
"solarized-dark",
include_str!("../../../themes/solarized-dark.toml"),
);
m.insert(
"solarized-light",
include_str!("../../../themes/solarized-light.toml"),
);
m.insert("dracula", include_str!("../../../themes/dracula.toml"));
m.insert("monokai", include_str!("../../../themes/monokai.toml"));
m.insert("onedark", include_str!("../../../themes/onedark.toml"));
m.insert(
"tokyonight",
include_str!("../../../themes/tokyonight.toml"),
);
m
};
}

View File

@ -3,7 +3,7 @@ use std::collections::HashMap;
use config::ValueKind; use config::ValueKind;
use serde::Deserialize; use serde::Deserialize;
use television_screen::layout::{InputPosition, PreviewTitlePosition}; use crate::screen::layout::{InputPosition, PreviewTitlePosition};
use super::themes::DEFAULT_THEME; use super::themes::DEFAULT_THEME;

View File

@ -1,5 +1,5 @@
use crate::action::Action; use crate::action::Action;
use television_utils::input::InputRequest; use crate::utils::input::InputRequest;
pub fn convert_action_to_input_request( pub fn convert_action_to_input_request(
action: &Action, action: &Action,

View File

@ -1,8 +1,8 @@
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::ops::Deref; use std::ops::Deref;
use crate::screen::mode::Mode;
use color_eyre::Result; use color_eyre::Result;
use television_screen::mode::Mode;
use crate::action::Action; use crate::action::Action;
use crate::config::{Binding, KeyBindings}; use crate::config::{Binding, KeyBindings};

19
television/lib.rs Normal file
View File

@ -0,0 +1,19 @@
pub mod action;
pub mod app;
pub mod cable;
pub mod channels;
pub mod cli;
pub mod config;
pub mod errors;
pub mod event;
pub mod input;
pub mod keymap;
pub mod logging;
pub mod matcher;
pub mod picker;
pub mod preview;
pub mod render;
pub mod screen;
pub mod television;
pub mod tui;
pub mod utils;

View File

@ -7,40 +7,24 @@ use clap::Parser;
use color_eyre::Result; use color_eyre::Result;
use tracing::{debug, error, info}; use tracing::{debug, error, info};
use crate::app::App; use television::app::App;
use crate::cli::{ use television::channels::{
entry::PreviewType, stdin::Channel as StdinChannel, TelevisionChannel,
};
use television::cli::{
guess_channel_from_prompt, list_channels, Cli, ParsedCliChannel, guess_channel_from_prompt, list_channels, Cli, ParsedCliChannel,
PostProcessedCli, PostProcessedCli,
}; };
use crate::config::Config; use television::config::Config;
use television_channels::{ use television::utils::{
channels::{stdin::Channel as StdinChannel, TelevisionChannel},
entry::PreviewType,
};
use television_utils::{
shell::{completion_script, Shell}, shell::{completion_script, Shell},
stdin::is_readable_stdin, stdin::is_readable_stdin,
}; };
pub mod action;
pub mod app;
pub mod cable;
pub mod cli;
pub mod config;
pub mod errors;
pub mod event;
pub mod input;
pub mod keymap;
pub mod logging;
pub mod picker;
pub mod render;
pub mod television;
pub mod tui;
#[tokio::main(flavor = "multi_thread")] #[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> { async fn main() -> Result<()> {
errors::init()?; television::errors::init()?;
logging::init()?; television::logging::init()?;
let args: PostProcessedCli = Cli::parse().into(); let args: PostProcessedCli = Cli::parse().into();
debug!("{:?}", args); debug!("{:?}", args);
@ -49,11 +33,11 @@ async fn main() -> Result<()> {
if let Some(command) = args.command { if let Some(command) = args.command {
match command { match command {
cli::Command::ListChannels => { television::cli::Command::ListChannels => {
list_channels(); list_channels();
exit(0); exit(0);
} }
cli::Command::InitShell { shell } => { television::cli::Command::InitShell { shell } => {
let script = completion_script(Shell::from(shell))?; let script = completion_script(Shell::from(shell))?;
println!("{script}"); println!("{script}");
exit(0); exit(0);

View File

@ -28,7 +28,7 @@ where
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use television_fuzzy::matcher::{config::Config, Matcher}; /// use television::matcher::{config::Config, Matcher};
/// ///
/// let config = Config::default(); /// let config = Config::default();
/// let matcher = Matcher::new(config); /// let matcher = Matcher::new(config);

View File

@ -9,7 +9,7 @@ use std::ops::DerefMut;
/// ///
/// # Example /// # Example
/// ```rust /// ```rust
/// use television_fuzzy::matcher::lazy::LazyMutex; /// use television::matcher::lazy::LazyMutex;
/// ///
/// struct Thing { /// struct Thing {
/// // ... /// // ...
@ -61,7 +61,7 @@ impl<T> LazyMutex<T> {
/// ///
/// # Example /// # Example
/// ```ignore /// ```ignore
/// use television-fuzzy::matcher::{lazy::MATCHER, matched_item::MatchedItem}; /// use television::matcher::{lazy::MATCHER, matched_item::MatchedItem};
/// ///
/// let snapshot = channel_matcher.snapshot(); /// let snapshot = channel_matcher.snapshot();
/// ///

View File

@ -1,10 +1,6 @@
use injector::Injector; use injector::Injector;
use std::sync::Arc; use std::sync::Arc;
use crate::matcher::{
config::Config, lazy::MATCHER, matched_item::MatchedItem,
};
pub mod config; pub mod config;
pub mod injector; pub mod injector;
pub mod lazy; pub mod lazy;
@ -61,7 +57,7 @@ where
I: Sync + Send + Clone + 'static, I: Sync + Send + Clone + 'static,
{ {
/// Create a new fuzzy matcher with the given configuration. /// Create a new fuzzy matcher with the given configuration.
pub fn new(config: Config) -> Self { pub fn new(config: config::Config) -> Self {
Self { Self {
inner: nucleo::Nucleo::new( inner: nucleo::Nucleo::new(
(&config).into(), (&config).into(),
@ -89,7 +85,7 @@ where
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use television_fuzzy::matcher::{config::Config, Matcher}; /// use television::matcher::{config::Config, Matcher};
/// ///
/// let config = Config::default(); /// let config = Config::default();
/// let matcher = Matcher::new(config); /// let matcher = Matcher::new(config);
@ -139,7 +135,7 @@ where
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use television_fuzzy::matcher::{config::Config, Matcher}; /// use television::matcher::{config::Config, Matcher};
/// ///
/// let config = Config::default(); /// let config = Config::default();
/// let mut matcher: Matcher<String> = Matcher::new(config); /// let mut matcher: Matcher<String> = Matcher::new(config);
@ -158,13 +154,13 @@ where
&mut self, &mut self,
num_entries: u32, num_entries: u32,
offset: u32, offset: u32,
) -> Vec<MatchedItem<I>> { ) -> Vec<matched_item::MatchedItem<I>> {
let snapshot = self.inner.snapshot(); let snapshot = self.inner.snapshot();
self.total_item_count = snapshot.item_count(); self.total_item_count = snapshot.item_count();
self.matched_item_count = snapshot.matched_item_count(); self.matched_item_count = snapshot.matched_item_count();
let mut col_indices = Vec::new(); let mut col_indices = Vec::new();
let mut matcher = MATCHER.lock(); let mut matcher = lazy::MATCHER.lock();
snapshot snapshot
.matched_items( .matched_items(
@ -182,7 +178,7 @@ where
let indices = col_indices.drain(..); let indices = col_indices.drain(..);
let matched_string = item.matcher_columns[0].to_string(); let matched_string = item.matcher_columns[0].to_string();
MatchedItem { matched_item::MatchedItem {
inner: item.data.clone(), inner: item.data.clone(),
matched_string, matched_string,
match_indices: indices.map(|i| (i, i + 1)).collect(), match_indices: indices.map(|i| (i, i + 1)).collect(),
@ -195,7 +191,7 @@ where
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use television_fuzzy::matcher::{config::Config, Matcher}; /// use television::matcher::{config::Config, Matcher};
/// ///
/// let config = Config::default(); /// let config = Config::default();
/// let mut matcher: Matcher<String> = Matcher::new(config); /// let mut matcher: Matcher<String> = Matcher::new(config);
@ -206,11 +202,14 @@ where
/// // ... /// // ...
/// } /// }
/// ``` /// ```
pub fn get_result(&self, index: u32) -> Option<MatchedItem<I>> { pub fn get_result(
&self,
index: u32,
) -> Option<matched_item::MatchedItem<I>> {
let snapshot = self.inner.snapshot(); let snapshot = self.inner.snapshot();
snapshot.get_matched_item(index).map(|item| { snapshot.get_matched_item(index).map(|item| {
let matched_string = item.matcher_columns[0].to_string(); let matched_string = item.matcher_columns[0].to_string();
MatchedItem { matched_item::MatchedItem {
inner: item.data.clone(), inner: item.data.clone(),
matched_string, matched_string,
match_indices: Vec::new(), match_indices: Vec::new(),

View File

@ -1,5 +1,5 @@
use crate::utils::{input::Input, strings::EMPTY_STRING};
use ratatui::widgets::ListState; use ratatui::widgets::ListState;
use television_utils::{input::Input, strings::EMPTY_STRING};
#[derive(Debug)] #[derive(Debug)]
pub struct Picker { pub struct Picker {

View File

@ -8,7 +8,7 @@ pub mod code;
pub mod error; pub mod error;
pub mod parser; pub mod parser;
pub use error::Error; pub use error::Error;
use tui::text::Text; use ratatui::text::Text;
/// `IntoText` will convert any type that has a `AsRef<[u8]>` to a Text. /// `IntoText` will convert any type that has a `AsRef<[u8]>` to a Text.
pub trait IntoText { pub trait IntoText {
@ -24,11 +24,11 @@ where
T: AsRef<[u8]>, T: AsRef<[u8]>,
{ {
fn into_text(&self) -> Result<Text<'static>, Error> { fn into_text(&self) -> Result<Text<'static>, Error> {
Ok(crate::ansi::parser::text(self.as_ref())?.1) Ok(parser::text(self.as_ref())?.1)
} }
#[cfg(feature = "zero-copy")] #[cfg(feature = "zero-copy")]
fn to_text(&self) -> Result<Text<'_>, Error> { fn to_text(&self) -> Result<Text<'_>, Error> {
Ok(crate::ansi::parser::text_fast(self.as_ref())?.1) Ok(parser::text_fast(self.as_ref())?.1)
} }
} }

View File

@ -1,4 +1,4 @@
use tui::style::Color; use ratatui::style::Color;
/// This enum stores most types of ansi escape sequences /// This enum stores most types of ansi escape sequences
/// ///

View File

@ -1,4 +1,4 @@
use crate::ansi::code::AnsiCode; use crate::preview::ansi::code::AnsiCode;
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::{tag, take, take_till, take_while}, bytes::complete::{tag, take, take_till, take_while},
@ -6,18 +6,17 @@ use nom::{
complete::{char, i64, not_line_ending, u8}, complete::{char, i64, not_line_ending, u8},
is_alphabetic, is_alphabetic,
}, },
combinator::{map_res, opt, recognize, value}, combinator::{map_res, opt},
error::{self, FromExternalError},
multi::fold_many0, multi::fold_many0,
sequence::{delimited, preceded, terminated, tuple}, sequence::{delimited, preceded, tuple},
IResult, Parser, IResult, Parser,
}; };
use smallvec::{SmallVec, ToSmallVec}; use ratatui::{
use std::str::FromStr;
use tui::{
style::{Color, Modifier, Style, Stylize}, style::{Color, Modifier, Style, Stylize},
text::{Line, Span, Text}, text::{Line, Span, Text},
}; };
use smallvec::SmallVec;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum ColorType { enum ColorType {
@ -35,11 +34,11 @@ struct AnsiItem {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
struct AnsiStates { struct AnsiStates {
pub items: smallvec::SmallVec<[AnsiItem; 2]>, pub items: SmallVec<[AnsiItem; 2]>,
pub style: Style, pub style: Style,
} }
impl From<AnsiStates> for tui::style::Style { impl From<AnsiStates> for Style {
fn from(states: AnsiStates) -> Self { fn from(states: AnsiStates) -> Self {
let mut style = states.style; let mut style = states.style;
for item in states.items { for item in states.items {

View File

@ -1,8 +1,8 @@
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::sync::Arc; use std::sync::Arc;
use crate::previewers::Preview; use crate::preview::Preview;
use television_utils::cache::RingSet; use crate::utils::cache::RingSet;
use tracing::debug; use tracing::debug;
/// Default size of the preview cache: 100 entries. /// Default size of the preview cache: 100 entries.

View File

@ -1,26 +1,23 @@
use std::sync::Arc; use std::sync::Arc;
use crate::channels::entry::{Entry, PreviewType};
use devicons::FileIcon; use devicons::FileIcon;
use television_channels::entry::{Entry, PreviewType};
pub mod basic; pub mod ansi;
pub mod cache; pub mod cache;
pub mod command; pub mod previewers;
pub mod env;
pub mod files;
pub mod meta;
// previewer types // previewer types
pub use basic::BasicPreviewer; use crate::utils::cache::RingSet;
pub use basic::BasicPreviewerConfig; use crate::utils::syntax::HighlightedLines;
pub use command::CommandPreviewer; pub use previewers::basic::BasicPreviewer;
pub use command::CommandPreviewerConfig; pub use previewers::basic::BasicPreviewerConfig;
pub use env::EnvVarPreviewer; pub use previewers::command::CommandPreviewer;
pub use env::EnvVarPreviewerConfig; pub use previewers::command::CommandPreviewerConfig;
pub use files::FilePreviewer; pub use previewers::env::EnvVarPreviewer;
pub use files::FilePreviewerConfig; pub use previewers::env::EnvVarPreviewerConfig;
use television_utils::cache::RingSet; pub use previewers::files::FilePreviewer;
use television_utils::syntax::HighlightedLines; pub use previewers::files::FilePreviewerConfig;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum PreviewContent { pub enum PreviewContent {

View File

@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use crate::previewers::{Preview, PreviewContent}; use crate::channels::entry::Entry;
use television_channels::entry::Entry; use crate::preview::{Preview, PreviewContent};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct BasicPreviewer { pub struct BasicPreviewer {

View File

@ -1,13 +1,13 @@
use crate::previewers::cache::PreviewCache; use crate::channels::entry::{Entry, PreviewCommand};
use crate::previewers::{Preview, PreviewContent}; use crate::preview::cache::PreviewCache;
use crate::preview::{Preview, PreviewContent};
use crate::utils::command::shell_command;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::Mutex; use parking_lot::Mutex;
use regex::Regex; use regex::Regex;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc; use std::sync::Arc;
use television_channels::entry::{Entry, PreviewCommand};
use television_utils::command::shell_command;
use tracing::debug; use tracing::debug;
#[allow(dead_code)] #[allow(dead_code)]
@ -123,8 +123,8 @@ lazy_static! {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use television_channels::entry::{PreviewCommand, PreviewType, Entry}; /// use television::channels::entry::{PreviewCommand, PreviewType, Entry};
/// use television_previewers::previewers::command::format_command; /// use television::preview::previewers::command::format_command;
/// ///
/// let command = PreviewCommand { /// let command = PreviewCommand {
/// command: "something {} {2} {0}".to_string(), /// command: "something {} {2} {0}".to_string(),
@ -200,7 +200,7 @@ pub fn try_preview(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use television_channels::entry::{Entry, PreviewType}; use crate::channels::entry::{Entry, PreviewType};
#[test] #[test]
fn test_format_command() { fn test_format_command() {

View File

@ -1,8 +1,8 @@
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::sync::Arc; use std::sync::Arc;
use crate::previewers::{Preview, PreviewContent}; use crate::channels::entry;
use television_channels::entry; use crate::preview::{Preview, PreviewContent};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EnvVarPreviewer { pub struct EnvVarPreviewer {

View File

@ -1,3 +1,5 @@
use crate::utils::files::{read_into_lines_capped, ReadResult};
use crate::utils::syntax::HighlightedLines;
use parking_lot::Mutex; use parking_lot::Mutex;
use rustc_hash::{FxBuildHasher, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
@ -8,16 +10,14 @@ use std::sync::{
atomic::{AtomicU8, Ordering}, atomic::{AtomicU8, Ordering},
Arc, Arc,
}; };
use television_utils::files::{read_into_lines_capped, ReadResult};
use television_utils::syntax::HighlightedLines;
use syntect::{highlighting::Theme, parsing::SyntaxSet}; use syntect::{highlighting::Theme, parsing::SyntaxSet};
use tracing::{debug, warn}; use tracing::{debug, warn};
use super::cache::PreviewCache; use crate::channels::entry;
use crate::previewers::{meta, Preview, PreviewContent}; use crate::preview::cache::PreviewCache;
use television_channels::entry; use crate::preview::{previewers::meta, Preview, PreviewContent};
use television_utils::{ use crate::utils::{
files::FileType, files::FileType,
strings::preprocess_line, strings::preprocess_line,
syntax::{self, load_highlighting_assets, HighlightingAssetsExt}, syntax::{self, load_highlighting_assets, HighlightingAssetsExt},

View File

@ -1,4 +1,4 @@
use crate::previewers::{Preview, PreviewContent}; use crate::preview::{Preview, PreviewContent};
use std::sync::Arc; use std::sync::Arc;
pub fn not_supported(title: &str) -> Arc<Preview> { pub fn not_supported(title: &str) -> Arc<Preview> {

View File

@ -0,0 +1,5 @@
pub mod basic;
pub mod command;
pub mod env;
pub mod files;
pub mod meta;

View File

@ -2,8 +2,8 @@ use devicons::FileIcon;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::sync::Arc; use std::sync::Arc;
use crate::utils::cache::RingSet;
use ratatui::widgets::Paragraph; use ratatui::widgets::Paragraph;
use television_utils::cache::RingSet;
const DEFAULT_RENDERED_PREVIEW_CACHE_SIZE: usize = 10; const DEFAULT_RENDERED_PREVIEW_CACHE_SIZE: usize = 10;

View File

@ -1,14 +1,14 @@
use super::layout::HelpBarLayout; use super::layout::HelpBarLayout;
use crate::colors::{Colorscheme, GeneralColorscheme}; use crate::channels::UnitChannel;
use crate::logo::build_logo_paragraph; use crate::screen::colors::{Colorscheme, GeneralColorscheme};
use crate::metadata::build_metadata_table; use crate::screen::logo::build_logo_paragraph;
use crate::mode::{mode_color, Mode}; use crate::screen::metadata::build_metadata_table;
use crate::screen::mode::{mode_color, Mode};
use crate::utils::metadata::AppMetadata;
use ratatui::layout::Rect; use ratatui::layout::Rect;
use ratatui::prelude::{Color, Style}; use ratatui::prelude::{Color, Style};
use ratatui::widgets::{Block, BorderType, Borders, Padding, Table}; use ratatui::widgets::{Block, BorderType, Borders, Padding, Table};
use ratatui::Frame; use ratatui::Frame;
use television_channels::channels::UnitChannel;
use television_utils::metadata::AppMetadata;
pub fn draw_logo_block( pub fn draw_logo_block(
f: &mut Frame, f: &mut Frame,

View File

@ -1,3 +1,4 @@
use crate::utils::input::Input;
use color_eyre::Result; use color_eyre::Result;
use ratatui::{ use ratatui::{
layout::{ layout::{
@ -8,9 +9,8 @@ use ratatui::{
widgets::{Block, BorderType, Borders, ListState, Paragraph}, widgets::{Block, BorderType, Borders, ListState, Paragraph},
Frame, Frame,
}; };
use television_utils::input::Input;
use crate::{ use crate::screen::{
colors::Colorscheme, colors::Colorscheme,
spinner::{Spinner, SpinnerState}, spinner::{Spinner, SpinnerState},
}; };

View File

@ -1,7 +1,7 @@
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::fmt::Display; use std::fmt::Display;
use crate::{colors::Colorscheme, mode::Mode}; use crate::screen::{colors::Colorscheme, mode::Mode};
use ratatui::{ use ratatui::{
layout::Constraint, layout::Constraint,
style::{Color, Style}, style::{Color, Style},

View File

@ -1,17 +1,17 @@
use std::fmt::Display; use std::fmt::Display;
use crate::{ use crate::channels::UnitChannel;
use crate::screen::{
colors::Colorscheme, colors::Colorscheme,
mode::{mode_color, Mode}, mode::{mode_color, Mode},
}; };
use crate::utils::metadata::AppMetadata;
use ratatui::{ use ratatui::{
layout::Constraint, layout::Constraint,
style::Style, style::Style,
text::Span, text::Span,
widgets::{Cell, Row, Table}, widgets::{Cell, Row, Table},
}; };
use television_channels::channels::UnitChannel;
use television_utils::metadata::AppMetadata;
impl Display for Mode { impl Display for Mode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

View File

@ -1,7 +1,7 @@
use ratatui::style::Color; use ratatui::style::Color;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::colors::ModeColorscheme; use crate::screen::colors::ModeColorscheme;
pub fn mode_color(mode: Mode, colorscheme: &ModeColorscheme) -> Color { pub fn mode_color(mode: Mode, colorscheme: &ModeColorscheme) -> Color {
match mode { match mode {

View File

@ -1,7 +1,16 @@
use crate::{ use crate::channels::entry::Entry;
use crate::preview::{
ansi::IntoText, Preview, PreviewContent, FILE_TOO_LARGE_MSG, LOADING_MSG,
PREVIEW_NOT_SUPPORTED_MSG, TIMEOUT_MSG,
};
use crate::screen::{
cache::RenderedPreviewCache, cache::RenderedPreviewCache,
colors::{Colorscheme, PreviewColorscheme}, colors::{Colorscheme, PreviewColorscheme},
}; };
use crate::utils::strings::{
replace_non_printable, shrink_with_ellipsis, ReplaceNonPrintableConfig,
EMPTY_STRING,
};
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use devicons::FileIcon; use devicons::FileIcon;
use ratatui::widgets::{Block, BorderType, Borders, Padding, Paragraph, Wrap}; use ratatui::widgets::{Block, BorderType, Borders, Padding, Paragraph, Wrap};
@ -12,18 +21,6 @@ use ratatui::{
}; };
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use television_channels::entry::Entry;
use television_previewers::{
ansi::IntoText,
previewers::{
Preview, PreviewContent, FILE_TOO_LARGE_MSG, LOADING_MSG,
PREVIEW_NOT_SUPPORTED_MSG, TIMEOUT_MSG,
},
};
use television_utils::strings::{
replace_non_printable, shrink_with_ellipsis, ReplaceNonPrintableConfig,
EMPTY_STRING,
};
#[allow(dead_code)] #[allow(dead_code)]
const FILL_CHAR_SLANTED: char = ''; const FILL_CHAR_SLANTED: char = '';

View File

@ -1,11 +1,11 @@
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::colors::{Colorscheme, GeneralColorscheme}; use crate::channels::entry::Entry;
use crate::logo::build_remote_logo_paragraph; use crate::screen::colors::{Colorscheme, GeneralColorscheme};
use crate::mode::{mode_color, Mode}; use crate::screen::logo::build_remote_logo_paragraph;
use crate::results::build_results_list; use crate::screen::mode::{mode_color, Mode};
use television_channels::entry::Entry; use crate::screen::results::build_results_list;
use television_utils::input::Input; use crate::utils::input::Input;
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect}; use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect};

View File

@ -1,5 +1,10 @@
use crate::colors::{Colorscheme, ResultsColorscheme}; use crate::channels::entry::Entry;
use crate::layout::InputPosition; use crate::screen::colors::{Colorscheme, ResultsColorscheme};
use crate::screen::layout::InputPosition;
use crate::utils::strings::{
make_matched_string_printable, next_char_boundary,
slice_at_char_boundaries,
};
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use ratatui::layout::{Alignment, Rect}; use ratatui::layout::{Alignment, Rect};
use ratatui::prelude::{Color, Line, Span, Style}; use ratatui::prelude::{Color, Line, Span, Style};
@ -10,15 +15,10 @@ use ratatui::widgets::{
use ratatui::Frame; use ratatui::Frame;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use std::str::FromStr; use std::str::FromStr;
use television_channels::entry::Entry;
use television_utils::strings::{
make_matched_string_printable, next_char_boundary,
slice_at_char_boundaries,
};
const POINTER_SYMBOL: &str = "> "; const POINTER_SYMBOL: &str = "> ";
const SELECTED_SYMBOL: &str = ""; const SELECTED_SYMBOL: &str = "";
const DESLECTED_SYMBOL: &str = " "; const DESELECTED_SYMBOL: &str = " ";
pub fn build_results_list<'a, 'b>( pub fn build_results_list<'a, 'b>(
results_block: Block<'b>, results_block: Block<'b>,
@ -43,7 +43,7 @@ where
Style::default().fg(colorscheme.result_selected_fg), Style::default().fg(colorscheme.result_selected_fg),
) )
} else { } else {
Span::from(DESLECTED_SYMBOL) Span::from(DESELECTED_SYMBOL)
}); });
} }
} }

View File

@ -1,7 +1,28 @@
use crate::action::Action; use crate::action::Action;
use crate::channels::entry::{Entry, PreviewType, ENTRY_PLACEHOLDER};
use crate::channels::{
remote_control::{load_builtin_channels, RemoteControl},
OnAir, TelevisionChannel, UnitChannel,
};
use crate::config::{Config, KeyBindings, Theme}; use crate::config::{Config, KeyBindings, Theme};
use crate::input::convert_action_to_input_request; use crate::input::convert_action_to_input_request;
use crate::picker::Picker; use crate::picker::Picker;
use crate::preview::Previewer;
use crate::screen::cache::RenderedPreviewCache;
use crate::screen::colors::Colorscheme;
use crate::screen::help::draw_help_bar;
use crate::screen::input::draw_input_box;
use crate::screen::keybindings::{
build_keybindings_table, DisplayableAction, DisplayableKeybindings,
};
use crate::screen::layout::{Dimensions, InputPosition, Layout};
use crate::screen::mode::Mode;
use crate::screen::preview::draw_preview_content_block;
use crate::screen::remote_control::draw_remote_control;
use crate::screen::results::draw_results_list;
use crate::screen::spinner::{Spinner, SpinnerState};
use crate::utils::metadata::{AppMetadata, BuildMetadata};
use crate::utils::strings::EMPTY_STRING;
use crate::{cable::load_cable_channels, keymap::Keymap}; use crate::{cable::load_cable_channels, keymap::Keymap};
use color_eyre::Result; use color_eyre::Result;
use copypasta::{ClipboardContext, ClipboardProvider}; use copypasta::{ClipboardContext, ClipboardProvider};
@ -9,27 +30,6 @@ use ratatui::{layout::Rect, style::Color, Frame};
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use television_channels::channels::{
remote_control::{load_builtin_channels, RemoteControl},
OnAir, TelevisionChannel, UnitChannel,
};
use television_channels::entry::{Entry, PreviewType, ENTRY_PLACEHOLDER};
use television_previewers::previewers::Previewer;
use television_screen::cache::RenderedPreviewCache;
use television_screen::colors::Colorscheme;
use television_screen::help::draw_help_bar;
use television_screen::input::draw_input_box;
use television_screen::keybindings::{
build_keybindings_table, DisplayableAction, DisplayableKeybindings,
};
use television_screen::layout::{Dimensions, InputPosition, Layout};
use television_screen::mode::Mode;
use television_screen::preview::draw_preview_content_block;
use television_screen::remote_control::draw_remote_control;
use television_screen::results::draw_results_list;
use television_screen::spinner::{Spinner, SpinnerState};
use television_utils::metadata::{AppMetadata, BuildMetadata};
use television_utils::strings::EMPTY_STRING;
use tokio::sync::mpsc::UnboundedSender; use tokio::sync::mpsc::UnboundedSender;
pub struct Television { pub struct Television {

View File

@ -11,7 +11,7 @@ use tracing::debug;
/// ///
/// # Example /// # Example
/// ```rust /// ```rust
/// use television_utils::cache::RingSet; /// use television::utils::cache::RingSet;
/// ///
/// let mut ring_set = RingSet::with_capacity(3); /// let mut ring_set = RingSet::with_capacity(3);
/// // push 3 values into the ringset /// // push 3 values into the ringset

View File

@ -11,10 +11,10 @@ use ignore::{overrides::Override, types::TypesBuilder, WalkBuilder};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use tracing::{debug, warn}; use tracing::{debug, warn};
use crate::strings::{ use crate::utils::strings::{
proportion_of_printable_ascii_characters, PRINTABLE_ASCII_THRESHOLD, proportion_of_printable_ascii_characters, PRINTABLE_ASCII_THRESHOLD,
}; };
use crate::threads::default_num_threads; use crate::utils::threads::default_num_threads;
pub struct PartialReadResult { pub struct PartialReadResult {
pub lines: Vec<String>, pub lines: Vec<String>,

View File

@ -9,9 +9,9 @@ pub enum Shell {
Cmd, Cmd,
} }
const COMPLETION_ZSH: &str = include_str!("../shell/completion.zsh"); const COMPLETION_ZSH: &str = include_str!("shell/completion.zsh");
const COMPLETION_BASH: &str = include_str!("../shell/completion.bash"); const COMPLETION_BASH: &str = include_str!("shell/completion.bash");
const COMPLETION_FISH: &str = include_str!("../shell/completion.fish"); const COMPLETION_FISH: &str = include_str!("shell/completion.fish");
pub fn completion_script(shell: Shell) -> Result<&'static str> { pub fn completion_script(shell: Shell) -> Result<&'static str> {
match shell { match shell {

View File

@ -7,7 +7,7 @@ use lazy_static::lazy_static;
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::next_char_boundary; /// use television::utils::strings::next_char_boundary;
/// ///
/// let s = "Hello, World!"; /// let s = "Hello, World!";
/// assert_eq!(next_char_boundary(s, 0), 0); /// assert_eq!(next_char_boundary(s, 0), 0);
@ -41,7 +41,7 @@ pub fn next_char_boundary(s: &str, start: usize) -> usize {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::prev_char_boundary; /// use television::utils::strings::prev_char_boundary;
/// ///
/// let s = "Hello, World!"; /// let s = "Hello, World!";
/// assert_eq!(prev_char_boundary(s, 0), 0); /// assert_eq!(prev_char_boundary(s, 0), 0);
@ -68,7 +68,7 @@ pub fn prev_char_boundary(s: &str, start: usize) -> usize {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::slice_at_char_boundaries; /// use television::utils::strings::slice_at_char_boundaries;
/// ///
/// let s = "Hello, World!"; /// let s = "Hello, World!";
/// assert_eq!(slice_at_char_boundaries(s, 0, 0), ""); /// assert_eq!(slice_at_char_boundaries(s, 0, 0), "");
@ -102,7 +102,7 @@ pub fn slice_at_char_boundaries(
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::slice_up_to_char_boundary; /// use television::utils::strings::slice_up_to_char_boundary;
/// ///
/// let s = "Hello, World!"; /// let s = "Hello, World!";
/// assert_eq!(slice_up_to_char_boundary(s, 0), ""); /// assert_eq!(slice_up_to_char_boundary(s, 0), "");
@ -125,7 +125,7 @@ pub fn slice_up_to_char_boundary(s: &str, byte_index: usize) -> &str {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::try_parse_utf8_char; /// use television::utils::strings::try_parse_utf8_char;
/// ///
/// let input = b"Hello, World!"; /// let input = b"Hello, World!";
/// let (chr, n) = try_parse_utf8_char(input).unwrap(); /// let (chr, n) = try_parse_utf8_char(input).unwrap();
@ -253,7 +253,7 @@ fn is_emoji(ch: char) -> bool {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::{replace_non_printable, ReplaceNonPrintableConfig}; /// use television::utils::strings::{replace_non_printable, ReplaceNonPrintableConfig};
/// ///
/// let input = b"Hello, World!"; /// let input = b"Hello, World!";
/// let (output, offsets) = replace_non_printable(input, &ReplaceNonPrintableConfig::default()); /// let (output, offsets) = replace_non_printable(input, &ReplaceNonPrintableConfig::default());
@ -363,7 +363,7 @@ pub const PRINTABLE_ASCII_THRESHOLD: f32 = 0.7;
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::proportion_of_printable_ascii_characters; /// use television::utils::strings::proportion_of_printable_ascii_characters;
/// ///
/// let buffer = b"Hello, World!"; /// let buffer = b"Hello, World!";
/// let proportion = proportion_of_printable_ascii_characters(buffer); /// let proportion = proportion_of_printable_ascii_characters(buffer);
@ -396,7 +396,7 @@ const MAX_LINE_LENGTH: usize = 300;
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::preprocess_line; /// use television::utils::strings::preprocess_line;
/// ///
/// let line = "Hello, World!"; /// let line = "Hello, World!";
/// let (processed, offsets) = preprocess_line(line); /// let (processed, offsets) = preprocess_line(line);
@ -434,7 +434,7 @@ pub fn preprocess_line(line: &str) -> (String, Vec<i16>) {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::make_matched_string_printable; /// use television::utils::strings::make_matched_string_printable;
/// ///
/// let matched_string = "Hello, World!"; /// let matched_string = "Hello, World!";
/// let match_ranges = vec![(0, 1), (7, 8)]; /// let match_ranges = vec![(0, 1), (7, 8)];
@ -525,7 +525,7 @@ pub fn make_matched_string_printable(
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use television_utils::strings::shrink_with_ellipsis; /// use television::utils::strings::shrink_with_ellipsis;
/// ///
/// let s = "Hello, World!"; /// let s = "Hello, World!";
/// assert_eq!(shrink_with_ellipsis(s, 13), "Hello, World!"); /// assert_eq!(shrink_with_ellipsis(s, 13), "Hello, World!");