use narwhal_domain::editor::EditorBuffer;
use narwhal_sql::{Dialect, split_with};
pub fn all_statements(buf: &EditorBuffer, dialect: Dialect) -> Vec<String> {
let text = buf.entire_text();
split_with(&text, dialect)
.into_iter()
.filter_map(|s| {
let cleaned = s.text.trim().trim_end_matches(';').trim().to_owned();
(!cleaned.is_empty()).then_some(cleaned)
})
.collect()
}
pub fn statement_at_cursor(buf: &EditorBuffer, dialect: Dialect) -> Option<String> {
let text = buf.entire_text();
let cursor_offset = buf.cursor_byte_offset();
let statements = split_with(&text, dialect);
if statements.is_empty() {
return None;
}
for stmt in &statements {
if cursor_offset >= stmt.start && cursor_offset <= stmt.end {
return Some(stmt.text.to_owned());
}
}
statements.last().map(|s| s.text.to_owned())
}
#[cfg(test)]
mod tests {
use super::*;
use narwhal_domain::Motion;
#[test]
fn statement_under_cursor_picks_the_right_one() {
let mut buf = EditorBuffer::new();
buf.insert_str("SELECT 1; SELECT 2; SELECT 3");
buf.apply_motion(Motion::LineStart, 1);
let first = statement_at_cursor(&buf, Dialect::Generic).expect("statement");
assert!(first.starts_with("SELECT 1"));
for _ in 0..12 {
buf.apply_motion(Motion::Right, 1);
}
let second = statement_at_cursor(&buf, Dialect::Generic).expect("statement");
assert!(second.contains("SELECT 2"));
}
#[test]
fn all_statements_splits_and_trims() {
let mut buf = EditorBuffer::new();
buf.insert_str("SELECT 1; SELECT 2;\n ; SELECT 3");
let stmts = all_statements(&buf, Dialect::Generic);
assert_eq!(stmts, vec!["SELECT 1", "SELECT 2", "SELECT 3"]);
}
#[test]
fn statement_at_cursor_empty_buffer_is_none() {
let buf = EditorBuffer::new();
assert!(statement_at_cursor(&buf, Dialect::Generic).is_none());
}
}