Skip to content

Add config to use a pager in the staging panel #4332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ git:
# ydiff -p cat -s --wrap --width={{columnWidth}}
pager: ""

# e.g.
# delta --dark --paging=never --color-only
# diff-so-fancy --patch
pagerForStaging: ""

# If true, Lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager).
useConfig: false

Expand Down
13 changes: 13 additions & 0 deletions pkg/config/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,15 @@ func (PagerType) JSONSchemaExtend(schema *jsonschema.Schema) {
}
}

type PagerForStagingType string

func (PagerForStagingType) JSONSchemaExtend(schema *jsonschema.Schema) {
schema.Examples = []any{
"delta --dark --paging=never --color-only",
"diff-so-fancy --patch",
}
}

type PagingConfig struct {
// Value of the --color arg in the git diff command. Some pagers want this to be set to 'always' and some want it set to 'never'
ColorArg string `yaml:"colorArg" jsonschema:"enum=always,enum=never"`
Expand All @@ -292,6 +301,10 @@ type PagingConfig struct {
// delta --dark --paging=never
// ydiff -p cat -s --wrap --width={{columnWidth}}
Pager PagerType `yaml:"pager"`
// e.g.
// delta --dark --paging=never --color-only
// diff-so-fancy --patch
PagerForStaging PagerForStagingType `yaml:"pagerForStaging"`
// If true, Lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager).
UseConfig bool `yaml:"useConfig"`
// e.g. 'difft --color=always'
Expand Down
2 changes: 1 addition & 1 deletion pkg/gui/controllers/helpers/patch_building_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (self *PatchBuildingHelper) RefreshPatchBuildingPanel(opts types.OnFocusOpt

oldState := context.GetState()

state := patch_exploring.NewState(diff, selectedLineIdx, context.GetView(), oldState)
state := patch_exploring.NewState(diff, selectedLineIdx, context.GetView(), oldState, string(self.c.UserConfig().Git.Paging.PagerForStaging))
context.SetState(state)
if state == nil {
self.Escape()
Expand Down
6 changes: 4 additions & 2 deletions pkg/gui/controllers/helpers/staging_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ func (self *StagingHelper) RefreshStagingPanel(focusOpts types.OnFocusOpts) {
mainContext.GetMutex().Lock()
secondaryContext.GetMutex().Lock()

pagerCommand := string(self.c.UserConfig().Git.Paging.PagerForStaging)

mainContext.SetState(
patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainContext.GetView(), mainContext.GetState()),
patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainContext.GetView(), mainContext.GetState(), pagerCommand),
)

secondaryContext.SetState(
patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondaryContext.GetView(), secondaryContext.GetState()),
patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondaryContext.GetView(), secondaryContext.GetState(), pagerCommand),
)

mainState := mainContext.GetState()
Expand Down
44 changes: 42 additions & 2 deletions pkg/gui/patch_exploring/state.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package patch_exploring

import (
"bytes"
"io"
"os/exec"
"strings"

"github.com./jesseduffield/generics/set"
"github.com./jesseduffield/gocui"
"github.com./jesseduffield/lazygit/pkg/commands/patch"
"github.com./jesseduffield/lazygit/pkg/utils"
"github.com./mgutz/str"
)

// State represents the current state of the patch explorer context i.e. when
Expand All @@ -20,6 +24,7 @@ type State struct {
// Otherwise, we cancel the range when we move up or down.
rangeIsSticky bool
diff string
diffFromPager string
patch *patch.Patch
selectMode selectMode

Expand All @@ -38,7 +43,7 @@ const (
HUNK
)

func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *State) *State {
func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *State, pagerCommand string) *State {
if oldState != nil && diff == oldState.diff && selectedLineIdx == -1 {
// if we're here then we can return the old state. If selectedLineIdx was not -1
// then that would mean we were trying to click and potentially drag a range, which
Expand All @@ -52,7 +57,13 @@ func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *Stat
return nil
}

viewLineIndices, patchLineIndices := wrapPatchLines(diff, view)
diffFromPager := formatDiffForStaging(diff, pagerCommand)
diffToWrap := diff
if len(diffFromPager) > 0 {
diffToWrap = utils.Decolorise(diffFromPager)
}

viewLineIndices, patchLineIndices := wrapPatchLines(diffToWrap, view)

rangeStartLineIdx := 0
if oldState != nil {
Expand Down Expand Up @@ -85,11 +96,37 @@ func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *Stat
rangeStartLineIdx: rangeStartLineIdx,
rangeIsSticky: false,
diff: diff,
diffFromPager: diffFromPager,
viewLineIndices: viewLineIndices,
patchLineIndices: patchLineIndices,
}
}

func formatDiffForStaging(diff string, pagerCommand string) string {
if len(pagerCommand) == 0 {
return ""
}

args := str.ToArgv(pagerCommand)
cmd := exec.Command(args[0], args[1:]...)
var stdout bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = io.Discard
cmd.Stdin = strings.NewReader(diff)

err := cmd.Run()
if err != nil {
// TODO report error somehow
return ""
}
diffFromPager := stdout.String()
if len(strings.Split(diffFromPager, "\n")) != len(strings.Split(diff, "\n")) {
// TODO report error somehow
return ""
}
return diffFromPager
}

func (s *State) OnViewWidthChanged(view *gocui.View) {
if !view.Wrap {
return
Expand Down Expand Up @@ -294,6 +331,9 @@ func (s *State) AdjustSelectedLineIdx(change int) {
}

func (s *State) RenderForLineIndices(includedLineIndices []int) string {
if includedLineIndices == nil && len(s.diffFromPager) > 0 {
return s.diffFromPager
}
includedLineIndicesSet := set.NewFromSlice(includedLineIndices)
return s.patch.FormatView(patch.FormatViewOpts{
IncLineIndices: includedLineIndicesSet,
Expand Down
9 changes: 9 additions & 0 deletions schema/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,15 @@
"ydiff -p cat -s --wrap --width={{columnWidth}}"
]
},
"pagerForStaging": {
"type": "string",
"description": "e.g.\ndelta --dark --paging=never --color-only\ndiff-so-fancy --patch",
"default": "",
"examples": [
"delta --dark --paging=never --color-only",
"diff-so-fancy --patch"
]
},
"useConfig": {
"type": "boolean",
"description": "If true, Lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager).",
Expand Down
Loading