m/fzf
1
0
mirror of https://github.com/junegunn/fzf.git synced 2025-11-15 06:43:47 -05:00

Compare commits

...

21 Commits

Author SHA1 Message Date
Junegunn Choi
19759ed36e 0.27.0 2021-04-06 22:53:59 +09:00
Junegunn Choi
1a7ae8e7b9 Update dependencies
go get: upgraded github.com/lucasb-eyer/go-colorful v1.0.3 => v1.2.0
go get: upgraded github.com/mattn/go-runewidth v0.0.9 => v0.0.12
go get: upgraded github.com/mattn/go-shellwords v1.0.10 => v1.0.11
go get: added github.com/rivo/uniseg v0.2.0
go get: upgraded github.com/saracen/walker v0.1.1 => v0.1.2
go get: upgraded golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 => v0.0.0-20210220032951-036812b2e83c
go get: upgraded golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 => v0.0.0-20210403161142-5e06dd20ab57
go get: upgraded golang.org/x/text v0.3.3 => v0.3.6
2021-04-06 20:32:18 +09:00
Junegunn Choi
da1f645670 Change --preview-window delimiter from : to , for consistency
Delimiter : was chosen when --preview-option only supported position and
size attributes. e.g. up:50%
2021-04-06 20:10:55 +09:00
Junegunn Choi
3a2015ee26 Fix minimum preview window height 2021-04-06 20:05:54 +09:00
Junegunn Choi
c440418ce6 Sign and notarize macOS binaries
Close #2408
2021-04-06 18:09:06 +09:00
Junegunn Choi
3d37a5ba1d Apply preview-bg color to preview border of all shapes 2021-04-06 18:01:29 +09:00
Junegunn Choi
15f4cfb6d9 More border optins for preview window
Close #2431
2021-04-06 17:37:11 +09:00
Junegunn Choi
be36de2482 Ignore more ANSI escape sequences
Fix #2420
2021-04-06 00:51:39 +09:00
Junegunn Choi
391237f7df [vim] Compare binary versions
Close #2410
2021-04-06 00:24:20 +09:00
Junegunn Choi
977e5effd9 [vim] Fix paste on MacVim
Close https://github.com/junegunn/fzf.vim/issues/1233
2021-04-05 17:28:18 +09:00
Junegunn Choi
8b36a4cb19 Speed up preview switching when doing partial rendering
Fix #2417
2021-04-04 13:43:16 +09:00
Michael Kelley
c8cd94a772 Ensure proper ESC seq handling under Windows preview mode (#2430)
- Increase go routine buffer size
- Add time wait for nonblock getchr()
- Resolve #2429
2021-04-04 13:19:43 +09:00
Junegunn Choi
764316a53d Fix flaky test case: test_interrupt_execute
Try to avoid extraneous INT signal
2021-03-26 17:40:12 +09:00
Philipp Schmitt
2048fd4042 Update README (--phony -> --disabled) (#2404) 2021-03-25 20:36:01 +09:00
Junegunn Choi
f84b3de24b Automatically set /dev/tty as STDIN on execute action
https://github.com/junegunn/fzf/issues/1360#issuecomment-788178140

  # Redirect /dev/tty to suppress "Vim: Warning: Input is not from a terminal"
  ls | fzf --bind "enter:execute(vim {} < /dev/tty)"

  # With this change, we can omit "< /dev/tty" part
  ls | fzf --bind "enter:execute(vim {})"
2021-03-25 20:00:09 +09:00
Junegunn Choi
6a1f3ec08b [install] Download Darwin arm64 binary (#2400 #2401) 2021-03-25 10:56:21 +09:00
Mitsuo Heijo
2e353aee96 Replace golang.org/x/crypto/ssh/terminal with golang.org/x/term (#2395)
See https://github.com/golang/go/issues/31044
2021-03-20 14:38:34 +09:00
Mitsuo Heijo
8edfd14a37 Test against Golang 1.14 and 1.16 (#2396)
1.14 for 32-bit binaries
2021-03-20 12:32:44 +09:00
Junegunn Choi
1a191ec6f7 Update FUNDING.yml 2021-03-14 12:03:11 +09:00
Junegunn Choi
e7171e94b4 Update FUNDING.yml 2021-03-14 12:01:57 +09:00
Junegunn Choi
398d937419 Create FUNDING.yml 2021-03-14 11:59:56 +09:00
23 changed files with 322 additions and 145 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
custom: ["https://paypal.me/junegunn", "https://www.buymeacoffee.com/junegunn"]

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
go: [1.14, 1.15] go: [1.14, 1.16]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: macos-latest runs-on: macos-latest
strategy: strategy:
matrix: matrix:
go: [1.14, 1.15] go: [1.14, 1.16]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:

View File

@@ -12,27 +12,20 @@ builds:
- darwin - darwin
goarch: goarch:
- amd64 - amd64
ldflags:
- "-s -w -X main.version={{ .Version }} -X main.revision={{ .ShortCommit }}"
- id: fzf-macos-arm
binary: fzf
goos:
- darwin
goarch:
- arm64 - arm64
ldflags: ldflags:
- "-s -w -X main.version={{ .Version }} -X main.revision={{ .ShortCommit }}" - "-s -w -X main.version={{ .Version }} -X main.revision={{ .ShortCommit }}"
hooks:
post: |-
sh -c '
cat > /tmp/fzf-gon.hcl << EOF
source = ["./dist/fzf-macos_darwin_{{ .Arch }}/fzf"]
bundle_id = "kr.junegunn.fzf"
apple_id {
username = "junegunn.c@gmail.com"
password = "@env:AC_PASSWORD"
}
sign {
application_identity = "Apple Development: junegunn.c@gmail.com"
}
EOF
gon /tmp/fzf-gon.hcl
'
- goos: - id: fzf
goos:
- linux - linux
- windows - windows
- freebsd - freebsd
@@ -59,6 +52,8 @@ builds:
archives: archives:
- name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" - name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
builds:
- fzf
format: tar.gz format: tar.gz
format_overrides: format_overrides:
- goos: windows - goos: windows
@@ -66,12 +61,61 @@ archives:
files: files:
- non-existent* - non-existent*
signs:
- id: fzf-macos-sign
ids: [fzf-macos]
artifacts: all
cmd: sh
args:
- "-c"
- |-
cat > /tmp/fzf-gon-amd64.hcl << EOF
source = ["./dist/fzf-macos_darwin_amd64/fzf"]
bundle_id = "kr.junegunn.fzf"
apple_id {
username = "junegunn.c@gmail.com"
password = "@env:AC_PASSWORD"
}
sign {
application_identity = "Developer ID Application: Junegunn Choi (Y254DRW44Z)"
}
zip {
output_path = "./dist/fzf-{{ .Version }}-darwin_amd64.zip"
}
EOF
gon /tmp/fzf-gon-amd64.hcl
- id: fzf-macos-arm-sign
ids: [fzf-macos-arm]
artifacts: all
cmd: sh
args:
- "-c"
- |-
cat > /tmp/fzf-gon-arm64.hcl << EOF
source = ["./dist/fzf-macos-arm_darwin_arm64/fzf"]
bundle_id = "kr.junegunn.fzf"
apple_id {
username = "junegunn.c@gmail.com"
password = "@env:AC_PASSWORD"
}
sign {
application_identity = "Developer ID Application: Junegunn Choi (Y254DRW44Z)"
}
zip {
output_path = "./dist/fzf-{{ .Version }}-darwin_arm64.zip"
}
EOF
gon /tmp/fzf-gon-arm64.hcl
release: release:
github: github:
owner: junegunn owner: junegunn
name: fzf name: fzf
prerelease: auto prerelease: auto
name_template: '{{ .Tag }}' name_template: '{{ .Tag }}'
extra_files:
- glob: ./dist/fzf-*darwin*.zip
snapshot: snapshot:
name_template: "{{ .Tag }}-devel" name_template: "{{ .Tag }}-devel"

View File

@@ -1,6 +1,27 @@
CHANGELOG CHANGELOG
========= =========
0.27.0
------
- More border options for `--preview-window`
```sh
fzf --preview 'cat {}' --preview-window border-left
fzf --preview 'cat {}' --preview-window border-left --border horizontal
fzf --preview 'cat {}' --preview-window top:border-bottom
fzf --preview 'cat {}' --preview-window top:border-horizontal
```
- Automatically set `/dev/tty` as STDIN on execute action
```sh
# Redirect /dev/tty to suppress "Vim: Warning: Input is not from a terminal"
# ls | fzf --bind "enter:execute(vim {} < /dev/tty)"
# "< /dev/tty" part is no longer needed
ls | fzf --bind "enter:execute(vim {})"
```
- Bug fixes and improvements
- Signed and notarized macOS binaries
(Huge thanks to [BACKERS.md](https://github.com/junegunn/junegunn/blob/main/BACKERS.md)!)
0.26.0 0.26.0
------ ------
- Added support for fixed header in preview window - Added support for fixed header in preview window

View File

@@ -572,8 +572,8 @@ FZF_DEFAULT_COMMAND='find . -type f' \
The following example uses fzf as the selector interface for ripgrep. We bound The following example uses fzf as the selector interface for ripgrep. We bound
`reload` action to `change` event, so every time you type on fzf, the ripgrep `reload` action to `change` event, so every time you type on fzf, the ripgrep
process will restart with the updated query string denoted by the placeholder process will restart with the updated query string denoted by the placeholder
expression `{q}`. Also, note that we used `--phony` option so that fzf doesn't expression `{q}`. Also, note that we used `--disabled` option so that fzf
perform any secondary filtering. doesn't perform any secondary filtering.
```sh ```sh
INITIAL_QUERY="" INITIAL_QUERY=""
@@ -615,7 +615,7 @@ You can customize the size, position, and border of the preview window using
```bash ```bash
fzf --height 40% --layout reverse --info inline --border \ fzf --height 40% --layout reverse --info inline --border \
--preview 'file {}' --preview-window down:1:noborder \ --preview 'file {}' --preview-window up,1,border-horizontal \
--color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899' --color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899'
``` ```

16
go.mod
View File

@@ -2,14 +2,16 @@ module github.com/junegunn/fzf
require ( require (
github.com/gdamore/tcell v1.4.0 github.com/gdamore/tcell v1.4.0
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-runewidth v0.0.9 github.com/mattn/go-runewidth v0.0.12
github.com/mattn/go-shellwords v1.0.10 github.com/mattn/go-shellwords v1.0.11
github.com/saracen/walker v0.1.1 github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 github.com/saracen/walker v0.1.2
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57
golang.org/x/text v0.3.3 // indirect golang.org/x/term v0.0.0-20210317153231-de623e64d2a6
golang.org/x/text v0.3.6 // indirect
) )
go 1.13 go 1.13

44
go.sum
View File

@@ -2,36 +2,32 @@ github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdk
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU= github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU=
github.com/gdamore/tcell v1.4.0/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0= github.com/gdamore/tcell v1.4.0/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw= github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/saracen/walker v0.1.1 h1:Ou2QIKTWqo0QxhtuHVmtObbmhjMCEUyJ82xp0uV+MGI= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/saracen/walker v0.1.1/go.mod h1:0oKYMsKVhSJ+ful4p/XbjvXbMgLEkLITZaxozsl4CGE= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= github.com/saracen/walker v0.1.2 h1:/o1TxP82n8thLvmL4GpJXduYaRmJ7qXp8u9dSlV0zmo=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= github.com/saracen/walker v0.1.2/go.mod h1:0oKYMsKVhSJ+ful4p/XbjvXbMgLEkLITZaxozsl4CGE=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 h1:/DtoiOYKoQCcIFXQjz07RnWNPRCbqmSXSpgEzhC9ZHM= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 h1:EC6+IGYTjPpRfv9a2b/6Puw0W+hLtAhkV1tPsXhutqs=
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@@ -2,7 +2,7 @@
set -u set -u
version=0.26.0 version=0.27.0
auto_completion= auto_completion=
key_bindings= key_bindings=
update_config=2 update_config=2
@@ -168,8 +168,8 @@ archi=$(uname -sm)
binary_available=1 binary_available=1
binary_error="" binary_error=""
case "$archi" in case "$archi" in
# Darwin\ arm64) download fzf-$version-darwin_arm64.tar.gz ;; # TODO Darwin\ arm64) download fzf-$version-darwin_arm64.zip ;;
Darwin\ x86_64) download fzf-$version-darwin_amd64.tar.gz ;; Darwin\ x86_64) download fzf-$version-darwin_amd64.zip ;;
Linux\ armv5*) download fzf-$version-linux_armv5.tar.gz ;; Linux\ armv5*) download fzf-$version-linux_armv5.tar.gz ;;
Linux\ armv6*) download fzf-$version-linux_armv6.tar.gz ;; Linux\ armv6*) download fzf-$version-linux_armv6.tar.gz ;;
Linux\ armv7*) download fzf-$version-linux_armv7.tar.gz ;; Linux\ armv7*) download fzf-$version-linux_armv7.tar.gz ;;

