Repository: starship/starship
File: src/modules/nix_shell.rs (Rust)

Code before:
    Pure,
    Impure,
    // We're in a Nix shell, but we don't know which type.
    Unknown,
}

impl NixShellType {
    fn detect_shell_type(context: &Context) -> Option<NixShellType> {
        use NixShellType::*;

        let shell_type = context.get_env("IN_NIX_SHELL");
        let shell_type_format_from_env = match shell_type.as_deref() {
            Some("pure") => Some(Pure),
            Some("impure") => Some(Impure),
            _ => None,
        };

        shell_type_format_from_env.or_else(|| Self::in_new_nix_shell(context).map(|_| Unknown))
    }

    // Hack to detect if we're in a `nix shell` (in constrast to a `nix-shell`).
    // A better way to do this will be enabled by https://github.com/NixOS/nix/issues/6677.
    fn in_new_nix_shell(context: &Context) -> Option<()> {
        let path = context.get_env("PATH")?;

        path.contains("/nix/store").then_some(())
    }
}

/// Creates a module showing if inside a nix-shell
///
/// The module will use the `$IN_NIX_SHELL` and `$name` environment variable to
/// determine if it's inside a nix-shell and the name of it.
///
/// The following options are availables:
///     - `impure_msg` (string) // change the impure msg
///     - `pure_msg` (string)   // change the pure msg
///
/// Will display the following:
///     - pure (name)    // $name == "name" in a pure nix-shell
///     - impure (name)  // $name == "name" in an impure nix-shell
///     - pure           // $name == "" in a pure nix-shell
///     - impure         // $name == "" in an impure nix-shell
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
    let mut module = context.new_module("nix_shell");
    let config: NixShellConfig = NixShellConfig::try_load(module.config);

    let shell_name = context.get_env("name");
    let shell_type = NixShellType::detect_shell_type(context)?;
    let shell_type_format = match shell_type {
        NixShellType::Pure => config.pure_msg,

Review comment (suggestion):
To reduce false positive, please use `env::split_paths` and check if any of the paths _starts_ with `/nix/store/`.

Code after:
    Pure,
    Impure,
    /// We're in a Nix shell, but we don't know which type.
    /// This can only happen in a `nix shell` shell (not a `nix-shell` one).
    Unknown,
}

impl NixShellType {
    fn detect_shell_type(use_heuristic: bool, context: &Context) -> Option<NixShellType> {
        use NixShellType::*;

        let shell_type = context.get_env("IN_NIX_SHELL");
        match shell_type.as_deref() {
            Some("pure") => return Some(Pure),
            Some("impure") => return Some(Impure),
            _ => {}
        };

        if use_heuristic {
            Self::in_new_nix_shell(context).map(|_| Unknown)
        } else {
            None
        }
    }

    // Hack to detect if we're in a `nix shell` (in constrast to a `nix-shell`).
    // A better way to do this will be enabled by https://github.com/NixOS/nix/issues/6677.
    fn in_new_nix_shell(context: &Context) -> Option<()> {
        let path = context.get_env("PATH")?;

        std::env::split_paths(&path)
            .any(|path| path.starts_with("/nix/store"))
            .then_some(())
    }
}

/// Creates a module showing if inside a nix-shell
///
/// The module will use the `$IN_NIX_SHELL` and `$name` environment variable to
/// determine if it's inside a nix-shell and the name of it.
///
/// The following options are availables:
///     - `impure_msg` (string)  // change the impure msg
///     - `pure_msg` (string)    // change the pure msg
///     - `unknown_msg` (string) // change the unknown message
///
/// Will display the following:
///     - pure (name)    // $name == "name" in a pure nix-shell
///     - impure (name)  // $name == "name" in an impure nix-shell
///     - pure           // $name == "" in a pure nix-shell
///     - impure         // $name == "" in an impure nix-shell