mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 02:28:34 +01:00
[html] move path completion inside html mode
This commit is contained in:
@@ -5,14 +5,14 @@
|
||||
'use strict';
|
||||
|
||||
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
|
||||
import { TextDocument, Position, Range } from 'vscode-languageserver-types';
|
||||
import { TextDocument, Position, Range, CompletionList } from 'vscode-languageserver-types';
|
||||
import { getCSSLanguageService, Stylesheet, ICompletionParticipant } from 'vscode-css-languageservice';
|
||||
import { LanguageMode, Settings } from './languageModes';
|
||||
import { LanguageMode, Workspace } from './languageModes';
|
||||
import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport';
|
||||
import { Color } from 'vscode-languageserver';
|
||||
import { extractAbbreviation } from 'vscode-emmet-helper';
|
||||
|
||||
export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>): LanguageMode {
|
||||
export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>, workspace: Workspace): LanguageMode {
|
||||
let cssLanguageService = getCSSLanguageService();
|
||||
let embeddedCSSDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('css'));
|
||||
let cssStylesheets = getLanguageModelCache<Stylesheet>(10, 60, document => cssLanguageService.parseStylesheet(document));
|
||||
@@ -21,19 +21,16 @@ export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegio
|
||||
getId() {
|
||||
return 'css';
|
||||
},
|
||||
configure(options: any) {
|
||||
cssLanguageService.configure(options && options.css);
|
||||
},
|
||||
doValidation(document: TextDocument, settings?: Settings) {
|
||||
doValidation(document: TextDocument, settings = workspace.settings) {
|
||||
let embedded = embeddedCSSDocuments.get(document);
|
||||
return cssLanguageService.doValidation(embedded, cssStylesheets.get(embedded), settings && settings.css);
|
||||
},
|
||||
doComplete(document: TextDocument, position: Position, settings?: Settings, registeredCompletionParticipants?: ICompletionParticipant[]) {
|
||||
doComplete(document: TextDocument, position: Position, settings = workspace.settings, registeredCompletionParticipants?: ICompletionParticipant[]) {
|
||||
let embedded = embeddedCSSDocuments.get(document);
|
||||
const stylesheet = cssStylesheets.get(embedded);
|
||||
|
||||
const nonEmmetCompletionParticipants = [];
|
||||
if (registeredCompletionParticipants) {
|
||||
const nonEmmetCompletionParticipants = [];
|
||||
// Css Emmet completions in html files are provided no matter where the cursor is inside the embedded css document
|
||||
// Mimic the same here, until we solve the issue of css language service not able to parse complete embedded documents when there are errors
|
||||
for (let i = 0; i < registeredCompletionParticipants.length; i++) {
|
||||
@@ -46,12 +43,9 @@ export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegio
|
||||
nonEmmetCompletionParticipants.push(registeredCompletionParticipants[i]);
|
||||
}
|
||||
}
|
||||
cssLanguageService.setCompletionParticipants(nonEmmetCompletionParticipants);
|
||||
}
|
||||
return cssLanguageService.doComplete(embedded, position, stylesheet);
|
||||
},
|
||||
setCompletionParticipants(registeredCompletionParticipants: ICompletionParticipant[]) {
|
||||
cssLanguageService.setCompletionParticipants(registeredCompletionParticipants);
|
||||
cssLanguageService.setCompletionParticipants(nonEmmetCompletionParticipants);
|
||||
return cssLanguageService.doComplete(embedded, position, stylesheet) || CompletionList.create();
|
||||
},
|
||||
doHover(document: TextDocument, position: Position) {
|
||||
let embedded = embeddedCSSDocuments.get(document);
|
||||
|
||||
@@ -6,40 +6,36 @@
|
||||
|
||||
import { getLanguageModelCache } from '../languageModelCache';
|
||||
import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions, HTMLFormatConfiguration, ICompletionParticipant } from 'vscode-html-languageservice';
|
||||
import { TextDocument, Position, Range } from 'vscode-languageserver-types';
|
||||
import { LanguageMode, Settings } from './languageModes';
|
||||
import { TextDocument, Position, Range, CompletionItem } from 'vscode-languageserver-types';
|
||||
import { LanguageMode, Settings, Workspace } from './languageModes';
|
||||
|
||||
import { FoldingRange } from '../protocol/foldingProvider.proposed';
|
||||
import { getHTMLFoldingRegions } from './htmlFolding';
|
||||
import { getPathCompletionParticipant } from './pathCompletion';
|
||||
|
||||
export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageMode {
|
||||
let globalSettings: Settings = {};
|
||||
export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: Workspace): LanguageMode {
|
||||
let htmlDocuments = getLanguageModelCache<HTMLDocument>(10, 60, document => htmlLanguageService.parseHTMLDocument(document));
|
||||
let completionParticipants: ICompletionParticipant[] = [];
|
||||
return {
|
||||
getId() {
|
||||
return 'html';
|
||||
},
|
||||
configure(options: any) {
|
||||
globalSettings = options;
|
||||
},
|
||||
doComplete(document: TextDocument, position: Position, settings: Settings = globalSettings, registeredCompletionParticipants?: ICompletionParticipant[]) {
|
||||
if (registeredCompletionParticipants) {
|
||||
completionParticipants = registeredCompletionParticipants;
|
||||
}
|
||||
doComplete(document: TextDocument, position: Position, settings = workspace.settings, completionParticipants?: ICompletionParticipant[]) {
|
||||
let options = settings && settings.html && settings.html.suggest;
|
||||
let doAutoComplete = settings && settings.html && settings.html.autoClosingTags;
|
||||
if (doAutoComplete) {
|
||||
options.hideAutoCompleteProposals = true;
|
||||
}
|
||||
let pathCompletionProposals: CompletionItem[] = [];
|
||||
let participants = [getPathCompletionParticipant(document, workspace.folders, pathCompletionProposals)];
|
||||
if (completionParticipants) {
|
||||
participants.push(...completionParticipants);
|
||||
}
|
||||
htmlLanguageService.setCompletionParticipants(participants);
|
||||
|
||||
const htmlDocument = htmlDocuments.get(document);
|
||||
htmlLanguageService.setCompletionParticipants(completionParticipants);
|
||||
|
||||
return htmlLanguageService.doComplete(document, position, htmlDocument, options);
|
||||
},
|
||||
setCompletionParticipants(registeredCompletionParticipants: any[]) {
|
||||
completionParticipants = registeredCompletionParticipants;
|
||||
let completionList = htmlLanguageService.doComplete(document, position, htmlDocument, options);
|
||||
completionList.items.push(...pathCompletionProposals);
|
||||
return completionList;
|
||||
},
|
||||
doHover(document: TextDocument, position: Position) {
|
||||
return htmlLanguageService.doHover(document, position, htmlDocuments.get(document));
|
||||
@@ -53,7 +49,7 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageM
|
||||
findDocumentSymbols(document: TextDocument) {
|
||||
return htmlLanguageService.findDocumentSymbols(document, htmlDocuments.get(document));
|
||||
},
|
||||
format(document: TextDocument, range: Range, formatParams: FormattingOptions, settings: Settings = globalSettings) {
|
||||
format(document: TextDocument, range: Range, formatParams: FormattingOptions, settings = workspace.settings) {
|
||||
let formatSettings: HTMLFormatConfiguration = settings && settings.html && settings.html.format;
|
||||
if (formatSettings) {
|
||||
formatSettings = merge(formatSettings, {});
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
|
||||
import { SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation, Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover, MarkedString, DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions } from 'vscode-languageserver-types';
|
||||
import { LanguageMode, Settings } from './languageModes';
|
||||
import { LanguageMode, Settings, Workspace } from './languageModes';
|
||||
import { getWordAtText, startsWith, isWhitespaceOnly, repeat } from '../utils/strings';
|
||||
import { HTMLDocumentRegions } from './embeddedSupport';
|
||||
|
||||
@@ -19,7 +19,7 @@ const JQUERY_D_TS = join(__dirname, '../../lib/jquery.d.ts');
|
||||
|
||||
const JS_WORD_REGEX = /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g;
|
||||
|
||||
export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>): LanguageMode {
|
||||
export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>, workspace: Workspace): LanguageMode {
|
||||
let jsDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('javascript'));
|
||||
|
||||
let compilerOptions: ts.CompilerOptions = { allowNonTsExtensions: true, allowJs: true, lib: ['lib.es6.d.ts'], target: ts.ScriptTarget.Latest, moduleResolution: ts.ModuleResolutionKind.Classic };
|
||||
@@ -67,9 +67,6 @@ export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocume
|
||||
getId() {
|
||||
return 'javascript';
|
||||
},
|
||||
configure(options: any) {
|
||||
globalSettings = options;
|
||||
},
|
||||
doValidation(document: TextDocument): Diagnostic[] {
|
||||
updateCurrentTextDocument(document);
|
||||
const syntaxDiagnostics = jsLanguageService.getSyntacticDiagnostics(FILE_NAME);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
CompletionItem, Location, SignatureHelp, Definition, TextEdit, TextDocument, Diagnostic, DocumentLink, Range,
|
||||
Hover, DocumentHighlight, CompletionList, Position, FormattingOptions, SymbolInformation
|
||||
} from 'vscode-languageserver-types';
|
||||
import { ColorInformation, ColorPresentation, Color } from 'vscode-languageserver';
|
||||
import { ColorInformation, ColorPresentation, Color, WorkspaceFolder } from 'vscode-languageserver';
|
||||
import { FoldingRange } from '../protocol/foldingProvider.proposed';
|
||||
|
||||
import { getLanguageModelCache, LanguageModelCache } from '../languageModelCache';
|
||||
@@ -27,16 +27,15 @@ export interface Settings {
|
||||
emmet?: { [key: string]: any };
|
||||
}
|
||||
|
||||
export interface SettingProvider {
|
||||
getDocumentSettings(textDocument: TextDocument): Thenable<Settings>;
|
||||
export interface Workspace {
|
||||
readonly settings: Settings;
|
||||
readonly folders: WorkspaceFolder[];
|
||||
}
|
||||
|
||||
export interface LanguageMode {
|
||||
getId(): string;
|
||||
configure?: (options: Settings) => void;
|
||||
doValidation?: (document: TextDocument, settings?: Settings) => Diagnostic[];
|
||||
doComplete?: (document: TextDocument, position: Position, settings?: Settings, registeredCompletionParticipants?: any[]) => CompletionList | null;
|
||||
setCompletionParticipants?: (registeredCompletionParticipants: any[]) => void;
|
||||
doComplete?: (document: TextDocument, position: Position, settings?: Settings, registeredCompletionParticipants?: any[]) => CompletionList;
|
||||
doResolve?: (document: TextDocument, item: CompletionItem) => CompletionItem;
|
||||
doHover?: (document: TextDocument, position: Position) => Hover | null;
|
||||
doSignatureHelp?: (document: TextDocument, position: Position) => SignatureHelp | null;
|
||||
@@ -69,7 +68,7 @@ export interface LanguageModeRange extends Range {
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean; }): LanguageModes {
|
||||
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean; }, workspace: Workspace): LanguageModes {
|
||||
|
||||
var htmlLanguageService = getHTMLLanguageService();
|
||||
let documentRegions = getLanguageModelCache<HTMLDocumentRegions>(10, 60, document => getDocumentRegions(htmlLanguageService, document));
|
||||
@@ -78,12 +77,12 @@ export function getLanguageModes(supportedLanguages: { [languageId: string]: boo
|
||||
modelCaches.push(documentRegions);
|
||||
|
||||
let modes = Object.create(null);
|
||||
modes['html'] = getHTMLMode(htmlLanguageService);
|
||||
modes['html'] = getHTMLMode(htmlLanguageService, workspace);
|
||||
if (supportedLanguages['css']) {
|
||||
modes['css'] = getCSSMode(documentRegions);
|
||||
modes['css'] = getCSSMode(documentRegions, workspace);
|
||||
}
|
||||
if (supportedLanguages['javascript']) {
|
||||
modes['javascript'] = getJavascriptMode(documentRegions);
|
||||
modes['javascript'] = getJavascriptMode(documentRegions, workspace);
|
||||
}
|
||||
return {
|
||||
getModeAtPosition(document: TextDocument, position: Position): LanguageMode | undefined {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TextDocument, CompletionList, CompletionItemKind, CompletionItem, TextEdit, Range, Position } from 'vscode-languageserver-types';
|
||||
import { TextDocument, CompletionItemKind, CompletionItem, TextEdit, Range, Position } from 'vscode-languageserver-types';
|
||||
import { WorkspaceFolder } from 'vscode-languageserver';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
@@ -15,22 +15,21 @@ import { contains } from '../utils/arrays';
|
||||
|
||||
export function getPathCompletionParticipant(
|
||||
document: TextDocument,
|
||||
workspaceFolders: WorkspaceFolder[] | undefined,
|
||||
result: CompletionList
|
||||
workspaceFolders: WorkspaceFolder[],
|
||||
result: CompletionItem[]
|
||||
): ICompletionParticipant {
|
||||
return {
|
||||
onHtmlAttributeValue: ({ tag, position, attribute, value: valueBeforeCursor, range }) => {
|
||||
const fullValue = getFullValueWithoutQuotes(document, range);
|
||||
|
||||
if (shouldDoPathCompletion(tag, attribute, fullValue)) {
|
||||
if (!workspaceFolders || workspaceFolders.length === 0) {
|
||||
if (workspaceFolders.length === 0) {
|
||||
return;
|
||||
}
|
||||
const workspaceRoot = resolveWorkspaceRoot(document, workspaceFolders);
|
||||
|
||||
const paths = providePaths(valueBeforeCursor, URI.parse(document.uri).fsPath, workspaceRoot);
|
||||
const suggestions = paths.map(p => pathToSuggestion(p, valueBeforeCursor, fullValue, range));
|
||||
result.items = [...suggestions, ...result.items];
|
||||
result.push(...paths.map(p => pathToSuggestion(p, valueBeforeCursor, fullValue, range)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user