@microsoft/inshellisense 0.0.1-rc.21 → 0.0.1-rc.23

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.
Files changed (48) hide show
  1. package/package.json +11 -78
  2. package/CODE_OF_CONDUCT.md +0 -9
  3. package/LICENSE +0 -21
  4. package/README.md +0 -132
  5. package/SECURITY.md +0 -41
  6. package/SUPPORT.md +0 -13
  7. package/build/commands/complete.js +0 -16
  8. package/build/commands/doctor.js +0 -11
  9. package/build/commands/init.js +0 -24
  10. package/build/commands/root.js +0 -37
  11. package/build/commands/specs/list.js +0 -26
  12. package/build/commands/specs/root.js +0 -8
  13. package/build/commands/uninstall.js +0 -11
  14. package/build/index.js +0 -35
  15. package/build/isterm/commandManager.js +0 -184
  16. package/build/isterm/index.js +0 -4
  17. package/build/isterm/pty.js +0 -361
  18. package/build/runtime/alias.js +0 -66
  19. package/build/runtime/generator.js +0 -55
  20. package/build/runtime/model.js +0 -3
  21. package/build/runtime/parser.js +0 -133
  22. package/build/runtime/runtime.js +0 -282
  23. package/build/runtime/spec.js +0 -36
  24. package/build/runtime/suggestion.js +0 -232
  25. package/build/runtime/template.js +0 -50
  26. package/build/runtime/utils.js +0 -121
  27. package/build/ui/suggestionManager.js +0 -162
  28. package/build/ui/ui-doctor.js +0 -69
  29. package/build/ui/ui-root.js +0 -141
  30. package/build/ui/ui-uninstall.js +0 -9
  31. package/build/ui/utils.js +0 -57
  32. package/build/utils/ansi.js +0 -37
  33. package/build/utils/config.js +0 -99
  34. package/build/utils/log.js +0 -39
  35. package/build/utils/shell.js +0 -318
  36. package/build/utils/version.js +0 -13
  37. package/scripts/postinstall.js +0 -9
  38. package/shell/bash-preexec.sh +0 -380
  39. package/shell/shellIntegration-env.zsh +0 -12
  40. package/shell/shellIntegration-login.zsh +0 -9
  41. package/shell/shellIntegration-profile.zsh +0 -9
  42. package/shell/shellIntegration-rc.zsh +0 -66
  43. package/shell/shellIntegration.bash +0 -114
  44. package/shell/shellIntegration.fish +0 -27
  45. package/shell/shellIntegration.nu +0 -29
  46. package/shell/shellIntegration.ps1 +0 -26
  47. package/shell/shellIntegration.xsh +0 -31
  48. package/todo.md +0 -17
