@ 261102.1

240523.4 · d4216b0dcc13567479d81cc5ad2adedb1443ea8b

Use MSYS=enable_pcon instead of winpty on mintty 3.4.5 or later

reading declarations

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 {

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+}

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)+}

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") }

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