diff --git a/configuration-sample/.gitignore b/configuration-sample/.gitignore new file mode 100644 index 00000000..8e5962ee --- /dev/null +++ b/configuration-sample/.gitignore @@ -0,0 +1,2 @@ +out +node_modules \ No newline at end of file diff --git a/configuration-sample/.vscode/launch.json b/configuration-sample/.vscode/launch.json new file mode 100644 index 00000000..03fdaddf --- /dev/null +++ b/configuration-sample/.vscode/launch.json @@ -0,0 +1,49 @@ +// 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" + }, + { + "type": "node", + "request": "attach", + "name": "Attach to Extension Host", + "protocol": "legacy", + "port": 5870, + "sourceMaps": true, + "restart": true, + "outFiles": [ + "${workspaceRoot}/out/src/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/configuration-sample/.vscode/settings.json b/configuration-sample/.vscode/settings.json new file mode 100644 index 00000000..7877e3fc --- /dev/null +++ b/configuration-sample/.vscode/settings.json @@ -0,0 +1,10 @@ +// 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 + }, + "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version +} \ No newline at end of file diff --git a/configuration-sample/.vscode/tasks.json b/configuration-sample/.vscode/tasks.json new file mode 100644 index 00000000..fb7f662e --- /dev/null +++ b/configuration-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 + "isWatching": 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/configuration-sample/.vscodeignore b/configuration-sample/.vscodeignore new file mode 100644 index 00000000..5ff3c193 --- /dev/null +++ b/configuration-sample/.vscodeignore @@ -0,0 +1,9 @@ +.vscode/** +.vscode-test/** +out/test/** +test/** +src/** +**/*.map +.gitignore +tsconfig.json +vsc-extension-quickstart.md diff --git a/configuration-sample/README.md b/configuration-sample/README.md new file mode 100644 index 00000000..9cd14515 --- /dev/null +++ b/configuration-sample/README.md @@ -0,0 +1,14 @@ +# Testing + +## Empty Workspace + +Explains how to test this extension in an Empty workspace + +## Folder Workspace + +Explains how to test this extension in a Folder workspace + +### Multiroot Workspace + +Explains how to test this extension in a Multiroot workspace + diff --git a/configuration-sample/package.json b/configuration-sample/package.json new file mode 100644 index 00000000..0aad6593 --- /dev/null +++ b/configuration-sample/package.json @@ -0,0 +1,72 @@ +{ + "name": "configuration-sample", + "displayName": "Configuration Sample", + "description": "How to contribute and use configurations in VS Code", + "version": "0.0.1", + "publisher": "ms-vscode", + "engines": { + "vscode": "^1.17.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "*" + ], + "main": "./out/src/extension", + "contributes": { + "configuration": [ + { + "title": "Configuration Samples", + "properties": { + "conf.view.showOnWindowOpen": { + "type": "string", + "enum": [ + "explorer", + "search", + "scm", + "debug", + "extensions" + ], + "default": "explorer", + "description": "Window configuration: View to show always when a window opens", + "scope": "window" + }, + "conf.resource.insertEmptyLastLine": { + "type": "object", + "default": {}, + "description": "Resource configurtion: Configure files using glob patterns to have an empty last line always", + "scope": "resource" + } + } + } + ], + "commands": [ + { + "category": "Configuration Sample", + "command": "config.commands.configureViewOnWindowOpen", + "title": "Configure view to show on window open" + }, + { + "category": "Configuration Sample", + "command": "config.commands.configureEmptyLastLineCurrentFile", + "title": "Configure empty last line for current file" + }, + { + "category": "Configuration Sample", + "command": "config.commands.configureEmptyLastLineFiles", + "title": "Configure empty last line for files" + } + ] + }, + "scripts": { + "vscode:prepublish": "tsc -p ./", + "compile": "tsc -watch -p ./", + "postinstall": "node ./node_modules/vscode/bin/install" + }, + "devDependencies": { + "typescript": "^2.1.4", + "vscode": "^1.0.0", + "@types/node": "*" + } +} \ No newline at end of file diff --git a/configuration-sample/src/extension.ts b/configuration-sample/src/extension.ts new file mode 100644 index 00000000..1cba097d --- /dev/null +++ b/configuration-sample/src/extension.ts @@ -0,0 +1,153 @@ +import * as vscode from 'vscode'; + +export function activate(context: vscode.ExtensionContext) { + + // Example 1: Reading Window scoped configuration + const configuredView = vscode.workspace.getConfiguration().get('conf.view.showOnWindowOpen'); + switch (configuredView) { + case 'explorer': + vscode.commands.executeCommand('workbench.view.explorer'); + break; + case 'search': + vscode.commands.executeCommand('workbench.view.search'); + break; + case 'scm': + vscode.commands.executeCommand('workbench.view.scm'); + break; + case 'debug': + vscode.commands.executeCommand('workbench.view.debug'); + break; + case 'extensions': + vscode.commands.executeCommand('workbench.view.extensions'); + break; + } + + // Example 2: Updating Window scoped configuration + vscode.commands.registerCommand('config.commands.configureViewOnWindowOpen', async () => { + + // 1) Getting the value + const value = await vscode.window.showQuickPick(['explorer', 'search', 'scm', 'debug', 'extensions'], { placeHolder: 'Select the view to show when opening a window.' }); + + // 2) Getting the Configuration target + const target = await vscode.window.showQuickPick( + [ + { label: 'User', description: 'User Settings', target: vscode.ConfigurationTarget.Global }, + { label: 'Workspace', description: 'Workspace Settings', target: vscode.ConfigurationTarget.Workspace } + ], + { placeHolder: 'Select the view to show when opening a window.' }); + + if (value && target) { + + // 3) Update the configuration value in the target + await vscode.workspace.getConfiguration().update('conf.view.showOnWindowOpen', value, target.target); + + /* + // Default is to update in Workspace + await vscode.workspace.getConfiguration().update('conf.view.showOnWindowOpen', value); + */ + } + }); + + // Example 3: Reading Resource scoped configuration for a file + context.subscriptions.push(vscode.workspace.onDidOpenTextDocument(e => { + + // 1) Get the configured glob pattern value for the current file + const value = vscode.workspace.getConfiguration('', e.uri).get('conf.resource.insertEmptyLastLine'); + + // 2) Check if the current resource matches the glob pattern + const matches = value[e.fileName]; + + // 3) If matches, insert empty last line + if (matches) { + vscode.window.showInformationMessage('An empty line will be added to the document ' + e.fileName); + } + + })); + + // Example 4: Updating Resource scoped Configuration for current file + vscode.commands.registerCommand('config.commands.configureEmptyLastLineCurrentFile', async () => { + + if (vscode.window.activeTextEditor) { + const currentDocument = vscode.window.activeTextEditor.document; + + // 1) Get the configuration for the current document + const configuration = vscode.workspace.getConfiguration('', currentDocument.uri); + + // 2) Get the configiuration value + const currentValue = configuration.get('conf.resource.insertEmptyLastLine', {}); + + // 3) Choose target to Global when there are no workspace folders + const target = vscode.workspace.workspaceFolders ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Global; + + // 4) Update the configuration + await configuration.update('conf.resource.insertEmptyLastLine', { ...currentValue, ...{ [currentDocument.fileName]: true } }, target) + } + + }); + + // Example 5: Updating Resource scoped Configuration + vscode.commands.registerCommand('config.commands.configureEmptyLastLineFiles', async () => { + + // 1) Getting the value + const value = await vscode.window.showInputBox({ prompt: 'Provide glob pattern of files to have empty last line.' }); + + // 2) Getting the target + const target = await vscode.window.showQuickPick( + [ + { label: 'Application', description: 'User Settings', target: vscode.ConfigurationTarget.Global }, + { label: 'Workspace', description: 'Workspace Settings', target: vscode.ConfigurationTarget.Workspace }, + { label: 'Workspace Folder', description: 'Workspace Folder Settings', target: vscode.ConfigurationTarget.WorkspaceFolder } + ], + { placeHolder: 'Select the target to which this setting should be applied' }); + + if (value && target) { + + if (target.target === vscode.ConfigurationTarget.WorkspaceFolder) { + + // 3) Getting the workspace folder + let workspaceFolder = await vscode.window.showWorkspaceFolderPick({ placeHolder: 'Pick Workspace Folder to which this setting should be applied' }) + if (workspaceFolder) { + + // 4) Get the configuration for the workspace folder + const configuration = vscode.workspace.getConfiguration('', workspaceFolder.uri); + + // 5) Get the current value + const currentValue = configuration.get('conf.resource.insertEmptyLastLine'); + + // 6) Update the configuration value + await configuration.update('conf.resource.insertEmptyLastLine', { ...currentValue, ...{ [value]: true } }, target.target); + } + } else { + + // 3) Get the configuration + const configuration = vscode.workspace.getConfiguration(); + + // 4) Get the current value + const currentValue = configuration.get('conf.resource.insertEmptyLastLine'); + + // 3) Update the value in the target + await vscode.workspace.getConfiguration().update('conf.resource.insertEmptyLastLine', { ...currentValue, ...{ [value]: true } }, target.target); + } + } + }); + + // Example 6: Listening to configuration changes + context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => { + if (vscode.window.activeTextEditor) { + + const currentDocument = vscode.window.activeTextEditor.document; + + // 1) Get the configured glob pattern value for the current file + const value = vscode.workspace.getConfiguration('', currentDocument.uri).get('conf.resource.insertEmptyLastLine'); + + // 2) Check if the current resource matches the glob pattern + const matches = value[currentDocument.fileName]; + + // 3) If matches, insert empty last line + if (matches) { + vscode.window.showInformationMessage('An empty line will be added to the document ' + currentDocument.fileName); + } + } + })); + +} \ No newline at end of file diff --git a/configuration-sample/tsconfig.json b/configuration-sample/tsconfig.json new file mode 100644 index 00000000..d9689931 --- /dev/null +++ b/configuration-sample/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "out", + "lib": [ + "es6" + ], + "sourceMap": true, + "rootDir": "." + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +}