Archived
1
0

chore(vscode): update to 1.54.2

This commit is contained in:
Joe Previte
2021-03-11 10:27:10 -07:00
1459 changed files with 53404 additions and 51004 deletions

View File

@ -1,29 +1,47 @@
{
"name": "bat",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js mmims/language-batchfile grammars/batchfile.cson ./syntaxes/batchfile.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "bat",
"extensions": [ ".bat", ".cmd"],
"aliases": [ "Batch", "bat" ],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "bat",
"scopeName": "source.batchfile",
"path": "./syntaxes/batchfile.tmLanguage.json"
}],
"snippets": [{
"language": "bat",
"path": "./snippets/batchfile.code-snippets"
}]
}
"name": "bat",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.52.0"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin mmims/language-batchfile grammars/batchfile.cson ./syntaxes/batchfile.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "bat",
"extensions": [
".bat",
".cmd"
],
"aliases": [
"Batch",
"bat"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "bat",
"scopeName": "source.batchfile",
"path": "./syntaxes/batchfile.tmLanguage.json"
}
],
"snippets": [
{
"language": "bat",
"path": "./snippets/batchfile.code-snippets"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Windows Bat Language Basics",
"description": "Provides snippets, syntax highlighting, bracket matching and folding in Windows batch files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -1,25 +1,45 @@
{
"name": "clojure",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-clojure grammars/clojure.cson ./syntaxes/clojure.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "clojure",
"aliases": ["Clojure", "clojure"],
"extensions": [".clj", ".cljs", ".cljc", ".cljx", ".clojure", ".edn"],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "clojure",
"scopeName": "source.clojure",
"path": "./syntaxes/clojure.tmLanguage.json"
}]
}
}
"name": "clojure",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-clojure grammars/clojure.cson ./syntaxes/clojure.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "clojure",
"aliases": [
"Clojure",
"clojure"
],
"extensions": [
".clj",
".cljs",
".cljc",
".cljx",
".clojure",
".edn"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "clojure",
"scopeName": "source.clojure",
"path": "./syntaxes/clojure.tmLanguage.json"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Clojure Language Basics",
"description": "Provides syntax highlighting and bracket matching in Clojure files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -1,34 +1,54 @@
{
"name": "coffeescript",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-coffee-script grammars/coffeescript.cson ./syntaxes/coffeescript.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "coffeescript",
"extensions": [ ".coffee", ".cson", ".iced" ],
"aliases": [ "CoffeeScript", "coffeescript", "coffee" ],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "coffeescript",
"scopeName": "source.coffee",
"path": "./syntaxes/coffeescript.tmLanguage.json"
}],
"breakpoints": [
{
"language": "coffeescript"
}
],
"snippets": [{
"language": "coffeescript",
"path": "./snippets/coffeescript.code-snippets"
}]
}
"name": "coffeescript",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-coffee-script grammars/coffeescript.cson ./syntaxes/coffeescript.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "coffeescript",
"extensions": [
".coffee",
".cson",
".iced"
],
"aliases": [
"CoffeeScript",
"coffeescript",
"coffee"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "coffeescript",
"scopeName": "source.coffee",
"path": "./syntaxes/coffeescript.tmLanguage.json"
}
],
"breakpoints": [
{
"language": "coffeescript"
}
],
"snippets": [
{
"language": "coffeescript",
"path": "./snippets/coffeescript.code-snippets"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -40,8 +40,12 @@
"keybindings.json",
"extensions.json",
"argv.json",
"profiles.json"
]
"profiles.json",
".devcontainer.json"
],
"filenamePatterns": [
"**/.devcontainer/devcontainer.json"
]
}
],
"jsonValidation": [
@ -129,5 +133,9 @@
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Configuration Editing",
"description": "Provides capabilities (advanced IntelliSense, auto-fixing) in configuration files like settings, launch, and extension recommendation files."
}
}

View File

@ -19,6 +19,63 @@
"type": "integer"
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"^\\d+(\\-\\d+)?$": {
"type": "object",
"description": "A port, or range of ports (ex. \"40000-55000\") that the attributes should apply to",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Labeled Port"
}
},
"default": {
"label": "Labeled Port",
"onAutoForward": "notify"
}
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Labeled Port\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:My Port}",
"onAutoForward": "notify"
}
}
}
],
"errorMessage": "Must be a port number or a range of port numbers",
"additionalProperties": false
},
"settings": {
"$ref": "vscode://schemas/settings/machine",
"description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time."

View File

@ -127,6 +127,64 @@
"minimum": 0
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"^\\d+(\\-\\d+)?$": {
"type": "object",
"description": "A port, or range of ports (ex. \"40000-55000\") that the attributes should apply to",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Labeled Port"
}
},
"default": {
"label": "Labeled Port",
"onAutoForward": "notify"
},
"additionalProperties": false
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Labeled Port\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:My Port}",
"onAutoForward": "notify"
}
}
}
],
"errorMessage": "Must be a port number or a range of port numbers",
"additionalProperties": false
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@ -326,6 +384,64 @@
"minimum": 0
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"^\\d+(\\-\\d+)?$": {
"type": "object",
"description": "A port, or range of ports (ex. \"40000-55000\") that the attributes should apply to",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Labeled Port"
}
},
"default": {
"label": "Labeled Port",
"onAutoForward": "notify"
},
"additionalProperties": false
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Labeled Port\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:My Port}",
"onAutoForward": "notify"
}
}
}
],
"errorMessage": "Must be a port number or a range of port numbers",
"additionalProperties": false
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@ -501,6 +617,64 @@
"minimum": 0
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"^\\d+(\\-\\d+)?$": {
"type": "object",
"description": "A port, or range of ports (ex. \"40000-55000\") that the attributes should apply to",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Labeled Port"
}
},
"default": {
"label": "Labeled Port",
"onAutoForward": "notify"
},
"additionalProperties": false
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Labeled Port\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:My Port}",
"onAutoForward": "notify"
}
}
}
],
"errorMessage": "Must be a port number or a range of port numbers",
"additionalProperties": false
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@ -642,6 +816,64 @@
"minimum": 0
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"^\\d+(\\-\\d+)?$": {
"type": "object",
"description": "A port, or range of ports (ex. \"40000-55000\") that the attributes should apply to",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Labeled Port"
}
},
"default": {
"label": "Labeled Port",
"onAutoForward": "notify"
},
"additionalProperties": false
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Labeled Port\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:My Port}",
"onAutoForward": "notify"
}
}
}
],
"errorMessage": "Must be a port number or a range of port numbers",
"additionalProperties": false
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@ -752,6 +984,64 @@
"minimum": 0
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"^\\d+(\\-\\d+)?$": {
"type": "object",
"description": "A port, or range of ports (ex. \"40000-55000\") that the attributes should apply to",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Labeled Port"
}
},
"default": {
"label": "Labeled Port",
"onAutoForward": "notify"
},
"additionalProperties": false
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Labeled Port\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:My Port}",
"onAutoForward": "notify"
}
}
}
],
"errorMessage": "Must be a port number or a range of port numbers",
"additionalProperties": false
},
"remoteEnv": {
"type": "object",
"additionalProperties": {

View File

@ -33,6 +33,63 @@
"minimum": 0
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"^\\d+(\\-\\d+)?$": {
"type": "object",
"description": "A port, or range of ports (ex. \"40000-55000\") that the attributes should apply to",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Labeled Port"
}
},
"default": {
"label": "Labeled Port",
"onAutoForward": "notify"
}
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Labeled Port\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:My Port}",
"onAutoForward": "notify"
}
}
}
],
"errorMessage": "Must be a port number or a range of port numbers",
"additionalProperties": false
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@ -205,7 +262,7 @@
"$ref": "#/definitions/buildOptions"
}
]
}
}
},
"required": [
"build"

View File

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getLocation, parse, visit } from 'jsonc-parser';
import { getLocation, JSONPath, parse, visit } from 'jsonc-parser';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { SettingsDocument } from './settingsDocumentHelper';
@ -22,6 +22,9 @@ export function activate(context: vscode.ExtensionContext): void {
// task.json variable suggestions
context.subscriptions.push(registerVariableCompletions('**/tasks.json'));
// keybindings.json/package.json context key suggestions
context.subscriptions.push(registerContextKeyCompletions());
}
function registerSettingsCompletions(): vscode.Disposable {
@ -136,3 +139,83 @@ vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', lan
return result;
}
}, { label: 'Launch Targets' });
function registerContextKeyCompletions(): vscode.Disposable {
type ContextKeyInfo = { key: string, type?: string, description?: string };
const paths = new Map<vscode.DocumentFilter, JSONPath[]>([
[{ language: 'jsonc', pattern: '**/keybindings.json' }, [
['*', 'when']
]],
[{ language: 'json', pattern: '**/package.json' }, [
['contributes', 'menus', '*', '*', 'when'],
['contributes', 'views', '*', '*', 'when'],
['contributes', 'viewsWelcome', '*', 'when'],
['contributes', 'keybindings', '*', 'when'],
['contributes', 'keybindings', 'when'],
]]
]);
return vscode.languages.registerCompletionItemProvider(
[...paths.keys()],
{
async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) {
const location = getLocation(document.getText(), document.offsetAt(position));
if (location.isAtPropertyKey) {
return;
}
let isValidLocation = false;
for (const [key, value] of paths) {
if (vscode.languages.match(key, document)) {
if (value.some(location.matches.bind(location))) {
isValidLocation = true;
break;
}
}
}
if (!isValidLocation) {
return;
}
// for JSON everything with quotes is a word
const jsonWord = document.getWordRangeAtPosition(position);
if (!jsonWord || jsonWord.start.isEqual(position) || jsonWord.end.isEqual(position)) {
// we aren't inside a "JSON word" or on its quotes
return;
}
let replacing: vscode.Range | undefined;
if (jsonWord.end.character - jsonWord.start.character === 2 || document.getWordRangeAtPosition(position, /\s+/)) {
// empty json word or on whitespace
replacing = new vscode.Range(position, position);
} else {
replacing = document.getWordRangeAtPosition(position, /[a-zA-Z.]+/);
}
if (!replacing) {
return;
}
const inserting = replacing.with(undefined, position);
const data = await vscode.commands.executeCommand<ContextKeyInfo[]>('getContextKeyInfo');
if (token.isCancellationRequested || !data) {
return;
}
const result = new vscode.CompletionList();
for (const item of data) {
const completion = new vscode.CompletionItem(item.key, vscode.CompletionItemKind.Constant);
completion.detail = item.type;
completion.range = { replacing, inserting };
completion.documentation = item.description;
result.items.push(completion);
}
return result;
}
}
);
}

View File

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
var updateGrammar = require('../../../build/npm/update-grammar');
var updateGrammar = require('vscode-grammar-updater');
updateGrammar.update('jeff-hykin/cpp-textmate-grammar', 'syntaxes/c.tmLanguage.json', './syntaxes/c.tmLanguage.json', undefined, 'master', 'source/languages/cpp/');
updateGrammar.update('jeff-hykin/cpp-textmate-grammar', 'syntaxes/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json', undefined, 'master', 'source/languages/cpp/');

View File

