Skip to content

Commit

Permalink
feat: upgrade to Volar 2.3 alpha (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk authored May 28, 2024
1 parent d53f4df commit 6afd557
Show file tree
Hide file tree
Showing 46 changed files with 660 additions and 349 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@lerna-lite/cli": "latest",
"@lerna-lite/exec": "latest",
"@lerna-lite/publish": "latest",
"@volar/language-service": "~2.2.3",
"@volar/language-service": "~2.3.0-alpha.0",
"@volar/tsl-config": "latest",
"tsl": "latest",
"typescript": "latest",
Expand Down
72 changes: 47 additions & 25 deletions packages/css/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CodeAction, Diagnostic, Disposable, DocumentSelector, FormattingOptions, LocationLink, ProviderResult, ServiceContext, LanguageServicePlugin, LanguageServicePluginInstance } from '@volar/language-service';
import type { CodeAction, Diagnostic, Disposable, DocumentSelector, FormattingOptions, LocationLink, ProviderResult, LanguageServiceContext, LanguageServicePlugin, LanguageServicePluginInstance } from '@volar/language-service';
import * as css from 'vscode-css-languageservice';
import { TextDocument } from 'vscode-languageserver-textdocument';
import { URI, Utils } from 'vscode-uri';
Expand All @@ -16,22 +16,22 @@ export function create({
getDocumentContext = context => {
return {
resolveReference(ref, base) {
const decoded = context.decodeEmbeddedDocumentUri(base);
let baseUri = URI.parse(base);
const decoded = context.decodeEmbeddedDocumentUri(baseUri);
if (decoded) {
base = decoded[0];
baseUri = decoded[0];
}
if (ref.match(/^\w[\w\d+.-]*:/)) {
// starts with a schema
return ref;
}
if (ref[0] === '/') { // resolve absolute path against the current workspace folder
let folderUri = context.env.workspaceFolder;
if (ref[0] === '/' && context.env.workspaceFolders.length) { // resolve absolute path against the current workspace folder
let folderUri = context.env.workspaceFolders[0].toString();
if (!folderUri.endsWith('/')) {
folderUri += '/';
}
return folderUri + ref.substring(1);
}
const baseUri = URI.parse(base);
const baseUriDir = baseUri.path.endsWith('/') ? baseUri : Utils.dirname(baseUri);
return Utils.resolvePath(baseUriDir, ref).toString(true);
},
Expand All @@ -53,15 +53,18 @@ export function create({
const customData: string[] = await context.env.getConfiguration?.('css.customData') ?? [];
const newData: css.ICSSDataProvider[] = [];
for (const customDataPath of customData) {
const uri = Utils.resolvePath(URI.parse(context.env.workspaceFolder), customDataPath);
const json = await context.env.fs?.readFile?.(uri.toString());
if (json) {
try {
const data = JSON.parse(json);
newData.push(css.newCSSDataProvider(data));
}
catch (error) {
console.error(error);
for (const workspaceFolder of context.env.workspaceFolders) {
const uri = Utils.resolvePath(workspaceFolder, customDataPath);
const json = await context.env.fs?.readFile?.(uri);
if (json) {
try {
const data = JSON.parse(json);
newData.push(css.newCSSDataProvider(data));
}
catch (error) {
console.error(error);
}
break;
}
}
}
Expand All @@ -80,24 +83,43 @@ export function create({
scssDocumentSelector?: DocumentSelector,
lessDocumentSelector?: DocumentSelector,
useDefaultDataProvider?: boolean;
getDocumentContext?(context: ServiceContext): css.DocumentContext;
isFormattingEnabled?(document: TextDocument, context: ServiceContext): ProviderResult<boolean>;
getFormattingOptions?(document: TextDocument, options: FormattingOptions, context: ServiceContext): ProviderResult<css.CSSFormatConfiguration>;
getLanguageSettings?(document: TextDocument, context: ServiceContext): ProviderResult<css.LanguageSettings | undefined>;
getCustomData?(context: ServiceContext): ProviderResult<css.ICSSDataProvider[]>;
onDidChangeCustomData?(listener: () => void, context: ServiceContext): Disposable;
getDocumentContext?(context: LanguageServiceContext): css.DocumentContext;
isFormattingEnabled?(document: TextDocument, context: LanguageServiceContext): ProviderResult<boolean>;
getFormattingOptions?(document: TextDocument, options: FormattingOptions, context: LanguageServiceContext): ProviderResult<css.CSSFormatConfiguration>;
getLanguageSettings?(document: TextDocument, context: LanguageServiceContext): ProviderResult<css.LanguageSettings | undefined>;
getCustomData?(context: LanguageServiceContext): ProviderResult<css.ICSSDataProvider[]>;
onDidChangeCustomData?(listener: () => void, context: LanguageServiceContext): Disposable;
} = {}): LanguageServicePlugin {
return {
name: 'css',
// https://github.com/microsoft/vscode/blob/09850876e652688fb142e2e19fd00fd38c0bc4ba/extensions/css-language-features/server/src/cssServer.ts#L97
triggerCharacters: ['/', '-', ':'],
capabilities: {
completionProvider: {
// https://github.com/microsoft/vscode/blob/09850876e652688fb142e2e19fd00fd38c0bc4ba/extensions/css-language-features/server/src/cssServer.ts#L97
triggerCharacters: ['/', '-', ':'],
},
renameProvider: {
prepareProvider: true,
},
codeActionProvider: {},
definitionProvider: true,
diagnosticProvider: true,
hoverProvider: true,
referencesProvider: true,
documentHighlightProvider: true,
documentLinkProvider: {},
documentSymbolProvider: true,
colorProvider: true,
foldingRangeProvider: true,
selectionRangeProvider: true,
documentFormattingProvider: true,
},
create(context): LanguageServicePluginInstance<Provide> {

const stylesheets = new WeakMap<TextDocument, [number, css.Stylesheet]>();
const fileSystemProvider: css.FileSystemProvider = {
stat: async uri => await context.env.fs?.stat(uri)
stat: async uri => await context.env.fs?.stat(URI.parse(uri))
?? { type: css.FileType.Unknown, ctime: 0, mtime: 0, size: 0 },
readDirectory: async uri => await context.env.fs?.readDirectory(uri) ?? [],
readDirectory: async uri => await context.env.fs?.readDirectory(URI.parse(uri)) ?? [],
};
const documentContext = getDocumentContext(context);
const disposable = onDidChangeCustomData(() => initializing = undefined, context);
Expand Down
2 changes: 1 addition & 1 deletion packages/css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@types/node": "latest"
},
"peerDependencies": {
"@volar/language-service": "~2.2.3"
"@volar/language-service": "~2.3.0-alpha.0"
},
"peerDependenciesMeta": {
"@volar/language-service": {
Expand Down
1 change: 1 addition & 0 deletions packages/emmet/empty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ console.warn('[volar-service-emmet] this module is not yet supported for web.');
export function create(): LanguageServicePlugin {
return {
name: 'emmet (stub)',
capabilities: {},
create() {
return {};
},
Expand Down
15 changes: 10 additions & 5 deletions packages/emmet/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type * as vscode from '@volar/language-service';
import type * as helper from '@vscode/emmet-helper';
import type { Node, Stylesheet } from 'EmmetFlatNode';
import { URI } from 'vscode-uri';
import { getSyntaxFromArgs, isValidLocationForEmmetAbbreviation } from './lib/abbreviationActions';
import { getRootNode } from './lib/parseDocument';
import { allowedMimeTypesInScriptTag, getEmbeddedCssNodeIfAny, getEmmetConfiguration, getEmmetHelper, getEmmetMode, getFlatNode, getHtmlFlatNode, isStyleSheet, parsePartialStylesheet } from './lib/util';
import { getSyntaxFromArgs, isValidLocationForEmmetAbbreviation } from './lib/abbreviationActions';

export function create({
mappedLanguages = {},
Expand All @@ -12,9 +13,12 @@ export function create({
} = {}): vscode.LanguageServicePlugin {
return {
name: 'emmet',
// https://docs.emmet.io/abbreviations/syntax/
triggerCharacters: '>+^*()#.[]$@-{}'.split(''),
// @ts-expect-error Need to update @volar/language-service
capabilities: {
completionProvider: {
// https://docs.emmet.io/abbreviations/syntax/
triggerCharacters: '>+^*()#.[]$@-{}'.split(''),
},
},
create(context, languageService): vscode.LanguageServicePluginInstance {

let lastCompletionType: string | undefined;
Expand Down Expand Up @@ -182,7 +186,8 @@ export function create({
if (abbreviation.startsWith('this.') || /\[[^\]=]*\]/.test(abbreviation)) {
isNoisePromise = Promise.resolve(true);
} else {
const documentUri = context.decodeEmbeddedDocumentUri(document.uri)?.[0] ?? document.uri;
const uri = URI.parse(document.uri);
const documentUri = context.decodeEmbeddedDocumentUri(uri)?.[0] ?? uri;
isNoisePromise = languageService.findDocumentSymbols(documentUri).then(symbols => {
return !!symbols && symbols.some(x => abbreviation === x.name || (abbreviation.startsWith(x.name + '.') && !/>|\*|\+/.test(abbreviation)));
});
Expand Down
4 changes: 2 additions & 2 deletions packages/emmet/lib/abbreviationActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const hexColorRegex = /^#[\da-fA-F]{0,6}$/;
* @param position position to validate
* @param abbreviationRange The range of the abbreviation for which given position is being validated
*/
export async function isValidLocationForEmmetAbbreviation(context: vscode.ServiceContext, document: vscode.TextDocument, rootNode: Node | undefined, currentNode: Node | undefined, syntax: string, offset: number, abbreviationRange: vscode.Range): Promise<boolean> {
export async function isValidLocationForEmmetAbbreviation(context: vscode.LanguageServiceContext, document: vscode.TextDocument, rootNode: Node | undefined, currentNode: Node | undefined, syntax: string, offset: number, abbreviationRange: vscode.Range): Promise<boolean> {
if (isStyleSheet(syntax)) {
const stylesheet = <Stylesheet>rootNode;
if (stylesheet && (stylesheet.comments || []).some(x => offset >= x.start && offset <= x.end)) {
Expand Down Expand Up @@ -203,7 +203,7 @@ export async function isValidLocationForEmmetAbbreviation(context: vscode.Servic
return valid;
}

export async function getSyntaxFromArgs(context: vscode.ServiceContext, args: { [x: string]: string; }): Promise<string | undefined> {
export async function getSyntaxFromArgs(context: vscode.LanguageServiceContext, args: { [x: string]: string; }): Promise<string | undefined> {
const mappedModes = await getMappingForIncludedLanguages(context);
const language: string = args['language'];
const parentMode: string = args['parentMode'];
Expand Down
4 changes: 2 additions & 2 deletions packages/emmet/lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function isStyleSheet(syntax: string): boolean {
return stylesheetSyntaxes.includes(syntax);
}

export async function getMappingForIncludedLanguages(context: vscode.ServiceContext): Promise<Record<string, string>> {
export async function getMappingForIncludedLanguages(context: vscode.LanguageServiceContext): Promise<Record<string, string>> {
// Explicitly map languages that have built-in grammar in VS Code to their parent language
// to get emmet completion support
// For other languages, users will have to use `emmet.includeLanguages` or
Expand Down Expand Up @@ -372,7 +372,7 @@ function setupCdataNodeSubtree(documentText: string, cdataNode: HtmlFlatNode): s
return cdataBody;
}

export async function getEmmetConfiguration(context: vscode.ServiceContext, syntax: string) {
export async function getEmmetConfiguration(context: vscode.LanguageServiceContext, syntax: string) {
const emmetConfig = await context.env.getConfiguration<any>?.('emmet') ?? {};
const syntaxProfiles = Object.assign({}, emmetConfig['syntaxProfiles'] || {});
const preferences = Object.assign({}, emmetConfig['preferences'] || {});
Expand Down
5 changes: 3 additions & 2 deletions packages/emmet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
"dependencies": {
"@emmetio/css-parser": "^0.4.0",
"@emmetio/html-matcher": "^1.3.0",
"@vscode/emmet-helper": "^2.9.2"
"@vscode/emmet-helper": "^2.9.2",
"vscode-uri": "^3.0.8"
},
"devDependencies": {
"@types/node": "latest"
},
"peerDependencies": {
"@volar/language-service": "~2.2.3"
"@volar/language-service": "~2.3.0-alpha.0"
},
"peerDependenciesMeta": {
"@volar/language-service": {
Expand Down
Loading

0 comments on commit 6afd557

Please sign in to comment.