mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
[html] add symbol highlighting
This commit is contained in:
parent
06727ce174
commit
6c8a859079
|
@ -3,12 +3,13 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { parse} from './parser/htmlParser';
|
||||
import { doComplete } from './services/htmlCompletion';
|
||||
import { format } from './services/htmlFormatter';
|
||||
import { TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, MarkedString } from 'vscode-languageserver-types';
|
||||
import {parse} from './parser/htmlParser';
|
||||
import {doComplete} from './services/htmlCompletion';
|
||||
import {format} from './services/htmlFormatter';
|
||||
import {findDocumentHighlights} from './services/htmlHighlighting';
|
||||
import {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, DocumentHighlight, FormattingOptions, MarkedString } from 'vscode-languageserver-types';
|
||||
|
||||
export { TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, MarkedString };
|
||||
export {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, DocumentHighlight, FormattingOptions, MarkedString };
|
||||
|
||||
|
||||
export interface HTMLFormatConfiguration {
|
||||
|
@ -35,10 +36,8 @@ export interface LanguageService {
|
|||
configure(settings: LanguageSettings): void;
|
||||
parseHTMLDocument(document: TextDocument): HTMLDocument;
|
||||
doValidation(document: TextDocument, htmlDocument: HTMLDocument): Diagnostic[];
|
||||
|
||||
// doResolve(item: CompletionItem): CompletionItem;
|
||||
doComplete(document: TextDocument, position: Position, doc: HTMLDocument): CompletionList;
|
||||
// findDocumentSymbols(document: TextDocument, doc: HTMLDocument): SymbolInformation[];
|
||||
findDocumentHighlights(document: TextDocument, position: Position, htmlDocument: HTMLDocument): DocumentHighlight[];
|
||||
doComplete(document: TextDocument, position: Position, htmlDocument: HTMLDocument): CompletionList;
|
||||
// doHover(document: TextDocument, position: Position, doc: HTMLDocument): Hover;
|
||||
format(document: TextDocument, range: Range, options: HTMLFormatConfiguration): TextEdit[];
|
||||
}
|
||||
|
@ -46,10 +45,10 @@ export interface LanguageService {
|
|||
export function getLanguageService() : LanguageService {
|
||||
return {
|
||||
doValidation: (document, htmlDocument) => { return []; },
|
||||
|
||||
configure: (settings) => {},
|
||||
parseHTMLDocument: (document) => parse(document.getText()),
|
||||
doComplete,
|
||||
format
|
||||
format,
|
||||
findDocumentHighlights
|
||||
};
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {HTMLDocument} from '../parser/htmlParser';
|
||||
import {TokenType, createScanner} from '../parser/htmlScanner';
|
||||
import {TextDocument, Range, Position, DocumentHighlightKind, DocumentHighlight} from 'vscode-languageserver-types';
|
||||
|
||||
export function findDocumentHighlights(document: TextDocument, position: Position, htmlDocument: HTMLDocument): DocumentHighlight[] {
|
||||
let offset = document.offsetAt(position);
|
||||
let node = htmlDocument.findNodeAt(offset);
|
||||
if (!node.tag || typeof node.endTagStart !== 'number') {
|
||||
return [];
|
||||
}
|
||||
let startTagRange = getTagNameRange(TokenType.StartTag, document, node.start);
|
||||
let endTagRange = getTagNameRange(TokenType.EndTag, document, node.endTagStart);
|
||||
if (startTagRange && endTagRange && (covers(startTagRange, position) || covers(endTagRange, position))) {
|
||||
return [ { kind: DocumentHighlightKind.Read, range: startTagRange }, { kind: DocumentHighlightKind.Read, range: endTagRange }];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function isBeforeOrEqual(pos1: Position, pos2: Position) {
|
||||
return pos1.line < pos2.line || (pos1.line === pos2.line && pos1.character <= pos2.character);
|
||||
}
|
||||
|
||||
function covers(range: Range, position: Position) {
|
||||
return isBeforeOrEqual(range.start, position) && isBeforeOrEqual(position, range.end);
|
||||
}
|
||||
|
||||
function getTagNameRange(tokenType: TokenType, document: TextDocument, startOffset: number ) : Range {
|
||||
let scanner = createScanner(document.getText(), startOffset);
|
||||
let token = scanner.scan();
|
||||
while (token !== TokenType.EOS && token !== TokenType.StartTag) {
|
||||
token = scanner.scan();
|
||||
}
|
||||
if (token !== TokenType.EOS) {
|
||||
return { start: document.positionAt(scanner.getTokenOffset()), end: document.positionAt(scanner.getTokenEnd()) };
|
||||
}
|
||||
return null;
|
||||
}
|
|
@ -60,8 +60,8 @@ let testCompletionFor = function (value: string, expected: { count?: number, ite
|
|||
|
||||
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
|
||||
let position = document.positionAt(offset);
|
||||
let jsonDoc = ls.parseHTMLDocument(document);
|
||||
return asPromise(ls.doComplete(document, position, jsonDoc)).then(list => {
|
||||
let htmlDoc = ls.parseHTMLDocument(document);
|
||||
return asPromise(ls.doComplete(document, position, htmlDoc)).then(list => {
|
||||
try {
|
||||
if (expected.count) {
|
||||
assert.equal(list.items, expected.count);
|
||||
|
|
43
extensions/html/server/src/service/test/highlighting.test.ts
Normal file
43
extensions/html/server/src/service/test/highlighting.test.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as htmlLanguageService from '../htmlLanguageService';
|
||||
import {CompletionList, TextDocument, TextEdit, Position, CompletionItemKind} from 'vscode-languageserver-types';
|
||||
|
||||
export function assertHighlights(value: string, expectedMatches: number[], elementName: string): Thenable<void> {
|
||||
let offset = value.indexOf('|');
|
||||
value = value.substr(0, offset) + value.substr(offset + 1);
|
||||
|
||||
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
|
||||
let htmlDocument = htmlLanguageService.getLanguageService().parseHTMLDocument(document);
|
||||
|
||||
let position = document.positionAt(offset);
|
||||
let ls = htmlLanguageService.getLanguageService();
|
||||
let htmlDoc = ls.parseHTMLDocument(document);
|
||||
|
||||
let highlights = ls.findDocumentHighlights(document, position, htmlDoc);
|
||||
assert.equal(highlights.length, expectedMatches.length);
|
||||
for (let i = 0; i < highlights.length; i++) {
|
||||
let actualStartOffset = document.offsetAt(highlights[i].range.start);
|
||||
assert.equal(actualStartOffset, expectedMatches[i]);
|
||||
let actualEndOffset = document.offsetAt(highlights[i].range.end);
|
||||
assert.equal(actualEndOffset, expectedMatches[i] + elementName.length);
|
||||
|
||||
assert.equal(document.getText().substring(actualStartOffset, actualEndOffset), elementName);
|
||||
}
|
||||
}
|
||||
|
||||
suite('HTML Highlighting', () => {
|
||||
|
||||
|
||||
|
||||
test('Highlighting', function (testDone): any {
|
||||
testHighlighting
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in a new issue