mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-06 07:02:09 -07:00
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:
@@ -22,9 +22,10 @@ const (
|
|||||||
readerPollIntervalMax = 50 * time.Millisecond
|
readerPollIntervalMax = 50 * time.Millisecond
|
||||||
|
|
||||||
// Terminal
|
// Terminal
|
||||||
initialDelay = 20 * time.Millisecond
|
initialDelay = 20 * time.Millisecond
|
||||||
initialDelayTac = 100 * time.Millisecond
|
initialDelayTac = 100 * time.Millisecond
|
||||||
spinnerDuration = 200 * time.Millisecond
|
spinnerDuration = 200 * time.Millisecond
|
||||||
|
maxPatternLength = 300
|
||||||
|
|
||||||
// Matcher
|
// Matcher
|
||||||
numPartitionsMultiplier = 8
|
numPartitionsMultiplier = 8
|
||||||
|
@@ -59,6 +59,7 @@ type Terminal struct {
|
|||||||
inlineInfo bool
|
inlineInfo bool
|
||||||
prompt string
|
prompt string
|
||||||
promptLen int
|
promptLen int
|
||||||
|
queryLen [2]int
|
||||||
layout layoutType
|
layout layoutType
|
||||||
fullscreen bool
|
fullscreen bool
|
||||||
hscroll bool
|
hscroll bool
|
||||||
@@ -68,6 +69,7 @@ type Terminal struct {
|
|||||||
cx int
|
cx int
|
||||||
cy int
|
cy int
|
||||||
offset int
|
offset int
|
||||||
|
xoffset int
|
||||||
yanked []rune
|
yanked []rune
|
||||||
input []rune
|
input []rune
|
||||||
multi bool
|
multi bool
|
||||||
@@ -364,6 +366,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
|||||||
t := Terminal{
|
t := Terminal{
|
||||||
initDelay: delay,
|
initDelay: delay,
|
||||||
inlineInfo: opts.InlineInfo,
|
inlineInfo: opts.InlineInfo,
|
||||||
|
queryLen: [2]int{0, 0},
|
||||||
layout: opts.Layout,
|
layout: opts.Layout,
|
||||||
fullscreen: fullscreen,
|
fullscreen: fullscreen,
|
||||||
hscroll: opts.Hscroll,
|
hscroll: opts.Hscroll,
|
||||||
@@ -373,6 +376,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
|||||||
cx: len(input),
|
cx: len(input),
|
||||||
cy: 0,
|
cy: 0,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
xoffset: 0,
|
||||||
yanked: []rune{},
|
yanked: []rune{},
|
||||||
input: input,
|
input: input,
|
||||||
multi: opts.Multi,
|
multi: opts.Multi,
|
||||||
@@ -640,7 +644,6 @@ func (t *Terminal) resizeWindows() {
|
|||||||
for i := 0; i < t.window.Height(); i++ {
|
for i := 0; i < t.window.Height(); i++ {
|
||||||
t.window.MoveAndClear(i, 0)
|
t.window.MoveAndClear(i, 0)
|
||||||
}
|
}
|
||||||
t.truncateQuery()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) move(y int, x int, clear bool) {
|
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() {
|
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() {
|
func (t *Terminal) printPrompt() {
|
||||||
t.move(0, 0, true)
|
t.move(0, 0, true)
|
||||||
t.window.CPrint(tui.ColPrompt, t.strong, t.prompt)
|
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() {
|
func (t *Terminal) printInfo() {
|
||||||
pos := 0
|
pos := 0
|
||||||
if t.inlineInfo {
|
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() {
|
if pos+len(" < ") > t.window.Width() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1334,12 +1361,6 @@ func (t *Terminal) buildPlusList(template string, forcePlus bool) (bool, []*Item
|
|||||||
return true, sels
|
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) {
|
func (t *Terminal) selectItem(item *Item) {
|
||||||
t.selected[item.Index()] = selectedItem{time.Now(), item}
|
t.selected[item.Index()] = selectedItem{time.Now(), item}
|
||||||
t.version++
|
t.version++
|
||||||
@@ -1392,10 +1413,10 @@ func (t *Terminal) Loop() {
|
|||||||
t.initFunc()
|
t.initFunc()
|
||||||
t.resizeWindows()
|
t.resizeWindows()
|
||||||
t.printPrompt()
|
t.printPrompt()
|
||||||
t.placeCursor()
|
|
||||||
t.refresh()
|
|
||||||
t.printInfo()
|
t.printInfo()
|
||||||
t.printHeader()
|
t.printHeader()
|
||||||
|
t.placeCursor()
|
||||||
|
t.refresh()
|
||||||
t.mutex.Unlock()
|
t.mutex.Unlock()
|
||||||
go func() {
|
go func() {
|
||||||
timer := time.NewTimer(t.initDelay)
|
timer := time.NewTimer(t.initDelay)
|
||||||
@@ -1529,9 +1550,9 @@ func (t *Terminal) Loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.placeCursor()
|
t.placeCursor()
|
||||||
|
t.refresh()
|
||||||
t.mutex.Unlock()
|
t.mutex.Unlock()
|
||||||
})
|
})
|
||||||
t.refresh()
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -1852,7 +1873,7 @@ func (t *Terminal) Loop() {
|
|||||||
} else if me.Down {
|
} else if me.Down {
|
||||||
if my == 0 && mx >= 0 {
|
if my == 0 && mx >= 0 {
|
||||||
// Prompt
|
// Prompt
|
||||||
t.cx = mx
|
t.cx = mx + t.xoffset
|
||||||
} else if my >= min {
|
} else if my >= min {
|
||||||
// List
|
// List
|
||||||
if t.vset(t.offset+my-min) && t.multi && me.Mod {
|
if t.vset(t.offset+my-min) && t.multi && me.Mod {
|
||||||
|
Reference in New Issue
Block a user