summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2023-03-29 20:36:09 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2023-04-01 12:59:44 +0900
commit1c7534f00966edca7c44054af199ca27aca0a80c (patch)
tree58ec99c05fc552f69ce05dc8160d70324254e6fd /src
parentae745d9397bdc8b91f3c1834def3b8ecb0ae57b1 (diff)
downloadfzf-1c7534f00966edca7c44054af199ca27aca0a80c.tar.gz
Add --track option to track the current selection
Close #3186 Related #1890
Diffstat (limited to 'src')
-rw-r--r--src/merger.go17
-rw-r--r--src/options.go7
-rw-r--r--src/terminal.go18
3 files changed, 41 insertions, 1 deletions
diff --git a/src/merger.go b/src/merger.go
index 8e6a884c..cdf00acc 100644
--- a/src/merger.go
+++ b/src/merger.go
@@ -17,6 +17,7 @@ type Merger struct {
tac bool
final bool
count int
+ pass bool
}
// PassMerger returns a new Merger that simply returns the items in the
@@ -26,7 +27,8 @@ func PassMerger(chunks *[]*Chunk, tac bool) *Merger {
pattern: nil,
chunks: chunks,
tac: tac,
- count: 0}
+ count: 0,
+ pass: true}
for _, chunk := range *mg.chunks {
mg.count += chunk.count
@@ -58,6 +60,19 @@ func (mg *Merger) Length() int {
return mg.count
}
+// FindIndex returns the index of the item with the given item index
+func (mg *Merger) FindIndex(itemIndex int32) int {
+ if mg.pass {
+ return int(itemIndex)
+ }
+ for i := 0; i < mg.count; i++ {
+ if mg.Get(i).item.Index() == itemIndex {
+ return i
+ }
+ }
+ return -1
+}
+
// Get returns the pointer to the Result object indexed by the given integer
func (mg *Merger) Get(idx int) Result {
if mg.chunks != nil {
diff --git a/src/options.go b/src/options.go
index 9f953bda..36ca7710 100644
--- a/src/options.go
+++ b/src/options.go
@@ -33,6 +33,7 @@ const usage = `usage: fzf [options]
field index expressions
-d, --delimiter=STR Field delimiter regex (default: AWK-style)
+s, --no-sort Do not sort the result
+ --track Track the current selection when the result is updated
--tac Reverse the order of the input
--disabled Do not perform search
--tiebreak=CRI[,..] Comma-separated list of sort criteria to apply
@@ -266,6 +267,7 @@ type Options struct {
WithNth []Range
Delimiter Delimiter
Sort int
+ Track bool
Tac bool
Criteria []criterion
Multi int
@@ -338,6 +340,7 @@ func defaultOptions() *Options {
WithNth: make([]Range, 0),
Delimiter: Delimiter{},
Sort: 1000,
+ Track: false,
Tac: false,
Criteria: []criterion{byScore, byLength},
Multi: 0,
@@ -1562,6 +1565,10 @@ func parseOptions(opts *Options, allArgs []string) {
opts.Sort = optionalNumeric(allArgs, &i, 1)
case "+s", "--no-sort":
opts.Sort = 0
+ case "--track":
+ opts.Track = true
+ case "--no-track":
+ opts.Track = false
case "--tac":
opts.Tac = true
case "--no-tac":
diff --git a/src/terminal.go b/src/terminal.go
index 468b90f8..57ff4f54 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -183,6 +183,7 @@ type Terminal struct {
multi int
sort bool
toggleSort bool
+ track bool
delimiter Delimiter
expect map[tui.Event]string
keymap map[tui.Event][]*action
@@ -599,6 +600,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
multi: opts.Multi,
sort: opts.Sort > 0,
toggleSort: opts.ToggleSort,
+ track: opts.Track,
delimiter: opts.Delimiter,
expect: opts.Expect,
keymap: opts.Keymap,
@@ -904,6 +906,10 @@ func (t *Terminal) UpdateProgress(progress float32) {
// UpdateList updates Merger to display the list
func (t *Terminal) UpdateList(merger *Merger, reset bool) {
t.mutex.Lock()
+ var prevIndex int32 = -1
+ if !reset && t.track && t.merger.Length() > 0 {
+ prevIndex = t.merger.Get(t.cy).item.Index()
+ }
t.progress = 100
t.merger = merger
if reset {
@@ -914,6 +920,18 @@ func (t *Terminal) UpdateList(merger *Merger, reset bool) {
t.triggerLoad = false
t.eventChan <- tui.Load.AsEvent()
}
+ if prevIndex >= 0 {
+ pos := t.cy - t.offset
+ count := t.merger.Length()
+ i := t.merger.FindIndex(prevIndex)
+ if i >= 0 {
+ t.cy = i
+ t.offset = t.cy - pos
+ } else if t.cy > count {
+ // Try to keep the vertical position when the list shrinks
+ t.cy = count - util.Min(count, t.maxItems()) + pos
+ }
+ }
t.mutex.Unlock()
t.reqBox.Set(reqInfo, nil)
t.reqBox.Set(reqList, nil)