From d201e7c503ab6e02da21a98d3f69012e01305493 Mon Sep 17 00:00:00 2001 From: Florian Sundermann Date: Wed, 14 Sep 2016 16:15:49 +0200 Subject: [PATCH 1/2] fixed directory completion on windows --- cmd/micro/util.go | 56 +++++++++++++++++++++++++++++------------- cmd/micro/util_test.go | 7 +++++- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/cmd/micro/util.go b/cmd/micro/util.go index a91295fe..4402a22e 100644 --- a/cmd/micro/util.go +++ b/cmd/micro/util.go @@ -230,42 +230,64 @@ func FuncName(i interface{}) string { // The returned slice contains at least one string func SplitCommandArgs(input string) []string { var result []string + var curQuote *bytes.Buffer = nil + curArg := new(bytes.Buffer) - inQuote := false escape := false - appendResult := func() { - str := curArg.String() - inQuote = false - escape = false - if strings.HasPrefix(str, `"`) && strings.HasSuffix(str, `"`) { - if unquoted, err := strconv.Unquote(str); err == nil { - str = unquoted - } + finishQuote := func() { + if curQuote == nil { + return } + str := curQuote.String() + if unquoted, err := strconv.Unquote(str); err == nil { + str = unquoted + } + curArg.WriteString(str) + curQuote = nil + } + + appendResult := func() { + finishQuote() + escape = false + + str := curArg.String() result = append(result, str) curArg.Reset() } for _, r := range input { - if r == ' ' && !inQuote { + if r == ' ' && curQuote == nil { appendResult() } else { - curArg.WriteRune(r) + runeHandled := false + appendRuneToBuff := func() { + if curQuote != nil { + curQuote.WriteRune(r) + } else { + curArg.WriteRune(r) + } + runeHandled = true + } - if r == '"' && !inQuote { - inQuote = true + if r == '"' && curQuote == nil { + curQuote = new(bytes.Buffer) + appendRuneToBuff() } else { - if inQuote && !escape { + if curQuote != nil && !escape { if r == '"' { - inQuote = false - } - if r == '\\' { + appendRuneToBuff() + finishQuote() + } else if r == '\\' { + appendRuneToBuff() escape = true continue } } } + if !runeHandled { + appendRuneToBuff() + } } escape = false diff --git a/cmd/micro/util_test.go b/cmd/micro/util_test.go index c3060ff5..16e46fe4 100644 --- a/cmd/micro/util_test.go +++ b/cmd/micro/util_test.go @@ -100,9 +100,14 @@ func TestJoinAndSplitCommandArgs(t *testing.T) { Query string Wanted []string }{ - {`"hallo""Welt"`, []string{`"hallo""Welt"`}}, + {`"hallo""Welt"`, []string{`halloWelt`}}, + {`"hallo" "Welt"`, []string{`hallo`, `Welt`}}, {`\"`, []string{`\"`}}, + {`"foo`, []string{`"foo`}}, + {`"foo"`, []string{`foo`}}, {`"\"`, []string{`"\"`}}, + {`"C:\\"foo.txt`, []string{`C:\foo.txt`}}, + {`"\n"new"\n"line`, []string{"\nnew\nline"}}, } for i, test := range splitTests { From 6cc12b871c7dff4a7ed489b9f0267467b6454680 Mon Sep 17 00:00:00 2001 From: Florian Sundermann Date: Wed, 14 Sep 2016 16:28:25 +0200 Subject: [PATCH 2/2] include trailing path delimiter "C:" is not valid on windows but "C:\" is. "foo" is as valid as "foo/" on other OS... --- cmd/micro/autocomplete.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/micro/autocomplete.go b/cmd/micro/autocomplete.go index 941f0fc5..9d4ceab4 100644 --- a/cmd/micro/autocomplete.go +++ b/cmd/micro/autocomplete.go @@ -18,12 +18,14 @@ var pluginCompletions []func(string) []string func FileComplete(input string) (string, []string) { var sep string = string(os.PathSeparator) dirs := strings.Split(input, sep) + var files []os.FileInfo var err error if len(dirs) > 1 { home, _ := homedir.Dir() - directories := strings.Join(dirs[:len(dirs)-1], sep) + directories := strings.Join(dirs[:len(dirs)-1], sep) + sep + if strings.HasPrefix(directories, "~") { directories = strings.Replace(directories, "~", home, 1) } @@ -31,6 +33,7 @@ func FileComplete(input string) (string, []string) { } else { files, err = ioutil.ReadDir(".") } + var suggestions []string if err != nil { return "", suggestions