git_ui: Allow opening a file with the diff hunks expanded (#40616)

So i just discovered `editor::ExpandAllDiffHunks`

I have been really missing the ability to look at changes NOT in a multi
buffer so i was very pleased to finally figure out that this is already
possible in Zed.

i have seen alot of discussion/issues requesting this feature so i think
it is safe to say i'm not the only one that is not aware it exists.

i think the wording in the docs could better communicate what this
feature actually is, however, i think an even better way to show users
that this feature exists would be to just put it in front of them.

In the `GitPanel`:
- `menu::Confirm` opens the project diff
- `menu::SecondaryConfirm` opens the selected file in a new editor.

I think it would be REALLY nice if opening a file with
`SecondaryConfirm` opened the file with the diff hunks already expanded
and scrolled the editor to the first hunk.

ideally i see this being toggle-able in settings something like
`GitPanel - Open File with Diffs Expanded` or something. so the user
could turn this off if they preferred.

I tried creating a new keybinding using the new `actions::Sequence`
it was something like:
```json
{
  "context": "GitPanel && ChangesList",
  "bindings": {
    "cmd-enter" : [ "actions::Sequence", ["menu:SecondaryConfirm", "editor::ToggleFocus", "editor::ExpandAllDiffHunks", "editor::GoToHunk"]]
  }
}
```
but the action sequence does not work. i think because opening the file
is an async task.

i have a first attempt here, of just trying to get the diff hunks to
expand after opening the file.
i tried to copy and paste the logic/structure as best i could from the
confirm method in file_finder.rs:1432

it compiles, but it does not work, and i do not have enough experience
in rust or in this project to figure out anything further.

if anyone was interested in working on this with me i would enjoy
learning more and i think this would be a nice way to showcase this
tool!
This commit is contained in:
Josh Piasecki
2025-11-14 07:47:46 -06:00
committed by GitHub
parent 723f9b1371
commit 092071a2f0

View File

@@ -12,7 +12,9 @@ use agent_settings::AgentSettings;
use anyhow::Context as _;
use askpass::AskPassDelegate;
use db::kvp::KEY_VALUE_STORE;
use editor::{Editor, EditorElement, EditorMode, MultiBuffer};
use editor::{
Direction, Editor, EditorElement, EditorMode, MultiBuffer, actions::ExpandAllDiffHunks,
};
use futures::StreamExt as _;
use git::blame::ParsedCommitMessage;
use git::repository::{
@@ -69,7 +71,7 @@ use cloud_llm_client::CompletionIntent;
use workspace::{
Workspace,
dock::{DockPosition, Panel, PanelEvent},
notifications::{DetachAndPromptErr, ErrorMessagePrompt, NotificationId},
notifications::{DetachAndPromptErr, ErrorMessagePrompt, NotificationId, NotifyResultExt},
};
actions!(
@@ -792,15 +794,46 @@ impl GitPanel {
return None;
}
self.workspace
let open_task = self
.workspace
.update(cx, |workspace, cx| {
workspace
.open_path_preview(path, None, false, false, true, window, cx)
.detach_and_prompt_err("Failed to open file", window, cx, |e, _, _| {
Some(format!("{e}"))
});
workspace.open_path_preview(path, None, false, false, true, window, cx)
})
.ok()
.ok()?;
cx.spawn_in(window, async move |_, mut cx| {
let item = open_task
.await
.notify_async_err(&mut cx)
.ok_or_else(|| anyhow::anyhow!("Failed to open file"))?;
if let Some(active_editor) = item.downcast::<Editor>() {
if let Some(diff_task) =
active_editor.update(cx, |editor, _cx| editor.wait_for_diff_to_load())?
{
diff_task.await;
}
cx.update(|window, cx| {
active_editor.update(cx, |editor, cx| {
editor.expand_all_diff_hunks(&ExpandAllDiffHunks, window, cx);
let snapshot = editor.snapshot(window, cx);
editor.go_to_hunk_before_or_after_position(
&snapshot,
language::Point::new(0, 0),
Direction::Next,
window,
cx,
);
})
})?;
}
anyhow::Ok(())
})
.detach();
Some(())
});
}