Workaround for flynn cli optionsFirst usage

Refs flynn/flynn#193

Signed-off-by: Jonathan Rudenberg <jonathan@titanous.com>
diff --git a/docopt.go b/docopt.go
index d3a1c4f..0a7cac6 100644
--- a/docopt.go
+++ b/docopt.go
@@ -103,7 +103,7 @@
 		return
 	}
 
-	patternArgv, err := parseArgv(newTokenList(argv, errorUser), &options, optionsFirst)
+	patternArgv, err := parseArgv(newTokenList(argv, errorUser), &options, optionsFirst, pat)
 	if err != nil {
 		output = handleError(err, usage)
 		return
@@ -199,7 +199,7 @@
 	return newRequired(result...), nil
 }
 
-func parseArgv(tokens *tokenList, options *patternList, optionsFirst bool) (patternList, error) {
+func parseArgv(tokens *tokenList, options *patternList, optionsFirst bool, pat *pattern) (patternList, error) {
 	/*
 		Parse command-line argument vector.
 
@@ -209,6 +209,16 @@
 			argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ;
 	*/
 	parsed := patternList{}
+
+	// This is a HACK that skips the command in:
+	// (*docopt.pattern)(0x208333dc0)(required(required(command(foo, false), ...)))
+	// when parsing with optionsFirst set. For more details see
+	// https://github.com/flynn/flynn/pull/193
+	skipArg := optionsFirst && pat != nil &&
+		pat.t == patternRequired && len(pat.children) == 1 &&
+		pat.children[0].t == patternRequired && len(pat.children[0].children) > 0 &&
+		pat.children[0].children[0].t == patternCommand
+
 	for tokens.current() != nil {
 		if tokens.current().eq("--") {
 			for _, v := range tokens.tokens {
@@ -227,13 +237,14 @@
 				return nil, err
 			}
 			parsed = append(parsed, ps...)
-		} else if optionsFirst {
+		} else if !skipArg && optionsFirst {
 			for _, v := range tokens.tokens {
 				parsed = append(parsed, newArgument("", v))
 			}
 			return parsed, nil
 		} else {
 			parsed = append(parsed, newArgument("", tokens.move().String()))
+			skipArg = false
 		}
 	}
 	return parsed, nil
diff --git a/docopt_test.go b/docopt_test.go
index 231bc81..65c85c8 100644
--- a/docopt_test.go
+++ b/docopt_test.go
@@ -171,19 +171,19 @@
 		newOption("-f", "--file", 1, false),
 	}
 
-	p, err := parseArgv(tokenListFromString(""), &o, false)
+	p, err := parseArgv(tokenListFromString(""), &o, false, nil)
 	q := patternList{}
 	if reflect.DeepEqual(p, q) != true {
 		t.Error(err)
 	}
 
-	p, err = parseArgv(tokenListFromString("-h"), &o, false)
+	p, err = parseArgv(tokenListFromString("-h"), &o, false, nil)
 	q = patternList{newOption("-h", "", 0, true)}
 	if reflect.DeepEqual(p, q) != true {
 		t.Error(err)
 	}
 
-	p, err = parseArgv(tokenListFromString("-h --verbose"), &o, false)
+	p, err = parseArgv(tokenListFromString("-h --verbose"), &o, false, nil)
 	q = patternList{
 		newOption("-h", "", 0, true),
 		newOption("-v", "--verbose", 0, true),
@@ -192,7 +192,7 @@
 		t.Error(err)
 	}
 
-	p, err = parseArgv(tokenListFromString("-h --file f.txt"), &o, false)
+	p, err = parseArgv(tokenListFromString("-h --file f.txt"), &o, false, nil)
 	q = patternList{
 		newOption("-h", "", 0, true),
 		newOption("-f", "--file", 1, "f.txt"),
@@ -201,7 +201,7 @@
 		t.Error(err)
 	}
 
-	p, err = parseArgv(tokenListFromString("-h --file f.txt arg"), &o, false)
+	p, err = parseArgv(tokenListFromString("-h --file f.txt arg"), &o, false, nil)
 	q = patternList{
 		newOption("-h", "", 0, true),
 		newOption("-f", "--file", 1, "f.txt"),
@@ -211,7 +211,7 @@
 		t.Error(err)
 	}
 
-	p, err = parseArgv(tokenListFromString("-h --file f.txt arg arg2"), &o, false)
+	p, err = parseArgv(tokenListFromString("-h --file f.txt arg arg2"), &o, false, nil)
 	q = patternList{
 		newOption("-h", "", 0, true),
 		newOption("-f", "--file", 1, "f.txt"),
@@ -222,7 +222,7 @@
 		t.Error(err)
 	}
 
-	p, err = parseArgv(tokenListFromString("-h arg -- -v"), &o, false)
+	p, err = parseArgv(tokenListFromString("-h arg -- -v"), &o, false, nil)
 	q = patternList{
 		newOption("-h", "", 0, true),
 		newArgument("", "arg"),
@@ -1295,6 +1295,10 @@
 	if v, err := Parse("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, true, "", true, false); reflect.DeepEqual(v.All, map[string]interface{}{"--opt": false, "<args>": []string{"this", "that", "--opt"}}) != true {
 		t.Error(err)
 	}
+
+	if v, err := Parse("usage: prog foo [--opt] [<args>...]", []string{"foo", "--opt", "this", "that"}, true, "", true, false); reflect.DeepEqual(v.All, map[string]interface{}{"foo": true, "--opt": true, "<args>": []string{"this", "that"}}) != true {
+		t.Error(err)
+	}
 }
 
 func TestIssue68OptionsShortcutDoesNotIncludeOptionsInUsagePattern(t *testing.T) {