Skip to content

Commit

Permalink
Improved handling of tab characters
Browse files Browse the repository at this point in the history
  • Loading branch information
junegunn committed Jan 18, 2015
1 parent 1b6cb35 commit 8bead4a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

// Current version
const Version = "0.9.1"
const Version = "0.9.2-dev"

// fzf events
const (
Expand Down
70 changes: 57 additions & 13 deletions src/terminal.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package fzf

import (
"bytes"
"fmt"
"os"
"regexp"
"sort"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -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 {
l := 0
for _, r := range runes {
l += runewidth.RuneWidth(r)
l += runeWidth(r, l)
}
return l
}
Expand Down Expand Up @@ -254,26 +264,37 @@ func (t *Terminal) printItem(item *Item, current bool) {
}

func trimRight(runes []rune, width int) ([]rune, int) {
currentWidth := displayWidth(runes)
trimmed := 0
// We start from the beginning to handle tab characters
l := 0
for idx, r := range runes {
l += runeWidth(r, l)
if idx > 0 && l > width {
return runes[:idx], len(runes) - idx
}
}
return runes, 0
}

for currentWidth > width && len(runes) > 0 {
sz := len(runes)
currentWidth -= runewidth.RuneWidth(runes[sz-1])
runes = runes[:sz-1]
trimmed++
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 runes, trimmed
return l
}

func trimLeft(runes []rune, width int) ([]rune, int32) {
currentWidth := displayWidth(runes)
var trimmed int32

for currentWidth > width && len(runes) > 0 {
currentWidth -= runewidth.RuneWidth(runes[0])
runes = runes[1:]
trimmed++
currentWidth = displayWidthWithLimit(runes, 2, width)
}
return runes, trimmed
}
Expand Down Expand Up @@ -323,16 +344,39 @@ func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) {

sort.Sort(ByOrder(offsets))
var index int32
var substr string
var prefixWidth int
for _, offset := range offsets {
b := util.Max32(index, offset[0])
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
}
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() {
Expand Down

0 comments on commit 8bead4a

Please sign in to comment.