@astrojs/language-server 0.16.1 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/core/config/ConfigManager.d.ts +4 -3
  3. package/dist/core/config/ConfigManager.js +15 -1
  4. package/dist/core/config/interfaces.d.ts +5 -0
  5. package/dist/core/documents/AstroDocument.d.ts +1 -0
  6. package/dist/core/documents/AstroDocument.js +1 -0
  7. package/dist/core/documents/DocumentMapper.d.ts +2 -0
  8. package/dist/core/documents/DocumentMapper.js +7 -5
  9. package/dist/core/documents/utils.d.ts +1 -0
  10. package/dist/core/documents/utils.js +16 -1
  11. package/dist/plugins/PluginHost.d.ts +2 -1
  12. package/dist/plugins/PluginHost.js +4 -0
  13. package/dist/plugins/astro/AstroPlugin.js +10 -3
  14. package/dist/plugins/astro/features/CompletionsProvider.d.ts +4 -5
  15. package/dist/plugins/astro/features/CompletionsProvider.js +53 -58
  16. package/dist/plugins/html/HTMLPlugin.d.ts +2 -1
  17. package/dist/plugins/html/HTMLPlugin.js +18 -0
  18. package/dist/plugins/typescript/TypeScriptPlugin.d.ts +3 -1
  19. package/dist/plugins/typescript/TypeScriptPlugin.js +5 -0
  20. package/dist/plugins/typescript/features/CodeActionsProvider.js +76 -17
  21. package/dist/plugins/typescript/features/CompletionsProvider.d.ts +2 -1
  22. package/dist/plugins/typescript/features/CompletionsProvider.js +107 -45
  23. package/dist/plugins/typescript/features/DefinitionsProvider.js +22 -1
  24. package/dist/plugins/typescript/features/DiagnosticsProvider.js +58 -15
  25. package/dist/plugins/typescript/features/FoldingRangesProvider.js +13 -6
  26. package/dist/plugins/typescript/features/FormattingProvider.d.ts +11 -0
  27. package/dist/plugins/typescript/features/FormattingProvider.js +132 -0
  28. package/dist/plugins/typescript/features/HoverProvider.js +14 -1
  29. package/dist/plugins/typescript/features/SignatureHelpProvider.js +9 -1
  30. package/dist/plugins/typescript/language-service.js +18 -0
  31. package/dist/plugins/typescript/snapshots/DocumentSnapshot.d.ts +22 -2
  32. package/dist/plugins/typescript/snapshots/DocumentSnapshot.js +48 -1
  33. package/dist/plugins/typescript/snapshots/SnapshotManager.js +1 -0
  34. package/dist/plugins/typescript/snapshots/utils.js +3 -2
  35. package/dist/plugins/typescript/utils.d.ts +11 -1
  36. package/dist/plugins/typescript/utils.js +17 -1
  37. package/dist/server.js +2 -0
  38. package/package.json +3 -2
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FormattingProviderImpl = void 0;
7
+ const typescript_1 = __importDefault(require("typescript"));
8
+ const vscode_languageserver_types_1 = require("vscode-languageserver-types");
9
+ const utils_1 = require("../utils");
10
+ class FormattingProviderImpl {
11
+ constructor(languageServiceManager, configManager) {
12
+ this.languageServiceManager = languageServiceManager;
13
+ this.configManager = configManager;
14
+ }
15
+ async formatDocument(document, options) {
16
+ const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
17
+ const filePath = (0, utils_1.toVirtualAstroFilePath)(tsDoc.filePath);
18
+ const formatConfig = await this.configManager.getTSFormatConfig(document, options);
19
+ let frontmatterEdits = [];
20
+ let scriptTagsEdits = [];
21
+ if (document.astroMeta.frontmatter.state === 'closed') {
22
+ const start = document.positionAt(document.astroMeta.frontmatter.startOffset + 3);
23
+ start.line += 1;
24
+ start.character = 0;
25
+ const startOffset = document.offsetAt(start);
26
+ const endOffset = document.astroMeta.frontmatter.endOffset;
27
+ const astroFormatConfig = await this.configManager.getAstroFormatConfig(document);
28
+ const settings = {
29
+ ...formatConfig,
30
+ baseIndentSize: astroFormatConfig.indentFrontmatter ? formatConfig.tabSize ?? 0 : undefined,
31
+ };
32
+ frontmatterEdits = lang.getFormattingEditsForRange(filePath, startOffset, endOffset, settings);
33
+ if (astroFormatConfig.newLineAfterFrontmatter) {
34
+ const templateStart = document.positionAt(endOffset + 3);
35
+ templateStart.line += 1;
36
+ templateStart.character = 0;
37
+ frontmatterEdits.push({
38
+ span: { start: document.offsetAt(templateStart), length: 0 },
39
+ newText: '\n',
40
+ });
41
+ }
42
+ }
43
+ document.scriptTags.forEach((scriptTag) => {
44
+ const { filePath: scriptFilePath, snapshot: scriptTagSnapshot } = (0, utils_1.getScriptTagSnapshot)(tsDoc, document, scriptTag.container);
45
+ const startLine = document.offsetAt(vscode_languageserver_types_1.Position.create(scriptTag.startPos.line, 0));
46
+ const initialIndentLevel = computeInitialIndent(document, startLine, options);
47
+ const baseIndent = (formatConfig.tabSize ?? 0) * (initialIndentLevel + 1);
48
+ const formatSettings = {
49
+ baseIndentSize: baseIndent,
50
+ indentStyle: typescript_1.default.IndentStyle.Smart,
51
+ ...formatConfig,
52
+ };
53
+ let edits = lang.getFormattingEditsForDocument(scriptFilePath, formatSettings);
54
+ if (edits) {
55
+ edits = edits
56
+ .map((edit) => {
57
+ edit.span.start = document.offsetAt(scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(edit.span.start)));
58
+ return edit;
59
+ })
60
+ .filter((edit) => {
61
+ return (scriptTagSnapshot.isInGenerated(document.positionAt(edit.span.start)) &&
62
+ scriptTag.end !== edit.span.start &&
63
+ // Don't format the last line of the file as it's in most case the indentation
64
+ scriptTag.endPos.line !== document.positionAt(edit.span.start).line);
65
+ });
66
+ const endLine = document.getLineUntilOffset(document.offsetAt(scriptTag.endPos));
67
+ if (isWhitespaceOnly(endLine)) {
68
+ const endLineStartOffset = document.offsetAt(vscode_languageserver_types_1.Position.create(scriptTag.endPos.line, 0));
69
+ const lastLineIndentRange = vscode_languageserver_types_1.Range.create(vscode_languageserver_types_1.Position.create(scriptTag.endPos.line, 0), scriptTag.endPos);
70
+ const newText = generateIndent(initialIndentLevel, options);
71
+ if (endLine !== newText) {
72
+ edits.push({
73
+ span: {
74
+ start: endLineStartOffset,
75
+ length: lastLineIndentRange.end.character,
76
+ },
77
+ newText,
78
+ });
79
+ }
80
+ }
81
+ }
82
+ scriptTagsEdits.push(...edits);
83
+ });
84
+ return [...frontmatterEdits, ...scriptTagsEdits].map((edit) => ({
85
+ range: (0, utils_1.convertRange)(document, edit.span),
86
+ newText: edit.newText,
87
+ }));
88
+ }
89
+ }
90
+ exports.FormattingProviderImpl = FormattingProviderImpl;
91
+ function computeInitialIndent(document, lineStart, options) {
92
+ let content = document.getText();
93
+ let i = lineStart;
94
+ let nChars = 0;
95
+ let tabSize = options.tabSize || 4;
96
+ while (i < content.length) {
97
+ let ch = content.charAt(i);
98
+ if (ch === ' ') {
99
+ nChars++;
100
+ }
101
+ else if (ch === '\t') {
102
+ nChars += tabSize;
103
+ }
104
+ else {
105
+ break;
106
+ }
107
+ i++;
108
+ }
109
+ return Math.floor(nChars / tabSize);
110
+ }
111
+ function generateIndent(level, options) {
112
+ if (options.insertSpaces) {
113
+ return repeat(' ', level * options.tabSize);
114
+ }
115
+ else {
116
+ return repeat('\t', level);
117
+ }
118
+ }
119
+ function repeat(value, count) {
120
+ let s = '';
121
+ while (count > 0) {
122
+ if ((count & 1) === 1) {
123
+ s += value;
124
+ }
125
+ value += value;
126
+ count = count >>> 1;
127
+ }
128
+ return s;
129
+ }
130
+ function isWhitespaceOnly(str) {
131
+ return /^\s*$/.test(str);
132
+ }
@@ -18,7 +18,20 @@ class HoverProviderImpl {
18
18
  const fragment = await tsDoc.createFragment();
19
19
  const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
20
20
  const filePath = (0, utils_1.toVirtualAstroFilePath)(tsDoc.filePath);
21
- let info = lang.getQuickInfoAtPosition(filePath, offset);
21
+ const html = document.html;
22
+ const documentOffset = document.offsetAt(position);
23
+ const node = html.findNodeAt(documentOffset);
24
+ let info;
25
+ if (node.tag === 'script') {
26
+ const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_1.getScriptTagSnapshot)(tsDoc, document, node, position);
27
+ info = lang.getQuickInfoAtPosition(scriptFilePath, scriptOffset);
28
+ if (info) {
29
+ info.textSpan.start = fragment.offsetAt(scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(info.textSpan.start)));
30
+ }
31
+ }
32
+ else {
33
+ info = lang.getQuickInfoAtPosition(filePath, offset);
34
+ }
22
35
  if (!info) {
23
36
  return null;
24
37
  }
