Skip to content

Commit 03ad23a

Browse files
authored
Adding boolean setting for history hints (#2298)
1 parent fc99d39 commit 03ad23a

File tree

2 files changed

+93
-18
lines changed

2 files changed

+93
-18
lines changed

crates/chat-cli/src/cli/chat/prompt.rs

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,24 @@ impl Completer for ChatCompleter {
215215
pub struct ChatHinter {
216216
/// Command history for providing suggestions based on past commands
217217
history: Vec<String>,
218+
/// Whether history-based hints are enabled
219+
history_hints_enabled: bool,
218220
}
219221

220222
impl ChatHinter {
221223
/// Creates a new ChatHinter instance
222-
pub fn new() -> Self {
223-
Self { history: Vec::new() }
224+
pub fn new(os: &Os) -> Self {
225+
// Default to disabled if setting doesn't exist
226+
let history_hints_enabled = os
227+
.database
228+
.settings
229+
.get_bool(Setting::ChatEnableHistoryHints)
230+
.unwrap_or(false);
231+
232+
Self {
233+
history: Vec::new(),
234+
history_hints_enabled,
235+
}
224236
}
225237

226238
/// Updates the history with a new command
@@ -245,12 +257,16 @@ impl ChatHinter {
245257
.map(|cmd| cmd[line.len()..].to_string());
246258
}
247259

248-
// Try to find a hint from history
249-
self.history
250-
.iter()
251-
.rev() // Start from most recent
252-
.find(|cmd| cmd.starts_with(line) && cmd.len() > line.len())
253-
.map(|cmd| cmd[line.len()..].to_string())
260+
// Try to find a hint from history if history hints are enabled
261+
if self.history_hints_enabled {
262+
return self.history
263+
.iter()
264+
.rev() // Start from most recent
265+
.find(|cmd| cmd.starts_with(line) && cmd.len() > line.len())
266+
.map(|cmd| cmd[line.len()..].to_string());
267+
}
268+
269+
None
254270
}
255271
}
256272

@@ -368,7 +384,7 @@ pub fn rl(
368384
.build();
369385
let h = ChatHelper {
370386
completer: ChatCompleter::new(sender, receiver),
371-
hinter: ChatHinter::new(),
387+
hinter: ChatHinter::new(os),
372388
validator: MultiLineValidator,
373389
};
374390
let mut rl = Editor::with_config(config)?;
@@ -401,6 +417,28 @@ mod tests {
401417
use rustyline::highlight::Highlighter;
402418

403419
use super::*;
420+
use crate::database::Settings;
421+
use crate::os::{
422+
Fs,
423+
Os,
424+
};
425+
426+
// Helper function to create a mock Os for testing
427+
fn create_mock_os() -> Os {
428+
let mut os = Os {
429+
database: crate::database::Database {
430+
pool: r2d2::Pool::builder()
431+
.build(r2d2_sqlite::SqliteConnectionManager::memory())
432+
.unwrap(),
433+
settings: Settings::default(),
434+
},
435+
fs: Fs::new(),
436+
env: crate::os::Env::new(),
437+
telemetry: crate::telemetry::Telemetry::new(),
438+
};
439+
os
440+
}
441+
404442
#[test]
405443
fn test_chat_completer_command_completion() {
406444
let (prompt_request_sender, _) = std::sync::mpsc::channel::<Option<String>>();
@@ -446,9 +484,10 @@ mod tests {
446484
fn test_highlight_prompt_basic() {
447485
let (prompt_request_sender, _) = std::sync::mpsc::channel::<Option<String>>();
448486
let (_, prompt_response_receiver) = std::sync::mpsc::channel::<Vec<String>>();
487+
let mock_os = create_mock_os();
449488
let helper = ChatHelper {
450489
completer: ChatCompleter::new(prompt_request_sender, prompt_response_receiver),
451-
hinter: ChatHinter::new(),
490+
hinter: ChatHinter::new(&mock_os),
452491
validator: MultiLineValidator,
453492
};
454493

@@ -462,9 +501,10 @@ mod tests {
462501
fn test_highlight_prompt_with_warning() {
463502
let (prompt_request_sender, _) = std::sync::mpsc::channel::<Option<String>>();
464503
let (_, prompt_response_receiver) = std::sync::mpsc::channel::<Vec<String>>();
504+
let mock_os = create_mock_os();
465505
let helper = ChatHelper {
466506
completer: ChatCompleter::new(prompt_request_sender, prompt_response_receiver),
467-
hinter: ChatHinter::new(),
507+
hinter: ChatHinter::new(&mock_os),
468508
validator: MultiLineValidator,
469509
};
470510

@@ -478,9 +518,10 @@ mod tests {
478518
fn test_highlight_prompt_with_profile() {
479519
let (prompt_request_sender, _) = std::sync::mpsc::channel::<Option<String>>();
480520
let (_, prompt_response_receiver) = std::sync::mpsc::channel::<Vec<String>>();
521+
let mock_os = create_mock_os();
481522
let helper = ChatHelper {
482523
completer: ChatCompleter::new(prompt_request_sender, prompt_response_receiver),
483-
hinter: ChatHinter::new(),
524+
hinter: ChatHinter::new(&mock_os),
484525
validator: MultiLineValidator,
485526
};
486527

@@ -494,9 +535,10 @@ mod tests {
494535
fn test_highlight_prompt_with_profile_and_warning() {
495536
let (prompt_request_sender, _) = std::sync::mpsc::channel::<Option<String>>();
496537
let (_, prompt_response_receiver) = std::sync::mpsc::channel::<Vec<String>>();
538+
let mock_os = create_mock_os();
497539
let helper = ChatHelper {
498540
completer: ChatCompleter::new(prompt_request_sender, prompt_response_receiver),
499-
hinter: ChatHinter::new(),
541+
hinter: ChatHinter::new(&mock_os),
500542
validator: MultiLineValidator,
501543
};
502544

@@ -513,9 +555,10 @@ mod tests {
513555
fn test_highlight_prompt_invalid_format() {
514556
let (prompt_request_sender, _) = std::sync::mpsc::channel::<Option<String>>();
515557
let (_, prompt_response_receiver) = std::sync::mpsc::channel::<Vec<String>>();
558+
let mock_os = create_mock_os();
516559
let helper = ChatHelper {
517560
completer: ChatCompleter::new(prompt_request_sender, prompt_response_receiver),
518-
hinter: ChatHinter::new(),
561+
hinter: ChatHinter::new(&mock_os),
519562
validator: MultiLineValidator,
520563
};
521564

@@ -527,7 +570,8 @@ mod tests {
527570

528571
#[test]
529572
fn test_chat_hinter_command_hint() {
530-
let hinter = ChatHinter::new();
573+
let mock_os = create_mock_os();
574+
let hinter = ChatHinter::new(&mock_os);
531575

532576
// Test hint for a command
533577
let line = "/he";
@@ -550,14 +594,42 @@ mod tests {
550594
}
551595

552596
#[test]
553-
fn test_chat_hinter_history_hint() {
554-
let mut hinter = ChatHinter::new();
597+
fn test_chat_hinter_history_hint_disabled() {
598+
let mock_os = create_mock_os();
599+
let mut hinter = ChatHinter::new(&mock_os); // Default is disabled
600+
601+
// Add some history
602+
hinter.update_history("Hello, world!");
603+
hinter.update_history("How are you?");
604+
605+
// Test hint from history - should be None since history hints are disabled
606+
let line = "How";
607+
let pos = line.len();
608+
let empty_history = DefaultHistory::new();
609+
let ctx = Context::new(&empty_history);
610+
611+
let hint = hinter.hint(line, pos, &ctx);
612+
assert_eq!(hint, None);
613+
}
614+
615+
#[test]
616+
fn test_chat_hinter_history_hint_enabled() {
617+
let mut mock_os = create_mock_os();
618+
619+
// Enable history hints
620+
mock_os
621+
.database
622+
.settings
623+
.0
624+
.insert("chat.enableHistoryHints".to_string(), serde_json::Value::Bool(true));
625+
626+
let mut hinter = ChatHinter::new(&mock_os);
555627

556628
// Add some history
557629
hinter.update_history("Hello, world!");
558630
hinter.update_history("How are you?");
559631

560-
// Test hint from history
632+
// Test hint from history - should work since history hints are enabled
561633
let line = "How";
562634
let pos = line.len();
563635
let empty_history = DefaultHistory::new();

crates/chat-cli/src/database/settings.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub enum Setting {
3535
ChatDefaultModel,
3636
ChatDefaultAgent,
3737
ChatDisableAutoCompaction,
38+
ChatEnableHistoryHints,
3839
}
3940

4041
impl AsRef<str> for Setting {
@@ -58,6 +59,7 @@ impl AsRef<str> for Setting {
5859
Self::ChatDefaultModel => "chat.defaultModel",
5960
Self::ChatDefaultAgent => "chat.defaultAgent",
6061
Self::ChatDisableAutoCompaction => "chat.disableAutoCompaction",
62+
Self::ChatEnableHistoryHints => "chat.enableHistoryHints",
6163
}
6264
}
6365
}
@@ -91,6 +93,7 @@ impl TryFrom<&str> for Setting {
9193
"chat.defaultModel" => Ok(Self::ChatDefaultModel),
9294
"chat.defaultAgent" => Ok(Self::ChatDefaultAgent),
9395
"chat.disableAutoCompaction" => Ok(Self::ChatDisableAutoCompaction),
96+
"chat.enableHistoryHints" => Ok(Self::ChatEnableHistoryHints),
9497
_ => Err(DatabaseError::InvalidSetting(value.to_string())),
9598
}
9699
}

0 commit comments

Comments
 (0)