View File

@@ -1,4 +1,4 @@
$version="0.26.0" $version="0.27.0"
$fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition

View File

@@ -5,7 +5,7 @@ import (
"github.com/junegunn/fzf/src/protector" "github.com/junegunn/fzf/src/protector"
) )
var version string = "0.26" var version string = "0.27"
var revision string = "devel" var revision string = "devel"
func main() { func main() {

View File

@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
.. ..
.TH fzf-tmux 1 "Mar 2021" "fzf 0.26.0" "fzf-tmux - open fzf in tmux split pane" .TH fzf-tmux 1 "Apr 2021" "fzf 0.27.0" "fzf-tmux - open fzf in tmux split pane"
.SH NAME .SH NAME
fzf-tmux - open fzf in tmux split pane fzf-tmux - open fzf in tmux split pane

View File

@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
.. ..
.TH fzf 1 "Mar 2021" "fzf 0.26.0" "fzf - a command-line fuzzy finder" .TH fzf 1 "Apr 2021" "fzf 0.27.0" "fzf - a command-line fuzzy finder"
.SH NAME .SH NAME
fzf - a command-line fuzzy finder fzf - a command-line fuzzy finder
@@ -203,6 +203,8 @@ Draw border around the finder
.br .br
.BR right .BR right
.br .br
.BR none
.br
.TP .TP
.B "--no-unicode" .B "--no-unicode"
@@ -442,7 +444,7 @@ e.g.
done'\fR done'\fR
.RE .RE
.TP .TP
.BI "--preview-window=" "[POSITION][:SIZE[%]][:rounded|sharp|noborder][:[no]wrap][:[no]follow][:[no]cycle][:[no]hidden][:+SCROLL[OFFSETS][/DENOM]][:~HEADER_LINES][:default]" .BI "--preview-window=" "[POSITION][,SIZE[%]][,border-BORDER_OPT][,[no]wrap][,[no]follow][,[no]cycle][,[no]hidden][,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES][,default]"
.RS .RS
.B POSITION: (default: right) .B POSITION: (default: right)
@@ -477,8 +479,10 @@ e.g.
* Cyclic scrolling is enabled with \fB:cycle\fR flag. * Cyclic scrolling is enabled with \fB:cycle\fR flag.
* To change the style of the border of the preview window, specify one of * To change the style of the border of the preview window, specify one of
\fBrounded\fR (border with rounded edges, default), \fBsharp\fR (border with the options for \fB--border\fR with \fBborder-\fR prefix.
sharp edges), or \fBnoborder\fR (no border). e.g. \fBborder-rounded\fR (border with rounded edges, default),
\fBborder-sharp\fR (border with sharp edges), \fBborder-left\fR,
\fBborder-none\fR, etc.
* \fB[:+SCROLL[OFFSETS][/DENOM]]\fR determines the initial scroll offset of the * \fB[:+SCROLL[OFFSETS][/DENOM]]\fR determines the initial scroll offset of the
preview window. preview window.
@@ -497,8 +501,8 @@ are always visible.
.RS .RS
e.g. e.g.
\fB# Non-default scroll window positions and sizes \fB# Non-default scroll window positions and sizes
fzf --preview="head {}" --preview-window=up:30% fzf --preview="head {}" --preview-window=up,30%
fzf --preview="file {}" --preview-window=down:1 fzf --preview="file {}" --preview-window=down,1
# Initial scroll offset is set to the line number of each line of # Initial scroll offset is set to the line number of each line of
# git grep output *minus* 5 lines (-5) # git grep output *minus* 5 lines (-5)
@@ -516,7 +520,7 @@ e.g.
git grep --line-number '' | git grep --line-number '' |
fzf --delimiter : \\ fzf --delimiter : \\
--preview 'bat --style=full --color=always --highlight-line {2} {1}' \\ --preview 'bat --style=full --color=always --highlight-line {2} {1}' \\
--preview-window '~3:+{2}+3/2' --preview-window '~3,+{2}+3/2'
# Display top 3 lines as the fixed header # Display top 3 lines as the fixed header
fzf --preview 'bat --style=full --color=always {}' --preview-window '~3'\fR fzf --preview 'bat --style=full --color=always {}' --preview-window '~3'\fR

View File

@@ -154,46 +154,79 @@ function! fzf#install()
endif endif
endfunction endfunction
function! s:version_requirement(val, min) let s:versions = {}
let val = split(a:val, '\.') function s:get_version(bin)
let min = split(a:min, '\.') if has_key(s:versions, a:bin)
for idx in range(0, len(min) - 1) return s:versions[a:bin]
let v = get(val, idx, 0) end
if v < min[idx] | return 0 let command = a:bin . ' --version'
elseif v > min[idx] | return 1 let output = systemlist(command)
if v:shell_error || empty(output)
return ''
endif
let ver = matchstr(output[-1], '[0-9.]\+')
let s:versions[a:bin] = ver
return ver
endfunction
function! s:compare_versions(a, b)
let a = split(a:a, '\.')
let b = split(a:b, '\.')
for idx in range(0, max([len(a), len(b)]) - 1)
let v1 = str2nr(get(a, idx, 0))
let v2 = str2nr(get(b, idx, 0))
if v1 < v2 | return -1
elseif v1 > v2 | return 1
endif endif
endfor endfor
return 1 return 0
endfunction
function! s:compare_binary_versions(a, b)
return s:compare_versions(s:get_version(a:a), s:get_version(a:b))
endfunction endfunction
let s:checked = {} let s:checked = {}
function! fzf#exec(...) function! fzf#exec(...)
if !exists('s:exec') if !exists('s:exec')
if executable(s:fzf_go) let binaries = []
let s:exec = s:fzf_go if executable('fzf')
elseif executable('fzf') call add(binaries, 'fzf')
let s:exec = 'fzf'
elseif input('fzf executable not found. Download binary? (y/n) ') =~? '^y'
redraw
call fzf#install()
return fzf#exec()
else
redraw
throw 'fzf executable not found'
endif endif
if executable(s:fzf_go)
call add(binaries, s:fzf_go)
endif
if empty(binaries)
if input('fzf executable not found. Download binary? (y/n) ') =~? '^y'
redraw
call fzf#install()
return fzf#exec()
else
redraw
throw 'fzf executable not found'
endif
elseif len(binaries) > 1
call sort(binaries, 's:compare_binary_versions')
endif
let s:exec = binaries[-1]
endif endif
if a:0 && !has_key(s:checked, a:1) if a:0 && !has_key(s:checked, a:1)
let command = s:exec . ' --version' let fzf_version = s:get_version(s:exec)
let output = systemlist(command) if empty(fzf_version)
if v:shell_error || empty(output) let message = printf('Failed to run "%s --version"', s:exec)
throw printf('Failed to run "%s": %s', command, output) unlet s:exec
endif throw message
let fzf_version = matchstr(output[-1], '[0-9.]\+') end
if s:version_requirement(fzf_version, a:1)
if s:compare_versions(fzf_version, a:1) >= 0
let s:checked[a:1] = 1 let s:checked[a:1] = 1
return s:exec return s:exec
elseif a:0 < 2 && input(printf('You need fzf %s or above. Found: %s. Download binary? (y/n) ', a:1, fzf_version)) =~? '^y' elseif a:0 < 2 && input(printf('You need fzf %s or above. Found: %s. Download binary? (y/n) ', a:1, fzf_version)) =~? '^y'
let s:versions = {}
unlet s:exec
redraw redraw
call fzf#install() call fzf#install()
return fzf#exec(a:1, 1) return fzf#exec(a:1, 1)
@@ -852,9 +885,6 @@ function! s:execute_term(dict, command, temps) abort
let term_opts.curwin = 1 let term_opts.curwin = 1
endif endif
let fzf.buf = term_start([&shell, &shellcmdflag, command], term_opts) let fzf.buf = term_start([&shell, &shellcmdflag, command], term_opts)
if exists('&termwinkey')
call setbufvar(fzf.buf, '&termwinkey', '<c-z>')
endif
if is_popup && exists('#TerminalWinOpen') if is_popup && exists('#TerminalWinOpen')
doautocmd <nomodeline> TerminalWinOpen doautocmd <nomodeline> TerminalWinOpen
endif endif
@@ -863,6 +893,9 @@ function! s:execute_term(dict, command, temps) abort
endif endif
endif endif
tnoremap <buffer> <c-z> <nop> tnoremap <buffer> <c-z> <nop>
if exists('&termwinkey') && (empty(&termwinkey) || &termwinkey =~? '<c-w>')
tnoremap <buffer> <c-w> <c-w>.
endif
finally finally
call s:dopopd() call s:dopopd()
endtry endtry

View File

@@ -103,11 +103,11 @@ func matchOperatingSystemCommand(s string) int {
} }
func matchControlSequence(s string) int { func matchControlSequence(s string) int {
// `\x1b[\\[()][0-9;]*[a-zA-Z@]` // `\x1b[\\[()][0-9;?]*[a-zA-Z@]`
// ^ match starting here // ^ match starting here
// //
i := 2 // prefix matched in nextAnsiEscapeSequence() i := 2 // prefix matched in nextAnsiEscapeSequence()
for ; i < len(s) && (isNumeric(s[i]) || s[i] == ';'); i++ { for ; i < len(s) && (isNumeric(s[i]) || s[i] == ';' || s[i] == '?'); i++ {
} }
if i < len(s) { if i < len(s) {
c := s[i] c := s[i]
@@ -125,7 +125,7 @@ func isCtrlSeqStart(c uint8) bool {
// nextAnsiEscapeSequence returns the ANSI escape sequence and is equivalent to // nextAnsiEscapeSequence returns the ANSI escape sequence and is equivalent to
// calling FindStringIndex() on the below regex (which was originally used): // calling FindStringIndex() on the below regex (which was originally used):
// //
// "(?:\x1b[\\[()][0-9;]*[a-zA-Z@]|\x1b][0-9];[[:print:]]+(?:\x1b\\\\|\x07)|\x1b.|[\x0e\x0f]|.\x08)" // "(?:\x1b[\\[()][0-9;?]*[a-zA-Z@]|\x1b][0-9];[[:print:]]+(?:\x1b\\\\|\x07)|\x1b.|[\x0e\x0f]|.\x08)"
// //
func nextAnsiEscapeSequence(s string) (int, int) { func nextAnsiEscapeSequence(s string) (int, int) {
// fast check for ANSI escape sequences // fast check for ANSI escape sequences
@@ -154,7 +154,7 @@ Loop:
return i - n, i + 1 return i - n, i + 1
} }
case '\x1b': case '\x1b':
// match: `\x1b[\\[()][0-9;]*[a-zA-Z@]` // match: `\x1b[\\[()][0-9;?]*[a-zA-Z@]`
if i+2 < len(s) && isCtrlSeqStart(s[i+1]) { if i+2 < len(s) && isCtrlSeqStart(s[i+1]) {
if j := matchControlSequence(s[i:]); j != -1 { if j := matchControlSequence(s[i:]); j != -1 {
return i, i + j return i, i + j

View File

@@ -58,7 +58,7 @@ const usage = `usage: fzf [options]
--layout=LAYOUT Choose layout: [default|reverse|reverse-list] --layout=LAYOUT Choose layout: [default|reverse|reverse-list]
--border[=STYLE] Draw border around the finder --border[=STYLE] Draw border around the finder
[rounded|sharp|horizontal|vertical| [rounded|sharp|horizontal|vertical|
top|bottom|left|right] (default: rounded) top|bottom|left|right|none] (default: rounded)
--margin=MARGIN Screen margin (TRBL | TB,RL | T,RL,B | T,R,B,L) --margin=MARGIN Screen margin (TRBL | TB,RL | T,RL,B | T,R,B,L)
--padding=PADDING Padding inside border (TRBL | TB,RL | T,RL,B | T,R,B,L) --padding=PADDING Padding inside border (TRBL | TB,RL | T,RL,B | T,R,B,L)
--info=STYLE Finder info style [default|inline|hidden] --info=STYLE Finder info style [default|inline|hidden]
@@ -81,11 +81,11 @@ const usage = `usage: fzf [options]
Preview Preview
--preview=COMMAND Command to preview highlighted line ({}) --preview=COMMAND Command to preview highlighted line ({})
--preview-window=OPT Preview window layout (default: right:50%) --preview-window=OPT Preview window layout (default: right:50%)
[up|down|left|right][:SIZE[%]] [up|down|left|right][,SIZE[%]]
[:[no]wrap][:[no]cycle][:[no]follow][:[no]hidden] [,[no]wrap][,[no]cycle][,[no]follow][,[no]hidden]
[:rounded|sharp|noborder] [,border-BORDER_OPT]
[:+SCROLL[OFFSETS][/DENOM]][:~HEADER_LINES] [,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES]
[:default] [,default]
Scripting Scripting
-q, --query=STR Start the finder with the given query -q, --query=STR Start the finder with the given query
@@ -436,11 +436,13 @@ func parseBorder(str string, optional bool) tui.BorderShape {
return tui.BorderLeft return tui.BorderLeft
case "right": case "right":
return tui.BorderRight return tui.BorderRight
case "none":
return tui.BorderNone
default: default:
if optional && str == "" { if optional && str == "" {
return tui.BorderRounded return tui.BorderRounded
} }
errorExit("invalid border style (expected: rounded|sharp|horizontal|vertical|top|bottom|left|right)") errorExit("invalid border style (expected: rounded|sharp|horizontal|vertical|top|bottom|left|right|none)")
} }
return tui.BorderNone return tui.BorderNone
} }
@@ -1076,10 +1078,11 @@ func parseInfoStyle(str string) infoStyle {
} }
func parsePreviewWindow(opts *previewOpts, input string) { func parsePreviewWindow(opts *previewOpts, input string) {
tokens := strings.Split(input, ":") delimRegex := regexp.MustCompile("[:,]") // : for backward compatibility
sizeRegex := regexp.MustCompile("^[0-9]+%?$") sizeRegex := regexp.MustCompile("^[0-9]+%?$")
offsetRegex := regexp.MustCompile(`^(\+{-?[0-9]+})?([+-][0-9]+)*(-?/[1-9][0-9]*)?$`) offsetRegex := regexp.MustCompile(`^(\+{-?[0-9]+})?([+-][0-9]+)*(-?/[1-9][0-9]*)?$`)
headerRegex := regexp.MustCompile("^~(0|[1-9][0-9]*)$") headerRegex := regexp.MustCompile("^~(0|[1-9][0-9]*)$")
tokens := delimRegex.Split(input, -1)
for _, token := range tokens { for _, token := range tokens {
switch token { switch token {
case "": case "":
@@ -1105,12 +1108,24 @@ func parsePreviewWindow(opts *previewOpts, input string) {
opts.position = posLeft opts.position = posLeft
case "right": case "right":
opts.position = posRight opts.position = posRight
case "rounded", "border": case "rounded", "border", "border-rounded":
opts.border = tui.BorderRounded opts.border = tui.BorderRounded
case "sharp": case "sharp", "border-sharp":
opts.border = tui.BorderSharp opts.border = tui.BorderSharp
case "noborder": case "noborder", "border-none":
opts.border = tui.BorderNone opts.border = tui.BorderNone
case "border-horizontal":
opts.border = tui.BorderHorizontal
case "border-vertical":
opts.border = tui.BorderVertical
case "border-top":
opts.border = tui.BorderTop
case "border-bottom":
opts.border = tui.BorderBottom
case "border-left":
opts.border = tui.BorderLeft
case "border-right":
opts.border = tui.BorderRight
case "follow": case "follow":
opts.follow = true opts.follow = true
case "nofollow": case "nofollow":
@@ -1368,7 +1383,7 @@ func parseOptions(opts *Options, allArgs []string) {
opts.Preview.command = "" opts.Preview.command = ""
case "--preview-window": case "--preview-window":
parsePreviewWindow(&opts.Preview, parsePreviewWindow(&opts.Preview,
nextString(allArgs, &i, "preview window layout required: [up|down|left|right][:SIZE[%]][:rounded|sharp|noborder][:wrap][:cycle][:hidden][:+SCROLL[OFFSETS][/DENOM]][:~HEADER_LINES][:default]")) nextString(allArgs, &i, "preview window layout required: [up|down|left|right][,SIZE[%]][,border-BORDER_OPT][,wrap][,cycle][,hidden][,+SCROLL[OFFSETS][/DENOM]][,~HEADER_LINES][,default]"))
case "--height": case "--height":
opts.Height = parseHeight(nextString(allArgs, &i, "height required: HEIGHT[%]")) opts.Height = parseHeight(nextString(allArgs, &i, "height required: HEIGHT[%]"))
case "--min-height": case "--min-height":

View File

@@ -384,7 +384,7 @@ func TestPreviewOpts(t *testing.T) {
opts.Preview.size.size == 50) { opts.Preview.size.size == 50) {
t.Error() t.Error()
} }
opts = optsFor("--preview", "cat {}", "--preview-window=left:15:hidden:wrap:+{1}-/2") opts = optsFor("--preview", "cat {}", "--preview-window=left:15,hidden,wrap:+{1}-/2")
if !(opts.Preview.command == "cat {}" && if !(opts.Preview.command == "cat {}" &&
opts.Preview.hidden == true && opts.Preview.hidden == true &&
opts.Preview.wrap == true && opts.Preview.wrap == true &&
@@ -394,7 +394,7 @@ func TestPreviewOpts(t *testing.T) {
opts.Preview.size.size == 15) { opts.Preview.size.size == 15) {
t.Error(opts.Preview) t.Error(opts.Preview)
} }
opts = optsFor("--preview-window=up:15:wrap:hidden:+{1}+3-1-2/2", "--preview-window=down", "--preview-window=cycle") opts = optsFor("--preview-window=up,15,wrap,hidden,+{1}+3-1-2/2", "--preview-window=down", "--preview-window=cycle")
if !(opts.Preview.command == "" && if !(opts.Preview.command == "" &&
opts.Preview.hidden == true && opts.Preview.hidden == true &&
opts.Preview.wrap == true && opts.Preview.wrap == true &&

View File

@@ -831,16 +831,33 @@ func (t *Terminal) resizeWindows() {
createPreviewWindow := func(y int, x int, w int, h int) { createPreviewWindow := func(y int, x int, w int, h int) {
pwidth := w pwidth := w
pheight := h pheight := h
if t.previewOpts.border != tui.BorderNone { var previewBorder tui.BorderStyle
previewBorder := tui.MakeBorderStyle(t.previewOpts.border, t.unicode) if t.previewOpts.border == tui.BorderNone {
t.pborder = t.tui.NewWindow(y, x, w, h, true, previewBorder) previewBorder = tui.MakeTransparentBorder()
} else {
previewBorder = tui.MakeBorderStyle(t.previewOpts.border, t.unicode)
}
t.pborder = t.tui.NewWindow(y, x, w, h, true, previewBorder)
switch t.previewOpts.border {
case tui.BorderSharp, tui.BorderRounded:
pwidth -= 4 pwidth -= 4
pheight -= 2 pheight -= 2
x += 2 x += 2
y += 1 y += 1
} else { case tui.BorderLeft:
previewBorder := tui.MakeTransparentBorder() pwidth -= 2
t.pborder = t.tui.NewWindow(y, x, w, h, true, previewBorder) x += 2
case tui.BorderRight:
pwidth -= 2
case tui.BorderTop:
pheight -= 1
y += 1
case tui.BorderBottom:
pheight -= 1
case tui.BorderHorizontal:
pheight -= 2
y += 1
case tui.BorderVertical:
pwidth -= 4 pwidth -= 4
x += 2 x += 2
} }
@@ -848,9 +865,13 @@ func (t *Terminal) resizeWindows() {
} }
verticalPad := 2 verticalPad := 2
minPreviewHeight := 3 minPreviewHeight := 3
if t.previewOpts.border == tui.BorderNone { switch t.previewOpts.border {
case tui.BorderNone, tui.BorderVertical, tui.BorderLeft, tui.BorderRight:
verticalPad = 0 verticalPad = 0
minPreviewHeight = 1 minPreviewHeight = 1
case tui.BorderTop, tui.BorderBottom:
verticalPad = 1
minPreviewHeight = 2
} }
switch t.previewOpts.position { switch t.previewOpts.position {
case posUp: case posUp:
@@ -1722,24 +1743,22 @@ func (t *Terminal) executeCommand(template string, forcePlus bool, background bo
} }
command := t.replacePlaceholder(template, forcePlus, string(t.input), list) command := t.replacePlaceholder(template, forcePlus, string(t.input), list)
cmd := util.ExecCommand(command, false) cmd := util.ExecCommand(command, false)
t.executing.Set(true)
if !background { if !background {
cmd.Stdin = os.Stdin cmd.Stdin = tui.TtyIn()
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
t.tui.Pause(true) t.tui.Pause(true)
t.executing.Set(true)
cmd.Run() cmd.Run()
t.executing.Set(false)
t.tui.Resume(true, false) t.tui.Resume(true, false)
t.redraw() t.redraw()
t.refresh() t.refresh()
} else { } else {
t.tui.Pause(false) t.tui.Pause(false)
t.executing.Set(true)
cmd.Run() cmd.Run()
t.executing.Set(false)
t.tui.Resume(false, false) t.tui.Resume(false, false)
} }
t.executing.Set(false)
cleanTemporaryFiles() cleanTemporaryFiles()
} }
@@ -1970,6 +1989,7 @@ func (t *Terminal) Loop() {
}() }()
// Goroutine 2 periodically requests rendering // Goroutine 2 periodically requests rendering
rendered := util.NewAtomicBool(false)
go func(version int64) { go func(version int64) {
lines := []string{} lines := []string{}
spinner := makeSpinner(t.unicode) spinner := makeSpinner(t.unicode)
@@ -1984,6 +2004,7 @@ func (t *Terminal) Loop() {
if spinnerIndex >= 0 { if spinnerIndex >= 0 {
spin := spinner[spinnerIndex%len(spinner)] spin := spinner[spinnerIndex%len(spinner)]
t.reqBox.Set(reqPreviewDisplay, previewResult{version, lines, offset, spin}) t.reqBox.Set(reqPreviewDisplay, previewResult{version, lines, offset, spin})
rendered.Set(true)
offset = -1 offset = -1
} }
spinnerIndex++ spinnerIndex++
@@ -2003,6 +2024,7 @@ func (t *Terminal) Loop() {
} }
if err != nil { if err != nil {
t.reqBox.Set(reqPreviewDisplay, previewResult{version, lines, offset, ""}) t.reqBox.Set(reqPreviewDisplay, previewResult{version, lines, offset, ""})
rendered.Set(true)
break Loop break Loop
} }
} }
@@ -2024,7 +2046,13 @@ func (t *Terminal) Loop() {
util.KillCommand(cmd) util.KillCommand(cmd)
t.eventBox.Set(EvtQuit, code) t.eventBox.Set(EvtQuit, code)
} else { } else {
timer := time.NewTimer(previewCancelWait) // We can immediately kill a long-running preview program
// once we started rendering its partial output
delay := previewCancelWait
if rendered.Get() {
delay = 0
}
timer := time.NewTimer(delay)
select { select {
case <-timer.C: case <-timer.C:
util.KillCommand(cmd) util.KillCommand(cmd)

View File

@@ -12,7 +12,7 @@ import (
"github.com/junegunn/fzf/src/util" "github.com/junegunn/fzf/src/util"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/term"
) )
const ( const (
@@ -74,7 +74,7 @@ type LightRenderer struct {
clickY []int clickY []int
ttyin *os.File ttyin *os.File
buffer []byte buffer []byte
origState *terminal.State origState *term.State
width int width int
height int height int
yoffset int yoffset int
@@ -693,13 +693,17 @@ func (w *LightWindow) drawBorder() {
} }
func (w *LightWindow) drawBorderHorizontal(top, bottom bool) { func (w *LightWindow) drawBorderHorizontal(top, bottom bool) {
color := ColBorder
if w.preview {
color = ColPreviewBorder
}
if top { if top {
w.Move(0, 0) w.Move(0, 0)
w.CPrint(ColBorder, repeat(w.border.horizontal, w.width)) w.CPrint(color, repeat(w.border.horizontal, w.width))
} }
if bottom { if bottom {
w.Move(w.height-1, 0) w.Move(w.height-1, 0)
w.CPrint(ColBorder, repeat(w.border.horizontal, w.width)) w.CPrint(color, repeat(w.border.horizontal, w.width))
} }
} }
@@ -708,14 +712,18 @@ func (w *LightWindow) drawBorderVertical(left, right bool) {
if !left || !right { if !left || !right {
width++ width++
} }
color := ColBorder
if w.preview {
color = ColPreviewBorder
}
for y := 0; y < w.height; y++ { for y := 0; y < w.height; y++ {
w.Move(y, 0) w.Move(y, 0)
if left { if left {
w.CPrint(ColBorder, string(w.border.vertical)) w.CPrint(color, string(w.border.vertical))
} }
w.CPrint(ColBorder, repeat(' ', width)) w.CPrint(color, repeat(' ', width))
if right { if right {
w.CPrint(ColBorder, string(w.border.vertical)) w.CPrint(color, string(w.border.vertical))
} }
} }
} }

View File

@@ -10,7 +10,7 @@ import (
"syscall" "syscall"
"github.com/junegunn/fzf/src/util" "github.com/junegunn/fzf/src/util"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/term"
) )
func IsLightRendererSupported() bool { func IsLightRendererSupported() bool {
@@ -34,12 +34,12 @@ func (r *LightRenderer) fd() int {
func (r *LightRenderer) initPlatform() error { func (r *LightRenderer) initPlatform() error {
fd := r.fd() fd := r.fd()
origState, err := terminal.GetState(fd) origState, err := term.GetState(fd)
if err != nil { if err != nil {
return err return err
} }
r.origState = origState r.origState = origState
terminal.MakeRaw(fd) term.MakeRaw(fd)
return nil return nil
} }
@@ -63,15 +63,15 @@ func openTtyIn() *os.File {
} }
func (r *LightRenderer) setupTerminal() { func (r *LightRenderer) setupTerminal() {
terminal.MakeRaw(r.fd()) term.MakeRaw(r.fd())
} }
func (r *LightRenderer) restoreTerminal() { func (r *LightRenderer) restoreTerminal() {
terminal.Restore(r.fd(), r.origState) term.Restore(r.fd(), r.origState)
} }
func (r *LightRenderer) updateTerminalSize() { func (r *LightRenderer) updateTerminalSize() {
width, height, err := terminal.GetSize(r.fd()) width, height, err := term.GetSize(r.fd())
if err == nil { if err == nil {
r.width = width r.width = width

View File

@@ -5,11 +5,16 @@ package tui
import ( import (
"os" "os"
"syscall" "syscall"
"time"
"github.com/junegunn/fzf/src/util" "github.com/junegunn/fzf/src/util"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
) )
const (
timeoutInterval = 10
)
var ( var (
consoleFlagsInput = uint32(windows.ENABLE_VIRTUAL_TERMINAL_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_EXTENDED_FLAGS) consoleFlagsInput = uint32(windows.ENABLE_VIRTUAL_TERMINAL_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_EXTENDED_FLAGS)
consoleFlagsOutput = uint32(windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING | windows.ENABLE_PROCESSED_OUTPUT | windows.DISABLE_NEWLINE_AUTO_RETURN) consoleFlagsOutput = uint32(windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING | windows.ENABLE_PROCESSED_OUTPUT | windows.DISABLE_NEWLINE_AUTO_RETURN)
@@ -60,7 +65,7 @@ func (r *LightRenderer) initPlatform() error {
// channel for non-blocking reads. Buffer to make sure // channel for non-blocking reads. Buffer to make sure
// we get the ESC sets: // we get the ESC sets:
r.ttyinChannel = make(chan byte, 12) r.ttyinChannel = make(chan byte, 1024)
// the following allows for non-blocking IO. // the following allows for non-blocking IO.
// syscall.SetNonblock() is a NOOP under Windows. // syscall.SetNonblock() is a NOOP under Windows.
@@ -68,9 +73,6 @@ func (r *LightRenderer) initPlatform() error {
fd := int(r.inHandle) fd := int(r.inHandle)
b := make([]byte, 1) b := make([]byte, 1)
for { for {
// HACK: if run from PSReadline, something resets ConsoleMode to remove ENABLE_VIRTUAL_TERMINAL_INPUT.
_ = windows.SetConsoleMode(windows.Handle(r.inHandle), consoleFlagsInput)
_, err := util.Read(fd, b) _, err := util.Read(fd, b)
if err == nil { if err == nil {
r.ttyinChannel <- b[0] r.ttyinChannel <- b[0]
@@ -130,7 +132,7 @@ func (r *LightRenderer) getch(nonblock bool) (int, bool) {
select { select {
case bc := <-r.ttyinChannel: case bc := <-r.ttyinChannel:
return int(bc), true return int(bc), true
default: case <-time.After(timeoutInterval * time.Millisecond):
return 0, false return 0, false
} }
} else { } else {

View File

@@ -4,6 +4,7 @@ package tui
import ( import (
"io/ioutil" "io/ioutil"
"os"
"syscall" "syscall"
) )
@@ -29,3 +30,18 @@ func ttyname() string {
} }
return "" return ""
} }
// TtyIn returns terminal device to be used as STDIN, falls back to os.Stdin
func TtyIn() *os.File {
in, err := os.OpenFile(consoleDevice, syscall.O_RDONLY, 0)
if err != nil {
tty := ttyname()
if len(tty) > 0 {
if in, err := os.OpenFile(tty, syscall.O_RDONLY, 0); err == nil {
return in
}
}
return os.Stdin
}
return in
}

View File

@@ -2,6 +2,13 @@
package tui package tui
import "os"
func ttyname() string { func ttyname() string {
return "" return ""
} }
// TtyIn on Windows returns os.Stdin
func TtyIn() *os.File {
return os.Stdin
}