From e868678139bc8f4f5b14236c3c3c3f6aa4aab47b Mon Sep 17 00:00:00 2001 From: Yomain Date: Wed, 8 Nov 2023 19:38:17 +0100 Subject: Add command to move files with LSP support (#8584) * Added rename command * Added an error if the new path already exists * Fixed wrong command name being used * fixed clippy suggestions * removed didRenameFiles call, fixed early return due to path Err * added ':rnm' alias to ':rename' * code cleanup * formatting * removed debug line * cargo fmt * Improved new buffer error message Co-authored-by: Pascal Kuthe * Removed unnecessary path normalizing Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * feat: change `rename` command to `move` * feat: add multi lsp support when moving files * feat: allow lsp calls with a custom timeout * feat: sending lsp file_changed event once file has moved --------- Co-authored-by: ontley Co-authored-by: ontley <67148677+ontley@users.noreply.github.com> Co-authored-by: Pascal Kuthe --- helix-term/src/commands/typed.rs | 84 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'helix-term') diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index e7343308..4148257f 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -6,7 +6,8 @@ use crate::job::Job; use super::*; use helix_core::fuzzy::fuzzy_match; -use helix_core::{encoding, line_ending, shellwords::Shellwords}; +use helix_core::{encoding, line_ending, path::get_canonicalized_path, shellwords::Shellwords}; +use helix_lsp::{OffsetEncoding, Url}; use helix_view::document::DEFAULT_LANGUAGE_NAME; use helix_view::editor::{Action, CloseError, ConfigEvent}; use serde_json::Value; @@ -2408,6 +2409,80 @@ fn redraw( Ok(()) } +fn move_buffer( + cx: &mut compositor::Context, + args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + ensure!(args.len() == 1, format!(":move takes one argument")); + let doc = doc!(cx.editor); + + let new_path = get_canonicalized_path(&PathBuf::from(args.first().unwrap().to_string())); + let old_path = doc + .path() + .ok_or_else(|| anyhow!("Scratch buffer cannot be moved. Use :write instead"))? + .clone(); + let old_path_as_url = doc.url().unwrap(); + let new_path_as_url = Url::from_file_path(&new_path).unwrap(); + + let edits: Vec<( + helix_lsp::Result, + OffsetEncoding, + String, + )> = doc + .language_servers() + .map(|lsp| { + ( + lsp.prepare_file_rename(&old_path_as_url, &new_path_as_url), + lsp.offset_encoding(), + lsp.name().to_owned(), + ) + }) + .filter(|(f, _, _)| f.is_some()) + .map(|(f, encoding, name)| (helix_lsp::block_on(f.unwrap()), encoding, name)) + .collect(); + + for (lsp_reply, encoding, name) in edits { + match lsp_reply { + Ok(edit) => { + if let Err(e) = apply_workspace_edit(cx.editor, encoding, &edit) { + log::error!( + ":move command failed to apply edits from lsp {}: {:?}", + name, + e + ); + }; + } + Err(e) => { + log::error!("LSP {} failed to treat willRename request: {:?}", name, e); + } + }; + } + + let doc = doc_mut!(cx.editor); + + doc.set_path(Some(new_path.as_path())); + if let Err(e) = std::fs::rename(&old_path, &new_path) { + doc.set_path(Some(old_path.as_path())); + bail!("Could not move file: {}", e); + }; + + doc.language_servers().for_each(|lsp| { + lsp.did_file_rename(&old_path_as_url, &new_path_as_url); + }); + + cx.editor + .language_servers + .file_event_handler + .file_changed(new_path); + + Ok(()) +} + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -3008,6 +3083,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: redraw, signature: CommandSignature::none(), }, + TypableCommand { + name: "move", + aliases: &[], + doc: "Move the current buffer and its corresponding file to a different path", + fun: move_buffer, + signature: CommandSignature::positional(&[completers::filename]), + }, ]; pub static TYPABLE_COMMAND_MAP: Lazy> = -- cgit v1.2.3-70-g09d2