@microsoft/inshellisense 0.0.1-rc.2 → 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/LICENSE +21 -21
- package/README.md +80 -6
- package/SECURITY.md +41 -41
- package/build/commands/complete.js +16 -0
- package/build/commands/doctor.js +11 -0
- package/build/commands/init.js +24 -0
- package/build/commands/root.js +27 -30
- package/build/commands/specs/list.js +26 -0
- package/build/commands/specs/root.js +8 -0
- package/build/commands/uninstall.js +1 -1
- package/build/index.js +20 -7
- package/build/isterm/commandManager.js +290 -0
- package/build/isterm/index.js +4 -0
- package/build/isterm/pty.js +372 -0
- package/build/runtime/alias.js +61 -0
- package/build/runtime/generator.js +24 -11
- package/build/runtime/parser.js +86 -16
- package/build/runtime/runtime.js +103 -45
- package/build/runtime/suggestion.js +70 -22
- package/build/runtime/template.js +33 -18
- package/build/runtime/utils.js +111 -12
- package/build/ui/suggestionManager.js +162 -0
- package/build/ui/ui-doctor.js +69 -0
- package/build/ui/ui-root.js +130 -64
- package/build/ui/ui-uninstall.js +3 -5
- package/build/ui/utils.js +57 -0
- package/build/utils/ansi.js +37 -0
- package/build/utils/config.js +132 -0
- package/build/utils/log.js +39 -0
- package/build/utils/shell.js +316 -0
- package/package.json +39 -6
- package/scripts/postinstall.js +9 -0
- package/shell/bash-preexec.sh +380 -0
- package/shell/shellIntegration-env.zsh +12 -0
- package/shell/shellIntegration-login.zsh +9 -0
- package/shell/shellIntegration-profile.zsh +9 -0
- package/shell/shellIntegration-rc.zsh +66 -0
- package/shell/shellIntegration.bash +125 -0
- package/shell/shellIntegration.fish +28 -0
- package/shell/shellIntegration.nu +36 -0
- package/shell/shellIntegration.ps1 +27 -0
- package/shell/shellIntegration.xsh +37 -0
- package/build/commands/bind.js +0 -12
- package/build/ui/input.js +0 -55
- package/build/ui/suggestions.js +0 -84
- package/build/ui/ui-bind.js +0 -69
- package/build/utils/bindings.js +0 -216
- package/build/utils/cache.js +0 -21
- package/shell/key-bindings-powershell.ps1 +0 -27
- package/shell/key-bindings-pwsh.ps1 +0 -27
- package/shell/key-bindings.bash +0 -7
- package/shell/key-bindings.fish +0 -8
- package/shell/key-bindings.zsh +0 -10
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
$Global:__IsOriginalPrompt = $function:Prompt
|
|
2
|
+
|
|
3
|
+
function Global:__IsTestingPrompt() {
|
|
4
|
+
return "PS > "
|
|
5
|
+
}
|
|
6
|
+
if ($env:ISTERM_TESTING -eq "1") {
|
|
7
|
+
$Global:__IsOriginalPrompt = $function:__IsTestingPrompt
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function Global:__IS-Escape-Value([string]$value) {
|
|
11
|
+
[regex]::Replace($value, "[$([char]0x1b)$([char]0x07)\\\n;]", { param($match)
|
|
12
|
+
-Join (
|
|
13
|
+
[System.Text.Encoding]::UTF8.GetBytes($match.Value) | ForEach-Object { '\x{0:x2}' -f $_ }
|
|
14
|
+
)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function Global:Prompt() {
|
|
19
|
+
$Result = "$([char]0x1b)]6973;PS`a"
|
|
20
|
+
$OriginalPrompt += $Global:__IsOriginalPrompt.Invoke()
|
|
21
|
+
$Result += $OriginalPrompt
|
|
22
|
+
$Result += "$([char]0x1b)]6973;PE`a"
|
|
23
|
+
|
|
24
|
+
$Result += "$([char]0x1b)]6973;PROMPT;$(__IS-Escape-Value $OriginalPrompt)`a"
|
|
25
|
+
$Result += if ($pwd.Provider.Name -eq 'FileSystem') { "$([char]0x1b)]6973;CWD;$(__IS-Escape-Value $pwd.ProviderPath)`a" }
|
|
26
|
+
return $Result
|
|
27
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from xonsh.main import XSH
|
|
3
|
+
|
|
4
|
+
def __is_prompt_start() -> str:
|
|
5
|
+
return "\001" + "\x1b]6973;PS\x07"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def __is_prompt_end() -> str:
|
|
9
|
+
return "\001" + "\x1b]6973;PE\x07" + "\002"
|
|
10
|
+
|
|
11
|
+
def __is_escape_value(value: str) -> str:
|
|
12
|
+
byte_list = [bytes([byte]).decode("utf-8") for byte in list(value.encode("utf-8"))]
|
|
13
|
+
return "".join(
|
|
14
|
+
[
|
|
15
|
+
"\\x3b" if byte == ";" else "\\\\" if byte == "\\" else "\\x1b" if byte == "\x1b" else "\x0a" if byte == "\n"else "\\x07" if byte == "\x07" else byte
|
|
16
|
+
for byte in byte_list
|
|
17
|
+
]
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def __is_update_cwd() -> str:
|
|
21
|
+
return f"\x1b]6973;CWD;{__is_escape_value(os.getcwd())}\x07"
|
|
22
|
+
|
|
23
|
+
__is_original_prompt = $PROMPT
|
|
24
|
+
def __is_report_prompt() -> str:
|
|
25
|
+
prompt = ""
|
|
26
|
+
formatted_prompt = XSH.shell.prompt_formatter(__is_original_prompt)
|
|
27
|
+
prompt = "".join([text for _, text in XSH.shell.format_color(formatted_prompt)])
|
|
28
|
+
return f"\x1b]6973;PROMPT;{__is_escape_value(prompt)}\x07" + "\002"
|
|
29
|
+
|
|
30
|
+
$PROMPT_FIELDS['__is_prompt_start'] = __is_prompt_start
|
|
31
|
+
$PROMPT_FIELDS['__is_prompt_end'] = __is_prompt_end
|
|
32
|
+
$PROMPT_FIELDS['__is_update_cwd'] = __is_update_cwd
|
|
33
|
+
$PROMPT_FIELDS['__is_report_prompt'] = __is_report_prompt
|
|
34
|
+
if 'ISTERM_TESTING' in ${...}:
|
|
35
|
+
$PROMPT = "> "
|
|
36
|
+
|
|
37
|
+
$PROMPT = "{__is_prompt_start}{__is_update_cwd}{__is_report_prompt}" + $PROMPT + "{__is_prompt_end}"
|
package/build/commands/bind.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import { Command } from "commander";
|
|
4
|
-
import { supportedShells } from "../utils/bindings.js";
|
|
5
|
-
import { render } from "../ui/ui-bind.js";
|
|
6
|
-
const action = async () => {
|
|
7
|
-
await render();
|
|
8
|
-
};
|
|
9
|
-
const cmd = new Command("bind");
|
|
10
|
-
cmd.description(`adds keybindings to the selected shell: ${supportedShells.join(", ")}`);
|
|
11
|
-
cmd.action(action);
|
|
12
|
-
export default cmd;
|
package/build/ui/input.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import React, { useState, useEffect } from "react";
|
|
4
|
-
import { useInput, Text } from "ink";
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
const BlinkSpeed = 530;
|
|
7
|
-
const CursorColor = "#FFFFFF";
|
|
8
|
-
export default function Input({ value, setValue, prompt, activeSuggestion, tabCompletionDropSize, }) {
|
|
9
|
-
const [cursorLocation, setCursorLocation] = useState(value.length);
|
|
10
|
-
const [cursorBlink, setCursorBlink] = useState(true);
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
setTimeout(() => {
|
|
13
|
-
setCursorBlink(!cursorBlink);
|
|
14
|
-
}, BlinkSpeed);
|
|
15
|
-
}, [cursorBlink]);
|
|
16
|
-
// TODO: arrow key navigation shortcuts (emacs & vim modes)
|
|
17
|
-
useInput((input, key) => {
|
|
18
|
-
// TODO: handle delete better on unix systems: https://github.com/vadimdemedes/ink/issues/634
|
|
19
|
-
const windows = process.platform === "win32";
|
|
20
|
-
const backspaceKey = windows ? key.backspace : key.backspace || key.delete;
|
|
21
|
-
const deleteKey = windows ? key.delete : false;
|
|
22
|
-
if (backspaceKey) {
|
|
23
|
-
setValue([...value].slice(0, Math.max(cursorLocation - 1, 0)).join("") + [...value].slice(cursorLocation).join(""));
|
|
24
|
-
setCursorLocation(Math.max(cursorLocation - 1, 0));
|
|
25
|
-
}
|
|
26
|
-
else if (deleteKey) {
|
|
27
|
-
setValue([...value].slice(0, cursorLocation).join("") + [...value].slice(Math.min(value.length, cursorLocation + 1)).join(""));
|
|
28
|
-
}
|
|
29
|
-
else if (key.leftArrow) {
|
|
30
|
-
setCursorLocation(Math.max(cursorLocation - 1, 0));
|
|
31
|
-
}
|
|
32
|
-
else if (key.rightArrow) {
|
|
33
|
-
setCursorLocation(Math.min(cursorLocation + 1, value.length));
|
|
34
|
-
}
|
|
35
|
-
else if (key.tab) {
|
|
36
|
-
if (activeSuggestion) {
|
|
37
|
-
// TOOD: support insertValue
|
|
38
|
-
const newValue = [...value].slice(0, cursorLocation - tabCompletionDropSize).join("") + activeSuggestion.name + " ";
|
|
39
|
-
setValue(newValue);
|
|
40
|
-
setCursorLocation(newValue.length);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else if (input) {
|
|
44
|
-
setValue([...value].slice(0, cursorLocation).join("") + input + [...value].slice(cursorLocation).join(""));
|
|
45
|
-
setCursorLocation(cursorLocation + input.length);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
const cursoredCommand = value + " ";
|
|
49
|
-
const cursoredText = [...cursoredCommand].slice(0, cursorLocation).join("") +
|
|
50
|
-
(cursorBlink ? chalk.bgHex(CursorColor).inverse([...cursoredCommand].at(cursorLocation)) : [...cursoredCommand].at(cursorLocation)) +
|
|
51
|
-
[...cursoredCommand].slice(cursorLocation + 1).join("");
|
|
52
|
-
return (React.createElement(Text, null,
|
|
53
|
-
prompt,
|
|
54
|
-
cursoredText));
|
|
55
|
-
}
|
package/build/ui/suggestions.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import React, { useState, useCallback, useEffect } from "react";
|
|
4
|
-
import { Text, useInput, Box, measureElement } from "ink";
|
|
5
|
-
import wrapAnsi from "wrap-ansi";
|
|
6
|
-
const MaxSuggestions = 5;
|
|
7
|
-
const SuggestionWidth = 40;
|
|
8
|
-
const DescriptionWidth = 30;
|
|
9
|
-
const DescriptionMaxHeight = 6;
|
|
10
|
-
const BorderWidth = 2;
|
|
11
|
-
const ActiveSuggestionBackgroundColor = "#7D56F4";
|
|
12
|
-
function Description({ description }) {
|
|
13
|
-
wrapAnsi(description, DescriptionWidth, { hard: true });
|
|
14
|
-
if (description.length !== 0) {
|
|
15
|
-
return (React.createElement(Box, { flexDirection: "column" },
|
|
16
|
-
React.createElement(Box, { borderStyle: "single", width: DescriptionWidth },
|
|
17
|
-
React.createElement(Text, null, truncateDescription(description, DescriptionMaxHeight)))));
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function truncateDescription(description, maxHeight) {
|
|
21
|
-
const wrappedText = wrapAnsi(description, DescriptionWidth - BorderWidth, {
|
|
22
|
-
trim: false,
|
|
23
|
-
hard: true,
|
|
24
|
-
});
|
|
25
|
-
const lines = wrappedText.split("\n");
|
|
26
|
-
const truncatedLines = lines.slice(0, maxHeight);
|
|
27
|
-
if (lines.length > maxHeight) {
|
|
28
|
-
truncatedLines[maxHeight - 1] = [...truncatedLines[maxHeight - 1]].slice(0, -1).join("") + "…";
|
|
29
|
-
}
|
|
30
|
-
return truncatedLines.join("\n");
|
|
31
|
-
}
|
|
32
|
-
function SuggestionList({ suggestions, activeSuggestionIdx }) {
|
|
33
|
-
return (React.createElement(Box, { flexDirection: "column" },
|
|
34
|
-
React.createElement(Box, { borderStyle: "single", width: SuggestionWidth, flexDirection: "column" }, suggestions
|
|
35
|
-
.map((suggestion, idx) => {
|
|
36
|
-
const bgColor = idx === activeSuggestionIdx ? ActiveSuggestionBackgroundColor : undefined;
|
|
37
|
-
return (React.createElement(Box, { key: idx },
|
|
38
|
-
React.createElement(Text, { backgroundColor: bgColor, wrap: "truncate-end" }, `${suggestion.icon} ${suggestion.name}`.padEnd(SuggestionWidth - BorderWidth, " "))));
|
|
39
|
-
})
|
|
40
|
-
.filter((node) => node !== undefined))));
|
|
41
|
-
}
|
|
42
|
-
export default function Suggestions({ leftPadding, setActiveSuggestion, suggestions, }) {
|
|
43
|
-
const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(0);
|
|
44
|
-
const [windowWidth, setWindowWidth] = useState(500);
|
|
45
|
-
const page = Math.floor(activeSuggestionIndex / MaxSuggestions) + 1;
|
|
46
|
-
const pagedSuggestions = suggestions.filter((_, idx) => idx < page * MaxSuggestions && idx >= (page - 1) * MaxSuggestions);
|
|
47
|
-
const activePagedSuggestionIndex = activeSuggestionIndex % MaxSuggestions;
|
|
48
|
-
const activeDescription = pagedSuggestions.at(activePagedSuggestionIndex)?.description || "";
|
|
49
|
-
const wrappedPadding = leftPadding % windowWidth;
|
|
50
|
-
const maxPadding = activeDescription.length !== 0 ? windowWidth - SuggestionWidth - DescriptionWidth : windowWidth - SuggestionWidth;
|
|
51
|
-
const swapDescription = wrappedPadding > maxPadding;
|
|
52
|
-
const swappedPadding = swapDescription ? Math.max(wrappedPadding - DescriptionWidth, 0) : wrappedPadding;
|
|
53
|
-
const clampedLeftPadding = Math.min(Math.min(wrappedPadding, swappedPadding), maxPadding);
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
setActiveSuggestion(suggestions[activeSuggestionIndex]);
|
|
56
|
-
}, [activeSuggestionIndex, suggestions]);
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
if (suggestions.length <= activeSuggestionIndex) {
|
|
59
|
-
setActiveSuggestionIndex(Math.max(suggestions.length - 1, 0));
|
|
60
|
-
}
|
|
61
|
-
}, [suggestions]);
|
|
62
|
-
useInput((_, key) => {
|
|
63
|
-
if (key.upArrow) {
|
|
64
|
-
setActiveSuggestionIndex(Math.max(0, activeSuggestionIndex - 1));
|
|
65
|
-
}
|
|
66
|
-
if (key.downArrow) {
|
|
67
|
-
setActiveSuggestionIndex(Math.min(activeSuggestionIndex + 1, suggestions.length - 1));
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
const measureRef = useCallback((node) => {
|
|
71
|
-
if (node !== null) {
|
|
72
|
-
const { width } = measureElement(node);
|
|
73
|
-
setWindowWidth(width);
|
|
74
|
-
}
|
|
75
|
-
}, []);
|
|
76
|
-
if (suggestions.length === 0)
|
|
77
|
-
return React.createElement(React.Fragment, null);
|
|
78
|
-
return (React.createElement(Box, { ref: measureRef },
|
|
79
|
-
React.createElement(Box, { paddingLeft: clampedLeftPadding }, swapDescription ? (React.createElement(React.Fragment, null,
|
|
80
|
-
React.createElement(Description, { description: activeDescription }),
|
|
81
|
-
React.createElement(SuggestionList, { suggestions: pagedSuggestions, activeSuggestionIdx: activePagedSuggestionIndex }))) : (React.createElement(React.Fragment, null,
|
|
82
|
-
React.createElement(SuggestionList, { suggestions: pagedSuggestions, activeSuggestionIdx: activePagedSuggestionIndex }),
|
|
83
|
-
React.createElement(Description, { description: activeDescription }))))));
|
|
84
|
-
}
|
package/build/ui/ui-bind.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import React, { useEffect, useState } from "react";
|
|
4
|
-
import { Box, Text, render as inkRender, useInput, useApp } from "ink";
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
import { availableBindings, bind, supportedShells } from "../utils/bindings.js";
|
|
7
|
-
let uiResult = "";
|
|
8
|
-
function UI() {
|
|
9
|
-
const { exit } = useApp();
|
|
10
|
-
const [selectionIdx, setSelectionIdx] = useState(0);
|
|
11
|
-
const [loaded, setLoaded] = useState(false);
|
|
12
|
-
const [availableShells, setAvailableShells] = useState([]);
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
availableBindings().then((bindings) => {
|
|
15
|
-
if (bindings.length == 0) {
|
|
16
|
-
exit();
|
|
17
|
-
}
|
|
18
|
-
setAvailableShells(bindings);
|
|
19
|
-
setLoaded(true);
|
|
20
|
-
});
|
|
21
|
-
}, []);
|
|
22
|
-
useInput(async (_, key) => {
|
|
23
|
-
if (key.upArrow) {
|
|
24
|
-
setSelectionIdx(Math.max(0, selectionIdx - 1));
|
|
25
|
-
}
|
|
26
|
-
else if (key.downArrow) {
|
|
27
|
-
setSelectionIdx(Math.min(availableShells.length - 1, selectionIdx + 1));
|
|
28
|
-
}
|
|
29
|
-
else if (key.return) {
|
|
30
|
-
await bind(availableShells[selectionIdx]);
|
|
31
|
-
uiResult = availableShells[selectionIdx];
|
|
32
|
-
exit();
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
return (React.createElement(Box, { flexDirection: "column" },
|
|
36
|
-
React.createElement(Box, null,
|
|
37
|
-
React.createElement(Text, { bold: true }, "Select your desired shell for keybinding creation")),
|
|
38
|
-
React.createElement(Box, { flexDirection: "column" },
|
|
39
|
-
availableShells.map((shell, idx) => {
|
|
40
|
-
if (idx == selectionIdx) {
|
|
41
|
-
return (React.createElement(Text, { color: "cyan", underline: true, key: idx },
|
|
42
|
-
">",
|
|
43
|
-
" ",
|
|
44
|
-
shell));
|
|
45
|
-
}
|
|
46
|
-
return (React.createElement(Text, { key: idx },
|
|
47
|
-
" ",
|
|
48
|
-
shell));
|
|
49
|
-
}),
|
|
50
|
-
loaded
|
|
51
|
-
? supportedShells
|
|
52
|
-
.filter((s) => !availableShells.includes(s))
|
|
53
|
-
.map((shell, idx) => (React.createElement(Text, { color: "gray", key: idx },
|
|
54
|
-
" ",
|
|
55
|
-
shell,
|
|
56
|
-
" (already bound)")))
|
|
57
|
-
: null,
|
|
58
|
-
!loaded ? React.createElement(Text, null, "Loading...") : null)));
|
|
59
|
-
}
|
|
60
|
-
export const render = async () => {
|
|
61
|
-
const { waitUntilExit } = inkRender(React.createElement(UI, null));
|
|
62
|
-
await waitUntilExit();
|
|
63
|
-
if (uiResult.length !== 0) {
|
|
64
|
-
process.stdout.write("\n" + chalk.green("✓") + " successfully created new bindings \n");
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
process.stdout.write("\n");
|
|
68
|
-
}
|
|
69
|
-
};
|
package/build/utils/bindings.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import fsAsync from "node:fs/promises";
|
|
6
|
-
import fs from "node:fs";
|
|
7
|
-
import process from "node:process";
|
|
8
|
-
import url from "node:url";
|
|
9
|
-
import { exec } from "node:child_process";
|
|
10
|
-
import util from "node:util";
|
|
11
|
-
const execAsync = util.promisify(exec);
|
|
12
|
-
const __filename = url.fileURLToPath(import.meta.url);
|
|
13
|
-
const __dirname = path.dirname(__filename);
|
|
14
|
-
const cacheFolder = ".inshellisense";
|
|
15
|
-
export var Shell;
|
|
16
|
-
(function (Shell) {
|
|
17
|
-
Shell["Bash"] = "bash";
|
|
18
|
-
Shell["Powershell"] = "powershell";
|
|
19
|
-
Shell["Pwsh"] = "pwsh";
|
|
20
|
-
Shell["Zsh"] = "zsh";
|
|
21
|
-
Shell["Fish"] = "fish";
|
|
22
|
-
})(Shell || (Shell = {}));
|
|
23
|
-
export const supportedShells = [Shell.Bash, process.platform == "win32" ? Shell.Powershell : null, Shell.Pwsh, Shell.Zsh, Shell.Fish].filter((shell) => shell != null);
|
|
24
|
-
const bashScriptCommand = () => {
|
|
25
|
-
return `[ -f ~/${cacheFolder}/key-bindings.bash ] && source ~/${cacheFolder}/key-bindings.bash`;
|
|
26
|
-
};
|
|
27
|
-
const zshScriptCommand = () => {
|
|
28
|
-
return `[ -f ~/${cacheFolder}/key-bindings.zsh ] && source ~/${cacheFolder}/key-bindings.zsh`;
|
|
29
|
-
};
|
|
30
|
-
const fishScriptCommand = () => {
|
|
31
|
-
return `[ -f ~/${cacheFolder}/key-bindings.fish ] && source ~/${cacheFolder}/key-bindings.fish`;
|
|
32
|
-
};
|
|
33
|
-
const powershellScriptCommand = () => {
|
|
34
|
-
const bindingsPath = path.join(os.homedir(), cacheFolder, "key-bindings-powershell.ps1");
|
|
35
|
-
return `if(Test-Path '${bindingsPath}' -PathType Leaf){. ${bindingsPath}}`;
|
|
36
|
-
};
|
|
37
|
-
const pwshScriptCommand = () => {
|
|
38
|
-
const bindingsPath = path.join(os.homedir(), cacheFolder, "key-bindings-pwsh.ps1");
|
|
39
|
-
return `if(Test-Path '${bindingsPath}' -PathType Leaf){. ${bindingsPath}}`;
|
|
40
|
-
};
|
|
41
|
-
const pwshConfigPath = async () => {
|
|
42
|
-
const { stdout } = await execAsync("echo $profile", { shell: "pwsh" });
|
|
43
|
-
return stdout.trim();
|
|
44
|
-
};
|
|
45
|
-
const powershellConfigPath = async () => {
|
|
46
|
-
const { stdout } = await execAsync("echo $profile", { shell: "powershell" });
|
|
47
|
-
return stdout.trim();
|
|
48
|
-
};
|
|
49
|
-
export const availableBindings = async () => {
|
|
50
|
-
const cliConfigPath = path.join(os.homedir(), cacheFolder);
|
|
51
|
-
if (!fs.existsSync(cliConfigPath)) {
|
|
52
|
-
await fsAsync.mkdir(cliConfigPath);
|
|
53
|
-
}
|
|
54
|
-
const bindings = [];
|
|
55
|
-
const bashConfigPath = path.join(os.homedir(), ".bashrc");
|
|
56
|
-
if (!fs.existsSync(bashConfigPath)) {
|
|
57
|
-
bindings.push(Shell.Bash);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
const bashConfigContent = fsAsync.readFile(bashConfigPath, { encoding: "utf-8" });
|
|
61
|
-
if (!(await bashConfigContent).includes(bashScriptCommand())) {
|
|
62
|
-
bindings.push(Shell.Bash);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
const zshConfigPath = path.join(os.homedir(), ".zshrc");
|
|
66
|
-
if (!fs.existsSync(zshConfigPath)) {
|
|
67
|
-
bindings.push(Shell.Zsh);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
const zshConfigContent = fsAsync.readFile(zshConfigPath, { encoding: "utf-8" });
|
|
71
|
-
if (!(await zshConfigContent).includes(zshScriptCommand())) {
|
|
72
|
-
bindings.push(Shell.Zsh);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
const fishConfigPath = path.join(os.homedir(), ".config", "fish", "config.fish");
|
|
76
|
-
if (!fs.existsSync(fishConfigPath)) {
|
|
77
|
-
bindings.push(Shell.Fish);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
const fishConfigContent = fsAsync.readFile(fishConfigPath, { encoding: "utf-8" });
|
|
81
|
-
if (!(await fishConfigContent).includes(fishScriptCommand())) {
|
|
82
|
-
bindings.push(Shell.Fish);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const powershellResolvedConfigPath = await powershellConfigPath();
|
|
86
|
-
if (process.platform == "win32") {
|
|
87
|
-
if (!fs.existsSync(powershellResolvedConfigPath)) {
|
|
88
|
-
bindings.push(Shell.Powershell);
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
const powershellConfigContent = fsAsync.readFile(powershellResolvedConfigPath, { encoding: "utf-8" });
|
|
92
|
-
if (!(await powershellConfigContent).includes(powershellScriptCommand())) {
|
|
93
|
-
bindings.push(Shell.Powershell);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const pwshResolvedConfigPath = await pwshConfigPath();
|
|
98
|
-
if (!fs.existsSync(pwshResolvedConfigPath)) {
|
|
99
|
-
bindings.push(Shell.Pwsh);
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
const pwshConfigContent = fsAsync.readFile(pwshResolvedConfigPath, { encoding: "utf-8" });
|
|
103
|
-
if (!(await pwshConfigContent).includes(pwshScriptCommand())) {
|
|
104
|
-
bindings.push(Shell.Pwsh);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return bindings;
|
|
108
|
-
};
|
|
109
|
-
export const unbindAll = async () => {
|
|
110
|
-
try {
|
|
111
|
-
const bashConfigPath = path.join(os.homedir(), ".bashrc");
|
|
112
|
-
const bashConfig = (await fsAsync.readFile(bashConfigPath)).toString();
|
|
113
|
-
if (bashConfig.includes(bashScriptCommand())) {
|
|
114
|
-
const unboundBashConfig = bashConfig.toString().replace(bashScriptCommand(), "");
|
|
115
|
-
await fsAsync.writeFile(bashConfigPath, unboundBashConfig);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
/* empty */
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
const zshConfigPath = path.join(os.homedir(), ".zshrc");
|
|
123
|
-
const zshConfig = (await fsAsync.readFile(zshConfigPath)).toString();
|
|
124
|
-
if (zshConfig.includes(zshScriptCommand())) {
|
|
125
|
-
const unboundZshConfig = zshConfig.toString().replace(zshScriptCommand(), "");
|
|
126
|
-
await fsAsync.writeFile(zshConfigPath, unboundZshConfig);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
/* empty */
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
const fishConfigPath = path.join(os.homedir(), ".config", "fish", "config.fish");
|
|
134
|
-
const fishConfig = (await fsAsync.readFile(fishConfigPath)).toString();
|
|
135
|
-
if (fishConfig.includes(fishScriptCommand())) {
|
|
136
|
-
const unboundFishConfig = fishConfig.toString().replace(fishScriptCommand(), "");
|
|
137
|
-
await fsAsync.writeFile(fishConfigPath, unboundFishConfig);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
/* empty */
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
const powershellResolvedConfigPath = await powershellConfigPath();
|
|
145
|
-
const powershellConfig = (await fsAsync.readFile(powershellResolvedConfigPath)).toString();
|
|
146
|
-
if (powershellConfig.includes(powershellScriptCommand())) {
|
|
147
|
-
const unboundPowershellConfig = powershellConfig.toString().replace(powershellScriptCommand(), "");
|
|
148
|
-
await fsAsync.writeFile(powershellResolvedConfigPath, unboundPowershellConfig);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
/* empty */
|
|
153
|
-
}
|
|
154
|
-
try {
|
|
155
|
-
const pwshResolvedConfigPath = await pwshConfigPath();
|
|
156
|
-
const pwshConfig = (await fsAsync.readFile(pwshResolvedConfigPath)).toString();
|
|
157
|
-
if (pwshConfig.includes(pwshScriptCommand())) {
|
|
158
|
-
const unboundPwshConfig = pwshConfig.toString().replace(pwshScriptCommand(), "");
|
|
159
|
-
await fsAsync.writeFile(pwshResolvedConfigPath, unboundPwshConfig);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
/* empty */
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
export const deleteConfigFolder = async () => {
|
|
167
|
-
const cliConfigPath = path.join(os.homedir(), cacheFolder);
|
|
168
|
-
if (fs.existsSync(cliConfigPath)) {
|
|
169
|
-
fs.rmSync(cliConfigPath, { recursive: true });
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
const safeAppendFile = async (filepath, data) => {
|
|
173
|
-
if (!fs.existsSync(filepath)) {
|
|
174
|
-
await fsAsync.mkdir(path.dirname(filepath), { recursive: true });
|
|
175
|
-
await fsAsync.writeFile(filepath, data);
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
await fsAsync.appendFile(filepath, data);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
export const bind = async (shell) => {
|
|
182
|
-
const cliConfigPath = path.join(os.homedir(), cacheFolder);
|
|
183
|
-
if (!fs.existsSync(cliConfigPath)) {
|
|
184
|
-
await fsAsync.mkdir(cliConfigPath);
|
|
185
|
-
}
|
|
186
|
-
switch (shell) {
|
|
187
|
-
case Shell.Bash: {
|
|
188
|
-
const bashConfigPath = path.join(os.homedir(), ".bashrc");
|
|
189
|
-
await safeAppendFile(bashConfigPath, `\n${bashScriptCommand()}`);
|
|
190
|
-
await fsAsync.copyFile(path.join(__dirname, "..", "..", "shell", "key-bindings.bash"), path.join(os.homedir(), cacheFolder, "key-bindings.bash"));
|
|
191
|
-
break;
|
|
192
|
-
}
|
|
193
|
-
case Shell.Zsh: {
|
|
194
|
-
const zshConfigPath = path.join(os.homedir(), ".zshrc");
|
|
195
|
-
await safeAppendFile(zshConfigPath, `\n${zshScriptCommand()}`);
|
|
196
|
-
await fsAsync.copyFile(path.join(__dirname, "..", "..", "shell", "key-bindings.zsh"), path.join(os.homedir(), cacheFolder, "key-bindings.zsh"));
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
case Shell.Fish: {
|
|
200
|
-
const fishConfigPath = path.join(os.homedir(), ".config", "fish", "config.fish");
|
|
201
|
-
await safeAppendFile(fishConfigPath, `\n${fishScriptCommand()}`);
|
|
202
|
-
await fsAsync.copyFile(path.join(__dirname, "..", "..", "shell", "key-bindings.fish"), path.join(os.homedir(), cacheFolder, "key-bindings.fish"));
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
case Shell.Powershell: {
|
|
206
|
-
await safeAppendFile(await powershellConfigPath(), `\n${powershellScriptCommand()}`);
|
|
207
|
-
await fsAsync.copyFile(path.join(__dirname, "..", "..", "shell", "key-bindings-powershell.ps1"), path.join(os.homedir(), cacheFolder, "key-bindings-powershell.ps1"));
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
case Shell.Pwsh: {
|
|
211
|
-
await safeAppendFile(await pwshConfigPath(), `\n${pwshScriptCommand()}`);
|
|
212
|
-
await fsAsync.copyFile(path.join(__dirname, "..", "..", "shell", "key-bindings-pwsh.ps1"), path.join(os.homedir(), cacheFolder, "key-bindings-pwsh.ps1"));
|
|
213
|
-
break;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
};
|
package/build/utils/cache.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import fsAsync from "node:fs/promises";
|
|
6
|
-
import fs from "node:fs";
|
|
7
|
-
const cacheFolder = ".inshellisense";
|
|
8
|
-
const folderPath = path.join(os.homedir(), cacheFolder);
|
|
9
|
-
const cachePath = path.join(os.homedir(), cacheFolder, "inshellisense.cache");
|
|
10
|
-
export const saveCommand = async (command) => {
|
|
11
|
-
if (!fs.existsSync(folderPath)) {
|
|
12
|
-
await fsAsync.mkdir(folderPath);
|
|
13
|
-
}
|
|
14
|
-
await fsAsync.writeFile(cachePath, command.map((c, idx) => `${idx.toString().padStart(5)} ${c}`).join("\n"));
|
|
15
|
-
};
|
|
16
|
-
export const loadCommand = async () => {
|
|
17
|
-
if (!fs.existsSync(folderPath)) {
|
|
18
|
-
await fsAsync.mkdir(folderPath);
|
|
19
|
-
}
|
|
20
|
-
return fsAsync.readFile(cachePath, { encoding: "utf-8" });
|
|
21
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
Set-PSReadLineKeyHandler -Chord 'Ctrl+a' -ScriptBlock {
|
|
2
|
-
$command = $null
|
|
3
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$null)
|
|
4
|
-
|
|
5
|
-
$oldPrompt = $function:prompt
|
|
6
|
-
function prompt { "`r" }
|
|
7
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
|
|
8
|
-
$prompt = $oldPrompt
|
|
9
|
-
|
|
10
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::ClearKillRing()
|
|
11
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::BeginningOfLine()
|
|
12
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::KillLine()
|
|
13
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
|
|
14
|
-
|
|
15
|
-
$inshellisense = "$env:USERPROFILE\AppData\Roaming\npm\node_modules\@microsoft\inshellisense\build\index.js"
|
|
16
|
-
if ($command) {
|
|
17
|
-
Start-Process -NoNewWindow -Wait "node" "$inshellisense -c $command -s powershell"
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
Start-Process -NoNewWindow -Wait "node" "$inshellisense -s powershell"
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
$executedCommand = node $inshellisense --history
|
|
24
|
-
if ($executedCommand) {
|
|
25
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($executedCommand)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
Set-PSReadLineKeyHandler -Chord 'Ctrl+a' -ScriptBlock {
|
|
2
|
-
$command = $null
|
|
3
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$null)
|
|
4
|
-
|
|
5
|
-
$oldPrompt = $function:prompt
|
|
6
|
-
function prompt { "`r" }
|
|
7
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
|
|
8
|
-
$prompt = $oldPrompt
|
|
9
|
-
|
|
10
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::ClearKillRing()
|
|
11
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::BeginningOfLine()
|
|
12
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::KillLine()
|
|
13
|
-
|
|
14
|
-
$inshellisense = "$env:USERPROFILE\AppData\Roaming\npm\node_modules\@microsoft\inshellisense\build\index.js"
|
|
15
|
-
if ($command) {
|
|
16
|
-
Start-Process -NoNewWindow -Wait "node" "$inshellisense -c $command -s pwsh"
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
Start-Process -NoNewWindow -Wait "node" "$inshellisense -s pwsh"
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
$executedCommand = node $inshellisense --history
|
|
23
|
-
if ($executedCommand) {
|
|
24
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($executedCommand)
|
|
25
|
-
}
|
|
26
|
-
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
|
|
27
|
-
}
|
package/shell/key-bindings.bash
DELETED
package/shell/key-bindings.fish
DELETED
package/shell/key-bindings.zsh
DELETED