@@ -20,8 +20,16 @@ class SignatureHelpProviderImpl {
20
20
  }
21
21
  const filePath = (0, utils_1.toVirtualAstroFilePath)(tsDoc.filePath);
22
22
  const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
23
+ const node = document.html.findNodeAt(offset);
24
+ let info;
23
25
  const triggerReason = this.toTsTriggerReason(context);
24
- const info = lang.getSignatureHelpItems(filePath, offset, triggerReason ? { triggerReason } : undefined);
26
+ if (node.tag === 'script') {
27
+ const { filePath: scriptFilePath, offset: scriptOffset } = (0, utils_1.getScriptTagSnapshot)(tsDoc, document, node, position);
28
+ info = lang.getSignatureHelpItems(scriptFilePath, scriptOffset, triggerReason ? { triggerReason } : undefined);
29
+ }
30
+ else {
31
+ info = lang.getSignatureHelpItems(filePath, offset, triggerReason ? { triggerReason } : undefined);
32
+ }
25
33
  if (!info) {
26
34
  return null;
27
35
  }
@@ -33,6 +33,7 @@ const utils_1 = require("../../utils");
33
33
  const module_loader_1 = require("./module-loader");
34
34
  const SnapshotManager_1 = require("./snapshots/SnapshotManager");
35
35
  const utils_2 = require("./utils");
