-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(vscode): multi workspace support & only load au2 extension if pa…
- Loading branch information
1 parent
99b90ed
commit 2665faf
Showing
5 changed files
with
111 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { workspace as Workspace, OutputChannel } from 'vscode'; | ||
import { LanguageClient, TransportKind, LanguageClientOptions, ServerOptions, WorkspaceFolder } from 'vscode-languageclient'; | ||
import * as path from 'path'; | ||
import { asyncForEach } from './util/asyncForEach'; | ||
import { clients } from './clients'; | ||
|
||
/** | ||
* Responsible for creating clients for each separate workspace | ||
* | ||
* @export | ||
* @class WorkspaceLoader | ||
*/ | ||
export class WorkspaceLoader { | ||
|
||
constructor(private channel: OutputChannel, private serverModule: string) { | ||
} | ||
|
||
/** | ||
* Load the initial workspace state and subscribe to changes of the workspace(s). | ||
* | ||
* @memberof WorkspaceLoader | ||
*/ | ||
public async load() { | ||
|
||
this.channel.appendLine('⚙️ checking workspaces for Aurelia workspaces'); | ||
await this.initializeWorkspaces(); | ||
this.watchForWorkspaceChanges(); | ||
} | ||
|
||
private async initializeWorkspaces() { | ||
try { | ||
await asyncForEach(Workspace.workspaceFolders, this.addWorkspaceFolder.bind(this)); | ||
} catch(err) { | ||
this.channel.appendLine(err); | ||
} | ||
|
||
} | ||
|
||
private watchForWorkspaceChanges() { | ||
Workspace.onDidChangeWorkspaceFolders(async (event) => { | ||
|
||
if (event.added.length > 0) { | ||
this.channel.appendLine('⚙️ checking newly added workspace(s)'); | ||
await asyncForEach(event.added, this.addWorkspaceFolder.bind(this)); | ||
} | ||
|
||
if (event.removed.length > 0) { | ||
this.channel.appendLine('⚙️ checking removed workspace(s)'); | ||
for (let folder of event.removed) { | ||
let client = clients.get(folder.uri.toString()); | ||
if (client) { | ||
clients.delete(folder.uri.toString()); | ||
client.stop(); | ||
this.channel.appendLine('⚰️ client stopped and deleted'); | ||
} | ||
} | ||
} | ||
|
||
}); | ||
} | ||
|
||
private async addWorkspaceFolder(folder) { | ||
|
||
this.channel.appendLine(" ⚙️ processing workspace: " + folder.uri.toString()); | ||
|
||
const workspacePath = folder.uri.fsPath; | ||
const packageJsonPath = path.join(workspacePath, 'package.json'); | ||
const document = await Workspace.openTextDocument(packageJsonPath); | ||
|
||
let packageJson = JSON.parse(document.getText()); | ||
let isAureliaProject = false; | ||
for (let npmPackage in packageJson.dependencies) { | ||
if (packageJson.dependencies[npmPackage] && npmPackage.startsWith('@aurelia/')) { | ||
isAureliaProject = true; | ||
break; | ||
} | ||
} | ||
if (!isAureliaProject) { | ||
return; | ||
} | ||
this.channel.appendLine(" 🌱 activating Aurelia2 plugin for workspace: " + folder.uri.toString()); | ||
const debugOptions = { execArgv: ["--nolazy", `--inspect=${6011 + clients.size}`] }; | ||
const serverOptions: ServerOptions = { | ||
run: { module: this.serverModule, transport: TransportKind.ipc }, | ||
debug: { module: this.serverModule, transport: TransportKind.ipc, options: debugOptions } | ||
}; | ||
const clientOptions: LanguageClientOptions = { | ||
documentSelector: [ | ||
{ scheme: 'file', language: 'plaintext', pattern: `${folder.uri.toString()}/**/*` } | ||
], | ||
diagnosticCollectionName: 'aurelia|' + folder.uri.toString(), | ||
workspaceFolder: folder, | ||
outputChannel: this.channel | ||
}; | ||
const client = new LanguageClient('aurelia', serverOptions, clientOptions); | ||
client.start(); | ||
clients.set(folder.uri.toString(), client); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { LanguageClient } from 'vscode-languageclient'; | ||
|
||
export const clients: Map<string, LanguageClient> = new Map(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,16 @@ | ||
import { | ||
workspace as Workspace, | ||
ExtensionContext, | ||
window as Window | ||
} from 'vscode'; | ||
import * as path from 'path'; | ||
import { WorkspaceLoader } from './WorkspaceLoader'; | ||
|
||
import { | ||
LanguageClient, TransportKind, LanguageClientOptions, ServerOptions | ||
} from 'vscode-languageclient'; | ||
|
||
let clients: Map<string, LanguageClient> = new Map(); | ||
|
||
export function activate(context: ExtensionContext) { | ||
export async function activate(context: ExtensionContext) { | ||
|
||
const channel = Window.createOutputChannel('aurelia'); | ||
channel.appendLine('checking workspaces for Aurelia workspaces'); | ||
|
||
workspacePluginLoader(channel, context); | ||
|
||
await new WorkspaceLoader(channel, context.asAbsolutePath(path.join('server', 'dist', 'server.js'))).load(); | ||
} | ||
|
||
export function deactivate(): Thenable<void> { | ||
return Promise.resolve(); | ||
} | ||
|
||
/** | ||
* Load the plugin for each seperate workspace (Proof of Concept) | ||
*/ | ||
function workspacePluginLoader(channel, context) { | ||
const serverModule = context.asAbsolutePath(path.join('server', 'dist', 'server.js')); | ||
|
||
// Initial check of workspaces | ||
Workspace.workspaceFolders.forEach(async (folder) => { | ||
|
||
channel.appendLine("processing workspace: " + folder.uri.toString()); | ||
|
||
const workspacePath = folder.uri.fsPath; | ||
const packageJsonPath = path.join(workspacePath, 'package.json'); | ||
const document = await Workspace.openTextDocument(packageJsonPath); | ||
let packageJson = JSON.parse(document.getText()); | ||
|
||
// TODO: figure out if this is the right way to detect it's an Aurelia 2 workspace | ||
if (!packageJson.dependencies.hasOwnProperty('@aurelia/runtime')) { | ||
return; | ||
} | ||
|
||
channel.appendLine("activating Aurelia plugin for workspace: " + folder.uri.toString()); | ||
|
||
const debugOptions = { execArgv: ["--nolazy", `--inspect=${6011 + clients.size}`] }; | ||
const serverOptions: ServerOptions = { | ||
run: { module: serverModule, transport: TransportKind.ipc }, | ||
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions} | ||
}; | ||
const clientOptions: LanguageClientOptions = { | ||
documentSelector: [ | ||
{ scheme: 'file', language: 'plaintext', pattern: `${folder.uri.fsPath}/**/*` } | ||
], | ||
diagnosticCollectionName: 'aurelia|' + workspacePath, | ||
workspaceFolder: folder, | ||
outputChannel: channel | ||
} | ||
|
||
const client = new LanguageClient('aurelia', serverOptions, clientOptions); | ||
client.start(); | ||
clients.set(workspacePath, client); | ||
|
||
}); | ||
|
||
Workspace.onDidChangeWorkspaceFolders((event) => { | ||
|
||
// add client if workspace is added | ||
for (let folder of event.removed) { | ||
channel.appendLine("workspace added :" + folder.uri.fsPath); | ||
} | ||
|
||
// remove client when workspace is removed | ||
for (let folder of event.removed) { | ||
let client = clients.get(folder.uri.fsPath); | ||
channel.appendLine("workspace deleted :" + folder.uri.fsPath); | ||
if (client) { | ||
clients.delete(folder.uri.toString()); | ||
client.stop(); | ||
} | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export async function asyncForEach(array, callback) { | ||
for (let index = 0; index < array.length; index++) { | ||
await callback(array[index], index, array); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters