use rustyline::completion::Pair;
impl super::SqlCompleter {
pub(super) fn complete_list(&self, text_before_cursor: &str) -> Option<Vec<Pair>> {
let trimmed = text_before_cursor.trim_start();
if let Some(after_list) = trimmed.strip_prefix(r"\list+ ") {
return self.complete_list_args(after_list);
}
if let Some(after_list) = trimmed.strip_prefix(r"\list ") {
return self.complete_list_args(after_list);
}
if trimmed.starts_with(r"\dt+ ") || trimmed.starts_with(r"\dt ") {
return Some(Vec::new());
}
None
}
fn complete_list_args(&self, after_list: &str) -> Option<Vec<Pair>> {
let parts: Vec<&str> = after_list.split_whitespace().collect();
if parts.is_empty() {
return Some(vec![
Pair {
display: "table".to_string(),
replacement: "table".to_string(),
},
Pair {
display: "index".to_string(),
replacement: "index".to_string(),
},
Pair {
display: "function".to_string(),
replacement: "function".to_string(),
},
Pair {
display: "view".to_string(),
replacement: "view".to_string(),
},
Pair {
display: "schema".to_string(),
replacement: "schema".to_string(),
},
Pair {
display: "sequence".to_string(),
replacement: "sequence".to_string(),
},
]);
}
if parts.len() == 1 {
let partial = parts[0];
let mut completions = Vec::new();
if "table".starts_with(&partial.to_lowercase()) {
completions.push(Pair {
display: "table".to_string(),
replacement: "table".to_string(),
});
}
if "index".starts_with(&partial.to_lowercase()) {
completions.push(Pair {
display: "index".to_string(),
replacement: "index".to_string(),
});
}
if "function".starts_with(&partial.to_lowercase()) {
completions.push(Pair {
display: "function".to_string(),
replacement: "function".to_string(),
});
}
if "view".starts_with(&partial.to_lowercase()) {
completions.push(Pair {
display: "view".to_string(),
replacement: "view".to_string(),
});
}
if "schema".starts_with(&partial.to_lowercase()) {
completions.push(Pair {
display: "schema".to_string(),
replacement: "schema".to_string(),
});
}
if "sequence".starts_with(&partial.to_lowercase()) {
completions.push(Pair {
display: "sequence".to_string(),
replacement: "sequence".to_string(),
});
}
if !completions.is_empty() {
return Some(completions);
}
}
Some(Vec::new())
}
}
#[cfg(test)]
mod tests {
use crate::{completer::*, theme::Theme};
#[test]
fn test_list_command_completion() {
let completer = SqlCompleter::new(Theme::Dark);
let completions = completer.find_completions("\\", 1);
assert!(completions.iter().any(|c| c.display == "\\list"));
assert!(completions.iter().any(|c| c.display == "\\list+"));
assert!(completions.iter().any(|c| c.display == "\\dt"));
assert!(completions.iter().any(|c| c.display == "\\dt+"));
assert!(completions.iter().any(|c| c.display == "\\ds"));
assert!(completions.iter().any(|c| c.display == "\\ds+"));
}
#[test]
fn test_list_table_argument_completion() {
let completer = SqlCompleter::new(Theme::Dark);
let input = "\\list ";
let completions = completer.find_completions(input, input.len());
assert!(!completions.is_empty());
assert!(completions.iter().any(|c| c.display == "table"));
assert!(completions.iter().any(|c| c.display == "index"));
assert!(completions.iter().any(|c| c.display == "function"));
assert!(completions.iter().any(|c| c.display == "view"));
assert!(completions.iter().any(|c| c.display == "schema"));
assert!(completions.iter().any(|c| c.display == "sequence"));
let input = "\\list ta";
let completions = completer.find_completions(input, input.len());
assert!(!completions.is_empty());
assert!(completions.iter().any(|c| c.display == "table"));
let input = "\\list in";
let completions = completer.find_completions(input, input.len());
assert!(!completions.is_empty());
assert!(completions.iter().any(|c| c.display == "index"));
let input = "\\list table";
let completions = completer.find_completions(input, input.len());
assert!(!completions.is_empty());
assert!(completions.iter().any(|c| c.display == "table"));
}
#[test]
fn test_list_plus_table_argument_completion() {
let completer = SqlCompleter::new(Theme::Dark);
let input = "\\list+ ";
let completions = completer.find_completions(input, input.len());
assert!(!completions.is_empty());
assert!(completions.iter().any(|c| c.display == "table"));
assert!(completions.iter().any(|c| c.display == "index"));
assert!(completions.iter().any(|c| c.display == "function"));
assert!(completions.iter().any(|c| c.display == "view"));
assert!(completions.iter().any(|c| c.display == "schema"));
assert!(completions.iter().any(|c| c.display == "sequence"));
}
}