Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add official init command for plugging inshellisense into shell config startups #229

Merged
merged 2 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ npm install -g @microsoft/inshellisense

After completing the installation, you can run `is` to start the autocomplete session for your desired shell. Additionally, inshellisense is also aliased under `inshellisense` after installation.

### Shell Plugin

If you'd like to automatically start inshellisense when you open your shell, run the respective command for your shell. After running the command, inshellisense will automatically open when you start any new shell session:

```shell
# bash
is init bash >> ~/.bashrc
```

### Usage

| Action | Command | Description |
Expand Down
23 changes: 23 additions & 0 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { Command } from "commander";
import { Shell, initSupportedShells as shells, getShellConfig } from "../utils/shell.js";

const supportedShells = shells.join(", ");

const action = (program: Command) => async (shell: string) => {
if (!shells.map((s) => s.valueOf()).includes(shell)) {
program.error(`Unsupported shell: '${shell}', supported shells: ${supportedShells}`, { exitCode: 1 });
}
const config = getShellConfig(shell as Shell);
process.stdout.write(`\n\n# ---------------- inshellisense shell plugin ----------------\n${config}`);
process.exit(0);
};

const cmd = new Command("init");
cmd.description(`generates shell configurations for the provided shell`);
cmd.argument("<shell>", `shell to generate configuration for, supported shells: ${supportedShells}`);
cmd.action(action(cmd));

export default cmd;
3 changes: 1 addition & 2 deletions src/commands/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ type RootCommandOptions = {
verbose: boolean | undefined;
check: boolean | undefined;
test: boolean | undefined;
parentTermExit: boolean | undefined;
};

export const action = (program: Command) => async (options: RootCommandOptions) => {
Expand Down Expand Up @@ -46,5 +45,5 @@ export const action = (program: Command) => async (options: RootCommandOptions)
await setupBashPreExec();
}
await loadAliases(shell);
await render(shell, options.test ?? false, options.parentTermExit ?? false);
await render(shell, options.test ?? false);
};
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Command, Option } from "commander";

import complete from "./commands/complete.js";
import uninstall from "./commands/uninstall.js";
import init from "./commands/init.js";
import { action, supportedShells } from "./commands/root.js";
import { getVersion } from "./utils/version.js";

Expand All @@ -27,12 +28,12 @@ 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`)
.option("--parent-term-exit", `when inshellisense is closed, kill the parent process`)
.addOption(hiddenOption("-T, --test", "used to make e2e tests reproducible across machines"))
.option("-V, --verbose", `enable verbose logging`)
.showHelpAfterError("(add --help for additional information)");

program.addCommand(complete);
program.addCommand(uninstall);
program.addCommand(init);

program.parse();
2 changes: 1 addition & 1 deletion src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type ExecuteShellCommandTTYResult = {
export const buildExecuteShellCommand =
(timeout: number): Fig.ExecuteCommandFunction =>
async ({ command, env, args, cwd }: Fig.ExecuteCommandInput): Promise<Fig.ExecuteCommandOutput> => {
const child = spawn(command, args, { cwd, env });
const child = spawn(command, args, { cwd, env: { ...env, ISTERM: "1" } });
setTimeout(() => child.kill("SIGKILL"), timeout);
let stdout = "";
let stderr = "";
Expand Down
5 changes: 1 addition & 4 deletions src/ui/ui-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const renderConfirmation = (live: boolean): string => {
return `inshellisense session [${statusMessage}]\n`;
};

export const render = async (shell: Shell, underTest: boolean, parentTermExit: boolean) => {
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;
Expand Down Expand Up @@ -140,9 +140,6 @@ export const render = async (shell: Shell, underTest: boolean, parentTermExit: b
});

term.onExit(({ exitCode }) => {
if (parentTermExit && process.ppid) {
process.kill(process.ppid);
}
process.exit(exitCode);
});
process.stdout.on("resize", () => {
Expand Down
12 changes: 12 additions & 0 deletions src/utils/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export const supportedShells = [
Shell.Nushell,
].filter((shell) => shell != null) as Shell[];

export const initSupportedShells = [Shell.Bash];

export const userZdotdir = process.env?.ZDOTDIR ?? os.homedir() ?? `~`;
export const zdotdir = path.join(os.tmpdir(), `is-zsh`);
const configFolder = ".inshellisense";
Expand Down Expand Up @@ -119,3 +121,13 @@ export const getPathSeperator = (shell: Shell) => (shell == Shell.Bash || shell

// nu fully re-writes the prompt every keystroke resulting in duplicate start/end sequences on the same line
export const getShellPromptRewrites = (shell: Shell) => shell == Shell.Nushell;

export const getShellConfig = (shell: Shell): string => {
switch (shell) {
case Shell.Bash:
return `if [[ -z "\${ISTERM}" && $- = *i* && $- != *c* ]]; then
is -s bash ; exit
fi`;
}
return "";
};
Loading