36
+ const DocumentSnapshot_1 = require("./snapshots/DocumentSnapshot");
36
37
  const DocumentSnapshotUtils = __importStar(require("./snapshots/utils"));
37
38
  const services = new Map();
38
39
  async function getLanguageService(path, workspaceUris, docContext) {
@@ -140,6 +141,12 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
140
141
  }
141
142
  const newSnapshot = DocumentSnapshotUtils.createFromDocument(document);
142
143
  snapshotManager.set(filePath, newSnapshot);
144
+ document.scriptTags.forEach((scriptTag, index) => {
145
+ const scriptFilePath = filePath + `.__script${index}.js`;
146
+ const scriptSnapshot = new DocumentSnapshot_1.ScriptTagDocumentSnapshot(scriptTag, document, scriptFilePath);
147
+ snapshotManager.set(scriptFilePath, scriptSnapshot);
148
+ newSnapshot.scriptTagSnapshots?.push(scriptSnapshot);
149
+ });
143
150
  if (prevSnapshot && prevSnapshot.scriptKind !== newSnapshot.scriptKind) {
144
151
  // Restart language service as it doesn't handle script kind changes.
145
152
  languageService.dispose();
@@ -166,6 +173,16 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
166
173
  astroModuleLoader.deleteUnresolvedResolutionsFromCache(fileName);
167
174
  doc = DocumentSnapshotUtils.createFromFilePath(fileName, docContext.createDocument);
168
175
  snapshotManager.set(fileName, doc);
176
+ // If we needed to create an Astro snapshot, also create its script tags snapshots
177
+ if ((0, utils_2.isAstroFilePath)(fileName)) {
178
+ const document = doc.parent;
179
+ document.scriptTags.forEach((scriptTag, index) => {
180
+ const scriptFilePath = fileName + `.__script${index}.js`;
181
+ const scriptSnapshot = new DocumentSnapshot_1.ScriptTagDocumentSnapshot(scriptTag, document, scriptFilePath);
182
+ snapshotManager.set(scriptFilePath, scriptSnapshot);
183
+ doc.scriptTagSnapshots?.push(scriptSnapshot);
184
+ });
185
+ }
169
186
  return doc;
170
187
  }
