Fix ruler overwriting neighboring split pane + fix crash #3052 (#3069)

* Fix gutter overwriting other split pane

When we resize a split pane to a very small width, so that the gutter
does not fit in the pane, it overwrites the sibling split pane.

To fix it, clean up the calculation of gutter width, buffer width and
scrollbar width, so that they add up exactly to the window width, and
ensure that we don't draw the gutter beyond this calculated gutter
width (gutterOffset).

As a bonus, this also fixes the crash #3052 (observed when resizing a
split pane to a very small width, if wordwrap is enabled), by ensuring
that bufWidth is never negative.

[*] By the gutter we mean of course gutter + diffgutter + ruler.

* Don't display line numbers if buffer width is 0 and softwrap is on

If softwrap is enabled, the line numbers displayed in the ruler depend
on the heights of the displayed softwrapped lines, which depend on the
width of the displayed buffer. If this width is 0 (e.g. after resizing
buffer pane to a very small width), there is no displayed text at all,
so line numbers don't make sense. So don't display line numbers in this
case.

* Fix buffer text overwriting scrollbar when window width is 1 char
This commit is contained in:
Dmytro Maluka 2024-03-13 21:11:04 +01:00 committed by GitHub
parent 628d9bb37b
commit dcdd3e749a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -129,6 +129,11 @@ func (w *BufWindow) updateDisplayInfo() {
w.bufHeight--
}
scrollbarWidth := 0
if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height && w.Width > 0 {
scrollbarWidth = 1
}
w.hasMessage = len(b.Messages) > 0
// We need to know the string length of the largest line number
@ -146,13 +151,13 @@ func (w *BufWindow) updateDisplayInfo() {
w.gutterOffset += w.maxLineNumLength + 1
}
prevBufWidth := w.bufWidth
w.bufWidth = w.Width - w.gutterOffset
if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
w.bufWidth--
if w.gutterOffset > w.Width-scrollbarWidth {
w.gutterOffset = w.Width - scrollbarWidth
}
prevBufWidth := w.bufWidth
w.bufWidth = w.Width - w.gutterOffset - scrollbarWidth
if w.bufWidth != prevBufWidth && w.Buf.Settings["softwrap"].(bool) {
for _, c := range w.Buf.GetCursors() {
c.LastVisualX = c.GetVisualX()
@ -277,13 +282,17 @@ func (w *BufWindow) drawGutter(vloc *buffer.Loc, bloc *buffer.Loc) {
break
}
}
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, s)
vloc.X++
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, s)
vloc.X++
for i := 0; i < 2 && vloc.X < w.gutterOffset; i++ {
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, s)
vloc.X++
}
}
func (w *BufWindow) drawDiffGutter(backgroundStyle tcell.Style, softwrapped bool, vloc *buffer.Loc, bloc *buffer.Loc) {
if vloc.X >= w.gutterOffset {
return
}
symbol := ' '
styleName := ""
@ -319,26 +328,28 @@ func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, vloc
} else {
lineInt = bloc.Y - cursorLine
}
lineNum := strconv.Itoa(util.Abs(lineInt))
lineNum := []rune(strconv.Itoa(util.Abs(lineInt)))
// Write the spaces before the line number if necessary
for i := 0; i < w.maxLineNumLength-len(lineNum); i++ {
for i := 0; i < w.maxLineNumLength-len(lineNum) && vloc.X < w.gutterOffset; i++ {
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
vloc.X++
}
// Write the actual line number
for _, ch := range lineNum {
if softwrapped {
for i := 0; i < len(lineNum) && vloc.X < w.gutterOffset; i++ {
if softwrapped || (w.bufWidth == 0 && w.Buf.Settings["softwrap"] == true) {
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
} else {
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ch, nil, lineNumStyle)
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, lineNum[i], nil, lineNumStyle)
}
vloc.X++
}
// Write the extra space
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
vloc.X++
if vloc.X < w.gutterOffset {
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
vloc.X++
}
}
// getStyle returns the highlight style for the given character position
@ -619,7 +630,7 @@ func (w *BufWindow) displayBuffer() {
wordwidth := 0
totalwidth := w.StartCol - nColsBeforeStart
for len(line) > 0 {
for len(line) > 0 && vloc.X < maxWidth {
r, combc, size := util.DecodeCharacter(line)
line = line[size:]