diff --git a/datafusion-cli/src/exec.rs b/datafusion-cli/src/exec.rs index 94bd8ee2c4f9..0cda855bff72 100644 --- a/datafusion-cli/src/exec.rs +++ b/datafusion-cli/src/exec.rs @@ -196,6 +196,7 @@ pub async fn exec_from_repl( } Err(ReadlineError::Interrupted) => { println!("^C"); + rl.helper().unwrap().reset_hint(); continue; } Err(ReadlineError::Eof) => { diff --git a/datafusion-cli/src/helper.rs b/datafusion-cli/src/helper.rs index c53272ee196c..f01d0891b964 100644 --- a/datafusion-cli/src/helper.rs +++ b/datafusion-cli/src/helper.rs @@ -19,6 +19,7 @@ //! and auto-completion for file name during creating external table. use std::borrow::Cow; +use std::cell::Cell; use crate::highlighter::{Color, NoSyntaxHighlighter, SyntaxHighlighter}; @@ -40,6 +41,10 @@ pub struct CliHelper { completer: FilenameCompleter, dialect: Dialect, highlighter: Box, + /// Tracks whether to show the default hint. Set to `false` once the user + /// types anything, so the hint doesn't reappear after deleting back to + /// an empty line. Reset to `true` when the line is submitted. + show_hint: Cell, } impl CliHelper { @@ -53,6 +58,7 @@ impl CliHelper { completer: FilenameCompleter::new(), dialect: *dialect, highlighter, + show_hint: Cell::new(true), } } @@ -62,6 +68,11 @@ impl CliHelper { } } + /// Re-enable the default hint for the next prompt. + pub fn reset_hint(&self) { + self.show_hint.set(true); + } + fn validate_input(&self, input: &str) -> Result { if let Some(sql) = input.strip_suffix(';') { let dialect = match dialect_from_str(self.dialect) { @@ -119,12 +130,11 @@ impl Hinter for CliHelper { type Hint = String; fn hint(&self, line: &str, _pos: usize, _ctx: &Context<'_>) -> Option { - if line.trim().is_empty() { - let suggestion = Color::gray(DEFAULT_HINT_SUGGESTION); - Some(suggestion) - } else { - None + if !line.is_empty() { + self.show_hint.set(false); } + (self.show_hint.get() && line.trim().is_empty()) + .then(|| Color::gray(DEFAULT_HINT_SUGGESTION)) } } @@ -133,12 +143,9 @@ impl Hinter for CliHelper { fn is_open_quote_for_location(line: &str, pos: usize) -> bool { let mut sql = line[..pos].to_string(); sql.push('\''); - if let Ok(stmts) = DFParser::parse_sql(&sql) - && let Some(Statement::CreateExternalTable(_)) = stmts.back() - { - return true; - } - false + DFParser::parse_sql(&sql).is_ok_and(|stmts| { + matches!(stmts.back(), Some(Statement::CreateExternalTable(_))) + }) } impl Completer for CliHelper { @@ -161,7 +168,9 @@ impl Completer for CliHelper { impl Validator for CliHelper { fn validate(&self, ctx: &mut ValidationContext<'_>) -> Result { let input = ctx.input().trim_end(); - self.validate_input(input) + let result = self.validate_input(input); + self.reset_hint(); + result } }