@ -1,87 +1,91 @@
{
"name": "cpp",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ./build/update-grammars.js"
},
"contributes": {
"languages": [
{
"id": "c",
"extensions": [
".c",
".i"
],
"aliases": [
"C",
"c"
],
"configuration": "./language-configuration.json"
},
{
"id": "cpp",
"extensions": [
".cpp",
".cc",
".cxx",
".c++",
".hpp",
".hh",
"name": "cpp",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ./build/update-grammars.js"
},
"contributes": {
"languages": [
{
"id": "c",
"extensions": [
".c",
".i"
],
"aliases": [
"C",
"c"
],
"configuration": "./language-configuration.json"
},
{
"id": "cpp",
"extensions": [
".cpp",
".cc",
".cxx",
".c++",
".hpp",
".hh",
".hxx",
".h++",
".h",
".ii",
".ino",
".inl",
".ipp",
".hpp.in",
".h.in"
],
"aliases": [
"C++",
"Cpp",
"cpp"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "c",
"scopeName": "source.c",
"path": "./syntaxes/c.tmLanguage.json"
},
{
"language": "cpp",
"scopeName": "source.cpp.embedded.macro",
"path": "./syntaxes/cpp.embedded.macro.tmLanguage.json"
},
{
"language": "cpp",
"scopeName": "source.cpp",
"path": "./syntaxes/cpp.tmLanguage.json"
},
{
"scopeName": "source.c.platform",
"path": "./syntaxes/platform.tmLanguage.json"
}
],
"snippets": [
{
"language": "c",
"path": "./snippets/c.code-snippets"
},
{
"language": "cpp",
"path": "./snippets/cpp.code-snippets"
}
]
}
".h",
".ii",
".ino",
".inl",
".ipp",
".hpp.in",
".h.in"
],
"aliases": [
"C++",
"Cpp",
"cpp"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "c",
"scopeName": "source.c",
"path": "./syntaxes/c.tmLanguage.json"
},
{
"language": "cpp",
"scopeName": "source.cpp.embedded.macro",
"path": "./syntaxes/cpp.embedded.macro.tmLanguage.json"
},
{
"language": "cpp",
"scopeName": "source.cpp",
"path": "./syntaxes/cpp.tmLanguage.json"
},
{
"scopeName": "source.c.platform",
"path": "./syntaxes/platform.tmLanguage.json"
}
],
"snippets": [
{
"language": "c",
"path": "./snippets/c.code-snippets"
},
{
"language": "cpp",
"path": "./snippets/cpp.code-snippets"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "C/C++ Language Basics",
"description": "Provides snippets, syntax highlighting, bracket matching and folding in C/C++ files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -1,7 +1,7 @@
{
"name": "csharp",
"displayName": "%displayName%",
"description": "%description%",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
@ -9,9 +9,8 @@
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js dotnet/csharp-tmLanguage grammars/csharp.tmLanguage ./syntaxes/csharp.tmLanguage.json"
},
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin dotnet/csharp-tmLanguage grammars/csharp.tmLanguage ./syntaxes/csharp.tmLanguage.json"
},
"contributes": {
"languages": [
{
@ -35,9 +34,15 @@
"path": "./syntaxes/csharp.tmLanguage.json"
}
],
"snippets": [{
"language": "csharp",
"path": "./snippets/csharp.code-snippets"
}]
"snippets": [
{
"language": "csharp",
"path": "./snippets/csharp.code-snippets"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "C# Language Basics",
"description": "Provides snippets, syntax highlighting, bracket matching and folding in C# files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -61,6 +61,18 @@
"default": true,
"description": "%css.validate.desc%"
},
"css.hover.documentation": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%css.hover.documentation%"
},
"css.hover.references": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%css.hover.references%"
},
"css.lint.compatibleVendorPrefixes": {
"type": "string",
"scope": "resource",
@ -316,6 +328,18 @@
"default": true,
"description": "%scss.validate.desc%"
},
"scss.hover.documentation": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%scss.hover.documentation%"
},
"scss.hover.references": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%scss.hover.references%"
},
"scss.lint.compatibleVendorPrefixes": {
"type": "string",
"scope": "resource",
@ -561,6 +585,18 @@
"default": true,
"description": "%less.validate.desc%"
},
"less.hover.documentation": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%less.hover.documentation%"
},
"less.hover.references": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%less.hover.references%"
},
"less.lint.compatibleVendorPrefixes": {
"type": "string",
"scope": "resource",
@ -812,5 +848,9 @@
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -28,6 +28,8 @@
"css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.",
"css.validate.title": "Controls CSS validation and problem severities.",
"css.validate.desc": "Enables or disables all validations.",
"css.hover.documentation": "Show tag and attribute documentation in CSS hovers.",
"css.hover.references": "Show references to MDN in CSS hovers.",
"less.title": "LESS",
"less.completion.triggerPropertyValueCompletion.desc": "By default, VS Code triggers property value completion after selecting a CSS property. Use this setting to disable this behavior.",
"less.completion.completePropertyWithSemicolon.desc": "Insert semicolon at end of line when completing CSS properties",
@ -53,6 +55,8 @@
"less.lint.zeroUnits.desc": "No unit for zero needed.",
"less.validate.title": "Controls LESS validation and problem severities.",
"less.validate.desc": "Enables or disables all validations.",
"less.hover.documentation": "Show tag and attribute documentation in LESS hovers.",
"less.hover.references": "Show references to MDN in LESS hovers.",
"scss.title": "SCSS (Sass)",
"scss.completion.triggerPropertyValueCompletion.desc": "By default, VS Code triggers property value completion after selecting a CSS property. Use this setting to disable this behavior.",
"scss.completion.completePropertyWithSemicolon.desc": "Insert semicolon at end of line when completing CSS properties",
@ -78,6 +82,8 @@
"scss.lint.zeroUnits.desc": "No unit for zero needed.",
"scss.validate.title": "Controls SCSS validation and problem severities.",
"scss.validate.desc": "Enables or disables all validations.",
"scss.hover.documentation": "Show tag and attribute documentation in SCSS hovers.",
"scss.hover.references": "Show references to MDN in SCSS hovers.",
"css.colorDecorators.enable.deprecationMessage": "The setting `css.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.",
"scss.colorDecorators.enable.deprecationMessage": "The setting `scss.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.",
"less.colorDecorators.enable.deprecationMessage": "The setting `less.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`."

View File

@ -10,7 +10,7 @@
"main": "./out/node/cssServerMain",
"browser": "./dist/browser/cssServerMain",
"dependencies": {
"vscode-css-languageservice": "^5.0.3",
"vscode-css-languageservice": "^5.1.0",
"vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2"
},

View File

@ -206,10 +206,10 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
return runSafeAsync(async () => {
const document = documents.get(textDocumentPosition.textDocument.uri);
if (document) {
await dataProvidersReady;
const [settings,] = await Promise.all([getDocumentSettings(document), dataProvidersReady]);
const styleSheet = stylesheets.get(document);
const documentContext = getDocumentContext(document.uri, workspaceFolders);
return getLanguageService(document).doComplete2(document, textDocumentPosition.position, styleSheet, documentContext);
return getLanguageService(document).doComplete2(document, textDocumentPosition.position, styleSheet, documentContext, settings?.completion);
}
return null;
}, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`, token);
@ -219,9 +219,9 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
return runSafeAsync(async () => {
const document = documents.get(textDocumentPosition.textDocument.uri);
if (document) {
await dataProvidersReady;
const [settings,] = await Promise.all([getDocumentSettings(document), dataProvidersReady]);
const styleSheet = stylesheets.get(document);
return getLanguageService(document).doHover(document, textDocumentPosition.position, styleSheet);
return getLanguageService(document).doHover(document, textDocumentPosition.position, styleSheet, settings?.hover);
}
return null;
}, null, `Error while computing hover for ${textDocumentPosition.textDocument.uri}`, token);

View File

@ -12,10 +12,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
vscode-css-languageservice@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-5.0.3.tgz#2d400a47e73d0bfc5bc0d3fdf5be487cfdca341b"
integrity sha512-KJt4jhCxqrgGrC02UsQsKw90dPkFknMHsH5HTInT7gkDRRfGFwEd+e2O1/E75br3TdFhvRmzjljYz5thZ58L3A==
vscode-css-languageservice@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-5.1.0.tgz#cd172d13e9e7ae23ba567c73778aee10475ff716"
integrity sha512-iLHd/WjRKgaZBXMNeUooHG+r0qlhJBkXa+3MpQQR6Rpm928cis/3OV2Mp1R80yAQevIMeDL32RIJfHoJCT/RRg==
dependencies:
vscode-languageserver-textdocument "^1.0.1"
vscode-languageserver-types "^3.16.0"

View File

@ -1,7 +1,7 @@
{
"name": "css",
"displayName": "%displayName%",
"description": "%description%",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
@ -9,7 +9,7 @@
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js octref/language-css grammars/css.cson ./syntaxes/css.tmLanguage.json"
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin octref/language-css grammars/css.cson ./syntaxes/css.tmLanguage.json"
},
"contributes": {
"languages": [
@ -38,5 +38,9 @@
}
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "CSS Language Basics",
"description": "Provides syntax highlighting and bracket matching for CSS, LESS and SCSS files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -1,40 +1,44 @@
{
"name": "debug-auto-launch",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.5.0"
},
"activationEvents": [
"*"
],
"main": "./out/extension",
"scripts": {
"compile": "gulp compile-extension:debug-auto-launch",
"watch": "gulp watch-extension:debug-auto-launch"
},
"contributes": {
"commands": [
{
"command": "extension.node-debug.toggleAutoAttach",
"title": "%toggle.auto.attach%",
"category": "Debug"
}
]
},
"dependencies": {
"vscode-nls": "^4.0.0"
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"prettier": {
"printWidth": 100,
"trailingComma": "all",
"singleQuote": true,
"arrowParens": "avoid"
}
"name": "debug-auto-launch",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.5.0"
},
"activationEvents": [
"*"
],
"main": "./out/extension",
"scripts": {
"compile": "gulp compile-extension:debug-auto-launch",
"watch": "gulp watch-extension:debug-auto-launch"
},
"contributes": {
"commands": [
{
"command": "extension.node-debug.toggleAutoAttach",
"title": "%toggle.auto.attach%",
"category": "Debug"
}
]
},
"dependencies": {
"vscode-nls": "^4.0.0"
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"prettier": {
"printWidth": 100,
"trailingComma": "all",
"singleQuote": true,
"arrowParens": "avoid"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,143 +1,149 @@
{
"name": "debug-server-ready",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.32.0"
},
"activationEvents": [
"onDebugResolve"
],
"enableProposedApi": true,
"main": "./out/extension",
"scripts": {
"compile": "gulp compile-extension:debug-server-ready",
"watch": "gulp watch-extension:debug-server-ready"
},
"contributes": {
"debuggers": [
{
"type": "*",
"configurationAttributes": {
"launch": {
"properties": {
"serverReadyAction": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"markdownDescription": "%debug.server.ready.serverReadyAction.description%",
"default": {
"action": "openExternally"
},
"properties": {
"action": {
"type": "string",
"enum": [
"openExternally"
],
"enumDescriptions": [
"%debug.server.ready.action.openExternally.description%"
],
"markdownDescription": "%debug.server.ready.action.description%",
"default": "openExternally"
},
"pattern": {
"type": "string",
"markdownDescription": "%debug.server.ready.pattern.description%",
"default": "listening on port ([0-9]+)"
},
"uriFormat": {
"type": "string",
"markdownDescription": "%debug.server.ready.uriFormat.description%",
"default": "http://localhost:%s"
}
}
},
{
"type": "object",
"additionalProperties": false,
"markdownDescription": "%debug.server.ready.serverReadyAction.description%",
"default": {
"action": "openExternally"
},
"properties": {
"action": {
"type": "string",
"enum": [
"debugWithChrome"
],
"enumDescriptions": [
"%debug.server.ready.action.debugWithChrome.description%"
],
"markdownDescription": "%debug.server.ready.action.description%",
"default": "openExternally"
},
"pattern": {
"type": "string",
"markdownDescription": "%debug.server.ready.pattern.description%",
"default": "listening on port ([0-9]+)"
},
"uriFormat": {
"type": "string",
"markdownDescription": "%debug.server.ready.uriFormat.description%",
"default": "http://localhost:%s"
},
"webRoot": {
"type": "string",
"markdownDescription": "%debug.server.ready.webRoot.description%",
"default": "${workspaceFolder}"
}
}
},
{
"type": "object",
"additionalProperties": false,
"markdownDescription": "%debug.server.ready.serverReadyAction.description%",
"default": {
"name": "debug-server-ready",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.32.0"
},
"activationEvents": [
"onDebugResolve"
],
"enableProposedApi": true,
"main": "./out/extension",
"scripts": {
"compile": "gulp compile-extension:debug-server-ready",
"watch": "gulp watch-extension:debug-server-ready"
},
"contributes": {
"debuggers": [
{
"type": "*",
"configurationAttributes": {
"launch": {
"properties": {
"serverReadyAction": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"markdownDescription": "%debug.server.ready.serverReadyAction.description%",
"default": {
"action": "openExternally"
},
"properties": {
"action": {
"type": "string",
"enum": [
"openExternally"
],
"enumDescriptions": [
"%debug.server.ready.action.openExternally.description%"
],
"markdownDescription": "%debug.server.ready.action.description%",
"default": "openExternally"
},
"pattern": {
"type": "string",
"markdownDescription": "%debug.server.ready.pattern.description%",
"default": "listening on port ([0-9]+)"
},
"uriFormat": {
"type": "string",
"markdownDescription": "%debug.server.ready.uriFormat.description%",
"default": "http://localhost:%s"
}
}
},
{
"type": "object",
"additionalProperties": false,
"markdownDescription": "%debug.server.ready.serverReadyAction.description%",
"default": {
"action": "openExternally"
},
"properties": {
"action": {
"type": "string",
"enum": [
"debugWithChrome"
],
"enumDescriptions": [
"%debug.server.ready.action.debugWithChrome.description%"
],
"markdownDescription": "%debug.server.ready.action.description%",
"default": "openExternally"
},
"pattern": {
"type": "string",
"markdownDescription": "%debug.server.ready.pattern.description%",
"default": "listening on port ([0-9]+)"
},
"uriFormat": {
"type": "string",
"markdownDescription": "%debug.server.ready.uriFormat.description%",
"default": "http://localhost:%s"
},
"webRoot": {
"type": "string",
"markdownDescription": "%debug.server.ready.webRoot.description%",
"default": "${workspaceFolder}"
}
}
},
{
"type": "object",
"additionalProperties": false,
"markdownDescription": "%debug.server.ready.serverReadyAction.description%",
"default": {
"action": "startDebugging",
"name": "<launch browser config name>"
},
"required": ["name"],
"properties": {
"action": {
"type": "string",
"enum": [
"startDebugging"
],
"enumDescriptions": [
"%debug.server.ready.action.startDebugging.description%"
],
"markdownDescription": "%debug.server.ready.action.description%",
"default": "startDebugging"
},
"pattern": {
"type": "string",
"markdownDescription": "%debug.server.ready.pattern.description%",
"default": "listening on port ([0-9]+)"
},
"name": {
"type": "string",
"markdownDescription": "%debug.server.ready.debugConfigName.description%",
"default": "Launch Browser"
}
}
}
]
}
}
}
}
}
]
},
"dependencies": {
"vscode-nls": "^4.0.0"
},
"devDependencies": {
"@types/node": "^12.19.9"
}
"required": [
"name"
],
"properties": {
"action": {
"type": "string",
"enum": [
"startDebugging"
],
"enumDescriptions": [
"%debug.server.ready.action.startDebugging.description%"
],
"markdownDescription": "%debug.server.ready.action.description%",
"default": "startDebugging"
},
"pattern": {
"type": "string",
"markdownDescription": "%debug.server.ready.pattern.description%",
"default": "listening on port ([0-9]+)"
},
"name": {
"type": "string",
"markdownDescription": "%debug.server.ready.debugConfigName.description%",
"default": "Launch Browser"
}
}
}
]
}
}
}
}
}
]
},
"dependencies": {
"vscode-nls": "^4.0.0"
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,34 +1,57 @@
{
"name": "docker",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js moby/moby contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage ./syntaxes/docker.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "dockerfile",
"extensions": [ ".dockerfile", ".containerfile" ],
"filenames": [ "Dockerfile", "Containerfile" ],
"filenamePatterns": [ "Dockerfile.*", "Containerfile.*" ],
"aliases": [ "Docker", "Dockerfile", "Containerfile" ],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "dockerfile",
"scopeName": "source.dockerfile",
"path": "./syntaxes/docker.tmLanguage.json"
}],
"configurationDefaults": {
"[dockerfile]": {
"editor.quickSuggestions": {
"strings": true
}
}
}
}
"name": "docker",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin moby/moby contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage ./syntaxes/docker.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "dockerfile",
"extensions": [
".dockerfile",
".containerfile"
],
"filenames": [
"Dockerfile",
"Containerfile"
],
"filenamePatterns": [
"Dockerfile.*",
"Containerfile.*"
],
"aliases": [
"Docker",
"Dockerfile",
"Containerfile"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "dockerfile",
"scopeName": "source.dockerfile",
"path": "./syntaxes/docker.tmLanguage.json"
}
],
"configurationDefaults": {
"[dockerfile]": {
"editor.quickSuggestions": {
"strings": true
}
}
}
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Docker Language Basics",
"description": "Provides syntax highlighting and bracket matching in Docker files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -1,445 +1,447 @@
{
"name": "emmet",
"displayName": "Emmet",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"icon": "images/icon.png",
"categories": [
"Other"
],
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode-emmet"
},
"activationEvents": [
"onStartupFinished",
"onCommand:emmet.expandAbbreviation",
"onLanguage:html",
"onLanguage:css",
"onLanguage:scss",
"onLanguage:less"
],
"main": "./out/node/emmetNodeMain",
"browser": "./dist/browser/emmetBrowserMain",
"contributes": {
"configuration": {
"type": "object",
"title": "Emmet",
"properties": {
"emmet.showExpandedAbbreviation": {
"type": [
"string"
],
"enum": [
"never",
"always",
"inMarkupAndStylesheetFilesOnly"
],
"default": "always",
"markdownDescription": "%emmetShowExpandedAbbreviation%"
},
"emmet.showAbbreviationSuggestions": {
"type": "boolean",
"default": true,
"markdownDescription": "%emmetShowAbbreviationSuggestions%"
},
"emmet.includeLanguages": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"default": {},
"markdownDescription": "%emmetIncludeLanguages%"
},
"emmet.variables": {
"type": "object",
"properties": {
"lang": {
"type": "string",
"default": "en"
},
"charset": {
"type": "string",
"default": "UTF-8"
}
},
"default": {},
"description": "%emmetVariables%"
},
"emmet.syntaxProfiles": {
"type": "object",
"default": {},
"description": "%emmetSyntaxProfiles%"
},
"emmet.excludeLanguages": {
"type": "array",
"default": [
"markdown"
],
"description": "%emmetExclude%"
},
"emmet.extensionsPath": {
"type": [
"string",
"null"
],
"default": null,
"description": "%emmetExtensionsPath%"
},
"emmet.triggerExpansionOnTab": {
"type": "boolean",
"default": false,
"description": "%emmetTriggerExpansionOnTab%"
},
"emmet.preferences": {
"type": "object",
"default": {},
"description": "%emmetPreferences%",
"properties": {
"css.intUnit": {
"type": "string",
"default": "px",
"description": "%emmetPreferencesIntUnit%"
},
"css.floatUnit": {
"type": "string",
"default": "em",
"description": "%emmetPreferencesFloatUnit%"
},
"css.propertyEnd": {
"type": "string",
"default": ";",
"description": "%emmetPreferencesCssAfter%"
},
"sass.propertyEnd": {
"type": "string",
"default": "",
"description": "%emmetPreferencesSassAfter%"
},
"stylus.propertyEnd": {
"type": "string",
"default": "",
"description": "%emmetPreferencesStylusAfter%"
},
"css.valueSeparator": {
"type": "string",
"default": ": ",
"description": "%emmetPreferencesCssBetween%"
},
"sass.valueSeparator": {
"type": "string",
"default": ": ",
"description": "%emmetPreferencesSassBetween%"
},
"stylus.valueSeparator": {
"type": "string",
"default": " ",
"description": "%emmetPreferencesStylusBetween%"
},
"bem.elementSeparator": {
"type": "string",
"default": "__",
"description": "%emmetPreferencesBemElementSeparator%"
},
"bem.modifierSeparator": {
"type": "string",
"default": "_",
"description": "%emmetPreferencesBemModifierSeparator%"
},
"filter.commentBefore": {
"type": "string",
"default": "",
"description": "%emmetPreferencesFilterCommentBefore%"
},
"filter.commentAfter": {
"type": "string",
"default": "\n<!-- /[#ID][.CLASS] -->",
"description": "%emmetPreferencesFilterCommentAfter%"
},
"filter.commentTrigger": {
"type": "array",
"default": [
"id",
"class"
],
"description": "%emmetPreferencesFilterCommentTrigger%"
},
"format.noIndentTags": {
"type": "array",
"default": [
"html"
],
"description": "%emmetPreferencesFormatNoIndentTags%"
},
"format.forceIndentationForTags": {
"type": "array",
"default": [
"body"
],
"description": "%emmetPreferencesFormatForceIndentTags%"
},
"profile.allowCompactBoolean": {
"type": "boolean",
"default": false,
"description": "%emmetPreferencesAllowCompactBoolean%"
},
"css.webkitProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssWebkitProperties%"
},
"css.mozProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssMozProperties%"
},
"css.oProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssOProperties%"
},
"css.msProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssMsProperties%"
},
"css.fuzzySearchMinScore": {
"type": "number",
"default": 0.3,
"description": "%emmetPreferencesCssFuzzySearchMinScore%"
}
}
},
"emmet.showSuggestionsAsSnippets": {
"type": "boolean",
"default": false,
"markdownDescription": "%emmetShowSuggestionsAsSnippets%"
},
"emmet.optimizeStylesheetParsing": {
"type": "boolean",
"default": true,
"markdownDescription": "%emmetOptimizeStylesheetParsing%"
}
}
"name": "emmet",
"displayName": "Emmet",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"icon": "images/icon.png",
"categories": [
"Other"
],
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
},
"activationEvents": [
"onStartupFinished",
"onCommand:emmet.expandAbbreviation",
"onLanguage:html",
"onLanguage:css",
"onLanguage:scss",
"onLanguage:less"
],
"main": "./out/node/emmetNodeMain",
"browser": "./dist/browser/emmetBrowserMain",
"contributes": {
"configuration": {
"type": "object",
"title": "Emmet",
"properties": {
"emmet.showExpandedAbbreviation": {
"type": [
"string"
],
"enum": [
"never",
"always",
"inMarkupAndStylesheetFilesOnly"
],
"default": "always",
"markdownDescription": "%emmetShowExpandedAbbreviation%"
},
"commands": [
{
"command": "editor.emmet.action.wrapIndividualLinesWithAbbreviation",
"title": "%command.wrapIndividualLinesWithAbbreviation%",
"category": "Emmet"
"emmet.showAbbreviationSuggestions": {
"type": "boolean",
"default": true,
"markdownDescription": "%emmetShowAbbreviationSuggestions%"
},
"emmet.includeLanguages": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"default": {},
"markdownDescription": "%emmetIncludeLanguages%"
},
"emmet.variables": {
"type": "object",
"properties": {
"lang": {
"type": "string",
"default": "en"
},
{
"command": "editor.emmet.action.wrapWithAbbreviation",
"title": "%command.wrapWithAbbreviation%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.removeTag",
"title": "%command.removeTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.updateTag",
"title": "%command.updateTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.matchTag",
"title": "%command.matchTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.balanceIn",
"title": "%command.balanceIn%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.balanceOut",
"title": "%command.balanceOut%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.prevEditPoint",
"title": "%command.prevEditPoint%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.nextEditPoint",
"title": "%command.nextEditPoint%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.mergeLines",
"title": "%command.mergeLines%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.selectPrevItem",
"title": "%command.selectPrevItem%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.selectNextItem",
"title": "%command.selectNextItem%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.splitJoinTag",
"title": "%command.splitJoinTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.toggleComment",
"title": "%command.toggleComment%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.evaluateMathExpression",
"title": "%command.evaluateMathExpression%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.updateImageSize",
"title": "%command.updateImageSize%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.incrementNumberByOneTenth",
"title": "%command.incrementNumberByOneTenth%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.incrementNumberByOne",
"title": "%command.incrementNumberByOne%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.incrementNumberByTen",
"title": "%command.incrementNumberByTen%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.decrementNumberByOneTenth",
"title": "%command.decrementNumberByOneTenth%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.decrementNumberByOne",
"title": "%command.decrementNumberByOne%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.decrementNumberByTen",
"title": "%command.decrementNumberByTen%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.reflectCSSValue",
"title": "%command.reflectCSSValue%",
"category": "Emmet"
},
{
"command": "workbench.action.showEmmetCommands",
"title": "%command.showEmmetCommands%",
"category": ""
"charset": {
"type": "string",
"default": "UTF-8"
}
],
"menus": {
"commandPalette": [
{
"command": "editor.emmet.action.wrapIndividualLinesWithAbbreviation"
},
{
"command": "editor.emmet.action.wrapWithAbbreviation"
},
{
"command": "editor.emmet.action.removeTag"
},
{
"command": "editor.emmet.action.updateTag"
},
{
"command": "editor.emmet.action.matchTag"
},
{
"command": "editor.emmet.action.balanceIn"
},
{
"command": "editor.emmet.action.balanceOut"
},
{
"command": "editor.emmet.action.prevEditPoint"
},
{
"command": "editor.emmet.action.nextEditPoint"
},
{
"command": "editor.emmet.action.mergeLines"
},
{
"command": "editor.emmet.action.selectPrevItem"
},
{
"command": "editor.emmet.action.selectNextItem"
},
{
"command": "editor.emmet.action.splitJoinTag"
},
{
"command": "editor.emmet.action.toggleComment"
},
{
"command": "editor.emmet.action.evaluateMathExpression"
},
{
"command": "editor.emmet.action.updateImageSize",
"when": "resourceScheme =~ /^file$/"
},
{
"command": "editor.emmet.action.incrementNumberByOneTenth"
},
{
"command": "editor.emmet.action.incrementNumberByOne"
},
{
"command": "editor.emmet.action.incrementNumberByTen"
},
{
"command": "editor.emmet.action.decrementNumberByOneTenth"
},
{
"command": "editor.emmet.action.decrementNumberByOne"
},
{
"command": "editor.emmet.action.decrementNumberByTen"
},
{
"command": "editor.emmet.action.reflectCSSValue"
}
]
},
"default": {},
"description": "%emmetVariables%"
},
"emmet.syntaxProfiles": {
"type": "object",
"default": {},
"description": "%emmetSyntaxProfiles%"
},
"emmet.excludeLanguages": {
"type": "array",
"default": [
"markdown"
],
"description": "%emmetExclude%"
},
"emmet.extensionsPath": {
"type": [
"string",
"array",
"null"
],
"default": null,
"description": "%emmetExtensionsPath%"
},
"emmet.triggerExpansionOnTab": {
"type": "boolean",
"default": false,
"description": "%emmetTriggerExpansionOnTab%"
},
"emmet.preferences": {
"type": "object",
"default": {},
"description": "%emmetPreferences%",
"properties": {
"css.intUnit": {
"type": "string",
"default": "px",
"description": "%emmetPreferencesIntUnit%"
},
"css.floatUnit": {
"type": "string",
"default": "em",
"description": "%emmetPreferencesFloatUnit%"
},
"css.propertyEnd": {
"type": "string",
"default": ";",
"description": "%emmetPreferencesCssAfter%"
},
"sass.propertyEnd": {
"type": "string",
"default": "",
"description": "%emmetPreferencesSassAfter%"
},
"stylus.propertyEnd": {
"type": "string",
"default": "",
"description": "%emmetPreferencesStylusAfter%"
},
"css.valueSeparator": {
"type": "string",
"default": ": ",
"description": "%emmetPreferencesCssBetween%"
},
"sass.valueSeparator": {
"type": "string",
"default": ": ",
"description": "%emmetPreferencesSassBetween%"
},
"stylus.valueSeparator": {
"type": "string",
"default": " ",
"description": "%emmetPreferencesStylusBetween%"
},
"bem.elementSeparator": {
"type": "string",
"default": "__",
"description": "%emmetPreferencesBemElementSeparator%"
},
"bem.modifierSeparator": {
"type": "string",
"default": "_",
"description": "%emmetPreferencesBemModifierSeparator%"
},
"filter.commentBefore": {
"type": "string",
"default": "",
"description": "%emmetPreferencesFilterCommentBefore%"
},
"filter.commentAfter": {
"type": "string",
"default": "\n<!-- /[#ID][.CLASS] -->",
"description": "%emmetPreferencesFilterCommentAfter%"
},
"filter.commentTrigger": {
"type": "array",
"default": [
"id",
"class"
],
"description": "%emmetPreferencesFilterCommentTrigger%"
},
"format.noIndentTags": {
"type": "array",
"default": [
"html"
],
"description": "%emmetPreferencesFormatNoIndentTags%"
},
"format.forceIndentationForTags": {
"type": "array",
"default": [
"body"
],
"description": "%emmetPreferencesFormatForceIndentTags%"
},
"profile.allowCompactBoolean": {
"type": "boolean",
"default": false,
"description": "%emmetPreferencesAllowCompactBoolean%"
},
"css.webkitProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssWebkitProperties%"
},
"css.mozProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssMozProperties%"
},
"css.oProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssOProperties%"
},
"css.msProperties": {
"type": "string",
"default": null,
"markdownDescription": "%emmetPreferencesCssMsProperties%"
},
"css.fuzzySearchMinScore": {
"type": "number",
"default": 0.3,
"description": "%emmetPreferencesCssFuzzySearchMinScore%"
},
"output.reverseAttributes": {
"type": "boolean",
"default": false,
"description": "%emmetPreferencesOutputReverseAttributes%"
},
"css.color.short": {
"type": "boolean",
"default": true,
"description": "%emmetPreferencesCssColorShort%"
}
}
},
"emmet.showSuggestionsAsSnippets": {
"type": "boolean",
"default": false,
"markdownDescription": "%emmetShowSuggestionsAsSnippets%"
},
"emmet.optimizeStylesheetParsing": {
"type": "boolean",
"default": true,
"markdownDescription": "%emmetOptimizeStylesheetParsing%"
}
}
},
"scripts": {
"watch": "gulp watch-extension:emmet",
"compile": "gulp compile-extension:emmet",
"deps": "yarn add vscode-emmet-helper"
},
"devDependencies": {
"@types/node": "^12.19.9",
"emmet": "https://github.com/rzhao271/emmet.git#1b2df677d8925ef5ea6da9df8845968403979a0a"
},
"dependencies": {
"@emmetio/abbreviation": "^2.2.0",
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
"@emmetio/html-matcher": "^0.3.3",
"@emmetio/math-expression": "^1.0.4",
"image-size": "^0.5.2",
"vscode-emmet-helper": "2.2.4",
"vscode-languageserver-textdocument": "^1.0.1"
"commands": [
{
"command": "editor.emmet.action.wrapWithAbbreviation",
"title": "%command.wrapWithAbbreviation%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.removeTag",
"title": "%command.removeTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.updateTag",
"title": "%command.updateTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.matchTag",
"title": "%command.matchTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.balanceIn",
"title": "%command.balanceIn%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.balanceOut",
"title": "%command.balanceOut%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.prevEditPoint",
"title": "%command.prevEditPoint%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.nextEditPoint",
"title": "%command.nextEditPoint%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.mergeLines",
"title": "%command.mergeLines%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.selectPrevItem",
"title": "%command.selectPrevItem%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.selectNextItem",
"title": "%command.selectNextItem%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.splitJoinTag",
"title": "%command.splitJoinTag%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.toggleComment",
"title": "%command.toggleComment%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.evaluateMathExpression",
"title": "%command.evaluateMathExpression%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.updateImageSize",
"title": "%command.updateImageSize%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.incrementNumberByOneTenth",
"title": "%command.incrementNumberByOneTenth%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.incrementNumberByOne",
"title": "%command.incrementNumberByOne%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.incrementNumberByTen",
"title": "%command.incrementNumberByTen%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.decrementNumberByOneTenth",
"title": "%command.decrementNumberByOneTenth%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.decrementNumberByOne",
"title": "%command.decrementNumberByOne%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.decrementNumberByTen",
"title": "%command.decrementNumberByTen%",
"category": "Emmet"
},
{
"command": "editor.emmet.action.reflectCSSValue",
"title": "%command.reflectCSSValue%",
"category": "Emmet"
},
{
"command": "workbench.action.showEmmetCommands",
"title": "%command.showEmmetCommands%",
"category": ""
}
],
"menus": {
"commandPalette": [
{
"command": "editor.emmet.action.wrapWithAbbreviation"
},
{
"command": "editor.emmet.action.removeTag"
},
{
"command": "editor.emmet.action.updateTag"
},
{
"command": "editor.emmet.action.matchTag"
},
{
"command": "editor.emmet.action.balanceIn"
},
{
"command": "editor.emmet.action.balanceOut"
},
{
"command": "editor.emmet.action.prevEditPoint"
},
{
"command": "editor.emmet.action.nextEditPoint"
},
{
"command": "editor.emmet.action.mergeLines"
},
{
"command": "editor.emmet.action.selectPrevItem"
},
{
"command": "editor.emmet.action.selectNextItem"
},
{
"command": "editor.emmet.action.splitJoinTag"
},
{
"command": "editor.emmet.action.toggleComment"
},
{
"command": "editor.emmet.action.evaluateMathExpression"
},
{
"command": "editor.emmet.action.updateImageSize",
"when": "resourceScheme =~ /^file$/"
},
{
"command": "editor.emmet.action.incrementNumberByOneTenth"
},
{
"command": "editor.emmet.action.incrementNumberByOne"
},
{
"command": "editor.emmet.action.incrementNumberByTen"
},
{
"command": "editor.emmet.action.decrementNumberByOneTenth"
},
{
"command": "editor.emmet.action.decrementNumberByOne"
},
{
"command": "editor.emmet.action.decrementNumberByTen"
},
{
"command": "editor.emmet.action.reflectCSSValue"
}
]
}
},
"scripts": {
"watch": "gulp watch-extension:emmet",
"compile": "gulp compile-extension:emmet",
"deps": "yarn add vscode-emmet-helper"
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"dependencies": {
"@emmetio/abbreviation": "^2.2.0",
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
"@emmetio/html-matcher": "^0.3.3",
"@emmetio/math-expression": "^1.0.4",
"image-size": "^0.5.2",
"vscode-emmet-helper": "^2.3.0",
"vscode-languageserver-textdocument": "^1.0.1"
}
}

View File

@ -1,7 +1,6 @@
{
"description": "Emmet support for VS Code",
"command.wrapWithAbbreviation": "Wrap with Abbreviation",
"command.wrapIndividualLinesWithAbbreviation": "Wrap Individual Lines with Abbreviation",
"command.removeTag": "Remove Tag",
"command.updateTag": "Update Tag",
"command.matchTag": "Go to Matching Pair",
@ -55,5 +54,7 @@
"emmetPreferencesCssOProperties": "Comma separated CSS properties that get the 'o' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'o' prefix.",
"emmetPreferencesCssMsProperties": "Comma separated CSS properties that get the 'ms' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'ms' prefix.",
"emmetPreferencesCssFuzzySearchMinScore": "The minimum score (from 0 to 1) that fuzzy-matched abbreviation should achieve. Lower values may produce many false-positive matches, higher values may reduce possible matches.",
"emmetOptimizeStylesheetParsing": "When set to `false`, the whole file is parsed to determine if current position is valid for expanding Emmet abbreviations. When set to `true`, only the content around the current position in css/scss/less files is parsed."
"emmetOptimizeStylesheetParsing": "When set to `false`, the whole file is parsed to determine if current position is valid for expanding Emmet abbreviations. When set to `true`, only the content around the current position in css/scss/less files is parsed.",
"emmetPreferencesOutputReverseAttributes": "If `true`, reverses attribute merging directions when resolving snippets.",
"emmetPreferencesCssColorShort": "If `true`, color values like #f will be expanded to #fff instead of #ffffff."
}

View File

@ -6,19 +6,12 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { Node, HtmlNode, Rule, Property, Stylesheet } from 'EmmetFlatNode';
import { getEmmetHelper, getFlatNode, getMappingForIncludedLanguages, validate, getEmmetConfiguration, isStyleSheet, getEmmetMode, parsePartialStylesheet, isStyleAttribute, getEmbeddedCssNodeIfAny, allowedMimeTypesInScriptTag, toLSTextDocument } from './util';
import { getEmmetHelper, getFlatNode, getMappingForIncludedLanguages, validate, getEmmetConfiguration, isStyleSheet, getEmmetMode, parsePartialStylesheet, isStyleAttribute, getEmbeddedCssNodeIfAny, allowedMimeTypesInScriptTag, toLSTextDocument, isOffsetInsideOpenOrCloseTag } from './util';
import { getRootNode as parseDocument } from './parseDocument';
import { MarkupAbbreviation } from 'emmet';
// import { AbbreviationNode } from '@emmetio/abbreviation';
const localize = nls.loadMessageBundle();
const trimRegex = /[\u00a0]*[\d#\-\*\u2022]+\.?/;
const hexColorRegex = /^#[\da-fA-F]{0,6}$/;
// const inlineElements = ['a', 'abbr', 'acronym', 'applet', 'b', 'basefont', 'bdo',
// 'big', 'br', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i',
// 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'map', 'object', 'q',
// 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup',
// 'textarea', 'tt', 'u', 'var'];
interface ExpandAbbreviationInput {
syntax: string;
@ -26,6 +19,8 @@ interface ExpandAbbreviationInput {
rangeToReplace: vscode.Range;
textToWrap?: string[];
filter?: string;
indent?: string;
baseIndent?: string;
}
interface PreviewRangesWithContent {
@ -33,22 +28,15 @@ interface PreviewRangesWithContent {
originalRange: vscode.Range;
originalContent: string;
textToWrapInPreview: string[];
baseIndent: string;
}
export function wrapWithAbbreviation(args: any) {
return doWrapping(true, args);
}
export function wrapIndividualLinesWithAbbreviation(args: any) {
return doWrapping(true, args);
}
function doWrapping(_: boolean, args: any) {
if (!validate(false) || !vscode.window.activeTextEditor) {
return;
export async function wrapWithAbbreviation(args: any): Promise<boolean> {
if (!validate(false)) {
return false;
}
const editor = vscode.window.activeTextEditor;
const editor = vscode.window.activeTextEditor!;
const document = editor.document;
args = args || {};
@ -59,44 +47,68 @@ function doWrapping(_: boolean, args: any) {
const syntax = getSyntaxFromArgs(args) || 'html';
const rootNode = parseDocument(document, true);
let inPreview = false;
let currentValue = '';
const helper = getEmmetHelper();
// Fetch general information for the succesive expansions. i.e. the ranges to replace and its contents
const rangesToReplace: PreviewRangesWithContent[] = editor.selections.sort((a: vscode.Selection, b: vscode.Selection) => { return a.start.compareTo(b.start); }).map(selection => {
let rangeToReplace: vscode.Range = selection.isReversed ? new vscode.Range(selection.active, selection.anchor) : selection;
if (!rangeToReplace.isSingleLine && rangeToReplace.end.character === 0) {
// in case of multi-line, exclude last empty line from rangeToReplace
const previousLine = rangeToReplace.end.line - 1;
const lastChar = document.lineAt(previousLine).text.length;
rangeToReplace = new vscode.Range(rangeToReplace.start, new vscode.Position(previousLine, lastChar));
} else if (rangeToReplace.isEmpty) {
const { active } = selection;
const activeOffset = document.offsetAt(active);
const currentNode = getFlatNode(rootNode, activeOffset, true);
if (currentNode) {
const currentNodeStart = document.positionAt(currentNode.start);
const currentNodeEnd = document.positionAt(currentNode.end);
if (currentNodeStart.line === active.line || currentNodeEnd.line === active.line) {
// wrap around entire node
rangeToReplace = new vscode.Range(currentNodeStart, currentNodeEnd);
}
else {
// wrap line that cursor is on
rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, document.lineAt(rangeToReplace.start.line).text.length);
}
} else {
// wrap line that cursor is on
rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, document.lineAt(rangeToReplace.start.line).text.length);
const operationRanges = editor.selections.sort((a, b) => a.start.compareTo(b.start)).map(selection => {
let rangeToReplace: vscode.Range = selection;
// wrap around the node if the selection falls inside its open or close tag
{
let { start, end } = rangeToReplace;
const startOffset = document.offsetAt(start);
const startNode = getFlatNode(rootNode, startOffset, true);
if (startNode && isOffsetInsideOpenOrCloseTag(startNode, startOffset)) {
start = document.positionAt(startNode.start);
const nodeEndPosition = document.positionAt(startNode.end);
end = nodeEndPosition.isAfter(end) ? nodeEndPosition : end;
}
const endOffset = document.offsetAt(end);
const endNode = getFlatNode(rootNode, endOffset, true);
if (endNode && isOffsetInsideOpenOrCloseTag(endNode, endOffset)) {
const nodeStartPosition = document.positionAt(endNode.start);
start = nodeStartPosition.isBefore(start) ? nodeStartPosition : start;
const nodeEndPosition = document.positionAt(endNode.end);
end = nodeEndPosition.isAfter(end) ? nodeEndPosition : end;
}
rangeToReplace = new vscode.Range(start, end);
}
// in case of multi-line, exclude last empty line from rangeToReplace
if (!rangeToReplace.isSingleLine && rangeToReplace.end.character === 0) {
const previousLine = rangeToReplace.end.line - 1;
rangeToReplace = new vscode.Range(rangeToReplace.start, document.lineAt(previousLine).range.end);
}
// wrap line the cursor is on
if (rangeToReplace.isEmpty) {
rangeToReplace = document.lineAt(rangeToReplace.start).range;
}
const firstLineOfSelection = document.lineAt(rangeToReplace.start).text.substr(rangeToReplace.start.character);
const matches = firstLineOfSelection.match(/^(\s*)/);
const extraWhitespaceSelected = matches ? matches[1].length : 0;
rangeToReplace = new vscode.Range(rangeToReplace.start.line, rangeToReplace.start.character + extraWhitespaceSelected, rangeToReplace.end.line, rangeToReplace.end.character);
// ignore whitespace on the first line
const firstLineOfRange = document.lineAt(rangeToReplace.start);
if (!firstLineOfRange.isEmptyOrWhitespace && firstLineOfRange.firstNonWhitespaceCharacterIndex > rangeToReplace.start.character) {
rangeToReplace = rangeToReplace.with(new vscode.Position(rangeToReplace.start.line, firstLineOfRange.firstNonWhitespaceCharacterIndex));
}
return rangeToReplace;
}).reduce((mergedRanges, range) => {
// Merge overlapping ranges
if (mergedRanges.length > 0 && range.intersection(mergedRanges[mergedRanges.length - 1])) {
mergedRanges.push(range.union(mergedRanges.pop()!));
} else {
mergedRanges.push(range);
}
return mergedRanges;
}, [] as vscode.Range[]);
// Backup orginal selections and update selections
// Also helps with https://github.com/microsoft/vscode/issues/113930 by avoiding `editor.linkedEditing`
// execution if selection is inside an open or close tag
const oldSelections = editor.selections;
editor.selections = operationRanges.map(range => new vscode.Selection(range.start, range.end));
// Fetch general information for the succesive expansions. i.e. the ranges to replace and its contents
const rangesToReplace: PreviewRangesWithContent[] = operationRanges.map(rangeToReplace => {
let textToWrapInPreview: string[];
const textToReplace = document.getText(rangeToReplace);
@ -104,10 +116,10 @@ function doWrapping(_: boolean, args: any) {
// this assumption helps with applyPreview later
const wholeFirstLine = document.lineAt(rangeToReplace.start).text;
const otherMatches = wholeFirstLine.match(/^(\s*)/);
const precedingWhitespace = otherMatches ? otherMatches[1] : '';
const baseIndent = otherMatches ? otherMatches[1] : '';
textToWrapInPreview = rangeToReplace.isSingleLine ?
[textToReplace] :
textToReplace.split('\n' + precedingWhitespace).map(x => x.trimEnd());
textToReplace.split('\n' + baseIndent).map(x => x.trimEnd());
// escape $ characters, fixes #52640
textToWrapInPreview = textToWrapInPreview.map(e => e.replace(/(\$\d)/g, '\\$1'));
@ -116,31 +128,13 @@ function doWrapping(_: boolean, args: any) {
previewRange: rangeToReplace,
originalRange: rangeToReplace,
originalContent: textToReplace,
textToWrapInPreview
textToWrapInPreview,
baseIndent
};
});
// if a selection falls on a node, it could interfere with linked editing,
// so back up the selections, and change selections to wrap around the node
const oldSelections = editor.selections;
const newSelections: vscode.Selection[] = [];
editor.selections.forEach(selection => {
let { start, end } = selection;
const startOffset = document.offsetAt(start);
const startNode = <HtmlNode>getFlatNode(rootNode, startOffset, true);
const endOffset = document.offsetAt(end);
const endNode = <HtmlNode>getFlatNode(rootNode, endOffset, true);
if (startNode) {
start = document.positionAt(startNode.start);
}
if (endNode) {
end = document.positionAt(endNode.end);
}
// don't need to preserve active/anchor order since the selection changes
// after wrapping anyway
newSelections.push(new vscode.Selection(start, end));
});
editor.selections = newSelections;
const { tabSize, insertSpaces } = editor.options;
const indent = insertSpaces ? ' '.repeat(tabSize as number) : '\t';
function revertPreview(): Thenable<boolean> {
return editor.edit(builder => {
@ -168,16 +162,10 @@ function doWrapping(_: boolean, args: any) {
// get the current preview range, format the new wrapped text, and then replace
// the text in the preview range with that new text
const oldPreviewRange = rangesToReplace[i].previewRange;
const preceedingText = editor.document.getText(new vscode.Range(oldPreviewRange.start.line, 0, oldPreviewRange.start.line, oldPreviewRange.start.character));
const indentPrefix = (preceedingText.match(/^(\s*)/) || ['', ''])[1];
let newText = expandedText;
newText = newText.replace(/\n/g, '\n' + indentPrefix); // Adding indentation on each line of expanded text
newText = newText.replace(/\$\{[\d]*\}/g, '|'); // Removing Tabstops
newText = newText.replace(/\$\{[\d]*(:[^}]*)?\}/g, (match) => { // Replacing Placeholders
return match.replace(/^\$\{[\d]*:/, '').replace('}', '');
});
newText = newText.replace(/\\\$/g, '$'); // Remove backslashes before $
const newText = expandedText
.replace(/\$\{[\d]*\}/g, '|') // Removing Tabstops
.replace(/\$\{[\d]*:([^}]*)\}/g, (_, placeholder) => placeholder) // Replacing Placeholders
.replace(/\\\$/g, '$'); // Remove backslashes before $
builder.replace(oldPreviewRange, newText);
// calculate the new preview range to use for future previews
@ -198,12 +186,10 @@ function doWrapping(_: boolean, args: any) {
// plus the number of characters between both selections.
newPreviewStart = lastNewPreviewRange.end.character + (oldPreviewRange.start.character - lastOldPreviewRange.end.character);
newPreviewEnd += newPreviewStart;
}
else if (i > 0 && newPreviewLineStart === lastNewPreviewRange.end.line) {
} else if (i > 0 && newPreviewLineStart === lastNewPreviewRange.end.line) {
// Same as above but expandedTextLines.length > 1 so newPreviewEnd keeps its value.
newPreviewStart = lastNewPreviewRange.end.character + (oldPreviewRange.start.character - lastOldPreviewRange.end.character);
}
else if (expandedTextLines.length === 1) {
} else if (expandedTextLines.length === 1) {
// If the expandedText is single line, add the length of preceeding text as it will not be included in line length.
newPreviewEnd += oldPreviewRange.start.character;
}
@ -216,66 +202,64 @@ function doWrapping(_: boolean, args: any) {
}, { undoStopBefore: false, undoStopAfter: false });
}
function makeChanges(inputAbbreviation: string | undefined, definitive: boolean): Thenable<boolean> {
if (!inputAbbreviation || !inputAbbreviation.trim() || !helper.isAbbreviationValid(syntax, inputAbbreviation)) {
return inPreview ? revertPreview().then(() => { return false; }) : Promise.resolve(inPreview);
}
const extractedResults = helper.extractAbbreviationFromText(inputAbbreviation);
let inPreviewMode = false;
async function makeChanges(inputAbbreviation: string | undefined, previewChanges: boolean): Promise<boolean> {
const isAbbreviationValid = !!inputAbbreviation && !!inputAbbreviation.trim() && helper.isAbbreviationValid(syntax, inputAbbreviation);
const extractedResults = isAbbreviationValid ? helper.extractAbbreviationFromText(inputAbbreviation!) : undefined;
if (!extractedResults) {
return Promise.resolve(inPreview);
} else if (extractedResults.abbreviation !== inputAbbreviation) {
// Not clear what should we do in this case. Warn the user? How?
if (inPreviewMode) {
inPreviewMode = false;
await revertPreview();
}
return false;
}
const { abbreviation, filter } = extractedResults;
if (definitive) {
const revertPromise = inPreview ? revertPreview() : Promise.resolve(true);
return revertPromise.then(() => {
const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => {
const rangeToReplace = rangesAndContent.originalRange;
let textToWrap: string[];
// if (individualLines) {
textToWrap = rangesAndContent.textToWrapInPreview;
// } else {
// // use the p tag as a dummy element to get Emmet to wrap the expression properly
// textToWrap = rangeToReplace.isSingleLine ?
// ['$TM_SELECTED_TEXT'] : ['<p>$TM_SELECTED_TEXT</p>'];
// }
return { syntax: syntax || '', abbreviation, rangeToReplace, textToWrap, filter };
});
return expandAbbreviationInRange(editor, expandAbbrList, false).then(() => { return true; });
});
if (abbreviation !== inputAbbreviation) {
// Not clear what should we do in this case. Warn the user? How?
}
const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => {
return { syntax: syntax || '', abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter };
});
if (previewChanges) {
const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent =>
({ syntax, abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter, indent, baseIndent: rangesAndContent.baseIndent })
);
return applyPreview(expandAbbrList);
inPreviewMode = true;
return applyPreview(expandAbbrList);
}
const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent =>
({ syntax, abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter, indent })
);
if (inPreviewMode) {
inPreviewMode = false;
await revertPreview();
}
return expandAbbreviationInRange(editor, expandAbbrList, false);
}
let currentValue = '';
function inputChanged(value: string): string {
if (value !== currentValue) {
currentValue = value;
makeChanges(value, false).then((out) => {
inPreview = out;
});
makeChanges(value, true);
}
return '';
}
const prompt = localize('wrapWithAbbreviationPrompt', "Enter Abbreviation");
const abbreviationPromise: Thenable<string | undefined> = (args && args['abbreviation']) ?
Promise.resolve(args['abbreviation']) :
vscode.window.showInputBox({ prompt, validateInput: inputChanged });
return abbreviationPromise.then(async (inputAbbreviation) => {
const changesWereMade = await makeChanges(inputAbbreviation, true);
if (!changesWereMade) {
editor.selections = oldSelections;
}
return changesWereMade;
});
const inputAbbreviation = (args && args['abbreviation'])
? (args['abbreviation'] as string)
: await vscode.window.showInputBox({ prompt, validateInput: inputChanged });
const changesWereMade = await makeChanges(inputAbbreviation, false);
if (!changesWereMade) {
editor.selections = oldSelections;
}
return changesWereMade;
}
export function expandEmmetAbbreviation(args: any): Thenable<boolean | undefined> {
@ -654,36 +638,13 @@ function expandAbbreviationInRange(editor: vscode.TextEditor, expandAbbrList: Ex
// all cursors are maintained after snippet insertion
const anyExpandAbbrInput = expandAbbrList[0];
const expandedText = expandAbbr(anyExpandAbbrInput);
const allRanges = expandAbbrList.map(value => {
return new vscode.Range(value.rangeToReplace.start.line, value.rangeToReplace.start.character, value.rangeToReplace.end.line, value.rangeToReplace.end.character);
});
const allRanges = expandAbbrList.map(value => value.rangeToReplace);
if (expandedText) {
return editor.insertSnippet(new vscode.SnippetString(expandedText), allRanges);
}
return Promise.resolve(false);
}
// /*
// * Walks the tree rooted at root and apply function fn on each node.
// * if fn return false at any node, the further processing of tree is stopped.
// */
// function walk(root: AbbreviationNode, fn: ((node: AbbreviationNode) => boolean)): boolean {
// if (fn(root) === false || walkChildren(root.children, fn) === false) {
// return false;
// }
// return true;
// }
// function walkChildren(children: AbbreviationNode[], fn: ((node: AbbreviationNode) => boolean)): boolean {
// for (let i = 0; i < children.length; i++) {
// const child = children[i];
// if (walk(child, fn) === false) {
// return false;
// }
// }
// return true;
// }
/**
* Expands abbreviation as detailed in given input.
*/
@ -699,54 +660,26 @@ function expandAbbr(input: ExpandAbbreviationInput): string | undefined {
}
expandOptions['text'] = input.textToWrap;
// Below fixes https://github.com/microsoft/vscode/issues/29898
// With this, Emmet formats inline elements as block elements
// ensuring the wrapped multi line text does not get merged to a single line
if (!input.rangeToReplace.isSingleLine && expandOptions.options) {
expandOptions.options['output.inlineBreak'] = 1;
if (expandOptions.options) {
// Below fixes https://github.com/microsoft/vscode/issues/29898
// With this, Emmet formats inline elements as block elements
// ensuring the wrapped multi line text does not get merged to a single line
if (!input.rangeToReplace.isSingleLine) {
expandOptions.options['output.inlineBreak'] = 1;
}
if (input.indent) {
expandOptions.options['output.indent'] = input.indent;
}
if (input.baseIndent) {
expandOptions.options['output.baseIndent'] = input.baseIndent;
}
}
}
let expandedText;
let expandedText: string | undefined;
try {
// Expand the abbreviation
if (input.textToWrap && !isStyleSheet(input.syntax)) {
const parsedAbbr = <MarkupAbbreviation>helper.parseAbbreviation(input.abbreviation, expandOptions);
// if (input.rangeToReplace.isSingleLine && input.textToWrap.length === 1) {
// // Fetch rightmost element in the parsed abbreviation (i.e the element that will contain the wrapped text).
// const wrappingNodeChildren = parsedAbbr.children;
// let wrappingNode = wrappingNodeChildren[wrappingNodeChildren.length - 1];
// while (wrappingNode && wrappingNode.children && wrappingNode.children.length > 0) {
// wrappingNode = wrappingNode.children[wrappingNode.children.length - 1];
// }
// // If wrapping with a block element, insert newline in the text to wrap.
// // const format = expandOptions.options ? (expandOptions.options['output.format'] ?? true) : true;
// // if (wrappingNode && wrappingNode.name && wrappingNode.value
// // && inlineElements.indexOf(wrappingNode.name) === -1
// // && format) {
// // wrappingNode.value[0] = '\n\t' + wrappingNode.value[0] + '\n';
// // }
// }
// Below fixes https://github.com/microsoft/vscode/issues/78219
// walk the tree and remove tags for empty values
// walkChildren(parsedAbbr.children, node => {
// if (node.name !== null && node.value && node.value[0] === '' && !node.selfClosing && node.children.length === 0) {
// node.name = '';
// node.value[0] = '\n';
// }
// return true;
// });
expandedText = helper.expandAbbreviation(parsedAbbr, expandOptions);
// All $anyword would have been escaped by the emmet helper.
// Remove the escaping backslash from $TM_SELECTED_TEXT so that VS Code Snippet controller can treat it as a variable
expandedText = expandedText.replace('<p>\\$TM_SELECTED_TEXT</p>', '$TM_SELECTED_TEXT');
} else {
expandedText = helper.expandAbbreviation(input.abbreviation, expandOptions);
}
expandedText = helper.expandAbbreviation(input.abbreviation, expandOptions);
} catch (e) {
vscode.window.showErrorMessage('Failed to expand abbreviation');
}

View File

@ -5,7 +5,7 @@
import * as vscode from 'vscode';
import { DefaultCompletionItemProvider } from './defaultCompletionProvider';
import { expandEmmetAbbreviation, wrapWithAbbreviation, wrapIndividualLinesWithAbbreviation } from './abbreviationActions';
import { expandEmmetAbbreviation, wrapWithAbbreviation } from './abbreviationActions';
import { removeTag } from './removeTag';
import { updateTag } from './updateTag';
import { matchTag } from './matchTag';
@ -23,15 +23,12 @@ import { addFileToParseCache, removeFileFromParseCache } from './parseDocument';
export function activateEmmetExtension(context: vscode.ExtensionContext) {
registerCompletionProviders(context);
updateEmmetExtensionsPath();
context.subscriptions.push(vscode.commands.registerCommand('editor.emmet.action.wrapWithAbbreviation', (args) => {
wrapWithAbbreviation(args);
}));
context.subscriptions.push(vscode.commands.registerCommand('editor.emmet.action.wrapIndividualLinesWithAbbreviation', (args) => {
wrapIndividualLinesWithAbbreviation(args);
}));
context.subscriptions.push(vscode.commands.registerCommand('emmet.expandAbbreviation', (args) => {
expandEmmetAbbreviation(args);
}));
@ -129,8 +126,6 @@ export function activateEmmetExtension(context: vscode.ExtensionContext) {
vscode.commands.executeCommand('workbench.action.quickOpen', '>Emmet: ');
}));
updateEmmetExtensionsPath();
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration((e) => {
if (e.affectsConfiguration('emmet.includeLanguages')) {
registerCompletionProviders(context);

View File

@ -37,6 +37,13 @@ suite('Tests for completion in CSS embedded in HTML', () => {
{ label: 'widows: ;', documentation: `widows: ;` }
]);
});
// https://github.com/microsoft/vscode/issues/117020
test('#117020, ! at end of abbreviation should have completion', async () => {
await testCssCompletionProvider(`.foo { bdbn!| }`, [
{ label: 'border-bottom: none !important;', documentation: `border-bottom: none !important;` }
]);
});
});
interface TestCompletionItem {

View File

@ -0,0 +1,3 @@
{
"editor.minimap.enabled": false // see https://github.com/microsoft/vscode/issues/115747
}

View File

@ -7,7 +7,7 @@ import 'mocha';
import * as assert from 'assert';
import { Selection, workspace, ConfigurationTarget } from 'vscode';
import { withRandomFileEditor, closeAllEditors } from './testUtils';
import { wrapWithAbbreviation, wrapIndividualLinesWithAbbreviation } from '../abbreviationActions';
import { wrapWithAbbreviation } from '../abbreviationActions';
const htmlContentsForBlockWrapTests = `
<ul class="nav main">
@ -167,7 +167,7 @@ suite('Tests for Wrap with Abbreviations', () => {
</div>
</a>
`;
return testWrapWithAbbreviation([new Selection(1, 1, 1, 1)], 'a[href="https://example.com"]>div', expectedContents, contents);
return testWrapWithAbbreviation([new Selection(1, 2, 1, 2)], 'a[href="https://example.com"]>div', expectedContents, contents);
});
test('Wrap with abbreviation entire node when cursor is on opening tag', () => {
@ -183,7 +183,7 @@ suite('Tests for Wrap with Abbreviations', () => {
</div>
</div>
`;
return testWrapWithAbbreviation([new Selection(1, 1, 1, 1)], 'div', expectedContents, contents);
return testWrapWithAbbreviation([new Selection(1, 2, 1, 2)], 'div', expectedContents, contents);
});
test('Wrap with abbreviation entire node when cursor is on closing tag', () => {
@ -199,7 +199,7 @@ suite('Tests for Wrap with Abbreviations', () => {
</div>
</div>
`;
return testWrapWithAbbreviation([new Selection(3, 1, 3, 1)], 'div', expectedContents, contents);
return testWrapWithAbbreviation([new Selection(3, 2, 3, 2)], 'div', expectedContents, contents);
});
test('Wrap with multiline abbreviation doesnt add extra spaces', () => {
@ -302,7 +302,7 @@ suite('Tests for Wrap with Abbreviations', () => {
});
test('Wrap with abbreviation and format set to false', () => {
return workspace.getConfiguration('emmet').update('syntaxProfiles', { 'html' : { 'format': false } }, ConfigurationTarget.Global).then(() => {
return workspace.getConfiguration('emmet').update('syntaxProfiles', { 'html': { 'format': false } }, ConfigurationTarget.Global).then(() => {
return testWrapWithAbbreviation(multiCursors, 'h1', wrapInlineElementExpectedFormatFalse, htmlContentsForBlockWrapTests).then(() => {
return workspace.getConfiguration('emmet').update('syntaxProfiles', oldValueForSyntaxProfiles ? oldValueForSyntaxProfiles.globalValue : undefined, ConfigurationTarget.Global);
});
@ -347,7 +347,7 @@ suite('Tests for Wrap with Abbreviations', () => {
</ul>
`;
return testWrapWithAbbreviation([new Selection(2,2,3,33)], '.hello', wrapMultiLineJsxExpected, htmlContentsForBlockWrapTests, 'jsx');
return testWrapWithAbbreviation([new Selection(2, 2, 3, 33)], '.hello', wrapMultiLineJsxExpected, htmlContentsForBlockWrapTests, 'jsx');
});
test('Wrap individual line with abbreviation uses className for jsx files', () => {
@ -362,8 +362,34 @@ suite('Tests for Wrap with Abbreviations', () => {
</ul>
`;
return testWrapIndividualLinesWithAbbreviation([new Selection(2,2,3,33)], '.hello$*', wrapIndividualLinesJsxExpected, htmlContentsForBlockWrapTests, 'jsx');
return testWrapIndividualLinesWithAbbreviation([new Selection(2, 2, 3, 33)], '.hello$*', wrapIndividualLinesJsxExpected, htmlContentsForBlockWrapTests, 'jsx');
});
test('Wrap with abbreviation merge overlapping computed ranges', () => {
const contents = `
<div class="nav main">
hello
</div>
`;
const expectedContents = `
<div>
<div class="nav main">
hello
</div>
</div>
`;
return testWrapWithAbbreviation([new Selection(1, 2, 1, 2), new Selection(1, 10, 1, 10)], 'div', expectedContents, contents);
});
test('Wrap with abbreviation ignore invalid abbreviation', () => {
const contents = `
<div class="nav main">
hello
</div>
`;
return testWrapWithAbbreviation([new Selection(1, 2, 1, 2)], 'div]', contents, contents);
});
});
@ -386,7 +412,7 @@ function testWrapWithAbbreviation(selections: Selection[], abbreviation: string,
function testWrapIndividualLinesWithAbbreviation(selections: Selection[], abbreviation: string, expectedContents: string, input: string, fileExtension: string = 'html'): Thenable<any> {
return withRandomFileEditor(input, fileExtension, (editor, _) => {
editor.selections = selections;
const promise = wrapIndividualLinesWithAbbreviation({ abbreviation });
const promise = wrapWithAbbreviation({ abbreviation });
if (!promise) {
assert.equal(1, 2, 'Wrap individual lines with Abbreviation returned undefined.');
return Promise.resolve();

View File

@ -28,7 +28,6 @@ export function getEmmetHelper() {
if (!_emmetHelper) {
_emmetHelper = require('vscode-emmet-helper');
}
updateEmmetExtensionsPath();
return _emmetHelper;
}
@ -36,9 +35,7 @@ export function getEmmetHelper() {
* Update Emmet Helper to use user snippets from the extensionsPath setting
*/
export function updateEmmetExtensionsPath(forceRefresh: boolean = false) {
if (!_emmetHelper) {
return;
}
const helper = getEmmetHelper();
let extensionsPath = vscode.workspace.getConfiguration('emmet')['extensionsPath'];
if (forceRefresh || _currentExtensionsPath !== extensionsPath) {
_currentExtensionsPath = extensionsPath;
@ -47,7 +44,7 @@ export function updateEmmetExtensionsPath(forceRefresh: boolean = false) {
} else {
const rootPath = vscode.workspace.workspaceFolders[0].uri;
const fileSystem = vscode.workspace.fs;
_emmetHelper.updateExtensionsPath(extensionsPath, fileSystem, rootPath, _homeDir).then(null, (err: string) => vscode.window.showErrorMessage(err));
helper.updateExtensionsPath(extensionsPath, fileSystem, rootPath, _homeDir).catch(err => vscode.window.showErrorMessage(err.message));
}
}
}
@ -62,18 +59,18 @@ export const LANGUAGE_MODES: { [id: string]: string[] } = {
'haml': ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'xml': ['.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'xsl': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'css': [':', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'scss': [':', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'sass': [':', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'less': [':', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'stylus': [':', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'css': [':', '!', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'scss': [':', '!', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'sass': [':', '!', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'less': [':', '!', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'stylus': [':', '!', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'javascriptreact': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
'typescriptreact': ['!', '.', '}', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
};
export function isStyleSheet(syntax: string): boolean {
let stylesheetSyntaxes = ['css', 'scss', 'sass', 'less', 'stylus'];
return (stylesheetSyntaxes.indexOf(syntax) > -1);
return stylesheetSyntaxes.includes(syntax);
}
export function validate(allowStylesheet: boolean = true): boolean {
@ -374,6 +371,16 @@ export function getHtmlFlatNode(documentText: string, root: FlatNode | undefined
return currentNode;
}
export function isOffsetInsideOpenOrCloseTag(node: FlatNode, offset: number): boolean {
const htmlNode = node as HtmlFlatNode;
if ((htmlNode.open && offset > htmlNode.open.start && offset < htmlNode.open.end)
|| (htmlNode.close && offset > htmlNode.close.start && offset < htmlNode.close.end)) {
return true;
}
return false;
}
export function offsetRangeToSelection(document: vscode.TextDocument, start: number, end: number): vscode.Selection {
const startPos = document.positionAt(start);
const endPos = document.positionAt(end);

View File

@ -2,10 +2,10 @@
# yarn lockfile v1
"@emmetio/abbreviation@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@emmetio/abbreviation/-/abbreviation-2.2.0.tgz#9f8dedbdb00e3136d6d37c6415375c82c0bb477f"
integrity sha512-NPGVUmnr7cLj4i6MKS4c8NjuoIIJROrruJl/8nXsp2MdbDRHvtfq25foySvv/NbfqTQm+P9JzVLDD9JxGIpvkQ==
"@emmetio/abbreviation@^2.2.0", "@emmetio/abbreviation@^2.2.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@emmetio/abbreviation/-/abbreviation-2.2.1.tgz#d9458fe1f09fe042f019c48aa681165ba613a48d"
integrity sha512-uUNwNgbH0JPlrdXhy8VQbNPLLG7abMvOaLVMblx22i68Rl9r+2N235ALgIYFUty1yXC9DkVw6xMbz/D4QVARcQ==
dependencies:
"@emmetio/scanner" "^1.0.0"
@ -54,15 +54,16 @@
integrity sha1-Rs/+oRmgoAMxKiHC2bVijLX81EI=
"@types/node@^12.19.9":
version "12.19.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.12.tgz#04793c2afa4ce833a9972e4c476432e30f9df47b"
integrity sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw==
version "12.20.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.1.tgz#63d36c10e162666f0107f247cdca76542c3c7472"
integrity sha512-tCkE96/ZTO+cWbln2xfyvd6ngHLanvVlJ3e5BeirJ3BYI5GbAyubIrmV4JjjugDly5D9fHjOL5MNsqsCnqwW6g==
"emmet@https://github.com/rzhao271/emmet.git#1b2df677d8925ef5ea6da9df8845968403979a0a":
version "2.3.0"
resolved "https://github.com/rzhao271/emmet.git#1b2df677d8925ef5ea6da9df8845968403979a0a"
emmet@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/emmet/-/emmet-2.3.1.tgz#77614d949d1d01e5c248d08043a13a7f4d539e47"
integrity sha512-u8h++9u3y9QWhn0imUXfQO+s80To5MGD97zd/00wGC39CfNGBPe//ZKepJz9I1LQ2FDRXHrn+e3JaN/53Y5z6A==
dependencies:
"@emmetio/abbreviation" "^2.2.0"
"@emmetio/abbreviation" "^2.2.1"
"@emmetio/css-abbreviation" "^2.1.2"
image-size@^0.5.2:
@ -75,12 +76,12 @@ jsonc-parser@^2.3.0:
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342"
integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==
vscode-emmet-helper@2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-2.2.4.tgz#8ab86d2b7fe9e6270b4c77c9fd8d1eb8f3f4c401"
integrity sha512-1N6bMzP1ZzkDGzamvsKxQ/lOmBc4+OQdj0dA2C9A5PSeYV9gh5xbJ061sm+VyFHOGZE+VyUQq5m/WFmFsLbKnA==
vscode-emmet-helper@^2.3.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-2.3.2.tgz#7f73cd579eef187a4456dc71768fb2237f47fbd4"
integrity sha512-uulOziI/5Ml+AyfHwgkZDXlGZsu9yNcfwZgOfRSPokc6lqYEoGK+/u902LH8Xaf68dhPLctJlhhGYwDJuqoGxg==
dependencies:
emmet "https://github.com/rzhao271/emmet.git#1b2df677d8925ef5ea6da9df8845968403979a0a"
emmet "^2.3.0"
jsonc-parser "^2.3.0"
vscode-languageserver-textdocument "^1.0.1"
vscode-languageserver-types "^3.15.1"

View File

@ -1,64 +1,71 @@
{
"name": "extension-editing",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.4.0"
},
"activationEvents": [
"onLanguage:json",
"onLanguage:markdown",
"onLanguage:typescript"
],
"main": "./out/extensionEditingMain",
"browser": "./dist/browser/extensionEditingBrowserMain",
"scripts": {
"compile": "gulp compile-extension:extension-editing",
"watch": "gulp watch-extension:extension-editing"
},
"dependencies": {
"jsonc-parser": "^2.2.1",
"markdown-it": "^8.3.1",
"parse5": "^3.0.2",
"vscode-nls": "^4.1.1"
},
"contributes": {
"jsonValidation": [
{
"fileMatch": "package.json",
"url": "vscode://schemas/vscode-extensions"
},
{
"fileMatch": "*language-configuration.json",
"url": "vscode://schemas/language-configuration"
},
{
"fileMatch": ["*icon-theme.json", "!*product-icon-theme.json"],
"url": "vscode://schemas/icon-theme"
},
{
"fileMatch": "*product-icon-theme.json",
"url": "vscode://schemas/product-icon-theme"
},
{
"fileMatch": "*color-theme.json",
"url": "vscode://schemas/color-theme"
}
],
"languages": [
{
"id": "ignore",
"filenames": [
".vscodeignore"
]
}
]
},
"devDependencies": {
"@types/markdown-it": "0.0.2",
"@types/node": "^12.19.9"
}
"name": "extension-editing",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "^1.4.0"
},
"activationEvents": [
"onLanguage:json",
"onLanguage:markdown",
"onLanguage:typescript"
],
"main": "./out/extensionEditingMain",
"browser": "./dist/browser/extensionEditingBrowserMain",
"scripts": {
"compile": "gulp compile-extension:extension-editing",
"watch": "gulp watch-extension:extension-editing"
},
"dependencies": {
"jsonc-parser": "^2.2.1",
"markdown-it": "^8.3.1",
"parse5": "^3.0.2",
"vscode-nls": "^4.1.1"
},
"contributes": {
"jsonValidation": [
{
"fileMatch": "package.json",
"url": "vscode://schemas/vscode-extensions"
},
{
"fileMatch": "*language-configuration.json",
"url": "vscode://schemas/language-configuration"
},
{
"fileMatch": [
"*icon-theme.json",
"!*product-icon-theme.json"
],
"url": "vscode://schemas/icon-theme"
},
{
"fileMatch": "*product-icon-theme.json",
"url": "vscode://schemas/product-icon-theme"
},
{
"fileMatch": "*color-theme.json",
"url": "vscode://schemas/color-theme"
}
],
"languages": [
{
"id": "ignore",
"filenames": [
".vscodeignore"
]
}
]
},
"devDependencies": {
"@types/markdown-it": "0.0.2",
"@types/node": "^12.19.9"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Extension Authoring",
"description": "Provides linting capabilities for authoring extensions."
}
}

View File

@ -1,29 +1,50 @@
{
"name": "fsharp",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js ionide/ionide-fsgrammar grammars/fsharp.json ./syntaxes/fsharp.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "fsharp",
"extensions": [ ".fs", ".fsi", ".fsx", ".fsscript" ],
"aliases": [ "F#", "FSharp", "fsharp" ],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "fsharp",
"scopeName": "source.fsharp",
"path": "./syntaxes/fsharp.tmLanguage.json"
}],
"snippets": [{
"language": "fsharp",
"path": "./snippets/fsharp.code-snippets"
}]
}
"name": "fsharp",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin ionide/ionide-fsgrammar grammars/fsharp.json ./syntaxes/fsharp.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "fsharp",
"extensions": [
".fs",
".fsi",
".fsx",
".fsscript"
],
"aliases": [
"F#",
"FSharp",
"fsharp"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "fsharp",
"scopeName": "source.fsharp",
"path": "./syntaxes/fsharp.tmLanguage.json"
}
],
"snippets": [
{
"language": "fsharp",
"path": "./snippets/fsharp.code-snippets"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "F# Language Basics",
"description": "Provides snippets, syntax highlighting, bracket matching and folding in F# files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -27,5 +27,9 @@
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Git UI",
"description": "Git SCM UI Integration"
}
}

View File

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
var updateGrammar = require('../../../build/npm/update-grammar');
var updateGrammar = require('vscode-grammar-updater');
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Commit%20Message.tmLanguage', './syntaxes/git-commit.tmLanguage.json');
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Rebase%20Message.tmLanguage', './syntaxes/git-rebase.tmLanguage.json');

View File

@ -495,6 +495,16 @@
"title": "%command.timelineCopyCommitMessage%",
"category": "Git"
},
{
"command": "git.timeline.selectForCompare",
"title": "%command.timelineSelectForCompare%",
"category": "Git"
},
{
"command": "git.timeline.compareWithSelected",
"title": "%command.timelineCompareWithSelected%",
"category": "Git"
},
{
"command": "git.rebaseAbort",
"title": "%command.rebaseAbort%",
@ -874,6 +884,14 @@
{
"command": "git.timeline.copyCommitMessage",
"when": "false"
},
{
"command": "git.timeline.selectForCompare",
"when": "false"
},
{
"command": "git.timeline.compareWithSelected",
"when": "false"
}
],
"scm/title": [
@ -964,7 +982,7 @@
{
"command": "git.stageAllMerge",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.unstageAll",
@ -974,7 +992,7 @@
{
"command": "git.unstageAll",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.cleanAll",
@ -989,12 +1007,12 @@
{
"command": "git.cleanAll",
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges == mixed",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.stageAll",
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges == mixed",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.cleanAllTracked",
@ -1009,12 +1027,12 @@
{
"command": "git.cleanAllTracked",
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges != mixed",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.stageAllTracked",
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges != mixed",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.cleanAllUntracked",
@ -1029,12 +1047,12 @@
{
"command": "git.cleanAllUntracked",
"when": "scmProvider == git && scmResourceGroup == untracked",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.stageAllUntracked",
"when": "scmProvider == git && scmResourceGroup == untracked",
"group": "inline"
"group": "inline@2"
}
],
"scm/resourceFolder/context": [
@ -1046,7 +1064,7 @@
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.unstage",
@ -1056,7 +1074,7 @@
{
"command": "git.unstage",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.stage",
@ -1071,12 +1089,12 @@
{
"command": "git.clean",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.ignore",
@ -1091,7 +1109,7 @@
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == untracked",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.clean",
@ -1101,7 +1119,7 @@
{
"command": "git.clean",
"when": "scmProvider == git && scmResourceGroup == untracked",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.ignore",
@ -1123,7 +1141,7 @@
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.revealInExplorer",
@ -1133,12 +1151,12 @@
{
"command": "git.openFile2",
"when": "scmProvider == git && scmResourceGroup == merge && config.git.showInlineOpenFileAction && config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.openChange",
"when": "scmProvider == git && scmResourceGroup == merge && config.git.showInlineOpenFileAction && !config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.openChange",
@ -1163,7 +1181,7 @@
{
"command": "git.unstage",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.revealInExplorer",
@ -1173,12 +1191,12 @@
{
"command": "git.openFile2",
"when": "scmProvider == git && scmResourceGroup == index && config.git.showInlineOpenFileAction && config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.openChange",
"when": "scmProvider == git && scmResourceGroup == index && config.git.showInlineOpenFileAction && !config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.openChange",
@ -1208,22 +1226,22 @@
{
"command": "git.clean",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.openFile2",
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.showInlineOpenFileAction && config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.openChange",
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.showInlineOpenFileAction && !config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.ignore",
@ -1263,22 +1281,22 @@
{
"command": "git.clean",
"when": "scmProvider == git && scmResourceGroup == untracked && !gitFreshRepository",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == untracked",
"group": "inline"
"group": "inline@2"
},
{
"command": "git.openFile2",
"when": "scmProvider == git && scmResourceGroup == untracked && config.git.showInlineOpenFileAction && config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.openChange",
"when": "scmProvider == git && scmResourceGroup == untracked && config.git.showInlineOpenFileAction && !config.git.openDiffOnClick",
"group": "inline0"
"group": "inline@1"
},
{
"command": "git.ignore",
@ -1349,17 +1367,27 @@
{
"command": "git.timeline.openDiff",
"group": "1_actions",
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file\\b/"
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file\\b/ && !listMultiSelection"
},
{
"command": "git.timeline.compareWithSelected",
"group": "3_compare@1",
"when": "config.git.enabled && !git.missing && git.timeline.selectedForCompare && timelineItem =~ /git:file\\b/ && !listMultiSelection"
},
{
"command": "git.timeline.selectForCompare",
"group": "3_compare@2",
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file\\b/ && !listMultiSelection"
},
{
"command": "git.timeline.copyCommitId",
"group": "5_copy@1",
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file:commit\\b/"
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file:commit\\b/ && !listMultiSelection"
},
{
"command": "git.timeline.copyCommitMessage",
"group": "5_copy@2",
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file:commit\\b/"
"when": "config.git.enabled && !git.missing && timelineItem =~ /git:file:commit\\b/ && !listMultiSelection"
}
],
"git.commit": [
@ -2140,6 +2168,15 @@
"highContrast": "#c74e39"
}
},
{
"id": "gitDecoration.renamedResourceForeground",
"description": "%colors.renamed%",
"defaults": {
"light": "#007100",
"dark": "#73C991",
"highContrast": "#73C991"
}
},
{
"id": "gitDecoration.untrackedResourceForeground",
"description": "%colors.untracked%",
@ -2180,9 +2217,9 @@
"id": "gitDecoration.conflictingResourceForeground",
"description": "%colors.conflict%",
"defaults": {
"light": "#6c6cc4",
"dark": "#6c6cc4",
"highContrast": "#6c6cc4"
"light": "#ad0707",
"dark": "#e4676b",
"highContrast": "#c74e39"
}
},
{
@ -2342,5 +2379,9 @@
"@types/mocha": "^8.2.0",
"@types/node": "^12.19.9",
"@types/which": "^1.0.28"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -90,6 +90,8 @@
"command.timelineOpenDiff": "Open Changes",
"command.timelineCopyCommitId": "Copy Commit ID",
"command.timelineCopyCommitMessage": "Copy Commit Message",
"command.timelineSelectForCompare": "Select for Compare",
"command.timelineCompareWithSelected": "Compare with Selected",
"config.enabled": "Whether git is enabled.",
"config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows). This can also be an array of string values containing multiple paths to look up.",
"config.autoRepositoryDetection": "Configures when repositories should be automatically detected.",
@ -198,6 +200,7 @@
"colors.stageModified": "Color for modified resources which have been staged.",
"colors.stageDeleted": "Color for deleted resources which have been staged.",
"colors.deleted": "Color for deleted resources.",
"colors.renamed": "Color for renamed or copied resources.",
"colors.untracked": "Color for untracked resources.",
"colors.ignored": "Color for ignored resources.",
"colors.conflict": "Color for resources with conflicts.",

View File

@ -30,7 +30,7 @@ function main(argv: string[]): void {
const output = process.env['VSCODE_GIT_ASKPASS_PIPE'] as string;
const request = argv[2];
const host = argv[4].replace(/^["']+|["']+$/g, '');
const host = argv[4].replace(/^["']+|["':]+$/g, '');
const ipcClient = new IPCClient('askpass');
ipcClient.call({ request, host }).then(res => {

View File

@ -5,7 +5,7 @@
import * as os from 'os';
import * as path from 'path';
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider } from 'vscode';
import { Command, commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider } from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
import { Branch, ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourceProvider } from './api/git';
@ -153,21 +153,21 @@ class AddRemoteItem implements QuickPickItem {
}
}
interface CommandOptions {
interface ScmCommandOptions {
repository?: boolean;
diff?: boolean;
}
interface Command {
interface ScmCommand {
commandId: string;
key: string;
method: Function;
options: CommandOptions;
options: ScmCommandOptions;
}
const Commands: Command[] = [];
const Commands: ScmCommand[] = [];
function command(commandId: string, options: CommandOptions = {}): Function {
function command(commandId: string, options: ScmCommandOptions = {}): Function {
return (_target: any, key: string, descriptor: any) => {
if (!(typeof descriptor.value === 'function')) {
throw new Error('not supported');
@ -374,16 +374,20 @@ export class CommandCenter {
@command('git.openAllChanges', { repository: true })
async openChanges(repository: Repository): Promise<void> {
[
...repository.workingTreeGroup.resourceStates,
...repository.untrackedGroup.resourceStates,
].forEach(resource => {
commands.executeCommand(
for (const resource of [...repository.workingTreeGroup.resourceStates, ...repository.untrackedGroup.resourceStates]) {
if (
resource.type === Status.DELETED || resource.type === Status.DELETED_BY_THEM ||
resource.type === Status.DELETED_BY_US || resource.type === Status.BOTH_DELETED
) {
continue;
}
void commands.executeCommand(
'vscode.open',
resource.resourceUri,
{ preview: false, }
{ background: true, preview: false, }
);
});
}
}
async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean } = {}): Promise<void> {
@ -2608,6 +2612,22 @@ export class CommandCenter {
@command('git.timeline.openDiff', { repository: false })
async timelineOpenDiff(item: TimelineItem, uri: Uri | undefined, _source: string) {
const cmd = this.resolveTimelineOpenDiffCommand(
item, uri,
{
preserveFocus: true,
preview: true,
viewColumn: ViewColumn.Active
},
);
if (cmd === undefined) {
return undefined;
}
return commands.executeCommand(cmd.command, ...(cmd.arguments ?? []));
}
resolveTimelineOpenDiffCommand(item: TimelineItem, uri: Uri | undefined, options?: TextDocumentShowOptions): Command | undefined {
if (uri === undefined || uri === null || !GitTimelineItem.is(item)) {
return undefined;
}
@ -2624,13 +2644,11 @@ export class CommandCenter {
title = localize('git.title.diffRefs', '{0} ({1}) ⟷ {0} ({2})', basename, item.shortPreviousRef, item.shortRef);
}
const options: TextDocumentShowOptions = {
preserveFocus: true,
preview: true,
viewColumn: ViewColumn.Active
return {
command: 'vscode.diff',
title: 'Open Comparison',
arguments: [toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title, options]
};
return commands.executeCommand('vscode.diff', toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title, options);
}
@command('git.timeline.copyCommitId', { repository: false })
@ -2651,6 +2669,52 @@ export class CommandCenter {
env.clipboard.writeText(item.message);
}
private _selectedForCompare: { uri: Uri, item: GitTimelineItem } | undefined;
@command('git.timeline.selectForCompare', { repository: false })
async timelineSelectForCompare(item: TimelineItem, uri: Uri | undefined, _source: string) {
if (!GitTimelineItem.is(item) || !uri) {
return;
}
this._selectedForCompare = { uri, item };
await commands.executeCommand('setContext', 'git.timeline.selectedForCompare', true);
}
@command('git.timeline.compareWithSelected', { repository: false })
async timelineCompareWithSelected(item: TimelineItem, uri: Uri | undefined, _source: string) {
if (!GitTimelineItem.is(item) || !uri || !this._selectedForCompare || uri.toString() !== this._selectedForCompare.uri.toString()) {
return;
}
const { item: selected } = this._selectedForCompare;
const basename = path.basename(uri.fsPath);
let leftTitle;
if ((selected.previousRef === 'HEAD' || selected.previousRef === '~') && selected.ref === '') {
leftTitle = localize('git.title.workingTree', '{0} (Working Tree)', basename);
}
else if (selected.previousRef === 'HEAD' && selected.ref === '~') {
leftTitle = localize('git.title.index', '{0} (Index)', basename);
} else {
leftTitle = localize('git.title.ref', '{0} ({1})', basename, selected.shortRef);
}
let rightTitle;
if ((item.previousRef === 'HEAD' || item.previousRef === '~') && item.ref === '') {
rightTitle = localize('git.title.workingTree', '{0} (Working Tree)', basename);
}
else if (item.previousRef === 'HEAD' && item.ref === '~') {
rightTitle = localize('git.title.index', '{0} (Index)', basename);
} else {
rightTitle = localize('git.title.ref', '{0} ({1})', basename, item.shortRef);
}
const title = localize('git.title.diff', '{0} ⟷ {1}', leftTitle, rightTitle);
await commands.executeCommand('vscode.diff', selected.ref === '' ? uri : toGitUri(uri, selected.ref), item.ref === '' ? uri : toGitUri(uri, item.ref), title);
}
@command('git.rebaseAbort', { repository: true })
async rebaseAbort(repository: Repository): Promise<void> {
if (repository.rebaseCommit) {
@ -2660,7 +2724,7 @@ export class CommandCenter {
}
}
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
private createCommand(id: string, key: string, method: Function, options: ScmCommandOptions): (...args: any[]) => any {
const result = (...args: any[]) => {
let result: Promise<any>;

View File

@ -823,8 +823,7 @@ export class Repository {
return this.repositoryRoot;
}
// TODO@Joao: rename to exec
async run(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
async exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
return await this.git.exec(this.repositoryRoot, args, options);
}
@ -849,7 +848,7 @@ export class Repository {
args.push(value);
}
const result = await this.run(args, options);
const result = await this.exec(args, options);
return result.stdout.trim();
}
@ -862,7 +861,7 @@ export class Repository {
args.push('-l');
const result = await this.run(args);
const result = await this.exec(args);
const lines = result.stdout.trim().split(/\r|\r\n|\n/);
return lines.map(entry => {
@ -878,7 +877,7 @@ export class Repository {
args.push(options.path);
}
const result = await this.run(args);
const result = await this.exec(args);
if (result.exitCode) {
// An empty repo
return [];
@ -909,7 +908,7 @@ export class Repository {
args.push('--', uri.fsPath);
const result = await this.run(args);
const result = await this.exec(args);
if (result.exitCode) {
// No file history, e.g. a new file or untracked
return [];
@ -964,7 +963,7 @@ export class Repository {
}
const { mode, object } = elements[0];
const catFile = await this.run(['cat-file', '-s', object]);
const catFile = await this.exec(['cat-file', '-s', object]);
const size = parseInt(catFile.stdout);
return { mode, object, size };
@ -981,12 +980,12 @@ export class Repository {
}
async lstree(treeish: string, path: string): Promise<LsTreeElement[]> {
const { stdout } = await this.run(['ls-tree', '-l', treeish, '--', sanitizePath(path)]);
const { stdout } = await this.exec(['ls-tree', '-l', treeish, '--', sanitizePath(path)]);
return parseLsTree(stdout);
}
async lsfiles(path: string): Promise<LsFilesElement[]> {
const { stdout } = await this.run(['ls-files', '--stage', '--', sanitizePath(path)]);
const { stdout } = await this.exec(['ls-files', '--stage', '--', sanitizePath(path)]);
return parseLsFiles(stdout);
}
@ -1051,7 +1050,7 @@ export class Repository {
}
try {
await this.run(args);
await this.exec(args);
} catch (err) {
if (/patch does not apply/.test(err.stderr)) {
err.gitErrorCode = GitErrorCodes.PatchDoesNotApply;
@ -1068,7 +1067,7 @@ export class Repository {
args.push('--cached');
}
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1081,7 +1080,7 @@ export class Repository {
}
const args = ['diff', '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1094,7 +1093,7 @@ export class Repository {
}
const args = ['diff', ref, '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1107,7 +1106,7 @@ export class Repository {
}
const args = ['diff', '--cached', '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1120,13 +1119,13 @@ export class Repository {
}
const args = ['diff', '--cached', ref, '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
async diffBlobs(object1: string, object2: string): Promise<string> {
const args = ['diff', object1, object2];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout;
}
@ -1140,7 +1139,7 @@ export class Repository {
}
const args = ['diff', range, '--', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout.trim();
}
@ -1155,7 +1154,7 @@ export class Repository {
args.push(ref);
}
const gitResult = await this.run(args);
const gitResult = await this.exec(args);
if (gitResult.exitCode) {
return [];
}
@ -1228,14 +1227,14 @@ export class Repository {
async getMergeBase(ref1: string, ref2: string): Promise<string> {
const args = ['merge-base', ref1, ref2];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout.trim();
}
async hashObject(data: string): Promise<string> {
const args = ['hash-object', '-w', '--stdin'];
const result = await this.run(args, { input: data });
const result = await this.exec(args, { input: data });
return result.stdout.trim();
}
@ -1251,10 +1250,10 @@ export class Repository {
if (paths && paths.length) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
} else {
await this.run([...args, '--', '.']);
await this.exec([...args, '--', '.']);
}
}
@ -1267,7 +1266,7 @@ export class Repository {
args.push(...paths.map(sanitizePath));
await this.run(args);
await this.exec(args);
}
async stage(path: string, data: string): Promise<void> {
@ -1300,7 +1299,7 @@ export class Repository {
add = '--add';
}
await this.run(['update-index', add, '--cacheinfo', mode, hash, path]);
await this.exec(['update-index', add, '--cacheinfo', mode, hash, path]);
}
async checkout(treeish: string, paths: string[], opts: { track?: boolean, detached?: boolean } = Object.create(null)): Promise<void> {
@ -1321,10 +1320,10 @@ export class Repository {
try {
if (paths && paths.length > 0) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
} else {
await this.run(args);
await this.exec(args);
}
} catch (err) {
if (/Please,? commit your changes or stash them/.test(err.stderr || '')) {
@ -1375,21 +1374,21 @@ export class Repository {
}
try {
await this.run(args, !opts.amend || message ? { input: message || '' } : {});
await this.exec(args, !opts.amend || message ? { input: message || '' } : {});
} catch (commitErr) {
await this.handleCommitError(commitErr);
}
}
async rebaseAbort(): Promise<void> {
await this.run(['rebase', '--abort']);
await this.exec(['rebase', '--abort']);
}
async rebaseContinue(): Promise<void> {
const args = ['rebase', '--continue'];
try {
await this.run(args);
await this.exec(args);
} catch (commitErr) {
await this.handleCommitError(commitErr);
}
@ -1402,14 +1401,14 @@ export class Repository {
}
try {
await this.run(['config', '--get-all', 'user.name']);
await this.exec(['config', '--get-all', 'user.name']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserNameConfigured;
throw err;
}
try {
await this.run(['config', '--get-all', 'user.email']);
await this.exec(['config', '--get-all', 'user.email']);
} catch (err) {
err.gitErrorCode = GitErrorCodes.NoUserEmailConfigured;
throw err;
@ -1425,39 +1424,39 @@ export class Repository {
args.push(ref);
}
await this.run(args);
await this.exec(args);
}
async deleteBranch(name: string, force?: boolean): Promise<void> {
const args = ['branch', force ? '-D' : '-d', name];
await this.run(args);
await this.exec(args);
}
async renameBranch(name: string): Promise<void> {
const args = ['branch', '-m', name];
await this.run(args);
await this.exec(args);
}
async move(from: string, to: string): Promise<void> {
const args = ['mv', from, to];
await this.run(args);
await this.exec(args);
}
async setBranchUpstream(name: string, upstream: string): Promise<void> {
const args = ['branch', '--set-upstream-to', upstream, name];
await this.run(args);
await this.exec(args);
}
async deleteRef(ref: string): Promise<void> {
const args = ['update-ref', '-d', ref];
await this.run(args);
await this.exec(args);
}
async merge(ref: string): Promise<void> {
const args = ['merge', ref];
try {
await this.run(args);
await this.exec(args);
} catch (err) {
if (/^CONFLICT /m.test(err.stdout || '')) {
err.gitErrorCode = GitErrorCodes.Conflict;
@ -1476,12 +1475,12 @@ export class Repository {
args = [...args, name];
}
await this.run(args);
await this.exec(args);
}
async deleteTag(name: string): Promise<void> {
let args = ['tag', '-d', name];
await this.run(args);
await this.exec(args);
}
async clean(paths: string[]): Promise<void> {
@ -1494,7 +1493,7 @@ export class Repository {
for (const paths of groups) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
promises.push(limiter.queue(() => this.run([...args, '--', ...chunk])));
promises.push(limiter.queue(() => this.exec([...args, '--', ...chunk])));
}
}
@ -1502,10 +1501,10 @@ export class Repository {
}
async undo(): Promise<void> {
await this.run(['clean', '-fd']);
await this.exec(['clean', '-fd']);
try {
await this.run(['checkout', '--', '.']);
await this.exec(['checkout', '--', '.']);
} catch (err) {
if (/did not match any file\(s\) known to git\./.test(err.stderr || '')) {
return;
@ -1517,11 +1516,11 @@ export class Repository {
async reset(treeish: string, hard: boolean = false): Promise<void> {
const args = ['reset', hard ? '--hard' : '--soft', treeish];
await this.run(args);
await this.exec(args);
}
async revert(treeish: string, paths: string[]): Promise<void> {
const result = await this.run(['branch']);
const result = await this.exec(['branch']);
let args: string[];
// In case there are no branches, we must use rm --cached
@ -1534,10 +1533,10 @@ export class Repository {
try {
if (paths && paths.length > 0) {
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
} else {
await this.run([...args, '--', '.']);
await this.exec([...args, '--', '.']);
}
} catch (err) {
// In case there are merge conflicts to be resolved, git reset will output
@ -1552,17 +1551,17 @@ export class Repository {
async addRemote(name: string, url: string): Promise<void> {
const args = ['remote', 'add', name, url];
await this.run(args);
await this.exec(args);
}
async removeRemote(name: string): Promise<void> {
const args = ['remote', 'remove', name];
await this.run(args);
await this.exec(args);
}
async renameRemote(name: string, newName: string): Promise<void> {
const args = ['remote', 'rename', name, newName];
await this.run(args);
await this.exec(args);
}
async fetch(options: { remote?: string, ref?: string, all?: boolean, prune?: boolean, depth?: number, silent?: boolean, readonly cancellationToken?: CancellationToken } = {}): Promise<void> {
@ -1595,7 +1594,7 @@ export class Repository {
}
try {
await this.run(args, spawnOptions);
await this.exec(args, spawnOptions);
} catch (err) {
if (/No remote repository specified\./.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoRemoteRepositorySpecified;
@ -1628,7 +1627,7 @@ export class Repository {
}
try {
await this.run(args, {
await this.exec(args, {
cancellationToken: options.cancellationToken,
env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent }
});
@ -1658,7 +1657,7 @@ export class Repository {
args.push(branch);
try {
await this.run(args, options);
await this.exec(args, options);
} catch (err) {
if (/^CONFLICT \([^)]+\): \b/m.test(err.stdout || '')) {
err.gitErrorCode = GitErrorCodes.Conflict;
@ -1700,7 +1699,7 @@ export class Repository {
}
try {
await this.run(args, { env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent } });
await this.exec(args, { env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent } });
} catch (err) {
if (/^error: failed to push some refs to\b/m.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.PushRejected;
@ -1718,13 +1717,13 @@ export class Repository {
async cherryPick(commitHash: string): Promise<void> {
const args = ['cherry-pick', commitHash];
await this.run(args);
await this.exec(args);
}
async blame(path: string): Promise<string> {
try {
const args = ['blame', sanitizePath(path)];
const result = await this.run(args);
const result = await this.exec(args);
return result.stdout.trim();
} catch (err) {
if (/^fatal: no such path/.test(err.stderr || '')) {
@ -1747,7 +1746,7 @@ export class Repository {
args.push('-m', message);
}
await this.run(args);
await this.exec(args);
} catch (err) {
if (/No local changes to save/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoLocalChanges;
@ -1773,7 +1772,7 @@ export class Repository {
args.push(`stash@{${index}}`);
}
await this.run(args);
await this.exec(args);
} catch (err) {
if (/No stash found/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoStashFound;
@ -1795,7 +1794,7 @@ export class Repository {
}
try {
await this.run(args);
await this.exec(args);
} catch (err) {
if (/No stash found/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoStashFound;
@ -1860,7 +1859,7 @@ export class Repository {
async getHEAD(): Promise<Ref> {
try {
const result = await this.run(['symbolic-ref', '--short', 'HEAD']);
const result = await this.exec(['symbolic-ref', '--short', 'HEAD']);
if (!result.stdout) {
throw new Error('Not in a branch');
@ -1868,7 +1867,7 @@ export class Repository {
return { name: result.stdout.trim(), commit: undefined, type: RefType.Head };
} catch (err) {
const result = await this.run(['rev-parse', 'HEAD']);
const result = await this.exec(['rev-parse', 'HEAD']);
if (!result.stdout) {
throw new Error('Error parsing HEAD');
@ -1879,7 +1878,7 @@ export class Repository {
}
async findTrackingBranches(upstreamBranch: string): Promise<Branch[]> {
const result = await this.run(['for-each-ref', '--format', '%(refname:short)%00%(upstream:short)', 'refs/heads']);
const result = await this.exec(['for-each-ref', '--format', '%(refname:short)%00%(upstream:short)', 'refs/heads']);
return result.stdout.trim().split('\n')
.map(line => line.trim().split('\0'))
.filter(([_, upstream]) => upstream === upstreamBranch)
@ -1907,7 +1906,7 @@ export class Repository {
args.push('--contains', opts.contains);
}
const result = await this.run(args);
const result = await this.exec(args);
const fn = (line: string): Ref | null => {
let match: RegExpExecArray | null;
@ -1930,7 +1929,7 @@ export class Repository {
}
async getStashes(): Promise<Stash[]> {
const result = await this.run(['stash', 'list']);
const result = await this.exec(['stash', 'list']);
const regex = /^stash@{(\d+)}:(.+)$/;
const rawStashes = result.stdout.trim().split('\n')
.filter(b => !!b)
@ -1942,7 +1941,7 @@ export class Repository {
}
async getRemotes(): Promise<Remote[]> {
const result = await this.run(['remote', '--verbose']);
const result = await this.exec(['remote', '--verbose']);
const lines = result.stdout.trim().split('\n').filter(l => !!l);
const remotes: MutableRemote[] = [];
@ -1985,7 +1984,7 @@ export class Repository {
args.push(`refs/heads/${name}`, `refs/remotes/${name}`);
}
const result = await this.run(args);
const result = await this.exec(args);
const branches: Branch[] = result.stdout.trim().split('\n').map<Branch | undefined>(line => {
let [branchName, upstream, status, ref] = line.trim().split('\0');
@ -2067,7 +2066,7 @@ export class Repository {
async getCommitTemplate(): Promise<string> {
try {
const result = await this.run(['config', '--get', 'commit.template']);
const result = await this.exec(['config', '--get', 'commit.template']);
if (!result.stdout) {
return '';
@ -2090,7 +2089,7 @@ export class Repository {
}
async getCommit(ref: string): Promise<Commit> {
const result = await this.run(['show', '-s', `--format=${COMMIT_FORMAT}`, '-z', ref]);
const result = await this.exec(['show', '-s', `--format=${COMMIT_FORMAT}`, '-z', ref]);
const commits = parseGitCommits(result.stdout);
if (commits.length === 0) {
return Promise.reject<Commit>('bad commit format');
@ -2102,7 +2101,7 @@ export class Repository {
const args = ['submodule', 'update'];
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
await this.run([...args, '--', ...chunk]);
await this.exec([...args, '--', ...chunk]);
}
}

View File

@ -73,12 +73,13 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
git.onOutput.addListener('log', onOutput);
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
const cc = new CommandCenter(git, model, outputChannel, telemetryReporter);
disposables.push(
new CommandCenter(git, model, outputChannel, telemetryReporter),
cc,
new GitFileSystemProvider(model),
new GitDecorations(model),
new GitProtocolHandler(),
new GitTimelineProvider(model)
new GitTimelineProvider(model, cc)
);
checkGitVersion(info);

View File

@ -55,13 +55,13 @@ export class Resource implements SourceControlResourceState {
case Status.UNTRACKED: return localize('untracked', "Untracked");
case Status.IGNORED: return localize('ignored', "Ignored");
case Status.INTENT_TO_ADD: return localize('intent to add', "Intent to Add");
case Status.BOTH_DELETED: return localize('both deleted', "Both Deleted");
case Status.ADDED_BY_US: return localize('added by us', "Added By Us");
case Status.DELETED_BY_THEM: return localize('deleted by them', "Deleted By Them");
case Status.ADDED_BY_THEM: return localize('added by them', "Added By Them");
case Status.DELETED_BY_US: return localize('deleted by us', "Deleted By Us");
case Status.BOTH_ADDED: return localize('both added', "Both Added");
case Status.BOTH_MODIFIED: return localize('both modified', "Both Modified");
case Status.BOTH_DELETED: return localize('both deleted', "Conflict: Both Deleted");
case Status.ADDED_BY_US: return localize('added by us', "Conflict: Added By Us");
case Status.DELETED_BY_THEM: return localize('deleted by them', "Conflict: Deleted By Them");
case Status.ADDED_BY_THEM: return localize('added by them', "Conflict: Added By Them");
case Status.DELETED_BY_US: return localize('deleted by us', "Conflict: Deleted By Us");
case Status.BOTH_ADDED: return localize('both added', "Conflict: Both Added");
case Status.BOTH_MODIFIED: return localize('both modified', "Conflict: Both Modified");
default: return '';
}
}
@ -199,12 +199,13 @@ export class Resource implements SourceControlResourceState {
case Status.DELETED_BY_US:
return 'D';
case Status.INDEX_COPIED:
return 'C';
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.ADDED_BY_THEM:
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return 'C';
return '!'; // Using ! instead of ⚠, because the latter looks really bad on windows
default:
throw new Error('Unknown git status: ' + this.type);
}
@ -223,12 +224,13 @@ export class Resource implements SourceControlResourceState {
case Status.INDEX_ADDED:
case Status.INTENT_TO_ADD:
return new ThemeColor('gitDecoration.addedResourceForeground');
case Status.INDEX_COPIED:
case Status.INDEX_RENAMED:
return new ThemeColor('gitDecoration.renamedResourceForeground');
case Status.UNTRACKED:
return new ThemeColor('gitDecoration.untrackedResourceForeground');
case Status.IGNORED:
return new ThemeColor('gitDecoration.ignoredResourceForeground');
case Status.INDEX_COPIED:
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.DELETED_BY_THEM:
@ -246,10 +248,10 @@ export class Resource implements SourceControlResourceState {
switch (this.type) {
case Status.INDEX_MODIFIED:
case Status.MODIFIED:
case Status.INDEX_COPIED:
return 2;
case Status.IGNORED:
return 3;
case Status.INDEX_COPIED:
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.DELETED_BY_THEM:
@ -1482,7 +1484,7 @@ export class Repository implements Disposable {
const maybeRebased = await this.run(Operation.Log, async () => {
try {
const result = await this.repository.run(['log', '--oneline', '--cherry', `${currentBranch ?? ''}...${currentBranch ?? ''}@{upstream}`, '--']);
const result = await this.repository.exec(['log', '--oneline', '--cherry', `${currentBranch ?? ''}...${currentBranch ?? ''}@{upstream}`, '--']);
if (result.exitCode) {
return false;
}

View File

@ -9,6 +9,7 @@ import { Model } from './model';
import { Repository, Resource } from './repository';
import { debounce } from './decorators';
import { emojify, ensureEmojis } from './emoji';
import { CommandCenter } from './commands';
const localize = nls.loadMessageBundle();
@ -73,7 +74,7 @@ export class GitTimelineProvider implements TimelineProvider {
private repoDisposable: Disposable | undefined;
private repoStatusDate: Date | undefined;
constructor(private readonly model: Model) {
constructor(private readonly model: Model, private commands: CommandCenter) {
this.disposable = Disposable.from(
model.onDidOpenRepository(this.onRepositoriesChanged, this),
workspace.onDidChangeConfiguration(this.onConfigurationChanged, this)
@ -161,16 +162,20 @@ export class GitTimelineProvider implements TimelineProvider {
const message = emojify(c.message);
const item = new GitTimelineItem(c.hash, commits[i + 1]?.hash ?? `${c.hash}^`, message, date?.getTime() ?? 0, c.hash, 'git:file:commit');
item.iconPath = new (ThemeIcon as any)('git-commit');
item.iconPath = new ThemeIcon('git-commit');
if (showAuthor) {
item.description = c.authorName;
}
item.detail = `${c.authorName} (${c.authorEmail}) — ${c.hash.substr(0, 8)}\n${dateFormatter.format(date)}\n\n${message}`;
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
arguments: [item, uri, this.id]
};
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
item.command = {
title: 'Open Comparison',
command: cmd.command,
arguments: cmd.arguments,
};
}
return item;
});
@ -184,14 +189,18 @@ export class GitTimelineProvider implements TimelineProvider {
const item = new GitTimelineItem('~', 'HEAD', localize('git.timeline.stagedChanges', 'Staged Changes'), date.getTime(), 'index', 'git:file:index');
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.iconPath = new ThemeIcon('git-commit');
item.description = '';
item.detail = localize('git.timeline.detail', '{0} — {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format(date), Resource.getStatusText(index.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
arguments: [item, uri, this.id]
};
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
item.command = {
title: 'Open Comparison',
command: cmd.command,
arguments: cmd.arguments,
};
}
items.splice(0, 0, item);
}
@ -202,14 +211,18 @@ export class GitTimelineProvider implements TimelineProvider {
const item = new GitTimelineItem('', index ? '~' : 'HEAD', localize('git.timeline.uncommitedChanges', 'Uncommitted Changes'), date.getTime(), 'working', 'git:file:working');
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.iconPath = new ThemeIcon('git-commit');
item.description = '';
item.detail = localize('git.timeline.detail', '{0} — {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format(date), Resource.getStatusText(working.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
arguments: [item, uri, this.id]
};
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
item.command = {
title: 'Open Comparison',
command: cmd.command,
arguments: cmd.arguments,
};
}
items.splice(0, 0, item);
}

View File

@ -53,7 +53,7 @@
"vscode:prepublish": "npm run compile"
},
"dependencies": {
"node-fetch": "2.6.0",
"node-fetch": "2.6.1",
"uuid": "8.1.0",
"vscode-extension-telemetry": "0.1.1",
"vscode-nls": "^4.1.2"
@ -62,5 +62,9 @@
"@types/node": "^12.19.9",
"@types/node-fetch": "^2.5.7",
"@types/uuid": "8.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event, Disposable } from 'vscode';
import { EventEmitter, Event, Disposable } from 'vscode';
export function filterEvent<T>(event: Event<T>, filter: (e: T) => boolean): Event<T> {
return (listener, thisArgs = null, disposables?) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables);
@ -47,27 +47,54 @@ const passthrough = (value: any, resolve: (value?: any) => void) => resolve(valu
* @param adapter controls resolution of the returned promise
* @returns a promise that resolves or rejects as specified by the adapter
*/
export async function promiseFromEvent<T, U>(
export function promiseFromEvent<T, U>(
event: Event<T>,
adapter: PromiseAdapter<T, U> = passthrough): Promise<U> {
adapter: PromiseAdapter<T, U> = passthrough): { promise: Promise<U>, cancel: EventEmitter<void> } {
let subscription: Disposable;
return new Promise<U>((resolve, reject) =>
subscription = event((value: T) => {
try {
Promise.resolve(adapter(value, resolve, reject))
.catch(reject);
} catch (error) {
reject(error);
let cancel = new EventEmitter<void>();
return {
promise: new Promise<U>((resolve, reject) => {
cancel.event(_ => reject());
subscription = event((value: T) => {
try {
Promise.resolve(adapter(value, resolve, reject))
.catch(reject);
} catch (error) {
reject(error);
}
});
}).then(
(result: U) => {
subscription.dispose();
return result;
},
error => {
subscription.dispose();
throw error;
}
})
).then(
(result: U) => {
subscription.dispose();
return result;
},
error => {
subscription.dispose();
throw error;
}
);
),
cancel
};
}
export function arrayEquals<T>(one: ReadonlyArray<T> | undefined, other: ReadonlyArray<T> | undefined, itemEquals: (a: T, b: T) => boolean = (a, b) => a === b): boolean {
if (one === other) {
return true;
}
if (!one || !other) {
return false;
}
if (one.length !== other.length) {
return false;
}
for (let i = 0, len = one.length; i < len; i++) {
if (!itemEquals(one[i], other[i])) {
return false;
}
}
return true;
}

View File

@ -14,7 +14,7 @@ export async function activate(context: vscode.ExtensionContext) {
const telemetryReporter = new TelemetryReporter(name, version, aiKey);
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
const loginService = new GitHubAuthenticationProvider(context);
const loginService = new GitHubAuthenticationProvider(context, telemetryReporter);
await loginService.initialize(context);
@ -24,17 +24,17 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.authentication.registerAuthenticationProvider('github', 'GitHub', {
onDidChangeSessions: onDidChangeSessions.event,
getSessions: () => Promise.resolve(loginService.sessions),
login: async (scopeList: string[]) => {
getSessions: (scopes?: string[]) => loginService.getSessions(scopes),
createSession: async (scopeList: string[]) => {
try {
/* __GDPR__
"login" : { }
*/
telemetryReporter.sendTelemetryEvent('login');
const session = await loginService.login(scopeList.sort().join(' '));
const session = await loginService.createSession(scopeList.sort().join(' '));
Logger.info('Login success!');
onDidChangeSessions.fire({ added: [session.id], removed: [], changed: [] });
onDidChangeSessions.fire({ added: [session], removed: [], changed: [] });
return session;
} catch (e) {
// If login was cancelled, do not notify user.
@ -56,15 +56,17 @@ export async function activate(context: vscode.ExtensionContext) {
throw e;
}
},
logout: async (id: string) => {
removeSession: async (id: string) => {
try {
/* __GDPR__
"logout" : { }
*/
telemetryReporter.sendTelemetryEvent('logout');
await loginService.logout(id);
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
const session = await loginService.removeSession(id);
if (session) {
onDidChangeSessions.fire({ added: [], removed: [session], changed: [] });
}
} catch (e) {
/* __GDPR__
"logoutFailed" : { }

View File

@ -8,6 +8,8 @@ import { v4 as uuid } from 'uuid';
import { Keychain } from './common/keychain';
import { GitHubServer, NETWORK_ERROR } from './githubServer';
import Logger from './common/logger';
import { arrayEquals } from './common/utils';
import TelemetryReporter from 'vscode-extension-telemetry';
export const onDidChangeSessions = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
@ -24,12 +26,13 @@ interface SessionData {
export class GitHubAuthenticationProvider {
private _sessions: vscode.AuthenticationSession[] = [];
private _githubServer = new GitHubServer();
private _githubServer: GitHubServer;
private _keychain: Keychain;
constructor(context: vscode.ExtensionContext) {
constructor(context: vscode.ExtensionContext, telemetryReporter: TelemetryReporter) {
this._keychain = new Keychain(context);
this._githubServer = new GitHubServer(telemetryReporter);
}
public async initialize(context: vscode.ExtensionContext): Promise<void> {
@ -43,11 +46,18 @@ export class GitHubAuthenticationProvider {
context.subscriptions.push(context.secrets.onDidChange(() => this.checkForUpdates()));
}
async getSessions(scopes?: string[]): Promise<vscode.AuthenticationSession[]> {
return scopes
? this._sessions.filter(session => arrayEquals(session.scopes, scopes))
: this._sessions;
}
private async verifySessions(): Promise<void> {
const verifiedSessions: vscode.AuthenticationSession[] = [];
const verificationPromises = this._sessions.map(async session => {
try {
await this._githubServer.getUserInfo(session.accessToken);
this._githubServer.checkIsEdu(session.accessToken);
verifiedSessions.push(session);
} catch (e) {
// Remove sessions that return unauthorized response
@ -74,8 +84,8 @@ export class GitHubAuthenticationProvider {
return;
}
const added: string[] = [];
const removed: string[] = [];
const added: vscode.AuthenticationSession[] = [];
const removed: vscode.AuthenticationSession[] = [];
storedSessions.forEach(session => {
const matchesExisting = this._sessions.some(s => s.id === session.id);
@ -83,7 +93,7 @@ export class GitHubAuthenticationProvider {
if (!matchesExisting) {
Logger.info('Adding session found in keychain');
this._sessions.push(session);
added.push(session.id);
added.push(session);
}
});
@ -97,7 +107,7 @@ export class GitHubAuthenticationProvider {
this._sessions.splice(sessionIndex, 1);
}
removed.push(session.id);
removed.push(session);
}
});
@ -153,9 +163,10 @@ export class GitHubAuthenticationProvider {
return this._sessions;
}
public async login(scopes: string): Promise<vscode.AuthenticationSession> {
public async createSession(scopes: string): Promise<vscode.AuthenticationSession> {
const token = await this._githubServer.login(scopes);
const session = await this.tokenToSession(token, scopes.split(' '));
this._githubServer.checkIsEdu(token);
await this.setToken(session);
return session;
}
@ -185,15 +196,18 @@ export class GitHubAuthenticationProvider {
await this.storeSessions();
}
public async logout(id: string) {
public async removeSession(id: string): Promise<vscode.AuthenticationSession | undefined> {
Logger.info(`Logging out of ${id}`);
const sessionIndex = this._sessions.findIndex(session => session.id === id);
let session: vscode.AuthenticationSession | undefined;
if (sessionIndex > -1) {
session = this._sessions[sessionIndex];
this._sessions.splice(sessionIndex, 1);
} else {
Logger.error('Session not found');
}
await this.storeSessions();
return session;
}
}

View File

@ -9,6 +9,7 @@ import fetch, { Response } from 'node-fetch';
import { v4 as uuid } from 'uuid';
import { PromiseAdapter, promiseFromEvent } from './common/utils';
import Logger from './common/logger';
import TelemetryReporter from 'vscode-extension-telemetry';
const localize = nls.loadMessageBundle();
@ -39,7 +40,9 @@ export class GitHubServer {
private _statusBarItem: vscode.StatusBarItem | undefined;
private _pendingStates = new Map<string, string[]>();
private _codeExchangePromises = new Map<string, Promise<string>>();
private _codeExchangePromises = new Map<string, { promise: Promise<string>, cancel: vscode.EventEmitter<void> }>();
constructor(private readonly telemetryReporter: TelemetryReporter) { }
private isTestEnvironment(url: vscode.Uri): boolean {
return url.authority === 'vscode-web-test-playground.azurewebsites.net' || url.authority.startsWith('localhost:');
@ -83,17 +86,21 @@ export class GitHubServer {
// Register a single listener for the URI callback, in case the user starts the login process multiple times
// before completing it.
let existingPromise = this._codeExchangePromises.get(scopes);
if (!existingPromise) {
existingPromise = promiseFromEvent(uriHandler.event, this.exchangeCodeForToken(scopes));
this._codeExchangePromises.set(scopes, existingPromise);
let codeExchangePromise = this._codeExchangePromises.get(scopes);
if (!codeExchangePromise) {
codeExchangePromise = promiseFromEvent(uriHandler.event, this.exchangeCodeForToken(scopes));
this._codeExchangePromises.set(scopes, codeExchangePromise);
}
return Promise.race([
existingPromise,
promiseFromEvent<string | undefined, string>(onDidManuallyProvideToken.event, (token: string | undefined): string => { if (!token) { throw new Error('Cancelled'); } return token; })
codeExchangePromise.promise,
promiseFromEvent<string | undefined, string>(onDidManuallyProvideToken.event, (token: string | undefined): string => {
if (!token) { throw new Error('Cancelled'); }
return token;
}).promise
]).finally(() => {
this._pendingStates.delete(scopes);
codeExchangePromise?.cancel.fire();
this._codeExchangePromises.delete(scopes);
this.updateStatusBarItem(false);
});
@ -153,7 +160,7 @@ export class GitHubServer {
}
try {
const uri = vscode.Uri.parse(uriOrToken);
const uri = vscode.Uri.parse(uriOrToken.trim());
if (!uri.scheme || uri.scheme === 'file') { throw new Error; }
uriHandler.handleUri(uri);
} catch (e) {
@ -210,4 +217,36 @@ export class GitHubServer {
throw new Error(result.statusText);
}
}
public async checkIsEdu(token: string): Promise<void> {
try {
const result = await fetch('https://education.github.com/api/user', {
headers: {
Authorization: `token ${token}`,
'faculty-check-preview': 'true',
'User-Agent': 'Visual-Studio-Code'
}
});
if (result.ok) {
const json: { student: boolean, faculty: boolean } = await result.json();
/* __GDPR__
"session" : {
"isEdu": { "classification": "NonIdentifiableDemographicInfo", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('session', {
isEdu: json.student
? 'student'
: json.faculty
? 'faculty'
: 'none'
});
}
} catch (e) {
// No-op
}
}
}

View File

@ -84,10 +84,10 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.44.0"
node-fetch@2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-fetch@2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
semver@^5.3.0:
version "5.7.1"

View File

@ -64,5 +64,9 @@
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -125,9 +125,9 @@ is-plain-object@^3.0.0:
integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==
node-fetch@^2.3.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
once@^1.4.0:
version "1.4.0"

View File

@ -1,40 +1,44 @@
{
"name": "go",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js jeff-hykin/better-go-syntax export/generated.tmLanguage.json ./syntaxes/go.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "go",
"extensions": [
".go"
],
"aliases": [
"Go"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "go",
"scopeName": "source.go",
"path": "./syntaxes/go.tmLanguage.json"
}
],
"configurationDefaults": {
"[go]": {
"editor.insertSpaces": false
}
}
}
"name": "go",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin jeff-hykin/better-go-syntax export/generated.tmLanguage.json ./syntaxes/go.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "go",
"extensions": [
".go"
],
"aliases": [
"Go"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "go",
"scopeName": "source.go",
"path": "./syntaxes/go.tmLanguage.json"
}
],
"configurationDefaults": {
"[go]": {
"editor.insertSpaces": false
}
}
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Go Language Basics",
"description": "Provides syntax highlighting and bracket matching in Go files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -1,32 +1,57 @@
{
"name": "groovy",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js textmate/groovy.tmbundle Syntaxes/Groovy.tmLanguage ./syntaxes/groovy.tmLanguage.json"
"name": "groovy",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"contributes": {
"languages": [{
"id": "groovy",
"aliases": ["Groovy", "groovy"],
"extensions": [".groovy", ".gvy", ".gradle", ".jenkinsfile", ".nf"],
"filenames": [ "Jenkinsfile" ],
"filenamePatterns": ["Jenkinsfile.*"],
"firstLine": "^#!.*\\bgroovy\\b",
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "groovy",
"scopeName": "source.groovy",
"path": "./syntaxes/groovy.tmLanguage.json"
}],
"snippets": [{
"language": "groovy",
"path": "./snippets/groovy.code-snippets"
}]
}
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/groovy.tmbundle Syntaxes/Groovy.tmLanguage ./syntaxes/groovy.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "groovy",
"aliases": [
"Groovy",
"groovy"
],
"extensions": [
".groovy",
".gvy",
".gradle",
".jenkinsfile",
".nf"
],
"filenames": [
"Jenkinsfile"
],
"filenamePatterns": [
"Jenkinsfile.*"
],
"firstLine": "^#!.*\\bgroovy\\b",
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "groovy",
"scopeName": "source.groovy",
"path": "./syntaxes/groovy.tmLanguage.json"
}
],
"snippets": [
{
"language": "groovy",
"path": "./snippets/groovy.code-snippets"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Groovy Language Basics",
"description": "Provides snippets, syntax highlighting and bracket matching in Groovy files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -66,5 +66,9 @@
}
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -62,5 +62,9 @@
}
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -4,4 +4,4 @@
"config.gulp.autoDetect": "Controls whether auto detection of Gulp tasks is on or off. Default is on.",
"gulp.taskDefinition.type.description": "The Gulp task to customize.",
"gulp.taskDefinition.file.description": "The Gulp file that provides the task. Can be omitted."
}
}

View File

@ -1,7 +1,7 @@
{
"name": "handlebars",
"displayName": "%displayName%",
"description": "%description%",
"name": "handlebars",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
@ -9,20 +9,37 @@
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js daaain/Handlebars grammars/Handlebars.json ./syntaxes/Handlebars.tmLanguage.json"
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin daaain/Handlebars grammars/Handlebars.json ./syntaxes/Handlebars.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "handlebars",
"extensions": [ ".handlebars", ".hbs", ".hjs" ],
"aliases": [ "Handlebars", "handlebars" ],
"mimetypes": ["text/x-handlebars-template"],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "handlebars",
"scopeName": "text.html.handlebars",
"path": "./syntaxes/Handlebars.tmLanguage.json"
}]
"contributes": {
"languages": [
{
"id": "handlebars",
"extensions": [
".handlebars",
".hbs",
".hjs"
],
"aliases": [
"Handlebars",
"handlebars"
],
"mimetypes": [
"text/x-handlebars-template"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "handlebars",
"scopeName": "text.html.handlebars",
"path": "./syntaxes/Handlebars.tmLanguage.json"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Handlebars Language Basics",
"description": "Provides syntax highlighting and bracket matching in Handlebars files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -1,25 +1,47 @@
{
"name": "hlsl",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js tgjones/shaders-tmLanguage grammars/hlsl.json ./syntaxes/hlsl.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "hlsl",
"extensions": [".hlsl",".hlsli",".fx",".fxh",".vsh",".psh",".cginc",".compute"],
"aliases": ["HLSL", "hlsl"],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "hlsl",
"path": "./syntaxes/hlsl.tmLanguage.json",
"scopeName":"source.hlsl"
}]
}
}
"name": "hlsl",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin tgjones/shaders-tmLanguage grammars/hlsl.json ./syntaxes/hlsl.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "hlsl",
"extensions": [
".hlsl",
".hlsli",
".fx",
".fxh",
".vsh",
".psh",
".cginc",
".compute"
],
"aliases": [
"HLSL",
"hlsl"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "hlsl",
"path": "./syntaxes/hlsl.tmLanguage.json",
"scopeName": "source.hlsl"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "HLSL Language Basics",
"description": "Provides syntax highlighting and bracket matching in HLSL files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -240,5 +240,9 @@
},
"devDependencies": {
"@types/node": "^12.19.9"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -9,7 +9,7 @@
},
"main": "./out/node/htmlServerMain",
"dependencies": {
"vscode-css-languageservice": "^5.0.3",
"vscode-css-languageservice": "^5.1.0",
"vscode-html-languageservice": "^4.0.1",
"vscode-languageserver": "^7.0.0",
"vscode-nls": "^5.0.0",

View File

@ -5,7 +5,7 @@
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
import { Stylesheet, LanguageService as CSSLanguageService } from 'vscode-css-languageservice';
import { LanguageMode, Workspace, Color, TextDocument, Position, Range, CompletionList, DocumentContext, Settings } from './languageModes';
import { LanguageMode, Workspace, Color, TextDocument, Position, Range, CompletionList, DocumentContext } from './languageModes';
import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport';
export function getCSSMode(cssLanguageService: CSSLanguageService, documentRegions: LanguageModelCache<HTMLDocumentRegions>, workspace: Workspace): LanguageMode {
@ -23,11 +23,11 @@ export function getCSSMode(cssLanguageService: CSSLanguageService, documentRegio
async doComplete(document: TextDocument, position: Position, documentContext: DocumentContext, _settings = workspace.settings) {
let embedded = embeddedCSSDocuments.get(document);
const stylesheet = cssStylesheets.get(embedded);
return cssLanguageService.doComplete2(embedded, position, stylesheet, documentContext) || CompletionList.create();
return cssLanguageService.doComplete2(embedded, position, stylesheet, documentContext, _settings?.css?.completion) || CompletionList.create();
},
async doHover(document: TextDocument, position: Position, settings?: Settings) {
async doHover(document: TextDocument, position: Position, settings = workspace.settings) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doHover(embedded, position, cssStylesheets.get(embedded), settings?.html?.hover);
return cssLanguageService.doHover(embedded, position, cssStylesheets.get(embedded), settings?.css?.hover);
},
async findDocumentHighlight(document: TextDocument, position: Position) {
let embedded = embeddedCSSDocuments.get(document);

View File

@ -12,10 +12,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
vscode-css-languageservice@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-5.0.3.tgz#2d400a47e73d0bfc5bc0d3fdf5be487cfdca341b"
integrity sha512-KJt4jhCxqrgGrC02UsQsKw90dPkFknMHsH5HTInT7gkDRRfGFwEd+e2O1/E75br3TdFhvRmzjljYz5thZ58L3A==
vscode-css-languageservice@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-5.1.0.tgz#cd172d13e9e7ae23ba567c73778aee10475ff716"
integrity sha512-iLHd/WjRKgaZBXMNeUooHG+r0qlhJBkXa+3MpQQR6Rpm928cis/3OV2Mp1R80yAQevIMeDL32RIJfHoJCT/RRg==
dependencies:
vscode-languageserver-textdocument "^1.0.1"
vscode-languageserver-types "^3.16.0"

View File

@ -5,7 +5,7 @@
// @ts-check
'use strict';
var updateGrammar = require('../../../build/npm/update-grammar');
var updateGrammar = require('vscode-grammar-updater');
function patchGrammar(grammar) {
let patchCount = 0;

View File

@ -1,7 +1,7 @@
{
"name": "html",
"displayName": "%displayName%",
"description": "%description%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
@ -77,5 +77,9 @@
}
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "HTML Language Basics",
"description": "Provides syntax highlighting, bracket matching & snippets in HTML files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -77,5 +77,9 @@
"dependencies": {
"vscode-extension-telemetry": "0.1.1",
"vscode-nls": "^4.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -11,7 +11,7 @@ export abstract class PreviewStatusBarEntry extends Disposable {
protected readonly entry: vscode.StatusBarItem;
constructor(options: vscode.window.StatusBarItemOptions) {
constructor(options: vscode.StatusBarItemOptions) {
super();
this.entry = this._register(vscode.window.createStatusBarItem(options));
}

View File

@ -1,37 +1,70 @@
{
"name": "ini",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js textmate/ini.tmbundle Syntaxes/Ini.plist ./syntaxes/ini.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "ini",
"extensions": [ ".ini"],
"aliases": [ "Ini", "ini" ],
"configuration": "./ini.language-configuration.json"
},
{
"id": "properties",
"extensions": [ ".properties", ".cfg", ".conf", ".directory", ".gitattributes", ".gitconfig", ".gitmodules", ".editorconfig" ],
"filenames": [ "gitconfig" ],
"filenamePatterns": [ "**/.config/git/config", "**/.git/config" ],
"aliases": [ "Properties", "properties" ],
"configuration": "./properties.language-configuration.json"
}],
"grammars": [{
"language": "ini",
"scopeName": "source.ini",
"path": "./syntaxes/ini.tmLanguage.json"
},{
"language": "properties",
"scopeName": "source.ini",
"path": "./syntaxes/ini.tmLanguage.json"
}]
}
"name": "ini",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/ini.tmbundle Syntaxes/Ini.plist ./syntaxes/ini.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "ini",
"extensions": [
".ini"
],
"aliases": [
"Ini",
"ini"
],
"configuration": "./ini.language-configuration.json"
},
{
"id": "properties",
"extensions": [
".properties",
".cfg",
".conf",
".directory",
".gitattributes",
".gitconfig",
".gitmodules",
".editorconfig"
],
"filenames": [
"gitconfig"
],
"filenamePatterns": [
"**/.config/git/config",
"**/.git/config"
],
"aliases": [
"Properties",
"properties"
],
"configuration": "./properties.language-configuration.json"
}
],
"grammars": [
{
"language": "ini",
"scopeName": "source.ini",
"path": "./syntaxes/ini.tmLanguage.json"
},
{
"language": "properties",
"scopeName": "source.ini",
"path": "./syntaxes/ini.tmLanguage.json"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Ini Language Basics",
"description": "Provides syntax highlighting and bracket matching in Ini files."
}
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -62,5 +62,9 @@
}
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -4,4 +4,4 @@
"jake.taskDefinition.type.description": "The Jake task to customize.",
"jake.taskDefinition.file.description": "The Jake file that provides the task. Can be omitted.",
"config.jake.autoDetect": "Controls whether auto detection of Jake tasks is on or off. Default is on."
}
}

View File

@ -6,11 +6,11 @@
"git": {
"name": "atom/language-java",
"repositoryUrl": "https://github.com/atom/language-java",
"commitHash": "2bd3e55a72b08e171f811a2445343e2df9d89b71"
"commitHash": "29f977dc42a7e2568b39bb6fb34c4ef108eb59b3"
}
},
"license": "MIT",
"version": "0.32.0"
"version": "0.32.1"
}
],
"version": 1

View File

@ -1,29 +1,47 @@
{
"name": "java",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-java grammars/java.cson ./syntaxes/java.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "java",
"extensions": [ ".java", ".jav" ],
"aliases": [ "Java", "java" ],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "java",
"scopeName": "source.java",
"path": "./syntaxes/java.tmLanguage.json"
}],
"snippets": [{
"language": "java",
"path": "./snippets/java.code-snippets"
}]
}
"name": "java",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin atom/language-java grammars/java.cson ./syntaxes/java.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "java",
"extensions": [
".java",
".jav"
],
"aliases": [
"Java",
"java"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "java",
"scopeName": "source.java",
"path": "./syntaxes/java.tmLanguage.json"
}
],
"snippets": [
{
"language": "java",
"path": "./snippets/java.code-snippets"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@ -1,4 +1,4 @@
{
"displayName": "Java Language Basics",
"description": "Provides snippets, syntax highlighting, bracket matching and folding in Java files."
}
}

Some files were not shown because too many files have changed in this diff Show More