@astrojs/language-server 0.12.0 → 0.13.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @astrojs/language-server
2
2
 
3
+ ## 0.13.1
4
+
5
+ ### Patch Changes
6
+
7
+ - ea74fdb: Publish failed
8
+
9
+ ## 0.13.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 82b8891: Add HTML hover info, fix Astro directives producing errors, fix missing children property for JSX based frameworks
14
+
15
+ ### Patch Changes
16
+
17
+ - 9f4f907: Add CSS hover info
18
+ - c09116f: Add support for Document Symbols (Outline tab, breadcrumb navigation)
19
+
20
+ ## 0.12.1
21
+
22
+ ### Patch Changes
23
+
24
+ - 49955c6: Add support for colors indicators and color picker
25
+
3
26
  ## 0.12.0
4
27
 
5
28
  ### Minor Changes
@@ -1,4 +1,4 @@
1
- import { HTMLDocument } from 'vscode-html-languageservice';
1
+ import { HTMLDocument, Range } from 'vscode-html-languageservice';
2
2
  import { WritableDocument } from './DocumentBase';
3
3
  import { AstroMetadata } from './parseAstro';
4
4
  import { TagInformation } from './utils';
@@ -12,7 +12,7 @@ export declare class AstroDocument extends WritableDocument {
12
12
  constructor(url: string, content: string);
13
13
  private updateDocInfo;
14
14
  setText(text: string): void;
15
- getText(): string;
15
+ getText(range?: Range | undefined): string;
16
16
  getURL(): string;
17
17
  getFilePath(): string | null;
18
18
  }
@@ -24,7 +24,12 @@ class AstroDocument extends DocumentBase_1.WritableDocument {
24
24
  this.version++;
25
25
  this.updateDocInfo();
26
26
  }
