Repository: jesseduffield/lazygit (language: go)

Issue:
Unable to scroll the `post-checkout` hook error popup
**Describe the bug**
When the `post-checkout` hook fails, `lazygit` shows the popup covering most of the UI with the output, which is great!
However, it seems like you can only scroll this output by one line, using `j` and `k`. Hitting `Ctrl+d`/`Ctrl+u` scrolls the git log underneath (which is barely even visible).
I'm working in a huge monorepo and sometimes the output is really big. The reason for the hook failure is usually at the very bottom of the output and to actually see it I have to hold `j` for a very long time and most of the time I just end up going outside of the `lazygit` to run the same command that the hook is running so that I can see the output.

**To Reproduce**
Steps to reproduce the behavior:

1. Create a `post-checkout` hook in `<repo root>/.git/hooks/post-checkout` with the following content
```sh
#!/bin/bash

echo $(man less)
exit 1
```
2. Make sure it's executable with `sudo chmod +x .git/hooks/post-checkout`.
3. Switch to another branch by selecting it in the "Local branches" panel (3) and hitting Space.
4. See the popup with an big output appear
5. Try to scroll that popup.

**Expected behavior**
When the output popup is displayed, I would expect `Crtl+d` and `Ctrl+u` to scroll the popup contents rather than git log.
Maybe it would be reasonable to scroll to the end of the output automatically, because the popup shows Error and the error is most likely at the bottom of the output.

**Screenshots**

![Image](https://github.com/user-attachments/assets/d032aa80-8d45-4069-971c-18d90ff70066)

**Version info:**
_Run `lazygit --version` and paste the result here_
```
commit=, build date=, build source=nix, version=0.48.0, os=darwin, arch=arm64, git version=2.39.5 (Apple Git-154)
```
_Run `git --version` and paste the result here_
```
git version 2.39.5 (Apple Git-154)
```
**Additional context**
I'm happy to try submitting a PR, but I haven't contributed to this project before so I'll need to spend some time digesting contributing guide and just getting familiar with the project.
If someone could point me to the right direction, that would also be highly appreciated!

<!--
If you want to try and debug this issue yourself, you can run `lazygit --debug` in one terminal panel and `lazygit --logs` in another to view the logs.
-->



Discussion / hints:
I have never liked ctrl-d/ctrl-u very much, I think they are crutches that were added because the main view can't be focused, so we need _some_ way to scroll it. (Also, they scroll line by line too, so this wouldn't help much here?) I have been working on a branch that makes it possible to focus the main view, so that you can then navigate it with the same keys that we use in list views (arrow up/down or `j`/`k` to scroll by line, `,` and `.` to scroll by page, `<` and `>` to go to beginning/end).

For the error popup, I think that's what we should do too: support these four keys (`,.<>`). Let me know if you think this would solve it for you.

In the meantime, mouse wheel works in confirmation panels, so I can pretty quickly flick the view to the end using two fingers on my track pad.

Finally, for those who want to reproduce the issue: an easier way to do this is with a custom command like this:
```yml
customCommands:
  - command: man less
    context: global
    showOutput: true
```
@stefanhaller 
> Also, they scroll line by line too, so this wouldn't help much here?

Oh, I somehow never noticed that. I guess, I just always assumed it would work like in Vim but never actually used it. 🤦
Given that, you're right. That wouldn't help.

Your suggestion to use the keys that are used in other places sounds reasonable and will definitely solve the issue for me.

> In the meantime, mouse wheel works in confirmation panels, so I can pretty quickly flick the view to the end using two fingers on my track pad.

Mouse scroll doesn't work for me as I'm working in `tmux` and mouse scroll just scrolls the terminal output.
Not sure if that's my tmux config issue or `lazygit` could improve this (for example, there are programs that override this behavior and actually allow me to scroll content inside of them or just prevent `tmux` from scrolling the history, for example `neovim`), but I don't want to use mouse to scroll this popup anyway. That haven't even crossed my mind tbh. 🤔 

Fix patch:
diff --git a/pkg/gui/extras_panel.go b/pkg/gui/extras_panel.go
index 96fa225d325..0c3f20cd5c1 100644
--- a/pkg/gui/extras_panel.go
+++ b/pkg/gui/extras_panel.go
@@ -58,6 +58,38 @@ func (gui *Gui) scrollDownExtra() error {
 	return nil
 }
 
+func (gui *Gui) pageUpExtrasPanel() error {
+	gui.Views.Extras.Autoscroll = false
+
+	gui.Views.Extras.ScrollUp(gui.Contexts().CommandLog.GetViewTrait().PageDelta())
+
+	return nil
+}
+
+func (gui *Gui) pageDownExtrasPanel() error {
+	gui.Views.Extras.Autoscroll = false
+
+	gui.Views.Extras.ScrollDown(gui.Contexts().CommandLog.GetViewTrait().PageDelta())
+
+	return nil
+}
+
+func (gui *Gui) goToExtrasPanelTop() error {
+	gui.Views.Extras.Autoscroll = false
+
+	gui.Views.Extras.ScrollUp(gui.Views.Extras.ViewLinesHeight())
+
+	return nil
+}
+
+func (gui *Gui) goToExtrasPanelBottom() error {
+	gui.Views.Extras.Autoscroll = true
+
+	gui.Views.Extras.ScrollDown(gui.Views.Extras.ViewLinesHeight())
+
+	return nil
+}
+
 func (gui *Gui) getCmdWriter() io.Writer {
 	return &prefixWriter{writer: gui.Views.Extras, prefix: style.FgMagenta.Sprintf("\n\n%s\n", gui.c.Tr.GitOutput)}
 }
