inshellisense使用说明
IDE style command line auto complete
以下inshellisense
简称为is
安装
1 | 如果还未安装node,推荐nvm方式先安装node |
安装中出现的npm WARN EBADENGINE required: { node: '>=18' },
不用担心,只是Fig规范推荐的18以上。is是支持16的,但推荐高版本
node<21
测试发现node21安装报错,原因是依赖的node-gyp不支持21。
使用
1 | 进入补全会话,进入后输入命令按空格可以唤起补全弹窗 |
- 如果没有正常进入,看下是否有报错
- 正常进入后没有报错但不会唤起补全弹窗,一般都是因为提示词PS1检测问题,目前官方没有提供排查文档。
- 个人遇到的场景是ZSH下的
powerlevel10k/powerlevel9k
会有问题,目前解决办法即更换主题
- 个人遇到的场景是ZSH下的
操作热键
目前inshellisense不支持自定义热键
Action | Keybinding |
---|---|
Accept Current Suggestion | tab |
View Next Suggestion | ↓ |
View Previous Suggestion | ↑ |
Dismiss Suggestions | esc |
支持Shell
1 | export enum Shell { |
项目说明
https://github.com/microsoft/inshellisense
技术栈
1 | "@withfig/autocomplete": "^2.633.0", # Fig补全规范 |
项目结构
1 | ├── shell |
程序逻辑
process(<=>pty<=>xtermjs)
用户输入命令is,进入自动补全模式
加载is配置配置文件
确定Shell类型
is
命令中用户可以指定Shell否则is中自动根据SHELL环境变量确定
初始化Shell配置
- 如果是Zsh,补充以下文件到临时目录下
1
2
3
4- shellIntegration-env.zsh
- shellIntegration-login.zsh
- shellIntegration-profile.zsh
- shellIntegration-rc.zsh- 如果是Bash,补充
bash-preexec.sh
到用户主目录
is中加载全量Fig规范
process.stdin.setRawMode
设置为true,确保每个按键字符都触发data事件执行清屏
node-pty开启一个伪终端,加载对应Shell配置,同时创建xterm无头终端客户端。
process.stdin.on(“data”)监听用户输入,之后不断写入pty
pty监听输入,然后显示回显数据,同时写入xterm中
xterm监听写入数据
根据数据中的OSC,计算提示词起止位置。命令管理器同步终端情况
补全管理器计算补全,确定是不是需要显示补全
补全命令模块做命令的词法分析,确定命令情况,之后生成补全
生成补全的依赖3点input,cwd,shell
1
2// input为当前的命令,this.#term.getCommandState().commandText,process.cwd()为当前路径
getSuggestions(input, process.cwd())字符监听时针对热键也会做对应的处理,比如tab则写入补全的命令:
process.stdout写入终端
补全计算逻辑
命令文本进行分析,确定token数组
1
2
3
4const lex = (command: string): CommandToken[] => {
...
return tokens;
};token数组第一个为rootToken,根据rootToken来获取补全文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const loadSpec = async (cmd: CommandToken[]): Promise<Fig.Spec | undefined> => {
const rootToken = cmd.at(0);
if (!rootToken?.complete) {
return;
}
if (loadedSpecs[rootToken.token]) {
return loadedSpecs[rootToken.token];
}
if (specSet[rootToken.token]) {
const spec = (await import(specSet[rootToken.token])).default;
loadedSpecs[rootToken.token] = spec;
return spec;
}
};token数组的最后一个Token根据是否包含/来确定是不是路径
token数组从第二个开始计算补全
补全筛选
Suggestion数据定义
1 | export type Suggestion = { |
调试
直接执行
npm ru debug
,VSC下开启Attach to Node Process ⌘
~/.inshellisense/inshellisense.log
可以查看日志
写在最后
- 个人觉得is这种设计方案下速度还行,但直接在终端中绘制补全也就带来问题即:位置计算错误的话,光标很容易位置错
- 期待is早日发正式