27
- getText() {
27
+ getText(range) {
28
+ if (range) {
29
+ const start = this.offsetAt(range.start);
30
+ const end = this.offsetAt(range.end);
31
+ return this.content.substring(start, end);
32
+ }
28
33
  return this.content;
29
34
  }
30
35
  getURL() {
@@ -1,4 +1,4 @@
1
- import { CancellationToken, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FoldingRange, Hover, Position, Location, SignatureHelp, SignatureHelpContext, TextDocumentContentChangeEvent, TextDocumentIdentifier, WorkspaceEdit } from 'vscode-languageserver';
1
+ import { CancellationToken, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FoldingRange, Hover, Position, Range, Location, SignatureHelp, SignatureHelpContext, TextDocumentContentChangeEvent, TextDocumentIdentifier, WorkspaceEdit, SymbolInformation } from 'vscode-languageserver';
2
2
  import type { AppCompletionItem, Plugin } from './interfaces';
3
3
  import { DocumentManager } from '../core/documents/DocumentManager';
4
4
  interface PluginHostConfig {
@@ -18,8 +18,11 @@ export declare class PluginHost {
18
18
  doHover(textDocument: TextDocumentIdentifier, position: Position): Promise<Hover | null>;
19
19
  doTagComplete(textDocument: TextDocumentIdentifier, position: Position): Promise<string | null>;
20
20
  getFoldingRanges(textDocument: TextDocumentIdentifier): Promise<FoldingRange[] | null>;
21
+ getDocumentSymbols(textDocument: TextDocumentIdentifier, cancellationToken: CancellationToken): Promise<SymbolInformation[]>;
21
22
  getDefinitions(textDocument: TextDocumentIdentifier, position: Position): Promise<DefinitionLink[] | Location[]>;
22
23
  rename(textDocument: TextDocumentIdentifier, position: Position, newName: string): Promise<WorkspaceEdit | null>;
24
+ getDocumentColors(textDocument: TextDocumentIdentifier): Promise<ColorInformation[]>;
25
+ getColorPresentations(textDocument: TextDocumentIdentifier, range: Range, color: Color): Promise<ColorPresentation[]>;
23
26
  getSignatureHelp(textDocument: TextDocumentIdentifier, position: Position, context: SignatureHelpContext | undefined, cancellationToken: CancellationToken): Promise<SignatureHelp | null>;
24
27
  onWatchFileChanges(onWatchFileChangesParams: any[]): void;
25
28
  updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): void;
@@ -53,6 +53,10 @@ class PluginHost {
53
53
  const foldingRanges = (0, lodash_1.flatten)(await this.execute('getFoldingRanges', [document], ExecuteMode.Collect)).filter((completion) => completion != null);
54
54
  return foldingRanges;
55
55
  }
56
+ async getDocumentSymbols(textDocument, cancellationToken) {
57
+ const document = this.getDocument(textDocument.uri);
58
+ return (0, lodash_1.flatten)(await this.execute('getDocumentSymbols', [document, cancellationToken], ExecuteMode.Collect));
59
+ }
56
60
  async getDefinitions(textDocument, position) {
57
61
  const document = this.getDocument(textDocument.uri);
58
62
  const definitions = (0, lodash_1.flatten)(await this.execute('getDefinitions', [document, position], ExecuteMode.Collect));
@@ -67,6 +71,14 @@ class PluginHost {
67
71
  const document = this.getDocument(textDocument.uri);
68
72
  return this.execute('rename', [document, position, newName], ExecuteMode.FirstNonNull);
69
73
  }
74
+ async getDocumentColors(textDocument) {
75
+ const document = this.getDocument(textDocument.uri);
76
+ return (0, lodash_1.flatten)(await this.execute('getDocumentColors', [document], ExecuteMode.Collect));
77
+ }
78
+ async getColorPresentations(textDocument, range, color) {
79
+ const document = this.getDocument(textDocument.uri);
80
+ return (0, lodash_1.flatten)(await this.execute('getColorPresentations', [document, range, color], ExecuteMode.Collect));
81
+ }
70
82
  async getSignatureHelp(textDocument, position, context, cancellationToken) {
71
83
  const document = this.getDocument(textDocument.uri);
72
84
  if (!document) {
@@ -1,4 +1,4 @@
1
- import { CompletionContext, CompletionList, Position } from 'vscode-languageserver';
1
+ import { Color, ColorInformation, ColorPresentation, CompletionContext, CompletionList, Hover, Position, Range, SymbolInformation } from 'vscode-languageserver';
2
2
  import { ConfigManager } from '../../core/config/ConfigManager';
3
3
  import { AstroDocument } from '../../core/documents';
4
4
  import type { Plugin } from '../interfaces';
@@ -8,14 +8,25 @@ export declare class CSSPlugin implements Plugin {
8
8
  private cssDocuments;
9
9
  private triggerCharacters;
10
10
  constructor(configManager: ConfigManager);
11
+ doHover(document: AstroDocument, position: Position): Hover | null;
12
+ private doHoverInternal;
11
13
  getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): CompletionList | null;
12
14
  private getCompletionsInternal;
15
+ getDocumentColors(document: AstroDocument): ColorInformation[];
16
+ getColorPresentations(document: AstroDocument, range: Range, color: Color): ColorPresentation[];
17
+ getDocumentSymbols(document: AstroDocument): SymbolInformation[];
13
18
  private inStyleAttributeWithoutInterpolation;
14
19
  /**
15
20
  * Get the associated CSS Document for a style tag
16
21
  */
17
22
  private getCSSDocumentForStyleTag;
23
+ /**
24
+ * Get all the CSSDocuments in a document
25
+ */
18
26
  private getCSSDocumentsForDocument;
27
+ /**
28
+ * Get all the stylesheets (Stylesheet type) in a document
29
+ */
19
30
  private getStylesheetsForDocument;
20
31
  /**
21
32
  * Get style tag at position for a document
@@ -9,6 +9,7 @@ const language_service_1 = require("./language-service");
9
9
  const parseHtml_1 = require("../../core/documents/parseHtml");
10
10
  const StyleAttributeDocument_1 = require("./StyleAttributeDocument");
11
11
  const getIdClassCompletions_1 = require("./features/getIdClassCompletions");
12
+ const lodash_1 = require("lodash");
12
13
  class CSSPlugin {
13
14
  constructor(configManager) {
14
15
  this.__name = 'css';
@@ -16,6 +17,35 @@ class CSSPlugin {
16
17
  this.triggerCharacters = new Set(['.', ':', '-', '/']);
17
18
  this.configManager = configManager;
18
19
  }
20
+ doHover(document, position) {
21
+ if (!this.featureEnabled('hover')) {
22
+ return null;
23
+ }
24
+ if ((0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position))) {
25
+ return null;
26
+ }
27
+ const styleTag = this.getStyleTagForPosition(document, position);
28
+ if (!styleTag) {
29
+ const attributeContext = (0, parseHtml_1.getAttributeContextAtPosition)(document, position);
30
+ if (!attributeContext) {
31
+ return null;
32
+ }
33
+ if (this.inStyleAttributeWithoutInterpolation(attributeContext, document.getText())) {
34
+ const [start, end] = attributeContext.valueRange;
35
+ return this.doHoverInternal(new StyleAttributeDocument_1.StyleAttributeDocument(document, start, end), position);
36
+ }
37
+ return null;
38
+ }
39
+ const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
40
+ if (shouldExcludeHover(cssDocument)) {
41
+ return null;
42
+ }
43
+ return this.doHoverInternal(cssDocument, position);
44
+ }
45
+ doHoverInternal(cssDocument, position) {
46
+ const hoverInfo = (0, language_service_1.getLanguageService)(extractLanguage(cssDocument)).doHover(cssDocument, cssDocument.getGeneratedPosition(position), cssDocument.stylesheet);
47
+ return hoverInfo ? (0, documents_1.mapHoverToParent)(cssDocument, hoverInfo) : hoverInfo;
48
+ }
19
49
  getCompletions(document, position, completionContext) {
20
50
  if (!this.featureEnabled('completions')) {
21
51
  return null;
@@ -67,6 +97,49 @@ class CSSPlugin {
67
97
  // Emmet completions change on every keystroke, so they are never complete
68
98
  emmetResults.items.length > 0);
69
99
  }
100
+ getDocumentColors(document) {
101
+ if (!this.featureEnabled('documentColors')) {
102
+ return [];
103
+ }
104
+ const allColorInfo = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
105
+ const cssLang = extractLanguage(cssDoc);
106
+ const langService = (0, language_service_1.getLanguageService)(cssLang);
107
+ if (shouldExcludeColor(cssLang)) {
108
+ return [];
109
+ }
110
+ return langService
111
+ .findDocumentColors(cssDoc, cssDoc.stylesheet)
112
+ .map((colorInfo) => (0, documents_1.mapObjWithRangeToOriginal)(cssDoc, colorInfo));
113
+ });
114
+ return (0, lodash_1.flatten)(allColorInfo);
115
+ }
116
+ getColorPresentations(document, range, color) {
117
+ if (!this.featureEnabled('colorPresentations')) {
118
+ return [];
119
+ }
120
+ const allColorPres = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
121
+ const cssLang = extractLanguage(cssDoc);
122
+ const langService = (0, language_service_1.getLanguageService)(cssLang);
123
+ if ((!cssDoc.isInGenerated(range.start) && !cssDoc.isInGenerated(range.end)) || shouldExcludeColor(cssLang)) {
124
+ return [];
125
+ }
126
+ return langService
127
+ .getColorPresentations(cssDoc, cssDoc.stylesheet, color, (0, documents_1.mapRangeToGenerated)(cssDoc, range))
128
+ .map((colorPres) => (0, documents_1.mapColorPresentationToOriginal)(cssDoc, colorPres));
129
+ });
130
+ return (0, lodash_1.flatten)(allColorPres);
131
+ }
132
+ getDocumentSymbols(document) {
133
+ if (!this.featureEnabled('documentSymbols')) {
134
+ return [];
135
+ }
136
+ const allDocumentSymbols = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
137
+ return (0, language_service_1.getLanguageService)(extractLanguage(cssDoc))
138
+ .findDocumentSymbols(cssDoc, cssDoc.stylesheet)
139
+ .map((symbol) => (0, documents_1.mapSymbolInformationToOriginal)(cssDoc, symbol));
140
+ });
141
+ return (0, lodash_1.flatten)(allDocumentSymbols);
142
+ }
70
143
  inStyleAttributeWithoutInterpolation(attrContext, text) {
71
144
  return (attrContext.name === 'style' &&
72
145
  !!attrContext.valueRange &&
@@ -83,9 +156,15 @@ class CSSPlugin {
83
156
  }
84
157
  return cssDoc;
85
158
  }
159
+ /**
160
+ * Get all the CSSDocuments in a document
161
+ */
86
162
  getCSSDocumentsForDocument(document) {
87
163
  return document.styleTags.map((tag) => this.getCSSDocumentForStyleTag(tag, document));
88
164
  }
165
+ /**
166
+ * Get all the stylesheets (Stylesheet type) in a document
167
+ */
89
168
  getStylesheetsForDocument(document) {
90
169
  return this.getCSSDocumentsForDocument(document).map((cssDoc) => cssDoc.stylesheet);
91
170
  }
@@ -102,6 +181,38 @@ class CSSPlugin {
102
181
  }
103
182
  }
104
183
  exports.CSSPlugin = CSSPlugin;
184
+ /**
185
+ * Exclude certain language when getting hover info
186
+ * The CSS language service only supports CSS, LESS and SCSS,
187
+ * which mean that we cannot support hover info in other languages
188
+ */
189
+ function shouldExcludeHover(document) {
190
+ const language = typeof document === 'string' ? document : extractLanguage(document);
191
+ switch (language) {
192
+ case 'sass':
193
+ case 'stylus':
194
+ case 'styl':
195
+ return true;
196
+ default:
197
+ return false;
198
+ }
199
+ }
200
+ /**
201
+ * Exclude certain language when getting colors
202
+ * The CSS language service only supports CSS, LESS and SCSS,
203
+ * which mean that we cannot support colors in other languages
204
+ */
205
+ function shouldExcludeColor(document) {
206
+ const language = typeof document === 'string' ? document : extractLanguage(document);
207
+ switch (language) {
208
+ case 'sass':
209
+ case 'stylus':
210
+ case 'styl':
211
+ return true;
212
+ default:
213
+ return false;
214
+ }
215
+ }
105
216
  function isSASS(document) {
106
217
  switch (extractLanguage(document)) {
107
218
  case 'sass':
@@ -5,10 +5,10 @@ exports.pseudoClass = [
5
5
  {
6
6
  name: ':global()',
7
7
  description: `[astro] :global modifier
8
- Applying styles to a selector globally`,
8
+ Apply styles to a selector globally`,
9
9
  references: [
10
10
  {
11
- name: 'Astro Docs',
11
+ name: 'Astro documentation',
12
12
  url: 'https://docs.astro.build/en/guides/styling/#global-styles-within-style-tag',
13
13
  },
14
14
  ],
@@ -1,19 +1,22 @@
1
- import { CompletionList, Position, FoldingRange } from 'vscode-languageserver';
1
+ import { CompletionList, Position, FoldingRange, Hover, SymbolInformation } from 'vscode-languageserver';
2
2
  import type { Plugin } from '../interfaces';
3
3
  import { ConfigManager } from '../../core/config/ConfigManager';
4
4
  import { AstroDocument } from '../../core/documents/AstroDocument';
5
5
  export declare class HTMLPlugin implements Plugin {
6
6
  __name: string;
7
7
  private lang;
8
+ private componentLang;
8
9
  private styleScriptTemplate;
9
10
  private configManager;
10
11
  constructor(configManager: ConfigManager);
12
+ doHover(document: AstroDocument, position: Position): Hover | null;
11
13
  /**
12
14
  * Get HTML completions
13
15
  */
14
16
  getCompletions(document: AstroDocument, position: Position): CompletionList | null;
15
17
  getFoldingRanges(document: AstroDocument): FoldingRange[] | null;
16
18
  doTagComplete(document: AstroDocument, position: Position): string | null;
19
+ getDocumentSymbols(document: AstroDocument): SymbolInformation[];
17
20
  /**
18
21
  * Get lang completions for style tags (ex: `<style lang="scss">`)
19
22
  */
@@ -5,13 +5,39 @@ const vscode_languageserver_1 = require("vscode-languageserver");
5
5
  const emmet_helper_1 = require("@vscode/emmet-helper");
6
6
  const vscode_html_languageservice_1 = require("vscode-html-languageservice");
7
7
  const utils_1 = require("../../core/documents/utils");
8
+ const utils_2 = require("../../utils");
9
+ const astro_attributes_1 = require("./features/astro-attributes");
8
10
  class HTMLPlugin {
9
11
  constructor(configManager) {
10
12
  this.__name = 'html';
11
- this.lang = (0, vscode_html_languageservice_1.getLanguageService)();
13
+ this.lang = (0, vscode_html_languageservice_1.getLanguageService)({
14
+ customDataProviders: [astro_attributes_1.astroAttributes],
15
+ });
16
+ this.componentLang = (0, vscode_html_languageservice_1.getLanguageService)({
17
+ customDataProviders: [astro_attributes_1.astroAttributes, astro_attributes_1.astroDirectives],
18
+ useDefaultDataProvider: false,
19
+ });
12
20
  this.styleScriptTemplate = new Set(['style']);
13
21
  this.configManager = configManager;
14
22
  }
23
+ doHover(document, position) {
24
+ if (!this.featureEnabled('hover')) {
25
+ return null;
26
+ }
27
+ const html = document.html;
28
+ if (!html) {
29
+ return null;
30
+ }
31
+ const node = html.findNodeAt(document.offsetAt(position));
32
+ if (!node) {
33
+ return null;
34
+ }
35
+ // If the node we're hovering on is a component, instead only provide astro-specific hover info
36
+ if ((0, utils_2.isPossibleComponent)(node)) {
37
+ return this.componentLang.doHover(document, position, html);
38
+ }
39
+ return this.lang.doHover(document, position, html);
40
+ }
15
41
  /**
16
42
  * Get HTML completions
17
43
  */
@@ -66,6 +92,16 @@ class HTMLPlugin {
66
92
  }
67
93
  return this.lang.doTagComplete(document, position, html);
68
94
  }
95
+ getDocumentSymbols(document) {
96
+ if (!this.featureEnabled('documentSymbols')) {
97
+ return [];
98
+ }
99
+ const html = document.html;
100
+ if (!html) {
101
+ return [];
102
+ }
103
+ return this.lang.findDocumentSymbols(document, html);
104
+ }
69
105
  /**
70
106
  * Get lang completions for style tags (ex: `<style lang="scss">`)
71
107
  */
@@ -0,0 +1,2 @@
1
+ export declare const astroAttributes: import("vscode-html-languageservice").IHTMLDataProvider;
2
+ export declare const astroDirectives: import("vscode-html-languageservice").IHTMLDataProvider;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.astroDirectives = exports.astroAttributes = void 0;
4
+ const vscode_html_languageservice_1 = require("vscode-html-languageservice");
5
+ exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-attributes', {
6
+ version: 1,
7
+ globalAttributes: [
8
+ {
9
+ name: 'class:list',
10
+ description: 'Utility to provide a list of class',
11
+ },
12
+ {
13
+ name: 'set:html',
14
+ description: 'Inject unescaped HTML into this tag',
15
+ references: [
16
+ {
17
+ name: 'Astro documentation',
18
+ url: 'https://docs.astro.build/en/migrate/#deprecated-unescaped-html',
19
+ },
20
+ ],
21
+ },
22
+ {
23
+ name: 'set:text',
24
+ description: 'Inject escaped text into this tag',
25
+ references: [
26
+ {
27
+ name: 'Astro documentation',
28
+ url: 'https://docs.astro.build/en/migrate/#deprecated-unescaped-html',
29
+ },
30
+ ],
31
+ },
32
+ ],
33
+ tags: [
34
+ {
35
+ name: 'script',
36
+ attributes: [
37
+ {
38
+ // The VS Code tag definitions does not provide a description for the deprecated `charset` attribute on script tags
39
+ // Which mean that since we get no hover info for this, we instead get JSX hover info. So we'll just specify a description ourselves for this specific case
40
+ name: 'charset',
41
+ description: "(Deprecated) It's unnecessary to specify the charset attribute, because documents must use UTF-8, and the script element inherits its character encoding from the document.",
42
+ },
43
+ {
44
+ name: 'define:vars',
45
+ description: 'Passes serializable server-side variables into a client-side script element',
46
+ references: [
47
+ {
48
+ name: 'Astro documentation',
49
+ url: 'https://docs.astro.build/en/guides/styling/#variables-in-scripts--styles',
50
+ },
51
+ ],
52
+ },
53
+ ],
54
+ },
55
+ {
56
+ name: 'style',
57
+ attributes: [
58
+ {
59
+ name: 'define:vars',
60
+ description: 'Passes serializable server-side variables into a client-side style element',
61
+ references: [
62
+ {
63
+ name: 'Astro documentation',
64
+ url: 'https://docs.astro.build/en/guides/styling/#variables-in-scripts--styles',
65
+ },
66
+ ],
67
+ },
68
+ ],
69
+ },
70
+ ],
71
+ });
72
+ exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-directives', {
73
+ version: 1,
74
+ globalAttributes: [
75
+ {
76
+ name: 'client:load',
77
+ description: 'Start importing the component JS at page load. Hydrate the component when import completes.',
78
+ references: [
79
+ {
80
+ name: 'Astro documentation',
81
+ url: 'https://docs.astro.build/en/core-concepts/component-hydration/#hydrate-interactive-components',
82
+ },
83
+ ],
84
+ },
85
+ {
86
+ name: 'client:idle',
87
+ description: 'Start importing the component JS as soon as main thread is free (uses requestIdleCallback()). Hydrate the component when import completes.',
88
+ references: [
89
+ {
90
+ name: 'Astro documentation',
91
+ url: 'https://docs.astro.build/en/core-concepts/component-hydration/#hydrate-interactive-components',
92
+ },
93
+ ],
94
+ },
95
+ {
96
+ name: 'client:visible',
97
+ description: 'Start importing the component JS as soon as the element enters the viewport (uses IntersectionObserver). Hydrate the component when import completes. Useful for content lower down on the page.',
98
+ references: [
99
+ {
100
+ name: 'Astro documentation',
101
+ url: 'https://docs.astro.build/en/core-concepts/component-hydration/#hydrate-interactive-components',
102
+ },
103
+ ],
104
+ },
105
+ {
106
+ name: 'client:media',
107
+ description: 'Start importing the component JS as soon as the browser matches the given media query (uses matchMedia). Hydrate the component when import completes. Useful for sidebar toggles, or other elements that should only display on mobile or desktop devices.',
108
+ references: [
109
+ {
110
+ name: 'Astro documentation',
111
+ url: 'https://docs.astro.build/en/core-concepts/component-hydration/#hydrate-interactive-components',
112
+ },
113
+ ],
114
+ },
115
+ {
116
+ name: 'client:only',
117
+ description: 'Start importing the component JS at page load and hydrate when the import completes, similar to client:load. The component will be skipped at build time, useful for components that are entirely dependent on client-side APIs. This is best avoided unless absolutely needed, in most cases it is best to render placeholder content on the server and delay any browser API calls until the component hydrates in the browser.',
118
+ references: [
119
+ {
120
+ name: 'Astro documentation',
121
+ url: 'https://docs.astro.build/en/core-concepts/component-hydration/#hydrate-interactive-components',
122
+ },
123
+ ],
124
+ },
125
+ ],
126
+ });
@@ -1,4 +1,4 @@
1
- import { CancellationToken, CompletionContext, DefinitionLink, Diagnostic, Hover, Position, SignatureHelp, SignatureHelpContext, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
1
+ import { CancellationToken, CompletionContext, DefinitionLink, Diagnostic, Hover, Position, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
2
2
  import { ConfigManager } from '../../core/config';
3
3
  import { AstroDocument, DocumentManager } from '../../core/documents';
4
4
  import { AppCompletionItem, AppCompletionList, OnWatchFileChangesParam, Plugin } from '../interfaces';
@@ -11,9 +11,11 @@ export declare class TypeScriptPlugin implements Plugin {
11
11
  private readonly hoverProvider;
12
12
  private readonly signatureHelpProvider;
13
13
  private readonly diagnosticsProvider;
14
+ private readonly documentSymbolsProvider;
14
15
  constructor(docManager: DocumentManager, configManager: ConfigManager, workspaceUris: string[]);
15
16
  doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
16
17
  rename(document: AstroDocument, position: Position, newName: string): Promise<WorkspaceEdit | null>;
18
+ getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
17
19
  getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList<CompletionEntryWithIdentifer> | null>;
18
20
  resolveCompletion(document: AstroDocument, completionItem: AppCompletionItem<CompletionEntryWithIdentifer>): Promise<AppCompletionItem<CompletionEntryWithIdentifer>>;
19
21
  getDefinitions(document: AstroDocument, position: Position): Promise<DefinitionLink[]>;
@@ -35,6 +35,7 @@ const SignatureHelpProvider_1 = require("./features/SignatureHelpProvider");
35
35
  const utils_2 = require("./features/utils");
36
36
  const LanguageServiceManager_1 = require("./LanguageServiceManager");
37
37
  const utils_3 = require("./utils");
38
+ const DocumentSymbolsProvider_1 = require("./features/DocumentSymbolsProvider");
38
39
  class TypeScriptPlugin {
39
40
  constructor(docManager, configManager, workspaceUris) {
40
41
  this.__name = 'typescript';
@@ -44,8 +45,12 @@ class TypeScriptPlugin {
44
45
  this.hoverProvider = new HoverProvider_1.HoverProviderImpl(this.languageServiceManager);
45
46
  this.signatureHelpProvider = new SignatureHelpProvider_1.SignatureHelpProviderImpl(this.languageServiceManager);
46
47
  this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.languageServiceManager);
48
+ this.documentSymbolsProvider = new DocumentSymbolsProvider_1.DocumentSymbolsProviderImpl(this.languageServiceManager);
47
49
  }
48
50
  async doHover(document, position) {
51
+ if (!this.featureEnabled('hover')) {
52
+ return null;
53
+ }
49
54
  return this.hoverProvider.doHover(document, position);
50
55
  }
51
56
  async rename(document, position, newName) {
@@ -71,7 +76,17 @@ class TypeScriptPlugin {
71
76
  });
72
77
  return edit;
73
78
  }
79
+ async getDocumentSymbols(document) {
80
+ if (!this.featureEnabled('documentSymbols')) {
81
+ return [];
82
+ }
83
+ const symbols = await this.documentSymbolsProvider.getDocumentSymbols(document);
84
+ return symbols;
85
+ }
74
86
  async getCompletions(document, position, completionContext) {
87
+ if (!this.featureEnabled('completions')) {
88
+ return null;
89
+ }
75
90
  const completions = await this.completionProvider.getCompletions(document, position, completionContext);
76
91
  return completions;
77
92
  }
@@ -19,7 +19,7 @@ class CompletionsProviderImpl {
19
19
  }
20
20
  async getCompletions(document, position, _completionContext) {
21
21
  var _a;
22
- // TODO: handle inside expression
22
+ // TODO: handle inside expression and script tags
23
23
  if (!(0, utils_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position))) {
24
24
  return null;
25
25
  }
@@ -188,35 +188,14 @@ function isNoMarkdownBlockQuoteWithinMarkdown(sourceFile, boundaries, diagnostic
188
188
  * Some diagnostics have JSX-specific nomenclature. Enhance them for more clarity.
189
189
  */
190
190
  function enhanceIfNecessary(diagnostic) {
191
- if (diagnostic.code === 2786) {
192
- return {
193
- ...diagnostic,
194
- message: 'Type definitions are missing for this Svelte Component. ' +
195
- // eslint-disable-next-line max-len
196
- "It needs a class definition with at least the property '$$prop_def' which should contain a map of input property definitions.\n" +
197
- 'Example:\n' +
198
- ' class ComponentName { $$prop_def: { propertyName: string; } }\n' +
199
- 'If you are using Svelte 3.31+, use SvelteComponentTyped:\n' +
200
- ' import type { SvelteComponentTyped } from "svelte";\n' +
201
- ' class ComponentName extends SvelteComponentTyped<{propertyName: string;}> {}\n\n' +
202
- 'Underlying error:\n' +
203
- diagnostic.message,
204
- };
205
- }
206
- if (diagnostic.code === 2607) {
207
- return {
208
- ...diagnostic,
209
- message: 'Element does not support attributes because ' +
210
- 'type definitions are missing for this Svelte Component or element cannot be used as such.\n\n' +
211
- 'Underlying error:\n' +
212
- diagnostic.message,
213
- };
214
- }
215
- if (diagnostic.code === 1184) {
216
- return {
217
- ...diagnostic,
218
- message: diagnostic.message + '\nIf this is a declare statement, move it into <script context="module">..</script>',
219
- };
191
+ if (diagnostic.code === 2322) {
192
+ // For the rare case where an user might try to put a client directive on something that is not a component
193
+ if (diagnostic.message.includes("Property 'client:") && diagnostic.message.includes("to type 'HTMLProps")) {
194
+ return {
195
+ ...diagnostic,
196
+ message: 'Client directives are only available on framework components',
197
+ };
198
+ }
220
199
  }
221
200
  return diagnostic;
222
201
  }
@@ -0,0 +1,10 @@
1
+ import { SymbolInformation } from 'vscode-languageserver-types';
2
+ import { AstroDocument } from '../../../core/documents';
3
+ import { DocumentSymbolsProvider } from '../../interfaces';
4
+ import { LanguageServiceManager } from '../LanguageServiceManager';
5
+ export declare class DocumentSymbolsProviderImpl implements DocumentSymbolsProvider {
6
+ private languageServiceManager;
7
+ constructor(languageServiceManager: LanguageServiceManager);
8
+ getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
9
+ private collectSymbols;
10
+ }