@@ -1,184 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import convert from "color-convert";
4
- import { getShellPromptRewrites, Shell } from "../utils/shell.js";
5
- import log from "../utils/log.js";
6
- export class CommandManager {
7
- #activeCommand;
8
- #terminal;
9
- #acceptedCommandLines;
10
- #maxCursorY;
11
- #shell;
12
- #promptRewrites;
13
- constructor(terminal, shell) {
14
- this.#terminal = terminal;
15
- this.#shell = shell;
16
- this.#activeCommand = {};
17
- this.#maxCursorY = 0;
18
- this.#acceptedCommandLines = new Set();
19
- this.#promptRewrites = getShellPromptRewrites(shell);
20
- this.#terminal.parser.registerCsiHandler({ final: "J" }, (params) => {
21
- if (params.at(0) == 3 || params.at(0) == 2) {
22
- this.handleClear();
23
- }
24
- return false;
25
- });
26
- }
27
- handlePromptStart() {
28
- this.#activeCommand = { promptStartMarker: this.#terminal.registerMarker(0), hasOutput: false, cursorTerminated: false };
29
- }
30
- handlePromptEnd() {
31
- if (this.#activeCommand.promptEndMarker != null)
32
- return;
33
- if (this.#hasBeenAccepted()) {
34
- this.#activeCommand = {};
35
- return;
36
- }
37
- this.#activeCommand.promptEndMarker = this.#terminal.registerMarker(0);
38
- if (this.#activeCommand.promptEndMarker?.line === this.#terminal.buffer.active.cursorY) {
39
- this.#activeCommand.promptEndX = this.#terminal.buffer.active.cursorX;
40
- }
41
- this.#activeCommand.promptText = this.#terminal.buffer.active.getLine(this.#activeCommand.promptEndMarker?.line ?? 0)?.translateToString(true);
42
- }
43
- #hasBeenAccepted() {
44
- const commandLine = this.#activeCommand.promptStartMarker?.line ?? -1;
45
- const hasBeenAccepted = this.#acceptedCommandLines.has(commandLine) && commandLine != -1;
46
- return this.#promptRewrites && hasBeenAccepted; // this is a prompt + command that was accepted and is now being re-written by the shell for display purposes (e.g. nu)
47
- }
48
- handleClear() {
49
- this.handlePromptStart();
50
- this.#maxCursorY = 0;
51
- this.#acceptedCommandLines.clear();
52
- }
53
- _getFgPaletteColor(cell) {
54
- if (cell?.isFgDefault())
55
- return 0;
56
- if (cell?.isFgPalette())
57
- return cell.getFgColor();
58
- if (cell?.isFgRGB())
59
- return convert.hex.ansi256(cell.getFgColor().toString(16));
60
- }
61
- _isSuggestion(cell) {
62
- const color = this._getFgPaletteColor(cell);
63
- const dim = (cell?.isDim() ?? 0) > 0;
64
- const italic = (cell?.isItalic() ?? 0) > 0;
65
- const dullColor = color == 8 || color == 7 || (color ?? 0) > 235 || (color == 15 && dim);
66
- const dimItalic = dim || italic;
67
- if (this.#shell == Shell.Pwsh || this.#shell == Shell.Powershell) {
68
- return dimItalic;
69
- }
70
- return dullColor;
71
- }
72
- getState() {
73
- return {
74
- promptText: this.#activeCommand.promptText,
75
- commandText: this.#activeCommand.commandText,
76
- suggestionsText: this.#activeCommand.suggestionsText,
77
- hasOutput: this.#activeCommand.hasOutput,
78
- cursorTerminated: this.#activeCommand.cursorTerminated,
79
- };
80
- }
81
- clearActiveCommand() {
82
- this.#acceptedCommandLines.add(this.#activeCommand.promptEndMarker?.line ?? -1);
83
- this.#activeCommand = {};
84
- }
85
- _getCommandLines() {
86
- const lines = [];
87
- let lineY = this.#activeCommand.promptEndMarker.line;
88
- let line = this.#terminal.buffer.active.getLine(this.#activeCommand.promptEndMarker.line);
89
- const absoluteY = this.#terminal.buffer.active.baseY + this.#terminal.buffer.active.cursorY;
90
- for (; lineY < this.#terminal.buffer.active.baseY + this.#terminal.rows;) {
91
- if (line)
92
- lines.push(line);
93
- lineY += 1;
94
- line = this.#terminal.buffer.active.getLine(lineY);
95
- const lineWrapped = line?.isWrapped;
96
- const cursorWrapped = absoluteY > lineY - 1;
97
- const wrapped = lineWrapped || cursorWrapped;
98
- if (!wrapped)
99
- break;
100
- }
101
- return lines;
102
- }
103
- _getCommandText(commandLines) {
104
- const absoluteY = this.#terminal.buffer.active.baseY + this.#terminal.buffer.active.cursorY;
105
- const cursorLine = Math.max(absoluteY - this.#activeCommand.promptEndMarker.line, 0);
106
- let preCursorCommand = "";
107
- let postCursorCommand = "";
108
- let suggestion = "";
109
- for (const [y, line] of commandLines.entries()) {
110
- const startX = y == 0 ? this.#activeCommand.promptText?.length ?? 0 : 0;
111
- for (let x = startX; x < this.#terminal.cols; x++) {
112
- if (postCursorCommand.endsWith(" "))
113
- break; // assume that a command that ends with 4 spaces is terminated, avoids capturing right prompts
114
- const cell = line.getCell(x);
115
- if (cell == null)
116
- continue;
117
- const chars = cell.getChars() == "" ? " " : cell.getChars();
118
- const beforeCursor = y < cursorLine || (y == cursorLine && x < this.#terminal.buffer.active.cursorX);
119
- const isCommand = !this._isSuggestion(cell) && suggestion.length == 0;
120
- if (isCommand && beforeCursor) {
121
- preCursorCommand += chars;
122
- }
123
- else if (isCommand) {
124
- postCursorCommand += chars;
125
- }
126
- else {
127
- suggestion += chars;
128
- }
129
- }
130
- }
131
- log.debug({ msg: "command text", preCursorCommand, postCursorCommand, suggestion });
132
- return { suggestion, preCursorCommand, postCursorCommand };
133
- }
134
- _getCommandOutputStatus(commandLines) {
135
- const outputLineY = this.#activeCommand.promptEndMarker.line + commandLines;
136
- const maxLineY = this.#terminal.buffer.active.baseY + this.#terminal.rows;
137
- if (outputLineY >= maxLineY)
138
- return false;
139
- const line = this.#terminal.buffer.active.getLine(outputLineY);
140
- let cell = undefined;
141
- for (let i = 0; i < this.#terminal.cols; i++) {
142
- cell = line?.getCell(i, cell);
143
- if (cell?.getChars() != "") {
144
- return true;
145
- }
146
- }
147
- return false;
148
- }
149
- termSync() {
150
- if (this.#activeCommand.promptEndMarker == null || this.#activeCommand.promptStartMarker == null) {
151
- return;
152
- }
153
- const globalCursorPosition = this.#terminal.buffer.active.baseY + this.#terminal.buffer.active.cursorY;
154
- this.#maxCursorY = Math.max(this.#maxCursorY, globalCursorPosition);
155
- if (globalCursorPosition < this.#activeCommand.promptStartMarker.line || globalCursorPosition < this.#maxCursorY) {
156
- this.handleClear();
157
- this.#activeCommand.promptEndMarker = this.#terminal.registerMarker(0);
158
- return;
159
- }
160
- if (this.#activeCommand.promptEndMarker == null)
161
- return;
162
- // if the prompt is set, now parse out the values from the terminal
163
- if (this.#activeCommand.promptText != null) {
164
- const commandLines = this._getCommandLines();
165
- const { suggestion, preCursorCommand, postCursorCommand } = this._getCommandText(commandLines);
166
- const command = preCursorCommand + postCursorCommand.trim();
167
- const cursorAtEndOfInput = postCursorCommand.trim() == "";
168
- const hasOutput = this._getCommandOutputStatus(commandLines.length);
169
- this.#activeCommand.persistentOutput = this.#activeCommand.hasOutput && hasOutput;
170
- this.#activeCommand.hasOutput = hasOutput;
171
- this.#activeCommand.suggestionsText = suggestion;
172
- this.#activeCommand.commandText = command;
173
- this.#activeCommand.cursorTerminated = cursorAtEndOfInput;
174
- }
175
- log.debug({
176
- msg: "cmd manager state",
177
- ...this.#activeCommand,
178
- promptEndMarker: this.#activeCommand.promptEndMarker?.line,
179
- promptStartMarker: this.#activeCommand.promptStartMarker?.line,
180
- cursorX: this.#terminal.buffer.active.cursorX,
181
- cursorY: globalCursorPosition,
182
- });
183
- }
184
- }
@@ -1,4 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import { spawn } from "./pty.js";
4
- export default { spawn };
@@ -1,361 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import { EventEmitter } from "node:events";
4
- import process from "node:process";
5
- import os from "node:os";
6
- import path from "node:path";
7
- import url from "node:url";
8
- import fs from "node:fs";
9
- import stripAnsi from "strip-ansi";
10
- import { Unicode11Addon } from "@xterm/addon-unicode11";
11
- import pty from "@homebridge/node-pty-prebuilt-multiarch";
12
- import { Shell, userZdotdir, zdotdir } from "../utils/shell.js";
13
- import { IsTermOscPs, IstermOscPt, IstermPromptStart, IstermPromptEnd } from "../utils/ansi.js";
14
- import xterm from "@xterm/headless";
15
- import { CommandManager } from "./commandManager.js";
16
- import log from "../utils/log.js";
17
- import { gitBashPath } from "../utils/shell.js";
18
- import styles from "ansi-styles";
19
- import * as ansi from "../utils/ansi.js";
20
- import which from "which";
21
- const ISTermOnDataEvent = "data";
22
- export class ISTerm {
23
- pid;
24
- cols;
25
- rows;
26
- process;
27
- handleFlowControl = false;
28
- onData;
29
- onExit;
30
- shellBuffer;
31
- cwd = "";
32
- #pty;
33
- #ptyEmitter;
34
- #term;
35
- #commandManager;
36
- #shell;
37
- constructor({ shell, cols, rows, env, shellTarget, shellArgs, underTest, login }) {
38
- this.#pty = pty.spawn(shellTarget, shellArgs ?? [], {
39
- name: "xterm-256color",
40
- cols,
41
- rows,
42
- cwd: process.cwd(),
43
- env: { ...convertToPtyEnv(shell, underTest, login), ...env },
44
- useConpty: true,
45
- useConptyDll: true,
46
- });
47
- this.pid = this.#pty.pid;
48
- this.cols = this.#pty.cols;
49
- this.rows = this.#pty.rows;
50
- this.process = this.#pty.process;
51
- const unicode11Addon = new Unicode11Addon();
52
- this.#term = new xterm.Terminal({ allowProposedApi: true, rows, cols });
53
- this.#term.loadAddon(unicode11Addon);
54
- this.#term.unicode.activeVersion = "11";
55
- this.#term.parser.registerOscHandler(IsTermOscPs, (data) => this._handleIsSequence(data));
56
- this.#commandManager = new CommandManager(this.#term, shell);
57
- this.#shell = shell;
58
- this.#ptyEmitter = new EventEmitter();
59
- this.#pty.onData((data) => {
60
- this.#term.write(data, () => {
61
- log.debug({ msg: "parsing data", data, bytes: Uint8Array.from([...data].map((c) => c.charCodeAt(0))) });
62
- this.#commandManager.termSync();
63
- this.#ptyEmitter.emit(ISTermOnDataEvent, data);
64
- });
65
- });
66
- this.onData = (listener) => {
67
- this.#ptyEmitter.on(ISTermOnDataEvent, listener);
68
- return {
69
- dispose: () => this.#ptyEmitter.removeListener(ISTermOnDataEvent, listener),
70
- };
71
- };
72
- this.onExit = this.#pty.onExit;
73
- }
74
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
75
- on(_event, _listener) {
76
- throw new Error("Method not implemented as deprecated in node-pty.");
77
- }
78
- _deserializeIsMessage(message) {
79
- return message.replaceAll(/\\(\\|x([0-9a-f]{2}))/gi, (_match, op, hex) => (hex ? String.fromCharCode(parseInt(hex, 16)) : op));
80
- }
81
- _sanitizedCwd(cwd) {
82
- if (cwd.match(/^['"].*['"]$/)) {
83
- cwd = cwd.substring(1, cwd.length - 1);
84
- }
85
- // Convert a drive prefix to windows style when using Git Bash
86
- if (os.platform() === "win32" && this.#shell == Shell.Bash && cwd && cwd.match(/^\/[A-z]{1}\//)) {
87
- cwd = `${cwd[1]}:\\` + cwd.substring(3, cwd.length);
88
- }
89
- // Make the drive letter uppercase on Windows (see vscode #9448)
90
- if (os.platform() === "win32" && cwd && cwd[1] === ":") {
91
- return cwd[0].toUpperCase() + cwd.substring(1);
92
- }
93
- return cwd;
94
- }
95
- _sanitizedPrompt(prompt) {
96
- // eslint-disable-next-line no-control-regex -- strip OSC control sequences
97
- const oscStrippedPrompt = prompt.replace(/\x1b\][0-9]+;.*\x07/g, "");
98
- return stripAnsi(oscStrippedPrompt);
99
- }
100
- _handleIsSequence(data) {
101
- const argsIndex = data.indexOf(";");
102
- const sequence = argsIndex === -1 ? data : data.substring(0, argsIndex);
103
- switch (sequence) {
104
- case IstermOscPt.PromptStarted:
105
- this.#commandManager.handlePromptStart();
106
- break;
107
- case IstermOscPt.PromptEnded:
108
- this.#commandManager.handlePromptEnd();
109
- break;
110
- case IstermOscPt.CurrentWorkingDirectory: {
111
- const cwd = data.split(";").at(1);
112
- if (cwd != null) {
113
- this.cwd = path.resolve(this._sanitizedCwd(this._deserializeIsMessage(cwd)));
114
- }
115
- break;
116
- }
117
- default:
118
- return false;
119
- }
120
- return true;
121
- }
122
- noop() {
123
- this.#ptyEmitter.emit(ISTermOnDataEvent, "");
124
- }
125
- resize(columns, rows) {
126
- this.cols = columns;
127
- this.rows = rows;
128
- this.#pty.resize(columns, rows);
129
- this.#term.resize(columns, rows);
130
- }
131
- clear() {
132
- this.#term.reset();
133
- this.#pty.clear();
134
- }
135
- kill(signal) {
136
- this.#pty.kill(signal);
137
- }
138
- pause() {
139
- this.#pty.pause();
140
- }
141
- resume() {
142
- this.#pty.resume();
143
- }
144
- write(data) {
145
- log.debug({ msg: "reading data", data, bytes: Uint8Array.from([...data].map((c) => c.charCodeAt(0))) });
146
- this.#pty.write(data);
147
- }
148
- getCommandState() {
149
- return this.#commandManager.getState();
150
- }
151
- getCursorState() {
152
- return {
153
- onLastLine: this.#term.buffer.active.cursorY >= this.#term.rows - 2,
154
- remainingLines: Math.max(this.#term.rows - 2 - this.#term.buffer.active.cursorY, 0),
155
- cursorX: this.#term.buffer.active.cursorX,
156
- cursorY: this.#term.buffer.active.cursorY,
157
- };
158
- }
159
- _sameAccent(baseCell, targetCell) {
160
- return (baseCell?.isBold() == targetCell?.isBold() &&
161
- baseCell?.isItalic() == targetCell?.isItalic() &&
162
- baseCell?.isUnderline() == targetCell?.isUnderline() &&
163
- baseCell?.extended.underlineStyle == targetCell?.extended.underlineStyle &&
164
- baseCell?.hasExtendedAttrs() == targetCell?.hasExtendedAttrs() &&
165
- baseCell?.isInverse() == targetCell?.isInverse() &&
166
- baseCell?.isBlink() == targetCell?.isBlink() &&
167
- baseCell?.isInvisible() == targetCell?.isInvisible() &&
168
- baseCell?.isDim() == targetCell?.isDim() &&
169
- baseCell?.isStrikethrough() == targetCell?.isStrikethrough());
170
- }
171
- _getAnsiAccents(cell) {
172
- if (cell == null)
173
- return "";
174
- let underlineAnsi = "";
175
- if (cell.isUnderline()) {
176
- if (cell.hasExtendedAttrs() && cell.extended.underlineStyle) {
177
- underlineAnsi = `\x1b[4:${cell.extended.underlineStyle}m`;
178
- }
179
- else {
180
- underlineAnsi = "\x1b[4m";
181
- }
182
- }
183
- const boldAnsi = cell.isBold() ? "\x1b[1m" : "";
184
- const dimAnsi = cell.isDim() ? "\x1b[2m" : "";
185
- const italicAnsi = cell.isItalic() ? "\x1b[3m" : "";
186
- const blinkAnsi = cell.isBlink() ? "\x1b[5m" : "";
187
- const inverseAnsi = cell.isInverse() ? "\x1b[7m" : "";
188
- const invisibleAnsi = cell.isInvisible() ? "\x1b[8m" : "";
189
- const strikethroughAnsi = cell.isStrikethrough() ? "\x1b[9m" : "";
190
- return boldAnsi + italicAnsi + underlineAnsi + inverseAnsi + dimAnsi + blinkAnsi + invisibleAnsi + strikethroughAnsi;
191
- }
192
- _sameColor(baseCell, targetCell) {
193
- return (baseCell?.getBgColorMode() == targetCell?.getBgColorMode() &&
194
- baseCell?.getBgColor() == targetCell?.getBgColor() &&
195
- baseCell?.getFgColorMode() == targetCell?.getFgColorMode() &&
196
- baseCell?.getFgColor() == targetCell?.getFgColor());
197
- }
198
- _getAnsiColors(cell) {
199
- if (cell == null)
200
- return "";
201
- let bgAnsi = "";
202
- cell.getBgColor;
203
- cell.getFgColor;
204
- if (cell.isBgDefault()) {
205
- bgAnsi = "\x1b[49m";
206
- }
207
- else if (cell.isBgPalette()) {
208
- bgAnsi = `\x1b[48;5;${cell.getBgColor()}m`;
209
- }
210
- else {
211
- bgAnsi = `\x1b[48;5;${styles.hexToAnsi256(cell.getBgColor().toString(16))}m`;
212
- }
213
- let fgAnsi = "";
214
- if (cell.isFgDefault()) {
215
- fgAnsi = "\x1b[39m";
216
- }
217
- else if (cell.isFgPalette()) {
218
- fgAnsi = `\x1b[38;5;${cell.getFgColor()}m`;
219
- }
220
- else {
221
- fgAnsi = `\x1b[38;5;${styles.hexToAnsi256(cell.getFgColor().toString(16))}m`;
222
- }
223
- return bgAnsi + fgAnsi;
224
- }
225
- clearCommand() {
226
- this.#commandManager.clearActiveCommand();
227
- }
228
- getCells(height, direction) {
229
- const currentCursorPosition = this.#term.buffer.active.cursorY + this.#term.buffer.active.baseY;
230
- const writeLine = (y) => {
231
- const line = this.#term.buffer.active.getLine(y);
232
- const ansiLine = [ansi.resetColor, ansi.resetLine];
233
- if (line == null)
234
- return "";
235
- let prevCell;
236
- for (let x = 0; x < line.length; x++) {
237
- const cell = line.getCell(x);
238
- const chars = cell?.getChars() ?? "";
239
- const sameColor = this._sameColor(prevCell, cell);
240
- const sameAccents = this._sameAccent(prevCell, cell);
241
- if (!sameColor || !sameAccents) {
242
- ansiLine.push(ansi.resetColor);
243
- }
244
- if (!sameColor) {
245
- ansiLine.push(this._getAnsiColors(cell));
246
- }
247
- if (!sameAccents) {
248
- ansiLine.push(this._getAnsiAccents(cell));
249
- }
250
- const isWide = prevCell?.getWidth() == 2 && cell?.getWidth() == 0;
251
- const cursorForward = isWide ? "" : ansi.cursorForward();
252
- ansiLine.push(chars == "" ? cursorForward : chars);
253
- prevCell = cell;
254
- }
255
- return ansiLine.join("");
256
- };
257
- const lines = [];
258
- if (direction == "above") {
259
- const startCursorPosition = currentCursorPosition - 1;
260
- const endCursorPosition = currentCursorPosition - 1 - height;
261
- for (let y = startCursorPosition; y > endCursorPosition; y--) {
262
- lines.push(writeLine(y));
263
- }
264
- }
265
- else {
266
- const startCursorPosition = currentCursorPosition + 1;
267
- const endCursorPosition = currentCursorPosition + 1 + height;
268
- for (let y = startCursorPosition; y < endCursorPosition; y++) {
269
- lines.push(writeLine(y));
270
- }
271
- }
272
- return lines.reverse().join(ansi.cursorNextLine);
273
- }
274
- }
275
- export const spawn = async (program, options) => {
276
- const { shellTarget, shellArgs } = await convertToPtyTarget(options.shell, options.underTest, options.login);
277
- if (!(await shellExists(shellTarget))) {
278
- program.error(`shell not found on PATH: ${shellTarget}`, { exitCode: 1 });
279
- }
280
- return new ISTerm({ ...options, shellTarget, shellArgs });
281
- };
282
- const shellExists = async (shellTarget) => {
283
- const fileExists = fs.existsSync(shellTarget);
284
- const fileOnPath = await which(shellTarget, { nothrow: true });
285
- return fileExists || fileOnPath != null;
286
- };
287
- const convertToPtyTarget = async (shell, underTest, login) => {
288
- const platform = os.platform();
289
- const shellTarget = shell == Shell.Bash && platform == "win32" ? await gitBashPath() : platform == "win32" ? `${shell}.exe` : shell;
290
- const shellFolderPath = path.join(path.dirname(url.fileURLToPath(import.meta.url)), "..", "..", "shell");
291
- let shellArgs = [];
292
- switch (shell) {
293
- case Shell.Bash:
294
- shellArgs = ["--init-file", path.join(shellFolderPath, "shellIntegration.bash")];
295
- break;
296
- case Shell.Powershell:
297
- case Shell.Pwsh:
298
- shellArgs = ["-noexit", "-command", `try { . "${path.join(shellFolderPath, "shellIntegration.ps1")}" } catch {}`];
299
- break;
300
- case Shell.Fish:
301
- shellArgs =
302
- platform == "win32"
303
- ? ["--init-command", `. "$(cygpath -u '${path.join(shellFolderPath, "shellIntegration.fish")}')"`]
304
- : ["--init-command", `. ${path.join(shellFolderPath, "shellIntegration.fish").replace(/(\s+)/g, "\\$1")}`];
305
- break;
306
- case Shell.Xonsh: {
307
- const sharedConfig = os.platform() == "win32" ? path.join("C:\\ProgramData", "xonsh", "xonshrc") : path.join("etc", "xonsh", "xonshrc");
308
- const userConfigs = [
309
- path.join(os.homedir(), ".xonshrc"),
310
- path.join(os.homedir(), ".config", "xonsh", "rc.xsh"),
311
- path.join(os.homedir(), ".config", "xonsh", "rc.d"),
312
- ];
313
- const configs = [sharedConfig, ...userConfigs].filter((config) => fs.existsSync(config));
314
- shellArgs = ["--rc", ...configs, path.join(shellFolderPath, "shellIntegration.xsh")];
315
- break;
316
- }
317
- case Shell.Nushell:
318
- shellArgs = ["-e", `source \`${path.join(shellFolderPath, "shellIntegration.nu")}\``];
319
- if (underTest)
320
- shellArgs.push("-n");
321
- break;
322
- }
323
- if (login) {
324
- switch (shell) {
325
- case Shell.Powershell:
326
- case Shell.Pwsh:
327
- shellArgs.unshift("-login");
328
- break;
329
- case Shell.Zsh:
330
- case Shell.Fish:
331
- case Shell.Xonsh:
332
- case Shell.Nushell:
333
- shellArgs.unshift("--login");
334
- break;
335
- }
336
- }
337
- return { shellTarget, shellArgs };
338
- };
339
- const convertToPtyEnv = (shell, underTest, login) => {
340
- const env = {
341
- ...process.env,
342
- ISTERM: "1",
343
- };
344
- if (underTest)
345
- env.ISTERM_TESTING = "1";
346
- if (login)
347
- env.ISTERM_LOGIN = "1";
348
- switch (shell) {
349
- case Shell.Cmd: {
350
- if (underTest) {
351
- return { ...env, PROMPT: `${IstermPromptStart}$G ${IstermPromptEnd}` };
352
- }
353
- const prompt = process.env.PROMPT ? process.env.PROMPT : "$P$G";
354
- return { ...env, PROMPT: `${IstermPromptStart}${prompt}${IstermPromptEnd}` };
355
- }
356
- case Shell.Zsh: {
357
- return { ...env, ZDOTDIR: zdotdir, USER_ZDOTDIR: userZdotdir };
358
- }
359
- }
360
- return env;
361
- };
@@ -1,66 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import log from "../utils/log.js";
4
- import { gitBashPath, Shell } from "../utils/shell.js";
5
- import { parseCommand } from "./parser.js";
6
- import { buildExecuteShellCommand } from "./utils.js";
7
- import os from "node:os";
8
- const loadedAliases = {};
9
- const platform = os.platform();
10
- const executeShellCommand = await buildExecuteShellCommand(5000);
11
- const loadBashAliases = async () => {
12
- const shellTarget = platform == "win32" ? await gitBashPath() : Shell.Bash;
13
- const { stdout, stderr, status } = await executeShellCommand({
14
- command: `'${shellTarget}'`,
15
- args: ["-i", "-c", "alias"],
16
- cwd: process.cwd(),
17
- env: { ISTERM: "1" },
18
- });
19
- if (status !== 0) {
20
- log.debug({ msg: "failed to load bash aliases", stderr, status });
21
- return;
22
- }
23
- return stdout
24
- .trim()
25
- .split("\n")
26
- .forEach((line) => {
27
- const [alias, ...commandSegments] = line.replace("alias ", "").replaceAll("'\\''", "'").split("=");
28
- loadedAliases[alias] = parseCommand(commandSegments.join("=").slice(1, -1) + " ", Shell.Bash);
29
- });
30
- };
31
- const loadZshAliases = async () => {
32
- const { stdout, stderr, status } = await executeShellCommand({ command: Shell.Zsh, args: ["-i", "-c", "alias"], cwd: process.cwd(), env: { ISTERM: "1" } });
33
- if (status !== 0) {
34
- log.debug({ msg: "failed to load zsh aliases", stderr, status });
35
- return;
36
- }
37
- return stdout
38
- .trim()
39
- .split("\n")
40
- .forEach((line) => {
41
- const [alias, ...commandSegments] = line.replaceAll("'\\''", "'").split("=");
42
- loadedAliases[alias] = parseCommand(commandSegments.join("=").slice(1, -1) + " ", Shell.Zsh);
43
- });
44
- };
45
- export const loadAliases = async (shell) => {
46
- switch (shell) {
47
- case Shell.Bash:
48
- await loadBashAliases();
49
- break;
50
- case Shell.Zsh:
51
- await loadZshAliases();
52
- break;
53
- }
54
- return [];
55
- };
56
- export const getAliasNames = () => Object.keys(loadedAliases);
57
- export const aliasExpand = (command) => {
58
- if (!command.at(0)?.complete)
59
- return command;
60
- const alias = loadedAliases[command.at(0)?.token ?? ""];
61
- if (alias) {
62
- log.debug({ msg: "expanding alias", alias, command: command.slice(1) });
63
- return [...alias, ...command.slice(1)];
64
- }
65
- return command;
66
- };
@@ -1,55 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import log from "../utils/log.js";
4
- import { runTemplates } from "./template.js";
5
- import { buildExecuteShellCommand } from "./utils.js";
6
- const getGeneratorContext = (cwd) => {
7
- return {
8
- environmentVariables: Object.fromEntries(Object.entries(process.env).filter((entry) => entry[1] != null)),
9
- currentWorkingDirectory: cwd,
10
- currentProcess: "",
11
- sshPrefix: "",
12
- isDangerous: false,
13
- searchTerm: "", // TODO: define search term
14
- };
15
- };
16
- // TODO: add support for caching, trigger, & getQueryTerm
17
- export const runGenerator = async (generator, tokens, cwd) => {
18
- // TODO: support trigger
19
- const { script, postProcess, scriptTimeout, splitOn, custom, template, filterTemplateSuggestions } = generator;
20
- const executeShellCommand = await buildExecuteShellCommand(scriptTimeout ?? 5000);
21
- const suggestions = [];
22
- try {
23
- if (script) {
24
- const shellInput = typeof script === "function" ? script(tokens) : script;
25
- const scriptOutput = Array.isArray(shellInput)
26
- ? await executeShellCommand({ command: shellInput.at(0) ?? "", args: shellInput.slice(1), cwd })
27
- : await executeShellCommand({ ...shellInput, cwd });
28
- const scriptStdout = scriptOutput.stdout.trim();
29
- if (postProcess) {
30
- suggestions.push(...postProcess(scriptStdout, tokens));
31
- }
32
- else if (splitOn) {
33
- suggestions.push(...scriptStdout.split(splitOn).map((s) => ({ name: s })));
34
- }
35
- }
36
- if (custom) {
37
- suggestions.push(...(await custom(tokens, executeShellCommand, getGeneratorContext(cwd))));
38
- }
39
- if (template != null) {
40
- const templateSuggestions = await runTemplates(template, cwd);
41
- if (filterTemplateSuggestions) {
42
- suggestions.push(...filterTemplateSuggestions(templateSuggestions));
43
- }
44
- else {
45
- suggestions.push(...templateSuggestions);
46
- }
47
- }
48
- return suggestions;
49
- }
50
- catch (e) {
51
- const err = typeof e === "string" ? e : e instanceof Error ? e.message : e;
52
- log.debug({ msg: "generator failed", err, script, splitOn, template });
53
- }
54
- return suggestions;
55
- };
@@ -1,3 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- export {};