export functionality and session management
This commit is contained in:
114
src/cli.rs
114
src/cli.rs
@@ -201,6 +201,12 @@ impl ChatCLI {
|
||||
"/history" => {
|
||||
self.handle_history_command(&parts)?;
|
||||
}
|
||||
"/export" => {
|
||||
self.handle_export_command(&parts)?;
|
||||
}
|
||||
"/save" => {
|
||||
self.handle_save_command(&parts)?;
|
||||
}
|
||||
_ => {
|
||||
self.display.print_error(&format!("Unknown command: {} (see /help)", parts[0]));
|
||||
}
|
||||
@@ -490,4 +496,112 @@ impl ChatCLI {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_export_command(&mut self, parts: &[&str]) -> Result<()> {
|
||||
let format = if parts.len() > 1 {
|
||||
parts[1].to_lowercase()
|
||||
} else {
|
||||
// Default to markdown
|
||||
"markdown".to_string()
|
||||
};
|
||||
|
||||
let valid_formats = ["markdown", "md", "json", "txt"];
|
||||
if !valid_formats.contains(&format.as_str()) {
|
||||
self.display.print_error(&format!(
|
||||
"Invalid format '{}'. Supported formats: markdown, json, txt",
|
||||
format
|
||||
));
|
||||
self.display.print_info("Usage: /export [format]");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Generate filename with timestamp
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
|
||||
let extension = match format.as_str() {
|
||||
"markdown" | "md" => "md",
|
||||
"json" => "json",
|
||||
"txt" => "txt",
|
||||
_ => "md",
|
||||
};
|
||||
|
||||
// Create exports directory if it doesn't exist
|
||||
let exports_dir = std::path::Path::new("exports");
|
||||
if !exports_dir.exists() {
|
||||
if let Err(e) = std::fs::create_dir(exports_dir) {
|
||||
self.display.print_error(&format!("Failed to create exports directory: {}", e));
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let filename = format!("{}_{}.{}", self.session.name, now, extension);
|
||||
let file_path = exports_dir.join(&filename);
|
||||
|
||||
match self.session.export(&format, file_path.to_str().unwrap_or(&filename)) {
|
||||
Ok(()) => {
|
||||
self.display.print_command_result(&format!(
|
||||
"Conversation exported to '{}'",
|
||||
file_path.display()
|
||||
));
|
||||
}
|
||||
Err(e) => {
|
||||
self.display.print_error(&format!("Export failed: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_save_command(&mut self, parts: &[&str]) -> Result<()> {
|
||||
if parts.len() != 2 {
|
||||
self.display.print_error("Usage: /save <new_session_name>");
|
||||
self.display.print_info("Example: /save my_important_conversation");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let new_session_name = parts[1];
|
||||
|
||||
// Validate session name
|
||||
if new_session_name.is_empty() {
|
||||
self.display.print_error("Session name cannot be empty");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Check if session already exists
|
||||
if let Ok(sessions) = Session::list_sessions() {
|
||||
if sessions.iter().any(|(name, _)| name == new_session_name) {
|
||||
self.display.print_error(&format!(
|
||||
"Session '{}' already exists. Choose a different name.",
|
||||
new_session_name
|
||||
));
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
// Save the current session first to ensure it's up to date
|
||||
self.session.save()?;
|
||||
|
||||
// Copy the session with the new name
|
||||
match self.session.save_as(new_session_name) {
|
||||
Ok(()) => {
|
||||
self.display.print_command_result(&format!(
|
||||
"Current session saved as '{}' ({} messages copied)",
|
||||
new_session_name,
|
||||
self.session.messages.len().saturating_sub(1) // Exclude system prompt
|
||||
));
|
||||
self.display.print_info(&format!(
|
||||
"Use '/switch' to switch to the new session, or continue with current session '{}'",
|
||||
self.session.name
|
||||
));
|
||||
}
|
||||
Err(e) => {
|
||||
self.display.print_error(&format!("Failed to save session: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user