Add pos(...) action to move the cursor to the numeric position

# Put the cursor on the 10th item
  seq 100 | fzf --sync --bind 'start:pos(10)'

  # Put the cursor on the 10th to last item
  seq 100 | fzf --sync --bind 'start:pos(-10)'

Close #3069
Close #395
This commit is contained in:
Junegunn Choi 2022-12-27 01:01:06 +09:00
parent d42e708d31
commit 12af069dca
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
5 changed files with 41 additions and 3 deletions

View File

@ -12,6 +12,15 @@ CHANGELOG
# Send actions to the server
curl -XPOST localhost:6266 -d 'reload(seq 100)+change-prompt(hundred> )'
```
- Added `pos(...)` action to move the cursor to the numeric position
- `first` and `last` are equivalent to `pos(1)` and `pos(-1)` respectively
```sh
# Put the cursor on the 10th item
seq 100 | fzf --sync --bind 'start:pos(10)'
# Put the cursor on the 10th to last item
seq 100 | fzf --sync --bind 'start:pos(-10)'
```
- Added `next-selected` and `prev-selected` actions to move between selected
items
```sh

View File

@ -979,7 +979,7 @@ A key or an event can be bound to one or more of the following actions.
\fBend-of-line\fR \fIctrl-e end\fR
\fBexecute(...)\fR (see below for the details)
\fBexecute-silent(...)\fR (see below for the details)
\fBfirst\fR (move to the first match)
\fBfirst\fR (move to the first match; same as \fBpos(1)\fR)
\fBforward-char\fR \fIctrl-f right\fR
\fBforward-word\fR \fIalt-f shift-right\fR
\fBignore\fR
@ -987,13 +987,14 @@ A key or an event can be bound to one or more of the following actions.
\fBjump-accept\fR (jump and accept)
\fBkill-line\fR
\fBkill-word\fR \fIalt-d\fR
\fBlast\fR (move to the last match)
\fBlast\fR (move to the last match; same as \fBpos(-1)\fR)
\fBnext-history\fR (\fIctrl-n\fR on \fB--history\fR)
\fBnext-selected\fR (move to the next selected item)
\fBpage-down\fR \fIpgdn\fR
\fBpage-up\fR \fIpgup\fR
\fBhalf-page-down\fR
\fBhalf-page-up\fR
\fBpos(...)\fR (move cursor to the numeric position; negative number to count from the end)
\fBprev-history\fR (\fIctrl-p\fR on \fB--history\fR)
\fBprev-selected\fR (move to the previous selected item)
\fBpreview(...)\fR (see below for the details)

View File

@ -890,7 +890,7 @@ const (
func init() {
executeRegexp = regexp.MustCompile(
`(?si)[:+](execute(?:-multi|-silent)?|reload|preview|change-query|change-prompt|change-preview-window|change-preview|(?:re|un)bind)`)
`(?si)[:+](execute(?:-multi|-silent)?|reload|preview|change-query|change-prompt|change-preview-window|change-preview|(?:re|un)bind|pos)`)
splitRegexp = regexp.MustCompile("[,:]+")
actionNameRegexp = regexp.MustCompile("(?i)^[a-z-]+")
}
@ -1197,6 +1197,8 @@ func isExecuteAction(str string) actionType {
return actChangePrompt
case "change-query":
return actChangeQuery
case "pos":
return actPosition
case "execute":
return actExecute
case "execute-silent":

View File

@ -297,6 +297,7 @@ const (
actUp
actPageUp
actPageDown
actPosition
actHalfPageUp
actHalfPageDown
actJump
@ -2837,6 +2838,16 @@ func (t *Terminal) Loop() {
case actLast:
t.vset(t.merger.Length() - 1)
req(reqList)
case actPosition:
if n, e := strconv.Atoi(a.a); e == nil {
if n > 0 {
n--
} else if n < 0 {
n += t.merger.Length()
}
t.vset(n)
req(reqList)
}
case actUnixLineDiscard:
beof = len(t.input) == 0
if t.cx > 0 {

View File

@ -1605,6 +1605,21 @@ class TestGoFZF < TestBase
tmux.send_keys :Enter
end
def test_pos
tmux.send_keys %(seq 1000 | #{FZF} --bind 'a:pos(3),b:pos(-3),c:pos(1),d:pos(-1),e:pos(0)' --preview 'echo {}/{}'), :Enter
tmux.until { |lines| assert_equal 1000, lines.match_count }
tmux.send_keys :a
tmux.until { |lines| assert_includes lines[1], ' 3/3' }
tmux.send_keys :b
tmux.until { |lines| assert_includes lines[1], ' 998/998' }
tmux.send_keys :c
tmux.until { |lines| assert_includes lines[1], ' 1/1' }
tmux.send_keys :d
tmux.until { |lines| assert_includes lines[1], ' 1000/1000' }
tmux.send_keys :e
tmux.until { |lines| assert_includes lines[1], ' 1/1' }
end
def test_accept_non_empty
tmux.send_keys %(seq 1000 | #{fzf('--print-query --bind enter:accept-non-empty')}), :Enter
tmux.until { |lines| assert_equal 1000, lines.match_count }