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

Added support for ANSI color in watched command output lines #76

Merged
merged 1 commit into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ repository = "https://github.com/fritzrehde/watchbind"
description = "A CLI menu for periodically watching a program's output and executing commands on its lines through keybindings"

[dependencies]
clap = { version = "4.4.7", default-features = false, features = ["std", "help", "cargo", "derive", "error-context"] }
clap = { version = "4.4.7", default-features = false, features = ["std", "help", "cargo", "derive", "error-context", "string", "color"] }
serde = { version = "1.0", default-features = false, features = ["derive"] }
toml = { version = "0.7.8", default-features = false, features = ["parse"] }
ratatui = "0.22.0"
crossterm = { version = "0.27", features = ["events", "event-stream"] }
itertools = "0.11.0"
anyhow = "1.0.75"
indoc = "2.0.4"
derive_more = { version = "0.99.17", default-features = false, features = ["from", "into_iterator", "as_ref"] }
derive_more = { version = "0.99.17", default-features = false, features = ["from", "into", "into_iterator", "as_ref"] }
tabwriter = "1.3.0"
parse-display = "0.8.2"
derive-new = "0.5.9"
Expand All @@ -28,6 +28,7 @@ ranges = "0.3.3"
# TODO: maybe we don't need all tokio and futures features, try to reduce
tokio = { version = "1.33.0", features = ["full"] }
futures = "0.3.29"
ansi-to-tui = "3.1.0"

# Config for 'cargo dist'
[workspace.metadata.dist]
Expand Down
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
- [Installation](#installation)
- [Customizations](#customizations)
- [Keybindings](#customizations)
- [Formatting with Field Separators and Selections](#formatting-with-field-separators-and-selections)
- [Formatting with Field Separators and Field Selections](#formatting-with-field-separators-and-field-selections)
- [Styling](#styling)
- [Tips](#tips)

Expand Down Expand Up @@ -157,10 +157,9 @@ tab

#### Operations

All supported `OP` values:

<!-- Make table of toml config reference name,example,description -->
<!-- TODO: Make table of toml config reference name,example,description -->

All supported `OP` values:

Operation | Description
:-- | :--
Expand All @@ -186,7 +185,7 @@ The environment variable `lines` set to all selected lines, or if none are selec
All set environment variables `ENV` will be made available in all future spawned commands/processes, including the watched command, any executed subcommands, as well as commands executed in `set-env` operations.
If multiple lines are selected, they will be separated by newlines in `lines`.

### Formatting with Field Separators and Selections
### Formatting with Field Separators and Field Selections

`watchbind` supports some extra formatting features reminiscent of the Unix `cut` command:

Expand All @@ -203,13 +202,19 @@ For instance, the field selection `1,3-4,6-` will display the first, third and f

### Styling

Foreground colors, background colors and boldness of the line the cursor is on, the header lines and all other lines can be customized.
Foreground colors, background colors and boldness can be customized.
These styling options are available for:
- The line the cursor is currently on with `cursor-[fg|bg|boldness]`.
- The header lines with `header-[fg|bg|boldness]`.
- All other lines with `non-cursor-non-header-[fg|bg|boldness]`.
- The selection indicator with `selected-bg`.

To see all available fields you can customize, run `watchbind -h`.
The names of the customization fields from the command-line options (e.g. `--cursor-fg blue`) are the same in the TOML config file (e.g. `cursor-fg = "blue"`).

Furthermore, `watchbind` also supports styling according to ANSI codes in the input text.

All supported `COLOR` values:
```
```sh
white
black
red
Expand All @@ -226,6 +231,15 @@ light_yellow
light_blue
light_magenta
light_cyan
reset # Reset the fg and bg
unspecified # Don't applying any styling => use style from ANSI input text
```

All supported `BOLDNESS` values:
```sh
bold # Make everything bold
non-bold # Make sure nothing is bold (i.e. remove any bold styling from input ANSI)
unspecified # Don't applying any styling => use style from ANSI input text
```

## Tips
Expand Down
7 changes: 3 additions & 4 deletions examples/fields.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ watched-command = """
printf \
"id,col1,col2,col3
123,v1,v2,v3
456,v4,v5,v6"
456,v4,v5,v6
789,v7,v8,v9"
"""
interval = 5.0
header-lines = 1
header-lines = 2
field-separator = ","
fields = "1,3-4"

[keybindings]
14 changes: 10 additions & 4 deletions examples/ls.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
watched-command = "ls"
interval = 3.0
bold = false
cursor-fg = "black"

# cursor line
cursor-bg = "blue"
cursor-bold = true
selected-bg = "red"
cursor-boldness = "bold"

# header lines
header-lines = 1
header-fg = "blue"
header-boldness = "non-bold"

# selected lines
selected-bg = "red"

[keybindings]
"esc" = [ "unselect-all", "help-hide" ]
Expand Down
5 changes: 2 additions & 3 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ pub struct Interruptible {
}

// Advantages of the Type-State Builder Pattern:
// 1. We don't have any option/enum (an alternative configuration strategy)
// checking overhead at runtime.
// 1. We don't have any option/enum checking (an alternative configuration
// strategy) overhead at runtime.
// 2. We can guarantee that we handled all possible Command "variants"
// (combination of config options), that we use, at compile-time.
// 3. Arguably, this also results in separated, cleaner code.
Expand All @@ -50,7 +50,6 @@ pub struct Interruptible {
/// environment variables, whether the output is captured and whether the
/// execution can be interrupted. Utilizes the type-state builder pattern to
/// enforce these configurations at compile-time.
// #[derive(Clone)]
pub struct CommandBuilder<B = NonBlocking, E = WithoutEnv, O = NoOutput, I = NonInterruptible> {
command: String,
blocking: B,
Expand Down
8 changes: 5 additions & 3 deletions src/config/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ impl Fields {
}
}

/// Format a string as a table that has its fields separated by an elastic
/// tabstop, and only displays the fields that should be selected.
/// Only applies any formatting if a separator or selection is present.
pub trait TableFormatter {
/// Format a string as a table that has its fields separated by an elastic
/// tabstop, and only displays the fields that should be selected.
/// Only applies any formatting if a field separator or a field selection
/// are present.
/// Returns `None` if no formatting was applied.
fn format_as_table(&self, fields: &Fields) -> Result<Option<String>>;
}

Expand Down
Loading