mirror of
https://github.com/FliegendeWurst/tmux-thumbs.git
synced 2024-11-24 05:45:00 +00:00
Capture pane with ANSI escape codes
Co-Authored-By: Ian Henry <ianthehenry@gmail.com>
This commit is contained in:
parent
ae91d5f7c0
commit
c0ed78beee
60
Cargo.lock
generated
60
Cargo.lock
generated
@ -91,6 +91,24 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.13"
|
||||
@ -126,6 +144,15 @@ version = "0.6.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "strip-ansi-escapes"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa"
|
||||
dependencies = [
|
||||
"vte",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
@ -161,22 +188,55 @@ dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"strip-ansi-escapes",
|
||||
"termion",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "vte"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
"vte_generate_state_changes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vte_generate_state_changes"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -15,6 +15,7 @@ clap = "2.34.0"
|
||||
base64 = "0.13.1"
|
||||
unicode-width = "0.1.10"
|
||||
lazy_static = "1.4.0"
|
||||
strip-ansi-escapes = "0.2.0"
|
||||
|
||||
[[bin]]
|
||||
name = "thumbs"
|
||||
|
24
README.md
24
README.md
@ -106,6 +106,7 @@ NOTE: for changes to take effect, you'll need to source again your `.tmux.conf`
|
||||
* [@thumbs-multi-bg-color](#thumbs-multi-bg-color)
|
||||
* [@thumbs-contrast](#thumbs-contrast)
|
||||
* [@thumbs-osc52](#thumbs-osc52)
|
||||
* [@thumbs-keep-colors](#thumbs-keep-colors)
|
||||
|
||||
### @thumbs-key
|
||||
|
||||
@ -344,6 +345,18 @@ For example:
|
||||
set -g @thumbs-osc52 1
|
||||
```
|
||||
|
||||
### @thumbs-keep-colors
|
||||
|
||||
`default: 0`
|
||||
|
||||
Keep text styling of the input when displaying matches.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
set -g @thumbs-keep-colors 1
|
||||
```
|
||||
|
||||
#### Colors
|
||||
|
||||
This is the list of predefined colors:
|
||||
@ -433,7 +446,7 @@ cargo install thumbs
|
||||
And those are all available options:
|
||||
|
||||
```
|
||||
thumbs 0.7.1
|
||||
thumbs 0.8.0
|
||||
A lightning fast version copy/pasting like vimium/vimperator
|
||||
|
||||
USAGE:
|
||||
@ -442,6 +455,7 @@ USAGE:
|
||||
FLAGS:
|
||||
-c, --contrast Put square brackets around hint for visibility
|
||||
-h, --help Prints help information
|
||||
--keep-colors Preserve text styling of input
|
||||
-m, --multi Enable multi-selection
|
||||
-r, --reverse Reverse the order for assigned hints
|
||||
-u, --unique Don't show duplicated hints for the same match
|
||||
@ -456,12 +470,16 @@ OPTIONS:
|
||||
|
||||
--hint-bg-color <hint_background_color> Sets the background color for hints [default: black]
|
||||
--hint-fg-color <hint_foreground_color> Sets the foregroud color for hints [default: yellow]
|
||||
--multi-bg-color <multi_background_color>
|
||||
Sets the background color for a multi selected item [default: black]
|
||||
|
||||
--multi-fg-color <multi_foreground_color>
|
||||
Sets the foreground color for a multi selected item [default: yellow]
|
||||
|
||||
-p, --position <position> Hint position [default: left]
|
||||
-x, --regexp <regexp>... Use this regexp as extra pattern to match
|
||||
--select-bg-color <select_background_color> Sets the background color for selection [default: black]
|
||||
--select-fg-color <select_foreground_color> Sets the foreground color for selection [default: blue]
|
||||
--multi-bg-color <multi_background_color> Sets the background color for a multi selected item [default: black]
|
||||
--multi-fg-color <multi_foreground_color> Sets the foreground color for a multi selected item [default: cyan]
|
||||
-t, --target <target> Stores the hint in the specified path
|
||||
```
|
||||
|
||||
|
20
src/main.rs
20
src/main.rs
@ -136,6 +136,11 @@ fn app_args<'a>() -> clap::ArgMatches<'a> {
|
||||
.short("t")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("keep-colors")
|
||||
.help("Preserve text styling of input")
|
||||
.long("keep-colors"),
|
||||
)
|
||||
.get_matches()
|
||||
}
|
||||
|
||||
@ -149,6 +154,7 @@ fn main() {
|
||||
let reverse = args.is_present("reverse");
|
||||
let unique = args.is_present("unique");
|
||||
let contrast = args.is_present("contrast");
|
||||
let keep_colors = args.is_present("keep-colors");
|
||||
let regexp = if let Some(items) = args.values_of("regexp") {
|
||||
items.collect::<Vec<_>>()
|
||||
} else {
|
||||
@ -172,7 +178,19 @@ fn main() {
|
||||
|
||||
let lines = output.split('\n').collect::<Vec<&str>>();
|
||||
|
||||
let mut state = state::State::new(&lines, alphabet, ®exp);
|
||||
let mut state;
|
||||
// strip ansi color codes for match searching
|
||||
let unescaped: Vec<_> = lines
|
||||
.iter()
|
||||
.map(|line| String::from_utf8(strip_ansi_escapes::strip(line)).unwrap())
|
||||
.collect();
|
||||
let reference = unescaped.iter().map(|x| &**x).collect();
|
||||
|
||||
if keep_colors {
|
||||
state = state::State::new_extended(&lines, reference, alphabet, ®exp);
|
||||
} else {
|
||||
state = state::State::new_extended(&reference, reference.clone(), alphabet, ®exp);
|
||||
}
|
||||
|
||||
let selected = {
|
||||
let mut viewbox = view::View::new(
|
||||
|
20
src/state.rs
20
src/state.rs
@ -56,19 +56,36 @@ impl<'a> PartialEq for Match<'a> {
|
||||
|
||||
pub struct State<'a> {
|
||||
pub lines: &'a Vec<&'a str>,
|
||||
pub unescaped: Vec<&'a str>,
|
||||
alphabet: &'a str,
|
||||
regexp: &'a Vec<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a> State<'a> {
|
||||
#[cfg(test)]
|
||||
pub fn new(lines: &'a Vec<&'a str>, alphabet: &'a str, regexp: &'a Vec<&'a str>) -> State<'a> {
|
||||
State {
|
||||
unescaped: lines.clone(),
|
||||
lines,
|
||||
alphabet,
|
||||
regexp,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_extended(
|
||||
lines: &'a Vec<&'a str>,
|
||||
unescaped: Vec<&'a str>,
|
||||
alphabet: &'a str,
|
||||
regexp: &'a Vec<&'a str>,
|
||||
) -> State<'a> {
|
||||
State {
|
||||
lines,
|
||||
unescaped,
|
||||
alphabet,
|
||||
regexp,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn matches(&self, reverse: bool, unique: bool) -> Vec<Match<'a>> {
|
||||
let mut matches = Vec::new();
|
||||
|
||||
@ -91,8 +108,7 @@ impl<'a> State<'a> {
|
||||
// This order determines the priority of pattern matching
|
||||
let all_patterns = [exclude_patterns, custom_patterns, patterns].concat();
|
||||
|
||||
for (index, line) in self.lines.iter().enumerate() {
|
||||
let mut chunk: &str = line;
|
||||
for (index, &(mut chunk)) in self.unescaped.iter().enumerate() {
|
||||
let mut offset: i32 = 0;
|
||||
|
||||
loop {
|
||||
|
@ -164,7 +164,7 @@ impl<'a> Swapper<'a> {
|
||||
let name = captures.get(1).unwrap().as_str();
|
||||
let value = captures.get(2).unwrap().as_str();
|
||||
|
||||
let boolean_params = vec!["reverse", "unique", "contrast"];
|
||||
let boolean_params = vec!["reverse", "unique", "contrast", "keep-colors"];
|
||||
|
||||
if boolean_params.iter().any(|&x| x == name) {
|
||||
return vec![format!("--{}", name)];
|
||||
@ -215,7 +215,7 @@ impl<'a> Swapper<'a> {
|
||||
};
|
||||
|
||||
let pane_command = format!(
|
||||
"tmux capture-pane -J -t {active_pane_id} -p{scroll_params} | tail -n {height} | {dir}/target/release/thumbs -f '%U:%H' -t {tmp} {args}; tmux swap-pane -t {active_pane_id}; {zoom_command} tmux wait-for -S {signal}",
|
||||
"tmux capture-pane -J -et {active_pane_id} -p{scroll_params} | tail -n {height} | {dir}/target/release/thumbs -f '%U:%H' -t {tmp} {args}; tmux swap-pane -t {active_pane_id}; {zoom_command} tmux wait-for -S {signal}",
|
||||
active_pane_id = active_pane_id,
|
||||
scroll_params = scroll_params,
|
||||
height = self.active_pane_height.unwrap_or(i32::MAX),
|
||||
|
@ -124,7 +124,7 @@ impl<'a> View<'a> {
|
||||
};
|
||||
|
||||
// Find long utf sequences and extract it from mat.x
|
||||
let line = &self.state.lines[mat.y as usize];
|
||||
let line = &self.state.unescaped[mat.y as usize];
|
||||
let prefix = &line[0..mat.x as usize];
|
||||
let extra = prefix.width_cjk() - prefix.chars().count();
|
||||
let offset = (mat.x as u16) - (extra as u16);
|
||||
|
Loading…
Reference in New Issue
Block a user