mirror of
https://github.com/wavetermdev/inshellisense.git
synced 2026-08-05 13:43:30 -07:00
feat: add option to hide prompt information during e2e tests (#168)
* feat: add option to hide prompt information during e2e tests Signed-off-by: Chapman Pendery <cpendery@vt.edu> * fix: drop hidden option header Signed-off-by: Chapman Pendery <cpendery@vt.edu> * fix: tests to use -T Signed-off-by: Chapman Pendery <cpendery@vt.edu> --------- Signed-off-by: Chapman Pendery <cpendery@vt.edu>
This commit is contained in:
@@ -23,37 +23,6 @@ jobs:
|
||||
|
||||
- run: npm run lint
|
||||
|
||||
- name: setup pwsh prompt
|
||||
shell: pwsh
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
New-Item -Path $profile -ItemType File -Force
|
||||
Set-Content $profile 'function prompt {'
|
||||
Add-Content $profile ' $prompt = "PS: $(get-date)> "'
|
||||
Add-Content $profile ' return "`e]6973;PS`a$prompt`e]6973;PE`a"'
|
||||
Add-Content $profile '}'
|
||||
|
||||
- name: setup powershell prompt
|
||||
if: matrix.os == 'windows-latest'
|
||||
shell: powershell
|
||||
run: |
|
||||
New-Item -Path $profile -ItemType File -Force
|
||||
Set-Content $profile 'function prompt {'
|
||||
Add-Content $profile ' $ESC = [char]27'
|
||||
Add-Content $profile ' $BEL = [char]7'
|
||||
Add-Content $profile ' $prompt = "PS: $(Get-Location)> "'
|
||||
Add-Content $profile ' return "$ESC]6973;PS$BEL$prompt$ESC]6973;PE$BEL"'
|
||||
Add-Content $profile '}'
|
||||
|
||||
- name: setup fish prompt
|
||||
if: matrix.os != 'windows-latest'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ~/.config/fish/functions && touch ~/.config/fish/functions/fish_prompt.fish
|
||||
echo "function fish_prompt -d \"Write out the prompt\"" >> ~/.config/fish/functions/fish_prompt.fish
|
||||
echo " printf '\033]6973;PS\007%s@%s %s%s%s > \033]6973;PE\007' $USER $hostname (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)" >> ~/.config/fish/functions/fish_prompt.fish
|
||||
echo "end" >> ~/.config/fish/functions/fish_prompt.fish
|
||||
|
||||
- name: setup zsh-autosuggestions
|
||||
if: matrix.os != 'windows-latest'
|
||||
shell: bash
|
||||
|
||||
@@ -18,4 +18,5 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
testPathIgnorePatterns: ["/node_modules/", "src/tests/ui/", ".tui-test/"],
|
||||
};
|
||||
|
||||
@@ -41,6 +41,9 @@ __is_update_cwd() {
|
||||
|
||||
__is_update_prompt() {
|
||||
__is_prior_prompt="$PS1"
|
||||
if [ $ISTERM_TESTING == "1" ]; then
|
||||
__is_prior_prompt = "> "
|
||||
fi
|
||||
PS1="%{$(__is_prompt_start)%}$PS1%{$(__is_prompt_end)%}"
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ fi
|
||||
__is_update_prompt() {
|
||||
if [[ "$__is_custom_PS1" == "" || "$__is_custom_PS1" != "$PS1" ]]; then
|
||||
__is_original_PS1=$PS1
|
||||
if [ $ISTERM_TESTING == "1" ]; then
|
||||
__is_original_PS1="> "
|
||||
fi
|
||||
__is_custom_PS1="\[$(__is_prompt_start)\]$__is_original_PS1\[$(__is_prompt_end)\]"
|
||||
export PS1="$__is_custom_PS1"
|
||||
fi
|
||||
|
||||
@@ -11,4 +11,9 @@ end
|
||||
function __is_update_cwd --on-event fish_prompt; set __is_cwd (__is_escape_value "$PWD"); printf "\e]6973;CWD;$__is_cwd\a"; end
|
||||
|
||||
__is_copy_function fish_prompt is_user_prompt
|
||||
|
||||
if [ "$ISTERM_TESTING" == "1" ]
|
||||
function is_user_prompt; printf '> '; end
|
||||
end
|
||||
|
||||
function fish_prompt; printf (__is_prompt_start); printf (is_user_prompt); printf (__is_prompt_end); end
|
||||
@@ -1,5 +1,12 @@
|
||||
$Global:__IsOriginalPrompt = $function:Prompt
|
||||
|
||||
function Global:__IsTestingPrompt() {
|
||||
return "PS > "
|
||||
}
|
||||
if ($env:ISTERM_TESTING -eq "1") {
|
||||
$Global:__IsOriginalPrompt = $function:__IsTestingPrompt
|
||||
}
|
||||
|
||||
function Global:__IS-Escape-Value([string]$value) {
|
||||
[regex]::Replace($value, '[\\\n;]', { param($match)
|
||||
-Join (
|
||||
|
||||
@@ -14,6 +14,7 @@ type RootCommandOptions = {
|
||||
shell: Shell | undefined;
|
||||
verbose: boolean | undefined;
|
||||
check: boolean | undefined;
|
||||
test: boolean | undefined;
|
||||
};
|
||||
|
||||
export const action = (program: Command) => async (options: RootCommandOptions) => {
|
||||
@@ -39,5 +40,5 @@ export const action = (program: Command) => async (options: RootCommandOptions)
|
||||
} else if (shell == Shell.Bash) {
|
||||
await setupBashPreExec();
|
||||
}
|
||||
await render(shell);
|
||||
await render(shell, options.test ?? false);
|
||||
};
|
||||
|
||||
+8
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
/* eslint-disable header/header */
|
||||
|
||||
import { Command } from "commander";
|
||||
import { Command, Option } from "commander";
|
||||
|
||||
import complete from "./commands/complete.js";
|
||||
import uninstall from "./commands/uninstall.js";
|
||||
@@ -14,6 +14,12 @@ import { getVersion } from "./utils/version.js";
|
||||
|
||||
const program = new Command();
|
||||
|
||||
const hiddenOption = (flags: string, description: string) => {
|
||||
const option = new Option(flags, description);
|
||||
option.hidden = true;
|
||||
return option;
|
||||
};
|
||||
|
||||
program
|
||||
.name("inshellisense")
|
||||
.description("IDE style command line auto complete")
|
||||
@@ -21,6 +27,7 @@ program
|
||||
.action(action(program))
|
||||
.option("-s, --shell <shell>", `shell to use for command execution, supported shells: ${supportedShells}`)
|
||||
.option("-c, --check", `check if shell is in an inshellisense session`)
|
||||
.addOption(hiddenOption("-T, --test", "used to make e2e tests reproducible across machines"))
|
||||
.option("-V, --verbose", `enable verbose logging`)
|
||||
.showHelpAfterError("(add --help for additional information)");
|
||||
|
||||
|
||||
+6
-3
@@ -25,6 +25,7 @@ type ISTermOptions = {
|
||||
cols: number;
|
||||
shell: Shell;
|
||||
shellArgs?: string[];
|
||||
underTest: boolean;
|
||||
};
|
||||
|
||||
export class ISTerm implements IPty {
|
||||
@@ -44,13 +45,13 @@ export class ISTerm implements IPty {
|
||||
readonly #commandManager: CommandManager;
|
||||
readonly #shell: Shell;
|
||||
|
||||
constructor({ shell, cols, rows, env, shellTarget, shellArgs }: ISTermOptions & { shellTarget: string }) {
|
||||
constructor({ shell, cols, rows, env, shellTarget, shellArgs, underTest }: ISTermOptions & { shellTarget: string }) {
|
||||
this.#pty = pty.spawn(shellTarget, shellArgs ?? [], {
|
||||
name: "xterm-256color",
|
||||
cols,
|
||||
rows,
|
||||
cwd: process.cwd(),
|
||||
env: { ...convertToPtyEnv(shell), ...env },
|
||||
env: { ...convertToPtyEnv(shell, underTest), ...env },
|
||||
});
|
||||
this.pid = this.#pty.pid;
|
||||
this.cols = this.#pty.cols;
|
||||
@@ -264,10 +265,11 @@ const convertToPtyTarget = async (shell: Shell) => {
|
||||
return { shellTarget, shellArgs };
|
||||
};
|
||||
|
||||
const convertToPtyEnv = (shell: Shell) => {
|
||||
const convertToPtyEnv = (shell: Shell, underTest: boolean) => {
|
||||
const env = {
|
||||
...process.env,
|
||||
ISTERM: "1",
|
||||
ISTERM_TESTING: underTest ? "1" : undefined,
|
||||
};
|
||||
switch (shell) {
|
||||
case Shell.Cmd: {
|
||||
@@ -278,5 +280,6 @@ const convertToPtyEnv = (shell: Shell) => {
|
||||
return { ...env, ZDOTDIR: zdotdir, USER_ZDOTDIR: userZdotdir };
|
||||
}
|
||||
}
|
||||
|
||||
return env;
|
||||
};
|
||||
|
||||
@@ -3,17 +3,14 @@
|
||||
|
||||
import os from "node:os";
|
||||
import isterm from "../../isterm";
|
||||
import { cursorBackward, IstermPromptEnd, IstermPromptStart } from "../../utils/ansi";
|
||||
import { cursorBackward } from "../../utils/ansi";
|
||||
import { Shell } from "../../utils/shell";
|
||||
|
||||
const windowsTest = os.platform() == "win32" ? test.skip : test.skip;
|
||||
const unixTest = os.platform() == "darwin" || os.platform() == "linux" ? test.skip : test.skip;
|
||||
|
||||
const bashEnv = { PS1: `${IstermPromptStart}\\u$ ${IstermPromptEnd}` };
|
||||
const zshEnv = { PROMPT: `%{${IstermPromptStart}%}%/ %# %{${IstermPromptEnd}%}` };
|
||||
|
||||
const runTerm = async (shell: Shell, input: string[], env?: { [key: string]: string | undefined }) => {
|
||||
const ptyProcess = await isterm.spawn({ shell, rows: process.stdout.rows, cols: process.stdout.columns, env });
|
||||
const ptyProcess = await isterm.spawn({ shell, rows: process.stdout.rows, cols: process.stdout.columns, env, underTest: true });
|
||||
await new Promise((r) => setTimeout(r, 1_000));
|
||||
for (const data of input) {
|
||||
ptyProcess.write(data);
|
||||
@@ -82,7 +79,7 @@ windowsTest(
|
||||
unixTest(
|
||||
"test bash on initial simple command input",
|
||||
async () => {
|
||||
const r = await runTerm(Shell.Bash, ["ls\r", "zsh"], bashEnv);
|
||||
const r = await runTerm(Shell.Bash, ["ls\r", "zsh"]);
|
||||
expect(r).toMatchSnapshot();
|
||||
},
|
||||
10000,
|
||||
@@ -91,7 +88,7 @@ unixTest(
|
||||
unixTest(
|
||||
"test zsh on initial simple command input",
|
||||
async () => {
|
||||
const r = await runTerm(Shell.Zsh, ["ls\r", "zsh"], zshEnv);
|
||||
const r = await runTerm(Shell.Zsh, ["ls\r", "zsh"]);
|
||||
expect(r).toMatchSnapshot();
|
||||
},
|
||||
10000,
|
||||
@@ -100,7 +97,7 @@ unixTest(
|
||||
unixTest(
|
||||
"test zsh on suggestion detection",
|
||||
async () => {
|
||||
const r = await runTerm(Shell.Zsh, ["ls -la\r", "l"], zshEnv);
|
||||
const r = await runTerm(Shell.Zsh, ["ls -la\r", "l"]);
|
||||
expect(r).toMatchSnapshot();
|
||||
},
|
||||
10000,
|
||||
|
||||
@@ -480,7 +480,7 @@ exports[`parseCommand noOptionsSuggestedDuringVariadicArg 1`] = `
|
||||
exports[`parseCommand optionsSuggestedAfterVariadicArg 1`] = `
|
||||
{
|
||||
"argumentDescription": undefined,
|
||||
"charactersToDrop": 1,
|
||||
"charactersToDrop": 2,
|
||||
"suggestions": [
|
||||
{
|
||||
"allNames": [
|
||||
@@ -494,22 +494,22 @@ exports[`parseCommand optionsSuggestedAfterVariadicArg 1`] = `
|
||||
},
|
||||
{
|
||||
"allNames": [
|
||||
"-@",
|
||||
"-L",
|
||||
],
|
||||
"description": "Display extended attribute keys and sizes in long (-l) output",
|
||||
"description": "Follow all symbolic links to final target and list the file or directory the link references rather than the link itself. This option cancels the -P option",
|
||||
"icon": "🔗",
|
||||
"insertValue": undefined,
|
||||
"name": "-@",
|
||||
"name": "-L",
|
||||
"priority": 50,
|
||||
},
|
||||
{
|
||||
"allNames": [
|
||||
"-1",
|
||||
"-l",
|
||||
],
|
||||
"description": "(The numeric digit \`\`one''.) Force output to be one entry per line. This is the default when output is not to a terminal",
|
||||
"description": "(The lowercase letter \`\`ell''.) List in long format. (See below.) A total sum for all the file sizes is output on a line before the long listing",
|
||||
"icon": "🔗",
|
||||
"insertValue": undefined,
|
||||
"name": "-1",
|
||||
"name": "-l",
|
||||
"priority": 50,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -13,7 +13,7 @@ const testData = [
|
||||
{ name: "exclusiveOnOption", command: "ag --affinity --no" },
|
||||
{ name: "providedSuggestion", command: "bw completion --shell " },
|
||||
{ name: "fullyTypedSuggestion", command: "ls -W" },
|
||||
{ name: "optionsSuggestedAfterVariadicArg", command: "ls item -", maxSuggestions: 3 },
|
||||
{ name: "optionsSuggestedAfterVariadicArg", command: "ls item -l", maxSuggestions: 3 },
|
||||
{ name: "noOptionsSuggestedDuringVariadicArg", command: "ls -W ite" },
|
||||
{ name: "providedArgDescription", command: "act completion bash -a " },
|
||||
{ name: "completedOptionWithArg", command: "act completion bash -a 'actor' " },
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@ export const renderConfirmation = (live: boolean): string => {
|
||||
return `inshellisense session [${statusMessage}]\n`;
|
||||
};
|
||||
|
||||
export const render = async (shell: Shell) => {
|
||||
const term = await isterm.spawn({ shell, rows: process.stdout.rows, cols: process.stdout.columns });
|
||||
export const render = async (shell: Shell, underTest: boolean) => {
|
||||
const term = await isterm.spawn({ shell, rows: process.stdout.rows, cols: process.stdout.columns, underTest });
|
||||
const suggestionManager = new SuggestionManager(term, shell);
|
||||
let hasActiveSuggestions = false;
|
||||
let previousSuggestionsRows = 0;
|
||||
|
||||
Reference in New Issue
Block a user