mirror of
https://github.com/lotabout/skim.git
synced 2026-09-10 07:16:23 -04:00
feat!: use smarter setters, remove the need for Some(...) and String::from() in setters
This commit is contained in:
parent
495b9ae611
commit
d11e627ba6
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
|
@ -57,6 +57,8 @@ jobs:
|
|||
tool: cargo-llvm-cov@0.8
|
||||
- name: Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
- name: Run doctests
|
||||
run: cargo test --doc
|
||||
- name: Run tests
|
||||
run: cargo llvm-cov nextest --release --features test-utils --all-targets --codecov --output-path codecov.json
|
||||
env:
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ use skim::{prelude::*, reader::CommandCollector};
|
|||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let glogm = Some(String::from("git log --oneline --color=always | head -n10"));
|
||||
let glogm = "git log --oneline --color=always | head -n10";
|
||||
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.height(String::from("50%"))
|
||||
.height("50%")
|
||||
.cmd(glogm)
|
||||
.preview(Some(String::from("echo {}")))
|
||||
.preview("echo {}")
|
||||
.multi(true)
|
||||
.reverse(true)
|
||||
.cmd_collector(Rc::new(RefCell::new(SkimItemReader::new(
|
||||
|
|
@ -25,6 +25,6 @@ pub fn main() {
|
|||
.unwrap_or_default();
|
||||
|
||||
for item in selected_items.iter() {
|
||||
print!("selected: {}{}", item.output(), "\n");
|
||||
println!("selected: {}", item.output());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ use std::io::Cursor;
|
|||
/// 1. Create custom action callbacks
|
||||
/// 2. Bind them to specific key combinations
|
||||
/// 3. Use them interactively in skim
|
||||
|
||||
fn main() {
|
||||
// Create a custom callback that adds a prefix to the query
|
||||
let add_prefix_callback = ActionCallback::new(|app: &mut skim::tui::App<'static>| {
|
||||
|
|
@ -46,10 +45,8 @@ fn main() {
|
|||
// Build basic options
|
||||
let mut options = SkimOptionsBuilder::default()
|
||||
.multi(true)
|
||||
.prompt("Select> ".to_string())
|
||||
.header(Some(String::from(
|
||||
"<C-p>: add prefix to prompt\t<C-a>: select all and exit with count",
|
||||
)))
|
||||
.prompt("Select> ")
|
||||
.header("<C-p>: add prefix to prompt\t<C-a>: select all and exit with count")
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
|
@ -69,7 +66,7 @@ fn main() {
|
|||
);
|
||||
|
||||
// Create sample items
|
||||
let items = vec![
|
||||
let items = [
|
||||
"Write documentation",
|
||||
"Fix bug #123",
|
||||
"Implement feature X",
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ impl SkimItem for MyItem {
|
|||
|
||||
fn main() {
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.height(String::from("50%"))
|
||||
.height("50%")
|
||||
.multi(true)
|
||||
.preview(Some(String::new())) // preview should be specified to enable preview window
|
||||
.preview(String::new()) // preview should be specified to enable preview window
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ impl SkimItem for Item {
|
|||
|
||||
pub fn main() {
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.height(String::from("50%"))
|
||||
.height("50%")
|
||||
.multi(true)
|
||||
.preview(Some(String::new()))
|
||||
.preview("")
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
|
@ -40,15 +40,15 @@ pub fn main() {
|
|||
|
||||
tx.send(vec![
|
||||
Arc::new(Item {
|
||||
text: "a".to_string(),
|
||||
text: "a".into(),
|
||||
index: 0,
|
||||
}) as Arc<dyn SkimItem>,
|
||||
Arc::new(Item {
|
||||
text: "b".to_string(),
|
||||
text: "b".into(),
|
||||
index: 1,
|
||||
}) as Arc<dyn SkimItem>,
|
||||
Arc::new(Item {
|
||||
text: "c".to_string(),
|
||||
text: "c".into(),
|
||||
index: 2,
|
||||
}) as Arc<dyn SkimItem>,
|
||||
])
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
if &pattern == "" {
|
||||
if pattern.is_empty() {
|
||||
eprintln!("Usage: echo <piped_input> | fz --algo [skim|clangd] <pattern>");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -36,10 +36,10 @@ pub fn main() {
|
|||
|
||||
let stdin = io::stdin();
|
||||
for line in stdin.lock().lines() {
|
||||
if let Ok(line) = line {
|
||||
if let Some((score, indices)) = matcher.fuzzy_indices(&line, &pattern) {
|
||||
println!("{:8}: {}", score, wrap_matches(&line, &indices));
|
||||
}
|
||||
if let Ok(line) = line
|
||||
&& let Some((score, indices)) = matcher.fuzzy_indices(&line, &pattern)
|
||||
{
|
||||
println!("{:8}: {}", score, wrap_matches(&line, &indices));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ use skim::{Skim, prelude::SkimOptionsBuilder};
|
|||
fn main() {
|
||||
for i in 0..3 {
|
||||
let opts = SkimOptionsBuilder::default()
|
||||
.header(Some(format!("run {i}")))
|
||||
.header(format!("run {i}"))
|
||||
.build()
|
||||
.unwrap();
|
||||
let res = Skim::run_with(opts, None).unwrap();
|
||||
println!(
|
||||
"run {i}: {:?}, sleeping for 5 secs",
|
||||
res.selected_items.iter().next().map(|x| x.output())
|
||||
res.selected_items.first().map(|x| x.output())
|
||||
);
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ use std::io::Cursor;
|
|||
pub fn main() {
|
||||
let input = "foo 123";
|
||||
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.query(Some(String::from("f")))
|
||||
.build()
|
||||
.unwrap();
|
||||
let options = SkimOptionsBuilder::default().query("f").build().unwrap();
|
||||
let item_reader = SkimItemReader::new(SkimItemReaderOption::default().nth(vec!["2"].into_iter()).build());
|
||||
|
||||
let items = item_reader.of_bufread(Cursor::new(input));
|
||||
|
|
|
|||
|
|
@ -7,11 +7,7 @@ pub fn main() {
|
|||
|
||||
//==================================================
|
||||
// first run
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.height(String::from("50%"))
|
||||
.multi(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
let options = SkimOptionsBuilder::default().height("50%").multi(true).build().unwrap();
|
||||
let input = "aaaaa\nbbbb\nccc";
|
||||
let items = item_reader.of_bufread(Cursor::new(input));
|
||||
let selected_items = Skim::run_with(options, Some(items))
|
||||
|
|
@ -24,11 +20,7 @@ pub fn main() {
|
|||
|
||||
//==================================================
|
||||
// second run
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.height(String::from("50%"))
|
||||
.multi(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
let options = SkimOptionsBuilder::default().height("50%").multi(true).build().unwrap();
|
||||
let input = "11111\n22222\n333333333";
|
||||
let items = item_reader.of_bufread(Cursor::new(input));
|
||||
let selected_items = Skim::run_with(options, Some(items))
|
||||
|
|
|
|||
|
|
@ -6,12 +6,9 @@ pub fn main() {
|
|||
env_logger::init();
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.multi(true)
|
||||
.preview_fn(Some(PreviewCallback::from(|items: Vec<Arc<dyn SkimItem>>| {
|
||||
items
|
||||
.iter()
|
||||
.map(|s| s.text().to_ascii_uppercase().into())
|
||||
.collect::<Vec<_>>()
|
||||
})))
|
||||
.preview_fn(PreviewCallback::from(|items: Vec<Arc<dyn SkimItem>>| {
|
||||
items.iter().map(|s| s.text().to_ascii_uppercase()).collect::<Vec<_>>()
|
||||
}))
|
||||
.build()
|
||||
.unwrap();
|
||||
let item_reader = SkimItemReader::default();
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@ fn main() {
|
|||
drop(sender); // bug replicates even without this
|
||||
|
||||
let _ = Skim::run_with(
|
||||
SkimOptions {
|
||||
multi: true,
|
||||
..Default::default()
|
||||
},
|
||||
SkimOptionsBuilder::default().multi(true).build().unwrap(),
|
||||
Some(receiver),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ pub fn main() {
|
|||
};
|
||||
let options = SkimOptionsBuilder::default()
|
||||
.multi(true)
|
||||
.selector(Some(Rc::from(selector)))
|
||||
.query(Some(String::from("skim/")))
|
||||
.selector(Rc::from(selector))
|
||||
.query("skim/")
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
|
|
|||
2
justfile
2
justfile
|
|
@ -23,6 +23,6 @@ release version: (bump-version version) generate-files (changelog version) test
|
|||
auto-release:
|
||||
just release $(git cliff --bumped-version | sed 's/v\(.*\)/\1/')
|
||||
|
||||
test target="":
|
||||
test target="--all-targets":
|
||||
-cargo nextest run --release --features test-utils {{ target }}
|
||||
tmux kill-session -t skim_e2e
|
||||
|
|
|
|||
|
|
@ -307,12 +307,12 @@ When using skim as a library, this has no effect and ansi parsing should be enab
|
|||
use skim::prelude::*;
|
||||
|
||||
let _options = SkimOptionsBuilder::default()
|
||||
.cmd(ls \-\-color)
|
||||
.cmd("ls \-\-color")
|
||||
.cmd_collector(Rc::new(RefCell::new(SkimItemReader::new(
|
||||
SkimItemReaderOption::default().ansi(true),
|
||||
))) as Rc<RefCell<dyn CommandCollector>>)
|
||||
.build()
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
.TP
|
||||
\fB\-\-tabstop\fR \fI<TABSTOP>\fR [default: 8]
|
||||
|
|
@ -321,9 +321,9 @@ Number of spaces that make up a tab
|
|||
\fB\-\-info\fR \fI<INFO>\fR [default: default]
|
||||
Set matching result count display position
|
||||
|
||||
hidden: do not display info
|
||||
inline: display info in the same row as the input
|
||||
default: display info in a dedicated row above the input
|
||||
\- hidden: do not display info
|
||||
\- inline: display info in the same row as the input
|
||||
\- default: display info in a dedicated row above the input
|
||||
.br
|
||||
|
||||
.br
|
||||
|
|
@ -428,6 +428,7 @@ Examples:
|
|||
sk \-\-delimiter : \\
|
||||
\-\-preview \*(Aqbat \-\-style=numbers \-\-color=always \-\-highlight\-line {2} {1}\*(Aq \\
|
||||
\-\-preview\-window +{2}\-/2
|
||||
|
||||
.SH SCRIPTING
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-query\fR \fI<QUERY>\fR
|
||||
|
|
@ -466,9 +467,7 @@ Do not enter the TUI if the query passed in \-q does not match any item
|
|||
\fB\-\-sync\fR
|
||||
Synchronous search for multi\-staged filtering
|
||||
|
||||
Synchronous search for multi\-staged filtering. If specified, skim will launch ncurses finder only after the input stream is complete.
|
||||
|
||||
e.g. sk \-\-multi | sk \-\-sync
|
||||
Synchronous search for multi\-staged filtering. If specified, skim will launch ncurses finder only after the input stream is complete. e.g. sk \-\-multi | sk \-\-sync
|
||||
.TP
|
||||
\fB\-\-pre\-select\-n\fR \fI<PRE_SELECT_N>\fR [default: 0]
|
||||
Pre\-select the first n items in multi\-selection mode
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ _sk() {
|
|||
|
||||
case "${cmd}" in
|
||||
sk)
|
||||
opts="-t -n -d -e -b -m -c -i -I -p -q -1 -0 -f -x -h -V --tac --min-query-length --no-sort --tiebreak --nth --with-nth --delimiter --exact --regex --algo --case --normalize --split-match --bind --multi --no-multi --no-mouse --cmd --interactive --color --no-hscroll --keep-right --skip-to-pattern --no-clear-if-empty --no-clear-start --no-clear --show-cmd-error --cycle --disabled --layout --reverse --height --no-height --min-height --margin --prompt --cmd-prompt --selector --multi-selector --ansi --tabstop --info --no-info --inline-info --header --header-lines --border --wrap --history --history-size --cmd-history --cmd-history-size --preview --preview-window --query --cmd-query --read0 --print0 --print-query --print-cmd --print-score --print-header --no-strip-ansi --select-1 --exit-0 --sync --pre-select-n --pre-select-pat --pre-select-items --pre-select-file --filter --shell --shell-bindings --man --listen --remote --tmux --log-file --flags --extended --literal --hscroll-off --filepath-word --jump-labels --no-bold --phony --expect --help --version"
|
||||
opts="-t -n -d -e -b -m -c -i -I -p -q -1 -0 -f -x -h -V --tac --min-query-length --no-sort --tiebreak --nth --with-nth --delimiter --exact --regex --algo --case --normalize --split-match --bind --multi --no-multi --no-mouse --cmd --interactive --color --no-hscroll --keep-right --skip-to-pattern --no-clear-if-empty --no-clear-start --no-clear --show-cmd-error --cycle --disabled --layout --reverse --height --no-height --min-height --margin --prompt --cmd-prompt --selector --multi-selector --ansi --tabstop --info --no-info --inline-info --header --header-lines --border --wrap --history --history-size --cmd-history --cmd-history-size --preview --preview-window --query --cmd-query --read0 --print0 --print-query --print-cmd --print-score --print-header --no-strip-ansi --select-1 --exit-0 --sync --pre-select-n --pre-select-pat --pre-select-items --pre-select-file --filter --shell --shell-bindings --man --listen --remote --tmux --log-file --flags --extended --literal --hscroll-off --filepath-word --jump-labels --no-bold --phony --scheme --tail --style --no-color --padding --border-label --border-label-pos --highlight-line --wrap-sign --no-multi-line --raw --track --gap --gap-line --freeze-left --freeze-right --scroll-off --gutter --gutter-raw --marker-multi-line --ellipsis --scrollbar --no-scrollbar --list-border --list-label --list-label-pos --no-input --info-command --separator --no-separator --ghost --input-border --input-label --input-label-pos --preview-label --preview-label-pos --header-first --header-border --header-lines-border --footer --footer-border --footer-label --footer-label-pos --with-shell --expect --help --version"
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
|
@ -249,6 +249,146 @@ _sk() {
|
|||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--scheme)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--tail)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--style)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--padding)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--border-label)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--border-label-pos)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--wrap-sign)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--gap)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--gap-line)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--freeze-left)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--freeze-right)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--scroll-off)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--gutter)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--gutter-raw)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--marker-multi-line)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--ellipsis)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--scrollbar)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--list-border)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--list-label)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--list-label-pos)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--info-command)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--separator)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--ghost)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--input-border)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--input-label)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--input-label-pos)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--preview-label)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--preview-label-pos)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--header-border)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--header-lines-border)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--footer)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--footer-border)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--footer-label)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--footer-label-pos)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--with-shell)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--expect)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -77,8 +77,43 @@ complete -c sk -l remote -d 'Send commands to an IPC socket with optional name (
|
|||
complete -c sk -l tmux -d 'Run in a tmux popup' -r
|
||||
complete -c sk -l log-file -d 'Pipe log output to a file' -r
|
||||
complete -c sk -l flags -d 'Feature flags' -r -f -a "no-preview-pty\t'Disable preview PTY on linux'"
|
||||
complete -c sk -l hscroll-off -d 'Reserved for later use' -r
|
||||
complete -c sk -l jump-labels -d 'Reserved for later use' -r
|
||||
complete -c sk -l hscroll-off -r
|
||||
complete -c sk -l jump-labels -r
|
||||
complete -c sk -l scheme -r
|
||||
complete -c sk -l tail -r
|
||||
complete -c sk -l style -r
|
||||
complete -c sk -l padding -r
|
||||
complete -c sk -l border-label -r
|
||||
complete -c sk -l border-label-pos -r
|
||||
complete -c sk -l wrap-sign -r
|
||||
complete -c sk -l gap -r
|
||||
complete -c sk -l gap-line -r
|
||||
complete -c sk -l freeze-left -r
|
||||
complete -c sk -l freeze-right -r
|
||||
complete -c sk -l scroll-off -r
|
||||
complete -c sk -l gutter -r
|
||||
complete -c sk -l gutter-raw -r
|
||||
complete -c sk -l marker-multi-line -r
|
||||
complete -c sk -l ellipsis -r
|
||||
complete -c sk -l scrollbar -r
|
||||
complete -c sk -l list-border -r
|
||||
complete -c sk -l list-label -r
|
||||
complete -c sk -l list-label-pos -r
|
||||
complete -c sk -l info-command -r
|
||||
complete -c sk -l separator -r
|
||||
complete -c sk -l ghost -r
|
||||
complete -c sk -l input-border -r
|
||||
complete -c sk -l input-label -r
|
||||
complete -c sk -l input-label-pos -r
|
||||
complete -c sk -l preview-label -r
|
||||
complete -c sk -l preview-label-pos -r
|
||||
complete -c sk -l header-border -r
|
||||
complete -c sk -l header-lines-border -r
|
||||
complete -c sk -l footer -r
|
||||
complete -c sk -l footer-border -r
|
||||
complete -c sk -l footer-label -r
|
||||
complete -c sk -l footer-label-pos -r
|
||||
complete -c sk -l with-shell -r
|
||||
complete -c sk -l expect -d 'Deprecated, kept for compatibility purposes. See accept() bind instead' -r
|
||||
complete -c sk -l tac -d 'Show results in reverse order'
|
||||
complete -c sk -l no-sort -d 'Do not sort the results'
|
||||
|
|
@ -115,10 +150,19 @@ complete -c sk -s 0 -l exit-0 -d 'Do not enter the TUI if the query passed in -q
|
|||
complete -c sk -l sync -d 'Synchronous search for multi-staged filtering'
|
||||
complete -c sk -l shell-bindings -d 'Generate shell key bindings - only for bash, zsh and fish'
|
||||
complete -c sk -l man -d 'Generate man page and output it to stdout'
|
||||
complete -c sk -s x -l extended -d 'Reserved for later use'
|
||||
complete -c sk -l literal -d 'Reserved for later use'
|
||||
complete -c sk -l filepath-word -d 'Reserved for later use'
|
||||
complete -c sk -l no-bold -d 'Reserved for later use'
|
||||
complete -c sk -l phony -d 'Reserved for later use'
|
||||
complete -c sk -s x -l extended
|
||||
complete -c sk -l literal
|
||||
complete -c sk -l filepath-word
|
||||
complete -c sk -l no-bold
|
||||
complete -c sk -l phony
|
||||
complete -c sk -l no-color
|
||||
complete -c sk -l highlight-line
|
||||
complete -c sk -l no-multi-line
|
||||
complete -c sk -l raw
|
||||
complete -c sk -l track
|
||||
complete -c sk -l no-scrollbar
|
||||
complete -c sk -l no-input
|
||||
complete -c sk -l no-separator
|
||||
complete -c sk -l header-first
|
||||
complete -c sk -s h -l help -d 'Print help (see more with \'--help\')'
|
||||
complete -c sk -s V -l version -d 'Print version'
|
||||
|
|
|
|||
|
|
@ -114,13 +114,57 @@ module completions {
|
|||
--tmux: string # Run in a tmux popup
|
||||
--log-file: string # Pipe log output to a file
|
||||
--flags: string@"nu-complete sk flags" # Feature flags
|
||||
--extended(-x) # Reserved for later use
|
||||
--literal # Reserved for later use
|
||||
--hscroll-off: string # Reserved for later use
|
||||
--filepath-word # Reserved for later use
|
||||
--jump-labels: string # Reserved for later use
|
||||
--no-bold # Reserved for later use
|
||||
--phony # Reserved for later use
|
||||
--extended(-x)
|
||||
--literal
|
||||
--hscroll-off: string
|
||||
--filepath-word
|
||||
--jump-labels: string
|
||||
--no-bold
|
||||
--phony
|
||||
--scheme: string
|
||||
--tail: string
|
||||
--style: string
|
||||
--no-color
|
||||
--padding: string
|
||||
--border-label: string
|
||||
--border-label-pos: string
|
||||
--highlight-line
|
||||
--wrap-sign: string
|
||||
--no-multi-line
|
||||
--raw
|
||||
--track
|
||||
--gap: string
|
||||
--gap-line: string
|
||||
--freeze-left: string
|
||||
--freeze-right: string
|
||||
--scroll-off: string
|
||||
--gutter: string
|
||||
--gutter-raw: string
|
||||
--marker-multi-line: string
|
||||
--ellipsis: string
|
||||
--scrollbar: string
|
||||
--no-scrollbar
|
||||
--list-border: string
|
||||
--list-label: string
|
||||
--list-label-pos: string
|
||||
--no-input
|
||||
--info-command: string
|
||||
--separator: string
|
||||
--no-separator
|
||||
--ghost: string
|
||||
--input-border: string
|
||||
--input-label: string
|
||||
--input-label-pos: string
|
||||
--preview-label: string
|
||||
--preview-label-pos: string
|
||||
--header-first
|
||||
--header-border: string
|
||||
--header-lines-border: string
|
||||
--footer: string
|
||||
--footer-border: string
|
||||
--footer-label: string
|
||||
--footer-label-pos: string
|
||||
--with-shell: string
|
||||
--expect: string # Deprecated, kept for compatibility purposes. See accept() bind instead
|
||||
--help(-h) # Print help (see more with '--help')
|
||||
--version(-V) # Print version
|
||||
|
|
|
|||
|
|
@ -80,8 +80,43 @@ zsh\:"Zsh"))' \
|
|||
'--tmux=[Run in a tmux popup]::TMUX:_default' \
|
||||
'--log-file=[Pipe log output to a file]:LOG_FILE:_default' \
|
||||
'*--flags=[Feature flags]:FLAGS:((no-preview-pty\:"Disable preview PTY on linux"))' \
|
||||
'--hscroll-off=[Reserved for later use]:HSCROLL_OFF:_default' \
|
||||
'--jump-labels=[Reserved for later use]:JUMP_LABELS:_default' \
|
||||
'--hscroll-off=[]:HSCROLL_OFF:_default' \
|
||||
'--jump-labels=[]:JUMP_LABELS:_default' \
|
||||
'--scheme=[]:SCHEME:_default' \
|
||||
'--tail=[]:TAIL:_default' \
|
||||
'--style=[]:STYLE:_default' \
|
||||
'--padding=[]:PADDING:_default' \
|
||||
'--border-label=[]:BORDER_LABEL:_default' \
|
||||
'--border-label-pos=[]:BORDER_LABEL_POS:_default' \
|
||||
'--wrap-sign=[]:WRAP_SIGN:_default' \
|
||||
'--gap=[]:GAP:_default' \
|
||||
'--gap-line=[]:GAP_LINE:_default' \
|
||||
'--freeze-left=[]:FREEZE_LEFT:_default' \
|
||||
'--freeze-right=[]:FREEZE_RIGHT:_default' \
|
||||
'--scroll-off=[]:SCROLL_OFF:_default' \
|
||||
'--gutter=[]:GUTTER:_default' \
|
||||
'--gutter-raw=[]:GUTTER_RAW:_default' \
|
||||
'--marker-multi-line=[]:MARKER_MULTI_LINE:_default' \
|
||||
'--ellipsis=[]:ELLIPSIS:_default' \
|
||||
'--scrollbar=[]:SCROLLBAR:_default' \
|
||||
'--list-border=[]:LIST_BORDER:_default' \
|
||||
'--list-label=[]:LIST_LABEL:_default' \
|
||||
'--list-label-pos=[]:LIST_LABEL_POS:_default' \
|
||||
'--info-command=[]:INFO_COMMAND:_default' \
|
||||
'--separator=[]:SEPARATOR:_default' \
|
||||
'--ghost=[]:GHOST:_default' \
|
||||
'--input-border=[]:INPUT_BORDER:_default' \
|
||||
'--input-label=[]:INPUT_LABEL:_default' \
|
||||
'--input-label-pos=[]:INPUT_LABEL_POS:_default' \
|
||||
'--preview-label=[]:PREVIEW_LABEL:_default' \
|
||||
'--preview-label-pos=[]:PREVIEW_LABEL_POS:_default' \
|
||||
'--header-border=[]:HEADER_BORDER:_default' \
|
||||
'--header-lines-border=[]:HEADER_LINES_BORDER:_default' \
|
||||
'--footer=[]:FOOTER:_default' \
|
||||
'--footer-border=[]:FOOTER_BORDER:_default' \
|
||||
'--footer-label=[]:FOOTER_LABEL:_default' \
|
||||
'--footer-label-pos=[]:FOOTER_LABEL_POS:_default' \
|
||||
'--with-shell=[]:WITH_SHELL:_default' \
|
||||
'--expect=[Deprecated, kept for compatibility purposes. See accept() bind instead]:EXPECT:_default' \
|
||||
'--tac[Show results in reverse order]' \
|
||||
'--no-sort[Do not sort the results]' \
|
||||
|
|
@ -123,12 +158,21 @@ zsh\:"Zsh"))' \
|
|||
'--sync[Synchronous search for multi-staged filtering]' \
|
||||
'--shell-bindings[Generate shell key bindings - only for bash, zsh and fish]' \
|
||||
'--man[Generate man page and output it to stdout]' \
|
||||
'-x[Reserved for later use]' \
|
||||
'--extended[Reserved for later use]' \
|
||||
'--literal[Reserved for later use]' \
|
||||
'--filepath-word[Reserved for later use]' \
|
||||
'--no-bold[Reserved for later use]' \
|
||||
'--phony[Reserved for later use]' \
|
||||
'-x[]' \
|
||||
'--extended[]' \
|
||||
'--literal[]' \
|
||||
'--filepath-word[]' \
|
||||
'--no-bold[]' \
|
||||
'--phony[]' \
|
||||
'--no-color[]' \
|
||||
'--highlight-line[]' \
|
||||
'--no-multi-line[]' \
|
||||
'--raw[]' \
|
||||
'--track[]' \
|
||||
'--no-scrollbar[]' \
|
||||
'--no-input[]' \
|
||||
'--no-separator[]' \
|
||||
'--header-first[]' \
|
||||
'-h[Print help (see more with '\''--help'\'')]' \
|
||||
'--help[Print help (see more with '\''--help'\'')]' \
|
||||
'-V[Print version]' \
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
//! https://github.com/llvm-mirror/clang-tools-extra/blob/master/clangd/FuzzyMatch.cpp
|
||||
//!
|
||||
//! # Example:
|
||||
//! ```edition2018
|
||||
//! use crate::fuzzy_matcher::FuzzyMatcher;
|
||||
//! use crate::fuzzy_matcher::clangd::ClangdMatcher;
|
||||
//! ```
|
||||
//! use skim::fuzzy_matcher::FuzzyMatcher;
|
||||
//! use skim::fuzzy_matcher::clangd::ClangdMatcher;
|
||||
//!
|
||||
//! let matcher = ClangdMatcher::default();
|
||||
//!
|
||||
|
|
@ -419,6 +419,38 @@ fn match_bonus(
|
|||
score
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn print_dp(line: &str, pattern: &str, dp: &[Vec<Score>]) {
|
||||
let num_line_chars = line.chars().count();
|
||||
let num_pattern_chars = pattern.chars().count();
|
||||
|
||||
print!("\t");
|
||||
for (idx, ch) in line.chars().enumerate() {
|
||||
print!("\t\t{}/{}", idx + 1, ch);
|
||||
}
|
||||
|
||||
for (row_num, row) in dp.iter().enumerate().take(num_pattern_chars + 1) {
|
||||
print!("\n{}\t", row_num);
|
||||
for cell in row.iter().take(num_line_chars + 1) {
|
||||
print!(
|
||||
"({},{})/({},{})\t",
|
||||
cell.miss_score,
|
||||
if cell.last_action_miss == Action::Miss {
|
||||
'X'
|
||||
} else {
|
||||
'O'
|
||||
},
|
||||
cell.match_score,
|
||||
if cell.last_action_match == Action::Miss {
|
||||
'X'
|
||||
} else {
|
||||
'O'
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg_attr(coverage, coverage(off))]
|
||||
mod tests {
|
||||
|
|
@ -474,35 +506,3 @@ mod tests {
|
|||
assert_order(&matcher, "Int", &["int", "INT", "PRINT"]);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn print_dp(line: &str, pattern: &str, dp: &[Vec<Score>]) {
|
||||
let num_line_chars = line.chars().count();
|
||||
let num_pattern_chars = pattern.chars().count();
|
||||
|
||||
print!("\t");
|
||||
for (idx, ch) in line.chars().enumerate() {
|
||||
print!("\t\t{}/{}", idx + 1, ch);
|
||||
}
|
||||
|
||||
for (row_num, row) in dp.iter().enumerate().take(num_pattern_chars + 1) {
|
||||
print!("\n{}\t", row_num);
|
||||
for cell in row.iter().take(num_line_chars + 1) {
|
||||
print!(
|
||||
"({},{})/({},{})\t",
|
||||
cell.miss_score,
|
||||
if cell.last_action_miss == Action::Miss {
|
||||
'X'
|
||||
} else {
|
||||
'O'
|
||||
},
|
||||
cell.match_score,
|
||||
if cell.last_action_match == Action::Miss {
|
||||
'X'
|
||||
} else {
|
||||
'O'
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
//! The fuzzy matching algorithm used by skim
|
||||
//!
|
||||
//! # Example:
|
||||
//! ```edition2018
|
||||
//! use crate::fuzzy_matcher::FuzzyMatcher;
|
||||
//! use crate::fuzzy_matcher::skim::SkimMatcherV2;
|
||||
//! ```
|
||||
//! use skim::fuzzy_matcher::FuzzyMatcher;
|
||||
//! use skim::fuzzy_matcher::skim::SkimMatcherV2;
|
||||
//!
|
||||
//! let matcher = SkimMatcherV2::default();
|
||||
//! assert_eq!(None, matcher.fuzzy_match("abc", "abx"));
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ pub struct DefaultSkimItemMetadata {
|
|||
ansi_info: Option<Vec<(usize, usize)>>,
|
||||
|
||||
// The ranges on which to perform matching
|
||||
#[allow(clippy::box_collection)]
|
||||
matching_ranges: Option<Vec<(usize, usize)>>,
|
||||
}
|
||||
|
||||
|
|
@ -852,7 +851,7 @@ mod test {
|
|||
let line = item.display(context);
|
||||
|
||||
// Should have multiple spans for highlighting
|
||||
assert!(line.spans.len() >= 1, "Should have spans");
|
||||
assert!(!line.spans.is_empty(), "Should have spans");
|
||||
|
||||
// At least one span should have the yellow background (the highlighted portion)
|
||||
let has_highlight = line.spans.iter().any(|span| span.style.bg == Some(Color::Yellow));
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
/// # Example with Option<Type>
|
||||
///
|
||||
/// ```rust
|
||||
/// use skim::exhaustive_match;
|
||||
///
|
||||
/// enum Status { Active, Inactive, Pending }
|
||||
/// enum Output { Success, Failure, Unknown }
|
||||
///
|
||||
|
|
@ -25,6 +27,8 @@
|
|||
/// # Example with plain Type
|
||||
///
|
||||
/// ```rust
|
||||
/// use skim::exhaustive_match;
|
||||
///
|
||||
/// enum KeyCode { Enter, Char(char) }
|
||||
///
|
||||
/// fn parse(key: &str) -> KeyCode {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![cfg_attr(coverage, feature(coverage_attribute))]
|
||||
//! Skim is a fuzzy finder library for Rust.
|
||||
//!
|
||||
//! It provides a fast and customizable way to filter and select items interactively,
|
||||
|
|
@ -11,7 +10,7 @@
|
|||
//! use std::io::Cursor;
|
||||
//!
|
||||
//! let options = SkimOptionsBuilder::default()
|
||||
//! .height(Some("50%"))
|
||||
//! .height("50%")
|
||||
//! .multi(true)
|
||||
//! .build()
|
||||
//! .unwrap();
|
||||
|
|
@ -20,10 +19,11 @@
|
|||
//! let item_reader = SkimItemReader::default();
|
||||
//! let items = item_reader.of_bufread(Cursor::new(input));
|
||||
//!
|
||||
//! let output = Skim::run_with(&options, Some(items)).unwrap();
|
||||
//! let output = Skim::run_with(options, Some(items)).unwrap();
|
||||
//! ```
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![cfg_attr(coverage, feature(coverage_attribute))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
|
|
|||
269
src/options.rs
269
src/options.rs
|
|
@ -33,7 +33,7 @@ fn parse_delimiter_value(s: &str) -> Result<Regex, String> {
|
|||
///
|
||||
/// sk is a general purpose command-line fuzzy finder.
|
||||
#[derive(Builder)]
|
||||
#[builder(build_fn(name = "final_build"))]
|
||||
#[builder(build_fn(name = "final_build"), setter(into, strip_option))]
|
||||
#[builder(default)]
|
||||
#[cfg_attr(feature = "cli", derive(clap::Parser))]
|
||||
#[cfg_attr(
|
||||
|
|
@ -410,12 +410,12 @@ pub struct SkimOptions {
|
|||
/// use skim::prelude::*;
|
||||
///
|
||||
/// let _options = SkimOptionsBuilder::default()
|
||||
/// .cmd(ls --color)
|
||||
/// .cmd("ls --color")
|
||||
/// .cmd_collector(Rc::new(RefCell::new(SkimItemReader::new(
|
||||
/// SkimItemReaderOption::default().ansi(true),
|
||||
/// ))) as Rc<RefCell<dyn CommandCollector>>)
|
||||
/// .build()
|
||||
/// .unwrap()
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
#[cfg_attr(feature = "cli", arg(long, help_heading = "Display"))]
|
||||
pub ansi: bool,
|
||||
|
|
@ -426,12 +426,18 @@ pub struct SkimOptions {
|
|||
|
||||
/// Set matching result count display position
|
||||
///
|
||||
/// hidden: do not display info
|
||||
/// inline: display info in the same row as the input
|
||||
/// default: display info in a dedicated row above the input
|
||||
/// - hidden: do not display info
|
||||
/// - inline: display info in the same row as the input
|
||||
/// - default: display info in a dedicated row above the input
|
||||
#[cfg_attr(
|
||||
feature = "cli",
|
||||
arg(long, help_heading = "Display", value_enum, default_value = "default")
|
||||
arg(
|
||||
long,
|
||||
help_heading = "Display",
|
||||
value_enum,
|
||||
default_value = "default",
|
||||
verbatim_doc_comment
|
||||
)
|
||||
)]
|
||||
pub info: InfoDisplay,
|
||||
|
||||
|
|
@ -546,6 +552,7 @@ pub struct SkimOptions {
|
|||
/// sk --delimiter : \
|
||||
/// --preview 'bat --style=numbers --color=always --highlight-line {2} {1}' \
|
||||
/// --preview-window +{2}-/2
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "cli",
|
||||
arg(
|
||||
|
|
@ -606,8 +613,7 @@ pub struct SkimOptions {
|
|||
///
|
||||
/// Synchronous search for multi-staged filtering. If specified,
|
||||
/// skim will launch ncurses finder only after the input stream is complete.
|
||||
///
|
||||
/// e.g. sk --multi | sk --sync
|
||||
/// e.g. `sk --multi | sk --sync`
|
||||
#[cfg_attr(feature = "cli", arg(long, help_heading = "Scripting"))]
|
||||
pub sync: bool,
|
||||
|
||||
|
|
@ -695,58 +701,172 @@ pub struct SkimOptions {
|
|||
#[cfg_attr(feature = "cli", arg(long, help_heading = "Scripting"))]
|
||||
pub log_file: Option<String>,
|
||||
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, help_heading = "Scripting"))]
|
||||
/// Feature flags
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, help_heading = "Scripting"))]
|
||||
pub flags: Vec<FeatureFlag>,
|
||||
|
||||
/// Reserved for later use
|
||||
#[cfg_attr(
|
||||
feature = "cli",
|
||||
arg(short = 'x', long, hide = true, help_heading = "Reserved for later use")
|
||||
)]
|
||||
pub extended: bool,
|
||||
|
||||
/// Reserved for later use
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, help_heading = "Reserved for later use"))]
|
||||
pub literal: bool,
|
||||
|
||||
/// Reserved for later use
|
||||
#[cfg_attr(
|
||||
feature = "cli",
|
||||
arg(long, hide = true, default_value = "10", help_heading = "Reserved for later use")
|
||||
)]
|
||||
pub hscroll_off: usize,
|
||||
|
||||
/// Reserved for later use
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, help_heading = "Reserved for later use"))]
|
||||
pub filepath_word: bool,
|
||||
|
||||
/// Reserved for later use
|
||||
#[cfg_attr(
|
||||
feature = "cli",
|
||||
arg(
|
||||
long,
|
||||
hide = true,
|
||||
default_value = "abcdefghijklmnopqrstuvwxyz",
|
||||
help_heading = "Reserved for later use"
|
||||
)
|
||||
)]
|
||||
pub jump_labels: String,
|
||||
|
||||
/// Reserved for later use
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, help_heading = "Reserved for later use"))]
|
||||
pub no_bold: bool,
|
||||
|
||||
/// Reserved for later use
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, help_heading = "Reserved for later use"))]
|
||||
pub phony: bool,
|
||||
// FZF compatibility args
|
||||
#[cfg_attr(feature = "cli", arg(short = 'x', long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
extended: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
literal: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, default_value = "10"))]
|
||||
#[builder(setter(skip))]
|
||||
hscroll_off: usize,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
filepath_word: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, default_value = ""))]
|
||||
#[builder(setter(skip))]
|
||||
jump_labels: String,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
no_bold: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
phony: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
scheme: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
tail: Option<usize>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
style: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
no_color: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
padding: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
border_label: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
border_label_pos: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
highlight_line: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
wrap_sign: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
no_multi_line: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
raw: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
track: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
gap: Option<usize>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
gap_line: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, default_value = "0"))]
|
||||
#[builder(setter(skip))]
|
||||
freeze_left: usize,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, default_value = "0"))]
|
||||
#[builder(setter(skip))]
|
||||
freeze_right: usize,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true, default_value = "0"))]
|
||||
#[builder(setter(skip))]
|
||||
scroll_off: usize,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
gutter: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
gutter_raw: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
marker_multi_line: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
ellipsis: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
scrollbar: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
no_scrollbar: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
list_border: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
list_label: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
list_label_pos: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
no_input: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
info_command: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
separator: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
no_separator: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
ghost: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
input_border: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
input_label: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
input_label_pos: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
preview_label: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
preview_label_pos: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
header_first: bool,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
header_border: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
header_lines_border: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
footer: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
footer_border: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
footer_label: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
footer_label_pos: Option<String>,
|
||||
#[cfg_attr(feature = "cli", arg(long, hide = true))]
|
||||
#[builder(setter(skip))]
|
||||
with_shell: Option<String>,
|
||||
|
||||
/// Deprecated, kept for compatibility purposes. See accept() bind instead.
|
||||
#[cfg_attr(feature = "cli", arg(long, help_heading = "Deprecated", default_value = ""))]
|
||||
pub expect: String,
|
||||
expect: String,
|
||||
|
||||
/// Command collector for reading items from commands
|
||||
#[cfg_attr(feature = "cli", clap(skip = Rc::new(RefCell::new(SkimItemReader::default())) as Rc<RefCell<dyn CommandCollector>>))]
|
||||
#[builder(setter(into = false))]
|
||||
pub cmd_collector: Rc<RefCell<dyn CommandCollector>>,
|
||||
/// Query history entries loaded from history file
|
||||
#[cfg_attr(feature = "cli", clap(skip))]
|
||||
|
|
@ -756,6 +876,7 @@ pub struct SkimOptions {
|
|||
pub cmd_history: Vec<String>,
|
||||
/// Selector for pre-selecting items
|
||||
#[cfg_attr(feature = "cli", clap(skip))]
|
||||
#[builder(setter(into = false))]
|
||||
pub selector: Option<Rc<dyn Selector>>,
|
||||
/// Preview Callback
|
||||
///
|
||||
|
|
@ -857,6 +978,50 @@ impl Default for SkimOptions {
|
|||
border: Default::default(),
|
||||
no_bold: Default::default(),
|
||||
phony: Default::default(),
|
||||
scheme: Default::default(),
|
||||
tail: Default::default(),
|
||||
style: Default::default(),
|
||||
no_color: Default::default(),
|
||||
padding: Default::default(),
|
||||
border_label: Default::default(),
|
||||
border_label_pos: Default::default(),
|
||||
highlight_line: Default::default(),
|
||||
wrap_sign: Default::default(),
|
||||
no_multi_line: Default::default(),
|
||||
raw: Default::default(),
|
||||
track: Default::default(),
|
||||
gap: Default::default(),
|
||||
gap_line: Default::default(),
|
||||
freeze_left: Default::default(),
|
||||
freeze_right: Default::default(),
|
||||
scroll_off: Default::default(),
|
||||
gutter: Default::default(),
|
||||
gutter_raw: Default::default(),
|
||||
marker_multi_line: Default::default(),
|
||||
ellipsis: Default::default(),
|
||||
scrollbar: Default::default(),
|
||||
no_scrollbar: Default::default(),
|
||||
list_border: Default::default(),
|
||||
list_label: Default::default(),
|
||||
list_label_pos: Default::default(),
|
||||
no_input: Default::default(),
|
||||
info_command: Default::default(),
|
||||
separator: Default::default(),
|
||||
no_separator: Default::default(),
|
||||
ghost: Default::default(),
|
||||
input_border: Default::default(),
|
||||
input_label: Default::default(),
|
||||
input_label_pos: Default::default(),
|
||||
preview_label: Default::default(),
|
||||
preview_label_pos: Default::default(),
|
||||
header_first: Default::default(),
|
||||
header_border: Default::default(),
|
||||
header_lines_border: Default::default(),
|
||||
footer: Default::default(),
|
||||
footer_border: Default::default(),
|
||||
footer_label: Default::default(),
|
||||
footer_label_pos: Default::default(),
|
||||
with_shell: Default::default(),
|
||||
expect: Default::default(),
|
||||
cmd_collector: Rc::new(RefCell::new(SkimItemReader::default())) as Rc<RefCell<dyn CommandCollector>>,
|
||||
query_history: Default::default(),
|
||||
|
|
|
|||
|
|
@ -628,8 +628,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_init_from_options() {
|
||||
// Test initialization from SkimOptions
|
||||
let mut opts = crate::options::SkimOptionsBuilder::default().build().unwrap();
|
||||
opts.color = Some("matched:108".to_string());
|
||||
let opts = crate::options::SkimOptionsBuilder::default()
|
||||
.color("matched:108")
|
||||
.build()
|
||||
.unwrap();
|
||||
let theme = ColorTheme::init_from_options(&opts);
|
||||
assert_eq!(theme.matched.fg, Some(Color::Indexed(108)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,8 +167,7 @@ mod size_test {
|
|||
#[test]
|
||||
fn fixed_neg() {
|
||||
let SizeParseError::ParseError(err_value, internal_error) = Size::try_from("-10").unwrap_err() else {
|
||||
assert!(false);
|
||||
return;
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(internal_error.kind(), &IntErrorKind::InvalidDigit);
|
||||
assert_eq!(err_value, String::from("-10"));
|
||||
|
|
@ -176,8 +175,7 @@ mod size_test {
|
|||
#[test]
|
||||
fn percent_neg() {
|
||||
let SizeParseError::ParseError(err_value, internal_error) = Size::try_from("-10%").unwrap_err() else {
|
||||
assert!(false);
|
||||
return;
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(internal_error.kind(), &IntErrorKind::InvalidDigit);
|
||||
assert_eq!(err_value, String::from("-10%"));
|
||||
|
|
@ -185,16 +183,14 @@ mod size_test {
|
|||
#[test]
|
||||
fn percent_over_100() {
|
||||
let SizeParseError::InvalidPercent(internal_error) = Size::try_from("110%").unwrap_err() else {
|
||||
assert!(false);
|
||||
return;
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(internal_error, 110u16);
|
||||
}
|
||||
#[test]
|
||||
fn fixed_invalid_char() {
|
||||
let SizeParseError::ParseError(value, internal_error) = Size::try_from("1-0").unwrap_err() else {
|
||||
assert!(false);
|
||||
return;
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(internal_error.kind(), &IntErrorKind::InvalidDigit);
|
||||
assert_eq!(value, String::from("1-0"));
|
||||
|
|
@ -202,8 +198,7 @@ mod size_test {
|
|||
#[test]
|
||||
fn percent_invalid_char() {
|
||||
let SizeParseError::ParseError(value, internal_error) = Size::try_from("1-0%").unwrap_err() else {
|
||||
assert!(false);
|
||||
return;
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(internal_error.kind(), &IntErrorKind::InvalidDigit);
|
||||
assert_eq!(value, String::from("1-0%"));
|
||||
|
|
@ -211,8 +206,7 @@ mod size_test {
|
|||
#[test]
|
||||
fn percent_empty() {
|
||||
let SizeParseError::ParseError(value, internal_error) = Size::try_from("%").unwrap_err() else {
|
||||
assert!(false);
|
||||
return;
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(internal_error.kind(), &IntErrorKind::Empty);
|
||||
assert_eq!(value, String::from("%"));
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ mod tests {
|
|||
let layout = PreviewLayout::from("left");
|
||||
assert_eq!(layout.direction, Direction::Left);
|
||||
assert_eq!(layout.size, Size::Percent(50)); // default
|
||||
assert_eq!(layout.hidden, false);
|
||||
assert!(!layout.hidden);
|
||||
assert_eq!(layout.offset, None);
|
||||
|
||||
let layout = PreviewLayout::from("right");
|
||||
|
|
@ -115,7 +115,7 @@ mod tests {
|
|||
let layout = PreviewLayout::from("left:30%");
|
||||
assert_eq!(layout.direction, Direction::Left);
|
||||
assert_eq!(layout.size, Size::Percent(30));
|
||||
assert_eq!(layout.hidden, false);
|
||||
assert!(!layout.hidden);
|
||||
assert_eq!(layout.offset, None);
|
||||
|
||||
let layout = PreviewLayout::from("right:40");
|
||||
|
|
@ -155,12 +155,12 @@ mod tests {
|
|||
fn test_preview_layout_with_hidden() {
|
||||
let layout = PreviewLayout::from("left:hidden");
|
||||
assert_eq!(layout.direction, Direction::Left);
|
||||
assert_eq!(layout.hidden, true);
|
||||
assert!(layout.hidden);
|
||||
|
||||
let layout = PreviewLayout::from("right:50%:hidden");
|
||||
assert_eq!(layout.direction, Direction::Right);
|
||||
assert_eq!(layout.size, Size::Percent(50));
|
||||
assert_eq!(layout.hidden, true);
|
||||
assert!(layout.hidden);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -169,6 +169,6 @@ mod tests {
|
|||
assert_eq!(layout.direction, Direction::Left);
|
||||
assert_eq!(layout.size, Size::Percent(30));
|
||||
assert_eq!(layout.offset, Some("+{2}-5".to_string()));
|
||||
assert_eq!(layout.hidden, true);
|
||||
assert!(layout.hidden);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use std::sync::Arc;
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// ```ignore
|
||||
/// use skim::util::unescape_delimiter;
|
||||
///
|
||||
/// assert_eq!(unescape_delimiter(r"\x00"), "\0");
|
||||
|
|
@ -244,7 +244,7 @@ mod test {
|
|||
pattern,
|
||||
&delimiter,
|
||||
"{}",
|
||||
items.iter().map(|x| x.clone()),
|
||||
items.iter().cloned(),
|
||||
Some(Arc::new("item 2")),
|
||||
"query",
|
||||
"cmd query",
|
||||
|
|
@ -260,7 +260,7 @@ mod test {
|
|||
"{+}",
|
||||
&Regex::new(" ").unwrap(),
|
||||
"{}",
|
||||
vec![Arc::new("1"), Arc::new("2")]
|
||||
[Arc::new("1"), Arc::new("2")]
|
||||
.iter()
|
||||
.map(|x| x.clone() as Arc<dyn SkimItem>),
|
||||
Some(Arc::new("1")),
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ impl<'a> TestHarness<'a> {
|
|||
|
||||
let items: Vec<Arc<dyn SkimItem>> = reader
|
||||
.lines()
|
||||
.filter_map(|line| line.ok())
|
||||
.map_while(Result::ok)
|
||||
.enumerate()
|
||||
.map(|(idx, s)| {
|
||||
Arc::new(DefaultSkimItem::new(
|
||||
|
|
@ -344,18 +344,13 @@ impl<'a> TestHarness<'a> {
|
|||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
|
||||
// Try to process any pending events (including PreviewReady)
|
||||
loop {
|
||||
match self.tui.event_rx.try_recv() {
|
||||
Ok(event) => {
|
||||
let is_preview_ready = matches!(event, Event::PreviewReady);
|
||||
self.process_event(event)?;
|
||||
// If we got PreviewReady, render and return
|
||||
if is_preview_ready {
|
||||
self.render()?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Err(_) => break, // No more events
|
||||
while let Ok(event) = self.tui.event_rx.try_recv() {
|
||||
let is_preview_ready = matches!(event, Event::PreviewReady);
|
||||
self.process_event(event)?;
|
||||
// If we got PreviewReady, render and return
|
||||
if is_preview_ready {
|
||||
self.render()?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,7 +452,7 @@ pub fn enter_interactive<'a>(options: SkimOptions) -> Result<TestHarness<'a>> {
|
|||
|
||||
// Run initial command with current (empty) query
|
||||
if let Some(ref cmd_template) = harness.app.options.cmd.clone() {
|
||||
let expanded_cmd = harness.app.expand_cmd(&cmd_template, true);
|
||||
let expanded_cmd = harness.app.expand_cmd(cmd_template, true);
|
||||
harness.run_command(&expanded_cmd)?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ impl TmuxController {
|
|||
print!("typing `");
|
||||
for key in keys {
|
||||
Self::run(&["send-keys", "-t", &self.window, &key.to_string()])?;
|
||||
print!("{}", key.to_string());
|
||||
print!("{}", key);
|
||||
}
|
||||
println!("`");
|
||||
Ok(())
|
||||
|
|
@ -236,10 +236,10 @@ impl TmuxController {
|
|||
if pred(&lines) {
|
||||
return Ok(true);
|
||||
}
|
||||
Err(std::io::Error::new(ErrorKind::Other, "pred not matched"))
|
||||
Err(std::io::Error::other("pred not matched"))
|
||||
}) {
|
||||
Ok(true) => Ok(()),
|
||||
Ok(false) => Err(std::io::Error::new(ErrorKind::Other, self.capture()?.join("\n"))),
|
||||
Ok(false) => Err(std::io::Error::other(self.capture()?.join("\n"))),
|
||||
_ => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::TimedOut,
|
||||
self.capture()?.join("\n"),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ fn query_history() -> Result<()> {
|
|||
let mut tmux = TmuxController::new()?;
|
||||
let histfile = tmux.tempfile()?;
|
||||
|
||||
File::create(&histfile)?.write(b"a\nb\nc")?;
|
||||
File::create(&histfile)?.write_all(b"a\nb\nc")?;
|
||||
|
||||
tmux.start_sk(Some("echo -e -n 'a\\nb\\nc'"), &["--history", &histfile])?;
|
||||
tmux.until(|l| l[0].starts_with(">"))?;
|
||||
|
|
@ -55,7 +55,7 @@ fn cmd_history() -> Result<()> {
|
|||
let mut tmux = TmuxController::new()?;
|
||||
let histfile = tmux.tempfile()?;
|
||||
|
||||
File::create(&histfile)?.write(b"a\nb\nc")?;
|
||||
File::create(&histfile)?.write_all(b"a\nb\nc")?;
|
||||
|
||||
tmux.start_sk(
|
||||
Some("echo -e -n 'a\\nb\\nc'"),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use crate::common::SK;
|
|||
fn connect(name: &str) -> Result<Child> {
|
||||
Command::new("/bin/sh")
|
||||
.arg("-c")
|
||||
.arg(&format!("{SK} --remote {name}"))
|
||||
.arg(format!("{SK} --remote {name}"))
|
||||
.stdin(Stdio::piped())
|
||||
.spawn()
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ fn setup(name: &str, extra_args: &[&str]) -> Result<(TmuxController, Child)> {
|
|||
Some(&format!("echo -n -e '{}'", "a\\nb\\nc\\nd")),
|
||||
&[&["--listen", &socket_name], extra_args].concat(),
|
||||
)?;
|
||||
tmux.until(|l| l.len() > 0 && l[0].starts_with(">"))?;
|
||||
tmux.until(|l| !l.is_empty() && l[0].starts_with(">"))?;
|
||||
let stream = connect(&socket_name)?;
|
||||
Ok((tmux, stream))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -473,11 +473,11 @@ fn opt_select_1() -> std::io::Result<()> {
|
|||
let res = Command::new("/bin/sh")
|
||||
.arg("-c")
|
||||
.env_clear()
|
||||
.arg(&format!("printf '1\n2\n3' | {SK} --select-1 -q 3"))
|
||||
.arg(format!("printf '1\n2\n3' | {SK} --select-1 -q 3"))
|
||||
.stdin(std::process::Stdio::null())
|
||||
.output()?;
|
||||
assert_eq!(res.status.code(), Some(0));
|
||||
assert_eq!(res.stdout, &[b'3', b'\n']);
|
||||
assert_eq!(res.stdout, b"3\n");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -486,7 +486,7 @@ fn opt_exit_0() -> std::io::Result<()> {
|
|||
let res = Command::new("/bin/sh")
|
||||
.arg("-c")
|
||||
.env_clear()
|
||||
.arg(&format!("printf '1\n2\n3' | {SK} --exit-0 -q 4"))
|
||||
.arg(format!("printf '1\n2\n3' | {SK} --exit-0 -q 4"))
|
||||
.stdin(std::process::Stdio::null())
|
||||
.output()?;
|
||||
assert_eq!(res.status.code(), Some(1));
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ sk_test!(opt_read0, "a\\0b\\0c", &["--read0"], {
|
|||
sk_test!(opt_print0, "a\\nb\\nc", &["-m", "--print0"], {
|
||||
@lines |l| (l.len() > 4);
|
||||
@keys BTab, BTab, Enter;
|
||||
@lines |l| (l.len() > 0 && !l[0].starts_with(">"));
|
||||
@lines |l| (!l.is_empty() && !l[0].starts_with(">"));
|
||||
@output[0] trim().eq("a\0b\0");
|
||||
});
|
||||
|
||||
|
|
@ -152,8 +152,8 @@ sk_test!(opt_reserved_options, "a\\nb", &[], tmux => {
|
|||
for option in reserved_options {
|
||||
println!("Starting sk with opt {}", option);
|
||||
let mut tmux = TmuxController::new()?;
|
||||
tmux.start_sk(Some(&format!("echo -n -e 'a\\nb'")), &[option])?;
|
||||
tmux.until(|l| l.len() > 0 && l[0].starts_with(">"))?;
|
||||
tmux.start_sk(Some("echo -n -e 'a\\nb'"), &[option])?;
|
||||
tmux.until(|l| !l.is_empty() && l[0].starts_with(">"))?;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -197,8 +197,8 @@ sk_test!(opt_multiple_flags_basic, "a\\nb", &[], tmux => {
|
|||
|
||||
for cmd_flags in basic_flags {
|
||||
let mut tmux = TmuxController::new()?;
|
||||
tmux.start_sk(Some(&format!("echo -n -e 'a\\nb'")), &[cmd_flags])?;
|
||||
tmux.until(|l| l.len() > 0 && l[0].starts_with(">"))?;
|
||||
tmux.start_sk(Some("echo -n -e 'a\\nb'"), &[cmd_flags])?;
|
||||
tmux.until(|l| !l.is_empty() && l[0].starts_with(">"))?;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -207,10 +207,10 @@ use tempfile::NamedTempFile;
|
|||
|
||||
sk_test!(opt_pre_select_file, "a\\nb\\nc", &[], tmux => {
|
||||
let mut pre_select_file = NamedTempFile::new()?;
|
||||
pre_select_file.write(b"b\nc")?;
|
||||
pre_select_file.write_all(b"b\nc")?;
|
||||
let mut tmux = TmuxController::new()?;
|
||||
tmux.start_sk(
|
||||
Some(&format!("echo -n -e 'a\\nb\\nc'")),
|
||||
Some("echo -n -e 'a\\nb\\nc'"),
|
||||
&["-m", "--pre-select-file", pre_select_file.path().to_str().unwrap()],
|
||||
)?;
|
||||
tmux.until(|l| l.len() > 4 && l[2] == "> a" && l[3].trim() == ">b" && l[4].trim() == ">c")?;
|
||||
|
|
|
|||
Loading…
Reference in a new issue