feat: support comments in ordinary source buffers
This commit is contained in:
+99
-59
@@ -990,96 +990,91 @@ core_actions![
|
||||
true,
|
||||
),
|
||||
(
|
||||
"core.diff.comment",
|
||||
Action::DiffComment,
|
||||
"core.comment",
|
||||
Action::Comment,
|
||||
&[Mode::Normal, Mode::Visual],
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.edit",
|
||||
"core.review.edit",
|
||||
Action::ReviewEdit,
|
||||
&[Mode::Normal],
|
||||
true,
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.delete",
|
||||
"core.review.delete",
|
||||
Action::ReviewDelete,
|
||||
&[Mode::Normal],
|
||||
true,
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.resolve",
|
||||
"core.review.resolve",
|
||||
Action::ReviewResolve,
|
||||
&[Mode::Normal],
|
||||
true,
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.unresolve",
|
||||
"core.review.unresolve",
|
||||
Action::ReviewUnresolve,
|
||||
&[Mode::Normal],
|
||||
true,
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.next",
|
||||
"core.review.next",
|
||||
Action::ReviewNext,
|
||||
&[Mode::Normal],
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.previous",
|
||||
"core.review.previous",
|
||||
Action::ReviewPrevious,
|
||||
&[Mode::Normal],
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.overview",
|
||||
"core.review.overview",
|
||||
Action::ReviewOverview,
|
||||
&[Mode::Normal],
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.copy",
|
||||
"core.review.copy",
|
||||
Action::ReviewCopy,
|
||||
&[Mode::Normal],
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.summary",
|
||||
"core.review.summary",
|
||||
Action::ReviewSummary,
|
||||
&[Mode::Normal],
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.verdict",
|
||||
"core.review.verdict",
|
||||
Action::ReviewVerdict,
|
||||
&[Mode::Normal],
|
||||
true,
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.save",
|
||||
"core.review.save",
|
||||
Action::ReviewSave,
|
||||
&[Mode::Normal],
|
||||
true,
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.open",
|
||||
"core.review.open",
|
||||
Action::ReviewOpen,
|
||||
&[Mode::Normal],
|
||||
true,
|
||||
true
|
||||
),
|
||||
(
|
||||
"core.diff.review.new",
|
||||
Action::ReviewNew,
|
||||
&[Mode::Normal],
|
||||
true
|
||||
),
|
||||
("core.review.new", Action::ReviewNew, &[Mode::Normal], true),
|
||||
(
|
||||
"core.word_wrap.toggle",
|
||||
Action::WordWrapToggle,
|
||||
@@ -1193,6 +1188,20 @@ const COMMAND_ALIASES: &[(&str, Action)] = &[
|
||||
("bprev", Action::BufferPrevious),
|
||||
("bdelete", Action::BufferDelete),
|
||||
("bdelete!", Action::BufferForceDelete),
|
||||
("diff.comment", Action::Comment),
|
||||
("diff.review.edit", Action::ReviewEdit),
|
||||
("diff.review.delete", Action::ReviewDelete),
|
||||
("diff.review.resolve", Action::ReviewResolve),
|
||||
("diff.review.unresolve", Action::ReviewUnresolve),
|
||||
("diff.review.next", Action::ReviewNext),
|
||||
("diff.review.previous", Action::ReviewPrevious),
|
||||
("diff.review.overview", Action::ReviewOverview),
|
||||
("diff.review.copy", Action::ReviewCopy),
|
||||
("diff.review.summary", Action::ReviewSummary),
|
||||
("diff.review.verdict", Action::ReviewVerdict),
|
||||
("diff.review.save", Action::ReviewSave),
|
||||
("diff.review.open", Action::ReviewOpen),
|
||||
("diff.review.new", Action::ReviewNew),
|
||||
];
|
||||
|
||||
fn core_command(name: &str) -> Option<&'static CoreAction> {
|
||||
@@ -1893,6 +1902,7 @@ struct Tab {
|
||||
pane_id: usize,
|
||||
pane_layout: PaneTree,
|
||||
review_pane: Option<usize>,
|
||||
local_review: crate::review::ReviewState,
|
||||
file_picker: Option<FilePicker>,
|
||||
diff: Option<DiffState>,
|
||||
parked_diff: Option<DiffState>,
|
||||
@@ -2200,6 +2210,7 @@ pub struct Editor {
|
||||
panes: BTreeMap<usize, Pane>,
|
||||
pane_layout: PaneTree,
|
||||
review_pane: Option<usize>,
|
||||
pub(crate) local_review: crate::review::ReviewState,
|
||||
tab_id: usize,
|
||||
next_tab_id: usize,
|
||||
tab_order: Vec<usize>,
|
||||
@@ -2313,6 +2324,7 @@ impl Editor {
|
||||
)]),
|
||||
pane_layout: PaneTree::new(1),
|
||||
review_pane: None,
|
||||
local_review: Default::default(),
|
||||
tab_id: 1,
|
||||
next_tab_id: 2,
|
||||
tab_order: vec![1],
|
||||
@@ -3663,6 +3675,7 @@ impl Editor {
|
||||
pane_id: std::mem::replace(&mut self.pane_id, next.pane_id),
|
||||
pane_layout: std::mem::replace(&mut self.pane_layout, next.pane_layout),
|
||||
review_pane: std::mem::replace(&mut self.review_pane, next.review_pane),
|
||||
local_review: std::mem::replace(&mut self.local_review, next.local_review),
|
||||
file_picker: std::mem::replace(&mut self.file_picker, next.file_picker),
|
||||
diff: std::mem::replace(&mut self.diff, next.diff),
|
||||
parked_diff: std::mem::replace(&mut self.parked_diff, next.parked_diff),
|
||||
@@ -3712,6 +3725,7 @@ impl Editor {
|
||||
pane_id,
|
||||
pane_layout: PaneTree::new(pane_id),
|
||||
review_pane: None,
|
||||
local_review: Default::default(),
|
||||
file_picker: None,
|
||||
diff: None,
|
||||
parked_diff: None,
|
||||
@@ -3814,11 +3828,6 @@ impl Editor {
|
||||
|
||||
// No input dispatch or document copies: source documents stay unique in active/parked.
|
||||
fn select_pane(&mut self, id: usize) {
|
||||
let id = if self.review_pane == Some(id) && self.workspace_diff().is_none() {
|
||||
self.panes[&id].origin.unwrap_or(id)
|
||||
} else {
|
||||
id
|
||||
};
|
||||
if id == self.pane_id {
|
||||
return;
|
||||
}
|
||||
@@ -4223,7 +4232,12 @@ impl Editor {
|
||||
return;
|
||||
}
|
||||
self.finish_pane_interaction();
|
||||
if self.diff_owner == Some(id) && !force && self.local_review_close_blocked() {
|
||||
let review_source =
|
||||
self.review_pane.and_then(|panel| self.panes[&panel].origin) == Some(id);
|
||||
if (self.diff_owner == Some(id) || review_source)
|
||||
&& !force
|
||||
&& self.local_review_close_blocked()
|
||||
{
|
||||
return;
|
||||
}
|
||||
if self.diff_owner == Some(id) {
|
||||
@@ -4236,6 +4250,9 @@ impl Editor {
|
||||
}
|
||||
let next = self.pane_layout.close(id).expect("another pane exists");
|
||||
self.select_pane(next);
|
||||
if review_source && let Some(panel) = self.review_pane {
|
||||
self.panes.get_mut(&panel).unwrap().origin = Some(next);
|
||||
}
|
||||
self.panes.remove(&id);
|
||||
for buffer in buffers {
|
||||
self.forget_buffer(buffer);
|
||||
@@ -4627,11 +4644,17 @@ impl Editor {
|
||||
view.clamp(&self.active.lines);
|
||||
self.active.view = view;
|
||||
}
|
||||
if let Err(error) = self.initialize_local_review() {
|
||||
if self.review_directory.is_some()
|
||||
&& self.resolver().is_none()
|
||||
&& self
|
||||
.workspace_diff()
|
||||
.is_some_and(|diff| diff.phase == Phase::View)
|
||||
&& let Err(error) = self.initialize_local_review()
|
||||
{
|
||||
self.set_message(format!("Local review: {error}"));
|
||||
}
|
||||
if restore_reviewed && let Some(diff) = &mut self.diff {
|
||||
diff.restore_reviewed_files();
|
||||
diff.restore_reviewed_files(&self.local_review);
|
||||
}
|
||||
let reviewed = self.diff.as_mut().and_then(|diff| {
|
||||
(refresh
|
||||
@@ -5190,16 +5213,19 @@ impl Editor {
|
||||
|
||||
pub(crate) fn refresh_live_diff(&mut self) {
|
||||
self.refresh_resolver_comparison();
|
||||
for diff in self
|
||||
.diff
|
||||
.iter_mut()
|
||||
.chain(self.parked_diff.iter_mut())
|
||||
.chain(
|
||||
self.tabs
|
||||
.values_mut()
|
||||
.flat_map(|tab| tab.diff.iter_mut().chain(tab.parked_diff.iter_mut())),
|
||||
)
|
||||
{
|
||||
for (diff, parked, review) in std::iter::once((
|
||||
&mut self.diff,
|
||||
&mut self.parked_diff,
|
||||
&mut self.local_review,
|
||||
))
|
||||
.chain(
|
||||
self.tabs
|
||||
.values_mut()
|
||||
.map(|tab| (&mut tab.diff, &mut tab.parked_diff, &mut tab.local_review)),
|
||||
) {
|
||||
let Some(diff) = diff.as_mut().or(parked.as_mut()) else {
|
||||
continue;
|
||||
};
|
||||
let buffer = diff.live_buffer.and_then(|id| {
|
||||
if id == self.active.id {
|
||||
Some(&self.active)
|
||||
@@ -5211,7 +5237,7 @@ impl Editor {
|
||||
&& diff.live_after_available()
|
||||
&& diff.live_revision != Some(buffer.text_revision)
|
||||
{
|
||||
diff.refresh_after(&buffer.lines, buffer.text_revision);
|
||||
diff.refresh_after(&buffer.lines, buffer.text_revision, review);
|
||||
diff.follow_caret = true;
|
||||
}
|
||||
}
|
||||
@@ -5485,7 +5511,7 @@ impl Editor {
|
||||
| Action::DiffViewToggle
|
||||
| Action::DiffOrientationToggle
|
||||
| Action::DiffReviewToggle
|
||||
| Action::DiffComment
|
||||
| Action::Comment
|
||||
| Action::ReviewEdit
|
||||
| Action::ReviewDelete
|
||||
| Action::ReviewResolve
|
||||
@@ -8917,7 +8943,7 @@ impl Editor {
|
||||
| Action::DiffViewToggle
|
||||
| Action::DiffOrientationToggle
|
||||
| Action::DiffReviewToggle
|
||||
| Action::DiffComment
|
||||
| Action::Comment
|
||||
| Action::ReviewEdit
|
||||
| Action::ReviewDelete
|
||||
| Action::ReviewResolve
|
||||
@@ -9559,15 +9585,22 @@ impl Editor {
|
||||
.map(|buffer| buffer.id);
|
||||
if let Some(id) = loaded {
|
||||
self.switch_buffer(id);
|
||||
return Ok(());
|
||||
} else {
|
||||
let buffer = Buffer::open(
|
||||
self.next_buffer_id,
|
||||
Some(path),
|
||||
Some(identity),
|
||||
allow_missing,
|
||||
)?;
|
||||
self.add_buffer(buffer);
|
||||
}
|
||||
if self.review_directory.is_some()
|
||||
&& self.workspace_diff().is_none()
|
||||
&& self.resolver().is_none()
|
||||
&& let Err(error) = self.initialize_local_review()
|
||||
{
|
||||
self.set_message(format!("Local review: {error}"));
|
||||
}
|
||||
let buffer = Buffer::open(
|
||||
self.next_buffer_id,
|
||||
Some(path),
|
||||
Some(identity),
|
||||
allow_missing,
|
||||
)?;
|
||||
self.add_buffer(buffer);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -9745,7 +9778,7 @@ impl Editor {
|
||||
|
||||
fn restart(&mut self, force: bool) {
|
||||
if !force && self.local_reviews_dirty() {
|
||||
self.set_message("Unsaved local review; use :diff.review.save <path>");
|
||||
self.set_message("Unsaved local review; use :review.save <path>");
|
||||
return;
|
||||
}
|
||||
if force || !self.any_dirty() {
|
||||
@@ -9876,7 +9909,7 @@ impl Editor {
|
||||
}
|
||||
if matches!(
|
||||
entry.action,
|
||||
Action::DiffComment
|
||||
Action::Comment
|
||||
| Action::ReviewEdit
|
||||
| Action::ReviewDelete
|
||||
| Action::ReviewResolve
|
||||
@@ -10102,15 +10135,15 @@ impl Editor {
|
||||
self.diff_return_buffer = Some(self.active.id);
|
||||
return None;
|
||||
}
|
||||
let Some(diff) = self
|
||||
.picker_diff_mut()
|
||||
.filter(|diff| diff.phase == Phase::View)
|
||||
else {
|
||||
self.set_message("No comparison is open");
|
||||
return None;
|
||||
};
|
||||
if entry.action == Action::DiffReviewToggle {
|
||||
match diff.toggle_reviewed() {
|
||||
let mut review = std::mem::take(&mut self.local_review);
|
||||
let result = self
|
||||
.picker_diff_mut()
|
||||
.filter(|diff| diff.phase == Phase::View)
|
||||
.ok_or("No comparison is open")
|
||||
.and_then(|diff| diff.toggle_reviewed(&mut review));
|
||||
self.local_review = review;
|
||||
match result {
|
||||
Ok(reviewed) => {
|
||||
if self.resolver().is_none()
|
||||
&& let Err(error) = self.autosave_local_review()
|
||||
@@ -10128,6 +10161,13 @@ impl Editor {
|
||||
}
|
||||
return None;
|
||||
}
|
||||
let Some(diff) = self
|
||||
.picker_diff_mut()
|
||||
.filter(|diff| diff.phase == Phase::View)
|
||||
else {
|
||||
self.set_message("No comparison is open");
|
||||
return None;
|
||||
};
|
||||
if entry.action == Action::DiffViewToggle {
|
||||
diff.set_view_mode(match diff.view_mode {
|
||||
ViewMode::Split => ViewMode::Unified,
|
||||
|
||||
Reference in New Issue
Block a user