mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-30 00:33:56 +00:00
Improved handling of tab characters
This commit is contained in:
parent
1b6cb3532d
commit
8bead4ae34
@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Current version
|
// Current version
|
||||||
const Version = "0.9.1"
|
const Version = "0.9.2-dev"
|
||||||
|
|
||||||
// fzf events
|
// fzf events
|
||||||
const (
|
const (
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package fzf
|
package fzf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -169,10 +171,18 @@ func (t *Terminal) output() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runeWidth(r rune, prefixWidth int) int {
|
||||||
|
if r == '\t' {
|
||||||
|
return 8 - prefixWidth%8
|
||||||
|
} else {
|
||||||
|
return runewidth.RuneWidth(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func displayWidth(runes []rune) int {
|
func displayWidth(runes []rune) int {
|
||||||
l := 0
|
l := 0
|
||||||
for _, r := range runes {
|
for _, r := range runes {
|
||||||
l += runewidth.RuneWidth(r)
|
l += runeWidth(r, l)
|
||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
@ -254,16 +264,27 @@ func (t *Terminal) printItem(item *Item, current bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func trimRight(runes []rune, width int) ([]rune, int) {
|
func trimRight(runes []rune, width int) ([]rune, int) {
|
||||||
currentWidth := displayWidth(runes)
|
// We start from the beginning to handle tab characters
|
||||||
trimmed := 0
|
l := 0
|
||||||
|
for idx, r := range runes {
|
||||||
for currentWidth > width && len(runes) > 0 {
|
l += runeWidth(r, l)
|
||||||
sz := len(runes)
|
if idx > 0 && l > width {
|
||||||
currentWidth -= runewidth.RuneWidth(runes[sz-1])
|
return runes[:idx], len(runes) - idx
|
||||||
runes = runes[:sz-1]
|
|
||||||
trimmed++
|
|
||||||
}
|
}
|
||||||
return runes, trimmed
|
}
|
||||||
|
return runes, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func displayWidthWithLimit(runes []rune, prefixWidth int, limit int) int {
|
||||||
|
l := 0
|
||||||
|
for _, r := range runes {
|
||||||
|
l += runeWidth(r, l+prefixWidth)
|
||||||
|
if l > limit {
|
||||||
|
// Early exit
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimLeft(runes []rune, width int) ([]rune, int32) {
|
func trimLeft(runes []rune, width int) ([]rune, int32) {
|
||||||
@ -271,9 +292,9 @@ func trimLeft(runes []rune, width int) ([]rune, int32) {
|
|||||||
var trimmed int32
|
var trimmed int32
|
||||||
|
|
||||||
for currentWidth > width && len(runes) > 0 {
|
for currentWidth > width && len(runes) > 0 {
|
||||||
currentWidth -= runewidth.RuneWidth(runes[0])
|
|
||||||
runes = runes[1:]
|
runes = runes[1:]
|
||||||
trimmed++
|
trimmed++
|
||||||
|
currentWidth = displayWidthWithLimit(runes, 2, width)
|
||||||
}
|
}
|
||||||
return runes, trimmed
|
return runes, trimmed
|
||||||
}
|
}
|
||||||
@ -323,18 +344,41 @@ func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) {
|
|||||||
|
|
||||||
sort.Sort(ByOrder(offsets))
|
sort.Sort(ByOrder(offsets))
|
||||||
var index int32
|
var index int32
|
||||||
|
var substr string
|
||||||
|
var prefixWidth int
|
||||||
for _, offset := range offsets {
|
for _, offset := range offsets {
|
||||||
b := util.Max32(index, offset[0])
|
b := util.Max32(index, offset[0])
|
||||||
e := util.Max32(index, offset[1])
|
e := util.Max32(index, offset[1])
|
||||||
C.CPrint(col1, bold, string(text[index:b]))
|
|
||||||
C.CPrint(col2, bold, string(text[b:e]))
|
substr, prefixWidth = processTabs(text[index:b], prefixWidth)
|
||||||
|
C.CPrint(col1, bold, substr)
|
||||||
|
|
||||||
|
substr, prefixWidth = processTabs(text[b:e], prefixWidth)
|
||||||
|
C.CPrint(col2, bold, substr)
|
||||||
|
|
||||||
index = e
|
index = e
|
||||||
}
|
}
|
||||||
if index < int32(len(text)) {
|
if index < int32(len(text)) {
|
||||||
C.CPrint(col1, bold, string(text[index:]))
|
substr, _ = processTabs(text[index:], prefixWidth)
|
||||||
|
C.CPrint(col1, bold, substr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func processTabs(runes []rune, prefixWidth int) (string, int) {
|
||||||
|
var strbuf bytes.Buffer
|
||||||
|
l := prefixWidth
|
||||||
|
for _, r := range runes {
|
||||||
|
w := runeWidth(r, l)
|
||||||
|
l += w
|
||||||
|
if r == '\t' {
|
||||||
|
strbuf.WriteString(strings.Repeat(" ", w))
|
||||||
|
} else {
|
||||||
|
strbuf.WriteRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strbuf.String(), l
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Terminal) printAll() {
|
func (t *Terminal) printAll() {
|
||||||
t.printList()
|
t.printList()
|
||||||
t.printInfo()
|
t.printInfo()
|
||||||
|
Loading…
Reference in New Issue
Block a user