From eca349a706abb58c189655d02a5681e4455c01ad Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Thu, 3 Sep 2026 18:32:41 +0500 Subject: [PATCH] feat: edit config command --- src/cli.rs | 3 +++ src/config.rs | 9 +++++---- src/main.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 0568d89..d4a2266 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -42,6 +42,9 @@ pub enum Commands { /// List all available servers ListServers, + + /// Open global config in $EDITOR + EditConfig, } #[derive(Args, Debug)] diff --git a/src/config.rs b/src/config.rs index 3f5513a..5f7bce9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -184,11 +184,12 @@ pub fn display(path: &Path) -> String { format!("~/{}", rest.to_string_lossy().replace('\\', "/")) } +pub fn global_config_path(home: Option<&Path>) -> Option { + Some(home?.join(".config").join(GLOBAL_DIR).join(CONFIG_FILE_NAME)) +} + pub fn global_path(home: Option<&Path>) -> Option { - let path = home? - .join(".config") - .join(GLOBAL_DIR) - .join(CONFIG_FILE_NAME); + let path = global_config_path(home)?; path.is_file().then_some(path) } diff --git a/src/main.rs b/src/main.rs index dbf7fb3..869adaa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ mod local; mod ssh; mod sync; -use std::{path::Path, process::ExitCode}; +use std::{fs, path::Path, process::ExitCode}; use anyhow::{Context, Result, bail}; use clap::Parser; @@ -54,6 +54,56 @@ fn handle_list(path: &Path, cfg: &config::Config) -> Result<()> { Ok(()) } +fn handle_edit_config() -> Result<()> { + let path = config::global_config_path(home::home_dir().as_deref()) + .context("cannot determine home directory")?; + + if let Some(parent) = path.parent() { + fs::create_dir_all(parent) + .with_context(|| format!("cannot create {}", parent.display()))?; + } + if !path.exists() { + fs::write(&path, "").with_context(|| format!("cannot create {}", path.display()))?; + } + + let editor = std::env::var("EDITOR") + .or_else(|_| std::env::var("VISUAL")) + .unwrap_or_else(|_| { + #[cfg(target_os = "windows")] + { + "notepad".to_string() + } + #[cfg(not(target_os = "windows"))] + { + "vi".to_string() + } + }); + + let cmd = format!("{editor} {}", path.display()); + let mut process = { + #[cfg(target_os = "windows")] + { + let mut c = std::process::Command::new("cmd"); + c.arg("/C").arg(&cmd); + c + } + #[cfg(not(target_os = "windows"))] + { + let mut c = std::process::Command::new("sh"); + c.arg("-c").arg(&cmd); + c + } + }; + let status = process + .status() + .with_context(|| format!("failed to launch editor: {editor}"))?; + + if !status.success() { + std::process::exit(status.code().unwrap_or(1)); + } + Ok(()) +} + fn handle_list_servers(path: &Path, cfg: &config::Config) -> Result<()> { println!("config: {}", config::display(path)); println!("configured servers:"); @@ -112,6 +162,7 @@ fn run(cli: &Cli) -> Result<()> { Some(Commands::Pick) => handle_pick(cli, &path, &cfg), Some(Commands::List) => handle_list(&path, &cfg), Some(Commands::ListServers) => handle_list_servers(&path, &cfg), + Some(Commands::EditConfig) => handle_edit_config(), None => handle_default(&path, &cfg), } }