summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-05-23 18:41:13 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2024-05-23 18:42:54 +0900
commitd4216b0dcc13567479d81cc5ad2adedb1443ea8b (patch)
tree6ec7aa3dde44344312e483fce316dcce79e1f087
parentbfe2bf4dced665f8752dab5f2ce17b67f6ff8b53 (diff)
Use MSYS=enable_pcon instead of winpty on mintty 3.4.5 or later
-rw-r--r--src/core.go7
-rw-r--r--src/util/util.go32
-rw-r--r--src/util/util_test.go31
-rw-r--r--src/winpty.go4
-rw-r--r--src/winpty_windows.go49
5 files changed, 118 insertions, 5 deletions
diff --git a/src/core.go b/src/core.go
index f0728f80..ec25d1d0 100644
--- a/src/core.go
+++ b/src/core.go
@@ -3,7 +3,6 @@ package fzf
import (
"os"
- "os/exec"
"sync"
"time"
@@ -25,10 +24,8 @@ func Run(opts *Options) (int, error) {
return runTmux(os.Args, opts)
}
- if os.Getenv("TERM_PROGRAM") == "mintty" && !opts.NoWinpty {
- if _, err := exec.LookPath("winpty"); err == nil {
- return runWinpty(os.Args, opts)
- }
+ if needWinpty(opts) {
+ return runWinpty(os.Args, opts)
}
if err := postProcessOptions(opts); err != nil {
diff --git a/src/util/util.go b/src/util/util.go
index b5b27f28..9b926b8d 100644
--- a/src/util/util.go
+++ b/src/util/util.go
@@ -3,6 +3,7 @@ package util
import (
"math"
"os"
+ "strconv"
"strings"
"time"
@@ -189,3 +190,34 @@ func ToKebabCase(s string) string {
}
return strings.ToLower(name)
}
+
+// CompareVersions compares two version strings
+func CompareVersions(v1, v2 string) int {
+ parts1 := strings.Split(v1, ".")
+ parts2 := strings.Split(v2, ".")
+
+ atoi := func(s string) int {
+ n, e := strconv.Atoi(s)
+ if e != nil {
+ return 0
+ }
+ return n
+ }
+
+ for i := 0; i < Max(len(parts1), len(parts2)); i++ {
+ var p1, p2 int
+ if i < len(parts1) {
+ p1 = atoi(parts1[i])
+ }
+ if i < len(parts2) {
+ p2 = atoi(parts2[i])
+ }
+
+ if p1 > p2 {
+ return 1
+ } else if p1 < p2 {
+ return -1
+ }
+ }
+ return 0
+}
diff --git a/src/util/util_test.go b/src/util/util_test.go
index af0762b5..013f3c23 100644
--- a/src/util/util_test.go
+++ b/src/util/util_test.go
@@ -203,3 +203,34 @@ func TestStringWidth(t *testing.T) {
t.Errorf("Expected: %d, Actual: %d", 1, w)
}
}
+
+func TestCompareVersions(t *testing.T) {
+ assert := func(a, b string, expected int) {
+ if result := CompareVersions(a, b); result != expected {
+ t.Errorf("Expected: %d, Actual: %d", expected, result)
+ }
+ }
+
+ assert("2", "1", 1)
+ assert("2", "2", 0)
+ assert("2", "10", -1)
+
+ assert("2.1", "2.2", -1)
+ assert("2.1", "2.1.1", -1)
+
+ assert("1.2.3", "1.2.2", 1)
+ assert("1.2.3", "1.2.3", 0)
+ assert("1.2.3", "1.2.3.0", 0)
+ assert("1.2.3", "1.2.4", -1)
+
+ // Different number of parts
+ assert("1.0.0", "1", 0)
+ assert("1.0.0", "1.0", 0)
+ assert("1.0.0", "1.0.0", 0)
+ assert("1.0", "1.0.0", 0)
+ assert("1", "1.0.0", 0)
+ assert("1.0.0", "1.0.0.1", -1)
+ assert("1.0.0.1.0", "1.0.0.1", 0)
+
+ assert("", "3.4.5", -1)
+}
diff --git a/src/winpty.go b/src/winpty.go
index 46f9400f..adee3b0b 100644
--- a/src/winpty.go
+++ b/src/winpty.go
@@ -4,6 +4,10 @@ package fzf
import "errors"
+func needWinpty(_ *Options) bool {
+ return false
+}
+
func runWinpty(_ []string, _ *Options) (int, error) {
return ExitError, errors.New("Not supported")
}
diff --git a/src/winpty_windows.go b/src/winpty_windows.go
index 83802a2b..6d7e366f 100644
--- a/src/winpty_windows.go
+++ b/src/winpty_windows.go
@@ -6,8 +6,46 @@ import (
"fmt"
"os"
"os/exec"
+
+ "github.com/junegunn/fzf/src/util"
)
+func isMintty345() bool {
+ return util.CompareVersions(os.Getenv("TERM_PROGRAM_VERSION"), "3.4.5") >= 0
+}
+
+func needWinpty(opts *Options) bool {
+ if os.Getenv("TERM_PROGRAM") != "mintty" {
+ return false
+ }
+ if isMintty345() {
+ /*
+ See: https://github.com/junegunn/fzf/issues/3809
+
+ "MSYS=enable_pcon" allows fzf to run properly on mintty 3.4.5 or later,
+ however `--height` option still doesn't work, so let's just disable it.
+
+ We're not going to worry too much about restoring the original value.
+ */
+ if os.Getenv("MSYS") == "enable_pcon" {
+ opts.Height = heightSpec{}
+ return false
+ }
+
+ // Setting the environment variable here unfortunately doesn't help,
+ // so we need to start a child process with "MSYS=enable_pcon"
+ // os.Setenv("MSYS", "enable_pcon")
+ return true
+ }
+ if _, err := exec.LookPath("winpty"); err != nil {
+ return false
+ }
+ if opts.NoWinpty {
+ return false
+ }
+ return true
+}
+
func runWinpty(args []string, opts *Options) (int, error) {
sh, err := sh()
if err != nil {
@@ -20,6 +58,17 @@ func runWinpty(args []string, opts *Options) (int, error) {
}
argStr += ` --no-winpty --no-height`
+ if isMintty345() {
+ return runProxy(argStr, func(temp string) *exec.Cmd {
+ cmd := exec.Command(sh, temp)
+ cmd.Env = append(os.Environ(), "MSYS=enable_pcon")
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ return cmd
+ }, opts, false)
+ }
+
return runProxy(argStr, func(temp string) *exec.Cmd {
cmd := exec.Command(sh, "-c", fmt.Sprintf(`winpty < /dev/tty > /dev/tty -- sh %q`, temp))
cmd.Stdout = os.Stdout