From b9bde15c1fadd88ed35b915481d90ea2c799b8bb Mon Sep 17 00:00:00 2001 From: sigoden Date: Thu, 18 Apr 2024 18:22:15 +0800 Subject: feat: add config `buffer_editor` (#417) --- src/config/mod.rs | 30 ++++++++++++++++++------------ src/main.rs | 2 +- src/repl/mod.rs | 4 ++-- 3 files changed, 21 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/config/mod.rs b/src/config/mod.rs index 88235ac..963ad50 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -70,7 +70,9 @@ pub struct Config { /// REPL keybindings. (emacs, vi) pub keybindings: Keybindings, /// Set a default role or session (role:, session:) - pub prelude: String, + pub prelude: Option, + /// Command that will be used to edit the current line buffer + pub buffer_editor: Option, /// Compress session if tokens exceed this value (>=1000) pub compress_threshold: usize, /// The prompt for summarizing session messages @@ -115,7 +117,8 @@ impl Default for Config { ctrlc_exit: false, auto_copy: false, keybindings: Default::default(), - prelude: String::new(), + prelude: None, + buffer_editor: None, compress_threshold: 2000, summarize_prompt: "Summarize the discussion briefly in 200 words or less to use as a prompt for future context.".to_string(), summary_prompt: "This is a summary of the chat history as a recap: ".into(), @@ -171,8 +174,11 @@ impl Config { Ok(config) } - pub fn prelude(&mut self) -> Result<()> { - let prelude = self.prelude.clone(); + pub fn apply_prelude(&mut self) -> Result<()> { + let prelude = self.prelude.clone().unwrap_or_default(); + if prelude.is_empty() { + return Ok(()); + } let err_msg = || format!("Invalid prelude '{}", prelude); match prelude.split_once(':') { Some(("role", name)) => { @@ -185,14 +191,19 @@ impl Config { self.start_session(Some(name)).with_context(err_msg)?; } } - Some(_) => { + _ => { bail!("{}", err_msg()) } - None => {} } Ok(()) } + pub fn buffer_editor(&self) -> Option { + self.buffer_editor + .clone() + .or_else(|| env::var("VISUAL").ok().or_else(|| env::var("EDITOR").ok())) + } + pub fn retrieve_role(&self, name: &str) -> Result { self.roles .iter() @@ -413,11 +424,6 @@ impl Config { .wrap .clone() .map_or_else(|| String::from("no"), |v| v.to_string()); - let prelude = if self.prelude.is_empty() { - String::from("-") - } else { - self.prelude.clone() - }; let items = vec![ ("model", self.model.id()), ("temperature", format_option(&self.temperature)), @@ -430,7 +436,7 @@ impl Config { ("wrap_code", self.wrap_code.to_string()), ("auto_copy", self.auto_copy.to_string()), ("keybindings", self.keybindings.stringify().into()), - ("prelude", prelude), + ("prelude", format_option(&self.prelude)), ("compress_threshold", self.compress_threshold.to_string()), ("config_file", display_path(&Self::config_file()?)), ("roles_file", display_path(&Self::roles_file()?)), diff --git a/src/main.rs b/src/main.rs index be46bf1..90e1136 100644 --- a/src/main.rs +++ b/src/main.rs @@ -97,7 +97,7 @@ fn main() -> Result<()> { None => bail!("No input text"), } } - config.write().prelude()?; + config.write().apply_prelude()?; if let Err(err) = match input { Some(input) => start_directive(&config, input, cli.no_stream, cli.code), None => start_interactive(&config), diff --git a/src/repl/mod.rs b/src/repl/mod.rs index 30be73b..4de4251 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -316,7 +316,7 @@ Type ".help" for more information. .with_validator(Box::new(ReplValidator)) .with_ansi_colors(true); - if let Ok(cmd) = env::var("VISUAL").or_else(|_| env::var("EDITOR")) { + if let Some(cmd) = config.read().buffer_editor() { let temp_file = env::temp_dir().join(format!("aichat-{}.txt", chrono::Utc::now().timestamp())); let command = process::Command::new(cmd); @@ -425,7 +425,7 @@ fn dump_repl_help() { r###"{head} Type ::: to begin multi-line editing, type ::: to end it. -Press Ctrl+O to open an editor to modify the current prompt. +Press Ctrl+O to open an buffer editor to modify the current prompt. Press Ctrl+C to abort aichat, Ctrl+D to exit the REPL"###, ); } -- cgit v1.2.3