Edit the selected line of a diff from the focused main view

Reading a diff is often how you notice something to fix, and the file and
line are right there in front of you — so pressing edit opens the file at
the line under the selection, as it does in the staging view.

The line number the diff shows is the line number in the version the diff
is of, which for a commit's diff is not where that line sits today, so it
is carried forward the same way clicking a diff-renderer hyperlink already
does. A file header names no line, so it just opens the file.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-10-01 17:07:52 +02:00
co-authored by Claude Opus 5
parent cfb88005c8
commit cfde175e8a
12 changed files with 96 additions and 0 deletions
@@ -71,6 +71,14 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty
DescriptionFunc: self.diffSelectionDescriptionText(self.c.Tr.ToggleRangeSelect),
GetDisabledReason: self.diffSelectionDisabledReason,
},
{
Keys: opts.GetKeys(opts.Config.Universal.Edit),
Handler: self.editLine,
Description: self.c.Tr.EditFile,
DescriptionFunc: self.diffSelectionDescriptionText(self.c.Tr.EditFile),
GetDisabledReason: self.diffSelectionDisabledReason,
Tooltip: self.c.Tr.EditFileTooltip,
},
{
Keys: opts.GetKeys(opts.Config.Main.PrevHunk),
Handler: self.prevChangeBlock,
@@ -825,6 +833,30 @@ func (self *MainViewController) handleGotoBottom() error {
return nil
}
func (self *MainViewController) editLine() error {
view := self.context.GetView()
if !view.Highlight {
return nil
}
info, ok := self.c.Helpers().DiffLine.GetDiffLineInfo(view, view.SelectedLineIdx())
if !ok {
return nil
}
// A file-header row points at the file as a whole rather than at a line in it, so
// it opens the file without jumping anywhere — as pressing edit on a file in a side
// panel does.
if info.Type == types.DiffLineFileHeader {
return self.c.Helpers().Files.EditFiles([]string{info.Path})
}
// The diff may be of an older commit, whose line numbers aren't the file's current
// ones, so they have to be carried forward before we can point an editor at them.
lineNumber := self.c.Helpers().Diff.AdjustLineNumber(info.Path, info.NewLine, self.context.GetViewName())
return self.c.Helpers().Files.EditFileAtLine(info.Path, lineNumber)
}
func (self *MainViewController) openSearch() error {
if manager := self.c.GetViewBufferManagerForView(self.context.GetView()); manager != nil {
manager.ReadToEnd(func() {
@@ -0,0 +1,45 @@
package main_view
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var EditSelectedDiffLine = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Open the selected line of the main view's diff in the editor, at that line of the file",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Gui.UseHunkModeInStagingView = false
config.GetUserConfig().OS.EditAtLine = "echo {{filename}}:{{line}} > edit-command"
config.GetUserConfig().OS.Edit = "echo {{filename}} > edit-command"
},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "one\ntwo\nthree\nfour\nfive\n")
shell.Commit("one")
shell.UpdateFile("file1", "one\ntwo\nTHREE\nfour\nfive\n")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Files().
IsFocused().
Press(keys.Universal.FocusMainView)
// The addition is the third line of the file as it now stands.
t.Views().Main().
IsFocused().
NavigateToLine(Contains("+THREE")).
Press(keys.Universal.Edit)
// The editor is pointed at the file by absolute path.
t.FileSystem().FileContent("edit-command", Contains("/repo/file1:3\n"))
// A file header points at the file rather than at a line in it, so it opens the
// file with no line to jump to.
t.Views().Main().
NavigateToLine(Contains("diff --git a/file1 b/file1")).
Press(keys.Universal.Edit)
t.FileSystem().FileContent("edit-command", Contains("/repo/file1\n"))
},
})
+1
View File
@@ -367,6 +367,7 @@ var tests = []*components.IntegrationTest{
main_view.ClickSelectsDiffLine,
main_view.DragRangeWithAutoscroll,
main_view.DragSelectsDiffLineRange,
main_view.EditSelectedDiffLine,
main_view.EscapeDismissesSelection,
main_view.FileNavigationScrollsToTheTop,
main_view.HideSelectionWhenChangesVanish,