171
188
  function updateProjectFiles() {
@@ -214,6 +231,7 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
214
231
  jsxFactory: 'astroHTML',
215
232
  module: typescript_1.default.ModuleKind.ESNext,
216
233
  target: typescript_1.default.ScriptTarget.ESNext,
234
+ isolatedModules: true,
217
235
  moduleResolution: typescript_1.default.ModuleResolutionKind.NodeJs,
218
236
  };
219
237
  const project = typescript_1.default.parseJsonConfigFileContent(configJson, typescript_1.default.sys, tsconfigRoot, forcedCompilerOptions, tsconfigPath, undefined, [
@@ -1,6 +1,6 @@
1
1
  import ts from 'typescript';
2
2
  import { Position, TextDocumentContentChangeEvent } from 'vscode-languageserver';
3
- import { AstroDocument, DocumentMapper, IdentityMapper } from '../../../core/documents';
3
+ import { AstroDocument, DocumentMapper, IdentityMapper, FragmentMapper, TagInformation } from '../../../core/documents';
4
4
  import { FrameworkExt } from '../utils';
5
5
  export interface DocumentSnapshot extends ts.IScriptSnapshot {
6
6
  version: number;
@@ -36,11 +36,12 @@ export interface SnapshotFragment extends DocumentMapper {
36
36
  * Snapshots used for Astro files
37
37
  */
38
38
  export declare class AstroSnapshot implements DocumentSnapshot {
39
- private readonly parent;
39
+ readonly parent: AstroDocument;
40
40
  private readonly text;
41
41
  readonly scriptKind: ts.ScriptKind;
42
42
  private fragment?;
43
43
  version: number;
44
+ scriptTagSnapshots: ScriptTagDocumentSnapshot[];
44
45
  constructor(parent: AstroDocument, text: string, scriptKind: ts.ScriptKind);
45
46
  createFragment(): Promise<AstroSnapshotFragment>;
46
47
  destroyFragment(): null;
@@ -65,6 +66,25 @@ export declare class AstroSnapshotFragment implements SnapshotFragment {
65
66
  isInGenerated(pos: Position): boolean;
66
67
  getURL(): string;
67
68
  }
69
+ export declare class ScriptTagDocumentSnapshot extends FragmentMapper implements DocumentSnapshot, SnapshotFragment {
70
+ scriptTag: TagInformation;
71
+ private readonly parent;
72
+ filePath: string;
73
+ readonly version: number;
74
+ private text;
75
+ scriptKind: ts.ScriptKind;
76
+ private lineOffsets?;
77
+ constructor(scriptTag: TagInformation, parent: AstroDocument, filePath: string);
78
+ positionAt(offset: number): Position;
79
+ offsetAt(position: Position): number;
80
+ createFragment(): Promise<SnapshotFragment>;
81
+ destroyFragment(): void;
82
+ getText(start: number, end: number): string;
83
+ getLength(): number;
84
+ getFullText(): string;
85
+ getChangeRange(): undefined;
86
+ private getLineOffsets;
87
+ }
68
88
  /**
69
89
  * Snapshot used for anything that is not an Astro file
70
90
  * It's both used for .js(x)/.ts(x) files and .svelte/.vue files
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TypeScriptDocumentSnapshot = exports.AstroSnapshotFragment = exports.AstroSnapshot = void 0;
6
+ exports.TypeScriptDocumentSnapshot = exports.ScriptTagDocumentSnapshot = exports.AstroSnapshotFragment = exports.AstroSnapshot = void 0;
7
+ const typescript_1 = __importDefault(require("typescript"));
4
8
  const documents_1 = require("../../../core/documents");
5
9
  const utils_1 = require("../../../utils");
6
10
  const utils_2 = require("../utils");
@@ -13,6 +17,7 @@ class AstroSnapshot {
13
17
  this.text = text;
14
18
  this.scriptKind = scriptKind;
15
19
  this.version = this.parent.version;
20
+ this.scriptTagSnapshots = [];
16
21
  }
17
22
  async createFragment() {
18
23
  if (!this.fragment) {
@@ -72,6 +77,48 @@ class AstroSnapshotFragment {
72
77
  }
73
78
  }
74
79
  exports.AstroSnapshotFragment = AstroSnapshotFragment;
80
+ class ScriptTagDocumentSnapshot extends documents_1.FragmentMapper {
81
+ constructor(scriptTag, parent, filePath) {
82
+ super(parent.getText(), scriptTag, filePath);
83
+ this.scriptTag = scriptTag;
84
+ this.parent = parent;
85
+ this.filePath = filePath;
86
+ this.version = this.parent.version;
87
+ this.text = this.parent.getText().slice(this.scriptTag.start, this.scriptTag.end) + '\nexport {}';
88
+ this.scriptKind = typescript_1.default.ScriptKind.JS;
89
+ }
90
+ positionAt(offset) {
91
+ return (0, documents_1.positionAt)(offset, this.text, this.getLineOffsets());
92
+ }
93
+ offsetAt(position) {
94
+ return (0, documents_1.offsetAt)(position, this.text, this.getLineOffsets());
95
+ }
96
+ async createFragment() {
97
+ return this;
98
+ }
99
+ destroyFragment() {
100
+ //
101
+ }
102
+ getText(start, end) {
103
+ return this.text.substring(start, end);
104
+ }
105
+ getLength() {
106
+ return this.text.length;
107
+ }
108
+ getFullText() {
109
+ return this.text;
110
+ }
111
+ getChangeRange() {
112
+ return undefined;
113
+ }
114
+ getLineOffsets() {
115
+ if (!this.lineOffsets) {
116
+ this.lineOffsets = (0, documents_1.getLineOffsets)(this.text);
117
+ }
118
+ return this.lineOffsets;
119
+ }
120
+ }
121
+ exports.ScriptTagDocumentSnapshot = ScriptTagDocumentSnapshot;
75
122
  /**
76
123
  * Snapshot used for anything that is not an Astro file
77
124
  * It's both used for .js(x)/.ts(x) files and .svelte/.vue files
@@ -187,6 +187,7 @@ class SnapshotManager {
187
187
  const projectFiles = this.getProjectFileNames();
188
188
  let allFiles = Array.from(new Set([...projectFiles, ...this.getFileNames()]));
189
189
  allFiles = allFiles.map((file) => (0, utils_2.ensureRealFilePath)(file));
190
+ // eslint-disable-next-line no-console
190
191
  console.log('SnapshotManager File Statistics:\n' +
191
192
  `Project files: ${projectFiles.length}\n` +
192
193
  `Astro files: ${allFiles.filter((name) => name.endsWith('.astro')).length}\n` +
@@ -10,6 +10,7 @@ const vscode_uri_1 = require("vscode-uri");
10
10
  const utils_1 = require("../utils");
11
11
  const DocumentSnapshot_1 = require("./DocumentSnapshot");
12
12
  const svelte_language_integration_1 = require("@astrojs/svelte-language-integration");
13
+ const vue_language_integration_1 = require("@astrojs/vue-language-integration");
13
14
  const utils_2 = require("../../../utils");
14
15
  // Utilities to create Snapshots from different contexts
15
16
  function createFromDocument(document) {
@@ -76,8 +77,8 @@ function createFromFrameworkFilePath(filePath, framework) {
76
77
  if (framework === 'svelte') {
77
78
  code = (0, svelte_language_integration_1.toTSX)(originalText, className);
78
79
  }
79
- else {
80
- code = `export default function ${className}__AstroComponent_(props: Record<string, any>): any {}`;
80
+ else if (framework === 'vue') {
81
+ code = (0, vue_language_integration_1.toTSX)(originalText, className);
81
82
  }
82
83
  return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, code, typescript_1.default.ScriptKind.TSX);
83
84
  }
@@ -1,7 +1,8 @@
1
1
  import ts from 'typescript';
2
2
  import { CompletionItemKind, DiagnosticSeverity, Position, Range, SymbolKind, SemanticTokensLegend } from 'vscode-languageserver';
3
3
  import { AstroDocument } from '../../core/documents';
4
- import { SnapshotFragment } from './snapshots/DocumentSnapshot';
4
+ import { AstroSnapshot, ScriptTagDocumentSnapshot, SnapshotFragment } from './snapshots/DocumentSnapshot';
5
+ import { Node } from 'vscode-html-languageservice';
5
6
  export declare const enum TokenType {
6
7
  class = 0,
7
8
  enum = 1,
@@ -58,4 +59,13 @@ export declare function toVirtualFilePath(filePath: string): string;
58
59
  export declare function toRealAstroFilePath(filePath: string): string;
59
60
  export declare function ensureRealAstroFilePath(filePath: string): string;
60
61
  export declare function ensureRealFilePath(filePath: string): string;
62
+ export declare function getScriptTagSnapshot(snapshot: AstroSnapshot, document: AstroDocument, tagInfo: Node | {
63
+ start: number;
64
+ end: number;
65
+ }, position?: Position): {
66
+ snapshot: ScriptTagDocumentSnapshot;
67
+ filePath: string;
68
+ index: number;
69
+ offset: number;
70
+ };
61
71
  export {};
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ensureRealFilePath = exports.ensureRealAstroFilePath = exports.toRealAstroFilePath = exports.toVirtualFilePath = exports.toVirtualAstroFilePath = exports.isVirtualFilePath = exports.isVirtualSvelteFilePath = exports.isVirtualVueFilePath = exports.isVirtualAstroFilePath = exports.isFrameworkFilePath = exports.isAstroFilePath = exports.isVirtualFrameworkFilePath = exports.getFrameworkFromFilePath = exports.removeAstroComponentSuffix = exports.checkEndOfFileCodeInsert = exports.ensureFrontmatterInsert = exports.convertToLocationRange = exports.convertRange = exports.mapSeverity = exports.getScriptKindFromFileName = exports.isSubPath = exports.findTsConfigPath = exports.getExtensionFromScriptKind = exports.getCommitCharactersForScriptElement = exports.scriptElementKindToCompletionItemKind = exports.symbolKindFromString = exports.getSemanticTokenLegend = void 0;
6
+ exports.getScriptTagSnapshot = exports.ensureRealFilePath = exports.ensureRealAstroFilePath = exports.toRealAstroFilePath = exports.toVirtualFilePath = exports.toVirtualAstroFilePath = exports.isVirtualFilePath = exports.isVirtualSvelteFilePath = exports.isVirtualVueFilePath = exports.isVirtualAstroFilePath = exports.isFrameworkFilePath = exports.isAstroFilePath = exports.isVirtualFrameworkFilePath = exports.getFrameworkFromFilePath = exports.removeAstroComponentSuffix = exports.checkEndOfFileCodeInsert = exports.ensureFrontmatterInsert = exports.convertToLocationRange = exports.convertRange = exports.mapSeverity = exports.getScriptKindFromFileName = exports.isSubPath = exports.findTsConfigPath = exports.getExtensionFromScriptKind = exports.getCommitCharactersForScriptElement = exports.scriptElementKindToCompletionItemKind = exports.symbolKindFromString = exports.getSemanticTokenLegend = void 0;
7
7
  const typescript_1 = __importDefault(require("typescript"));
8
8
  const path_1 = require("path");
9
9
  const utils_1 = require("../../utils");
@@ -346,3 +346,19 @@ function ensureRealFilePath(filePath) {
346
346
  }
347
347
  }
348
348
  exports.ensureRealFilePath = ensureRealFilePath;
349
+ function getScriptTagSnapshot(snapshot, document, tagInfo, position) {
350
+ const index = document.scriptTags.findIndex((value) => value.container.start == tagInfo.start);
351
+ const scriptFilePath = snapshot.filePath + `.__script${index}.js`;
352
+ const scriptTagSnapshot = snapshot.scriptTagSnapshots[index];
353
+ let offset = 0;
354
+ if (position) {
355
+ offset = scriptTagSnapshot.offsetAt(scriptTagSnapshot.getGeneratedPosition(position));
356
+ }
357
+ return {
358
+ snapshot: scriptTagSnapshot,
359
+ filePath: scriptFilePath,
360
+ index,
361
+ offset,
362
+ };
363
+ }
364
+ exports.getScriptTagSnapshot = getScriptTagSnapshot;
package/dist/server.js CHANGED
@@ -88,6 +88,7 @@ function startLanguageServer(connection) {
88
88
  foldingRangeProvider: true,
89
89
  definitionProvider: true,
90
90
  renameProvider: true,
91
+ documentFormattingProvider: true,
91
92
  codeActionProvider: {
92
93
  codeActionKinds: [
93
94
  vscode_languageserver_1.CodeActionKind.QuickFix,
@@ -193,6 +194,7 @@ function startLanguageServer(connection) {
193
194
  connection.onDocumentSymbol((params, cancellationToken) => pluginHost.getDocumentSymbols(params.textDocument, cancellationToken));
194
195
  connection.onRequest(vscode_languageserver_1.SemanticTokensRequest.type, (evt, cancellationToken) => pluginHost.getSemanticTokens(evt.textDocument, undefined, cancellationToken));
195
196
  connection.onRequest(vscode_languageserver_1.SemanticTokensRangeRequest.type, (evt, cancellationToken) => pluginHost.getSemanticTokens(evt.textDocument, evt.range, cancellationToken));
197
+ connection.onDocumentFormatting((params) => pluginHost.formatDocument(params.textDocument, params.options));
196
198
  connection.onDocumentColor((params) => pluginHost.getDocumentColors(params.textDocument));
197
199
  connection.onColorPresentation((params) => pluginHost.getColorPresentations(params.textDocument, params.range, params.color));
198
200
  connection.onRequest(TagCloseRequest, (evt) => pluginHost.doTagComplete(evt.textDocument, evt.position));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/language-server",
3
- "version": "0.16.1",
3
+ "version": "0.18.1",
4
4
  "author": "withastro",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -19,13 +19,14 @@
19
19
  "test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --timeout 20000 --require ts-node/register \"test/**/*.ts\" --exclude \"test/**/*.d.ts\""
20
20
  },
21
21
  "dependencies": {
22
+ "@astrojs/vue-language-integration": "^0.1.0",
22
23
  "@astrojs/svelte-language-integration": "^0.1.4",
23
24
  "@vscode/emmet-helper": "^2.8.4",
24
25
  "lodash": "^4.17.21",
25
26
  "source-map": "^0.7.3",
26
27
  "typescript": "~4.6.2",
27
28
  "vscode-css-languageservice": "^5.1.13",
28
- "vscode-html-languageservice": "^4.2.2",
29
+ "vscode-html-languageservice": "^4.2.5",
29
30
  "vscode-languageserver": "7.0.0",
30
31
  "vscode-languageserver-protocol": "^3.16.0",
31
32
  "vscode-languageserver-textdocument": "^1.0.1",