From 7249b9502ff10b4ce209149afeb5656b125f51de Mon Sep 17 00:00:00 2001 From: Dmitry Maslennikov Date: Fri, 25 Jan 2019 18:55:18 +0300 Subject: [PATCH] multi-root for server explorer --- CHANGELOG.md | 3 +- api/index.ts | 30 ++++++--- commands/compile.ts | 12 ++-- commands/export.ts | 10 +-- commands/viewOthers.ts | 19 +----- commands/xml2doc.ts | 2 +- explorer/explorer.ts | 62 ++++++------------ explorer/models/classesNode.ts | 12 +++- explorer/models/nodeBase.ts | 2 +- explorer/models/packageNode.ts | 11 +++- explorer/models/rootNode.ts | 60 +++++++++--------- explorer/models/routineNode.ts | 11 +++- explorer/models/workspaceNode.ts | 69 +++++++++++++++++++++ extension.ts | 58 +++++++++++------ providers/DocumentContentProvider.ts | 40 +++++++++--- providers/ObjectScriptDefinitionProvider.ts | 6 +- 16 files changed, 257 insertions(+), 150 deletions(-) create mode 100644 explorer/models/workspaceNode.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 6de15ccb..7db1c21f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ - Preview XML As UDL by command from Command Palette and from Context Menu - Fixed highlighting for XData with css in style tag - Show percent-member in outline -- Multi-root workspace supported now, for different connections. +- Multi-root workspace supported now, for different connections +- Multi-root workspace also for server explorer ## [0.7.7] diff --git a/api/index.ts b/api/index.ts index 22ed0b06..ece3462f 100644 --- a/api/index.ts +++ b/api/index.ts @@ -1,21 +1,26 @@ import * as httpModule from 'http'; import * as httpsModule from 'https'; import * as vscode from 'vscode'; -import { outputConsole } from '../utils'; -import { config } from '../extension'; +import { outputConsole, outputChannel } from '../utils'; +import { config, currentWorkspaceFolder } from '../extension'; +import { type } from 'os'; export class AtelierAPI { private cookies: string[] = []; + private _config: any; + private _namespace: string; - private get config(): any { - return config().get('conn'); + private get ns(): string { + return this._namespace || this._config.ns; } - private get ns(): string { - return this.config.ns; + constructor() { + this.setConnection(currentWorkspaceFolder()); } - constructor() {} + setNamespace(namespace: string) { + this._namespace = namespace; + } updateCookies(cookies: string[]) { cookies.forEach(cookie => { @@ -29,8 +34,13 @@ export class AtelierAPI { }); } + setConnection(workspaceFolderName: string) { + let conn = config('conn', workspaceFolderName); + this._config = conn; + } + request(method: string, path?: string, params?: any, headers?: any, body?: any): Promise { - if (!config().conn.active) { + if (!this._config.active) { return Promise.reject(); } headers = { @@ -60,8 +70,8 @@ export class AtelierAPI { } headers['Cache-Control'] = 'no-cache'; - const { host, port, username, password } = this.config; - const http: any = this.config.https ? httpsModule : httpModule; + const { host, port, username, password } = this._config; + const http: any = this._config.https ? httpsModule : httpModule; const agent = new http.Agent({ keepAlive: true, maxSockets: 10 }); path = encodeURI(`/api/atelier/${path || ''}${buildParams()}`); console.log(`API request: ${method} ${path}`); diff --git a/commands/compile.ts b/commands/compile.ts index 067a2509..76902c4e 100644 --- a/commands/compile.ts +++ b/commands/compile.ts @@ -2,9 +2,8 @@ import vscode = require('vscode'); import fs = require('fs'); import { AtelierAPI } from '../api'; import { currentFile, CurrentFile, outputChannel } from '../utils'; -import { OBJECTSCRIPT_FILE_SCHEMA, documentContentProvider, config } from '../extension'; - -const api = new AtelierAPI(); +import { documentContentProvider, config } from '../extension'; +import { DocumentContentProvider } from '../providers/DocumentContentProvider'; async function compileFlags(): Promise { const defaultFlags = config().compileFlags; @@ -15,6 +14,7 @@ async function compileFlags(): Promise { } async function importFile(file: CurrentFile, flags: string): Promise { + const api = new AtelierAPI(); return api .putDoc( file.name, @@ -34,12 +34,13 @@ async function importFile(file: CurrentFile, flags: string): Promise { function updateOthers(others: string[]) { others.forEach(item => { - const uri = vscode.Uri.parse(encodeURI(`${OBJECTSCRIPT_FILE_SCHEMA}:///${item}`)); + const uri = DocumentContentProvider.getUri(item); documentContentProvider.update(uri); }); } async function loadChanges(file: CurrentFile): Promise { + const api = new AtelierAPI(); return api.getDoc(file.name).then(data => { fs.writeFileSync(file.fileName, (data.result.content || []).join('\n')); api @@ -50,6 +51,7 @@ async function loadChanges(file: CurrentFile): Promise { } async function compile(file: CurrentFile, flags: string): Promise { + const api = new AtelierAPI(); return api .actionCompile([file.name], flags) .then(data => { @@ -68,7 +70,7 @@ export async function importAndCompile(askFLags = false): Promise { if (!file) { return; } - if (!config().conn.active) { + if (!config('conn').active) { return; } const defaultFlags = config().compileFlags; diff --git a/commands/export.ts b/commands/export.ts index 4ca74e11..132f9b0d 100644 --- a/commands/export.ts +++ b/commands/export.ts @@ -8,8 +8,6 @@ import { ClassNode } from '../explorer/models/classesNode'; import { RoutineNode } from '../explorer/models/routineNode'; import { config } from '../extension'; -const api = new AtelierAPI(); - const filesFilter = (file: any) => { if (file.cat === 'CSP' || file.name.startsWith('%') || file.name.startsWith('INFORMATION.')) { return false; @@ -30,9 +28,10 @@ const getFileName = (folder: string, name: string, split: boolean): string => { }; export async function exportFile(name: string, fileName: string): Promise { - if (!config().conn.active) { + if (!config('conn').active) { return; } + const api = new AtelierAPI(); const log = status => outputChannel.appendLine(`export "${name}" as "${fileName}" - ${status}`); const folders = path.dirname(fileName); return mkdirSyncRecursive(folders) @@ -65,9 +64,10 @@ export async function exportList(files: string[]): Promise { } export async function exportAll(): Promise { - if (!config().conn.active) { + if (!config('conn').active) { return; } + const api = new AtelierAPI(); outputChannel.show(true); const { category, generated, filter } = config().get('export'); const files = data => data.result.content.filter(filesFilter).map(file => file.name); @@ -77,7 +77,7 @@ export async function exportAll(): Promise { } export async function exportExplorerItem(node: PackageNode | ClassNode | RoutineNode): Promise { - if (!config().conn.active) { + if (!config('conn').active) { return; } const items = node instanceof PackageNode ? node.getClasses() : [node.fullName]; diff --git a/commands/viewOthers.ts b/commands/viewOthers.ts index a393d04c..d9e08786 100644 --- a/commands/viewOthers.ts +++ b/commands/viewOthers.ts @@ -2,6 +2,7 @@ import * as vscode from 'vscode'; import { OBJECTSCRIPT_FILE_SCHEMA, config } from '../extension'; import { AtelierAPI } from '../api'; import { currentFile } from '../utils'; +import { DocumentContentProvider } from '../providers/DocumentContentProvider'; export async function viewOthers(): Promise { const api = new AtelierAPI(); @@ -9,26 +10,12 @@ export async function viewOthers(): Promise { if (!file) { return; } - if (!config().conn.active) { + if (!config('conn').active) { return; } const open = item => { - let uri = vscode.Uri.file(item).with({ - scheme: OBJECTSCRIPT_FILE_SCHEMA - }); - if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) { - if (file.uri.scheme === 'file') { - const workspaceFolder = vscode.workspace.getWorkspaceFolder(file.uri); - uri = uri.with({ - authority: workspaceFolder.name - }); - } else { - uri = uri.with({ - authority: file.uri.authority - }); - } - } + let uri = DocumentContentProvider.getUri(item); vscode.window.showTextDocument(uri); }; diff --git a/commands/xml2doc.ts b/commands/xml2doc.ts index ea991150..b9a20750 100644 --- a/commands/xml2doc.ts +++ b/commands/xml2doc.ts @@ -4,7 +4,7 @@ import { XmlContentProvider } from '../providers/XmlContentProvider'; export async function xml2doc(context: vscode.ExtensionContext, textEditor: vscode.TextEditor): Promise { const xmlContentProvider: XmlContentProvider = context.workspaceState.get('xmlContentProvider'); - if (!config().conn.active) { + if (!config('conn').active) { return; } diff --git a/explorer/explorer.ts b/explorer/explorer.ts index 48202e55..659eef67 100644 --- a/explorer/explorer.ts +++ b/explorer/explorer.ts @@ -3,24 +3,17 @@ import { NodeBase } from './models/nodeBase'; import { RootNode } from './models/rootNode'; import { AtelierAPI } from './../api'; -import { config } from '../extension'; +import { config, workspaceState } from '../extension'; +import { outputChannel } from '../utils'; +import { WorkspaceNode } from './models/workspaceNode'; export class ObjectScriptExplorerProvider implements vscode.TreeDataProvider { onDidChange?: vscode.Event; private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - private _classesNode: RootNode; - private _routinesNode: RootNode; - private _api: AtelierAPI; private _showSystem = false; - private get _namespace(): string { - return config().conn.ns; - } - - constructor() { - this._api = new AtelierAPI(); - } + constructor() {} get showSystem(): boolean { return this._showSystem; @@ -32,10 +25,7 @@ export class ObjectScriptExplorerProvider implements vscode.TreeDataProvider { - const rootNodes: RootNode[] = []; - let node: RootNode; - let data: any; - - data = await this.getDocNames('CLS'); - node = new RootNode('Classes', 'classesRootNode', this._onDidChangeTreeData, data); - this._classesNode = node; - rootNodes.push(node); + private async getRootNodes(): Promise { + const rootNodes: NodeBase[] = []; + let node: NodeBase; - data = await this.getDocNames('RTN'); - node = new RootNode('Routines', 'routinesRootNode', this._onDidChangeTreeData, data); - this._routinesNode = node; - rootNodes.push(node); + let workspaceFolders = vscode.workspace.workspaceFolders || []; + workspaceFolders.forEach(workspaceFolder => { + let conn: any = config('conn', workspaceFolder.name); + if (conn.active) { + node = new WorkspaceNode(workspaceFolder.name, this._onDidChangeTreeData, workspaceFolder.uri); + rootNodes.push(node); + if (this.showSystem) { + node = new WorkspaceNode(workspaceFolder.name, this._onDidChangeTreeData, workspaceFolder.uri, true); + rootNodes.push(node); + } + } + }); return rootNodes; } - - getDocNames(category: string): Promise { - const excludeSystem = - this._showSystem || this._namespace === '%SYS' - ? () => true - : ({ db }) => !['IRISLIB', 'IRISSYS', 'CACHELIB', 'CACHESYS'].includes(db); - - return this._api - .getDocNames({ - category - }) - .then(data => { - let content = data.result.content; - return content.filter(excludeSystem); - }); - } } diff --git a/explorer/models/classesNode.ts b/explorer/models/classesNode.ts index 970a6b42..144cfffe 100644 --- a/explorer/models/classesNode.ts +++ b/explorer/models/classesNode.ts @@ -1,10 +1,16 @@ import * as vscode from 'vscode'; import { NodeBase } from './nodeBase'; -import { OBJECTSCRIPT_FILE_SCHEMA } from '../../extension'; +import { DocumentContentProvider } from '../../providers/DocumentContentProvider'; +import { outputChannel } from '../../utils'; export class ClassNode extends NodeBase { public static readonly contextValue: string = 'classNode'; - constructor(public readonly label: string, public readonly fullName: string) { + constructor( + public readonly label: string, + public readonly fullName: string, + private _workspaceFolder: string, + private _namespace: string + ) { super(label); } @@ -17,7 +23,7 @@ export class ClassNode extends NodeBase { contextValue: 'classNode', command: { command: 'vscode-objectscript.explorer.openClass', - arguments: [vscode.Uri.parse(encodeURI(`${OBJECTSCRIPT_FILE_SCHEMA}:///${this.fullName}`))], + arguments: [DocumentContentProvider.getUri(this.fullName, this._workspaceFolder, this._namespace)], title: 'Open class' } // iconPath: { diff --git a/explorer/models/nodeBase.ts b/explorer/models/nodeBase.ts index ffd4db71..55054870 100644 --- a/explorer/models/nodeBase.ts +++ b/explorer/models/nodeBase.ts @@ -1,4 +1,4 @@ -import * as vscode from "vscode"; +import * as vscode from 'vscode'; export class NodeBase { readonly label: string; diff --git a/explorer/models/packageNode.ts b/explorer/models/packageNode.ts index d51d3421..c8955a82 100644 --- a/explorer/models/packageNode.ts +++ b/explorer/models/packageNode.ts @@ -4,7 +4,12 @@ import { ClassNode } from './classesNode'; export class PackageNode extends NodeBase { public static readonly contextValue: string = 'packageNode'; - constructor(public readonly label: string, private readonly _items) { + constructor( + public readonly label: string, + private readonly _items, + private readonly _workspaceFolder: string, + private _namespace: string + ) { super(label); } @@ -24,7 +29,9 @@ export class PackageNode extends NodeBase { async getChildren(element): Promise { return this._items.map(({ name, fullName, nodes }) => - nodes.length ? new PackageNode(name, nodes) : new ClassNode(name, fullName) + nodes.length + ? new PackageNode(name, nodes, this._workspaceFolder, this._namespace) + : new ClassNode(name, fullName, this._workspaceFolder, this._namespace) ); } diff --git a/explorer/models/rootNode.ts b/explorer/models/rootNode.ts index 8f1b36d9..382574ef 100644 --- a/explorer/models/rootNode.ts +++ b/explorer/models/rootNode.ts @@ -1,67 +1,71 @@ -import * as vscode from "vscode"; +import * as vscode from 'vscode'; -import { NodeBase } from "./nodeBase"; -import { PackageNode } from "./packageNode"; -import { RoutineNode } from "./routineNode"; +import { NodeBase } from './nodeBase'; +import { PackageNode } from './packageNode'; +import { RoutineNode } from './routineNode'; export class RootNode extends NodeBase { - constructor( public readonly label: string, public readonly contextValue: string, public eventEmitter: vscode.EventEmitter, - private _items: any[] + private _items: any[], + private _workspaceFolder: string, + private _namespace: string ) { super(label); } getTreeItem(): vscode.TreeItem { return { - label: this.label, - collapsibleState: vscode.TreeItemCollapsibleState.Collapsed, - contextValue: this.contextValue - } - -} + label: this.label, + collapsibleState: vscode.TreeItemCollapsibleState.Collapsed, + contextValue: this.contextValue + }; + } async getChildren(element): Promise { if (element.contextValue === 'classesRootNode') { - return this.getClasses(); + return this.getClasses(); } if (element.contextValue === 'routinesRootNode') { - return this.getRoutines(); + return this.getRoutines(); } - } private async getClasses(): Promise { let items = this.makeTree(this._items); - return items.map(({name, nodes}) => new PackageNode(name, nodes)); + return items.map(({ name, nodes }) => new PackageNode(name, nodes, this._workspaceFolder, this._namespace)); } private async getRoutines(): Promise { - return this._items.map(({name}) => new RoutineNode(name, name)); + return this._items.map(({ name }) => new RoutineNode(name, name, this._workspaceFolder, this._namespace)); } private makeTree(items: any[]): any[] { let tree; - tree = items.map(({name}) => ({name})); + tree = items.map(({ name }) => ({ name })); tree.forEach(el => { - let parent = el.name.split('.').slice(0, -2); - el.parent = parent.join('.'); - el.fullName = el.name; - el.name = el.name.split('.').slice(-2).join('.'); - let parents = parent.map((name, i) => { return {name, fullName: (parent.slice(0, i+1).join('.')), parent: (parent.slice(0, i).join('.'))}}); - tree = tree.concat(parents); + let parent = el.name.split('.').slice(0, -2); + el.parent = parent.join('.'); + el.fullName = el.name; + el.name = el.name + .split('.') + .slice(-2) + .join('.'); + let parents = parent.map((name, i) => { + return { name, fullName: parent.slice(0, i + 1).join('.'), parent: parent.slice(0, i).join('.') }; + }); + tree = tree.concat(parents); }); - tree = tree.filter((value, index, self) => self.findIndex(({fullName}) => fullName === value.fullName) === index); - tree = tree.sort((el1, el2) => el1.fullName < el2.fullName ? -1 : el1.fullName > el2.fullName ? 1 : 0); + tree = tree.filter((value, index, self) => self.findIndex(({ fullName }) => fullName === value.fullName) === index); + tree = tree.sort((el1, el2) => (el1.fullName < el2.fullName ? -1 : el1.fullName > el2.fullName ? 1 : 0)); tree.forEach(el => { - el.nodes = tree.filter(ch => el.fullName === ch.parent); + el.nodes = tree.filter(ch => el.fullName === ch.parent); }); - tree = tree.filter(el => el.parent === ""); + tree = tree.filter(el => el.parent === ''); return tree; } diff --git a/explorer/models/routineNode.ts b/explorer/models/routineNode.ts index 110dae28..ff4626c9 100644 --- a/explorer/models/routineNode.ts +++ b/explorer/models/routineNode.ts @@ -1,10 +1,15 @@ import * as vscode from 'vscode'; import { NodeBase } from './nodeBase'; -import { OBJECTSCRIPT_FILE_SCHEMA } from '../../extension'; +import { DocumentContentProvider } from '../../providers/DocumentContentProvider'; export class RoutineNode extends NodeBase { public static readonly contextValue: string = 'routineNode'; - constructor(public readonly label: string, public readonly fullName: string) { + constructor( + public readonly label: string, + public readonly fullName: string, + private _workspaceFolder: string, + private _namespace: string + ) { super(label); } @@ -17,7 +22,7 @@ export class RoutineNode extends NodeBase { contextValue: 'routineNode', command: { command: 'vscode-objectscript.explorer.openRoutine', - arguments: [vscode.Uri.parse(encodeURI(`${OBJECTSCRIPT_FILE_SCHEMA}:///${this.fullName}`))], + arguments: [DocumentContentProvider.getUri(this.fullName, this._workspaceFolder, this._namespace)], title: 'Open routine' } // iconPath: { diff --git a/explorer/models/workspaceNode.ts b/explorer/models/workspaceNode.ts new file mode 100644 index 00000000..120fd161 --- /dev/null +++ b/explorer/models/workspaceNode.ts @@ -0,0 +1,69 @@ +import * as vscode from 'vscode'; + +import { NodeBase } from './nodeBase'; +import { RootNode } from './rootNode'; +import { AtelierAPI } from '../../api'; +import { config } from '../../extension'; + +export class WorkspaceNode extends NodeBase { + private _conn: any; + private _namespace: string; + + constructor( + public readonly label: string, + public eventEmitter: vscode.EventEmitter, + private _uri: vscode.Uri, + private _showSystem: boolean = false + ) { + super(label); + this._conn = config('conn', this.label); + this._namespace = this._conn.ns; + if (this._showSystem) { + this._namespace = '%SYS'; + } + this._showSystem = this._showSystem || this._namespace === '%SYS'; + } + + getTreeItem(): vscode.TreeItem { + return { + label: `${this.label}${this._showSystem ? ' - System' : ''}`, + collapsibleState: vscode.TreeItemCollapsibleState.Expanded + }; + } + + async getChildren(element): Promise { + let children = []; + let node: RootNode; + let data: any; + let workspaceFolder = element.label; + + data = await this.getDocNames('CLS'); + node = new RootNode('Classes', 'classesRootNode', this.eventEmitter, data, workspaceFolder, this._namespace); + children.push(node); + + data = await this.getDocNames('RTN'); + node = new RootNode('Routines', 'routinesRootNode', this.eventEmitter, data, workspaceFolder, this._namespace); + children.push(node); + + return children; + } + + getDocNames(category: string): Promise { + const excludeSystem = + this._showSystem || this._namespace === '%SYS' + ? () => true + : ({ db }) => !['IRISLIB', 'IRISSYS', 'CACHELIB', 'CACHESYS'].includes(db); + + let api = new AtelierAPI(); + api.setNamespace(this._namespace); + api.setConnection(this.label); + return api + .getDocNames({ + category + }) + .then(data => { + let content = data.result.content; + return content.filter(excludeSystem); + }); + } +} diff --git a/extension.ts b/extension.ts index 9b7fbf26..7154574c 100644 --- a/extension.ts +++ b/extension.ts @@ -24,25 +24,22 @@ import { outputChannel, outputConsole } from './utils'; import { AtelierAPI } from './api'; export var explorerProvider: ObjectScriptExplorerProvider; export var documentContentProvider: DocumentContentProvider; +export var workspaceState: vscode.Memento; -export const config = () => { - const editor = vscode.window.activeTextEditor; - if (!editor || !vscode.workspace.workspaceFolders || vscode.workspace.workspaceFolders.length < 2) { - return vscode.workspace.getConfiguration('objectscript'); - } - let resource = editor.document.uri; - if (resource.scheme === 'file') { - return vscode.workspace.getConfiguration('objectscript', resource); - } - if (resource.scheme.startsWith('objectscript')) { - const workspaceFolderName = resource.authority; - if (!workspaceFolderName || workspaceFolderName === '') { - return vscode.workspace.getConfiguration('objectscript'); - } else { +export const config = (config?: string, workspaceFolderName?: string): any => { + workspaceFolderName = workspaceFolderName || currentWorkspaceFolder(); + + if (['conn'].includes(config)) { + if (workspaceFolderName !== '') { const workspaceFolder = vscode.workspace.workspaceFolders.find(el => el.name === workspaceFolderName); - return vscode.workspace.getConfiguration('objectscript', workspaceFolder.uri); + return vscode.workspace.getConfiguration('objectscript', workspaceFolder.uri).get(config); + } else { + return vscode.workspace.getConfiguration('objectscript', null).get(config); } } + if (config && config !== '') { + return vscode.workspace.getConfiguration('objectscript').get(config); + } return vscode.workspace.getConfiguration('objectscript'); }; @@ -56,9 +53,23 @@ export function getXmlUri(uri: vscode.Uri): vscode.Uri { }); } +export function currentWorkspaceFolder(): string { + let workspaceFolder; + if (vscode.window.activeTextEditor && vscode.window.activeTextEditor.document) { + const uri = vscode.window.activeTextEditor.document.uri; + if (uri.scheme === 'file') { + workspaceFolder = vscode.workspace.getWorkspaceFolder(uri).name; + } else if (uri.scheme.startsWith('objectscript')) { + workspaceFolder = uri.authority; + } + } + return workspaceFolder || workspaceState.get('workspaceFolder'); +} + export async function activate(context: vscode.ExtensionContext): Promise { const languages = require(context.asAbsolutePath('./package.json'))['contributes']['languages'].map(lang => lang.id); - const api = new AtelierAPI(); + workspaceState = context.workspaceState; + workspaceState.update('workspaceFolder', ''); explorerProvider = new ObjectScriptExplorerProvider(); documentContentProvider = new DocumentContentProvider(); @@ -72,13 +83,14 @@ export async function activate(context: vscode.ExtensionContext): Promise panel.tooltip = 'Open output'; panel.show(); const checkConnection = () => { - const conn = config().conn; + const conn = config('conn'); vscode.commands.executeCommand('setContext', 'vscode-objectscript.connectActive', conn.active); if (!conn.active) { panel.text = ''; return; } panel.text = `${conn.label}:${conn.ns}`; + const api = new AtelierAPI(); api .serverInfo() .then(info => { @@ -95,21 +107,27 @@ export async function activate(context: vscode.ExtensionContext): Promise }); workspace.onDidSaveTextDocument(file => { - if (!config().get('autoCompile') || !languages.includes(file.languageId)) { + if (!config('autoCompile') || !languages.includes(file.languageId)) { return; } vscode.commands.executeCommand('vscode-objectscript.compile'); }); vscode.window.onDidChangeActiveTextEditor((textEditor: vscode.TextEditor) => { - if (config().get('autoPreviewXML')) { + if (config('autoPreviewXML')) { xml2doc(context, textEditor); } }); context.subscriptions.push( window.onDidChangeActiveTextEditor(e => { - checkConnection(); + if (workspace.workspaceFolders && workspace.workspaceFolders.length > 1) { + let workspaceFolder = currentWorkspaceFolder(); + if (workspaceFolder && workspaceFolder !== workspaceState.get('workspaceFolder')) { + workspaceState.update('workspaceFolder', workspaceFolder); + checkConnection(); + } + } }), vscode.commands.registerCommand('vscode-objectscript.output', () => { diff --git a/providers/DocumentContentProvider.ts b/providers/DocumentContentProvider.ts index 68bdc5c8..cc7141c0 100644 --- a/providers/DocumentContentProvider.ts +++ b/providers/DocumentContentProvider.ts @@ -1,23 +1,45 @@ import * as vscode from 'vscode'; import { AtelierAPI } from './../api'; -import { OBJECTSCRIPT_FILE_SCHEMA } from '../extension'; - -export function getUri(name: string): vscode.Uri { - return vscode.Uri.parse(encodeURI(`${OBJECTSCRIPT_FILE_SCHEMA}:///${name}`)); -} +import { OBJECTSCRIPT_FILE_SCHEMA, workspaceState, currentWorkspaceFolder } from '../extension'; +const url = require('url'); export class DocumentContentProvider implements vscode.TextDocumentContentProvider { - private _api: AtelierAPI; private onDidChangeEvent: vscode.EventEmitter = new vscode.EventEmitter(); - constructor() { - this._api = new AtelierAPI(); + constructor() {} + + public static getUri(name: string, workspaceFolder?: string, namespace?: string): vscode.Uri { + workspaceFolder = workspaceFolder && workspaceFolder !== '' ? workspaceFolder : currentWorkspaceFolder(); + let uri = vscode.Uri.file(name).with({ + scheme: OBJECTSCRIPT_FILE_SCHEMA + }); + if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) { + if (workspaceFolder && workspaceFolder !== '') { + uri = uri.with({ + authority: workspaceFolder + }); + } + } + if (namespace && namespace !== '') { + uri = uri.with({ + query: `ns=${namespace}` + }); + } + return uri; } provideTextDocumentContent(uri: vscode.Uri, token: vscode.CancellationToken): vscode.ProviderResult { let fileName = uri.path.split('/')[1]; - return this._api.getDoc(fileName).then(data => { + const api = new AtelierAPI(); + let query = url.parse(decodeURIComponent(uri.toString()), true).query; + if (query) { + if (query.ns && query.ns !== '') { + api.setNamespace(query.ns); + } + } + api.setConnection(uri.authority); + return api.getDoc(fileName).then(data => { return data.result.content.join('\n'); }); } diff --git a/providers/ObjectScriptDefinitionProvider.ts b/providers/ObjectScriptDefinitionProvider.ts index 4aa3bbf7..d918adaf 100644 --- a/providers/ObjectScriptDefinitionProvider.ts +++ b/providers/ObjectScriptDefinitionProvider.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import { outputChannel } from '../utils'; -import { getUri } from './DocumentContentProvider'; +import { DocumentContentProvider } from './DocumentContentProvider'; export class ObjectScriptDefinitionProvider implements vscode.DefinitionProvider { provideDefinition( @@ -135,7 +135,7 @@ export class ObjectScriptDefinitionProvider implements vscode.DefinitionProvider new vscode.Position(position.line, end) ), targetRange: new vscode.Range(firstLinePos, firstLinePos), - targetUri: getUri(name) + targetUri: DocumentContentProvider.getUri(name) }; } @@ -147,7 +147,7 @@ export class ObjectScriptDefinitionProvider implements vscode.DefinitionProvider new vscode.Position(position.line, end) ), targetRange: new vscode.Range(firstLinePos, firstLinePos), - targetUri: getUri(name) + targetUri: DocumentContentProvider.getUri(name) }; } }