diff --git a/package.json b/package.json index 67b23cb..a06ffda 100644 --- a/package.json +++ b/package.json @@ -38,47 +38,32 @@ "commands": [ { "command": "sshfs.new", - "title": "Create a new SSH FS configuration", + "title": "Create a SSH FS configuration", "category": "SSH FS" }, { "command": "sshfs.connect", - "title": "Connect a SSH FS as Workspace folder", + "title": "Connect as Workspace folder", "category": "SSH FS" }, { "command": "sshfs.reconnect", - "title": "Reconnect a SSH FS Workspace folder", + "title": "Reconnect Workspace folder", "category": "SSH FS" }, { "command": "sshfs.disconnect", - "title": "Disconnect a SSH FS Workspace folder", + "title": "Disconnect Workspace folder", "category": "SSH FS" }, { - "command": "sshfs-configs.connect", - "title": "Connect", + "command": "sshfs.configure", + "title": "Edit configuration", "category": "SSH FS" }, { - "command": "sshfs-configs.reconnect", - "title": "Reconnect", - "category": "SSH FS" - }, - { - "command": "sshfs-configs.disconnect", - "title": "Disconnect", - "category": "SSH FS" - }, - { - "command": "sshfs-configs.configure", - "title": "Configure", - "category": "SSH FS" - }, - { - "command": "sshfs-configs.delete", - "title": "Delete", + "command": "sshfs.delete", + "title": "Delete configuration", "category": "SSH FS" } ], @@ -101,50 +86,43 @@ "group": "SSH FS@4" }, { - "command": "sshfs-configs.connect", - "when": "view == never" - }, - { - "command": "sshfs-configs.reconnect", - "when": "view == never" + "command": "sshfs.configure", + "group": "SSH FS@5" }, { - "command": "sshfs-configs.disconnect", - "when": "view == never" - }, - { - "command": "sshfs-configs.configure", - "when": "view == never" - }, - { - "command": "sshfs-configs.delete", - "when": "view == never" + "command": "sshfs.delete", + "group": "SSH FS@6" } ], "view/item/context": [ { - "command": "sshfs-configs.connect", - "when": "view == 'sshfs-configs' && viewItem == inactive" + "command": "sshfs.new", + "when": "view == 'sshfs-configs' && !viewItem" }, { - "command": "sshfs-configs.reconnect", - "when": "view == 'sshfs-configs' && viewItem == active" + "command": "sshfs.connect", + "when": "view == 'sshfs-configs' && viewItem == inactive", + "group": "SSH FS@1" }, { - "command": "sshfs-configs.disconnect", - "when": "view == 'sshfs-configs' && viewItem == active" + "command": "sshfs.reconnect", + "when": "view == 'sshfs-configs' && viewItem == active", + "group": "SSH FS@1" }, { - "command": "sshfs-configs.configure", - "when": "view == 'sshfs-configs' && viewItem" + "command": "sshfs.disconnect", + "when": "view == 'sshfs-configs' && viewItem == active", + "group": "SSH FS@2" }, { - "command": "sshfs-configs.delete", - "when": "view == 'sshfs-configs' && viewItem" + "command": "sshfs.configure", + "when": "view == 'sshfs-configs' && viewItem", + "group": "SSH FS@3" }, { - "command": "sshfs.new", - "when": "view == 'sshfs-configs' && !viewItem" + "command": "sshfs.delete", + "when": "view == 'sshfs-configs' && viewItem", + "group": "SSH FS@4" } ] }, diff --git a/src/extension.ts b/src/extension.ts index 0a18571..57c0e56 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,32 +6,41 @@ import { Manager } from './manager'; const workspace = vscode.workspace; +async function pickConfig(manager: Manager, activeOrNot?: boolean) { + let names = manager.getActive(); + const others = manager.loadConfigs().map(c => c.name); + if (activeOrNot === false) { + names = others.filter(n => names.indexOf(n) === -1); + } else if (activeOrNot === undefined) { + others.forEach(n => names.indexOf(n) === -1 && names.push(n)); + } + return vscode.window.showQuickPick(names, { placeHolder: 'SSH FS Configuration' }); +} + export function activate(context: vscode.ExtensionContext) { const manager = new Manager(context); - context.subscriptions.push(vscode.workspace.registerFileSystemProvider('ssh', manager, { isCaseSensitive: true })); + const subscribe = context.subscriptions.push.bind(context.subscriptions) as typeof context.subscriptions.push; + const registerCommand = (command: string, callback: (...args: any[]) => any, thisArg?: any) => + subscribe(vscode.commands.registerCommand(command, callback, thisArg)); - context.subscriptions.push(vscode.commands.registerCommand('sshfs.new', async () => { - const name = await vscode.window.showInputBox({ placeHolder: 'Name for the new SSH file system', validateInput: manager.invalidConfigName.bind(manager) }); - vscode.window.showTextDocument(vscode.Uri.parse(`ssh:///${name}.json`)); - })); - - async function pickAndClick(func: (name: string) => void, activeOrNot: boolean) { - const active = manager.getActive(); - const names = activeOrNot ? active : manager.loadConfigs().map(c => c.name).filter(n => active.indexOf(n) === -1); - const pick = await vscode.window.showQuickPick(names, { placeHolder: 'SSH FS Configuration' }); - if (pick) func.call(manager, pick); - } + subscribe(vscode.workspace.registerFileSystemProvider('ssh', manager, { isCaseSensitive: true })); - context.subscriptions.push(vscode.commands.registerCommand('sshfs.connect', () => pickAndClick(manager.commandConfigConnect, false))); - context.subscriptions.push(vscode.commands.registerCommand('sshfs.disconnect', () => pickAndClick(manager.commandConfigDisconnect, true))); - context.subscriptions.push(vscode.commands.registerCommand('sshfs.reconnect', () => pickAndClick(manager.commandConfigReconnect, true))); + async function pickAndClick(func: (name: string) => void, name?: string, activeOrNot?: boolean) { + name = name || await pickConfig(manager, activeOrNot); + if (name) func.call(manager, name); + } - context.subscriptions.push(vscode.commands.registerCommand('sshfs-configs.disconnect', manager.commandConfigDisconnect, manager)); - context.subscriptions.push(vscode.commands.registerCommand('sshfs-configs.reconnect', manager.commandConfigReconnect, manager)); - context.subscriptions.push(vscode.commands.registerCommand('sshfs-configs.connect', manager.commandConfigConnect, manager)); - context.subscriptions.push(vscode.commands.registerCommand('sshfs-configs.configure', manager.commandConfigure, manager)); - context.subscriptions.push(vscode.commands.registerCommand('sshfs-configs.delete', manager.commandConfigDelete, manager)); + registerCommand('sshfs.new', async () => { + const name = await vscode.window.showInputBox({ placeHolder: 'Name for the new SSH file system', validateInput: manager.invalidConfigName.bind(manager) }); + if (name) vscode.window.showTextDocument(vscode.Uri.parse(`ssh:///${name}.json`)); + }); + + registerCommand('sshfs.connect', (name?: string) => pickAndClick(manager.commandConnect, name, false)); + registerCommand('sshfs.disconnect', (name?: string) => pickAndClick(manager.commandDisconnect, name, true)); + registerCommand('sshfs.reconnect', (name?: string) => pickAndClick(manager.commandReconnect, name, true)); + registerCommand('sshfs.configure', (name?: string) => pickAndClick(manager.commandConfigure, name)); + registerCommand('sshfs.delete', (name?: string) => pickAndClick(manager.commandConfigDelete, name)); vscode.window.createTreeView('sshfs-configs', { treeDataProvider: manager }); } diff --git a/src/manager.ts b/src/manager.ts index 814aa85..c2386b6 100644 --- a/src/manager.ts +++ b/src/manager.ts @@ -62,7 +62,7 @@ function createConfigFs(manager: Manager): SSHFileSystem { } else { throw new Error(`This isn't supposed to happen! Config location was '${loc}' somehow`); } - dialog.then(o => o === 'Connect' && manager.commandConfigReconnect(name)); + dialog.then(o => o === 'Connect' && manager.commandReconnect(name)); } catch (e) { vscode.window.showErrorMessage(`Couldn't parse this config as JSON`); } @@ -93,7 +93,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid e.added.forEach(folderAdded); e.removed.forEach(async (folder) => { if (folder.uri.scheme !== 'ssh') return; - this.commandConfigDisconnect(folder.uri.authority); + this.commandDisconnect(folder.uri.authority); }); }); vscode.workspace.onDidChangeConfiguration((e) => { @@ -202,7 +202,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid }); }); client.on('timeout', () => reject(new Error(`Socket timed out while connecting SSH FS '${name}'`))); - client.on('close', hadError => hadError && this.commandConfigReconnect(name)); + client.on('close', hadError => hadError && this.commandReconnect(name)); client.on('error', (error) => { if (error.description) { error.message = `${error.description}\n${error.message}`; @@ -217,7 +217,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid }).catch((e) => { if (!e) { delete this.creatingFileSystems[name]; - this.commandConfigDisconnect(name); + this.commandDisconnect(name); throw e; } vscode.window.showErrorMessage(`Error while connecting to SSH FS ${name}:\n${e.message}`, 'Retry', 'Configure', 'Ignore').then((chosen) => { @@ -227,7 +227,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid } else if (chosen === 'Configure') { this.commandConfigure(name); } else { - this.commandConfigDisconnect(name); + this.commandDisconnect(name); } }); throw e; @@ -284,7 +284,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid return configs; } /* Commands (stuff for e.g. context menu for ssh-configs tree) */ - public commandConfigDisconnect(name: string) { + public commandDisconnect(name: string) { const fs = this.fileSystems.find(f => f.authority === name); if (fs) { fs.disconnect(); @@ -295,15 +295,15 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid if (index !== -1) vscode.workspace.updateWorkspaceFolders(index, 1); this.onDidChangeTreeDataEmitter.fire(); } - public commandConfigReconnect(name: string) { + public commandReconnect(name: string) { const fs = this.fileSystems.find(f => f.authority === name); if (fs) { fs.disconnect(); this.fileSystems.splice(this.fileSystems.indexOf(fs), 1); } - this.commandConfigConnect(name); + this.commandConnect(name); } - public commandConfigConnect(name: string) { + public commandConnect(name: string) { if (this.getActive().indexOf(name) !== -1) return vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer'); const folders = vscode.workspace.workspaceFolders!; const folder = folders && folders.find(f => f.uri.scheme === 'ssh' && f.uri.authority === name); @@ -318,7 +318,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid vscode.window.showTextDocument(vscode.Uri.parse(`ssh:///${name}.json`), { preview: false }); } public commandConfigDelete(name: string) { - this.commandConfigDisconnect(name); + this.commandDisconnect(name); this.updateConfig(name); } /* Configuration discovery */