diff --git a/src/Documentation/doc/en/basic/autocomplete.md b/src/Documentation/doc/en/basic/autocomplete.md index 77165a330..f86c0cab8 100644 --- a/src/Documentation/doc/en/basic/autocomplete.md +++ b/src/Documentation/doc/en/basic/autocomplete.md @@ -35,15 +35,15 @@ AutocompleteData is an object with the following properties; ```javascript { - command: // the command being run, as seen on the terminal. - enums: // the ns.enums object with various in-game strings. - filename: // the name of the script file containing the autocomplete function. - hostname: // the name of the host server the script would be running on. - processes: // list of all processes running on the current server. - servers: // list of all servers in the game. Some servers are hidden until you satisfy their requirements. This array does not contain those servers if you do not satisfy their requirements. - txts: // list of all text files on the current server. - scripts: // list of all scripts on the current server. - flags: // the same flags function as passed with ns. Calling this function adds all the flags as autocomplete arguments. + command: // The command being run, as seen on the terminal. + enums: // The ns.enums object with various in-game strings. + filename: // The name of the script file containing the autocomplete function. + hostname: // The name of the host server the script would be running on. + processes: // List of all processes running on the current server. + servers: // List of all servers in the game. Some servers are hidden until you satisfy their requirements. This array does not contain those servers if you do not satisfy their requirements. + txts: // List of all text files on the current server. + scripts: // List of all scripts on the current server. + flags: // A function similar to ns.flags(). Calling this function adds all the flags as autocomplete arguments. } ``` @@ -90,6 +90,35 @@ export function autocomplete(data, args) { In that example typing `run script.js` and pressing tab would initially suggest every server for autocomplete. Then if "n00dles" is added to the arguments and tab is pressed again, "n00dles" would no longer be suggested in subsequent autocomplete calls. +## data.flags + +This is a function that works nearly identically to `ns.flags()`. The only difference is that it allows unknown options. For example: + +```js +export function autocomplete(data, args) { + const parsedFlags = data.flags([["foo", true]]); + return []; +} + +/** @param {NS} ns */ +export async function main(ns) { + const parsedFlags = ns.flags([["foo", true]]); +} +``` + +If you type `run a.js --f` in the terminal and press tab, `parsedFlags` in `autocomplete` is `{_: ["--f"], foo: true}`. + +- `f` is not defined in the schema, so it's added to `_`. +- The command does not specify `foo`, so `foo` is set to the default value. + +If you type `run a.js --f` in the terminal and press enter, an error will be thrown: + +``` +ArgError: unknown or unexpected option: --f +``` + +This is because `f` is not defined in the schema, and `ns.flags` does not allow unknown options. + # Notes - The autocomplete function in the file is called each time the tab key is pressed following `run file.js` or `./file.js` in the terminal. diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 99924deb1..331e0a837 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -1524,7 +1524,7 @@ export const ns: InternalAPI = { //Script **must** be a script at this point return compile(script as Script, server.scripts); }, - flags: Flags, + flags: (ctx) => Flags(ctx, false), heart: { break: () => () => Player.karma }, ...NetscriptExtra(), }; diff --git a/src/NetscriptFunctions/Flags.ts b/src/NetscriptFunctions/Flags.ts index 15baa2aa6..5d12621b4 100644 --- a/src/NetscriptFunctions/Flags.ts +++ b/src/NetscriptFunctions/Flags.ts @@ -6,7 +6,7 @@ import { NetscriptContext } from "../Netscript/APIWrapper"; export type Schema = [string, string | number | boolean | string[]][]; type FlagType = StringConstructor | NumberConstructor | BooleanConstructor | StringConstructor[]; type FlagsRet = Record; -export function Flags(ctx: NetscriptContext | string[]): (data: unknown) => FlagsRet { +export function Flags(ctx: NetscriptContext | string[], permissive: boolean): (data: unknown) => FlagsRet { const vargs = Array.isArray(ctx) ? ctx : ctx.workerScript.args; return (schema: unknown): FlagsRet => { schema = toNative(schema); @@ -26,7 +26,7 @@ export function Flags(ctx: NetscriptContext | string[]): (data: unknown) => Flag args["-".repeat(numDashes) + d[0]] = t; } // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment - const ret: FlagsRet = libarg(args, { argv: vargs }); + const ret: FlagsRet = libarg(args, { argv: vargs, permissive }); for (const d of schema as Schema) { if (!Object.hasOwn(ret, "--" + d[0]) || !Object.hasOwn(ret, "-" + d[0])) ret[d[0]] = d[1]; } diff --git a/src/Terminal/getTabCompletionPossibilities.ts b/src/Terminal/getTabCompletionPossibilities.ts index c5dbcf065..8a6d2fe3f 100644 --- a/src/Terminal/getTabCompletionPossibilities.ts +++ b/src/Terminal/getTabCompletionPossibilities.ts @@ -325,7 +325,7 @@ export async function getTabCompletionPossibilities(terminalText: string, baseDi */ console.warn(error); } - const flagFunc = Flags(flags._); + const flagFunc = Flags(flags._, true); const autocompleteData: AutocompleteData = { servers: GetAllServers() .filter((server) => server.serversOnNetwork.length !== 0) @@ -355,7 +355,9 @@ export async function getTabCompletionPossibilities(terminalText: string, baseDi try { return flagFunc(schema); } catch (error) { - throw new Error("Cannot parse the schema passed to AutocompleteData.flags", { cause: error }); + throw new Error("Cannot parse the arguments with the schema passed to AutocompleteData.flags", { + cause: error, + }); } }, hostname: currServ.hostname,