Skip to content

Commit 2b247cc

Browse files
committed
[css] move to extension
1 parent 966cb81 commit 2b247cc

48 files changed

Lines changed: 30608 additions & 6 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build/gulpfile.hygiene.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ var copyrightFilter = [
7171
'!**/*.bat',
7272
'!**/*.cmd',
7373
'!resources/win32/bin/code.js',
74+
'!**/*.xml',
7475
'!**/*.sh',
7576
'!**/*.txt',
7677
'!**/*.xpm',

build/npm/postinstall.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const extensions = [
1313
'configuration-editing',
1414
'typescript',
1515
'php',
16-
'javascript'
16+
'javascript',
17+
'css'
1718
];
1819

1920
extensions.forEach(extension => {

extensions/css/.vscode/launch.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Launch Extension",
6+
"type": "extensionHost",
7+
"request": "launch",
8+
"runtimeExecutable": "${execPath}",
9+
"args": [
10+
"--extensionDevelopmentPath=${workspaceRoot}"
11+
],
12+
"stopOnEntry": false,
13+
"sourceMaps": true,
14+
"outDir": "${workspaceRoot}/client/out",
15+
"preLaunchTask": "npm"
16+
},
17+
{
18+
"name": "Launch Tests",
19+
"type": "extensionHost",
20+
"request": "launch",
21+
"runtimeExecutable": "${execPath}",
22+
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/client/out/test" ],
23+
"stopOnEntry": false,
24+
"sourceMaps": true,
25+
"outDir": "${workspaceRoot}/client/out/test",
26+
"preLaunchTask": "npm"
27+
}
28+
]
29+
}

