Skip to main content

nvrim/plugins/
fzf_lua.rs

1use nvim_oxi::Dictionary;
2
3/// [`Dictionary`] of `fzf-lua` helpers for previewless pickers.
4///
5/// `fzf-lua`'s built-in `line_query` depends on previewer state, so `path:line`
6/// can fail when preview is disabled.
7pub fn dict() -> Dictionary {
8    dict! {
9        "get_fd_flags": fn_from!(crate::cli::get_fd_flags),
10        "get_rg_flags": fn_from!(crate::cli::get_rg_flags),
11        "parse_line_query": fn_from!(parse_line_query),
12    }
13}
14
15/// Parses trailing `:<digits>` from live query or persisted fallback query.
16fn parse_line_query((query, last_query): (Option<String>, Option<String>)) -> Option<(String, Option<String>)> {
17    let query = query
18        .filter(|x| !x.is_empty())
19        .or_else(|| last_query.filter(|x| !x.is_empty()))?;
20
21    let (new_query, lnum) = query.rsplit_once(':')?;
22
23    if lnum.is_empty() || !lnum.bytes().all(|b| b.is_ascii_digit()) {
24        return None;
25    }
26
27    Some((lnum.to_string(), (!new_query.is_empty()).then(|| new_query.to_string())))
28}
29
30#[cfg(test)]
31mod tests {
32    use rstest::rstest;
33
34    use super::*;
35
36    #[rstest]
37    #[case(
38        Some("dir/foo/bar:42"),
39        Some("dir/foo/bar:9"),
40        Some(("42".to_string(), Some("dir/foo/bar".to_string())))
41    )]
42    #[case(
43        None,
44        Some("dir/foo/bar:42"),
45        Some(("42".to_string(), Some("dir/foo/bar".to_string())))
46    )]
47    #[case(
48        Some(":42"),
49        None,
50        Some(("42".to_string(), Option::<String>::None))
51    )]
52    #[case(Some("dir/foo/bar"), None, None)]
53    #[case(Some("dir/foo/bar:abc"), None, None)]
54    #[case(None, None, None)]
55    fn parse_line_query_works(
56        #[case] query: Option<&str>,
57        #[case] last_query: Option<&str>,
58        #[case] expected: Option<(String, Option<String>)>,
59    ) {
60        let actual = parse_line_query((query.map(ToOwned::to_owned), last_query.map(ToOwned::to_owned)));
61
62        pretty_assertions::assert_eq!(actual, expected);
63    }
64}