Add FileSystemConfig.label + fix bug with non-lowercase config names

pull/13/head
Kelvin Schoofs 7 years ago
parent e1c251583a
commit 4ad6b89243

@ -1,5 +1,6 @@
// If you haven't already, associate .jsonc files with "JSON with Comments (jsonc)" // If you haven't already, associate .jsonc files with "JSON with Comments (jsonc)"
{ {
"label": "An optional label for a good name",
"root": "/tmp", "root": "/tmp",
"host": "localhost", "host": "localhost",
"port": 22, "port": 22,

@ -8,13 +8,18 @@ const workspace = vscode.workspace;
async function pickConfig(manager: Manager, activeOrNot?: boolean) { async function pickConfig(manager: Manager, activeOrNot?: boolean) {
let names = manager.getActive(); let names = manager.getActive();
const others = manager.loadConfigs().map(c => c.name); const others = manager.loadConfigs();
if (activeOrNot === false) { if (activeOrNot === false) {
names = others.filter(n => names.indexOf(n) === -1); names = others.filter(c => !names.find(cc => cc.name === c.name));
} else if (activeOrNot === undefined) { } else if (activeOrNot === undefined) {
others.forEach(n => names.indexOf(n) === -1 && names.push(n)); others.forEach(n => names.indexOf(n) === -1 && names.push(n));
} }
return vscode.window.showQuickPick(names, { placeHolder: 'SSH FS Configuration' }); const options: vscode.QuickPickItem[] = names.map(config => ({
label: config.label || config.name,
description: config.label && config.name,
}));
const pick = await vscode.window.showQuickPick(options, { placeHolder: 'SSH FS Configuration' });
return pick && pick.detail;
} }
export function activate(context: vscode.ExtensionContext) { export function activate(context: vscode.ExtensionContext) {

@ -18,6 +18,7 @@ async function assertFs(man: Manager, uri: vscode.Uri) {
export interface FileSystemConfig extends ConnectConfig { export interface FileSystemConfig extends ConnectConfig {
name: string; name: string;
label?: string;
root?: string; root?: string;
putty?: string | boolean; putty?: string | boolean;
} }
@ -27,7 +28,7 @@ function createTreeItem(manager: Manager, name: string): vscode.TreeItem {
const folders = vscode.workspace.workspaceFolders || []; const folders = vscode.workspace.workspaceFolders || [];
const active = folders.some(f => f.uri.scheme === 'ssh' && f.uri.authority === name); const active = folders.some(f => f.uri.scheme === 'ssh' && f.uri.authority === name);
return { return {
label: name, label: config && config.label || name,
contextValue: active ? 'active' : 'inactive', contextValue: active ? 'active' : 'inactive',
tooltip: config ? (active ? 'Active' : 'Inactive') : 'Active but deleted', tooltip: config ? (active ? 'Active' : 'Inactive') : 'Active but deleted',
}; };
@ -40,15 +41,14 @@ function createConfigFs(manager: Manager): SSHFileSystem {
stat: (uri: vscode.Uri) => ({ type: vscode.FileType.File, ctime: 0, mtime: 0, size: 0 } as vscode.FileStat), stat: (uri: vscode.Uri) => ({ type: vscode.FileType.File, ctime: 0, mtime: 0, size: 0 } as vscode.FileStat),
readFile: async (uri: vscode.Uri) => { readFile: async (uri: vscode.Uri) => {
const name = uri.path.substring(1, uri.path.length - 12); const name = uri.path.substring(1, uri.path.length - 12);
let config = manager.getConfig(name); const config = manager.getConfig(name);
let str; let str;
if (config) { if (config) {
str = JSON.stringify(config, undefined, 4); str = JSON.stringify({ ...config, name: undefined }, undefined, 4);
str = `// If you haven't already, associate .jsonc files with "JSON with Comments (jsonc)"\n${str}`; str = `// If you haven't already, associate .jsonc files with "JSON with Comments (jsonc)"\n${str}`;
} else { } else {
str = await toPromise<string>(cb => readFile(path.resolve(__dirname, '../resources/defaultConfig.jsonc'), 'utf-8', cb)); str = await toPromise<string>(cb => readFile(path.resolve(__dirname, '../resources/defaultConfig.jsonc'), 'utf-8', cb));
} }
config = { ...config, name: undefined! };
return new Uint8Array(new Buffer(str)); return new Uint8Array(new Buffer(str));
}, },
writeFile: (uri: vscode.Uri, content: Uint8Array) => { writeFile: (uri: vscode.Uri, content: Uint8Array) => {
@ -112,7 +112,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
public invalidConfigName(name: string) { public invalidConfigName(name: string) {
if (!name) return 'Missing a name for this SSH FS'; if (!name) return 'Missing a name for this SSH FS';
if (name.match(/^[\w_\\\/\.@\-+]+$/)) return null; if (name.match(/^[\w_\\\/\.@\-+]+$/)) return null;
return `A SSH FS name can only exists of alphanumeric characters, slashes and any of these: _.+-@`; return `A SSH FS name can only exists of lowercase alphanumeric characters, slashes and any of these: _.+-@`;
} }
public getConfig(name: string) { public getConfig(name: string) {
if (name === '<config>') return null; if (name === '<config>') return null;
@ -135,7 +135,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
let promise = this.creatingFileSystems[name]; let promise = this.creatingFileSystems[name];
if (promise) return promise; if (promise) return promise;
// config = config || this.memento.get(`fs.config.${name}`); // config = config || this.memento.get(`fs.config.${name}`);
config = config || (await this.loadConfigs()).find(c => c.name === name); config = config || this.loadConfigs().find(c => c.name === name);
promise = new Promise<SSHFileSystem>(async (resolve, reject) => { promise = new Promise<SSHFileSystem>(async (resolve, reject) => {
if (!config) { if (!config) {
throw new Error(`A SSH filesystem with the name '${name}' doesn't exist`); throw new Error(`A SSH filesystem with the name '${name}' doesn't exist`);
@ -200,7 +200,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
return reject(err); return reject(err);
} }
sftp.on('end', () => client.end()); sftp.on('end', () => client.end());
const fs = new SSHFileSystem(name, sftp, config!.root || '/'); const fs = new SSHFileSystem(name, sftp, config!.root || '/', config!);
this.fileSystems.push(fs); this.fileSystems.push(fs);
delete this.creatingFileSystems[name]; delete this.creatingFileSystems[name];
vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer'); vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
@ -241,7 +241,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
return this.creatingFileSystems[name] = promise; return this.creatingFileSystems[name] = promise;
} }
public getActive() { public getActive() {
return this.fileSystems.map(fs => fs.authority); return this.fileSystems.map(fs => fs.config);
} }
public async getFs(uri: vscode.Uri) { public async getFs(uri: vscode.Uri) {
const fs = this.fileSystems.find(f => f.authority === uri.authority); const fs = this.fileSystems.find(f => f.authority === uri.authority);
@ -310,7 +310,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
this.commandConnect(name); this.commandConnect(name);
} }
public commandConnect(name: string) { public commandConnect(name: string) {
if (this.getActive().indexOf(name) !== -1) return vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer'); if (this.getActive().find(fs => fs.name === name)) return vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
const folders = vscode.workspace.workspaceFolders!; const folders = vscode.workspace.workspaceFolders!;
const folder = folders && folders.find(f => f.uri.scheme === 'ssh' && f.uri.authority === name); const folder = folders && folders.find(f => f.uri.scheme === 'ssh' && f.uri.authority === name);
if (folder) { if (folder) {
@ -337,6 +337,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
...(inspect.workspaceValue || []), ...(inspect.workspaceValue || []),
...(inspect.globalValue || []), ...(inspect.globalValue || []),
]; ];
configs.forEach(c => c.name = c.name.toLowerCase());
configs = configs.filter((c, i) => configs.findIndex(c2 => c2.name === c.name) === i); configs = configs.filter((c, i) => configs.findIndex(c2 => c2.name === c.name) === i);
for (const index in configs) { for (const index in configs) {
if (!configs[index].name) { if (!configs[index].name) {

@ -3,7 +3,7 @@ import * as path from 'path';
import * as ssh2 from 'ssh2'; import * as ssh2 from 'ssh2';
import * as ssh2s from 'ssh2-streams'; import * as ssh2s from 'ssh2-streams';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { FileSystemConfig } from './manager';
import { toPromise } from './toPromise'; import { toPromise } from './toPromise';
export class SSHFileSystem implements vscode.FileSystemProvider { export class SSHFileSystem implements vscode.FileSystemProvider {
@ -11,7 +11,8 @@ export class SSHFileSystem implements vscode.FileSystemProvider {
public onDidChangeFile: vscode.Event<vscode.FileChangeEvent[]>; public onDidChangeFile: vscode.Event<vscode.FileChangeEvent[]>;
protected onDidChangeFileEmitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>(); protected onDidChangeFileEmitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>();
constructor(public readonly authority: string, protected sftp: ssh2.SFTPWrapper, public readonly root: string) { constructor(public readonly authority: string, protected sftp: ssh2.SFTPWrapper,
public readonly root: string, public readonly config: FileSystemConfig) {
this.onDidChangeFile = this.onDidChangeFileEmitter.event; this.onDidChangeFile = this.onDidChangeFileEmitter.event;
} }

Loading…
Cancel
Save