mumu 0.11.1

Lava Mumu is a language for those in the now and that know
Documentation
// src/modules/repl/autocomplete.rs

#![allow(static_mut_refs)]

use crate::parser::interpreter::Interpreter;

static mut KNOWN_COMMANDS: Option<Vec<String>> = None;

pub fn reset_known_commands_from_interp(interp: &Interpreter) {
    let mut new_list = vec![
        "extend".to_string(),
        "type".to_string(),
        "compose".to_string(),
        "pipe".to_string(),
        "sput".to_string(),
        "slog".to_string(),
        "ink".to_string(),
        "include".to_string(),
    ];
    for (name, _) in interp.get_dynamic_functions_for_clone().iter() {
        if !new_list.contains(name) {
            new_list.push(name.clone());
        }
    }
    for var in interp.get_variables().keys() {
        if !new_list.contains(var) {
            new_list.push(var.clone());
        }
    }
    new_list.sort();
    unsafe {
        KNOWN_COMMANDS = Some(new_list);
    }
}

pub fn gather_completions_for_prefix(prefix: &str) -> Option<Vec<String>> {
    if prefix.is_empty() {
        return None;
    }
    unsafe {
        let commands = KNOWN_COMMANDS.as_ref()?;
        let lower = prefix.to_lowercase();
        let mut matches: Vec<String> = commands
            .iter()
            .filter(|cmd| cmd.to_lowercase().starts_with(&lower))
            .cloned()
            .collect();
        if matches.is_empty() {
            return None;
        }
        matches.sort();
        Some(matches)
    }
}

pub fn last_word_for_autocomplete(typed_line: &str, cursor_pos: usize) -> (usize, String) {
    if cursor_pos == 0 {
        return (0, "".to_string());
    }
    let sub = &typed_line[..cursor_pos];
    let mut idx = sub.len();
    while idx > 0 {
        let ch = sub.as_bytes()[idx - 1] as char;
        if ch.is_whitespace() || "(),[];\"'".contains(ch) {
            break;
        }
        idx -= 1;
    }
    (idx, sub[idx..].to_string())
}