extensions/css/.vscode/tasks.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Available variables which can be used inside of strings.
2+
// ${workspaceRoot}: the root folder of the team
3+
// ${file}: the current opened file
4+
// ${fileBasename}: the current opened file's basename
5+
// ${fileDirname}: the current opened file's dirname
6+
// ${fileExtname}: the current opened file's extension
7+
// ${cwd}: the current working directory of the spawned process
8+
9+
// A task runner that calls a custom npm script that compiles the extension.
10+
{
11+
"version": "0.1.0",
12+
13+
// we want to run npm
14+
"command": "npm",
15+
16+
// the command is a shell script
17+
"isShellCommand": true,
18+
19+
// show the output window only if unrecognized errors occur.
20+
"showOutput": "silent",
21+
22+
// we run the custom script "compile" as defined in package.json
23+
"args": ["run", "compile"],
24+
25+
// The tsc compiler is started in watching mode
26+
"isWatching": true,
27+
28+
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
29+
"problemMatcher": "$tsc-watch"
30+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import {window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range} from 'vscode';
8+
9+
let decorationType: DecorationRenderOptions = {
10+
before: {
11+
contentText: ' ',
12+
border: 'solid 0.1em #000',
13+
margin: '0.1em 0.2em 0 0.2em',
14+
width: '0.8em',
15+
height: '0.8em'
16+
},
17+
dark: {
18+
before: {
19+
border: 'solid 0.1em #eee'
20+
}
21+
}
22+
};
23+
24+
export function activateColorDecorations(decoratorProvider: (uri: string) => Thenable<Range[]>, supportedLanguages: { [id: string]: boolean }): Disposable {
25+
26+
let disposables: Disposable[] = [];
27+
28+
let colorsDecorationType = window.createTextEditorDecorationType(decorationType);
29+
disposables.push(colorsDecorationType);
30+
31+
let activeEditor = window.activeTextEditor;
32+
if (activeEditor) {
33+
triggerUpdateDecorations();
34+
}
35+
36+
window.onDidChangeActiveTextEditor(editor => {
37+
activeEditor = editor;
38+
if (editor && supportedLanguages[activeEditor.document.languageId]) {
39+
triggerUpdateDecorations();
40+
}
41+
}, null, disposables);
42+
43+
workspace.onDidChangeTextDocument(event => {
44+
if (activeEditor && event.document === activeEditor.document && supportedLanguages[activeEditor.document.languageId]) {
45+
triggerUpdateDecorations();
46+
}
47+
}, null, disposables);
48+
49+
let timeout = null;
50+
function triggerUpdateDecorations() {
51+
if (timeout) {
52+
clearTimeout(timeout);
53+
}
54+
timeout = setTimeout(updateDecorations, 500);
55+
}
56+
57+
function updateDecorations() {
58+
if (!activeEditor) {
59+
return;
60+
}
61+
let document = activeEditor.document;
62+
if (!supportedLanguages[document.languageId]) {
63+
return;
64+
}
65+
let uri = activeEditor.document.uri.toString();
66+
decoratorProvider(uri).then(ranges => {
67+
68+
let decorations = ranges.map(range => {
69+
let color = document.getText(range);
70+
return <DecorationOptions>{
71+
range: range,
72+
renderOptions: {
73+
before: {
74+
backgroundColor: color
75+
}
76+
}
77+
};
78+
});
79+
activeEditor.setDecorations(colorsDecorationType, decorations);
80+
});
81+
}
82+
return Disposable.from(...disposables);
83+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import * as path from 'path';
8+
9+
import {languages, window, commands, ExtensionContext} from 'vscode';
10+
import {LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, Range, TextEdit, Protocol2Code} from 'vscode-languageclient';
11+
import {activateColorDecorations} from './colorDecorators';
12+
13+
namespace ColorSymbolRequest {
14+
export const type: RequestType<string, Range[], any> = { get method() { return 'css/colorSymbols'; } };
15+
}
16+
17+
// this method is called when vs code is activated
18+
export function activate(context: ExtensionContext) {
19+
20+
// The server is implemented in node
21+
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'cssServerMain.js'));
22+
// The debug options for the server
23+
let debugOptions = { execArgv: ['--nolazy', '--debug=6004'] };
24+
25+
// If the extension is launch in debug mode the debug server options are use
26+
// Otherwise the run options are used
27+
let serverOptions: ServerOptions = {
28+
run: { module: serverModule, transport: TransportKind.ipc },
29+
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions }
30+
};
31+
32+
// Options to control the language client
33+
let clientOptions: LanguageClientOptions = {
34+
documentSelector: ['css', 'less', 'scss'],
35+
synchronize: {
36+
configurationSection: ['css', 'scss', 'less']
37+
},
38+
initializationOptions: {
39+
}
40+
};
41+
42+
// Create the language client and start the client.
43+
let client = new LanguageClient('css', serverOptions, clientOptions);
44+
45+
let disposable = client.start();
46+
// Push the disposable to the context's subscriptions so that the
47+
// client can be deactivated on extension deactivation
48+
context.subscriptions.push(disposable);
49+
50+
let colorRequestor = (uri: string) => {
51+
return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(Protocol2Code.asRange));
52+
};
53+
disposable = activateColorDecorations(colorRequestor, { css: true, scss: true, less: true });
54+
context.subscriptions.push(disposable);
55+
56+
languages.setLanguageConfiguration('css', {
57+
wordPattern: /(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g,
58+
comments: {
59+
blockComment: ['/*', '*/']
60+
},
61+
brackets: [['{', '}'], ['[', ']'], ['(', ')']],
62+
autoClosingPairs: [
63+
{ open: '{', close: '}' },
64+
{ open: '[', close: ']' },
65+
{ open: '(', close: ')' },
66+
{ open: '"', close: '"', notIn: ['string'] },
67+
{ open: '\'', close: '\'', notIn: ['string'] }
68+
]
69+
});
70+
71+
languages.setLanguageConfiguration('less', {
72+
wordPattern: /(#?-?\d*\.\d\w*%?)|([@#!.:]?[\w-?]+%?)|[@#!.]/g,
73+
comments: {
74+
blockComment: ['/*', '*/'],
75+
lineComment: '//'
76+
},
77+
brackets: [['{', '}'], ['[', ']'], ['(', ')'], ['<', '>']],
78+
autoClosingPairs: [
79+
{ open: '"', close: '"', notIn: ['string', 'comment'] },
80+
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
81+
{ open: '{', close: '}', notIn: ['string', 'comment'] },
82+
{ open: '[', close: ']', notIn: ['string', 'comment'] },
83+
{ open: '(', close: ')', notIn: ['string', 'comment'] },
84+
{ open: '<', close: '>', notIn: ['string', 'comment'] },
85+
]
86+
});
87+
88+
languages.setLanguageConfiguration('scss', {
89+
wordPattern: /(#?-?\d*\.\d\w*%?)|([@#!.:]?[\w-?]+%?)|[@#!.]/g,
90+
comments: {
91+
blockComment: ['/*', '*/'],
92+
lineComment: '//'
93+
},
94+
brackets: [['{', '}'], ['[', ']'], ['(', ')'], ['<', '>']],
95+
autoClosingPairs: [
96+
{ open: '"', close: '"', notIn: ['string', 'comment'] },
97+
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
98+
{ open: '{', close: '}', notIn: ['string', 'comment'] },
99+
{ open: '[', close: ']', notIn: ['string', 'comment'] },
100+
{ open: '(', close: ')', notIn: ['string', 'comment'] },
101+
{ open: '<', close: '>', notIn: ['string', 'comment'] },
102+
]
103+
});
104+
105+
commands.registerCommand('_css.applyCodeAction', applyCodeAction);
106+
}
107+
108+
function applyCodeAction(uri: string, documentVersion: number, edits: TextEdit[]) {
109+
let textEditor = window.activeTextEditor;
110+
if (textEditor && textEditor.document.uri.toString() === uri) {
111+
if (textEditor.document.version !== documentVersion) {
112+
window.showInformationMessage(`CSS fix is outdated and can't be applied to the document.`);
113+
}
114+
textEditor.edit(mutator => {
115+
for (let edit of edits) {
116+
mutator.replace(Protocol2Code.asRange(edit.range), edit.newText);
117+
}
118+
}).then(success => {
119+
if (!success) {
120+
window.showErrorMessage('Failed to apply CSS fix to the document. Please consider opening an issue with steps to reproduce.');
121+
}
122+
});
123+
}
124+
}
125+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
/// <reference path='../../../../../src/vs/vscode.d.ts'/>
7+
/// <reference path='../../../../../src/typings/mocha.d.ts'/>
8+
/// <reference path='../../../../../extensions/node.d.ts'/>
9+
/// <reference path='../../../../../extensions/lib.core.d.ts'/>
10+
/// <reference path='../../../../../extensions/declares.d.ts'/>
11+
/// <reference path='../../../node_modules/vscode-languageclient/lib/main.d.ts'/>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"noLib": true,
4+
"target": "es5",
5+
"module": "commonjs",
6+
"outDir": "./out"
7+
},
8+
"exclude": [
9+
"node_modules"
10+
]
11+
}

0 commit comments

Comments
 (0)