]> git.lizzy.rs Git - micro.git/commitdiff
Add BufWidth and BufHeight
authorDmitry Maluka <dmitrymaluka@gmail.com>
Sat, 27 Feb 2021 16:37:15 +0000 (17:37 +0100)
committerDmitry Maluka <dmitrymaluka@gmail.com>
Thu, 8 Apr 2021 21:53:40 +0000 (23:53 +0200)
Fixes issue with the usage of a slightly incorrect buffer height value
(v.Height should be v.Height-1 if statusline is displayed).

Also, to avoid too many duplications, the code reorganized a little:
buffer display params (width, height, gutter offset and others) are
calculated in a single place.

internal/action/actions.go
internal/display/bufwindow.go
internal/display/infowindow.go
internal/display/softwrap.go
internal/display/window.go

index 6db8e82203e97c294de4f9cf671a819b775f36bc..c0334a6ae090e6f2ebbc9f1b931d612efc2f7c13 100644 (file)
@@ -36,8 +36,8 @@ func (h *BufPane) ScrollDown(n int) {
 func (h *BufPane) ScrollAdjust() {
        v := h.GetView()
        end := h.SLocFromLoc(h.Buf.End())
-       if h.Diff(v.StartLine, end) < v.Height-1 {
-               v.StartLine = h.Scroll(end, -v.Height+1)
+       if h.Diff(v.StartLine, end) < h.BufHeight()-1 {
+               v.StartLine = h.Scroll(end, -h.BufHeight()+1)
        }
        h.SetView(v)
 }
@@ -117,7 +117,7 @@ func (h *BufPane) ScrollDownAction() bool {
 // Center centers the view on the cursor
 func (h *BufPane) Center() bool {
        v := h.GetView()
-       v.StartLine = h.Scroll(h.SLocFromLoc(h.Cursor.Loc), -v.Height/2)
+       v.StartLine = h.Scroll(h.SLocFromLoc(h.Cursor.Loc), -h.BufHeight()/2)
        h.SetView(v)
        h.ScrollAdjust()
        return true
@@ -1251,22 +1251,20 @@ func (h *BufPane) Start() bool {
 // End moves the viewport to the end of the buffer
 func (h *BufPane) End() bool {
        v := h.GetView()
-       v.StartLine = h.Scroll(h.SLocFromLoc(h.Buf.End()), -v.Height+1)
+       v.StartLine = h.Scroll(h.SLocFromLoc(h.Buf.End()), -h.BufHeight()+1)
        h.SetView(v)
        return true
 }
 
 // PageUp scrolls the view up a page
 func (h *BufPane) PageUp() bool {
-       v := h.GetView()
-       h.ScrollUp(v.Height)
+       h.ScrollUp(h.BufHeight())
        return true
 }
 
 // PageDown scrolls the view down a page
 func (h *BufPane) PageDown() bool {
-       v := h.GetView()
-       h.ScrollDown(v.Height)
+       h.ScrollDown(h.BufHeight())
        h.ScrollAdjust()
        return true
 }
@@ -1276,7 +1274,7 @@ func (h *BufPane) SelectPageUp() bool {
        if !h.Cursor.HasSelection() {
                h.Cursor.OrigSelection[0] = h.Cursor.Loc
        }
-       h.Cursor.UpN(h.GetView().Height)
+       h.Cursor.UpN(h.BufHeight())
        h.Cursor.SelectTo(h.Cursor.Loc)
        h.Relocate()
        return true
@@ -1287,7 +1285,7 @@ func (h *BufPane) SelectPageDown() bool {
        if !h.Cursor.HasSelection() {
                h.Cursor.OrigSelection[0] = h.Cursor.Loc
        }
-       h.Cursor.DownN(h.GetView().Height)
+       h.Cursor.DownN(h.BufHeight())
        h.Cursor.SelectTo(h.Cursor.Loc)
        h.Relocate()
        return true
@@ -1302,7 +1300,7 @@ func (h *BufPane) CursorPageUp() bool {
                h.Cursor.ResetSelection()
                h.Cursor.StoreVisualX()
        }
-       h.Cursor.UpN(h.GetView().Height)
+       h.Cursor.UpN(h.BufHeight())
        h.Relocate()
        return true
 }
@@ -1316,22 +1314,20 @@ func (h *BufPane) CursorPageDown() bool {
                h.Cursor.ResetSelection()
                h.Cursor.StoreVisualX()
        }
-       h.Cursor.DownN(h.GetView().Height)
+       h.Cursor.DownN(h.BufHeight())
        h.Relocate()
        return true
 }
 
 // HalfPageUp scrolls the view up half a page
 func (h *BufPane) HalfPageUp() bool {
-       v := h.GetView()
-       h.ScrollUp(v.Height / 2)
+       h.ScrollUp(h.BufHeight() / 2)
        return true
 }
 
 // HalfPageDown scrolls the view down half a page
 func (h *BufPane) HalfPageDown() bool {
-       v := h.GetView()
-       h.ScrollDown(v.Height / 2)
+       h.ScrollDown(h.BufHeight() / 2)
        h.ScrollAdjust()
        return true
 }
index 2fcf0ac50c27fffb089911e3e547ddd8c232fd85..3c1136b154636844323fb009ca5d1cf1b6c44f4d 100644 (file)
@@ -23,8 +23,12 @@ type BufWindow struct {
 
        sline *StatusLine
 
-       gutterOffset int
-       drawStatus   bool
+       bufWidth         int
+       bufHeight        int
+       gutterOffset     int
+       hasMessage       bool
+       maxLineNumLength int
+       drawDivider      bool
 }
 
 // NewBufWindow creates a new window at a location in the screen with a width and height
@@ -64,6 +68,61 @@ func (w *BufWindow) IsActive() bool {
        return w.active
 }
 
+// BufWidth returns the width of the actual buffer displayed in the window,
+// which is usually less than the window width due to the gutter, ruler or scrollbar
+func (w *BufWindow) BufWidth() int {
+       return w.bufWidth
+}
+
+// BufHeight returns the height of the actual buffer displayed in the window,
+// which is usually less than the window height due to the statusline
+func (w *BufWindow) BufHeight() int {
+       return w.bufHeight
+}
+
+func (w *BufWindow) updateDisplayInfo() {
+       b := w.Buf
+
+       w.drawDivider = false
+       if !b.Settings["statusline"].(bool) {
+               _, h := screen.Screen.Size()
+               infoY := h
+               if config.GetGlobalOption("infobar").(bool) {
+                       infoY--
+               }
+               if w.Y+w.Height != infoY {
+                       w.drawDivider = true
+               }
+       }
+
+       w.bufHeight = w.Height
+       if b.Settings["statusline"].(bool) || w.drawDivider {
+               w.bufHeight--
+       }
+
+       w.hasMessage = len(b.Messages) > 0
+
+       // We need to know the string length of the largest line number
+       // so we can pad appropriately when displaying line numbers
+       w.maxLineNumLength = len(strconv.Itoa(b.LinesNum()))
+
+       w.gutterOffset = 0
+       if w.hasMessage {
+               w.gutterOffset += 2
+       }
+       if b.Settings["diffgutter"].(bool) {
+               w.gutterOffset++
+       }
+       if b.Settings["ruler"].(bool) {
+               w.gutterOffset += w.maxLineNumLength + 1
+       }
+
+       w.bufWidth = w.Width - w.gutterOffset
+       if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
+               w.bufWidth--
+       }
+}
+
 func (w *BufWindow) getStartInfo(n, lineN int) ([]byte, int, int, *tcell.Style) {
        tabsize := util.IntOpt(w.Buf.Settings["tabsize"])
        width := 0
@@ -111,10 +170,7 @@ func (w *BufWindow) Clear() {
 // Returns true if the window location is moved
 func (w *BufWindow) Relocate() bool {
        b := w.Buf
-       height := w.Height
-       if w.drawStatus {
-               height--
-       }
+       height := w.bufHeight
        ret := false
        activeC := w.Buf.GetActiveCursor()
        scrollmargin := int(b.Settings["scrollmargin"].(float64))
@@ -162,20 +218,7 @@ func (w *BufWindow) Relocate() bool {
 func (w *BufWindow) LocFromVisual(svloc buffer.Loc) buffer.Loc {
        b := w.Buf
 
-       hasMessage := len(b.Messages) > 0
-       bufHeight := w.Height
-       if w.drawStatus {
-               bufHeight--
-       }
-
-       bufWidth := w.Width
-       if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
-               bufWidth--
-       }
-
-       // We need to know the string length of the largest line number
-       // so we can pad appropriately when displaying line numbers
-       maxLineNumLength := len(strconv.Itoa(b.LinesNum()))
+       maxWidth := w.gutterOffset + w.bufWidth
 
        tabsize := int(b.Settings["tabsize"].(float64))
        softwrap := b.Settings["softwrap"].(bool)
@@ -191,17 +234,8 @@ func (w *BufWindow) LocFromVisual(svloc buffer.Loc) buffer.Loc {
        // this represents the current draw position in the buffer (char positions)
        bloc := buffer.Loc{X: -1, Y: w.StartLine.Line}
 
-       for ; vloc.Y < bufHeight; vloc.Y++ {
-               vloc.X = 0
-               if hasMessage {
-                       vloc.X += 2
-               }
-               if b.Settings["diffgutter"].(bool) {
-                       vloc.X++
-               }
-               if b.Settings["ruler"].(bool) {
-                       vloc.X += maxLineNumLength + 1
-               }
+       for ; vloc.Y < w.bufHeight; vloc.Y++ {
+               vloc.X = w.gutterOffset
 
                line := b.LineBytes(bloc.Y)
                line, nColsBeforeStart, bslice := util.SliceVisualEnd(line, w.StartCol, tabsize)
@@ -251,12 +285,12 @@ func (w *BufWindow) LocFromVisual(svloc buffer.Loc) buffer.Loc {
                        totalwidth += width
 
                        // If we reach the end of the window then we either stop or we wrap for softwrap
-                       if vloc.X >= bufWidth {
+                       if vloc.X >= maxWidth {
                                if !softwrap {
                                        break
                                } else {
                                        vloc.Y++
-                                       if vloc.Y >= bufHeight {
+                                       if vloc.Y >= w.bufHeight {
                                                break
                                        }
                                        vloc.X = w.gutterOffset
@@ -267,7 +301,7 @@ func (w *BufWindow) LocFromVisual(svloc buffer.Loc) buffer.Loc {
                        return bloc
                }
 
-               if bloc.Y+1 >= b.LinesNum() || vloc.Y+1 >= bufHeight {
+               if bloc.Y+1 >= b.LinesNum() || vloc.Y+1 >= w.bufHeight {
                        return bloc
                }
 
@@ -322,7 +356,7 @@ func (w *BufWindow) drawDiffGutter(backgroundStyle tcell.Style, softwrapped bool
        vloc.X++
 }
 
-func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxLineNumLength int, vloc *buffer.Loc, bloc *buffer.Loc) {
+func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, vloc *buffer.Loc, bloc *buffer.Loc) {
        cursorLine := w.Buf.GetActiveCursor().Loc.Y
        var lineInt int
        if w.Buf.Settings["relativeruler"] == false || cursorLine == bloc.Y {
@@ -333,7 +367,7 @@ func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxL
        lineNum := strconv.Itoa(util.Abs(lineInt))
 
        // Write the spaces before the line number if necessary
-       for i := 0; i < maxLineNumLength-len(lineNum); i++ {
+       for i := 0; i < w.maxLineNumLength-len(lineNum); i++ {
                screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
                vloc.X++
        }
@@ -380,16 +414,7 @@ func (w *BufWindow) displayBuffer() {
                return
        }
 
-       hasMessage := len(b.Messages) > 0
-       bufHeight := w.Height
-       if w.drawStatus {
-               bufHeight--
-       }
-
-       bufWidth := w.Width
-       if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
-               bufWidth--
-       }
+       maxWidth := w.gutterOffset + w.bufWidth
 
        if b.ModifiedThisFrame {
                if b.Settings["diffgutter"].(bool) {
@@ -450,10 +475,6 @@ func (w *BufWindow) displayBuffer() {
                }
        }
 
-       // We need to know the string length of the largest line number
-       // so we can pad appropriately when displaying line numbers
-       maxLineNumLength := len(strconv.Itoa(b.LinesNum()))
-
        softwrap := b.Settings["softwrap"].(bool)
        tabsize := util.IntOpt(b.Settings["tabsize"])
        colorcolumn := util.IntOpt(b.Settings["colorcolumn"])
@@ -472,7 +493,7 @@ func (w *BufWindow) displayBuffer() {
        cursors := b.GetCursors()
 
        curStyle := config.DefStyle
-       for ; vloc.Y < bufHeight; vloc.Y++ {
+       for ; vloc.Y < w.bufHeight; vloc.Y++ {
                vloc.X = 0
 
                currentLine := false
@@ -489,7 +510,7 @@ func (w *BufWindow) displayBuffer() {
                }
 
                if vloc.Y >= 0 {
-                       if hasMessage {
+                       if w.hasMessage {
                                w.drawGutter(&vloc, &bloc)
                        }
 
@@ -498,22 +519,12 @@ func (w *BufWindow) displayBuffer() {
                        }
 
                        if b.Settings["ruler"].(bool) {
-                               w.drawLineNum(s, false, maxLineNumLength, &vloc, &bloc)
+                               w.drawLineNum(s, false, &vloc, &bloc)
                        }
                } else {
-                       if hasMessage {
-                               vloc.X += 2
-                       }
-                       if b.Settings["diffgutter"].(bool) {
-                               vloc.X++
-                       }
-                       if b.Settings["ruler"].(bool) {
-                               vloc.X += maxLineNumLength + 1
-                       }
+                       vloc.X = w.gutterOffset
                }
 
-               w.gutterOffset = vloc.X
-
                line, nColsBeforeStart, bslice, startStyle := w.getStartInfo(w.StartCol, bloc.Y)
                if startStyle != nil {
                        curStyle = *startStyle
@@ -633,16 +644,16 @@ func (w *BufWindow) displayBuffer() {
                        totalwidth += width
 
                        // If we reach the end of the window then we either stop or we wrap for softwrap
-                       if vloc.X >= bufWidth {
+                       if vloc.X >= maxWidth {
                                if !softwrap {
                                        break
                                } else {
                                        vloc.Y++
-                                       if vloc.Y >= bufHeight {
+                                       if vloc.Y >= w.bufHeight {
                                                break
                                        }
                                        vloc.X = 0
-                                       if hasMessage {
+                                       if w.hasMessage {
                                                w.drawGutter(&vloc, &bloc)
                                        }
                                        if b.Settings["diffgutter"].(bool) {
@@ -651,7 +662,7 @@ func (w *BufWindow) displayBuffer() {
 
                                        // This will draw an empty line number because the current line is wrapped
                                        if b.Settings["ruler"].(bool) {
-                                               w.drawLineNum(lineNumStyle, true, maxLineNumLength, &vloc, &bloc)
+                                               w.drawLineNum(lineNumStyle, true, &vloc, &bloc)
                                        }
                                }
                        }
@@ -667,7 +678,7 @@ func (w *BufWindow) displayBuffer() {
                                }
                        }
                }
-               for i := vloc.X; i < bufWidth; i++ {
+               for i := vloc.X; i < maxWidth; i++ {
                        curStyle := style
                        if s, ok := config.Colorscheme["color-column"]; ok {
                                if colorcolumn != 0 && i-w.gutterOffset+w.StartCol == colorcolumn {
@@ -678,7 +689,7 @@ func (w *BufWindow) displayBuffer() {
                        screen.SetContent(i+w.X, vloc.Y+w.Y, ' ', nil, curStyle)
                }
 
-               if vloc.X != bufWidth {
+               if vloc.X != maxWidth {
                        // Display newline within a selection
                        draw(' ', nil, config.DefStyle, true)
                }
@@ -692,18 +703,9 @@ func (w *BufWindow) displayBuffer() {
 }
 
 func (w *BufWindow) displayStatusLine() {
-       _, h := screen.Screen.Size()
-       infoY := h
-       if config.GetGlobalOption("infobar").(bool) {
-               infoY--
-       }
-
        if w.Buf.Settings["statusline"].(bool) {
-               w.drawStatus = true
                w.sline.Display()
-       } else if w.Y+w.Height != infoY {
-               w.drawStatus = true
-
+       } else if w.drawDivider {
                divchars := config.GetGlobalOption("divchars").(string)
                if util.CharacterCountInString(divchars) != 2 {
                        divchars = "|-"
@@ -725,18 +727,12 @@ func (w *BufWindow) displayStatusLine() {
                for x := w.X; x < w.X+w.Width; x++ {
                        screen.SetContent(x, w.Y+w.Height-1, divchar, combc, dividerStyle)
                }
-       } else {
-               w.drawStatus = false
        }
 }
 
 func (w *BufWindow) displayScrollBar() {
        if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
                scrollX := w.X + w.Width - 1
-               bufHeight := w.Height
-               if w.drawStatus {
-                       bufHeight--
-               }
                barsize := int(float64(w.Height) / float64(w.Buf.LinesNum()) * float64(w.Height))
                if barsize < 1 {
                        barsize = 1
@@ -748,7 +744,7 @@ func (w *BufWindow) displayScrollBar() {
                        scrollBarStyle = style
                }
 
-               for y := barstart; y < util.Min(barstart+barsize, w.Y+bufHeight); y++ {
+               for y := barstart; y < util.Min(barstart+barsize, w.Y+w.bufHeight); y++ {
                        screen.SetContent(scrollX, y, '|', nil, scrollBarStyle)
                }
        }
@@ -756,6 +752,8 @@ func (w *BufWindow) displayScrollBar() {
 
 // Display displays the buffer and the statusline
 func (w *BufWindow) Display() {
+       w.updateDisplayInfo()
+
        w.displayStatusLine()
        w.displayScrollBar()
        w.displayBuffer()
index 4cfbca32b11ab0f9e2cdfb3cb97f2127bd5f72f4..530dce67adcc38d1aaf7efd305913ee34cdef00e 100644 (file)
@@ -72,6 +72,9 @@ func (i *InfoWindow) LocFromVisual(vloc buffer.Loc) buffer.Loc {
        return buffer.Loc{c.GetCharPosInLine(l, vloc.X-n), 0}
 }
 
+func (i *InfoWindow) BufWidth() int  { return i.Width }
+func (i *InfoWindow) BufHeight() int { return 1 }
+
 func (i *InfoWindow) Scroll(s SLoc, n int) SLoc       { return s }
 func (i *InfoWindow) Diff(s1, s2 SLoc) int            { return 0 }
 func (i *InfoWindow) SLocFromLoc(loc buffer.Loc) SLoc { return SLoc{0, 0} }
index 0f99b526bfa3068f21d19f3fb098d4201ba52644..bbcc99e089bb8d6db3e67ef0a33887d6ab8051fd 100644 (file)
@@ -36,17 +36,13 @@ type SoftWrap interface {
 }
 
 func (w *BufWindow) getRow(loc buffer.Loc) int {
-       width := w.Width - w.gutterOffset
-       if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
-               width--
-       }
-       if width <= 0 {
+       if w.bufWidth <= 0 {
                return 0
        }
        // TODO: this doesn't work quite correctly if there is an incomplete tab
        // or wide character at the end of a row. See also issue #1979
        x := util.StringWidth(w.Buf.LineBytes(loc.Y), loc.X, util.IntOpt(w.Buf.Settings["tabsize"]))
-       return x / width
+       return x / w.bufWidth
 }
 
 func (w *BufWindow) getRowCount(line int) int {
index eb71970f6eabb34607565601aac88c26458cdce4..eb2c09f4f628c70c10937271a8678ad369f14790 100644 (file)
@@ -33,4 +33,6 @@ type BWindow interface {
        Window
        SoftWrap
        SetBuffer(b *buffer.Buffer)
+       BufWidth() int
+       BufHeight() int
 }