Skip to content

Commit 8d4915c

Browse files
committed
Add css based completions
1 parent 5005c31 commit 8d4915c

File tree

7 files changed

+93
-2
lines changed

7 files changed

+93
-2
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ package-lock.json
2121
packages/theme-check-docs-updater/data
2222
packages/lang-jsonc/src/parser.*
2323
.vscode-test-web
24+
.shopify

packages/theme-language-server-common/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@vscode/web-custom-data": "^0.4.6",
3333
"vscode-json-languageservice": "^5.3.10",
3434
"vscode-languageserver": "^8.0.2",
35+
"vscode-css-languageservice": "6.3.2",
3536
"vscode-languageserver-textdocument": "^1.0.8",
3637
"vscode-uri": "^3.0.7"
3738
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { CompletionItem, TextDocument } from 'vscode-languageserver';
2+
import { LiquidCompletionParams } from '../params';
3+
import { Provider } from './common';
4+
import { getCssLanguageService } from '../../plugins/css';
5+
import { Position } from 'vscode-json-languageservice';
6+
7+
export class CompletionsForStyleSheetProvider implements Provider {
8+
constructor(
9+
private readonly getThemeBlockNames: (
10+
rootUri: string,
11+
includePrivate: boolean,
12+
) => Promise<string[]>,
13+
) {}
14+
15+
async completions(params: LiquidCompletionParams): Promise<CompletionItem[]> {
16+
if (!params.completionContext) return [];
17+
18+
const { node } = params.completionContext;
19+
const { document } = params;
20+
if (node && document.stylesheet && document.stylesheet.cssStart >= node.position.start && document.stylesheet.cssEnd <= node.position.end) {
21+
const cssLanguageService = getCssLanguageService('css');
22+
const offset = document.stylesheet.cssStart;
23+
const position = offsetToPosition(document.stylesheet.source, offset);
24+
const stylesheet = cssLanguageService.parseStylesheet(document.stylesheet.source);
25+
const completions = cssLanguageService.doComplete(document.stylesheet.source, position, stylesheet, {triggerPropertyValueCompletion: true });
26+
return completions.items.map(item => ({
27+
label: item.label,
28+
kind: item.kind,
29+
insertText: item.insertText,
30+
documentation: item.documentation,
31+
detail: item.detail,
32+
}));
33+
} else {
34+
return [];
35+
}
36+
}
37+
}
38+
39+
function offsetToPosition(source: TextDocument, offset: number): Position {
40+
const line = source.getText().slice(0, offset).split('\n').length - 1;
41+
const character = offset - source.getText().slice(0, offset).lastIndexOf('\n');
42+
return { line, character };
43+
}

packages/theme-language-server-common/src/documents/DocumentManager.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,17 @@ export class DocumentManager {
181181
textDocument,
182182
};
183183
case SourceCodeType.LiquidHtml:
184+
const stylesheet = sourceCode.source.match(/{% stylesheet %}([\s\S]*?){% endstylesheet %}/)?.[1];
184185
return {
185186
...sourceCode,
186187
textDocument,
187-
188+
stylesheet: stylesheet ? {
189+
source: TextDocument.create(uri + '-css', 'css', sourceCode.version ?? 0, stylesheet),
190+
tagStart: stylesheet.indexOf('{% stylesheet %}'),
191+
tagEnd: stylesheet.indexOf('{% stylesheet %}'),
192+
cssStart: stylesheet.indexOf('{% stylesheet %}') + '{% stylesheet %}'.length,
193+
cssEnd: stylesheet.indexOf('{% endstylesheet %}') + '{% endstylesheet %}'.length,
194+
} : undefined,
188195
/** Lazy and only computed once per file version */
189196
getSchema: memo(async () => {
190197
if (!this.getModeForUri || !this.isValidSchema) return undefined;

packages/theme-language-server-common/src/documents/types.ts

+9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ type _AugmentedSourceCode<SCT extends SourceCodeType = SourceCodeType> = SourceC
1616
/** JsonSourceCode + textDocument */
1717
export type AugmentedJsonSourceCode = _AugmentedSourceCode<SourceCodeType.JSON>;
1818

19+
export type StyleSheetTag = {
20+
source: TextDocument;
21+
tagStart: number;
22+
tagEnd: number;
23+
cssStart: number;
24+
cssEnd: number;
25+
}
26+
1927
/**
2028
* AugmentedLiquidSourceCode may hold the schema for the section or block.
2129
*
@@ -25,6 +33,7 @@ export type AugmentedJsonSourceCode = _AugmentedSourceCode<SourceCodeType.JSON>;
2533
export type AugmentedLiquidSourceCode = _AugmentedSourceCode<SourceCodeType.LiquidHtml> & {
2634
getSchema: () => Promise<SectionSchema | ThemeBlockSchema | AppBlockSchema | undefined>;
2735
getLiquidDoc: (snippetName: string) => Promise<SnippetDefinition | undefined>;
36+
stylesheet: StyleSheetTag | undefined;
2837
};
2938

3039
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {
2+
getCSSLanguageService,
3+
LanguageService,
4+
} from 'vscode-css-languageservice';
5+
6+
const cssLanguageService = getCSSLanguageService();
7+
8+
const languageServices = {
9+
css: cssLanguageService,
10+
}
11+
export type CSSLanguageServices = Record<'css' | 'less' | 'scss', LanguageService>;
12+
13+
export function getCssLanguageService( kind: 'css'): LanguageService {
14+
return languageServices[kind];
15+
}

yarn.lock

+16-1
Original file line numberDiff line numberDiff line change
@@ -6679,6 +6679,16 @@ vitest@^2.1.1:
66796679
vite-node "2.1.1"
66806680
why-is-node-running "^2.3.0"
66816681

6682+
6683+
version "6.3.2"
6684+
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.3.2.tgz#dd54161776f1663fa514a1b5df0d3990bda604bb"
6685+
integrity sha512-GEpPxrUTAeXWdZWHev1OJU9lz2Q2/PPBxQ2TIRmLGvQiH3WZbqaNoute0n0ewxlgtjzTW3AKZT+NHySk5Rf4Eg==
6686+
dependencies:
6687+
"@vscode/l10n" "^0.0.18"
6688+
vscode-languageserver-textdocument "^1.0.12"
6689+
vscode-languageserver-types "3.17.5"
6690+
vscode-uri "^3.0.8"
6691+
66826692
vscode-json-languageservice@^5.3.10:
66836693
version "5.3.10"
66846694
resolved "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.3.10.tgz#7d56872cbb7460baf0491cea31807e537244dbae"
@@ -6717,12 +6727,17 @@ vscode-languageserver-textdocument@^1.0.11, vscode-languageserver-textdocument@^
67176727
resolved "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz#0822a000e7d4dc083312580d7575fe9e3ba2e2bf"
67186728
integrity sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==
67196729

6730+
vscode-languageserver-textdocument@^1.0.12:
6731+
version "1.0.12"
6732+
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631"
6733+
integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==
6734+
67206735
67216736
version "3.17.3"
67226737
resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz"
67236738
integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==
67246739

6725-
vscode-languageserver-types@^3.17.5:
6740+
vscode-languageserver-types@3.17.5, vscode-languageserver-types@^3.17.5:
67266741
version "3.17.5"
67276742
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a"
67286743
integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==

0 commit comments

Comments
 (0)