feat: copy diff review comments to configured clipboard

This commit is contained in:
Valdemar Lorenzen
2026-10-20 12:16:22 +02:00
parent eae3bdba16
commit a5a246db77
11 changed files with 248 additions and 81 deletions
+80
View File
@@ -4,6 +4,7 @@ use std::{
cell::RefCell,
collections::BTreeSet,
ffi::OsStr,
fmt::Write as _,
fs::{self, OpenOptions},
io::{Read, Write},
path::{Path, PathBuf},
@@ -59,6 +60,22 @@ impl Anchor {
self.start.row..=end
}
pub fn excerpt(&self) -> &str {
let offset = |position: crate::plugin::TextPosition| {
let line = self.content.split('\n').nth(position.row).unwrap_or("");
self.content
.split('\n')
.take(position.row)
.map(|line| line.len() + 1)
.sum::<usize>()
+ line
.grapheme_indices(true)
.nth(position.column)
.map_or(line.len(), |(index, _)| index)
};
&self.content[offset(self.start)..offset(self.end)]
}
pub fn matches_lines(
&self,
revision: &str,
@@ -148,6 +165,69 @@ impl Review {
}
}
pub fn summary_text(&self) -> String {
let resolved = self
.comments
.iter()
.filter(|comment| comment.resolved)
.count();
format!(
"Review {} (revision {}): {}\n Verdict: {}; {} unresolved, {} resolved ({} total)\n",
self.storage_id
.map_or_else(|| "null".into(), |id| id.to_string()),
self.storage_revision,
self.summary,
match self.verdict {
Some(Verdict::LooksGood) => "looks_good",
Some(Verdict::ChangesRequested) => "changes_requested",
None => "none",
},
self.comments.len() - resolved,
resolved,
self.comments.len(),
)
}
/// CLI show format, including the repository, summary, and selected comments.
pub fn format_text(&self, all: bool) -> String {
let mut text = format!(
"Repository: {}\n{}",
self.root.display(),
self.summary_text()
);
for comment in self
.comments
.iter()
.filter(|comment| all || !comment.resolved)
{
let anchor = &comment.anchor;
writeln!(
text,
"\nComment {} [{}] {} ({}) {}:{}–{}:{} @ {}\n{}\n{}",
comment.id,
if comment.resolved {
"resolved"
} else {
"unresolved"
},
anchor.path.display(),
match anchor.side {
Side::Before => "before",
Side::After => "after",
},
anchor.start.row,
anchor.start.column,
anchor.end.row,
anchor.end.column,
anchor.revision,
anchor.excerpt(),
comment.body,
)
.unwrap();
}
text
}
fn validate(&self) -> Result<(), String> {
if self.version != 4 {
return Err(format!("Unsupported review version {}", self.version));