feat: enable native readonly diff interaction and synchronized pane cursors

This commit is contained in:
2026-10-11 11:31:59 +02:00
parent f43a43fd53
commit 5186714ef5
8 changed files with 1329 additions and 272 deletions
+19 -11
View File
@@ -263,10 +263,11 @@ impl EditorSession {
comparison_id: u64,
file: usize,
top: usize,
left_before: usize,
left_after: usize,
) {
self.editor
.set_diff_viewport(comparison_id, file, top, left_after);
.set_diff_viewport(comparison_id, file, top, left_before, left_after);
}
pub(crate) fn scroll_diff(&mut self, focus: Focus, down: bool) {
@@ -405,7 +406,7 @@ impl EditorSession {
return;
}
let context = self.editor.context();
let read_only = self.editor.diff().is_some() && !self.editor.diff_editing();
let read_only = self.editor.mutation_blocked();
let result = match self.plugins.get_mut(&invocation.plugin) {
Some(plugin) if plugin.is_async() => {
let requests = self.requests.entry(invocation.plugin.clone()).or_default();
@@ -483,7 +484,7 @@ impl EditorSession {
}
let mut events = Vec::new();
if !self.editor.should_quit() {
for document in self.editor.documents() {
for document in self.editor.interaction_documents() {
let path = document.path.map(Path::to_string_lossy);
let previous = self.documents.get(&document.id);
let renamed = previous
@@ -576,7 +577,7 @@ impl EditorSession {
fn source_is_current(&self, source: InvocationSource) -> bool {
self.editor
.documents()
.interaction_documents()
.any(|document| document.id == source.buffer_id && document.revision == source.revision)
}
@@ -586,7 +587,7 @@ impl EditorSession {
request_id: Option<u64>,
source: InvocationSource,
) -> bool {
if self.editor.diff().is_some() && !self.editor.diff_editing() {
if self.editor.diff().is_some() && !self.editor.diff_interacting() {
return false;
}
self.editor.buffer_id() == source.buffer_id
@@ -622,6 +623,7 @@ impl EditorSession {
fn completion_is_current(&self, request_id: Option<u64>, source: InvocationSource) -> bool {
self.pending_completion
&& !self.editor.mutation_blocked()
&& self.request_is_current("core", request_id, source)
&& self.editor.mode() == Mode::Insert
&& self.editor.palette().is_none()
@@ -855,7 +857,7 @@ impl EditorSession {
}
return Ok(changed);
}
if self.editor.diff().is_some() && !self.editor.diff_editing() {
if self.editor.mutation_blocked() {
return Ok(false);
}
let changed = !effects.is_empty();
@@ -3425,29 +3427,35 @@ end
.apply_response("fixture", 2, vec![Effect::Insert("stale".into())])
.unwrap()
);
let current = InvocationSource {
session.editor.scroll_diff(Focus::Before, false);
let readonly = InvocationSource {
buffer_id: session.editor.buffer_id(),
revision: session.editor.text_revision(),
};
session.editor.scroll_diff(Focus::Before, false);
session
.requests
.get_mut("fixture")
.unwrap()
.pending
.insert(3, current);
.insert(3, readonly);
assert!(
!session
.apply_response("fixture", 3, vec![Effect::Insert("readonly".into())])
.unwrap()
);
assert_eq!(session.editor.lines(), ["acceptedbase"]);
assert_eq!(session.editor.lines(), ["base"]);
assert!(
session
.editor
.documents()
.any(|document| document.lines == ["acceptedbase"])
);
session
.requests
.get_mut("fixture")
.unwrap()
.pending
.insert(4, current);
.insert(4, readonly);
assert!(
session
.apply_response("fixture", 4, vec![Effect::Message("allowed".into())])