@microsoft/inshellisense 0.0.1-rc.19 → 0.0.1-rc.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/commands/root.js +1 -1
- package/build/index.js +0 -1
- package/build/isterm/pty.js +10 -1
- package/build/runtime/alias.js +2 -2
- package/build/ui/ui-doctor.js +29 -1
- package/build/ui/ui-root.js +2 -2
- package/build/utils/shell.js +33 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,7 +93,7 @@ You can customize the keybindings for inshellisense by adding a `bindings` secti
|
|
|
93
93
|
```toml
|
|
94
94
|
[bindings.acceptSuggestion]
|
|
95
95
|
key = "tab"
|
|
96
|
-
# shift and
|
|
96
|
+
# shift and ctrl are optional and default to false
|
|
97
97
|
shift = false
|
|
98
98
|
ctrl = false
|
|
99
99
|
|
package/build/commands/root.js
CHANGED
|
@@ -33,5 +33,5 @@ export const action = (program) => async (options) => {
|
|
|
33
33
|
await setupBashPreExec();
|
|
34
34
|
}
|
|
35
35
|
await loadAliases(shell);
|
|
36
|
-
await render(shell, options.test ?? false, options.login ?? false);
|
|
36
|
+
await render(program, shell, options.test ?? false, options.login ?? false);
|
|
37
37
|
};
|
package/build/index.js
CHANGED
|
@@ -26,7 +26,6 @@ program
|
|
|
26
26
|
.option("-c, --check", `check if shell is in an inshellisense session`)
|
|
27
27
|
.addOption(hiddenOption("-T, --test", "used to make e2e tests reproducible across machines"))
|
|
28
28
|
.option("-V, --verbose", `enable verbose logging`)
|
|
29
|
-
.showHelpAfterError("(add --help for additional information)")
|
|
30
29
|
.passThroughOptions();
|
|
31
30
|
program.addCommand(complete);
|
|
32
31
|
program.addCommand(uninstall);
|
package/build/isterm/pty.js
CHANGED
|
@@ -17,6 +17,7 @@ import log from "../utils/log.js";
|
|
|
17
17
|
import { gitBashPath } from "../utils/shell.js";
|
|
18
18
|
import styles from "ansi-styles";
|
|
19
19
|
import * as ansi from "../utils/ansi.js";
|
|
20
|
+
import which from "which";
|
|
20
21
|
const ISTermOnDataEvent = "data";
|
|
21
22
|
export class ISTerm {
|
|
22
23
|
pid;
|
|
@@ -282,10 +283,18 @@ export class ISTerm {
|
|
|
282
283
|
return lines.reverse().join(ansi.cursorNextLine);
|
|
283
284
|
}
|
|
284
285
|
}
|
|
285
|
-
export const spawn = async (options) => {
|
|
286
|
+
export const spawn = async (program, options) => {
|
|
286
287
|
const { shellTarget, shellArgs } = await convertToPtyTarget(options.shell, options.underTest, options.login);
|
|
288
|
+
if (!(await shellExists(shellTarget))) {
|
|
289
|
+
program.error(`shell not found on PATH: ${shellTarget}`, { exitCode: 1 });
|
|
290
|
+
}
|
|
287
291
|
return new ISTerm({ ...options, shellTarget, shellArgs });
|
|
288
292
|
};
|
|
293
|
+
const shellExists = async (shellTarget) => {
|
|
294
|
+
const fileExists = fs.existsSync(shellTarget);
|
|
295
|
+
const fileOnPath = await which(shellTarget, { nothrow: true });
|
|
296
|
+
return fileExists || fileOnPath != null;
|
|
297
|
+
};
|
|
289
298
|
const convertToPtyTarget = async (shell, underTest, login) => {
|
|
290
299
|
const platform = os.platform();
|
|
291
300
|
const shellTarget = shell == Shell.Bash && platform == "win32" ? await gitBashPath() : platform == "win32" ? `${shell}.exe` : shell;
|
package/build/runtime/alias.js
CHANGED
|
@@ -10,7 +10,7 @@ const platform = os.platform();
|
|
|
10
10
|
const executeShellCommand = await buildExecuteShellCommand(5000);
|
|
11
11
|
const loadBashAliases = async () => {
|
|
12
12
|
const shellTarget = platform == "win32" ? await gitBashPath() : Shell.Bash;
|
|
13
|
-
const { stdout, stderr, status } = await executeShellCommand({ command: shellTarget, args: ["-i", "-c", "alias"], cwd: process.cwd() });
|
|
13
|
+
const { stdout, stderr, status } = await executeShellCommand({ command: shellTarget, args: ["-i", "-c", "alias"], cwd: process.cwd(), env: { ISTERM: "1" } });
|
|
14
14
|
if (status !== 0) {
|
|
15
15
|
log.debug({ msg: "failed to load bash aliases", stderr, status });
|
|
16
16
|
return;
|
|
@@ -24,7 +24,7 @@ const loadBashAliases = async () => {
|
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
const loadZshAliases = async () => {
|
|
27
|
-
const { stdout, stderr, status } = await executeShellCommand({ command: Shell.Zsh, args: ["-i", "-c", "alias"], cwd: process.cwd() });
|
|
27
|
+
const { stdout, stderr, status } = await executeShellCommand({ command: Shell.Zsh, args: ["-i", "-c", "alias"], cwd: process.cwd(), env: { ISTERM: "1" } });
|
|
28
28
|
if (status !== 0) {
|
|
29
29
|
log.debug({ msg: "failed to load zsh aliases", stderr, status });
|
|
30
30
|
return;
|
package/build/ui/ui-doctor.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
-
import { checkLegacyConfigs, checkShellConfigs } from "../utils/shell.js";
|
|
4
|
+
import { checkLegacyConfigs, checkShellConfigPlugin, checkShellConfigs } from "../utils/shell.js";
|
|
5
5
|
export const render = async () => {
|
|
6
6
|
let errors = 0;
|
|
7
7
|
errors += await renderLegacyConfigIssues();
|
|
8
|
+
errors += await renderShellPluginIssues();
|
|
8
9
|
errors += renderShellConfigIssues();
|
|
9
10
|
process.exit(errors);
|
|
10
11
|
};
|
|
@@ -39,3 +40,30 @@ const renderShellConfigIssues = () => {
|
|
|
39
40
|
}
|
|
40
41
|
return 0;
|
|
41
42
|
};
|
|
43
|
+
const renderShellPluginIssues = async () => {
|
|
44
|
+
const { shellsWithoutPlugin, shellsWithBadPlugin } = await checkShellConfigPlugin();
|
|
45
|
+
if (shellsWithoutPlugin.length == 0) {
|
|
46
|
+
process.stdout.write(chalk.green("✓") + " all shells have plugins\n");
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
process.stderr.write(chalk.red("•") + " the following shells do not have the plugin installed:\n");
|
|
50
|
+
shellsWithoutPlugin.forEach((shell) => {
|
|
51
|
+
process.stderr.write(chalk.red(" - ") + shell + "\n");
|
|
52
|
+
});
|
|
53
|
+
process.stderr.write(chalk.yellow(" review the README to generate the missing shell plugins, this warning can be ignored if you prefer manual startup\n"));
|
|
54
|
+
}
|
|
55
|
+
if (shellsWithBadPlugin.length == 0) {
|
|
56
|
+
process.stdout.write(chalk.green("✓") + " all shells have correct plugins\n");
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
process.stderr.write(chalk.red("•") + " the following shells have plugins incorrectly installed:\n");
|
|
60
|
+
shellsWithBadPlugin.forEach((shell) => {
|
|
61
|
+
process.stderr.write(chalk.red(" - ") + shell + "\n");
|
|
62
|
+
});
|
|
63
|
+
process.stderr.write(chalk.yellow(" remove and regenerate the plugins according to the README, only whitespace can be after the shell plugins\n"));
|
|
64
|
+
}
|
|
65
|
+
if (shellsWithoutPlugin.length > 0 || shellsWithBadPlugin.length > 0) {
|
|
66
|
+
return 1;
|
|
67
|
+
}
|
|
68
|
+
return 0;
|
|
69
|
+
};
|
package/build/ui/ui-root.js
CHANGED
|
@@ -12,8 +12,8 @@ export const renderConfirmation = (live) => {
|
|
|
12
12
|
const statusMessage = live ? chalk.green("live") : chalk.red("not found");
|
|
13
13
|
return `inshellisense session [${statusMessage}]\n`;
|
|
14
14
|
};
|
|
15
|
-
export const render = async (shell, underTest, login) => {
|
|
16
|
-
const term = await isterm.spawn({ shell, rows: process.stdout.rows, cols: process.stdout.columns, underTest, login });
|
|
15
|
+
export const render = async (program, shell, underTest, login) => {
|
|
16
|
+
const term = await isterm.spawn(program, { shell, rows: process.stdout.rows, cols: process.stdout.columns, underTest, login });
|
|
17
17
|
const suggestionManager = new SuggestionManager(term, shell);
|
|
18
18
|
let hasActiveSuggestions = false;
|
|
19
19
|
let previousSuggestionsRows = 0;
|
package/build/utils/shell.js
CHANGED
|
@@ -12,6 +12,17 @@ import util from "node:util";
|
|
|
12
12
|
import childProcess from "node:child_process";
|
|
13
13
|
import log from "./log.js";
|
|
14
14
|
const exec = util.promisify(childProcess.exec);
|
|
15
|
+
const safeExec = async (command, options) => {
|
|
16
|
+
const defaultOptions = { timeout: 500, env: { ISTERM: "1" } };
|
|
17
|
+
try {
|
|
18
|
+
const { stdout, stderr } = await exec(command, { ...defaultOptions, ...options });
|
|
19
|
+
return { stdout, stderr };
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
log.debug({ msg: `error executing exec command: ${e}` });
|
|
23
|
+
return { stdout: undefined, stderr: undefined };
|
|
24
|
+
}
|
|
25
|
+
};
|
|
15
26
|
export var Shell;
|
|
16
27
|
(function (Shell) {
|
|
17
28
|
Shell["Bash"] = "bash";
|
|
@@ -64,14 +75,33 @@ export const checkLegacyConfigs = async () => {
|
|
|
64
75
|
}
|
|
65
76
|
return shellsWithLegacyConfig;
|
|
66
77
|
};
|
|
78
|
+
export const checkShellConfigPlugin = async () => {
|
|
79
|
+
const shellsWithoutPlugin = [];
|
|
80
|
+
const shellsWithBadPlugin = [];
|
|
81
|
+
for (const shell of supportedShells) {
|
|
82
|
+
const profilePath = await getProfilePath(shell);
|
|
83
|
+
if (profilePath != null && fs.existsSync(profilePath)) {
|
|
84
|
+
const profile = await fsAsync.readFile(profilePath, "utf8");
|
|
85
|
+
const profileContainsSource = profile.includes(getShellSourceCommand(shell));
|
|
86
|
+
const profileEndsWithSource = profile.trimEnd().endsWith(getShellSourceCommand(shell));
|
|
87
|
+
if (!profileContainsSource) {
|
|
88
|
+
shellsWithoutPlugin.push(shell);
|
|
89
|
+
}
|
|
90
|
+
else if (!profileEndsWithSource) {
|
|
91
|
+
shellsWithBadPlugin.push(shell);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { shellsWithoutPlugin, shellsWithBadPlugin };
|
|
96
|
+
};
|
|
67
97
|
const getProfilePath = async (shell) => {
|
|
68
98
|
switch (shell) {
|
|
69
99
|
case Shell.Bash:
|
|
70
100
|
return path.join(os.homedir(), ".bashrc");
|
|
71
101
|
case Shell.Powershell:
|
|
72
|
-
return (await
|
|
102
|
+
return (await safeExec(`echo $profile`, { shell })).stdout?.trim();
|
|
73
103
|
case Shell.Pwsh:
|
|
74
|
-
return (await
|
|
104
|
+
return (await safeExec(`echo $profile`, { shell })).stdout?.trim();
|
|
75
105
|
case Shell.Zsh:
|
|
76
106
|
return path.join(os.homedir(), ".zshrc");
|
|
77
107
|
case Shell.Fish:
|
|
@@ -79,7 +109,7 @@ const getProfilePath = async (shell) => {
|
|
|
79
109
|
case Shell.Xonsh:
|
|
80
110
|
return path.join(os.homedir(), ".xonshrc");
|
|
81
111
|
case Shell.Nushell:
|
|
82
|
-
return (await
|
|
112
|
+
return (await safeExec(`echo $nu.env-path`, { shell })).stdout?.trim();
|
|
83
113
|
}
|
|
84
114
|
};
|
|
85
115
|
export const createShellConfigs = async () => {
|