feat: add Git and Jujutsu gutter indicators

This commit is contained in:
2026-10-13 17:44:29 +02:00
parent e84d70463f
commit 55cdee1a13
14 changed files with 1392 additions and 32 deletions
+37 -3
View File
@@ -39,6 +39,7 @@ pub struct Config {
pub file_explorer_view: String,
pub clipboard_mode: String,
pub git_blame: bool,
pub git_gutter: crate::gutter::GutterStyle,
pub top_bar: ChromeLine,
pub bottom_bar: ChromeLine,
pub popup: PopupConfig,
@@ -83,6 +84,7 @@ impl Default for Config {
file_explorer_view: "tree".into(),
clipboard_mode: "system".into(),
git_blame: true,
git_gutter: crate::gutter::GutterStyle::default(),
top_bar: ChromeLine::top(),
bottom_bar: ChromeLine::bottom(),
popup: PopupConfig::default(),
@@ -114,6 +116,7 @@ pub fn load_config(path: &Path) -> Result<Config, String> {
file_explorer_view,
clipboard_mode,
git_blame,
git_gutter,
top_bar,
bottom_bar,
popup,
@@ -146,6 +149,7 @@ pub fn load_config(path: &Path) -> Result<Config, String> {
config.file_explorer_view = file_explorer_view;
config.clipboard_mode = clipboard_mode;
config.git_blame = git_blame;
config.git_gutter = git_gutter;
config.top_bar = top_bar;
config.bottom_bar = bottom_bar;
config.popup = popup;
@@ -462,6 +466,7 @@ struct ConfigFrame {
file_explorer_view: String,
clipboard_mode: String,
git_blame: bool,
git_gutter: crate::gutter::GutterStyle,
#[serde(deserialize_with = "crate::chrome::top")]
top_bar: ChromeLine,
#[serde(deserialize_with = "crate::chrome::bottom")]
@@ -1212,14 +1217,41 @@ end
assert!(load_config(&path).unwrap_err().contains(error), "{value}");
}
for frame in [
r#"{"type":"config","version":1,"plugins":[],"lsp":{},"bindings":[],"file_explorer_side":"right","file_picker_view":"list","file_explorer_view":"tree","clipboard_mode":"system","git_blame":true,"top_bar":{},"bottom_bar":{},"popup":{"command":{},"search":{}},"labels":{},"diff_context_lines":10,"diff_expand_lines":15,"diff_view_mode":"split","diff_split_orientation":"vertical","diff_follow_working_copy":true}"#,
r#"{"type":"config","version":1,"plugins":[],"lsp":{},"bindings":[],"leader":null,"file_explorer_side":"right","file_picker_view":"list","file_explorer_view":"tree","clipboard_mode":"system","git_blame":true,"top_bar":{},"bottom_bar":{},"popup":{"command":{},"search":{}},"labels":{},"diff_context_lines":10,"diff_expand_lines":15,"diff_view_mode":"split","diff_split_orientation":"vertical","diff_follow_working_copy":true}"#,
r#"{"type":"config","version":1,"plugins":[],"lsp":{},"bindings":[],"leader":7,"file_explorer_side":"right","file_picker_view":"list","file_explorer_view":"tree","clipboard_mode":"system","git_blame":true,"top_bar":{},"bottom_bar":{},"popup":{"command":{},"search":{}},"labels":{},"diff_context_lines":10,"diff_expand_lines":15,"diff_view_mode":"split","diff_split_orientation":"vertical","diff_follow_working_copy":true}"#,
r#"{"type":"config","version":1,"plugins":[],"lsp":{},"bindings":[],"file_explorer_side":"right","file_picker_view":"list","file_explorer_view":"tree","clipboard_mode":"system","git_blame":true,"git_gutter":"bar","top_bar":{},"bottom_bar":{},"popup":{"command":{},"search":{}},"labels":{},"diff_context_lines":10,"diff_expand_lines":15,"diff_view_mode":"split","diff_split_orientation":"vertical","diff_follow_working_copy":true}"#,
r#"{"type":"config","version":1,"plugins":[],"lsp":{},"bindings":[],"leader":null,"file_explorer_side":"right","file_picker_view":"list","file_explorer_view":"tree","clipboard_mode":"system","git_blame":true,"git_gutter":"bar","top_bar":{},"bottom_bar":{},"popup":{"command":{},"search":{}},"labels":{},"diff_context_lines":10,"diff_expand_lines":15,"diff_view_mode":"split","diff_split_orientation":"vertical","diff_follow_working_copy":true}"#,
r#"{"type":"config","version":1,"plugins":[],"lsp":{},"bindings":[],"leader":7,"file_explorer_side":"right","file_picker_view":"list","file_explorer_view":"tree","clipboard_mode":"system","git_blame":true,"git_gutter":"bar","top_bar":{},"bottom_bar":{},"popup":{"command":{},"search":{}},"labels":{},"diff_context_lines":10,"diff_expand_lines":15,"diff_view_mode":"split","diff_split_orientation":"vertical","diff_follow_working_copy":true}"#,
] {
assert!(serde_json::from_str::<Response>(frame).is_err(), "{frame}");
}
}
#[test]
fn git_gutter_config_modes_default_and_rejection() {
use crate::gutter::GutterStyle;
let fixture = Fixture::new();
let path = fixture.file("config.rb", "Vamp.configure { |_config| }");
assert_eq!(load_config(&path).unwrap().git_gutter, GutterStyle::Bar);
for (name, expected) in [
("bar", GutterStyle::Bar),
("symbols", GutterStyle::Symbols),
("line_numbers", GutterStyle::LineNumbers),
("none", GutterStyle::None),
] {
let path = fixture.file(
"config.rb",
&format!("Vamp.configure {{ |config| config.git_gutter = {name:?} }}"),
);
assert_eq!(load_config(&path).unwrap().git_gutter, expected);
}
for value in ["\"unsupported\"", "\"\"", "false", "7", ":bar"] {
let path = fixture.file(
"config.rb",
&format!("Vamp.configure {{ |config| config.git_gutter = {value} }}"),
);
assert!(load_config(&path).is_err(), "{value}");
}
}
#[test]
fn git_blame_boolean_config_typed_toggle_palette_and_wire_validation() {
let fixture = Fixture::new();
@@ -1262,6 +1294,7 @@ end
"type": "config", "version": 1, "plugins": [], "lsp": {}, "bindings": [],
"leader": "space", "file_explorer_side": "right", "file_picker_view": "tree",
"file_explorer_view": "tree", "clipboard_mode": "system", "git_blame": true,
"git_gutter": "bar",
"top_bar": {}, "bottom_bar": {}, "popup": {"command": {}, "search": {}},
"labels": {}, "diff_context_lines": 10, "diff_expand_lines": 15,
"diff_view_mode": "split", "diff_split_orientation": "vertical",
@@ -1928,6 +1961,7 @@ end"#,
"bindings": [], "leader": "space", "file_explorer_side": "right",
"file_picker_view": "tree", "file_explorer_view": "tree",
"git_blame": true,
"git_gutter": "bar",
"top_bar": {}, "bottom_bar": {}, "labels": {},
"popup": {"command": {}, "search": {}},
"clipboard_mode": "system", "diff_context_lines": 10, "diff_expand_lines": 15,