diff --git a/extensions/emmet/npm-shrinkwrap.json b/extensions/emmet/npm-shrinkwrap.json index 349dae1cb78477b88007fcab523bab4294b0077f..eaf2e9b641cd861a7e76542d02c1e213799e4f89 100644 --- a/extensions/emmet/npm-shrinkwrap.json +++ b/extensions/emmet/npm-shrinkwrap.json @@ -67,6 +67,11 @@ "from": "@emmetio/markup-formatters@>=0.3.3 <0.4.0", "resolved": "https://registry.npmjs.org/@emmetio/markup-formatters/-/markup-formatters-0.3.3.tgz" }, + "@emmetio/math-expression": { + "version": "0.1.1", + "from": "@emmetio/math-expression@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/@emmetio/math-expression/-/math-expression-0.1.1.tgz" + }, "@emmetio/node": { "version": "0.1.2", "from": "@emmetio/node@>=0.1.2 <0.2.0", @@ -111,6 +116,11 @@ "version": "0.2.1", "from": "@emmetio/variable-resolver@>=0.2.1 <0.3.0", "resolved": "https://registry.npmjs.org/@emmetio/variable-resolver/-/variable-resolver-0.2.1.tgz" + }, + "vscode-emmet-helper": { + "version": "0.0.6", + "from": "vscode-emmet-helper@0.0.6", + "resolved": "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-0.0.6.tgz" } } } diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index f6a6a2f462becdc55b5d5c66e7c6d8c96ec80a60..1ae8a6d0ea82d70ea33afd6dde439d8ebb7064eb 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -74,6 +74,7 @@ "@emmetio/extract-abbreviation": "^0.1.1", "@emmetio/html-matcher": "^0.3.1", "@emmetio/css-parser": "^0.3.0", + "@emmetio/math-expression": "^0.1.1", "vscode-emmet-helper":"0.0.6" } } \ No newline at end of file diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 6d38bd66cda839096614e1ab856397879e88cf7f..6d5c86f2bb233bc69fda9eadac5762dc7edfaaa4 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -18,17 +18,19 @@ export function wrapWithAbbreviation() { vscode.window.showInformationMessage('No editor is active'); return; } - let rangeToReplace: vscode.Range = editor.selection; - if (rangeToReplace.isEmpty) { - rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, editor.document.lineAt(rangeToReplace.start.line).text.length); - } - let textToReplace = editor.document.getText(rangeToReplace); let syntax = getSyntax(editor.document); vscode.window.showInputBox({ prompt: 'Enter Abbreviation' }).then(abbr => { if (!abbr || !abbr.trim()) { return; } - let expandedText = expand(abbr, getExpandOptions(syntax, textToReplace)); - editor.insertSnippet(new vscode.SnippetString(expandedText), rangeToReplace); + editor.selections.forEach(selection => { + let rangeToReplace: vscode.Range = selection; + if (rangeToReplace.isEmpty) { + rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, editor.document.lineAt(rangeToReplace.start.line).text.length); + } + let textToReplace = editor.document.getText(rangeToReplace); + let expandedText = expand(abbr, getExpandOptions(syntax, textToReplace)); + editor.insertSnippet(new vscode.SnippetString(expandedText), rangeToReplace); + }); }); } @@ -43,25 +45,27 @@ export function expandAbbreviation(args) { return; } let syntax = args['syntax']; - let abbreviationRange: vscode.Range = editor.selection; - let position = editor.selection.isReversed ? editor.selection.anchor : editor.selection.active; - let abbreviation = editor.document.getText(abbreviationRange); - if (abbreviationRange.isEmpty) { - [abbreviationRange, abbreviation] = extractAbbreviation(editor.document, position); - } - let parseContent = isStyleSheet(syntax) ? parseStylesheet : parse; let rootNode: Node = parseContent(new DocumentStreamReader(editor.document)); - let currentNode = getNode(rootNode, position); - if (!isValidLocationForEmmetAbbreviation(currentNode, syntax, position)) { - return; - } + editor.selections.forEach(selection => { + let abbreviationRange: vscode.Range = selection; + let position = selection.isReversed ? selection.anchor : selection.active; + let abbreviation = editor.document.getText(abbreviationRange); + if (abbreviationRange.isEmpty) { + [abbreviationRange, abbreviation] = extractAbbreviation(editor.document, position); + } - let expandedText = expand(abbreviation, getExpandOptions(syntax)); - if (expandedText) { - editor.insertSnippet(new vscode.SnippetString(expandedText), abbreviationRange); - } + let currentNode = getNode(rootNode, position); + if (!isValidLocationForEmmetAbbreviation(currentNode, syntax, position)) { + return; + } + + let expandedText = expand(abbreviation, getExpandOptions(syntax)); + if (expandedText) { + editor.insertSnippet(new vscode.SnippetString(expandedText), abbreviationRange); + } + }); } diff --git a/extensions/emmet/src/bufferStream.ts b/extensions/emmet/src/bufferStream.ts index 923c7d04d0df4343e6eec7e71b39b40b89083540..261b844c608ba2e1c57a3ea428d653c00f312633 100644 --- a/extensions/emmet/src/bufferStream.ts +++ b/extensions/emmet/src/bufferStream.ts @@ -15,7 +15,7 @@ export class DocumentStreamReader { private document: TextDocument; private start: Position; private _eof: Position; - private pos: Position; + public pos: Position; private _eol: string; /** diff --git a/extensions/emmet/src/evaluateMathExpression.ts b/extensions/emmet/src/evaluateMathExpression.ts new file mode 100644 index 0000000000000000000000000000000000000000..b01b6327965635eabe1ebb435a994ca6cd8e19b1 --- /dev/null +++ b/extensions/emmet/src/evaluateMathExpression.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import evaluate from '@emmetio/math-expression'; +import { DocumentStreamReader } from './bufferStream'; + +export function evaluateMathExpression() { + let editor = vscode.window.activeTextEditor; + if (!editor) { + vscode.window.showInformationMessage('No editor is active'); + return; + } + const stream = new DocumentStreamReader(editor.document); + editor.edit(editBuilder => { + editor.selections.forEach(selection => { + const pos = selection.isReversed ? selection.anchor : selection.active; + stream.pos = pos; + + try { + const result = String(evaluate(stream, true)); + editBuilder.replace(new vscode.Range(stream.pos, pos), result); + } catch (err) { + // Ignore error since most likely it’s because of non-math expression + console.warn('Math evaluation error', err); + } + }); + }); + +} diff --git a/extensions/emmet/src/extension.ts b/extensions/emmet/src/extension.ts index fdd0507cbb353e7d46dca05f1d063525c6d7b441..7598f3ccd28a8893bb350551c29fe0276604474d 100644 --- a/extensions/emmet/src/extension.ts +++ b/extensions/emmet/src/extension.ts @@ -15,6 +15,7 @@ import { mergeLines } from './mergeLines'; import { toggleComment } from './toggleComment'; import { fetchEditPoint } from './editPoint'; import { fetchSelectItem } from './selectItem'; +import { evaluateMathExpression } from './evaluateMathExpression'; import { LANGUAGE_MODES, getMappedModes } from './util'; import { updateExtensionsPath } from 'vscode-emmet-helper'; @@ -91,6 +92,10 @@ export function activate(context: vscode.ExtensionContext) { fetchSelectItem('prev'); })); + context.subscriptions.push(vscode.commands.registerCommand('emmet.evaluateMathExpression', () => { + evaluateMathExpression(); + })); + updateExtensionsPath(); context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => { updateExtensionsPath(); diff --git a/extensions/emmet/src/util.ts b/extensions/emmet/src/util.ts index ad6c82e78034ec1f712061203ab86ecdeab05bea..81ccb506acefce2254de722deff96c3a59447f48 100644 --- a/extensions/emmet/src/util.ts +++ b/extensions/emmet/src/util.ts @@ -16,8 +16,6 @@ export const LANGUAGE_MODES: Object = { 'haml': ['!', '.', '}'], 'xml': ['.', '}'], 'xsl': ['.', '}'], - 'javascriptreact': ['.'], - 'typescriptreact': ['.'], 'css': [':'], 'scss': [':'], 'sass': [':'], @@ -25,7 +23,7 @@ export const LANGUAGE_MODES: Object = { 'stylus': [':'] }; -// Explicitly map languages to their parent language to get emmet support +// Explicitly map languages to their parent language to get emmet completion support export const MAPPED_MODES: Object = { 'handlebars': 'html' }; @@ -45,9 +43,6 @@ export function getSyntax(document: vscode.TextDocument): string { if (document.languageId === 'jade') { return 'pug'; } - if (document.languageId === 'javascriptreact' || document.languageId === 'typescriptreact') { - return 'jsx'; - } return document.languageId; } diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index da1effa132364377438f00caccfef0f6459f9535..9702c2b36e1ed4f60fdffe7b5c69bb7daa757833 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -911,14 +911,16 @@ export class CodeMenu { } private setTaskMenu(taskMenu: Electron.Menu): void { - const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.tasks.runTask'); - const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Task"), 'workbench.action.tasks.restartTask'); - const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task"), 'workbench.action.tasks.terminate'); - const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "&&Build Task"), 'workbench.action.tasks.build'); - const testTask = this.createMenuItem(nls.localize({ key: 'miTestTask', comment: ['&& denotes a mnemonic'] }, "Test T&&ask"), 'workbench.action.tasks.test'); - const showTaskLog = this.createMenuItem(nls.localize({ key: 'miShowTaskLog', comment: ['&& denotes a mnemonic'] }, "&&Show Task Log"), 'workbench.action.tasks.showLog'); + const runTask = this.createMenuItem(nls.localize({ key: 'miRunTask', comment: ['&& denotes a mnemonic'] }, "&&Run Task..."), 'workbench.action.taskAction.runTask'); + const restartTask = this.createMenuItem(nls.localize({ key: 'miRestartTask', comment: ['&& denotes a mnemonic'] }, "R&&estart Task"), 'workbench.action.taskAction.restartTask'); + const terminateTask = this.createMenuItem(nls.localize({ key: 'miTerminateTask', comment: ['&& denotes a mnemonic'] }, "&&Terminate Task"), 'workbench.action.taskAction.terminateTask'); + const buildTask = this.createMenuItem(nls.localize({ key: 'miBuildTask', comment: ['&& denotes a mnemonic'] }, "&&Build Task"), 'workbench.action.taskAction.build'); + const testTask = this.createMenuItem(nls.localize({ key: 'miTestTask', comment: ['&& denotes a mnemonic'] }, "Test T&&ask"), 'workbench.action.taskAction.test'); + const showTaskLog = this.createMenuItem(nls.localize({ key: 'miShowTaskLog', comment: ['&& denotes a mnemonic'] }, "&&Show Task Log"), 'workbench.action.taskAction.showLog'); + const configureTask = this.createMenuItem(nls.localize({ key: 'miConfigureTask', comment: ['&& denotes a mnemonic'] }, "&&Configure Task Runner"), 'workbench.action.tasks.configureTaskRunner'); [ + configureTask, showTaskLog, runTask, restartTask, diff --git a/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts b/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts index d136af8f1fab612b8804e16634633d5b8a533bf3..f048e7c36edf5e4761fc721fbc3fe3f2813a52c4 100644 --- a/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts +++ b/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts @@ -250,7 +250,8 @@ export abstract class EmmetEditorAction extends EditorAction { 'editor.emmet.action.selectPreviousItem': 'emmet.selectPrevItem', 'editor.emmet.action.selectNextItem': 'emmet.selectNextItem', 'editor.emmet.action.splitJoinTag': 'emmet.splitJoinTag', - 'editor.emmet.action.toggleComment': 'emmet.toggleComment' + 'editor.emmet.action.toggleComment': 'emmet.toggleComment', + 'editor.emmet.action.evaluateMath': 'emmet.evaluateMathExpression' }; protected emmetActionName: string; diff --git a/src/vs/workbench/parts/tasks/common/taskActions.ts b/src/vs/workbench/parts/tasks/common/taskActions.ts new file mode 100644 index 0000000000000000000000000000000000000000..5f5c2f240f445279d868c1e18a2be08270d7787c --- /dev/null +++ b/src/vs/workbench/parts/tasks/common/taskActions.ts @@ -0,0 +1,141 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { TPromise } from 'vs/base/common/winjs.base'; +import nls = require('vs/nls'); +import { Action } from 'vs/base/common/actions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry'; + +export class RunTaskAction extends Action { + + public static ID = 'workbench.action.taskAction.runTask'; + public static LABEL = nls.localize('runTaskAction', "Run task"); + + constructor( + id: string, + label: string, + @ICommandService private commandService: ICommandService + ) { + super(id, label); + } + + public run(context?: any): TPromise { + this.commandService.executeCommand('workbench.action.tasks.runTask'); + return TPromise.as(null); + } +} + +export class RestartTaskAction extends Action { + + public static ID = 'workbench.action.taskAction.restartTask'; + public static LABEL = nls.localize('restartTaskAction', "Restart task"); + + constructor( + id: string, + label: string, + @ICommandService private commandService: ICommandService + ) { + super(id, label); + } + + public run(context?: any): TPromise { + this.commandService.executeCommand('workbench.action.tasks.restartTask'); + return TPromise.as(null); + } +} + +export class TerminateTaskAction extends Action { + + public static ID = 'workbench.action.taskAction.terminateTask'; + public static LABEL = nls.localize('terminateTaskAction', "Terminate task"); + + constructor( + id: string, + label: string, + @ICommandService private commandService: ICommandService + ) { + super(id, label); + } + + public run(context?: any): TPromise { + this.commandService.executeCommand('workbench.action.tasks.terminate'); + return TPromise.as(null); + } +} + +export class BuildTaskAction extends Action { + + public static ID = 'workbench.action.taskAction.build'; + public static LABEL = nls.localize('buildTaskAction', "Build task"); + + constructor( + id: string, + label: string, + @ICommandService private commandService: ICommandService + ) { + super(id, label); + } + + public run(context?: any): TPromise { + this.commandService.executeCommand('workbench.action.tasks.build'); + return TPromise.as(null); + } +} + +export class TestTaskAction extends Action { + + public static ID = 'workbench.action.taskAction.test'; + public static LABEL = nls.localize('testTaskAction', "Test task"); + + constructor( + id: string, + label: string, + @ICommandService private commandService: ICommandService + ) { + super(id, label); + } + + public run(context?: any): TPromise { + this.commandService.executeCommand('workbench.action.tasks.test'); + return TPromise.as(null); + } +} + +export class ShowTaskLogAction extends Action { + + public static ID = 'workbench.action.taskAction.showLog'; + public static LABEL = nls.localize('showTaskLogAction', "Show task log"); + + constructor( + id: string, + label: string, + @ICommandService private commandService: ICommandService + ) { + super(id, label); + } + + public run(context?: any): TPromise { + this.commandService.executeCommand('workbench.action.tasks.showLog'); + return TPromise.as(null); + } +} + +Registry.as(ActionExtensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(RunTaskAction, RunTaskAction.ID, RunTaskAction.LABEL), 'Run Task'); +Registry.as(ActionExtensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(RestartTaskAction, RestartTaskAction.ID, RestartTaskAction.LABEL), 'Restart Task'); +Registry.as(ActionExtensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(TerminateTaskAction, TerminateTaskAction.ID, TerminateTaskAction.LABEL), 'Terminate Task'); +Registry.as(ActionExtensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(BuildTaskAction, BuildTaskAction.ID, BuildTaskAction.LABEL), 'Build Task'); +Registry.as(ActionExtensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(TestTaskAction, TestTaskAction.ID, TestTaskAction.LABEL), 'Test Task'); +Registry.as(ActionExtensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(ShowTaskLogAction, ShowTaskLogAction.ID, ShowTaskLogAction.LABEL), 'Show Task Log'); \ No newline at end of file diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 6e2906edfd6119bcfa904a311c5971b0ddfed387..13697f20a92db40b91a3901e0b5d7070e5aa1ecc 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -11,6 +11,7 @@ import 'vs/workbench/parts/tasks/browser/terminateQuickOpen'; import 'vs/workbench/parts/tasks/browser/restartQuickOpen'; import 'vs/workbench/parts/tasks/browser/buildQuickOpen'; import 'vs/workbench/parts/tasks/browser/testQuickOpen'; +import 'vs/workbench/parts/tasks/common/taskActions'; import * as nls from 'vs/nls';