diff --git a/crates/goose-cli/src/session/builder.rs b/crates/goose-cli/src/session/builder.rs index ba2f37f3..9782dea3 100644 --- a/crates/goose-cli/src/session/builder.rs +++ b/crates/goose-cli/src/session/builder.rs @@ -7,6 +7,7 @@ use goose::recipe::{Response, SubRecipe}; use goose::session; use goose::session::Identifier; use mcp_client::transport::Error as McpClientError; +use rustyline::EditMode; use std::process; use std::sync::Arc; @@ -136,6 +137,7 @@ async fn offer_extension_debugging_help( false, None, None, + None, ); // Process the debugging request @@ -383,6 +385,19 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session { } } + // Determine editor mode + let edit_mode = config + .get_param::("EDIT_MODE") + .ok() + .and_then(|edit_mode| match edit_mode.to_lowercase().as_str() { + "emacs" => Some(EditMode::Emacs), + "vi" => Some(EditMode::Vi), + _ => { + eprintln!("Invalid EDIT_MODE specified, defaulting to Emacs"); + None + } + }); + // Create new session let mut session = Session::new( agent, @@ -390,6 +405,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session { session_config.debug, session_config.scheduled_job_id.clone(), session_config.max_turns, + edit_mode, ); // Add extensions if provided diff --git a/crates/goose-cli/src/session/mod.rs b/crates/goose-cli/src/session/mod.rs index 27ec8507..a3784b79 100644 --- a/crates/goose-cli/src/session/mod.rs +++ b/crates/goose-cli/src/session/mod.rs @@ -32,6 +32,7 @@ use mcp_core::protocol::JsonRpcMessage; use mcp_core::protocol::JsonRpcNotification; use rand::{distributions::Alphanumeric, Rng}; +use rustyline::EditMode; use serde_json::Value; use std::collections::HashMap; use std::path::PathBuf; @@ -54,6 +55,7 @@ pub struct Session { run_mode: RunMode, scheduled_job_id: Option, // ID of the scheduled job that triggered this session max_turns: Option, + edit_mode: Option, } // Cache structure for completion data @@ -116,6 +118,7 @@ impl Session { debug: bool, scheduled_job_id: Option, max_turns: Option, + edit_mode: Option, ) -> Self { let messages = if let Some(session_file) = &session_file { match session::read_messages(session_file) { @@ -139,6 +142,7 @@ impl Session { run_mode: RunMode::Normal, scheduled_job_id, max_turns, + edit_mode, } } @@ -399,9 +403,15 @@ impl Session { self.update_completion_cache().await?; // Create a new editor with our custom completer - let config = rustyline::Config::builder() - .completion_type(rustyline::CompletionType::Circular) - .build(); + let builder = + rustyline::Config::builder().completion_type(rustyline::CompletionType::Circular); + let builder = if let Some(edit_mode) = self.edit_mode { + builder.edit_mode(edit_mode) + } else { + // Default to Emacs mode if no edit mode is set + builder.edit_mode(EditMode::Emacs) + }; + let config = builder.build(); let mut editor = rustyline::Editor::::with_config( config,