diff --git a/.gitignore b/.gitignore index b76a3f1..8bde085 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ bin/fzf bin/fzf.exe +dist target pkg Gemfile.lock @@ -9,3 +10,5 @@ vendor gopath *.zwc fzf +tmp +*.patch diff --git a/.gon.hcl b/.gon.hcl new file mode 100644 index 0000000..459ca4d --- /dev/null +++ b/.gon.hcl @@ -0,0 +1,11 @@ +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 = "Apple Development: junegunn.c@gmail.com" +} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..57e3b28 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,69 @@ +--- +project_name: fzf + +before: + hooks: + - go mod download + +builds: + - id: fzf-macos + binary: fzf + goos: + - darwin + goarch: + - amd64 + ldflags: + - "-s -w -X main.version={{ .Version }} -X main.revision={{ .ShortCommit }}" + hooks: + post: gon .gon.hcl + + - goos: + - linux + - windows + - freebsd + - openbsd + goarch: + - amd64 + - arm + - arm64 + goarm: + - 5 + - 6 + - 7 + ldflags: + - "-s -w -X main.version={{ .Version }} -X main.revision={{ .ShortCommit }}" + ignore: + - goos: freebsd + goarch: arm + - goos: openbsd + goarch: arm + - goos: freebsd + goarch: arm64 + - goos: openbsd + goarch: arm64 + +archives: + - name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" + format: tar.gz + format_overrides: + - goos: windows + format: zip + files: + - non-existent* + +release: + github: + owner: junegunn + name: fzf + prerelease: auto + name_template: '{{ .Tag }}' + +snapshot: + name_template: "{{ .Tag }}-devel" + +changelog: + sort: asc + filters: + exclude: + - README + - test diff --git a/CHANGELOG.md b/CHANGELOG.md index ecbade6..626105c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,10 +23,12 @@ CHANGELOG # * Italic style may not be supported by some terminals rg --line-number --no-heading --color=always "" | fzf --ansi --prompt "Rg: " \ - --color fg+:italic,hl:underline:-1,hl+:underline:reverse:-1 \ + --color fg+:italic,hl:underline:-1,hl+:italic:underline:reverse:-1 \ --color pointer:reverse,prompt:reverse,input:159 \ --pointer ' ' ``` +- More `--border` options + - `vertical`, `top`, `bottom`, `left`, `right` - To indicate if `--multi` mode is enabled, fzf will print the number of selected items even when no item is selected ```sh diff --git a/Makefile b/Makefile index 54fce67..5b0a278 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,9 @@ MAKEFILE := $(realpath $(lastword $(MAKEFILE_LIST))) ROOT_DIR := $(shell dirname $(MAKEFILE)) SOURCES := $(wildcard *.go src/*.go src/*/*.go) $(MAKEFILE) +VERSION := $(shell git describe --abbrev=0) REVISION := $(shell git log -n 1 --pretty=format:%h -- $(SOURCES)) -BUILD_FLAGS := -a -ldflags "-X main.revision=$(REVISION) -w '-extldflags=$(LDFLAGS)'" -tags "$(TAGS)" +BUILD_FLAGS := -a -ldflags "-X main.version=$(VERSION) -X main.revision=$(REVISION) -w '-extldflags=$(LDFLAGS)'" -tags "$(TAGS)" BINARY64 := fzf-$(GOOS)_amd64 BINARYARM5 := fzf-$(GOOS)_arm5 @@ -15,12 +16,6 @@ BINARYARM7 := fzf-$(GOOS)_arm7 BINARYARM8 := fzf-$(GOOS)_arm8 BINARYPPC64LE := fzf-$(GOOS)_ppc64le VERSION := $(shell awk -F= '/version =/ {print $$2}' src/constants.go | tr -d "\" ") -RELEASE64 := fzf-$(VERSION)-$(GOOS)_amd64 -RELEASEARM5 := fzf-$(VERSION)-$(GOOS)_arm5 -RELEASEARM6 := fzf-$(VERSION)-$(GOOS)_arm6 -RELEASEARM7 := fzf-$(VERSION)-$(GOOS)_arm7 -RELEASEARM8 := fzf-$(VERSION)-$(GOOS)_arm8 -RELEASEPPC64LE := fzf-$(VERSION)-$(GOOS)_ppc64le # https://en.wikipedia.org/wiki/Uname UNAME_M := $(shell uname -m) @@ -46,35 +41,6 @@ endif all: target/$(BINARY) -target: - mkdir -p $@ - -ifeq ($(GOOS),windows) -release: target/$(BINARY64) - cd target && cp -f $(BINARY64) fzf.exe && zip $(RELEASE64).zip fzf.exe - cd target && rm -f fzf.exe -else ifeq ($(GOOS),linux) -release: target/$(BINARY64) target/$(BINARYARM5) target/$(BINARYARM6) target/$(BINARYARM7) target/$(BINARYARM8) target/$(BINARYPPC64LE) - cd target && cp -f $(BINARY64) fzf && tar -czf $(RELEASE64).tgz fzf - cd target && cp -f $(BINARYARM5) fzf && tar -czf $(RELEASEARM5).tgz fzf - cd target && cp -f $(BINARYARM6) fzf && tar -czf $(RELEASEARM6).tgz fzf - cd target && cp -f $(BINARYARM7) fzf && tar -czf $(RELEASEARM7).tgz fzf - cd target && cp -f $(BINARYARM8) fzf && tar -czf $(RELEASEARM8).tgz fzf - cd target && cp -f $(BINARYPPC64LE) fzf && tar -czf $(RELEASEPPC64LE).tgz fzf - cd target && rm -f fzf -else -release: target/$(BINARY64) - cd target && cp -f $(BINARY64) fzf && tar -czf $(RELEASE64).tgz fzf - cd target && rm -f fzf -endif - -release-all: clean test - GOOS=darwin make release - GOOS=linux make release - GOOS=freebsd make release - GOOS=openbsd make release - GOOS=windows make release - test: $(SOURCES) SHELL=/bin/sh GOOS= $(GO) test -v -tags "$(TAGS)" \ github.com/junegunn/fzf/src \ @@ -84,8 +50,11 @@ test: $(SOURCES) install: bin/fzf +release: + goreleaser --rm-dist --snapshot + clean: - $(RM) -r target + $(RM) -r dist target target/$(BINARY64): $(SOURCES) GOARCH=amd64 $(GO) build $(BUILD_FLAGS) -o $@ @@ -121,4 +90,4 @@ update: $(GO) get -u $(GO) mod tidy -.PHONY: all release release-all test install clean docker docker-test update +.PHONY: all release test install clean docker docker-test update diff --git a/README-VIM.md b/README-VIM.md index 568f723..e632526 100644 --- a/README-VIM.md +++ b/README-VIM.md @@ -300,7 +300,7 @@ following options are allowed: - `xoffset` [float default 0.5 range [0 ~ 1]] - `highlight` [string default `'Comment'`]: Highlight group for border - `border` [string default `rounded`]: Border style - - `rounded` / `sharp` / `horizontal` / `vertical` / `top` / `bottom` / `left` / `right` + - `rounded` / `sharp` / `horizontal` / `vertical` / `top` / `bottom` / `left` / `right` / `none` `fzf#wrap` ---------- diff --git a/README.md b/README.md index de186a3..8bfa884 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ fzf project consists of the following components: You can [download fzf executable][bin] alone if you don't need the extra stuff. -[bin]: https://github.com/junegunn/fzf-bin/releases +[bin]: https://github.com/junegunn/fzf/releases ### Using Homebrew or Linuxbrew diff --git a/go.mod b/go.mod index 7c6a522..03e7782 100644 --- a/go.mod +++ b/go.mod @@ -2,14 +2,14 @@ module github.com/junegunn/fzf require ( github.com/gdamore/tcell v1.4.0 - github.com/lucasb-eyer/go-colorful v1.0.3 // indirect github.com/mattn/go-isatty v0.0.12 github.com/mattn/go-runewidth v0.0.9 - github.com/mattn/go-shellwords v1.0.9 - github.com/saracen/walker v0.0.0-20191201085201-324a081bae7e - golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d - golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 - golang.org/x/text v0.3.2 // indirect + github.com/mattn/go-shellwords v1.0.10 + github.com/saracen/walker v0.1.1 + golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 + golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect + golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 + golang.org/x/text v0.3.3 // indirect ) go 1.13 diff --git a/go.sum b/go.sum index 01e1e58..4fcf318 100644 --- a/go.sum +++ b/go.sum @@ -1,47 +1,35 @@ -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= 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/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0= -github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= -github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= 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/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0= -github.com/mattn/go-runewidth v0.0.8/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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-shellwords v1.0.9 h1:eaB5JspOwiKKcHdqcjbfe5lA9cNn/4NRRtddXJCimqk= -github.com/mattn/go-shellwords v1.0.9/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/saracen/walker v0.0.0-20191201085201-324a081bae7e h1:NO86zOn5ScSKW8wRbMaSIcjDZUFpWdCQQnexRqZ9h9A= -github.com/saracen/walker v0.0.0-20191201085201-324a081bae7e/go.mod h1:G0Z6yVPru183i2MuRJx1DcR4dgIZtLcTdaaE/pC1BJU= +github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw= +github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/saracen/walker v0.1.1 h1:Ou2QIKTWqo0QxhtuHVmtObbmhjMCEUyJ82xp0uV+MGI= +github.com/saracen/walker v0.1.1/go.mod h1:0oKYMsKVhSJ+ful4p/XbjvXbMgLEkLITZaxozsl4CGE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U= -golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-20201020160332-67f06af15bc9/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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 h1:/DtoiOYKoQCcIFXQjz07RnWNPRCbqmSXSpgEzhC9ZHM= +golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191011211836-4c025a95b26e h1:1o2bDs9pCd2xFhdwqJTrCIswAeEsn4h/PCNelWpfcsI= -golang.org/x/tools v0.0.0-20191011211836-4c025a95b26e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/install b/install index 75ca5e9..e704909 100755 --- a/install +++ b/install @@ -2,11 +2,10 @@ set -u -version=0.23.1 +version=0.24.0-rc1 auto_completion= key_bindings= update_config=2 -binary_arch= shells="bash zsh fish" prefix='~/.fzf' prefix_expand=~/.fzf @@ -115,7 +114,7 @@ link_fzf_in_path() { try_curl() { command -v curl > /dev/null && - if [[ $1 =~ tgz$ ]]; then + if [[ $1 =~ tar.gz$ ]]; then curl -fL $1 | tar -xzf - else local temp=${TMPDIR:-/tmp}/fzf.zip @@ -125,7 +124,7 @@ try_curl() { try_wget() { command -v wget > /dev/null && - if [[ $1 =~ tgz$ ]]; then + if [[ $1 =~ tar.gz$ ]]; then wget -O - $1 | tar -xzf - else local temp=${TMPDIR:-/tmp}/fzf.zip @@ -135,13 +134,11 @@ try_wget() { download() { echo "Downloading bin/fzf ..." - if [[ ! "$version" =~ alpha ]]; then - if [ -x "$fzf_base"/bin/fzf ]; then - echo " - Already exists" - check_binary && return - fi - link_fzf_in_path && return + if [ -x "$fzf_base"/bin/fzf ]; then + echo " - Already exists" + check_binary && return fi + link_fzf_in_path && return mkdir -p "$fzf_base"/bin && cd "$fzf_base"/bin if [ $? -ne 0 ]; then binary_error="Failed to create bin directory" @@ -149,9 +146,7 @@ download() { fi local url - [[ "$version" =~ alpha ]] && - url=https://github.com/junegunn/fzf-bin/releases/download/alpha/${1} || - url=https://github.com/junegunn/fzf-bin/releases/download/$version/${1} + url=https://github.com/junegunn/fzf/releases/download/$version/${1} set -o pipefail if ! (try_curl $url || try_wget $url); then set +o pipefail @@ -173,20 +168,20 @@ archi=$(uname -sm) binary_available=1 binary_error="" case "$archi" in - Darwin\ *64) download fzf-$version-darwin_${binary_arch:-amd64}.tgz ;; - Linux\ armv5*) download fzf-$version-linux_${binary_arch:-arm5}.tgz ;; - Linux\ armv6*) download fzf-$version-linux_${binary_arch:-arm6}.tgz ;; - Linux\ armv7*) download fzf-$version-linux_${binary_arch:-arm7}.tgz ;; - Linux\ armv8*) download fzf-$version-linux_${binary_arch:-arm8}.tgz ;; - Linux\ aarch64*) download fzf-$version-linux_${binary_arch:-arm8}.tgz ;; - Linux\ *64) download fzf-$version-linux_${binary_arch:-amd64}.tgz ;; - FreeBSD\ *64) download fzf-$version-freebsd_${binary_arch:-amd64}.tgz ;; - OpenBSD\ *64) download fzf-$version-openbsd_${binary_arch:-amd64}.tgz ;; - CYGWIN*\ *64) download fzf-$version-windows_${binary_arch:-amd64}.zip ;; - MINGW*\ *64) download fzf-$version-windows_${binary_arch:-amd64}.zip ;; - MSYS*\ *64) download fzf-$version-windows_${binary_arch:-amd64}.zip ;; - Windows*\ *64) download fzf-$version-windows_${binary_arch:-amd64}.zip ;; - *) binary_available=0 binary_error=1 ;; + Darwin\ *64) download fzf-$version-darwin_amd64.tar.gz ;; + Linux\ armv5*) download fzf-$version-linux_armv5.tar.gz ;; + Linux\ armv6*) download fzf-$version-linux_armv6.tar.gz ;; + Linux\ armv7*) download fzf-$version-linux_armv7.tar.gz ;; + Linux\ armv8*) download fzf-$version-linux_arm64.tar.gz ;; + Linux\ aarch64*) download fzf-$version-linux_arm64.tar.gz ;; + Linux\ *64) download fzf-$version-linux_amd64.tar.gz ;; + FreeBSD\ *64) download fzf-$version-freebsd_amd64.tar.gz ;; + OpenBSD\ *64) download fzf-$version-openbsd_amd64.tar.gz ;; + CYGWIN*\ *64) download fzf-$version-windows_amd64.zip ;; + MINGW*\ *64) download fzf-$version-windows_amd64.zip ;; + MSYS*\ *64) download fzf-$version-windows_amd64.zip ;; + Windows*\ *64) download fzf-$version-windows_amd64.zip ;; + *) binary_available=0 binary_error=1 ;; esac cd "$fzf_base" diff --git a/install.ps1 b/install.ps1 index f29ed6b..855a6f3 100644 --- a/install.ps1 +++ b/install.ps1 @@ -1,10 +1,4 @@ -$version="0.23.1" - -if ([Environment]::Is64BitProcess) { - $binary_arch="amd64" -} else { - $binary_arch="386" -} +$version="0.24.0-rc1" $fzf_base=Split-Path -Parent $MyInvocation.MyCommand.Definition @@ -32,12 +26,10 @@ function check_binary () { function download { param($file) Write-Host "Downloading bin/fzf ..." - if ("$version" -ne "alpha") { - if (Test-Path "$fzf_base\bin\fzf.exe") { - Write-Host " - Already exists" - if (check_binary) { - return - } + if (Test-Path "$fzf_base\bin\fzf.exe") { + Write-Host " - Already exists" + if (check_binary) { + return } } if (-not (Test-Path "$fzf_base\bin")) { @@ -48,11 +40,7 @@ function download { return } cd "$fzf_base\bin" - if ("$version" -eq "alpha") { - $url="https://github.com/junegunn/fzf-bin/releases/download/alpha/$file" - } else { - $url="https://github.com/junegunn/fzf-bin/releases/download/$version/$file" - } + $url="https://github.com/junegunn/fzf/releases/download/$version/$file" $temp=$env:TMP + "\fzf.zip" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 (New-Object Net.WebClient).DownloadFile($url, $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("$temp")) @@ -68,6 +56,6 @@ function download { check_binary >$null } -download "fzf-$version-windows_$binary_arch.zip" +download "fzf-$version-windows_amd64.zip" Write-Host 'For more information, see: https://github.com/junegunn/fzf' diff --git a/main.go b/main.go index f444f8b..d73ab88 100644 --- a/main.go +++ b/main.go @@ -5,9 +5,10 @@ import ( "github.com/junegunn/fzf/src/protector" ) +var version string var revision string func main() { protector.Protect() - fzf.Run(fzf.ParseOptions(), revision) + fzf.Run(fzf.ParseOptions(), version, revision) } diff --git a/man/man1/fzf-tmux.1 b/man/man1/fzf-tmux.1 index 1775d2e..9cf5594 100644 --- a/man/man1/fzf-tmux.1 +++ b/man/man1/fzf-tmux.1 @@ -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 THE SOFTWARE. .. -.TH fzf-tmux 1 "Oct 2020" "fzf 0.23.1" "fzf-tmux - open fzf in tmux split pane" +.TH fzf-tmux 1 "Oct 2020" "fzf 0.24.0" "fzf-tmux - open fzf in tmux split pane" .SH NAME fzf-tmux - open fzf in tmux split pane diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index da2642e..ce8c631 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -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 THE SOFTWARE. .. -.TH fzf 1 "Oct 2020" "fzf 0.23.1" "fzf - a command-line fuzzy finder" +.TH fzf 1 "Oct 2020" "fzf 0.24.0" "fzf - a command-line fuzzy finder" .SH NAME fzf - a command-line fuzzy finder @@ -192,6 +192,16 @@ Draw border around the finder .br .BR horizontal " Horizontal lines above and below the finder" .br +.BR vertical " Vertical lines on each side of the finder" +.br +.BR top +.br +.BR bottom +.br +.BR left +.br +.BR right +.br .TP .B "--no-unicode" diff --git a/plugin/fzf.vim b/plugin/fzf.vim index 7dc677f..50fcbc0 100644 --- a/plugin/fzf.vim +++ b/plugin/fzf.vim @@ -154,7 +154,20 @@ function! fzf#install() endif endfunction -function! fzf#exec() +function! s:version_requirement(val, min) + let val = split(a:val, '\.') + let min = split(a:min, '\.') + for idx in range(0, len(min) - 1) + let v = get(val, idx, 0) + if v < min[idx] | return 0 + elseif v > min[idx] | return 1 + endif + endfor + return 1 +endfunction + +let s:checked = {} +function! fzf#exec(...) if !exists('s:exec') if executable(s:fzf_go) let s:exec = s:fzf_go @@ -169,6 +182,26 @@ function! fzf#exec() throw 'fzf executable not found' endif endif + + if a:0 && !has_key(s:checked, a:1) + let command = s:exec . ' --version' + let output = systemlist(command) + if v:shell_error || empty(output) + throw printf('Failed to run "%s": %s', command, output) + endif + let fzf_version = matchstr(output[0], '[0-9.]\+') + if s:version_requirement(fzf_version, a:1) + let s:checked[a:1] = 1 + 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' + redraw + call fzf#install() + return fzf#exec(a:1, 1) + else + throw printf('You need to upgrade fzf (required: %s or above)', a:1) + endif + endif + return s:exec endfunction @@ -432,6 +465,7 @@ try elseif use_term let optstr .= ' --no-height' endif + let optstr .= s:border_opt(get(dict, 'window', 0)) let command = prefix.(use_tmux ? s:fzf_tmux(dict) : fzf_exec).' '.optstr.' > '.temps.result if use_term @@ -656,6 +690,32 @@ function! s:getpos() return {'tab': tabpagenr(), 'win': winnr(), 'winid': win_getid(), 'cnt': winnr('$'), 'tcnt': tabpagenr('$')} endfunction +function! s:border_opt(window) + if type(a:window) != type({}) + return '' + endif + + " Border style + let style = tolower(get(a:window, 'border', 'rounded')) + if !has_key(a:window, 'border') && !get(a:window, 'rounded', 1) + let style = 'sharp' + endif + if style == 'none' + return '' + endif + + " For --border styles, we need fzf 0.24.0 or above + call fzf#exec('0.24.0') + let opt = ' --border=' . style + if has_key(a:window, 'highlight') + let color = s:get_color('fg', a:window.highlight) + if len(color) + let opt .= ' --color=border:' . color + endif + endif + return opt +endfunction + function! s:split(dict) let directions = { \ 'up': ['topleft', 'resize', &lines], @@ -869,12 +929,8 @@ else endif function! s:popup(opts) abort - " Support ambiwidth == 'double' - let ambidouble = &ambiwidth == 'double' ? 2 : 1 - " Size and position let width = min([max([8, a:opts.width > 1 ? a:opts.width : float2nr(&columns * a:opts.width)]), &columns]) - let width += width % ambidouble let height = min([max([4, a:opts.height > 1 ? a:opts.height : float2nr(&lines * a:opts.height)]), &lines - has('nvim')]) let row = float2nr(get(a:opts, 'yoffset', 0.5) * (&lines - height)) let col = float2nr(get(a:opts, 'xoffset', 0.5) * (&columns - width)) @@ -885,45 +941,9 @@ function! s:popup(opts) abort let row += !has('nvim') let col += !has('nvim') - " Border style - let style = tolower(get(a:opts, 'border', 'rounded')) - if !has_key(a:opts, 'border') && !get(a:opts, 'rounded', 1) - let style = 'sharp' - endif - - if style =~ 'vertical\|left\|right' - let mid = style == 'vertical' ? '│' .. repeat(' ', width - 2 * ambidouble) .. '│' : - \ style == 'left' ? '│' .. repeat(' ', width - 1 * ambidouble) - \ : repeat(' ', width - 1 * ambidouble) .. '│' - let border = repeat([mid], height) - let shift = { 'row': 0, 'col': style == 'right' ? 0 : 2, 'width': style == 'vertical' ? -4 : -2, 'height': 0 } - elseif style =~ 'horizontal\|top\|bottom' - let hor = repeat('─', width / ambidouble) - let mid = repeat(' ', width) - let border = style == 'horizontal' ? [hor] + repeat([mid], height - 2) + [hor] : - \ style == 'top' ? [hor] + repeat([mid], height - 1) - \ : repeat([mid], height - 1) + [hor] - let shift = { 'row': style == 'bottom' ? 0 : 1, 'col': 0, 'width': 0, 'height': style == 'horizontal' ? -2 : -1 } - else - let edges = style == 'sharp' ? ['┌', '┐', '└', '┘'] : ['╭', '╮', '╰', '╯'] - let bar = repeat('─', width / ambidouble - 2) - let top = edges[0] .. bar .. edges[1] - let mid = '│' .. repeat(' ', width - 2 * ambidouble) .. '│' - let bot = edges[2] .. bar .. edges[3] - let border = [top] + repeat([mid], height - 2) + [bot] - let shift = { 'row': 1, 'col': 2, 'width': -4, 'height': -2 } - endif - - let highlight = get(a:opts, 'highlight', 'Comment') - let frame = s:create_popup(highlight, { - \ 'row': row, 'col': col, 'width': width, 'height': height, 'border': border - \ }) call s:create_popup('Normal', { - \ 'row': row + shift.row, 'col': col + shift.col, 'width': width + shift.width, 'height': height + shift.height + \ 'row': row, 'col': col, 'width': width, 'height': height \ }) - if has('nvim') - execute 'autocmd BufWipeout bwipeout '..frame - endif endfunction let s:default_action = { diff --git a/src/constants.go b/src/constants.go index 9a5b8fa..9842e0b 100644 --- a/src/constants.go +++ b/src/constants.go @@ -9,9 +9,6 @@ import ( ) const ( - // Current version - version = "0.23.1" - // Core coordinatorDelayMax time.Duration = 100 * time.Millisecond coordinatorDelayStep time.Duration = 10 * time.Millisecond diff --git a/src/core.go b/src/core.go index bd45df6..ef470a8 100644 --- a/src/core.go +++ b/src/core.go @@ -43,7 +43,7 @@ Matcher -> EvtHeader -> Terminal (update header) */ // Run starts fzf -func Run(opts *Options, revision string) { +func Run(opts *Options, version string, revision string) { sort := opts.Sort > 0 sortCriteria = opts.Criteria diff --git a/src/options.go b/src/options.go index ce000a0..ab5ae27 100644 --- a/src/options.go +++ b/src/options.go @@ -58,7 +58,8 @@ const usage = `usage: fzf [options] (default: 10) --layout=LAYOUT Choose layout: [default|reverse|reverse-list] --border[=STYLE] Draw border around the finder - [rounded|sharp|horizontal] (default: rounded) + [rounded|sharp|horizontal|vertical| + top|bottom|left|right] (default: rounded) --margin=MARGIN Screen margin (TRBL / TB,RL / T,RL,B / T,R,B,L) --info=STYLE Finder info style [default|inline|hidden] --prompt=STR Input prompt (default: '> ') @@ -421,11 +422,21 @@ func parseBorder(str string, optional bool) tui.BorderShape { return tui.BorderSharp case "horizontal": return tui.BorderHorizontal + case "vertical": + return tui.BorderVertical + case "top": + return tui.BorderTop + case "bottom": + return tui.BorderBottom + case "left": + return tui.BorderLeft + case "right": + return tui.BorderRight default: if optional && str == "" { return tui.BorderRounded } - errorExit("invalid border style (expected: rounded|sharp|horizontal)") + errorExit("invalid border style (expected: rounded|sharp|horizontal|vertical|top|bottom|left|right)") } return tui.BorderNone } diff --git a/src/terminal.go b/src/terminal.go index d896d1d..778665a 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -670,7 +670,7 @@ func calculateSize(base int, size sizeSpec, occupied int, minSize int, pad int) func (t *Terminal) resizeWindows() { screenWidth := t.tui.MaxX() screenHeight := t.tui.MaxY() - marginInt := [4]int{} + marginInt := [4]int{} // TRBL t.prevLines = make([]itemLine, screenHeight) for idx, sizeSpec := range t.margin { if sizeSpec.percent { @@ -687,6 +687,24 @@ func (t *Terminal) resizeWindows() { switch t.borderShape { case tui.BorderHorizontal: marginInt[idx] += 1 - idx%2 + case tui.BorderVertical: + marginInt[idx] += 2 * (idx % 2) + case tui.BorderTop: + if idx == 0 { + marginInt[idx]++ + } + case tui.BorderRight: + if idx == 1 { + marginInt[idx] += 2 + } + case tui.BorderBottom: + if idx == 2 { + marginInt[idx]++ + } + case tui.BorderLeft: + if idx == 3 { + marginInt[idx] += 2 + } case tui.BorderRounded, tui.BorderSharp: marginInt[idx] += 1 + idx%2 } @@ -735,17 +753,31 @@ func (t *Terminal) resizeWindows() { switch t.borderShape { case tui.BorderHorizontal: t.border = t.tui.NewWindow( - marginInt[0]-1, - marginInt[3], - width, - height+2, + marginInt[0]-1, marginInt[3], width, height+2, false, tui.MakeBorderStyle(tui.BorderHorizontal, t.unicode)) + case tui.BorderVertical: + t.border = t.tui.NewWindow( + marginInt[0], marginInt[3]-2, width+4, height, + false, tui.MakeBorderStyle(tui.BorderVertical, t.unicode)) + case tui.BorderTop: + t.border = t.tui.NewWindow( + marginInt[0]-1, marginInt[3], width, height+1, + false, tui.MakeBorderStyle(tui.BorderTop, t.unicode)) + case tui.BorderBottom: + t.border = t.tui.NewWindow( + marginInt[0], marginInt[3], width, height+1, + false, tui.MakeBorderStyle(tui.BorderBottom, t.unicode)) + case tui.BorderLeft: + t.border = t.tui.NewWindow( + marginInt[0], marginInt[3]-2, width+2, height, + false, tui.MakeBorderStyle(tui.BorderLeft, t.unicode)) + case tui.BorderRight: + t.border = t.tui.NewWindow( + marginInt[0], marginInt[3], width+2, height, + false, tui.MakeBorderStyle(tui.BorderRight, t.unicode)) case tui.BorderRounded, tui.BorderSharp: t.border = t.tui.NewWindow( - marginInt[0]-1, - marginInt[3]-2, - width+4, - height+2, + marginInt[0]-1, marginInt[3]-2, width+4, height+2, false, tui.MakeBorderStyle(t.borderShape, t.unicode)) } noBorder := tui.MakeBorderStyle(tui.BorderNone, t.unicode) @@ -1823,13 +1855,9 @@ func (t *Terminal) Loop() { reader := bufio.NewReader(out) eofChan := make(chan bool) finishChan := make(chan bool, 1) - reapChan := make(chan bool) err := cmd.Start() - reaps := 0 - if err != nil { - t.reqBox.Set(reqPreviewDisplay, previewResult{version, []string{err.Error()}, 0, ""}) - } else { - reaps = 2 + if err == nil { + reapChan := make(chan bool) lineChan := make(chan eachLine) // Goroutine 1 reads process output go func() { @@ -1842,6 +1870,7 @@ func (t *Terminal) Loop() { } eofChan <- true }() + // Goroutine 2 periodically requests rendering go func(version int64) { lines := []string{} @@ -1883,42 +1912,47 @@ func (t *Terminal) Loop() { ticker.Stop() reapChan <- true }(version) - } - // Goroutine 3 is responsible for cancelling running preview command - go func(version int64) { - timer := time.NewTimer(previewDelayed) - Loop: - for { - select { - case <-timer.C: - t.reqBox.Set(reqPreviewDelayed, version) - case code := <-t.killChan: - if code != exitCancel { - util.KillCommand(cmd) - os.Exit(code) - } else { - timer := time.NewTimer(previewCancelWait) - select { - case <-timer.C: + + // Goroutine 3 is responsible for cancelling running preview command + go func(version int64) { + timer := time.NewTimer(previewDelayed) + Loop: + for { + select { + case <-timer.C: + t.reqBox.Set(reqPreviewDelayed, version) + case code := <-t.killChan: + if code != exitCancel { util.KillCommand(cmd) - case <-finishChan: + os.Exit(code) + } else { + timer := time.NewTimer(previewCancelWait) + select { + case <-timer.C: + util.KillCommand(cmd) + case <-finishChan: + } + timer.Stop() } - timer.Stop() + break Loop + case <-finishChan: + break Loop } - break Loop - case <-finishChan: - break Loop } - } - timer.Stop() - reapChan <- true - }(version) - <-eofChan - cmd.Wait() // NOTE: We should not call Wait before EOF - finishChan <- true - for i := 0; i < reaps; i++ { + timer.Stop() + reapChan <- true + }(version) + + <-eofChan // Goroutine 1 finished + cmd.Wait() // NOTE: We should not call Wait before EOF + finishChan <- true // Tell Goroutine 3 to stop + <-reapChan // Goroutine 2 and 3 finished <-reapChan + } else { + // Failed to start the command. Report the error immediately. + t.reqBox.Set(reqPreviewDisplay, previewResult{version, []string{err.Error()}, 0, ""}) } + cleanTemporaryFiles() } else { t.reqBox.Set(reqPreviewDisplay, previewResult{version, nil, 0, ""}) diff --git a/src/tui/light.go b/src/tui/light.go index 6bd0821..ad536f6 100644 --- a/src/tui/light.go +++ b/src/tui/light.go @@ -653,15 +653,46 @@ func (w *LightWindow) drawBorder() { case BorderRounded, BorderSharp: w.drawBorderAround() case BorderHorizontal: - w.drawBorderHorizontal() + w.drawBorderHorizontal(true, true) + case BorderVertical: + w.drawBorderVertical(true, true) + case BorderTop: + w.drawBorderHorizontal(true, false) + case BorderBottom: + w.drawBorderHorizontal(false, true) + case BorderLeft: + w.drawBorderVertical(true, false) + case BorderRight: + w.drawBorderVertical(false, true) } } -func (w *LightWindow) drawBorderHorizontal() { - w.Move(0, 0) - w.CPrint(ColBorder, repeat(w.border.horizontal, w.width)) - w.Move(w.height-1, 0) - w.CPrint(ColBorder, repeat(w.border.horizontal, w.width)) +func (w *LightWindow) drawBorderHorizontal(top, bottom bool) { + if top { + w.Move(0, 0) + w.CPrint(ColBorder, repeat(w.border.horizontal, w.width)) + } + if bottom { + w.Move(w.height-1, 0) + w.CPrint(ColBorder, repeat(w.border.horizontal, w.width)) + } +} + +func (w *LightWindow) drawBorderVertical(left, right bool) { + width := w.width - 2 + if !left || !right { + width++ + } + for y := 0; y < w.height; y++ { + w.Move(y, 0) + if left { + w.CPrint(ColBorder, string(w.border.vertical)) + } + w.CPrint(ColBorder, repeat(' ', width)) + if right { + w.CPrint(ColBorder, string(w.border.vertical)) + } + } } func (w *LightWindow) drawBorderAround() { diff --git a/src/tui/tcell.go b/src/tui/tcell.go index 0ad1488..4f80d06 100644 --- a/src/tui/tcell.go +++ b/src/tui/tcell.go @@ -583,7 +583,8 @@ func (w *TcellWindow) CFill(fg Color, bg Color, a Attr, str string) FillReturn { } func (w *TcellWindow) drawBorder() { - if w.borderStyle.shape == BorderNone { + shape := w.borderStyle.shape + if shape == BorderNone { return } @@ -603,17 +604,32 @@ func (w *TcellWindow) drawBorder() { style = w.normal.style() } - for x := left; x < right; x++ { - _screen.SetContent(x, top, w.borderStyle.horizontal, nil, style) - _screen.SetContent(x, bot-1, w.borderStyle.horizontal, nil, style) + switch shape { + case BorderRounded, BorderSharp, BorderHorizontal, BorderTop: + for x := left; x < right; x++ { + _screen.SetContent(x, top, w.borderStyle.horizontal, nil, style) + } } - - if w.borderStyle.shape != BorderHorizontal { + switch shape { + case BorderRounded, BorderSharp, BorderHorizontal, BorderBottom: + for x := left; x < right; x++ { + _screen.SetContent(x, bot-1, w.borderStyle.horizontal, nil, style) + } + } + switch shape { + case BorderRounded, BorderSharp, BorderVertical, BorderLeft: for y := top; y < bot; y++ { _screen.SetContent(left, y, w.borderStyle.vertical, nil, style) + } + } + switch shape { + case BorderRounded, BorderSharp, BorderVertical, BorderRight: + for y := top; y < bot; y++ { _screen.SetContent(right-1, y, w.borderStyle.vertical, nil, style) } - + } + switch shape { + case BorderRounded, BorderSharp: _screen.SetContent(left, top, w.borderStyle.topLeft, nil, style) _screen.SetContent(right-1, top, w.borderStyle.topRight, nil, style) _screen.SetContent(left, bot-1, w.borderStyle.bottomLeft, nil, style) diff --git a/src/tui/tui.go b/src/tui/tui.go index 40c7511..3cade21 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -259,6 +259,11 @@ const ( BorderRounded BorderSharp BorderHorizontal + BorderVertical + BorderTop + BorderBottom + BorderLeft + BorderRight ) type BorderStyle struct { diff --git a/src/update_assets.rb b/src/update_assets.rb deleted file mode 100755 index 531a8ee..0000000 --- a/src/update_assets.rb +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# http://www.rubydoc.info/github/rest-client/rest-client/RestClient -require 'rest_client' -require 'json' - -if ARGV.length < 3 - puts "usage: #{$PROGRAM_NAME} " - exit 1 -end - -token, version, *files = ARGV -base = 'https://api.github.com/repos/junegunn/fzf-bin/releases' - -# List releases -rels = JSON.parse(RestClient.get(base, authorization: "token #{token}")) -rel = rels.find { |r| r['tag_name'] == version } -unless rel - puts "#{version} not found" - exit 1 -end - -# List assets -assets = Hash[rel['assets'].map { |a| a.values_at('name', 'id') }] - -files.select { |f| File.exist?(f) }.map do |file| - Thread.new do - name = File.basename(file) - - if asset_id = assets[name] # rubocop:todo Lint/AssignmentInCondition - puts "#{name} found. Deleting asset id #{asset_id}." - RestClient.delete("#{base}/assets/#{asset_id}", - authorization: "token #{token}") - else - puts "#{name} not found" - end - - puts "Uploading #{name}" - RestClient.post( - "#{base.sub('api', 'uploads')}/#{rel['id']}/assets?name=#{name}", - File.read(file), - authorization: "token #{token}", - content_type: 'application/octet-stream' - ) - end -end.each(&:join)