diff options
| author | Junegunn Choi <junegunn.c@gmail.com> | 2023-03-29 20:36:09 +0900 |
|---|---|---|
| committer | Junegunn Choi <junegunn.c@gmail.com> | 2023-04-01 12:59:44 +0900 |
| commit | 1c7534f00966edca7c44054af199ca27aca0a80c (patch) | |
| tree | 58ec99c05fc552f69ce05dc8160d70324254e6fd /src | |
| parent | ae745d9397bdc8b91f3c1834def3b8ecb0ae57b1 (diff) | |
| download | fzf-1c7534f00966edca7c44054af199ca27aca0a80c.tar.gz | |
Add --track option to track the current selection
Close #3186
Related #1890
Diffstat (limited to 'src')
| -rw-r--r-- | src/merger.go | 17 | ||||
| -rw-r--r-- | src/options.go | 7 | ||||
| -rw-r--r-- | src/terminal.go | 18 |
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) |
