diff options
Diffstat (limited to 'vendor/github.com/jesseduffield/gocui/view.go')
-rw-r--r-- | vendor/github.com/jesseduffield/gocui/view.go | 109 |
1 files changed, 69 insertions, 40 deletions
diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 11e0e6d70..0ebd6e4a2 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -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) |