Add the ability to configure rustyline to use a different edit mode (e.g. vi) (#2769)

Co-authored-by: Jack Wright <jack.wright@nike.com>
Co-authored-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
Jack Wright
2025-07-13 17:36:06 -07:00
committed by GitHub
parent 3bc36307dc
commit ad1e322854
2 changed files with 29 additions and 3 deletions

View File

@@ -7,6 +7,7 @@ use goose::recipe::{Response, SubRecipe};
use goose::session; use goose::session;
use goose::session::Identifier; use goose::session::Identifier;
use mcp_client::transport::Error as McpClientError; use mcp_client::transport::Error as McpClientError;
use rustyline::EditMode;
use std::process; use std::process;
use std::sync::Arc; use std::sync::Arc;
@@ -136,6 +137,7 @@ async fn offer_extension_debugging_help(
false, false,
None, None,
None, None,
None,
); );
// Process the debugging request // 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::<String>("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 // Create new session
let mut session = Session::new( let mut session = Session::new(
agent, agent,
@@ -390,6 +405,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
session_config.debug, session_config.debug,
session_config.scheduled_job_id.clone(), session_config.scheduled_job_id.clone(),
session_config.max_turns, session_config.max_turns,
edit_mode,
); );
// Add extensions if provided // Add extensions if provided

View File

@@ -32,6 +32,7 @@ use mcp_core::protocol::JsonRpcMessage;
use mcp_core::protocol::JsonRpcNotification; use mcp_core::protocol::JsonRpcNotification;
use rand::{distributions::Alphanumeric, Rng}; use rand::{distributions::Alphanumeric, Rng};
use rustyline::EditMode;
use serde_json::Value; use serde_json::Value;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
@@ -54,6 +55,7 @@ pub struct Session {
run_mode: RunMode, run_mode: RunMode,
scheduled_job_id: Option<String>, // ID of the scheduled job that triggered this session scheduled_job_id: Option<String>, // ID of the scheduled job that triggered this session
max_turns: Option<u32>, max_turns: Option<u32>,
edit_mode: Option<EditMode>,
} }
// Cache structure for completion data // Cache structure for completion data
@@ -116,6 +118,7 @@ impl Session {
debug: bool, debug: bool,
scheduled_job_id: Option<String>, scheduled_job_id: Option<String>,
max_turns: Option<u32>, max_turns: Option<u32>,
edit_mode: Option<EditMode>,
) -> Self { ) -> Self {
let messages = if let Some(session_file) = &session_file { let messages = if let Some(session_file) = &session_file {
match session::read_messages(session_file) { match session::read_messages(session_file) {
@@ -139,6 +142,7 @@ impl Session {
run_mode: RunMode::Normal, run_mode: RunMode::Normal,
scheduled_job_id, scheduled_job_id,
max_turns, max_turns,
edit_mode,
} }
} }
@@ -399,9 +403,15 @@ impl Session {
self.update_completion_cache().await?; self.update_completion_cache().await?;
// Create a new editor with our custom completer // Create a new editor with our custom completer
let config = rustyline::Config::builder() let builder =
.completion_type(rustyline::CompletionType::Circular) rustyline::Config::builder().completion_type(rustyline::CompletionType::Circular);
.build(); 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 = let mut editor =
rustyline::Editor::<GooseCompleter, rustyline::history::DefaultHistory>::with_config( rustyline::Editor::<GooseCompleter, rustyline::history::DefaultHistory>::with_config(
config, config,