feat: show current-line git blame by default

This commit is contained in:
Valdemar Lorenzen
2026-10-13 12:21:03 +02:00
parent 5382307fcc
commit 7a3c27c30e
12 changed files with 1231 additions and 7 deletions
+113
View File
@@ -776,6 +776,18 @@ core_actions![
],
true,
),
(
"core.git_blame.toggle",
Action::GitBlameToggle,
&[
Mode::Normal,
Mode::Insert,
Mode::Visual,
Mode::Command,
Mode::Search
],
true,
),
(
"core.diff.close",
Action::DiffClose,
@@ -1654,6 +1666,16 @@ struct PendingLspNavigation {
request: Option<u64>,
}
#[derive(Clone)]
pub(crate) struct BlameSource {
buffer: usize,
revision: u64,
pub(crate) path: PathBuf,
pub(crate) row: usize,
pane: usize,
tab: usize,
}
pub struct Editor {
active: Buffer,
parked: BTreeMap<usize, Buffer>,
@@ -1689,6 +1711,8 @@ pub struct Editor {
labels: BTreeMap<String, String>,
battery_charge: Option<u8>,
battery_label: String,
git_blame: bool,
line_blame: Option<(BlameSource, String)>,
lsp_names: Vec<String>,
lsp_label: String,
quit: bool,
@@ -1787,6 +1811,8 @@ impl Editor {
labels: BTreeMap::new(),
battery_charge: None,
battery_label: String::new(),
git_blame: true,
line_blame: None,
lsp_names: Vec::new(),
lsp_label: String::new(),
quit: false,
@@ -3209,6 +3235,7 @@ impl Editor {
| Action::DiffViewToggle
| Action::DiffOrientationToggle
| Action::WordWrapToggle
| Action::GitBlameToggle
| Action::Quit
| Action::ForceQuit
| Action::Restart
@@ -4641,6 +4668,76 @@ impl Editor {
pub fn battery_label(&self) -> &str {
&self.battery_label
}
pub fn git_blame(&self) -> bool {
self.git_blame
}
pub(crate) fn set_git_blame(&mut self, enabled: bool) {
self.git_blame = enabled;
self.line_blame = None;
}
pub(crate) fn blame_source(&self) -> Option<BlameSource> {
if !self.git_blame
|| self.should_quit()
|| self.diff.is_some()
|| self.active.diff_snapshot.is_some()
{
return None;
}
Some(BlameSource {
buffer: self.buffer_id(),
revision: self.text_revision(),
path: self.path()?.to_owned(),
row: self.cursor().row,
pane: self.pane_id(),
tab: self.tab_id(),
})
}
pub(crate) fn blame_source_is_current(&self, source: &BlameSource) -> bool {
self.git_blame
&& !self.should_quit()
&& self.diff.is_none()
&& self.active.diff_snapshot.is_none()
&& source.buffer == self.buffer_id()
&& source.revision == self.text_revision()
&& Some(source.path.as_path()) == self.path()
&& source.row == self.cursor().row
&& source.pane == self.pane_id()
&& source.tab == self.tab_id()
}
pub(crate) fn clear_line_blame(&mut self) -> bool {
self.line_blame.take().is_some()
}
pub(crate) fn set_line_blame(
&mut self,
source: BlameSource,
blame: crate::blame::LineBlame,
) -> bool {
if !self.blame_source_is_current(&source) {
return false;
}
let label = if blame.uncommitted {
"Uncommitted".to_owned()
} else {
sanitize_label(format!(
"{} · {} ({:.8})",
blame.author, blame.summary, blame.commit
))
};
self.line_blame = Some((source, label));
true
}
pub(crate) fn line_blame(&self) -> Option<&str> {
self.line_blame
.as_ref()
.filter(|(source, _)| self.blame_source_is_current(source))
.map(|(_, label)| label.as_str())
}
pub fn lsp_names(&self) -> &[String] {
&self.lsp_names
}
@@ -6022,6 +6119,7 @@ impl Editor {
| Action::DiffViewToggle
| Action::DiffOrientationToggle
| Action::WordWrapToggle
| Action::GitBlameToggle
| Action::LspDefinition
| Action::LspHover
| Action::LspDiagnostics => unreachable!("catalog Ex actions dispatch above"),
@@ -6885,6 +6983,21 @@ impl Editor {
}
return None;
}
if entry.action == Action::GitBlameToggle {
if !args.is_empty() {
self.set_message("The git_blame.toggle command takes no arguments");
return None;
}
self.set_git_blame(!self.git_blame);
self.count = None;
self.clear_sequence();
self.palette = None;
if self.active.view.mode == Mode::Command {
self.active.view.command_line.clear();
self.active.view.mode = Mode::Normal;
}
return None;
}
if entry.action == Action::WordWrapToggle {
if !args.is_empty() {
self.set_message("The word_wrap.toggle command takes no arguments");