Allow search query longer than the screen width

By implementing horizontal scrolling of the prompt line.
Maximum length is hard-coded to 300-chars.

Close #1312
Fix #1225
This commit is contained in:
Junegunn Choi 2018-06-25 19:07:12 +09:00
parent f0fe79dd3b
commit 0edbcbdf19
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
2 changed files with 39 additions and 17 deletions

View File

@ -22,9 +22,10 @@ const (
readerPollIntervalMax = 50 * time.Millisecond
// Terminal
initialDelay = 20 * time.Millisecond
initialDelayTac = 100 * time.Millisecond
spinnerDuration = 200 * time.Millisecond
initialDelay = 20 * time.Millisecond
initialDelayTac = 100 * time.Millisecond
spinnerDuration = 200 * time.Millisecond
maxPatternLength = 300
// Matcher
numPartitionsMultiplier = 8

View File

@ -59,6 +59,7 @@ type Terminal struct {
inlineInfo bool
prompt string
promptLen int
queryLen [2]int
layout layoutType
fullscreen bool
hscroll bool
@ -68,6 +69,7 @@ type Terminal struct {
cx int
cy int
offset int
xoffset int
yanked []rune
input []rune
multi bool
@ -364,6 +366,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
t := Terminal{
initDelay: delay,
inlineInfo: opts.InlineInfo,
queryLen: [2]int{0, 0},
layout: opts.Layout,
fullscreen: fullscreen,
hscroll: opts.Hscroll,
@ -373,6 +376,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
cx: len(input),
cy: 0,
offset: 0,
xoffset: 0,
yanked: []rune{},
input: input,
multi: opts.Multi,
@ -640,7 +644,6 @@ func (t *Terminal) resizeWindows() {
for i := 0; i < t.window.Height(); i++ {
t.window.MoveAndClear(i, 0)
}
t.truncateQuery()
}
func (t *Terminal) move(y int, x int, clear bool) {
@ -668,20 +671,44 @@ func (t *Terminal) move(y int, x int, clear bool) {
}
}
func (t *Terminal) truncateQuery() {
t.input, _ = t.trimRight(t.input, maxPatternLength)
t.cx = util.Constrain(t.cx, 0, len(t.input))
}
func (t *Terminal) updatePromptOffset() ([]rune, []rune) {
maxWidth := util.Max(1, t.window.Width()-t.promptLen-1)
_, overflow := t.trimLeft(t.input[:t.cx], maxWidth)
minOffset := int(overflow)
maxOffset := util.Min(util.Min(len(t.input), minOffset+maxWidth), t.cx)
t.xoffset = util.Constrain(t.xoffset, minOffset, maxOffset)
before, _ := t.trimLeft(t.input[t.xoffset:t.cx], maxWidth)
beforeLen := t.displayWidth(before)
after, _ := t.trimRight(t.input[t.cx:], maxWidth-beforeLen)
afterLen := t.displayWidth(after)
t.queryLen = [2]int{beforeLen, afterLen}
return before, after
}
func (t *Terminal) placeCursor() {
t.move(0, t.promptLen+t.displayWidth(t.input[:t.cx]), false)
t.move(0, t.promptLen+t.queryLen[0], false)
}
func (t *Terminal) printPrompt() {
t.move(0, 0, true)
t.window.CPrint(tui.ColPrompt, t.strong, t.prompt)
t.window.CPrint(tui.ColNormal, t.strong, string(t.input))
before, after := t.updatePromptOffset()
t.window.CPrint(tui.ColNormal, t.strong, string(before))
t.window.CPrint(tui.ColNormal, t.strong, string(after))
}
func (t *Terminal) printInfo() {
pos := 0
if t.inlineInfo {
pos = t.promptLen + t.displayWidth(t.input) + 1
pos = t.promptLen + t.queryLen[0] + t.queryLen[1] + 1
if pos+len(" < ") > t.window.Width() {
return
}
@ -1334,12 +1361,6 @@ func (t *Terminal) buildPlusList(template string, forcePlus bool) (bool, []*Item
return true, sels
}
func (t *Terminal) truncateQuery() {
maxPatternLength := util.Max(1, t.window.Width()-t.promptLen-1)
t.input, _ = t.trimRight(t.input, maxPatternLength)
t.cx = util.Constrain(t.cx, 0, len(t.input))
}
func (t *Terminal) selectItem(item *Item) {
t.selected[item.Index()] = selectedItem{time.Now(), item}
t.version++
@ -1392,10 +1413,10 @@ func (t *Terminal) Loop() {
t.initFunc()
t.resizeWindows()
t.printPrompt()
t.placeCursor()
t.refresh()
t.printInfo()
t.printHeader()
t.placeCursor()
t.refresh()
t.mutex.Unlock()
go func() {
timer := time.NewTimer(t.initDelay)
@ -1529,9 +1550,9 @@ func (t *Terminal) Loop() {
}
}
t.placeCursor()
t.refresh()
t.mutex.Unlock()
})
t.refresh()
}
}()
@ -1852,7 +1873,7 @@ func (t *Terminal) Loop() {
} else if me.Down {
if my == 0 && mx >= 0 {
// Prompt
t.cx = mx
t.cx = mx + t.xoffset
} else if my >= min {
// List
if t.vset(t.offset+my-min) && t.multi && me.Mod {