-
Notifications
You must be signed in to change notification settings - Fork 384
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: (alpha) support terminal intell
- Loading branch information
Showing
20 changed files
with
2,768 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
packages/terminal-next/src/browser/component/terminal-intell-command-controller.module.less
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
.suggestions { | ||
display: flex; | ||
flex-direction: column; | ||
background-color: var(--editorGroupHeader-tabsBackground); | ||
color: var(--ai-native-text-color-common); | ||
max-height: 350px; | ||
width: 500px; | ||
overflow-y: auto; | ||
position: absolute; | ||
bottom: 100%; | ||
left: 0; | ||
border-top-left-radius: 8px; | ||
border-top-right-radius: 8px; | ||
} | ||
|
||
.suggestionItem { | ||
padding: 6px 10px 6px 16px; | ||
cursor: pointer; | ||
} | ||
|
||
.suggestionItemContainer { | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
|
||
.suggestionDesc { | ||
font-size: 12px; | ||
} | ||
|
||
.suggestionCmd { | ||
font-size: 12px; | ||
opacity: 0.6; | ||
} | ||
|
||
.suggestionItem:hover { | ||
filter: brightness(110%); | ||
background-color: var(--selection-background); | ||
} |
119 changes: 119 additions & 0 deletions
119
packages/terminal-next/src/browser/component/terminal-intell-command-controller.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
|
||
import { Emitter } from '@opensumi/ide-core-common'; | ||
|
||
import styles from './terminal-intell-command-controller.module.less'; | ||
|
||
export interface SmartCommandDesc { | ||
description: string; | ||
command: string; | ||
} | ||
|
||
// 支持键盘选择的列表 | ||
export const KeyboardSelectableList = (props: { | ||
items: { description: string; command: string }[]; | ||
handleSuggestionClick: (command: string) => void; | ||
controller?: Emitter<string>; | ||
noListen?: boolean; | ||
}) => { | ||
const { items, handleSuggestionClick, noListen = false, controller } = props; | ||
// 选中项的索引,默认为最后一个 | ||
const [selectedIndex, setSelectedIndex] = useState(-1); | ||
|
||
// 处理键盘事件 | ||
const handleKeyPress = (event: KeyboardEvent) => { | ||
switch (event.key) { | ||
case 'ArrowUp': // 上键 | ||
setSelectedIndex((prevIndex) => Math.max(prevIndex - 1, 0)); | ||
break; | ||
case 'ArrowDown': // 下键 | ||
setSelectedIndex((prevIndex) => | ||
Math.min(prevIndex + 1, items.length - 1), | ||
); | ||
break; | ||
case 'Enter': // 回车键 | ||
if (items[selectedIndex]) { | ||
handleSuggestionClick(items[selectedIndex].command); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
}; | ||
|
||
// 添加全局键盘事件监听器 | ||
useEffect(() => { | ||
if (noListen) {return;} | ||
window.addEventListener('keydown', handleKeyPress); | ||
return () => { | ||
window.removeEventListener('keydown', handleKeyPress); | ||
}; | ||
}, [items, selectedIndex]); | ||
|
||
useEffect(() => { | ||
if (!controller) {return;} | ||
const disposable = controller.event((e: string) => { | ||
if (e === 'ArrowUp') { | ||
setSelectedIndex((prevIndex) => Math.max(prevIndex - 1, 0)); | ||
} | ||
if (e === 'ArrowDown' || e === 'Tab') { | ||
setSelectedIndex((prevIndex) => | ||
Math.min(prevIndex + 1, items.length - 1), | ||
); | ||
} | ||
if (e === 'Enter') { | ||
if (items[selectedIndex]) { | ||
handleSuggestionClick(items[selectedIndex].command); | ||
} | ||
} | ||
}); | ||
|
||
return () => { | ||
disposable.dispose(); | ||
}; | ||
}, [controller, selectedIndex, items]); | ||
|
||
useEffect(() => { | ||
// HACK 定位到顶部 | ||
setSelectedIndex(0); | ||
}, [items]); | ||
|
||
return ( | ||
<div className={styles.suggestions}> | ||
{items.map((cmd, index) => ( | ||
<div | ||
key={index} | ||
className={styles.suggestionItem} | ||
style={{ backgroundColor: index === selectedIndex ? 'var(--selection-background)' : '' }} | ||
onClick={() => handleSuggestionClick(cmd.command)} | ||
> | ||
<div className={styles.suggestionItemContainer}> | ||
<div className={styles.suggestionDesc}>{cmd.description}</div> | ||
<div className={styles.suggestionCmd}>{cmd.command}</div> | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
); | ||
}; | ||
|
||
export const TerminalIntellCommandController = (props: { | ||
suggestions: SmartCommandDesc[]; | ||
controller: Emitter<string>; | ||
onSuggestion: (suggestion: string) => void; | ||
}) => { | ||
const { suggestions, controller, onSuggestion } = props; | ||
|
||
return ( | ||
<div style={{ position: 'relative' }}> | ||
{suggestions.length > 0 && ( | ||
<KeyboardSelectableList | ||
items={suggestions} | ||
controller={controller} | ||
handleSuggestionClick={onSuggestion} | ||
noListen | ||
/> | ||
)} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
packages/terminal-next/src/browser/contribution/terminal.intell.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Autowired } from '@opensumi/di'; | ||
import { ClientAppContribution, Domain } from '@opensumi/ide-core-browser'; | ||
import { | ||
MaybePromise, | ||
} from '@opensumi/ide-core-common'; | ||
|
||
import { IntellTerminalService } from '../intell/intell-terminal.service'; | ||
|
||
@Domain(ClientAppContribution) | ||
export class TerminalIntellContribution implements ClientAppContribution { | ||
|
||
@Autowired(IntellTerminalService) | ||
intellTerminalService: IntellTerminalService; | ||
|
||
onDidStart(): MaybePromise<void> { | ||
this.intellTerminalService.active(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
## 终端的智能补全能力 | ||
|
||
终端的智能补全能力是指终端在输入命令时,能够根据用户的输入,自动提示可能的命令或参数,交互方式类似于编程时的语言服务。 | ||
|
||
此功能可以增加用户使用终端时的易用性。 | ||
|
||
## 功能建设 | ||
此功能目前依然处于 Alpha 的早期实验版本,这里列举需要讨论或者处理的问题: | ||
|
||
- [ ] 补全设计优化:目前的设计主要服务于功能验证,因此 UI 看起来很简陋,需要做后续的优化 | ||
- [ ] 补全交互方式优化:比如说 上下键选择,Tab 确认。或者 Tab 或者 上下键 选择,Enter 确认 | ||
- [ ] Generator 补全支持,目前还不支持调用命令的 补全,因为是基于前端做的,可能要做个前后端通信 | ||
- [ ] 渲染方式优化,目前是直接渲染在 Xterm.js Decorations 上面的,考虑做一个全局 DOM,然后通过 DOM Align + Xterm.js Decoration 来做生命周期绑定和位置绑定 | ||
- [ ] 讨论是否需要转移补全逻辑到 Node.js | ||
- [ ] 把基于 Fig 打包 bundle 的逻辑转移到 OpenSumi 这边 | ||
- [ ] CodeStyle 处理,目前没有对从 inShellisense 项目的代码做处理,考虑到未来比较方便更新代码,不过这块要看看是不是要格式化一下代码什么的 | ||
|
||
## 开源项目依赖 | ||
感谢开源项目提供的灵感和相关能力支持: | ||
|
||
https://github.com/withfig/autocomplete | ||
|
||
https://github.com/microsoft/inshellisense |
Oops, something went wrong.