mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-19 00:28:03 +02:00
stream output from certain git commands in command log panel
This commit is contained in:
39
vendor/github.com/jesseduffield/gocui/escape.go
generated
vendored
39
vendor/github.com/jesseduffield/gocui/escape.go
generated
vendored
@ -29,12 +29,15 @@ type (
|
||||
fontEffect int
|
||||
)
|
||||
|
||||
type instruction struct {
|
||||
kind int
|
||||
param1 int
|
||||
param2 int
|
||||
toWrite []rune
|
||||
}
|
||||
type instruction interface{ isInstruction() }
|
||||
|
||||
type eraseInLineFromCursor struct{}
|
||||
|
||||
func (self eraseInLineFromCursor) isInstruction() {}
|
||||
|
||||
type noInstruction struct{}
|
||||
|
||||
func (self noInstruction) isInstruction() {}
|
||||
|
||||
const (
|
||||
stateNone escapeState = iota
|
||||
@ -87,7 +90,7 @@ func newEscapeInterpreter(mode OutputMode) *escapeInterpreter {
|
||||
curFgColor: ColorDefault,
|
||||
curBgColor: ColorDefault,
|
||||
mode: mode,
|
||||
instruction: instruction{kind: NONE},
|
||||
instruction: noInstruction{},
|
||||
}
|
||||
return ei
|
||||
}
|
||||
@ -101,7 +104,7 @@ func (ei *escapeInterpreter) reset() {
|
||||
}
|
||||
|
||||
func (ei *escapeInterpreter) instructionRead() {
|
||||
ei.instruction.kind = NONE
|
||||
ei.instruction = noInstruction{}
|
||||
}
|
||||
|
||||
// parseOne parses a rune. If isEscape is true, it means that the rune is part
|
||||
@ -137,6 +140,8 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
ei.csiParam = append(ei.csiParam, "")
|
||||
case ch == 'm':
|
||||
ei.csiParam = append(ei.csiParam, "0")
|
||||
case ch == 'K':
|
||||
// fall through
|
||||
default:
|
||||
return false, errCSIParseError
|
||||
}
|
||||
@ -168,12 +173,20 @@ func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
|
||||
ei.csiParam = nil
|
||||
return true, nil
|
||||
case ch == 'K':
|
||||
p, err := strconv.Atoi(ei.csiParam[0])
|
||||
if err != nil {
|
||||
return false, errCSIParseError
|
||||
p := 0
|
||||
if len(ei.csiParam) != 0 && ei.csiParam[0] != "" {
|
||||
p, err = strconv.Atoi(ei.csiParam[0])
|
||||
if err != nil {
|
||||
return false, errCSIParseError
|
||||
}
|
||||
}
|
||||
|
||||
if p == 0 {
|
||||
ei.instruction = eraseInLineFromCursor{}
|
||||
} else {
|
||||
// non-zero values of P not supported
|
||||
ei.instruction = noInstruction{}
|
||||
}
|
||||
ei.instruction.kind = ERASE_IN_LINE
|
||||
ei.instruction.param1 = p
|
||||
|
||||
ei.state = stateNone
|
||||
ei.csiParam = nil
|
||||
|
1
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
1
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@ -1041,7 +1041,6 @@ func (g *Gui) draw(v *View) error {
|
||||
Screen.HideCursor()
|
||||
}
|
||||
|
||||
v.clearRunes()
|
||||
if err := v.draw(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
109
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
109
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
@ -359,7 +359,32 @@ func (v *View) Dimensions() (int, int, int, int) {
|
||||
|
||||
// Size returns the number of visible columns and rows in the View.
|
||||
func (v *View) Size() (x, y int) {
|
||||
return v.x1 - v.x0 - 1, v.y1 - v.y0 - 1
|
||||
return v.Width(), v.Height()
|
||||
}
|
||||
|
||||
func (v *View) Width() int {
|
||||
return v.x1 - v.x0 - 1
|
||||
}
|
||||
|
||||
func (v *View) Height() int {
|
||||
return v.y1 - v.y0 - 1
|
||||
}
|
||||
|
||||
// if a view has a frame, that leaves less space for its writeable area
|
||||
func (v *View) InnerWidth() int {
|
||||
return v.Width() - v.frameOffset()
|
||||
}
|
||||
|
||||
func (v *View) InnerHeight() int {
|
||||
return v.Height() - v.frameOffset()
|
||||
}
|
||||
|
||||
func (v *View) frameOffset() int {
|
||||
if v.Frame {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the name of the view.
|
||||
@ -576,12 +601,14 @@ func (v *View) writeRunes(p []rune) {
|
||||
case '\r':
|
||||
v.wx = 0
|
||||
default:
|
||||
cells := v.parseInput(r)
|
||||
moveCursor, cells := v.parseInput(r)
|
||||
if cells == nil {
|
||||
continue
|
||||
}
|
||||
v.writeCells(v.wx, v.wy, cells)
|
||||
v.wx += len(cells)
|
||||
if moveCursor {
|
||||
v.wx += len(cells)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -589,8 +616,9 @@ func (v *View) writeRunes(p []rune) {
|
||||
// parseInput parses char by char the input written to the View. It returns nil
|
||||
// while processing ESC sequences. Otherwise, it returns a cell slice that
|
||||
// contains the processed data.
|
||||
func (v *View) parseInput(ch rune) []cell {
|
||||
func (v *View) parseInput(ch rune) (bool, []cell) {
|
||||
cells := []cell{}
|
||||
moveCursor := true
|
||||
|
||||
isEscape, err := v.ei.parseOne(ch)
|
||||
if err != nil {
|
||||
@ -604,25 +632,32 @@ func (v *View) parseInput(ch rune) []cell {
|
||||
}
|
||||
v.ei.reset()
|
||||
} else {
|
||||
if isEscape {
|
||||
return nil
|
||||
}
|
||||
repeatCount := 1
|
||||
if ch == '\t' {
|
||||
if _, ok := v.ei.instruction.(eraseInLineFromCursor); ok {
|
||||
// fill rest of line
|
||||
v.ei.instructionRead()
|
||||
repeatCount = v.InnerWidth() - v.wx
|
||||
ch = ' '
|
||||
moveCursor = false
|
||||
} else if isEscape {
|
||||
// do not output anything
|
||||
return moveCursor, nil
|
||||
} else if ch == '\t' {
|
||||
// fill tab-sized space
|
||||
ch = ' '
|
||||
repeatCount = 4
|
||||
}
|
||||
c := cell{
|
||||
fgColor: v.ei.curFgColor,
|
||||
bgColor: v.ei.curBgColor,
|
||||
chr: ch,
|
||||
}
|
||||
for i := 0; i < repeatCount; i++ {
|
||||
c := cell{
|
||||
fgColor: v.ei.curFgColor,
|
||||
bgColor: v.ei.curBgColor,
|
||||
chr: ch,
|
||||
}
|
||||
cells = append(cells, c)
|
||||
}
|
||||
}
|
||||
|
||||
return cells
|
||||
return moveCursor, cells
|
||||
}
|
||||
|
||||
// Read reads data into p from the current reading position set by SetReadPos.
|
||||
@ -767,6 +802,8 @@ func (v *View) IsTainted() bool {
|
||||
|
||||
// draw re-draws the view's contents.
|
||||
func (v *View) draw() error {
|
||||
v.clearRunes()
|
||||
|
||||
if !v.Visible {
|
||||
return nil
|
||||
}
|
||||
@ -809,8 +846,9 @@ func (v *View) draw() error {
|
||||
}
|
||||
}
|
||||
|
||||
if v.Autoscroll && len(v.viewLines) > maxY {
|
||||
v.oy = len(v.viewLines) - maxY
|
||||
visibleViewLinesHeight := v.viewLineLengthIgnoringTrailingBlankLines()
|
||||
if v.Autoscroll && visibleViewLinesHeight > maxY {
|
||||
v.oy = visibleViewLinesHeight - maxY
|
||||
}
|
||||
y := 0
|
||||
for i, vline := range v.viewLines {
|
||||
@ -858,6 +896,18 @@ func (v *View) draw() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if autoscroll is enabled but we only have a single row of cells shown to the
|
||||
// user, we don't want to scroll to the final line if it contains no text. So
|
||||
// this tells us the view lines height when we ignore any trailing blank lines
|
||||
func (v *View) viewLineLengthIgnoringTrailingBlankLines() int {
|
||||
for i := len(v.viewLines) - 1; i >= 0; i-- {
|
||||
if len(v.viewLines[i].line) > 0 {
|
||||
return i + 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (v *View) isPatternMatchedRune(x, y int) (bool, bool) {
|
||||
searchStringLength := len(v.searcher.searchString)
|
||||
for i, pos := range v.searcher.searchPositions {
|
||||
@ -1008,23 +1058,6 @@ func indexFunc(r rune) bool {
|
||||
return r == ' ' || r == 0
|
||||
}
|
||||
|
||||
// SetLine changes the contents of an existing line.
|
||||
func (v *View) SetLine(y int, text string) error {
|
||||
if y < 0 || y >= len(v.lines) {
|
||||
err := ErrInvalidPoint
|
||||
return err
|
||||
}
|
||||
|
||||
v.tainted = true
|
||||
line := make([]cell, 0)
|
||||
for _, r := range text {
|
||||
c := v.parseInput(r)
|
||||
line = append(line, c...)
|
||||
}
|
||||
v.lines[y] = line
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetHighlight toggles highlighting of separate lines, for custom lists
|
||||
// or multiple selection in views.
|
||||
func (v *View) SetHighlight(y int, on bool) error {
|
||||
@ -1129,14 +1162,10 @@ func (v *View) RenderTextArea() {
|
||||
fmt.Fprint(v, v.TextArea.GetContent())
|
||||
cursorX, cursorY := v.TextArea.GetCursorXY()
|
||||
prevOriginX, prevOriginY := v.Origin()
|
||||
width, height := v.Size()
|
||||
width, height := v.InnerWidth(), v.InnerHeight()
|
||||
|
||||
frameAdjustment := 0
|
||||
if v.Frame {
|
||||
frameAdjustment = -1
|
||||
}
|
||||
newViewCursorX, newOriginX := updatedCursorAndOrigin(prevOriginX, width+frameAdjustment, cursorX)
|
||||
newViewCursorY, newOriginY := updatedCursorAndOrigin(prevOriginY, height+frameAdjustment, cursorY)
|
||||
newViewCursorX, newOriginX := updatedCursorAndOrigin(prevOriginX, width, cursorX)
|
||||
newViewCursorY, newOriginY := updatedCursorAndOrigin(prevOriginY, height, cursorY)
|
||||
|
||||
_ = v.SetCursor(newViewCursorX, newViewCursorY)
|
||||
_ = v.SetOrigin(newOriginX, newOriginY)
|
||||
|
Reference in New Issue
Block a user