refactor: 终端操作抽象.
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 终端右键菜单 -->
|
<!-- 终端右键菜单 -->
|
||||||
<a-dropdown class="terminal-context-menu"
|
<a-dropdown class="terminal-context-menu"
|
||||||
trigger="contextMenu"
|
|
||||||
:popup-max-height="false"
|
:popup-max-height="false"
|
||||||
|
trigger="contextMenu"
|
||||||
position="bl"
|
position="bl"
|
||||||
alignPoint>
|
alignPoint>
|
||||||
<!-- 终端插槽 -->
|
<!-- 终端插槽 -->
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
// 发送命令
|
// 发送命令
|
||||||
const writeCommand = (value: string) => {
|
const writeCommand = (value: string) => {
|
||||||
if (session.value?.canWrite) {
|
if (session.value?.canWrite) {
|
||||||
session.value.pasteTrimEnd(value);
|
session.value?.handler.pasteTrimEnd(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -125,8 +125,7 @@
|
|||||||
|
|
||||||
// 执行终端操作
|
// 执行终端操作
|
||||||
const doTerminalHandle = (handle: string) => {
|
const doTerminalHandle = (handle: string) => {
|
||||||
const handler = session.value?.handler[handle as keyof ITerminalSessionHandler] as () => void;
|
session.value?.handler.invokeHandle.call(session.value?.handler, handle);
|
||||||
handler && handler.call(session.value?.handler);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 右侧操作
|
// 右侧操作
|
||||||
@@ -152,7 +151,7 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 会话
|
// 关闭会话
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
sessionManager.closeSession(props.tab.key);
|
sessionManager.closeSession(props.tab.key);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { TerminalPreference } from '@/store/modules/terminal/types';
|
import type { TerminalInteractSetting, TerminalShortcutKey } from '@/store/modules/terminal/types';
|
||||||
import type { ITerminalSession, ITerminalSessionHandler, ITerminalTabManager, TerminalDomRef } from '../types/terminal.type';
|
import type { ITerminalSession, ITerminalSessionHandler, ITerminalTabManager, TerminalDomRef } from '../types/terminal.type';
|
||||||
import type { Terminal } from 'xterm';
|
import type { Terminal } from 'xterm';
|
||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
@@ -15,7 +15,9 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler {
|
|||||||
|
|
||||||
private readonly session: ITerminalSession;
|
private readonly session: ITerminalSession;
|
||||||
|
|
||||||
private readonly preference: TerminalPreference;
|
private readonly interactSetting: TerminalInteractSetting;
|
||||||
|
|
||||||
|
private readonly shortcutKeys: Array<TerminalShortcutKey>;
|
||||||
|
|
||||||
private readonly tabManager: ITerminalTabManager;
|
private readonly tabManager: ITerminalTabManager;
|
||||||
|
|
||||||
@@ -25,7 +27,71 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler {
|
|||||||
this.inst = session.inst;
|
this.inst = session.inst;
|
||||||
this.domRef = domRef;
|
this.domRef = domRef;
|
||||||
const { preference, tabManager } = useTerminalStore();
|
const { preference, tabManager } = useTerminalStore();
|
||||||
this.preference = preference;
|
this.interactSetting = preference.interactSetting;
|
||||||
|
// this.shortcutKeys = preference.shortcutSetting.keys;
|
||||||
|
this.shortcutKeys = [
|
||||||
|
{
|
||||||
|
option: 'copy',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'C'
|
||||||
|
}, {
|
||||||
|
option: 'paste',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'V'
|
||||||
|
}, {
|
||||||
|
option: 'toTop',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'ArrowUp'
|
||||||
|
}, {
|
||||||
|
option: 'toBottom',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'ArrowDown'
|
||||||
|
}, {
|
||||||
|
option: 'selectAll',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'A'
|
||||||
|
}, {
|
||||||
|
option: 'search',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'F'
|
||||||
|
}, {
|
||||||
|
option: 'fontSizePlus',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: '+'
|
||||||
|
}, {
|
||||||
|
option: 'fontSizeSubtract',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: '_'
|
||||||
|
}, {
|
||||||
|
option: 'commandEditor',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'O'
|
||||||
|
}, {
|
||||||
|
option: 'close',
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
altKey: false,
|
||||||
|
key: 'W'
|
||||||
|
}
|
||||||
|
];
|
||||||
this.tabManager = tabManager;
|
this.tabManager = tabManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +99,7 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler {
|
|||||||
enabledStatus(option: string): boolean {
|
enabledStatus(option: string): boolean {
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'paste':
|
case 'paste':
|
||||||
|
case 'pasteTrimEnd':
|
||||||
case 'interrupt':
|
case 'interrupt':
|
||||||
case 'enter':
|
case 'enter':
|
||||||
case 'commandEditor':
|
case 'commandEditor':
|
||||||
@@ -44,12 +111,41 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 调用处理方法
|
||||||
|
invokeHandle(option: string) {
|
||||||
|
// 检测启用状态
|
||||||
|
if (!this.enabledStatus(option)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 调用实际处理方法
|
||||||
|
const handler = this[option as keyof this] as () => void;
|
||||||
|
handler && handler.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发快捷键
|
||||||
|
triggerShortcutKey(e: KeyboardEvent): boolean {
|
||||||
|
// 检测触发的快捷键
|
||||||
|
const key = this.shortcutKeys.find(key => {
|
||||||
|
return key.key === e.key
|
||||||
|
&& key.altKey === e.altKey
|
||||||
|
&& key.shiftKey === e.shiftKey
|
||||||
|
&& key.ctrlKey === e.ctrlKey;
|
||||||
|
});
|
||||||
|
if (key) {
|
||||||
|
// 调用处理方法
|
||||||
|
this.invokeHandle.call(this, key.option);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 复制选中
|
// 复制选中
|
||||||
copy() {
|
copy() {
|
||||||
let selection = this.inst.getSelection();
|
let selection = this.inst.getSelection();
|
||||||
if (selection) {
|
if (selection) {
|
||||||
// 去除尾部空格
|
// 去除尾部空格
|
||||||
if (this.preference.interactSetting.copyAutoTrim) {
|
if (this.interactSetting.copyAutoTrim) {
|
||||||
selection = selection.trimEnd();
|
selection = selection.trimEnd();
|
||||||
}
|
}
|
||||||
// 复制
|
// 复制
|
||||||
@@ -61,22 +157,18 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler {
|
|||||||
|
|
||||||
// 粘贴
|
// 粘贴
|
||||||
paste() {
|
paste() {
|
||||||
if (this.enabledStatus('paste')) {
|
readText().then(s => this.pasteTrimEnd(s));
|
||||||
readText().then(s => this.pasteTrimEnd(s));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 粘贴并且去除尾部空格 (如果配置)
|
// 粘贴并且去除尾部空格 (如果配置)
|
||||||
pasteTrimEnd(value: string) {
|
pasteTrimEnd(value: string) {
|
||||||
if (this.enabledStatus('paste')) {
|
if (this.interactSetting.pasteAutoTrim) {
|
||||||
if (this.preference.interactSetting.pasteAutoTrim) {
|
// 粘贴前去除尾部空格
|
||||||
// 粘贴前去除尾部空格
|
this.inst.paste(value.trimEnd());
|
||||||
this.inst.paste(value.trimEnd());
|
} else {
|
||||||
} else {
|
this.inst.paste(value);
|
||||||
this.inst.paste(value);
|
|
||||||
}
|
|
||||||
this.inst.focus();
|
|
||||||
}
|
}
|
||||||
|
this.inst.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选中全部
|
// 选中全部
|
||||||
@@ -123,35 +215,29 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler {
|
|||||||
|
|
||||||
// 打开命令编辑器
|
// 打开命令编辑器
|
||||||
commandEditor() {
|
commandEditor() {
|
||||||
if (this.enabledStatus('commandEditor')) {
|
this.domRef.editorModal?.open('', '');
|
||||||
this.domRef.editorModal?.open('', '');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ctrl + c
|
// ctrl + c
|
||||||
interrupt() {
|
interrupt() {
|
||||||
if (this.enabledStatus('interrupt')) {
|
this.inst.paste(String.fromCharCode(3));
|
||||||
this.inst.paste(String.fromCharCode(3));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回车
|
// 回车
|
||||||
enter() {
|
enter() {
|
||||||
if (this.enabledStatus('enter')) {
|
this.inst.paste(String.fromCharCode(13));
|
||||||
this.inst.paste(String.fromCharCode(13));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空
|
// 清空
|
||||||
clear() {
|
clear() {
|
||||||
this.inst.clear();
|
this.inst.clear();
|
||||||
|
this.inst.clearSelection();
|
||||||
|
this.inst.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 断开连接
|
// 断开连接
|
||||||
disconnect() {
|
disconnect() {
|
||||||
if (this.enabledStatus('disconnect')) {
|
this.session.disconnect();
|
||||||
this.session.disconnect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭
|
// 关闭
|
||||||
@@ -159,9 +245,8 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler {
|
|||||||
this.tabManager.deleteTab(this.session.sessionId);
|
this.tabManager.deleteTab(this.session.sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 聚焦
|
// todo
|
||||||
focus() {
|
// 切换 tab
|
||||||
this.inst.focus();
|
// 打开 新
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { ITerminalChannel, ITerminalSession, ITerminalSessionHandler, Termi
|
|||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
import { fontFamilySuffix, TerminalStatus } from '../types/terminal.const';
|
import { fontFamilySuffix, TerminalStatus } from '../types/terminal.const';
|
||||||
import { InputProtocol } from '../types/terminal.protocol';
|
import { InputProtocol } from '../types/terminal.protocol';
|
||||||
import { ITerminalOptions, Terminal } from 'xterm';
|
import { Terminal } from 'xterm';
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
import { WebLinksAddon } from 'xterm-addon-web-links';
|
import { WebLinksAddon } from 'xterm-addon-web-links';
|
||||||
import { ISearchOptions, SearchAddon } from 'xterm-addon-search';
|
import { ISearchOptions, SearchAddon } from 'xterm-addon-search';
|
||||||
@@ -12,12 +12,8 @@ import { ImageAddon } from 'xterm-addon-image';
|
|||||||
import { CanvasAddon } from 'xterm-addon-canvas';
|
import { CanvasAddon } from 'xterm-addon-canvas';
|
||||||
import { WebglAddon } from 'xterm-addon-webgl';
|
import { WebglAddon } from 'xterm-addon-webgl';
|
||||||
import { playBell } from '@/utils/bell';
|
import { playBell } from '@/utils/bell';
|
||||||
import useCopy from '@/hooks/copy';
|
|
||||||
import TerminalShortcutDispatcher from './terminal-shortcut-dispatch';
|
|
||||||
import TerminalSessionHandler from './terminal-session-handler';
|
import TerminalSessionHandler from './terminal-session-handler';
|
||||||
|
|
||||||
const copy = useCopy();
|
|
||||||
|
|
||||||
// 终端会话实现
|
// 终端会话实现
|
||||||
export default class TerminalSession implements ITerminalSession {
|
export default class TerminalSession implements ITerminalSession {
|
||||||
|
|
||||||
@@ -83,7 +79,6 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
|
|
||||||
// 注册快捷键
|
// 注册快捷键
|
||||||
private registerShortcut(preference: UnwrapRef<TerminalPreference>) {
|
private registerShortcut(preference: UnwrapRef<TerminalPreference>) {
|
||||||
const dispatcher = new TerminalShortcutDispatcher(this, preference.shortcutSetting.keys);
|
|
||||||
// 处理自定义按键
|
// 处理自定义按键
|
||||||
this.inst.attachCustomKeyEventHandler((e: KeyboardEvent) => {
|
this.inst.attachCustomKeyEventHandler((e: KeyboardEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -95,8 +90,8 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
if (e.type !== 'keydown') {
|
if (e.type !== 'keydown') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// 调度快捷键
|
// 触发快捷键
|
||||||
return dispatcher.dispatch(e);
|
return this.handler.triggerShortcutKey(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +119,7 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
if (preference.interactSetting.selectionChangeCopy) {
|
if (preference.interactSetting.selectionChangeCopy) {
|
||||||
this.inst.onSelectionChange(() => {
|
this.inst.onSelectionChange(() => {
|
||||||
// 复制选中内容
|
// 复制选中内容
|
||||||
this.copySelection();
|
this.handler.copy();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 注册 resize 事件
|
// 注册 resize 事件
|
||||||
@@ -139,7 +134,7 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
// 设置右键选项
|
// 设置右键选项
|
||||||
dom.addEventListener('contextmenu', async (event) => {
|
dom.addEventListener('contextmenu', async () => {
|
||||||
// 右键粘贴逻辑
|
// 右键粘贴逻辑
|
||||||
if (preference.interactSetting.rightClickPaste) {
|
if (preference.interactSetting.rightClickPaste) {
|
||||||
if (!this.canWrite || !this.connected) {
|
if (!this.canWrite || !this.connected) {
|
||||||
@@ -147,7 +142,7 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
}
|
}
|
||||||
// 未开启右键选中 || 开启并无选中的内容则粘贴
|
// 未开启右键选中 || 开启并无选中的内容则粘贴
|
||||||
if (!preference.interactSetting.rightClickSelectsWord || !this.inst.hasSelection()) {
|
if (!preference.interactSetting.rightClickSelectsWord || !this.inst.hasSelection()) {
|
||||||
this.pasteTrimEnd(await copy.readText());
|
this.handler.paste();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -172,6 +167,7 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
if (preference.pluginsSetting.enableImagePlugin) {
|
if (preference.pluginsSetting.enableImagePlugin) {
|
||||||
this.addons.image = new ImageAddon();
|
this.addons.image = new ImageAddon();
|
||||||
}
|
}
|
||||||
|
// 加载插件
|
||||||
for (const addon of Object.values(this.addons)) {
|
for (const addon of Object.values(this.addons)) {
|
||||||
this.inst.loadAddon(addon);
|
this.inst.loadAddon(addon);
|
||||||
}
|
}
|
||||||
@@ -209,53 +205,6 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
this.inst.focus();
|
this.inst.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空
|
|
||||||
clear(): void {
|
|
||||||
this.inst.clear();
|
|
||||||
this.inst.clearSelection();
|
|
||||||
this.inst.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 粘贴
|
|
||||||
paste(value: string): void {
|
|
||||||
this.inst.paste(value);
|
|
||||||
this.inst.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 粘贴并且去除尾部空格 (如果配置)
|
|
||||||
pasteTrimEnd(value: string): void {
|
|
||||||
if (useTerminalStore().preference.interactSetting.pasteAutoTrim) {
|
|
||||||
// 粘贴前去除尾部空格
|
|
||||||
this.inst.paste(value.trimEnd());
|
|
||||||
} else {
|
|
||||||
this.inst.paste(value);
|
|
||||||
}
|
|
||||||
this.inst.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 选中全部
|
|
||||||
selectAll(): void {
|
|
||||||
this.inst.selectAll();
|
|
||||||
this.inst.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复制选中
|
|
||||||
copySelection(): string {
|
|
||||||
let selection = this.inst.getSelection();
|
|
||||||
if (selection) {
|
|
||||||
// 去除尾部空格
|
|
||||||
const { preference } = useTerminalStore();
|
|
||||||
if (preference.interactSetting.copyAutoTrim) {
|
|
||||||
selection = selection.trimEnd();
|
|
||||||
}
|
|
||||||
// 复制
|
|
||||||
copy.copy(selection, false);
|
|
||||||
}
|
|
||||||
// 聚焦
|
|
||||||
this.inst.focus();
|
|
||||||
return selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找
|
// 查找
|
||||||
find(word: string, next: boolean, options: ISearchOptions): void {
|
find(word: string, next: boolean, options: ISearchOptions): void {
|
||||||
if (next) {
|
if (next) {
|
||||||
@@ -265,28 +214,6 @@ export default class TerminalSession implements ITerminalSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去顶部
|
|
||||||
toTop(): void {
|
|
||||||
this.inst.scrollToTop();
|
|
||||||
this.inst.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 去底部
|
|
||||||
toBottom(): void {
|
|
||||||
this.inst.scrollToBottom();
|
|
||||||
this.inst.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取配置
|
|
||||||
getOption(option: string): any {
|
|
||||||
return this.inst.options[option as keyof ITerminalOptions] as any;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置配置
|
|
||||||
setOption(option: string, value: any): void {
|
|
||||||
this.inst.options[option as keyof ITerminalOptions] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 断开连接
|
// 断开连接
|
||||||
disconnect(): void {
|
disconnect(): void {
|
||||||
// 发送关闭消息
|
// 发送关闭消息
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
import type { TerminalShortcutKey } from '@/store/modules/terminal/types';
|
|
||||||
import type { ITerminalSession, ITerminalShortcutDispatcher } from '../types/terminal.type';
|
|
||||||
import useCopy from '@/hooks/copy';
|
|
||||||
|
|
||||||
const { readText } = useCopy();
|
|
||||||
|
|
||||||
// 终端快捷键调度实现
|
|
||||||
export default class TerminalShortcutDispatch implements ITerminalShortcutDispatcher {
|
|
||||||
|
|
||||||
private readonly session: ITerminalSession;
|
|
||||||
|
|
||||||
private readonly keys: Array<TerminalShortcutKey>;
|
|
||||||
|
|
||||||
constructor(session: ITerminalSession, keys: Array<TerminalShortcutKey>) {
|
|
||||||
this.session = session;
|
|
||||||
// this.keys = keys;
|
|
||||||
this.keys = [
|
|
||||||
{
|
|
||||||
option: 'copy',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'C'
|
|
||||||
}, {
|
|
||||||
option: 'paste',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'V'
|
|
||||||
}, {
|
|
||||||
option: 'toTop',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'ArrowUp'
|
|
||||||
}, {
|
|
||||||
option: 'toBottom',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'ArrowDown'
|
|
||||||
}, {
|
|
||||||
option: 'selectAll',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'A'
|
|
||||||
}, {
|
|
||||||
option: 'search',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'F'
|
|
||||||
}, {
|
|
||||||
option: 'fontSizePlus',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: '+'
|
|
||||||
}, {
|
|
||||||
option: 'fontSizeSubtract',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: '_'
|
|
||||||
}, {
|
|
||||||
option: 'commandEditor',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'O'
|
|
||||||
}, {
|
|
||||||
option: 'close',
|
|
||||||
ctrlKey: true,
|
|
||||||
shiftKey: true,
|
|
||||||
altKey: false,
|
|
||||||
key: 'W'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调度快捷键
|
|
||||||
dispatch(e: KeyboardEvent): boolean {
|
|
||||||
console.log(e);
|
|
||||||
for (const key of this.keys) {
|
|
||||||
if (key.altKey === e.altKey
|
|
||||||
&& key.shiftKey === e.shiftKey
|
|
||||||
&& key.ctrlKey === e.ctrlKey
|
|
||||||
&& key.key === e.key) {
|
|
||||||
const runner = this[key.option as keyof this] as () => void;
|
|
||||||
runner && runner.apply(this);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复制
|
|
||||||
private copy(): void {
|
|
||||||
this.session.copySelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 粘贴
|
|
||||||
private paste(): void {
|
|
||||||
// FIXME status
|
|
||||||
readText().then((e) => {
|
|
||||||
this.session.pasteTrimEnd(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 去顶部
|
|
||||||
private toTop(): void {
|
|
||||||
this.session.toTop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 去底部
|
|
||||||
private toBottom(): void {
|
|
||||||
this.session.toBottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全选
|
|
||||||
private selectAll(): void {
|
|
||||||
this.session.selectAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 搜索
|
|
||||||
private search(): void {
|
|
||||||
// fixme
|
|
||||||
}
|
|
||||||
|
|
||||||
// 增大字号
|
|
||||||
private fontSizePlus(): void {
|
|
||||||
this.fontSizeAdd(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 减小字号
|
|
||||||
private fontSizeSubtract(): void {
|
|
||||||
this.fontSizeAdd(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 字号增加
|
|
||||||
private fontSizeAdd(addSize: number) {
|
|
||||||
this.session.setOption('fontSize', this.session.getOption('fontSize') + addSize);
|
|
||||||
if (this.session.connected) {
|
|
||||||
this.session.fit();
|
|
||||||
this.session.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 命令编辑器
|
|
||||||
private commandEditor(): void {
|
|
||||||
// fixme
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭终端
|
|
||||||
private close(): void {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private to(): void {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换 tab
|
|
||||||
// 打开 新
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -176,26 +176,8 @@ export interface ITerminalSession {
|
|||||||
fit: () => void;
|
fit: () => void;
|
||||||
// 聚焦
|
// 聚焦
|
||||||
focus: () => void;
|
focus: () => void;
|
||||||
// 清空
|
|
||||||
clear: () => void;
|
|
||||||
// 粘贴
|
|
||||||
paste: (value: string) => void;
|
|
||||||
// 粘贴并且去除尾部空格 (如果配置)
|
|
||||||
pasteTrimEnd: (value: string) => void;
|
|
||||||
// 选中全部
|
|
||||||
selectAll: () => void;
|
|
||||||
// 复制选中
|
|
||||||
copySelection: () => string;
|
|
||||||
// 查找
|
// 查找
|
||||||
find: (word: string, next: boolean, options: ISearchOptions) => void;
|
find: (word: string, next: boolean, options: ISearchOptions) => void;
|
||||||
// 去顶部
|
|
||||||
toTop: () => void;
|
|
||||||
// 去底部
|
|
||||||
toBottom: () => void;
|
|
||||||
// 获取配置
|
|
||||||
getOption: (option: string) => any;
|
|
||||||
// 设置配置
|
|
||||||
setOption: (option: string, value: any) => void;
|
|
||||||
// 断开连接
|
// 断开连接
|
||||||
disconnect: () => void;
|
disconnect: () => void;
|
||||||
// 关闭
|
// 关闭
|
||||||
@@ -206,6 +188,11 @@ export interface ITerminalSession {
|
|||||||
export interface ITerminalSessionHandler {
|
export interface ITerminalSessionHandler {
|
||||||
// 启用状态
|
// 启用状态
|
||||||
enabledStatus: (option: string) => boolean;
|
enabledStatus: (option: string) => boolean;
|
||||||
|
// 调用处理方法
|
||||||
|
invokeHandle: (option: string) => void;
|
||||||
|
// 触发快捷键
|
||||||
|
triggerShortcutKey: (e: KeyboardEvent) => boolean;
|
||||||
|
|
||||||
// 复制选中
|
// 复制选中
|
||||||
copy: () => void;
|
copy: () => void;
|
||||||
// 粘贴
|
// 粘贴
|
||||||
@@ -236,12 +223,4 @@ export interface ITerminalSessionHandler {
|
|||||||
disconnect: () => void;
|
disconnect: () => void;
|
||||||
// 关闭
|
// 关闭
|
||||||
close: () => void;
|
close: () => void;
|
||||||
// 聚焦
|
|
||||||
focus: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 终端快捷键调度定义
|
|
||||||
export interface ITerminalShortcutDispatcher {
|
|
||||||
// 调度快捷键
|
|
||||||
dispatch(e: KeyboardEvent): boolean;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user