From 42e0f0a225d0142eaea512fa4fecc08a2c1110ed Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Tue, 23 Aug 2022 12:03:17 -0700 Subject: [PATCH] helix-term: introduce cdf / change-directory-to-current-file This will set the current working directory to that of the current file's parent. --- book/src/generated/typable-cmd.md | 1 + helix-term/src/commands/typed.rs | 55 +++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 4cbff3061a440..296e9c9e9afdc 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -41,6 +41,7 @@ | `:primary-clipboard-paste-replace` | Replace selections with content of system primary clipboard. | | `:show-clipboard-provider` | Show clipboard provider name in status bar. | | `:change-current-directory`, `:cd` | Change the current working directory. | +| `:change-directory-to-current-file`, `:cdf` | Change the current working directory to the parent of the current document if provided no arguments. | | `:show-directory`, `:pwd` | Show the current working directory. | | `:encoding` | Set encoding. Based on `https://encoding.spec.whatwg.org`. | | `:reload` | Discard changes and reload from the source file. | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 96ff75c54a0f3..806e6fbaaef95 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -929,6 +929,43 @@ fn show_clipboard_provider( Ok(()) } +fn change_directory_impl(cx: &mut compositor::Context, dir: &Path) -> anyhow::Result<()> { + if let Err(e) = std::env::set_current_dir(dir) { + bail!("Couldn't change the current working directory: {}", e); + } + + let cwd = std::env::current_dir().context("Couldn't get the new working directory")?; + cx.editor.set_status(format!( + "Current working directory is now {}", + cwd.display() + )); + + Ok(()) +} + +fn change_directory_to_current_file( + cx: &mut compositor::Context, + _args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + let (_, doc) = current_ref!(cx.editor); + let dir = match doc.path() { + Some(path) => path + .parent() + .map(ToOwned::to_owned) + .context("Couldn't get parent of current document")?, + None => { + bail!("Current document has no path"); + } + }; + + change_directory_impl(cx, &dir) +} + fn change_current_directory( cx: &mut compositor::Context, args: &[Cow], @@ -945,16 +982,7 @@ fn change_current_directory( .as_ref(), ); - if let Err(e) = std::env::set_current_dir(dir) { - bail!("Couldn't change the current working directory: {}", e); - } - - let cwd = std::env::current_dir().context("Couldn't get the new working directory")?; - cx.editor.set_status(format!( - "Current working directory is now {}", - cwd.display() - )); - Ok(()) + change_directory_impl(cx, &dir) } fn show_current_directory( @@ -1897,6 +1925,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: change_current_directory, completer: Some(completers::directory), }, + TypableCommand { + name: "change-directory-to-current-file", + aliases: &["cdf"], + doc: "Change the current working directory to the parent of the current document if provided no arguments.", + fun: change_directory_to_current_file, + completer: Some(completers::directory), + }, TypableCommand { name: "show-directory", aliases: &["pwd"],