mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-08 16:12:09 -07:00
@@ -2,7 +2,6 @@ package fzf
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -15,6 +14,9 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/rivo/uniseg"
|
||||
|
||||
"github.com/junegunn/fzf/src/tui"
|
||||
"github.com/junegunn/fzf/src/util"
|
||||
)
|
||||
@@ -673,11 +675,8 @@ func (t *Terminal) sortSelected() []selectedItem {
|
||||
}
|
||||
|
||||
func (t *Terminal) displayWidth(runes []rune) int {
|
||||
l := 0
|
||||
for _, r := range runes {
|
||||
l += util.RuneWidth(r, l, t.tabstop)
|
||||
}
|
||||
return l
|
||||
width, _ := util.RunesWidth(runes, 0, t.tabstop, 0)
|
||||
return width
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -1141,28 +1140,18 @@ func (t *Terminal) printItem(result Result, line int, i int, current bool) {
|
||||
t.prevLines[i] = newLine
|
||||
}
|
||||
|
||||
func (t *Terminal) trimRight(runes []rune, width int) ([]rune, int) {
|
||||
func (t *Terminal) trimRight(runes []rune, width int) ([]rune, bool) {
|
||||
// We start from the beginning to handle tab characters
|
||||
l := 0
|
||||
for idx, r := range runes {
|
||||
l += util.RuneWidth(r, l, t.tabstop)
|
||||
if l > width {
|
||||
return runes[:idx], len(runes) - idx
|
||||
}
|
||||
width, overflowIdx := util.RunesWidth(runes, 0, t.tabstop, width)
|
||||
if overflowIdx >= 0 {
|
||||
return runes[:overflowIdx], true
|
||||
}
|
||||
return runes, 0
|
||||
return runes, false
|
||||
}
|
||||
|
||||
func (t *Terminal) displayWidthWithLimit(runes []rune, prefixWidth int, limit int) int {
|
||||
l := 0
|
||||
for _, r := range runes {
|
||||
l += util.RuneWidth(r, l+prefixWidth, t.tabstop)
|
||||
if l > limit {
|
||||
// Early exit
|
||||
return l
|
||||
}
|
||||
}
|
||||
return l
|
||||
width, _ := util.RunesWidth(runes, prefixWidth, t.tabstop, limit)
|
||||
return width
|
||||
}
|
||||
|
||||
func (t *Terminal) trimLeft(runes []rune, width int) ([]rune, int32) {
|
||||
@@ -1362,9 +1351,9 @@ func (t *Terminal) renderPreviewText(height int, lines []string, lineNo int, unc
|
||||
prefixWidth := 0
|
||||
_, _, ansi = extractColor(line, ansi, func(str string, ansi *ansiState) bool {
|
||||
trimmed := []rune(str)
|
||||
trimmedLen := 0
|
||||
isTrimmed := false
|
||||
if !t.previewOpts.wrap {
|
||||
trimmed, trimmedLen = t.trimRight(trimmed, maxWidth-t.pwindow.X())
|
||||
trimmed, isTrimmed = t.trimRight(trimmed, maxWidth-t.pwindow.X())
|
||||
}
|
||||
str, width := t.processTabs(trimmed, prefixWidth)
|
||||
prefixWidth += width
|
||||
@@ -1374,7 +1363,7 @@ func (t *Terminal) renderPreviewText(height int, lines []string, lineNo int, unc
|
||||
} else {
|
||||
fillRet = t.pwindow.CFill(tui.ColPreview.Fg(), tui.ColPreview.Bg(), tui.AttrRegular, str)
|
||||
}
|
||||
return trimmedLen == 0 &&
|
||||
return !isTrimmed &&
|
||||
(fillRet == tui.FillContinue || t.previewOpts.wrap && fillRet == tui.FillNextLine)
|
||||
})
|
||||
t.previewer.scrollable = t.previewer.scrollable || t.pwindow.Y() == height-1 && t.pwindow.X() == t.pwindow.Width()
|
||||
@@ -1430,16 +1419,21 @@ func (t *Terminal) printPreviewDelayed() {
|
||||
}
|
||||
|
||||
func (t *Terminal) processTabs(runes []rune, prefixWidth int) (string, int) {
|
||||
var strbuf bytes.Buffer
|
||||
var strbuf strings.Builder
|
||||
l := prefixWidth
|
||||
for _, r := range runes {
|
||||
w := util.RuneWidth(r, l, t.tabstop)
|
||||
l += w
|
||||
if r == '\t' {
|
||||
gr := uniseg.NewGraphemes(string(runes))
|
||||
for gr.Next() {
|
||||
rs := gr.Runes()
|
||||
str := string(rs)
|
||||
var w int
|
||||
if len(rs) == 1 && rs[0] == '\t' {
|
||||
w = t.tabstop - l%t.tabstop
|
||||
strbuf.WriteString(strings.Repeat(" ", w))
|
||||
} else {
|
||||
strbuf.WriteRune(r)
|
||||
w = runewidth.StringWidth(str)
|
||||
strbuf.WriteString(str)
|
||||
}
|
||||
l += w
|
||||
}
|
||||
return strbuf.String(), l
|
||||
}
|
||||
|
Reference in New Issue
Block a user