Repository: microsoft/inshellisense (ts)

Issue:
Typing "ls -" does not jump you to the options for the ls command
**Describe the bug**
Typing `ls -` does not jump you to the options for the ls command, I have to scroll past potentionally dozens of filenames (depending on the contents of the directory) to get to the parameters for the `ls` command.

**To Reproduce**
Steps to reproduce the behavior:
1. Type `ls `
2. Notice the filenames in the current dir are suggested, but not the options like `-h` etc.
3. Type `-`
4. I still am stuck on viewing filenames, and the options like `-h` etc. are not visible, I have to scroll down pages to get to them.

**Expected behavior**
Hitting `-` should jump you to the options of the `ls` command, just like `find -` does and many other commands.

**Environment**
 - OS: macox
 - Output of `inshellisense --version`: 0.0.1-rc.4
 - Nodejs Version: v18.16.0

**Additional context**
Perhaps hitting up arrow to backwards scroll (or some other key) would bypass filenames and get to the options of a command. Getting to the options of a command is, after all, the main point of inshellisense, so making it easy to get to the options is essential.


Pull request:
fix: showing option suggestions after variadic arg
## Description
This change makes it so that when an item is found after a variadic sequence, we can still suggest subcommands / options that break the sequence. It also fixes parsing an option found at the end of a command sequence.

Closes #56

Patch:
diff --git a/src/runtime/parser.ts b/src/runtime/parser.ts
index 3f9226c..77acd3c 100644
--- a/src/runtime/parser.ts
+++ b/src/runtime/parser.ts
@@ -65,7 +65,7 @@ const lex = (command: string): CommandToken[] => {
     tokens.push({
       token: command.slice(readingIdx),
       complete: false,
-      isOption: false,
+      isOption: readingFlag,
     });
   }
 
diff --git a/src/runtime/suggestion.ts b/src/runtime/suggestion.ts
index cd49229..5ee2d90 100644
--- a/src/runtime/suggestion.ts
+++ b/src/runtime/suggestion.ts
@@ -237,7 +237,7 @@ export const getArgDrivenRecommendation = async (
     ...(await templateSuggestions(args[0].template, activeArg?.filterStrategy, partialCmd)),
   ];
 
-  if ((activeArg.isOptional && !activeArg.isVariadic) || (activeArg.isVariadic && activeArg.isOptional && !variadicArgBound)) {
+  if (activeArg.isOptional || (activeArg.isVariadic && variadicArgBound)) {
     suggestions.push(...subcommandSuggestions(subcommand.subcommands, activeArg?.filterStrategy, partialCmd));
     suggestions.push(...optionSuggestions(allOptions, acceptedTokens, activeArg?.filterStrategy, partialCmd));
   }


Test patch:
diff --git a/src/tests/runtime/__snapshots__/parser.test.ts.snap b/src/tests/runtime/__snapshots__/parser.test.ts.snap
index 444287e..e205ba5 100644
--- a/src/tests/runtime/__snapshots__/parser.test.ts.snap
+++ b/src/tests/runtime/__snapshots__/parser.test.ts.snap
@@ -179,7 +179,7 @@ exports[`parseCommand cmd -f 1`] = `
   },
   {
     "complete": false,
-    "isOption": false,
+    "isOption": true,
     "token": "-f",
   },
 ]
@@ -194,7 +194,7 @@ exports[`parseCommand cmd -f 2`] = `
   },
   {
     "complete": false,
-    "isOption": false,
+    "isOption": true,
     "token": "-f",
   },
 ]
@@ -329,3 +329,18 @@ exports[`parseCommand cmd1 | cmd2  1`] = `
   },
 ]
 `;
+
+exports[`parseCommand cmd1 - 1`] = `
+[
+  {
+    "complete": true,
+    "isOption": false,
+    "token": "cmd1",
+  },
+  {
+    "complete": false,
+    "isOption": true,
+    "token": "-",
+  },
+]
+`;
diff --git a/src/tests/runtime/__snapshots__/runtime.test.ts.snap b/src/tests/runtime/__snapshots__/runtime.test.ts.snap
index 2c65993..52782f0 100644
--- a/src/tests/runtime/__snapshots__/runtime.test.ts.snap
+++ b/src/tests/runtime/__snapshots__/runtime.test.ts.snap
@@ -470,11 +470,49 @@ exports[`parseCommand noArgsArgumentGiven 1`] = `
 }
 `;
 
-exports[`parseCommand noOptionsSuggestedAfterVariadicArg 1`] = `
+exports[`parseCommand noOptionsSuggestedDuringVariadicArg 1`] = `
+{
+  "charactersToDrop": 3,
+  "suggestions": [],
+}
+`;
+
+exports[`parseCommand optionsSuggestedAfterVariadicArg 1`] = `
 {
   "argumentDescription": undefined,
   "charactersToDrop": 1,
-  "suggestions": [],
+  "suggestions": [
+    {
+      "allNames": [
+        "-@",
+      ],
+      "description": "Display extended attribute keys and sizes in long (-l) output",
+      "icon": "🔗",
+      "insertValue": undefined,
+      "name": "-@",
+      "priority": 50,
+    },
+    {
+      "allNames": [
+        "-1",
+      ],
+      "description": "(The numeric digit \`\`one''.)  Force output to be one entry per line.  This is the default when output is not to a terminal",
+      "icon": "🔗",
+      "insertValue": undefined,
+      "name": "-1",
+      "priority": 50,
+    },
+    {
+      "allNames": [
+        "-A",
+      ],
+      "description": "List all entries except for . and ...  Always set for the super-user",
+      "icon": "🔗",
+      "insertValue": undefined,
+      "name": "-A",
+      "priority": 50,
+    },
+  ],
 }
 `;
 
diff --git a/src/tests/runtime/parser.test.ts b/src/tests/runtime/parser.test.ts
index 37d7dae..3c42408 100644
--- a/src/tests/runtime/parser.test.ts
+++ b/src/tests/runtime/parser.test.ts
@@ -24,6 +24,7 @@ const testData = [
   { command: `cmd "value' ` },
   { command: `cmd "value'\\"\\"" ` },
   { command: `cmd1 | cmd2 ` },
+  { command: `cmd1 -` },
 ];
 
 describe(`parseCommand`, () => {
diff --git a/src/tests/runtime/runtime.test.ts b/src/tests/runtime/runtime.test.ts
index e6d1a0f..49a12bb 100644
--- a/src/tests/runtime/runtime.test.ts
+++ b/src/tests/runtime/runtime.test.ts
@@ -12,7 +12,8 @@ const testData = [
   { name: "exclusiveOnOption", command: "ag --affinity --no" },
   { name: "providedSuggestion", command: "bw completion --shell " },
   { name: "fullyTypedSuggestion", command: "ls -W" },
-  { name: "noOptionsSuggestedAfterVariadicArg", command: "ls item -" },
+  { name: "optionsSuggestedAfterVariadicArg", command: "ls item -", maxSuggestions: 3 },
+  { name: "noOptionsSuggestedDuringVariadicArg", command: "ls -W ite" },
   { name: "providedArgDescription", command: "act completion bash -a " },
   { name: "completedOptionWithArg", command: "act completion bash -a 'actor' " },
   { name: "command", command: "sudo git sta" },