|
|
@ -1,161 +1,416 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 导入 FileSystemConfig 类型,该类型定义了文件系统的配置
|
|
|
|
import type { FileSystemConfig } from 'common/fileSystemConfig';
|
|
|
|
import type { FileSystemConfig } from 'common/fileSystemConfig';
|
|
|
|
|
|
|
|
// 导入 vscode 模块,该模块提供了 VS Code 扩展 API
|
|
|
|
import * as vscode from 'vscode';
|
|
|
|
import * as vscode from 'vscode';
|
|
|
|
|
|
|
|
// 导入 loadConfigs 和 reloadWorkspaceFolderConfigs 函数,这些函数用于加载和重新加载配置
|
|
|
|
import { loadConfigs, reloadWorkspaceFolderConfigs } from './config';
|
|
|
|
import { loadConfigs, reloadWorkspaceFolderConfigs } from './config';
|
|
|
|
|
|
|
|
// 导入 Connection 类型,该类型定义了连接的配置
|
|
|
|
import type { Connection } from './connection';
|
|
|
|
import type { Connection } from './connection';
|
|
|
|
|
|
|
|
// 导入 FileSystemRouter 类,该类用于处理文件系统的路由
|
|
|
|
import { FileSystemRouter } from './fileSystemRouter';
|
|
|
|
import { FileSystemRouter } from './fileSystemRouter';
|
|
|
|
|
|
|
|
// 导入 Logging 类和 setDebug 函数,这些用于设置日志记录和调试模式
|
|
|
|
import { Logging, setDebug } from './logging';
|
|
|
|
import { Logging, setDebug } from './logging';
|
|
|
|
|
|
|
|
// 导入 Manager 类,该类用于管理文件系统的连接和配置
|
|
|
|
import { Manager } from './manager';
|
|
|
|
import { Manager } from './manager';
|
|
|
|
|
|
|
|
// 导入 SSHPseudoTerminal 类型,该类型定义了 SSH 伪终端的配置
|
|
|
|
import type { SSHPseudoTerminal } from './pseudoTerminal';
|
|
|
|
import type { SSHPseudoTerminal } from './pseudoTerminal';
|
|
|
|
|
|
|
|
// 导入 ConfigTreeProvider 和 ConnectionTreeProvider 类,这些类用于提供树形视图的数据
|
|
|
|
import { ConfigTreeProvider, ConnectionTreeProvider } from './treeViewManager';
|
|
|
|
import { ConfigTreeProvider, ConnectionTreeProvider } from './treeViewManager';
|
|
|
|
|
|
|
|
// 导入 PickComplexOptions 类型、pickComplex 函数、pickConnection 函数、setAsAbsolutePath 函数和 setupWhenClauseContexts 函数,这些函数和类型用于处理复杂的选择和设置绝对路径等操作
|
|
|
|
import { PickComplexOptions, pickComplex, pickConnection, setAsAbsolutePath, setupWhenClauseContexts } from './ui-utils';
|
|
|
|
import { PickComplexOptions, pickComplex, pickConnection, setAsAbsolutePath, setupWhenClauseContexts } from './ui-utils';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义一个命令处理器接口。
|
|
|
|
|
|
|
|
* 命令处理器用于处理各种命令,例如处理字符串、URI、配置、连接和终端等。
|
|
|
|
|
|
|
|
*/
|
|
|
|
interface CommandHandler {
|
|
|
|
interface CommandHandler {
|
|
|
|
/** If set, a string/undefined prompts using the given options.
|
|
|
|
/**
|
|
|
|
* If the input was a string, promptOptions.nameFilter is set to it */
|
|
|
|
* 如果设置了,则使用给定的选项提示字符串/未定义。
|
|
|
|
|
|
|
|
* 如果输入是字符串,则将 promptOptions.nameFilter 设置为它。
|
|
|
|
|
|
|
|
*/
|
|
|
|
promptOptions: PickComplexOptions;
|
|
|
|
promptOptions: PickComplexOptions;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理字符串的可选方法。
|
|
|
|
|
|
|
|
* @param string - 要处理的字符串。
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleString?(string: string): void;
|
|
|
|
handleString?(string: string): void;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理 URI 的可选方法。
|
|
|
|
|
|
|
|
* @param uri - 要处理的 URI。
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleUri?(uri: vscode.Uri): void;
|
|
|
|
handleUri?(uri: vscode.Uri): void;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理文件系统配置的可选方法。
|
|
|
|
|
|
|
|
* @param config - 要处理的文件系统配置。
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConfig?(config: FileSystemConfig): void;
|
|
|
|
handleConfig?(config: FileSystemConfig): void;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理连接的可选方法。
|
|
|
|
|
|
|
|
* @param connection - 要处理的连接。
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConnection?(connection: Connection): void;
|
|
|
|
handleConnection?(connection: Connection): void;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理 SSH 伪终端的可选方法。
|
|
|
|
|
|
|
|
* @param terminal - 要处理的 SSH 伪终端。
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleTerminal?(terminal: SSHPseudoTerminal): void;
|
|
|
|
handleTerminal?(terminal: SSHPseudoTerminal): void;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** `findConfigs` in config.ts ignores URIs for still-connecting connections */
|
|
|
|
/** `findConfigs` in config.ts ignores URIs for still-connecting connections */
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义一个全局变量 MANAGER,用于存储 Manager 类的实例。
|
|
|
|
|
|
|
|
* 该变量在扩展激活时被初始化,用于管理 SSH 文件系统的连接和配置。
|
|
|
|
|
|
|
|
*/
|
|
|
|
export let MANAGER: Manager | undefined;
|
|
|
|
export let MANAGER: Manager | undefined;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 激活 VS Code 扩展。
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* 此函数在扩展被激活时调用,负责初始化扩展的各种功能和组件。
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param context - 扩展上下文,包含扩展的各种资源和服务。
|
|
|
|
|
|
|
|
*/
|
|
|
|
export function activate(context: vscode.ExtensionContext) {
|
|
|
|
export function activate(context: vscode.ExtensionContext) {
|
|
|
|
|
|
|
|
// 通过 VS Code API 获取名为 'Kelvin.vscode-sshfs' 的扩展实例
|
|
|
|
const extension = vscode.extensions.getExtension('Kelvin.vscode-sshfs');
|
|
|
|
const extension = vscode.extensions.getExtension('Kelvin.vscode-sshfs');
|
|
|
|
|
|
|
|
// 尝试获取扩展的版本号,如果扩展不存在,则版本号为 undefined
|
|
|
|
const version = extension?.packageJSON?.version;
|
|
|
|
const version = extension?.packageJSON?.version;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 Logging 模块记录扩展激活的信息,包括版本和模式
|
|
|
|
Logging.info`Extension activated, version ${version}, mode ${context.extensionMode}`;
|
|
|
|
Logging.info`Extension activated, version ${version}, mode ${context.extensionMode}`;
|
|
|
|
|
|
|
|
// 使用 Logging 模块记录当前运行的 VS Code 版本和进程版本信息
|
|
|
|
Logging.debug`Running VS Code version ${vscode.version} ${process.versions}`;
|
|
|
|
Logging.debug`Running VS Code version ${vscode.version} ${process.versions}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查环境变量 VSCODE_SSHFS_DEBUG 是否设置为 true,以启用调试模式
|
|
|
|
setDebug(process.env.VSCODE_SSHFS_DEBUG?.toLowerCase() === 'true');
|
|
|
|
setDebug(process.env.VSCODE_SSHFS_DEBUG?.toLowerCase() === 'true');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 从全局状态中获取版本历史记录,如果没有则初始化为空数组
|
|
|
|
const versionHistory = context.globalState.get<[string, number, number][]>('versionHistory', []);
|
|
|
|
const versionHistory = context.globalState.get<[string, number, number][]>('versionHistory', []);
|
|
|
|
|
|
|
|
// 获取版本历史记录中的最后一个版本
|
|
|
|
const lastVersion = versionHistory[versionHistory.length - 1];
|
|
|
|
const lastVersion = versionHistory[versionHistory.length - 1];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否存在上一个版本记录
|
|
|
|
if (!lastVersion) {
|
|
|
|
if (!lastVersion) {
|
|
|
|
|
|
|
|
// 尝试从全局状态中获取旧版本记录(在 v1.21.0 之前的版本中使用)
|
|
|
|
const classicLastVersion = context.globalState.get<string>('lastVersion');
|
|
|
|
const classicLastVersion = context.globalState.get<string>('lastVersion');
|
|
|
|
|
|
|
|
// 如果存在旧版本记录
|
|
|
|
if (classicLastVersion) {
|
|
|
|
if (classicLastVersion) {
|
|
|
|
|
|
|
|
// 记录日志,表明正在从旧版本记录切换到新版本历史记录
|
|
|
|
Logging.debug`Previously used ${classicLastVersion}, switching over to new version history`;
|
|
|
|
Logging.debug`Previously used ${classicLastVersion}, switching over to new version history`;
|
|
|
|
|
|
|
|
// 将旧版本记录添加到新版本历史记录中
|
|
|
|
versionHistory.push([classicLastVersion, Date.now(), Date.now()]);
|
|
|
|
versionHistory.push([classicLastVersion, Date.now(), Date.now()]);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 记录日志,表明没有检测到之前的版本,可能是全新安装或安装了 v1.21.0 之前的版本
|
|
|
|
Logging.debug`No previous version detected. Fresh or pre-v1.21.0 installation?`;
|
|
|
|
Logging.debug`No previous version detected. Fresh or pre-v1.21.0 installation?`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 将当前版本添加到版本历史记录中
|
|
|
|
versionHistory.push([version, Date.now(), Date.now()]);
|
|
|
|
versionHistory.push([version, Date.now(), Date.now()]);
|
|
|
|
} else if (lastVersion[0] !== version) {
|
|
|
|
// 如果存在上一个版本记录,但是版本号与当前版本不同
|
|
|
|
|
|
|
|
} else if (lastVersion[0]!== version) {
|
|
|
|
|
|
|
|
// 记录日志,表明之前使用的是不同的版本,现在是切换到当前版本后的首次启动
|
|
|
|
Logging.debug`Previously used ${lastVersion[0]}, currently first launch since switching to ${version}`;
|
|
|
|
Logging.debug`Previously used ${lastVersion[0]}, currently first launch since switching to ${version}`;
|
|
|
|
|
|
|
|
// 将当前版本添加到版本历史记录中
|
|
|
|
versionHistory.push([version, Date.now(), Date.now()]);
|
|
|
|
versionHistory.push([version, Date.now(), Date.now()]);
|
|
|
|
|
|
|
|
// 如果存在上一个版本记录,且版本号与当前版本相同
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 更新上一个版本记录的最后更新时间为当前时间
|
|
|
|
lastVersion[2] = Date.now();
|
|
|
|
lastVersion[2] = Date.now();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 使用 Logging 模块记录版本历史记录,将版本历史记录中的每个版本号、创建时间和最后更新时间用冒号连接起来,并用大于号分隔
|
|
|
|
Logging.info`Version history: ${versionHistory.map(v => v.join(':')).join(' > ')}`;
|
|
|
|
Logging.info`Version history: ${versionHistory.map(v => v.join(':')).join(' > ')}`;
|
|
|
|
|
|
|
|
// 将更新后的版本历史记录保存到全局状态中,以便下次扩展激活时可以读取
|
|
|
|
context.globalState.update('versionHistory', versionHistory);
|
|
|
|
context.globalState.update('versionHistory', versionHistory);
|
|
|
|
|
|
|
|
|
|
|
|
// Really too bad we *need* the ExtensionContext for relative resources
|
|
|
|
// Really too bad we *need* the ExtensionContext for relative resources
|
|
|
|
// I really don't like having to pass context to *everything*, so let's do it this way
|
|
|
|
// I really don't like having to pass context to *everything*, so let's do it this way
|
|
|
|
|
|
|
|
// 真的很糟糕,我们确实需要扩展上下文(ExtensionContext)来获取相对资源。
|
|
|
|
|
|
|
|
// 我真的不喜欢必须将上下文传递给所有东西,所以让我们这样做吧。
|
|
|
|
|
|
|
|
// 将 context.asAbsolutePath 方法绑定到当前上下文中,并赋值给 setAsAbsolutePath 变量
|
|
|
|
setAsAbsolutePath(context.asAbsolutePath.bind(context));
|
|
|
|
setAsAbsolutePath(context.asAbsolutePath.bind(context));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建一个 Manager 实例,并将其赋值给全局变量 MANAGER
|
|
|
|
const manager = MANAGER = new Manager(context);
|
|
|
|
const manager = MANAGER = new Manager(context);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 定义一个函数,用于将订阅添加到 context.subscriptions 数组中
|
|
|
|
const subscribe = context.subscriptions.push.bind(context.subscriptions) as typeof context.subscriptions.push;
|
|
|
|
const subscribe = context.subscriptions.push.bind(context.subscriptions) as typeof context.subscriptions.push;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 定义一个函数,用于注册命令
|
|
|
|
const registerCommand = (command: string, callback: (...args: any[]) => any, thisArg?: any) =>
|
|
|
|
const registerCommand = (command: string, callback: (...args: any[]) => any, thisArg?: any) =>
|
|
|
|
subscribe(vscode.commands.registerCommand(command, callback, thisArg));
|
|
|
|
subscribe(vscode.commands.registerCommand(command, callback, thisArg));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注册一个文件系统提供程序,用于处理 ssh 协议的文件系统
|
|
|
|
subscribe(vscode.workspace.registerFileSystemProvider('ssh', new FileSystemRouter(manager), { isCaseSensitive: true }));
|
|
|
|
subscribe(vscode.workspace.registerFileSystemProvider('ssh', new FileSystemRouter(manager), { isCaseSensitive: true }));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注册一个树视图,用于展示 sshfs 配置
|
|
|
|
subscribe(vscode.window.createTreeView('sshfs-configs', { treeDataProvider: new ConfigTreeProvider(), showCollapseAll: true }));
|
|
|
|
subscribe(vscode.window.createTreeView('sshfs-configs', { treeDataProvider: new ConfigTreeProvider(), showCollapseAll: true }));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建一个 ConnectionTreeProvider 实例,用于展示连接信息
|
|
|
|
const connectionTreeProvider = new ConnectionTreeProvider(manager.connectionManager);
|
|
|
|
const connectionTreeProvider = new ConnectionTreeProvider(manager.connectionManager);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注册一个树视图,用于展示 sshfs 连接
|
|
|
|
subscribe(vscode.window.createTreeView('sshfs-connections', { treeDataProvider: connectionTreeProvider, showCollapseAll: true }));
|
|
|
|
subscribe(vscode.window.createTreeView('sshfs-connections', { treeDataProvider: connectionTreeProvider, showCollapseAll: true }));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注册一个任务提供程序,用于处理 ssh 任务
|
|
|
|
subscribe(vscode.tasks.registerTaskProvider('ssh-shell', manager));
|
|
|
|
subscribe(vscode.tasks.registerTaskProvider('ssh-shell', manager));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注册一个终端链接提供程序
|
|
|
|
subscribe(vscode.window.registerTerminalLinkProvider(manager));
|
|
|
|
subscribe(vscode.window.registerTerminalLinkProvider(manager));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置条件语句的上下文
|
|
|
|
setupWhenClauseContexts(manager.connectionManager);
|
|
|
|
setupWhenClauseContexts(manager.connectionManager);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令处理程序
|
|
|
|
|
|
|
|
* @param name - 命令的名称
|
|
|
|
|
|
|
|
* @param handler - 命令处理程序的配置
|
|
|
|
|
|
|
|
* @returns 注册的命令处理程序
|
|
|
|
|
|
|
|
*/
|
|
|
|
function registerCommandHandler(name: string, handler: CommandHandler) {
|
|
|
|
function registerCommandHandler(name: string, handler: CommandHandler) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理命令的输入参数
|
|
|
|
|
|
|
|
* @param arg - 输入参数,可以是字符串、文件系统配置、连接、SSH 伪终端或 URI
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
const callback = async (arg?: string | FileSystemConfig | Connection | SSHPseudoTerminal | vscode.Uri) => {
|
|
|
|
const callback = async (arg?: string | FileSystemConfig | Connection | SSHPseudoTerminal | vscode.Uri) => {
|
|
|
|
|
|
|
|
// 如果存在 promptOptions 并且输入参数为空或为字符串
|
|
|
|
if (handler.promptOptions && (!arg || typeof arg === 'string')) {
|
|
|
|
if (handler.promptOptions && (!arg || typeof arg === 'string')) {
|
|
|
|
arg = await pickComplex(manager, { ...handler.promptOptions, nameFilter: arg });
|
|
|
|
// 使用 pickComplex 函数从管理器中选择一个复杂的对象,并将其赋值给 arg
|
|
|
|
|
|
|
|
arg = await pickComplex(manager, {...handler.promptOptions, nameFilter: arg });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果输入参数是字符串,则调用 handleString 方法处理
|
|
|
|
if (typeof arg === 'string') return handler.handleString?.(arg);
|
|
|
|
if (typeof arg === 'string') return handler.handleString?.(arg);
|
|
|
|
|
|
|
|
// 如果输入参数为空,则直接返回
|
|
|
|
if (!arg) return;
|
|
|
|
if (!arg) return;
|
|
|
|
|
|
|
|
// 如果输入参数是 URI 类型,则调用 handleUri 方法处理
|
|
|
|
if (arg instanceof vscode.Uri) {
|
|
|
|
if (arg instanceof vscode.Uri) {
|
|
|
|
return handler.handleUri?.(arg);
|
|
|
|
return handler.handleUri?.(arg);
|
|
|
|
} else if ('handleInput' in arg) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果输入参数存在 handleInput 属性,则调用 handleTerminal 方法处理
|
|
|
|
|
|
|
|
else if ('handleInput' in arg) {
|
|
|
|
return handler.handleTerminal?.(arg);
|
|
|
|
return handler.handleTerminal?.(arg);
|
|
|
|
} else if ('client' in arg) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果输入参数存在 client 属性,则调用 handleConnection 方法处理
|
|
|
|
|
|
|
|
else if ('client' in arg) {
|
|
|
|
return handler.handleConnection?.(arg);
|
|
|
|
return handler.handleConnection?.(arg);
|
|
|
|
} else if ('name' in arg) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果输入参数存在 name 属性,则调用 handleConfig 方法处理
|
|
|
|
|
|
|
|
else if ('name' in arg) {
|
|
|
|
return handler.handleConfig?.(arg);
|
|
|
|
return handler.handleConfig?.(arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果以上条件都不满足,则记录一条警告信息
|
|
|
|
Logging.warning(`CommandHandler for '${name}' could not handle input '${arg}'`);
|
|
|
|
Logging.warning(`CommandHandler for '${name}' could not handle input '${arg}'`);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// 注册命令
|
|
|
|
registerCommand(name, callback);
|
|
|
|
registerCommand(name, callback);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令,用于打开创建新配置文件的设置界面
|
|
|
|
|
|
|
|
* 当用户执行此命令时,会调用 manager.openSettings 方法,并传入一个对象参数 { type: 'newconfig' }
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.new()
|
|
|
|
// sshfs.new()
|
|
|
|
registerCommand('sshfs.new', () => manager.openSettings({ type: 'newconfig' }));
|
|
|
|
registerCommand('sshfs.new', () => manager.openSettings({ type: 'newconfig' }));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令处理程序,用于添加新的配置文件或连接
|
|
|
|
|
|
|
|
* @param name - 命令的名称
|
|
|
|
|
|
|
|
* @param handler - 命令处理程序的配置
|
|
|
|
|
|
|
|
* @returns 注册的命令处理程序
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.add(target?: string | FileSystemConfig)
|
|
|
|
// sshfs.add(target?: string | FileSystemConfig)
|
|
|
|
registerCommandHandler('sshfs.add', {
|
|
|
|
registerCommandHandler('sshfs.add', {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义了命令执行时的提示选项
|
|
|
|
|
|
|
|
* promptConfigs: true 表示提示用户选择配置文件
|
|
|
|
|
|
|
|
* promptConnections: true 表示提示用户选择连接
|
|
|
|
|
|
|
|
* promptInstantConnection: true 表示提示用户是否立即连接
|
|
|
|
|
|
|
|
*/
|
|
|
|
promptOptions: { promptConfigs: true, promptConnections: true, promptInstantConnection: true },
|
|
|
|
promptOptions: { promptConfigs: true, promptConnections: true, promptInstantConnection: true },
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理配置文件的函数
|
|
|
|
|
|
|
|
* @param config - 配置文件对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConfig: config => manager.commandConnect(config),
|
|
|
|
handleConfig: config => manager.commandConnect(config),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令处理程序,用于断开 SSHFS 连接
|
|
|
|
|
|
|
|
* @param name - 命令的名称
|
|
|
|
|
|
|
|
* @param handler - 命令处理程序的配置
|
|
|
|
|
|
|
|
* @returns 注册的命令处理程序
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.disconnect(target: string | FileSystemConfig | Connection)
|
|
|
|
// sshfs.disconnect(target: string | FileSystemConfig | Connection)
|
|
|
|
registerCommandHandler('sshfs.disconnect', {
|
|
|
|
registerCommandHandler('sshfs.disconnect', {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义了命令执行时的提示选项
|
|
|
|
|
|
|
|
* promptConnections: true 表示提示用户选择连接
|
|
|
|
|
|
|
|
*/
|
|
|
|
promptOptions: { promptConnections: true },
|
|
|
|
promptOptions: { promptConnections: true },
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理字符串输入的函数
|
|
|
|
|
|
|
|
* @param name - 连接的名称
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleString: name => manager.commandDisconnect(name),
|
|
|
|
handleString: name => manager.commandDisconnect(name),
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理配置文件的函数
|
|
|
|
|
|
|
|
* @param config - 配置文件对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConfig: config => manager.commandDisconnect(config.name),
|
|
|
|
handleConfig: config => manager.commandDisconnect(config.name),
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理连接对象的函数
|
|
|
|
|
|
|
|
* @param con - 连接对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConnection: con => manager.commandDisconnect(con),
|
|
|
|
handleConnection: con => manager.commandDisconnect(con),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令,用于断开所有的 SSHFS 连接
|
|
|
|
|
|
|
|
* 当用户执行此命令时,会调用 manager.connectionManager.closeConnection 方法,关闭所有的活动连接
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.disconnectAll()
|
|
|
|
// sshfs.disconnectAll()
|
|
|
|
registerCommand('sshfs.disconnectAll', () => {
|
|
|
|
registerCommand('sshfs.disconnectAll', () => {
|
|
|
|
const conns = manager.connectionManager;
|
|
|
|
const conns = manager.connectionManager;
|
|
|
|
|
|
|
|
// 遍历所有的活动连接,并调用 closeConnection 方法关闭它们
|
|
|
|
// Does not close pending connections (yet?)
|
|
|
|
// Does not close pending connections (yet?)
|
|
|
|
conns.getActiveConnections().forEach(conn => conns.closeConnection(conn, 'command:disconnectAll'));
|
|
|
|
conns.getActiveConnections().forEach(conn => conns.closeConnection(conn, 'command:disconnectAll'));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// sshfs.terminal(target?: FileSystemConfig | Connection | vscode.Uri)
|
|
|
|
// sshfs.terminal(target?: FileSystemConfig | Connection | vscode.Uri)
|
|
|
|
registerCommandHandler('sshfs.terminal', {
|
|
|
|
registerCommandHandler('sshfs.terminal', {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义了命令执行时的提示选项
|
|
|
|
|
|
|
|
* promptConfigs: true 表示提示用户选择配置文件
|
|
|
|
|
|
|
|
* promptConnections: true 表示提示用户选择连接
|
|
|
|
|
|
|
|
* promptInstantConnection: true 表示提示用户是否立即连接
|
|
|
|
|
|
|
|
*/
|
|
|
|
promptOptions: { promptConfigs: true, promptConnections: true, promptInstantConnection: true },
|
|
|
|
promptOptions: { promptConfigs: true, promptConnections: true, promptInstantConnection: true },
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理配置文件的函数
|
|
|
|
|
|
|
|
* @param config - 配置文件对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConfig: config => manager.commandTerminal(config),
|
|
|
|
handleConfig: config => manager.commandTerminal(config),
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理连接对象的函数
|
|
|
|
|
|
|
|
* @param con - 连接对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConnection: con => manager.commandTerminal(con),
|
|
|
|
handleConnection: con => manager.commandTerminal(con),
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理 URI 的函数
|
|
|
|
|
|
|
|
* @param uri - URI 对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleUri: async uri => {
|
|
|
|
handleUri: async uri => {
|
|
|
|
|
|
|
|
// 根据 URI 的 authority 部分选择连接
|
|
|
|
const con = await pickConnection(manager, uri.authority);
|
|
|
|
const con = await pickConnection(manager, uri.authority);
|
|
|
|
|
|
|
|
// 如果找到了连接,则打开终端
|
|
|
|
con && manager.commandTerminal(con, uri);
|
|
|
|
con && manager.commandTerminal(con, uri);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令处理程序,用于聚焦(显示)SSHFS 终端
|
|
|
|
|
|
|
|
* @param name - 命令的名称
|
|
|
|
|
|
|
|
* @param handler - 命令处理程序的配置
|
|
|
|
|
|
|
|
* @returns 注册的命令处理程序
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.focusTerminal(target?: SSHPseudoTerminal)
|
|
|
|
// sshfs.focusTerminal(target?: SSHPseudoTerminal)
|
|
|
|
registerCommandHandler('sshfs.focusTerminal', {
|
|
|
|
registerCommandHandler('sshfs.focusTerminal', {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义了命令执行时的提示选项
|
|
|
|
|
|
|
|
* promptTerminals: true 表示提示用户选择终端
|
|
|
|
|
|
|
|
*/
|
|
|
|
promptOptions: { promptTerminals: true },
|
|
|
|
promptOptions: { promptTerminals: true },
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理终端对象的函数
|
|
|
|
|
|
|
|
* @param terminal - 终端对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleTerminal: ({ terminal }) => terminal?.show(false),
|
|
|
|
handleTerminal: ({ terminal }) => terminal?.show(false),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令处理程序,用于关闭 SSHFS 终端
|
|
|
|
|
|
|
|
* @param name - 命令的名称
|
|
|
|
|
|
|
|
* @param handler - 命令处理程序的配置
|
|
|
|
|
|
|
|
* @returns 注册的命令处理程序
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.closeTerminal(target?: SSHPseudoTerminal)
|
|
|
|
// sshfs.closeTerminal(target?: SSHPseudoTerminal)
|
|
|
|
registerCommandHandler('sshfs.closeTerminal', {
|
|
|
|
registerCommandHandler('sshfs.closeTerminal', {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义了命令执行时的提示选项
|
|
|
|
|
|
|
|
* promptTerminals: true 表示提示用户选择终端
|
|
|
|
|
|
|
|
*/
|
|
|
|
promptOptions: { promptTerminals: true },
|
|
|
|
promptOptions: { promptTerminals: true },
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理终端对象的函数
|
|
|
|
|
|
|
|
* @param terminal - 终端对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleTerminal: terminal => terminal.close(),
|
|
|
|
handleTerminal: terminal => terminal.close(),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令处理程序,用于配置 SSHFS 连接
|
|
|
|
|
|
|
|
* @param name - 命令的名称
|
|
|
|
|
|
|
|
* @param handler - 命令处理程序的配置
|
|
|
|
|
|
|
|
* @returns 注册的命令处理程序
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.configure(target?: string | FileSystemConfig)
|
|
|
|
// sshfs.configure(target?: string | FileSystemConfig)
|
|
|
|
registerCommandHandler('sshfs.configure', {
|
|
|
|
registerCommandHandler('sshfs.configure', {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 定义了命令执行时的提示选项
|
|
|
|
|
|
|
|
* promptConfigs: true 表示提示用户选择配置文件
|
|
|
|
|
|
|
|
*/
|
|
|
|
promptOptions: { promptConfigs: true },
|
|
|
|
promptOptions: { promptConfigs: true },
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 处理配置文件的函数
|
|
|
|
|
|
|
|
* @param config - 配置文件对象
|
|
|
|
|
|
|
|
* @returns 处理结果
|
|
|
|
|
|
|
|
*/
|
|
|
|
handleConfig: config => manager.commandConfigure(config),
|
|
|
|
handleConfig: config => manager.commandConfigure(config),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令,用于重新加载配置文件
|
|
|
|
|
|
|
|
* 当用户执行此命令时,会调用 loadConfigs 函数
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.reload()
|
|
|
|
// sshfs.reload()
|
|
|
|
registerCommand('sshfs.reload', loadConfigs);
|
|
|
|
registerCommand('sshfs.reload', loadConfigs);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令,用于打开插件的设置界面
|
|
|
|
|
|
|
|
* 当用户执行此命令时,会调用 manager.openSettings 方法
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.settings()
|
|
|
|
// sshfs.settings()
|
|
|
|
registerCommand('sshfs.settings', () => manager.openSettings());
|
|
|
|
registerCommand('sshfs.settings', () => manager.openSettings());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 注册一个命令,用于刷新连接树视图
|
|
|
|
|
|
|
|
* 当用户执行此命令时,会调用 connectionTreeProvider.refresh() 方法
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sshfs.refresh()
|
|
|
|
// sshfs.refresh()
|
|
|
|
registerCommand('sshfs.refresh', () => connectionTreeProvider.refresh());
|
|
|
|
registerCommand('sshfs.refresh', () => connectionTreeProvider.refresh());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 订阅连接管理器的 onConnectionAdded 事件,当有新连接添加时,自动重新加载工作区文件夹配置
|
|
|
|
|
|
|
|
* @param con - 新添加的连接对象
|
|
|
|
|
|
|
|
*/
|
|
|
|
subscribe(manager.connectionManager.onConnectionAdded(async con => {
|
|
|
|
subscribe(manager.connectionManager.onConnectionAdded(async con => {
|
|
|
|
|
|
|
|
// 当有新连接添加时,重新加载与该连接名称相关的工作区文件夹配置
|
|
|
|
await reloadWorkspaceFolderConfigs(con.actualConfig.name);
|
|
|
|
await reloadWorkspaceFolderConfigs(con.actualConfig.name);
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|