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    use test_that::prelude::*;
34
35    use super::*;
36
37    #[rstest]
38    #[case(
39        Some("dir/foo/bar:42"),
40        Some("dir/foo/bar:9"),
41        Some(("42".to_string(), Some("dir/foo/bar".to_string())))
42    )]
43    #[case(
44        None,
45        Some("dir/foo/bar:42"),
46        Some(("42".to_string(), Some("dir/foo/bar".to_string())))
47    )]
48    #[case(
49        Some(":42"),
50        None,
51        Some(("42".to_string(), Option::<String>::None))
52    )]
53    #[case(Some("dir/foo/bar"), None, None)]
54    #[case(Some("dir/foo/bar:abc"), None, None)]
55    #[case(None, None, None)]
56    fn parse_line_query_works(
57        #[case] query: Option<&str>,
58        #[case] last_query: Option<&str>,
59        #[case] expected: Option<(String, Option<String>)>,
60    ) {
61        let actual = parse_line_query((query.map(ToOwned::to_owned), last_query.map(ToOwned::to_owned)));
62
63        assert_that!(actual, eq(expected));
64    }
65}