Update diff gutter on document save

pull/13590/head
Jasper Krauter 2025-05-22 11:02:46 +03:00
parent 3a6c9747b8
commit b963098f01
No known key found for this signature in database
GPG Key ID: D2648B695747DE42
2 changed files with 41 additions and 14 deletions

View File

@ -1239,10 +1239,7 @@ impl Document {
self.pickup_last_saved_time(); self.pickup_last_saved_time();
self.detect_indent_and_line_ending(); self.detect_indent_and_line_ending();
match provider_registry.get_diff_base(&path) { self.set_diff_base(provider_registry.get_diff_base(&path));
Some(diff_base) => self.set_diff_base(diff_base),
None => self.diff_handle = None,
}
self.version_control_head = provider_registry.get_current_head_name(&path); self.version_control_head = provider_registry.get_current_head_name(&path);
@ -1861,7 +1858,12 @@ impl Document {
} }
/// Intialize/updates the differ for this document with a new base. /// Intialize/updates the differ for this document with a new base.
pub fn set_diff_base(&mut self, diff_base: Vec<u8>) { /// If no base is given, the differ will be removed from the document.
pub fn set_diff_base(&mut self, diff_base: Option<Vec<u8>>) {
let Some(diff_base) = diff_base else {
self.diff_handle = None;
return;
};
if let Ok((diff_base, ..)) = from_reader(&mut diff_base.as_slice(), Some(self.encoding)) { if let Ok((diff_base, ..)) = from_reader(&mut diff_base.as_slice(), Some(self.encoding)) {
if let Some(differ) = &self.diff_handle { if let Some(differ) = &self.diff_handle {
differ.update_diff_base(diff_base); differ.update_diff_base(diff_base);

View File

@ -1452,17 +1452,27 @@ impl Editor {
Ok(()) Ok(())
} }
/// Set the document path for a `doc_id`. The new path can also be the
/// old path, in which case the diff base and language will still be
/// updated.
///
/// This method is called, for example, when executing the write command.
/// Among other necessary updates, it ensures that the correct path is
/// registered with the language server and that the vcs diff is w.r.t the
/// (potentially new) path.
pub fn set_doc_path(&mut self, doc_id: DocumentId, path: &Path) { pub fn set_doc_path(&mut self, doc_id: DocumentId, path: &Path) {
let doc = doc_mut!(self, &doc_id); let doc = doc_mut!(self, &doc_id);
let old_path = doc.path(); let old_path = doc.path();
if let Some(old_path) = old_path { if let Some(old_path) = old_path {
// sanity check, should not occur but some callers (like an LSP) may
// create bogus calls
if old_path == path { if old_path == path {
// Status of the file might have changed (new commit etc...)
self.refresh_diff_base(doc_id);
// Abort early
return; return;
} }
// if we are open in LSPs send did_close notification // The old path and new path differ, so close the old path in the
// LS by sending did_close notification
for language_server in doc.language_servers() { for language_server in doc.language_servers() {
language_server.text_document_did_close(doc.identifier()); language_server.text_document_did_close(doc.identifier());
} }
@ -1474,7 +1484,12 @@ impl Editor {
doc.language_servers.clear(); doc.language_servers.clear();
doc.set_path(Some(path)); doc.set_path(Some(path));
doc.detect_editor_config(); doc.detect_editor_config();
self.refresh_doc_language(doc_id) // Update the diff base to represent the base in the vcs on disk under
// the new path
self.refresh_diff_base(doc_id);
// The doc language might have changed because of a new file extension,
// or a new shebang.
self.refresh_doc_language(doc_id);
} }
pub fn refresh_doc_language(&mut self, doc_id: DocumentId) { pub fn refresh_doc_language(&mut self, doc_id: DocumentId) {
@ -1490,6 +1505,20 @@ impl Editor {
doc.reset_all_inlay_hints(); doc.reset_all_inlay_hints();
} }
fn refresh_diff_base(&mut self, doc_id: DocumentId) {
let doc = doc_mut!(self, &doc_id);
let (base, head) = {
let path = doc.path();
let base = path.and_then(|path| self.diff_providers.get_diff_base(path));
let head = path.and_then(|path| self.diff_providers.get_current_head_name(path));
(base, head)
};
doc.set_diff_base(base);
doc.set_version_control_head(head);
}
/// Launch a language server for a given document /// Launch a language server for a given document
fn launch_language_servers(&mut self, doc_id: DocumentId) { fn launch_language_servers(&mut self, doc_id: DocumentId) {
if !self.config().lsp.enable { if !self.config().lsp.enable {
@ -1790,13 +1819,9 @@ impl Editor {
Editor::doc_diagnostics(&self.language_servers, &self.diagnostics, &doc); Editor::doc_diagnostics(&self.language_servers, &self.diagnostics, &doc);
doc.replace_diagnostics(diagnostics, &[], None); doc.replace_diagnostics(diagnostics, &[], None);
if let Some(diff_base) = self.diff_providers.get_diff_base(&path) {
doc.set_diff_base(diff_base);
}
doc.set_version_control_head(self.diff_providers.get_current_head_name(&path));
let id = self.new_document(doc); let id = self.new_document(doc);
self.launch_language_servers(id); self.launch_language_servers(id);
self.refresh_diff_base(id);
helix_event::dispatch(DocumentDidOpen { helix_event::dispatch(DocumentDidOpen {
editor: self, editor: self,