#![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())
}