mirror of
https://github.com/wavetermdev/inshellisense.git
synced 2026-08-05 13:43:30 -07:00
ci: add linting & formatting
Signed-off-by: Chapman Pendery <cpendery@vt.edu>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
es2021: true,
|
||||
node: true,
|
||||
},
|
||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react/recommended", "prettier"],
|
||||
overrides: [
|
||||
{
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
files: [".eslintrc.{js,cjs}"],
|
||||
parserOptions: {
|
||||
sourceType: "script",
|
||||
},
|
||||
},
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
},
|
||||
plugins: ["@typescript-eslint", "react"],
|
||||
rules: {},
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"printWidth": 160
|
||||
}
|
||||
Generated
+4225
File diff suppressed because it is too large
Load Diff
+9
-1
@@ -15,7 +15,9 @@
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node ./build/index.js",
|
||||
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
|
||||
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
||||
"lint": "eslint src/ --ext .ts,.tsx && prettier src/ --check",
|
||||
"lint:fix": "eslint src/ --ext .ts,.tsx --fix && prettier src/ --write"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -41,8 +43,14 @@
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@types/react": "^18.2.24",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||
"@typescript-eslint/parser": "^6.7.4",
|
||||
"@withfig/autocomplete-types": "^1.28.0",
|
||||
"eslint": "^8.51.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "3.0.3",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ export const runGenerator = async (generator: Fig.Generator, tokens: string[]):
|
||||
suggestions.push(...(await runTemplates(template)));
|
||||
}
|
||||
return suggestions;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
return suggestions;
|
||||
};
|
||||
|
||||
@@ -32,14 +32,9 @@ const lex = (command: string): CommandToken[] => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
readingQuotedString &&
|
||||
char === readingQuoteChar &&
|
||||
command.at(idx - 1) !== "\\"
|
||||
) {
|
||||
if (readingQuotedString && char === readingQuoteChar && command.at(idx - 1) !== "\\") {
|
||||
readingQuotedString = false;
|
||||
const complete =
|
||||
idx + 1 < command.length && spaceRegex.test(command[idx + 1]);
|
||||
const complete = idx + 1 < command.length && spaceRegex.test(command[idx + 1]);
|
||||
tokens.push({
|
||||
token: command.slice(readingIdx, idx + 1),
|
||||
complete,
|
||||
|
||||
+24
-13
@@ -1,5 +1,6 @@
|
||||
import speclist, {
|
||||
diffVersionedCompletions as versionedSpeclist,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
} from "@withfig/autocomplete/build/index.js";
|
||||
import { parseCommand, CommandToken } from "./parser.js";
|
||||
@@ -7,6 +8,7 @@ import { getArgDrivenRecommendation, getSubcommandDrivenRecommendation } from ".
|
||||
import { SuggestionBlob } from "./model.js";
|
||||
import { buildExecuteShellCommand } from "./utils.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- recursive type, setting as any
|
||||
const specSet: any = {};
|
||||
(speclist as string[]).forEach((s) => {
|
||||
let activeSet = specSet;
|
||||
@@ -45,6 +47,7 @@ const lazyLoadSpec = async (key: string): Promise<Fig.Spec | undefined> => {
|
||||
return (await import(`@withfig/autocomplete/build/${key}.js`)).default;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- will be implemented in below TODO
|
||||
const lazyLoadSpecLocation = async (location: Fig.SpecLocation): Promise<Fig.Spec | undefined> => {
|
||||
return; //TODO: implement spec location loading
|
||||
};
|
||||
@@ -72,8 +75,8 @@ const getPersistentOptions = (persistentOptions: Fig.Option[], options?: Fig.Opt
|
||||
const persistentOptionNames = new Set(persistentOptions.map((o) => (typeof o.name === "string" ? [o.name] : o.name)).flat());
|
||||
return persistentOptions.concat(
|
||||
(options ?? []).filter(
|
||||
(o) => (typeof o.name == "string" ? !persistentOptionNames.has(o.name) : o.name.some((n) => !persistentOptionNames.has(n))) && o.isPersistent === true
|
||||
)
|
||||
(o) => (typeof o.name == "string" ? !persistentOptionNames.has(o.name) : o.name.some((n) => !persistentOptionNames.has(n))) && o.isPersistent === true,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -82,7 +85,7 @@ const getSubcommand = (spec?: Fig.Spec): Fig.Subcommand | undefined => {
|
||||
if (spec == null) return;
|
||||
if (typeof spec === "function") {
|
||||
const potentialSubcommand = spec();
|
||||
if (potentialSubcommand.hasOwnProperty("name")) {
|
||||
if (Object.prototype.hasOwnProperty.call(potentialSubcommand, "name")) {
|
||||
return potentialSubcommand as Fig.Subcommand;
|
||||
}
|
||||
return;
|
||||
@@ -101,7 +104,7 @@ const genSubcommand = async (command: string, parentCommand: Fig.Subcommand): Pr
|
||||
// this pulls in the spec from the load spec and overwrites the subcommand in the parent with the loaded spec.
|
||||
// then it returns the subcommand and clears the loadSpec field so that it doesn't get called again
|
||||
switch (typeof subcommand.loadSpec) {
|
||||
case "function":
|
||||
case "function": {
|
||||
const partSpec = await subcommand.loadSpec(command, executeShellCommand);
|
||||
if (partSpec instanceof Array) {
|
||||
const locationSpecs = (await Promise.all(partSpec.map((s) => lazyLoadSpecLocation(s)))).filter((s) => s != null) as Fig.Spec[];
|
||||
@@ -112,23 +115,31 @@ const genSubcommand = async (command: string, parentCommand: Fig.Subcommand): Pr
|
||||
loadSpec: undefined,
|
||||
};
|
||||
return (parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx];
|
||||
} else if (partSpec.hasOwnProperty("type")) {
|
||||
} else if (Object.prototype.hasOwnProperty.call(partSpec, "type")) {
|
||||
const locationSingleSpec = await lazyLoadSpecLocation(partSpec as Fig.SpecLocation);
|
||||
(parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx] = { ...subcommand, ...(getSubcommand(locationSingleSpec) ?? []), loadSpec: undefined };
|
||||
(parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx] = {
|
||||
...subcommand,
|
||||
...(getSubcommand(locationSingleSpec) ?? []),
|
||||
loadSpec: undefined,
|
||||
};
|
||||
return (parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx];
|
||||
} else {
|
||||
(parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx] = { ...subcommand, ...partSpec, loadSpec: undefined };
|
||||
return (parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx];
|
||||
}
|
||||
case "string":
|
||||
}
|
||||
case "string": {
|
||||
const spec = await lazyLoadSpec(subcommand.loadSpec as string);
|
||||
(parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx] = { ...subcommand, ...(getSubcommand(spec) ?? []), loadSpec: undefined };
|
||||
return (parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx];
|
||||
case "object":
|
||||
}
|
||||
case "object": {
|
||||
(parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx] = { ...subcommand, ...(subcommand.loadSpec ?? {}), loadSpec: undefined };
|
||||
return (parentCommand.subcommands as Fig.Subcommand[])[subcommandIdx];
|
||||
case "undefined":
|
||||
}
|
||||
case "undefined": {
|
||||
return subcommand;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -149,7 +160,7 @@ const runOption = async (
|
||||
option: Fig.Option,
|
||||
subcommand: Fig.Subcommand,
|
||||
persistentOptions: Fig.Option[],
|
||||
acceptedTokens: CommandToken[]
|
||||
acceptedTokens: CommandToken[],
|
||||
): Promise<SuggestionBlob | undefined> => {
|
||||
if (tokens.length === 0) {
|
||||
throw new Error("invalid state reached, option expected but no tokens found");
|
||||
@@ -170,7 +181,7 @@ const runArg = async (
|
||||
persistentOptions: Fig.Option[],
|
||||
acceptedTokens: CommandToken[],
|
||||
fromOption: boolean,
|
||||
fromVariadic: boolean
|
||||
fromVariadic: boolean,
|
||||
): Promise<SuggestionBlob | undefined> => {
|
||||
if (args.length === 0) {
|
||||
return runSubcommand(tokens, subcommand, persistentOptions, acceptedTokens, true, !fromOption);
|
||||
@@ -218,7 +229,7 @@ const runSubcommand = async (
|
||||
persistentOptions: Fig.Option[] = [],
|
||||
acceptedTokens: CommandToken[] = [],
|
||||
argsDepleted = false,
|
||||
argsUsed = false
|
||||
argsUsed = false,
|
||||
): Promise<SuggestionBlob | undefined> => {
|
||||
if (tokens.length === 0) {
|
||||
return getSubcommandDrivenRecommendation(subcommand, persistentOptions, undefined, argsDepleted, argsUsed, acceptedTokens);
|
||||
@@ -244,7 +255,7 @@ const runSubcommand = async (
|
||||
tokens.slice(1),
|
||||
nextSubcommand,
|
||||
getPersistentOptions(persistentOptions, subcommand.options),
|
||||
getPersistentTokens(acceptedTokens.concat(activeToken))
|
||||
getPersistentTokens(acceptedTokens.concat(activeToken)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -57,7 +57,7 @@ function filter<T extends Fig.BaseSuggestion & { name?: Fig.SingleOrArray<string
|
||||
suggestions: T[],
|
||||
filterStrategy: FilterStrategy | undefined,
|
||||
partialCmd: string | undefined,
|
||||
suggestionType: Fig.SuggestionType | undefined
|
||||
suggestionType: Fig.SuggestionType | undefined,
|
||||
): Suggestion[] {
|
||||
if (!partialCmd) return suggestions.map((s) => toSuggestion(s, undefined, suggestionType)).filter((s) => s != null) as Suggestion[];
|
||||
|
||||
@@ -129,7 +129,7 @@ const generatorSuggestions = async (
|
||||
generator: Fig.SingleOrArray<Fig.Generator> | undefined,
|
||||
acceptedTokens: CommandToken[],
|
||||
filterStrategy: FilterStrategy | undefined,
|
||||
partialCmd: string | undefined
|
||||
partialCmd: string | undefined,
|
||||
): Promise<Suggestion[]> => {
|
||||
const generators = generator instanceof Array ? generator : generator ? [generator] : [];
|
||||
const tokens = acceptedTokens.map((t) => t.token);
|
||||
@@ -140,7 +140,7 @@ const generatorSuggestions = async (
|
||||
const templateSuggestions = async (
|
||||
templates: Fig.Template | undefined,
|
||||
filterStrategy: FilterStrategy | undefined,
|
||||
partialCmd: string | undefined
|
||||
partialCmd: string | undefined,
|
||||
): Promise<Suggestion[]> => {
|
||||
return filter<Fig.Suggestion>(await runTemplates(templates ?? []), filterStrategy, partialCmd, undefined);
|
||||
};
|
||||
@@ -148,7 +148,7 @@ const templateSuggestions = async (
|
||||
const suggestionSuggestions = (
|
||||
suggestions: (string | Fig.Suggestion)[] | undefined,
|
||||
filterStrategy: FilterStrategy | undefined,
|
||||
partialCmd: string | undefined
|
||||
partialCmd: string | undefined,
|
||||
): Suggestion[] => {
|
||||
const cleanedSuggestions = suggestions?.map((s) => (typeof s === "string" ? { name: s } : s)) ?? [];
|
||||
return filter<Fig.Suggestion>(cleanedSuggestions ?? [], filterStrategy, partialCmd, undefined);
|
||||
@@ -157,7 +157,7 @@ const suggestionSuggestions = (
|
||||
const subcommandSuggestions = (
|
||||
subcommands: Fig.Subcommand[] | undefined,
|
||||
filterStrategy: FilterStrategy | undefined,
|
||||
partialCmd: string | undefined
|
||||
partialCmd: string | undefined,
|
||||
): Suggestion[] => {
|
||||
return filter<Fig.Subcommand>(subcommands ?? [], filterStrategy, partialCmd, "subcommand");
|
||||
};
|
||||
@@ -166,7 +166,7 @@ const optionSuggestions = (
|
||||
options: Fig.Option[] | undefined,
|
||||
acceptedTokens: CommandToken[],
|
||||
filterStrategy: FilterStrategy | undefined,
|
||||
partialCmd: string | undefined
|
||||
partialCmd: string | undefined,
|
||||
): Suggestion[] => {
|
||||
const usedOptions = new Set(acceptedTokens.filter((t) => t.isOption).map((t) => t.token));
|
||||
const validOptions = options?.filter((o) => o.exclusiveOn?.every((exclusiveOption) => !usedOptions.has(exclusiveOption)) ?? true);
|
||||
@@ -188,7 +188,7 @@ export const getSubcommandDrivenRecommendation = async (
|
||||
partialCmd: string | undefined,
|
||||
argsDepleted: boolean,
|
||||
argsFromSubcommand: boolean,
|
||||
acceptedTokens: CommandToken[]
|
||||
acceptedTokens: CommandToken[],
|
||||
): Promise<SuggestionBlob | undefined> => {
|
||||
if (argsDepleted && argsFromSubcommand) {
|
||||
return;
|
||||
@@ -212,8 +212,8 @@ export const getSubcommandDrivenRecommendation = async (
|
||||
suggestions: removeEmptySuggestion(
|
||||
removeDuplicateSuggestions(
|
||||
suggestions.sort((a, b) => b.priority - a.priority),
|
||||
acceptedTokens
|
||||
)
|
||||
acceptedTokens,
|
||||
),
|
||||
),
|
||||
};
|
||||
};
|
||||
@@ -224,7 +224,7 @@ export const getArgDrivenRecommendation = async (
|
||||
persistentOptions: Fig.Option[],
|
||||
partialCmd: string | undefined,
|
||||
acceptedTokens: CommandToken[],
|
||||
variadicArgBound: boolean
|
||||
variadicArgBound: boolean,
|
||||
): Promise<SuggestionBlob | undefined> => {
|
||||
const activeArg = args[0];
|
||||
const allOptions = persistentOptions.concat(subcommand.options ?? []);
|
||||
@@ -243,8 +243,8 @@ export const getArgDrivenRecommendation = async (
|
||||
suggestions: removeEmptySuggestion(
|
||||
removeDuplicateSuggestions(
|
||||
suggestions.sort((a, b) => b.priority - a.priority),
|
||||
acceptedTokens
|
||||
)
|
||||
acceptedTokens,
|
||||
),
|
||||
),
|
||||
argumentDescription: activeArg.description ?? activeArg.name,
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ export const runTemplates = async (template: Fig.TemplateStrings[] | Fig.Templat
|
||||
case "help":
|
||||
return helpTemplate();
|
||||
}
|
||||
})
|
||||
}),
|
||||
)
|
||||
).flat();
|
||||
};
|
||||
|
||||
@@ -6,8 +6,9 @@ type ExecuteShellCommandTTYResult = {
|
||||
|
||||
export const buildExecuteShellCommand =
|
||||
(timeout: number) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- TODO: use cwd in the future
|
||||
async (command: string, cwd?: string): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
exec(command, { timeout }, (_, stdout, stderr) => {
|
||||
resolve(stdout || stderr);
|
||||
});
|
||||
|
||||
@@ -87,22 +87,25 @@ export const bind = async (shell: Shell): Promise<void> => {
|
||||
await fsAsync.mkdir(saConfigPath);
|
||||
}
|
||||
switch (shell) {
|
||||
case Shell.Bash:
|
||||
case Shell.Bash: {
|
||||
const bashConfigPath = path.join(os.homedir(), ".bashrc");
|
||||
await fsAsync.appendFile(bashConfigPath, `\n${bashScriptCommand()}`);
|
||||
await fsAsync.copyFile(path.join(__dirname, "..", "..", "shell", "key-bindings.bash"), path.join(os.homedir(), ".sa", "key-bindings.bash"));
|
||||
break;
|
||||
case Shell.Powershell:
|
||||
}
|
||||
case Shell.Powershell: {
|
||||
const powershellConfigPath = path.join(os.homedir(), "Documents", "WindowsPowershell", "Microsoft.PowerShell_profile.ps1");
|
||||
await fsAsync.appendFile(powershellConfigPath, `\n${powershellScriptCommand()}`);
|
||||
await fsAsync.copyFile(
|
||||
path.join(__dirname, "..", "..", "shell", "key-bindings-powershell.ps1"),
|
||||
path.join(os.homedir(), ".sa", "key-bindings-powershell.ps1")
|
||||
path.join(os.homedir(), ".sa", "key-bindings-powershell.ps1"),
|
||||
);
|
||||
break;
|
||||
case Shell.Pwsh:
|
||||
}
|
||||
case Shell.Pwsh: {
|
||||
await fsAsync.appendFile(pwshConfigPath(), `\n${pwshScriptCommand()}`);
|
||||
await fsAsync.copyFile(path.join(__dirname, "..", "..", "shell", "key-bindings-pwsh.ps1"), path.join(os.homedir(), ".sa", "key-bindings-pwsh.ps1"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user