fix: add allow_hyphen_values to --with-nth

Matches --nth and --hide-nth behavior to support documented negative indices syntax.
This commit is contained in:
VXNCXNX 2026-08-15 17:48:57 +00:00
parent fe45ed36b7
commit d0bf013447
3 changed files with 56 additions and 1 deletions

View file

@ -196,7 +196,13 @@ pub struct SkimOptions {
/// See **nth** for the details
#[cfg_attr(
feature = "cli",
arg(long, default_value = "", help_heading = "Search", value_delimiter = ',')
arg(
long,
default_value = "",
help_heading = "Search",
value_delimiter = ',',
allow_hyphen_values = true,
)
)]
pub with_nth: Vec<String>,

View file

@ -2,6 +2,7 @@
//! and history initialization, which apply defaults and cross-option rules.
use super::*;
use crate::field::FieldRange;
use crate::item::RankCriteria;
use crate::tui::statusline::InfoDisplay;
@ -287,3 +288,38 @@ fn build_history_file_adds_history_keybindings() {
let _ = std::fs::remove_file(&qpath);
}
/// Helper: parse real CLI args with no env influence.
fn parse_args(args: &[&str]) -> Result<SkimOptions, clap::Error> {
SkimOptions::merge_args_and_parse(
"sk".to_string(),
None,
None,
args.iter().map(|s| (*s).to_string()),
None,
)
}
#[test]
fn negative_field_indices_parse_for_every_nth_flag() {
// All three flags document the same `nth` syntax, which includes `-1` for the
// last field; a space-separated negative value must not be read as a flag.
for flag in ["--nth", "--with-nth", "--hide-nth"] {
let opts = parse_args(&[flag, "-1"]).unwrap_or_else(|e| panic!("{flag} -1 failed to parse: {e}"));
let got = match flag {
"--nth" => &opts.nth,
"--with-nth" => &opts.with_nth,
_ => &opts.hide_nth,
};
assert_eq!(got, &vec!["-1".to_string()], "{flag}");
assert_eq!(
FieldRange::from_str(&got[0]),
Some(FieldRange::Single(-1)),
"{flag} should resolve to the last field"
);
}
// ...and a negative index inside a comma-separated list.
let opts = parse_args(&["--with-nth", "2,-1"]).expect("--with-nth 2,-1 should parse");
assert_eq!(opts.with_nth, vec!["2".to_string(), "-1".to_string()]);
}

View file

@ -128,6 +128,19 @@ fn filter_mode_no_sort_preserves_input_order() {
);
}
#[test]
fn with_nth_accepts_space_separated_negative_index() {
// `--with-nth -1` (space form) used to be parsed as a missing value, while
// `--nth -1` and `--with-nth=-1` both worked.
let (code, stdout, stderr) = run_sk_argv("a b c", &["-f", "c", "--with-nth", "-1"], &[]);
assert_eq!(code, Some(0), "stderr: {stderr}");
assert_eq!(stdout.trim_end(), "a b c");
// The space form and the `=` form must agree.
let (code_eq, stdout_eq, _) = run_sk_argv("a b c", &["-f", "c", "--with-nth=-1"], &[]);
assert_eq!((code, stdout), (code_eq, stdout_eq));
}
#[test]
fn select_1_with_output_format() {
// --output-format renders the selected item through the printf branch.