瀏覽代碼

Add support for completing invocations of local executables

kas 1 年之前
父節點
當前提交
93c9f86555
共有 3 個文件被更改,包括 33 次插入6 次删除
  1. 3 0
      0.19.0-release-notes.md
  2. 29 5
      pkg/edit/complete/complete_test.go
  3. 1 1
      pkg/edit/complete/generators.go

+ 3 - 0
0.19.0-release-notes.md

@@ -30,6 +30,9 @@ and compiled, even if it is not executed:
 -   Broken symbolic links no longer terminate a wildcard expansion prematurely
     ([#1240](https://b.elv.sh/1240)).
 
+-   On Windows, command completion for executables now also works for local
+    files
+
 # Notable new features
 
 -   A new `inexact-num` converts its argument to an inexact number.

+ 29 - 5
pkg/edit/complete/complete_test.go

@@ -363,8 +363,35 @@ func TestComplete(t *testing.T) {
 		Args(cb("nop `"), ev, cfg).Rets((*Result)(nil), errNoCompletion),
 	})
 
-	// Symlinks and executable bits are not available on Windows.
-	if runtime.GOOS != "windows" {
+	if runtime.GOOS == "windows" {
+		// Symlinks require admin permissions on Windows, so we won't test them
+
+		// Check completions with forward slash
+		allLocalCommandItems := []modes.CompletionItem{
+			fci("./a.exe", " "), fci("./d\\", ""),
+		}
+		tt.Test(t, tt.Fn("Complete", Complete), tt.Table{
+			// Complete local external commands.
+			Args(cb("./"), ev, cfg).Rets(
+				&Result{
+					Name: "command", Replace: r(0, 2),
+					Items: allLocalCommandItems},
+				nil),
+		})
+
+		// Check completions with bckward slash
+		allLocalCommandItems = []modes.CompletionItem{
+			fci(".\\a.exe", " "), fci(".\\d\\", ""),
+		}
+		tt.Test(t, tt.Fn("Complete", Complete), tt.Table{
+			// Complete local external commands.
+			Args(cb(".\\"), ev, cfg).Rets(
+				&Result{
+					Name: "command", Replace: r(0, 2),
+					Items: allLocalCommandItems},
+				nil),
+		})
+	} else {
 		err := os.Symlink("d", "d2")
 		if err != nil {
 			panic(err)
@@ -383,9 +410,6 @@ func TestComplete(t *testing.T) {
 			),
 
 			// Complete local external commands.
-			//
-			// TODO(xiaq): Make this test applicable to Windows by using a
-			// different criteria for executable files on Window.
 			Args(cb("./"), ev, cfg).Rets(
 				&Result{
 					Name: "command", Replace: r(0, 2),

+ 1 - 1
pkg/edit/complete/generators.go

@@ -143,7 +143,7 @@ func generateFileNames(seed string, onlyExecutable bool) ([]RawItem, error) {
 		}
 		// Only accept searchable directories and executable files if
 		// executableOnly is true.
-		if onlyExecutable && (stat.Mode()&0111) == 0 {
+		if onlyExecutable && !fsutil.IsExecutable(stat) && !stat.IsDir() {
 			continue
 		}