diff --git a/basic-multi-root-sample/.vscode/launch.json b/basic-multi-root-sample/.vscode/launch.json new file mode 100644 index 00000000..cd6b87bd --- /dev/null +++ b/basic-multi-root-sample/.vscode/launch.json @@ -0,0 +1,28 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +{ + "version": "0.1.0", + "configurations": [ + { + "name": "Launch Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], + "stopOnEntry": false, + "sourceMaps": true, + "outFiles": [ "${workspaceRoot}/out/src/**/*.js" ], + "preLaunchTask": "npm" + }, + { + "name": "Launch Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], + "stopOnEntry": false, + "sourceMaps": true, + "outFiles": [ "${workspaceRoot}/out/test/**/*.js" ], + "preLaunchTask": "npm" + } + ] +} diff --git a/basic-multi-root-sample/.vscode/settings.json b/basic-multi-root-sample/.vscode/settings.json new file mode 100644 index 00000000..d1371333 --- /dev/null +++ b/basic-multi-root-sample/.vscode/settings.json @@ -0,0 +1,9 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + } +} \ No newline at end of file diff --git a/basic-multi-root-sample/.vscode/tasks.json b/basic-multi-root-sample/.vscode/tasks.json new file mode 100644 index 00000000..1e37eb7b --- /dev/null +++ b/basic-multi-root-sample/.vscode/tasks.json @@ -0,0 +1,30 @@ +// Available variables which can be used inside of strings. +// ${workspaceRoot}: the root folder of the team +// ${file}: the current opened file +// ${fileBasename}: the current opened file's basename +// ${fileDirname}: the current opened file's dirname +// ${fileExtname}: the current opened file's extension +// ${cwd}: the current working directory of the spawned process + +// A task runner that calls a custom npm script that compiles the extension. +{ + "version": "0.1.0", + + // we want to run npm + "command": "npm", + + // the command is a shell script + "isShellCommand": true, + + // show the output window only if unrecognized errors occur. + "showOutput": "silent", + + // we run the custom script "compile" as defined in package.json + "args": ["run", "compile", "--loglevel", "silent"], + + // The tsc compiler is started in watching mode + "isBackground": true, + + // use the standard tsc in watch mode problem matcher to find compile problems in the output. + "problemMatcher": "$tsc-watch" +} \ No newline at end of file diff --git a/basic-multi-root-sample/README.md b/basic-multi-root-sample/README.md new file mode 100644 index 00000000..a0a85216 --- /dev/null +++ b/basic-multi-root-sample/README.md @@ -0,0 +1,14 @@ +# Basic multi root API samples + +This extension adds an entry to the status bar that shows the name of the currently active file. To excercise multi root APIs it: +- only enables itself when more than one `WorkspaceFolder` is opened using `workspace.workspaceFolders` API +- shows the name of the `WorkspaceFolder` the file is from (if any) using `workspace.getWorkspaceFolder()` API +- updates when there are changes to the number of `WorkspaceFolder` via the `workspace.onDidChangeWorkspaceFolders()` API +- registers a setting `multiRootSample.statusColor` with a scope of `resource` to configure a color per `WorkspaceFolder` to use for the status bar item + +## Running the example + +- Open this example in VS Code +- `npm install` +- `npm run compile` +- `F5` to start debugging diff --git a/basic-multi-root-sample/package.json b/basic-multi-root-sample/package.json new file mode 100644 index 00000000..4732c8e0 --- /dev/null +++ b/basic-multi-root-sample/package.json @@ -0,0 +1,46 @@ +{ + "name": "basic-multi-root-sample", + "displayName": "Basic Multi Root Sample", + "description": "Samples for VSCode's multi root API", + "version": "0.0.1", + "publisher": "ms-vscode", + "engines": { + "vscode": "^1.15.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "*" + ], + "main": "./out/src/extension", + "scripts": { + "vscode:prepublish": "tsc -p ./", + "compile": "tsc -watch -p ./", + "postinstall": "node ./node_modules/vscode/bin/install", + "test": "node ./node_modules/vscode/bin/test" + }, + "contributes": { + "configuration": { + "type": "object", + "title": "Basic Multi Root Sample", + "properties": { + "multiRootSample.statusColor": { + "type": [ + "string" + ], + "default": "#FFFFFF", + "description": "Color to use for the status bar item. Can be set per workspace folder.", + "scope": "resource" + } + } + } + }, + "devDependencies": { + "typescript": "^2.0.3", + "vscode": "^1.0.0", + "mocha": "^2.3.3", + "@types/node": "^6.0.40", + "@types/mocha": "^2.2.32" + } +} \ No newline at end of file diff --git a/basic-multi-root-sample/src/extension.ts b/basic-multi-root-sample/src/extension.ts new file mode 100644 index 00000000..b0f351f1 --- /dev/null +++ b/basic-multi-root-sample/src/extension.ts @@ -0,0 +1,74 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +'use strict'; + +import { ExtensionContext, StatusBarAlignment, window, StatusBarItem, Selection, workspace, TextEditor, commands } from 'vscode'; +import { basename } from 'path'; + +export function activate(context: ExtensionContext) { + + // Create a status bar item + const status = window.createStatusBarItem(StatusBarAlignment.Left, 1000000); + context.subscriptions.push(status); + + // Update status bar item based on events for multi root folder changes + context.subscriptions.push(workspace.onDidChangeWorkspaceFolders(e => updateStatus(status))); + + // Update status bar item based on events for configuration + context.subscriptions.push(workspace.onDidChangeConfiguration(e => this.updateStatus(status))); + + // Update status bar item based on events around the active editor + context.subscriptions.push(window.onDidChangeActiveTextEditor(e => updateStatus(status))); + context.subscriptions.push(window.onDidChangeTextEditorViewColumn(e => updateStatus(status))); + context.subscriptions.push(workspace.onDidOpenTextDocument(e => updateStatus(status))); + context.subscriptions.push(workspace.onDidCloseTextDocument(e => updateStatus(status))); + + updateStatus(status); +} + +function updateStatus(status: StatusBarItem): void { + const info = getEditorInfo(); + status.text = info ? info.text : void 0; + status.tooltip = info ? info.tooltip : void 0; + status.color = info ? info.color : void 0; + + if (info) { + status.show(); + } else { + status.hide(); + } +} + +function getEditorInfo(): { text: string; tooltip: string; color: string; } { + const editor = window.activeTextEditor; + + // If no workspace is opened or just a single folder, we return without any status label + // because our extension only works when more than one folder is opened in a workspace. + if (!editor || !workspace.workspaceFolders || workspace.workspaceFolders.length < 2) { + return null; + } + + let text: string; + let tooltip: string; + let color: string; + + // If we have a file:// resource we resolve the WorkspaceFolder this file is from and update + // the status accordingly. + const resource = editor.document.uri; + if (resource.scheme === 'file') { + const folder = workspace.getWorkspaceFolder(resource); + if (!folder) { + text = `$(alert) → ${basename(resource.fsPath)}`; + } + + text = `$(file-submodule) ${basename(folder.uri.fsPath)} → $(file-code) ${basename(resource.fsPath)}`; + tooltip = resource.fsPath; + + const multiRootConfigForResource = workspace.getConfiguration('multiRootSample', resource); + color = multiRootConfigForResource.get('statusColor'); + } + + return { text, tooltip, color }; +} diff --git a/basic-multi-root-sample/tsconfig.json b/basic-multi-root-sample/tsconfig.json new file mode 100644 index 00000000..11282c9a --- /dev/null +++ b/basic-multi-root-sample/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "out", + "lib": [ + "es6" + ], + "sourceMap": true, + "rootDir": "." + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +} \ No newline at end of file