diff --git a/pkg/gui/global_handlers.go b/pkg/gui/global_handlers.go
index 9721b4b2ab0..0301cf63edb 100644
--- a/pkg/gui/global_handlers.go
+++ b/pkg/gui/global_handlers.go
@@ -109,6 +109,46 @@ func (gui *Gui) scrollDownConfirmationPanel() error {
 	return nil
 }
 
+func (gui *Gui) pageUpConfirmationPanel() error {
+	if gui.Views.Confirmation.Editable {
+		return nil
+	}
+
+	gui.Views.Confirmation.ScrollUp(gui.Contexts().Confirmation.GetViewTrait().PageDelta())
+
+	return nil
+}
+
+func (gui *Gui) pageDownConfirmationPanel() error {
+	if gui.Views.Confirmation.Editable {
+		return nil
+	}
+
+	gui.Views.Confirmation.ScrollDown(gui.Contexts().Confirmation.GetViewTrait().PageDelta())
+
+	return nil
+}
+
+func (gui *Gui) goToConfirmationPanelTop() error {
+	if gui.Views.Confirmation.Editable {
+		return nil
+	}
+
+	gui.Views.Confirmation.ScrollUp(gui.Views.Confirmation.ViewLinesHeight())
+
+	return nil
+}
+
+func (gui *Gui) goToConfirmationPanelBottom() error {
+	if gui.Views.Confirmation.Editable {
+		return nil
+	}
+
+	gui.Views.Confirmation.ScrollDown(gui.Views.Confirmation.ViewLinesHeight())
+
+	return nil
+}
+
 func (gui *Gui) handleCopySelectedSideContextItemToClipboard() error {
 	return gui.handleCopySelectedSideContextItemToClipboardWithTruncation(-1)
 }
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 20163b90bf2..e52f9a81534 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -260,6 +260,42 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
 			Key:      gocui.MouseWheelDown,
 			Handler:  self.scrollDownConfirmationPanel,
 		},
+		{
+			ViewName: "confirmation",
+			Key:      opts.GetKey(opts.Config.Universal.NextPage),
+			Modifier: gocui.ModNone,
+			Handler:  self.pageDownConfirmationPanel,
+		},
+		{
+			ViewName: "confirmation",
+			Key:      opts.GetKey(opts.Config.Universal.PrevPage),
+			Modifier: gocui.ModNone,
+			Handler:  self.pageUpConfirmationPanel,
+		},
+		{
+			ViewName: "confirmation",
+			Key:      opts.GetKey(opts.Config.Universal.GotoTop),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToConfirmationPanelTop,
+		},
+		{
+			ViewName: "confirmation",
+			Key:      opts.GetKey(opts.Config.Universal.GotoTopAlt),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToConfirmationPanelTop,
+		},
+		{
+			ViewName: "confirmation",
+			Key:      opts.GetKey(opts.Config.Universal.GotoBottom),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToConfirmationPanelBottom,
+		},
+		{
+			ViewName: "confirmation",
+			Key:      opts.GetKey(opts.Config.Universal.GotoBottomAlt),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToConfirmationPanelBottom,
+		},
 		{
 			ViewName:          "submodules",
 			Key:               opts.GetKey(opts.Config.Universal.CopyToClipboard),
@@ -305,6 +341,42 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
 			Modifier: gocui.ModNone,
 			Handler:  self.scrollDownExtra,
 		},
+		{
+			ViewName: "extras",
+			Key:      opts.GetKey(opts.Config.Universal.NextPage),
+			Modifier: gocui.ModNone,
+			Handler:  self.pageDownExtrasPanel,
+		},
+		{
+			ViewName: "extras",
+			Key:      opts.GetKey(opts.Config.Universal.PrevPage),
+			Modifier: gocui.ModNone,
+			Handler:  self.pageUpExtrasPanel,
+		},
+		{
+			ViewName: "extras",
+			Key:      opts.GetKey(opts.Config.Universal.GotoTop),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToExtrasPanelTop,
+		},
+		{
+			ViewName: "extras",
+			Key:      opts.GetKey(opts.Config.Universal.GotoTopAlt),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToExtrasPanelTop,
+		},
+		{
+			ViewName: "extras",
+			Key:      opts.GetKey(opts.Config.Universal.GotoBottom),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToExtrasPanelBottom,
+		},
+		{
+			ViewName: "extras",
+			Key:      opts.GetKey(opts.Config.Universal.GotoBottomAlt),
+			Modifier: gocui.ModNone,
+			Handler:  self.goToExtrasPanelBottom,
+		},
 		{
 			ViewName: "extras",
 			Tag:      "navigation",


Test patch: