diff options
author | Pascal Kuthe | 2024-01-28 16:34:45 +0000 |
---|---|---|
committer | GitHub | 2024-01-28 16:34:45 +0000 |
commit | 87a720c3a13ccc7245f5b0befc008db5bd039032 (patch) | |
tree | e0e3f91c516a10d154cd01861e96ae0f50ea3cad /helix-term/src/commands/typed.rs | |
parent | f5b67d9acb89ea54e7226111e3e4d8c3a008144b (diff) |
make path changes LSP spec conform (#8949)
Currently, helix implements operations which change the paths of files
incorrectly and inconsistently. This PR ensures that we do the following
whenever a buffer is renamed (`:move` and workspace edits)
* always send did_open/did_close notifications
* send will_rename/did_rename requests correctly
* send them to all LSP servers not just those that are active for a
buffer
* also send these requests for paths that are not yet open in a buffer (if
triggered from workspace edit).
* only send these if the server registered interests in the path
* autodetect language, indent, line ending, ..
This PR also centralizes the infrastructure for path setting and
therefore `:w <path>` benefits from similar fixed (but without didRename)
Diffstat (limited to 'helix-term/src/commands/typed.rs')
-rw-r--r-- | helix-term/src/commands/typed.rs | 62 |
1 files changed, 4 insertions, 58 deletions
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 81ffdf87..b7ceeba5 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -8,7 +8,6 @@ use super::*; use helix_core::fuzzy::fuzzy_match; use helix_core::indent::MAX_INDENT; use helix_core::{encoding, line_ending, 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; @@ -2404,67 +2403,14 @@ fn move_buffer( ensure!(args.len() == 1, format!(":move takes one argument")); let doc = doc!(cx.editor); - - let new_path = - helix_stdx::path::canonicalize(&PathBuf::from(args.first().unwrap().to_string())); let old_path = doc .path() - .ok_or_else(|| anyhow!("Scratch buffer cannot be moved. Use :write instead"))? + .context("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<helix_lsp::lsp::WorkspaceEdit>, - 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 new_path = args.first().unwrap().to_string(); + if let Err(err) = cx.editor.move_path(&old_path, new_path.as_ref()) { + bail!("Could not move file: {err}"); } - - 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(()) } |