mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-15 06:43:47 -05:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19759ed36e | ||
|
|
1a7ae8e7b9 | ||
|
|
da1f645670 | ||
|
|
3a2015ee26 | ||
|
|
c440418ce6 | ||
|
|
3d37a5ba1d | ||
|
|
15f4cfb6d9 | ||
|
|
be36de2482 | ||
|
|
391237f7df | ||
|
|
977e5effd9 | ||
|
|
8b36a4cb19 | ||
|
|
c8cd94a772 | ||
|
|
764316a53d | ||
|
|
2048fd4042 | ||
|
|
f84b3de24b | ||
|
|
6a1f3ec08b | ||
|
|
2e353aee96 | ||
|
|
8edfd14a37 | ||
|
|
1a191ec6f7 | ||
|
|
e7171e94b4 | ||
|
|
398d937419 |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
custom: ["https://paypal.me/junegunn", "https://www.buymeacoffee.com/junegunn"]
|
||||||
2
.github/workflows/linux.yml
vendored
2
.github/workflows/linux.yml
vendored
@@ -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:
|
||||||
|
|||||||
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
@@ -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:
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -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
|
||||||
|
|||||||
@@ -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
16
go.mod
@@ -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
44
go.sum
@@ -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=
|
||||||
|
|||||||
6
install
6
install
@@ -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 ;;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -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() {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
10
src/ansi.go
10
src/ansi.go
@@ -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
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
@@ -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 &&
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user