nu-command 0.113.1

Nushell's built-in commands
Documentation
use super::state::stream_find;
use nu_engine::command_prelude::*;

#[derive(Clone)]
pub struct IdxFind;

impl Command for IdxFind {
    fn name(&self) -> &str {
        "idx find"
    }

    fn signature(&self) -> Signature {
        Signature::build(self.name())
            .required("query", SyntaxShape::String, "Freeform fuzzy query.")
            .switch("verbose", "Include verbose scoring details.", Some('v'))
            .switch("dirs", "Search directories only.", Some('d'))
            .switch("files", "Search files only.", Some('f'))
            .named(
                "limit",
                SyntaxShape::Int,
                "Maximum number of rows to return (default 100).",
                Some('l'),
            )
            .input_output_types(vec![(Type::Nothing, Type::List(Box::new(Type::record())))])
            .category(Category::FileSystem)
    }

    fn description(&self) -> &str {
        "Search idx with fuzzy matching across files and directories by default."
    }

    fn extra_description(&self) -> &str {
        "`idx find` searches both files and directories unless you narrow it with `--files` or `--dirs`."
    }

    fn examples(&self) -> Vec<Example<'_>> {
        vec![
            Example {
                description: "Fuzzy search for files and directories matching 'main'",
                example: "idx find main",
                result: None,
            },
            Example {
                description: "Search only files with verbose scoring output",
                example: "idx find config --files --verbose",
                result: None,
            },
            Example {
                description: "Search only directories, limited to top 10 results",
                example: "idx find src --dirs --limit 10",
                result: None,
            },
        ]
    }

    fn run(
        &self,
        engine_state: &EngineState,
        stack: &mut Stack,
        call: &Call,
        _input: PipelineData,
    ) -> Result<PipelineData, ShellError> {
        let query: String = call.req(engine_state, stack, 0)?;
        let verbose = call.has_flag(engine_state, stack, "verbose")?;
        let dirs = call.has_flag(engine_state, stack, "dirs")?;
        let files = call.has_flag(engine_state, stack, "files")?;

        if files && dirs {
            return Err(ShellError::IncompatibleParameters {
                left_message: "--files cannot be used with --dirs".to_string(),
                left_span: call.get_flag_span(stack, "files").unwrap_or(call.head),
                right_message: "--dirs cannot be used with --files".to_string(),
                right_span: call.get_flag_span(stack, "dirs").unwrap_or(call.head),
            });
        }

        let limit = call
            .get_flag::<i64>(engine_state, stack, "limit")?
            .and_then(|v| usize::try_from(v).ok())
            .unwrap_or(100);

        let signals = engine_state.signals();
        stream_find(&query, files, dirs, verbose, limit, call.head, signals)
    }
}