@ripple-ts/language-server 0.3.41 → 0.3.43
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/dist/language-server.js +9 -0
- package/dist/language-server.js.map +1 -0
- package/dist/package.json +1 -0
- package/dist/server.js +111 -0
- package/dist/server.js.map +1 -0
- package/dist/typescriptService-CVPtEiKA.js +21866 -0
- package/dist/typescriptService-CVPtEiKA.js.map +1 -0
- package/package.json +8 -5
- package/CHANGELOG.md +0 -513
- package/bin/language-server.js +0 -5
- package/src/autoInsertPlugin.js +0 -163
- package/src/compileErrorDiagnosticPlugin.js +0 -155
- package/src/completionPlugin.js +0 -508
- package/src/definitionPlugin.js +0 -208
- package/src/documentHighlightPlugin.js +0 -118
- package/src/hoverPlugin.js +0 -146
- package/src/server.js +0 -155
- package/src/typescriptDiagnosticPlugin.js +0 -139
- package/src/typescriptService.js +0 -49
- package/src/utils.js +0 -162
- package/tsconfig.json +0 -17
- package/tsconfig.typecheck.json +0 -7
- package/tsdown.config.js +0 -41
package/src/autoInsertPlugin.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/** @import { LanguageServicePlugin } from '@volar/language-server' */
|
|
2
|
-
|
|
3
|
-
import { getVirtualCode, createLogging, is_ripple_document } from './utils.js';
|
|
4
|
-
|
|
5
|
-
const { log } = createLogging('[Ripple Auto-Insert Plugin]');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* List of HTML void/self-closing elements that don't need closing tags
|
|
9
|
-
* https://developer.mozilla.org/en-US/docs/Glossary/Void_element
|
|
10
|
-
*/
|
|
11
|
-
const VOID_ELEMENTS = new Set([
|
|
12
|
-
'area',
|
|
13
|
-
'base',
|
|
14
|
-
'br',
|
|
15
|
-
'col',
|
|
16
|
-
'command',
|
|
17
|
-
'embed',
|
|
18
|
-
'hr',
|
|
19
|
-
'img',
|
|
20
|
-
'input',
|
|
21
|
-
'keygen',
|
|
22
|
-
'link',
|
|
23
|
-
'meta',
|
|
24
|
-
'param',
|
|
25
|
-
'source',
|
|
26
|
-
'track',
|
|
27
|
-
'wbr',
|
|
28
|
-
]);
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Auto-insert plugin for Ripple
|
|
32
|
-
* Handles auto-closing tags when typing '>' after a tag name
|
|
33
|
-
* @returns {LanguageServicePlugin}
|
|
34
|
-
*/
|
|
35
|
-
export function createAutoInsertPlugin() {
|
|
36
|
-
return {
|
|
37
|
-
name: 'ripple-auto-insert',
|
|
38
|
-
capabilities: {
|
|
39
|
-
autoInsertionProvider: {
|
|
40
|
-
triggerCharacters: ['>'],
|
|
41
|
-
configurationSections: ['ripple.autoClosingTags.enabled'],
|
|
42
|
-
},
|
|
43
|
-
documentOnTypeFormattingProvider: {
|
|
44
|
-
triggerCharacters: ['>'],
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
// leaving context for future use
|
|
48
|
-
create(context) {
|
|
49
|
-
return {
|
|
50
|
-
/**
|
|
51
|
-
* @param {import('vscode-languageserver-textdocument').TextDocument} document
|
|
52
|
-
* @param {import('@volar/language-server').Position} position
|
|
53
|
-
* @param {{ rangeOffset: number; rangeLength: number; text: string }} lastChange
|
|
54
|
-
* @param {import('@volar/language-server').CancellationToken} _token
|
|
55
|
-
* @returns {Promise<string | null>}
|
|
56
|
-
*/
|
|
57
|
-
async provideAutoInsertSnippet(document, position, lastChange, _token) {
|
|
58
|
-
if (!is_ripple_document(document.uri)) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Only checking for '>' insertions
|
|
63
|
-
if (!lastChange.text.endsWith('>')) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const { virtualCode } = getVirtualCode(document, context);
|
|
68
|
-
|
|
69
|
-
if (virtualCode.languageId !== 'ripple') {
|
|
70
|
-
log(`Skipping auto-insert processing in the '${virtualCode.languageId}' context`);
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Map position back to source
|
|
75
|
-
const offset = document.offsetAt(position);
|
|
76
|
-
const mapping = virtualCode.findMappingByGeneratedRange(lastChange.rangeOffset, offset);
|
|
77
|
-
|
|
78
|
-
if (!mapping) {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const sourceOffset = mapping.sourceOffsets[0];
|
|
83
|
-
|
|
84
|
-
// search backwards from sourceOffset to find the line tag
|
|
85
|
-
const sourceCode = virtualCode.originalCode;
|
|
86
|
-
if (sourceCode[sourceOffset - 1] === '/') {
|
|
87
|
-
// self-closing tag '/>'
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let attempts = 0;
|
|
92
|
-
let found = false;
|
|
93
|
-
let i = sourceOffset - 1;
|
|
94
|
-
for (; i >= 0; i--) {
|
|
95
|
-
const char = sourceCode[i];
|
|
96
|
-
if (char === '<') {
|
|
97
|
-
attempts++;
|
|
98
|
-
// Confirm that it's definitely the start of the tag
|
|
99
|
-
// We have `<` and `>` in source maps
|
|
100
|
-
if (virtualCode.findMappingBySourceRange(i, i + 1)) {
|
|
101
|
-
found = true;
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (attempts === 3) {
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (!found) {
|
|
112
|
-
// This shouldn't happen in reality
|
|
113
|
-
log(`No opening tag position found from source position ${sourceOffset}`);
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const line = sourceCode.slice(i, sourceOffset + 1);
|
|
118
|
-
|
|
119
|
-
log('Auto-insert triggered at:', {
|
|
120
|
-
selection: `${position.line}:${position.character}`,
|
|
121
|
-
line,
|
|
122
|
-
change: lastChange,
|
|
123
|
-
sourceOffset,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// Check if we just typed '>' after a tag name
|
|
127
|
-
// Match patterns like: <div> or <Component> but not <div /> or <Component/>
|
|
128
|
-
const tagMatch = line.match(/<([@$\w][\w.-]*)[^>]*?(?<!\/)>$/);
|
|
129
|
-
if (!tagMatch) {
|
|
130
|
-
log('No tag match found');
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const tagName = tagMatch[1];
|
|
135
|
-
log('Tag matched:', tagName);
|
|
136
|
-
|
|
137
|
-
// Don't auto-close void elements (self-closing HTML tags)
|
|
138
|
-
if (VOID_ELEMENTS.has(tagName.toLowerCase())) {
|
|
139
|
-
log('Void element, skipping auto-close:', tagName);
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Check if there's already a closing tag ahead
|
|
144
|
-
const restOfLine = document.getText({
|
|
145
|
-
start: position,
|
|
146
|
-
end: { line: position.line, character: position.character + 100 },
|
|
147
|
-
});
|
|
148
|
-
if (restOfLine.startsWith(`</${tagName}>`)) {
|
|
149
|
-
log('Closing tag already exists, skipping');
|
|
150
|
-
return null;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Insert the closing tag
|
|
154
|
-
const closingTag = `</${tagName}>`;
|
|
155
|
-
log('Inserting closing tag:', closingTag);
|
|
156
|
-
|
|
157
|
-
// Return a snippet with $0 to place cursor between the tags
|
|
158
|
-
return `$0${closingTag}`;
|
|
159
|
-
},
|
|
160
|
-
};
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @import {Diagnostic, Range, LanguageServicePlugin, LanguageServiceContext, Position, Mapper} from '@volar/language-server';
|
|
3
|
-
* @import {TextDocument} from 'vscode-languageserver-textdocument';
|
|
4
|
-
* @import {TSRXVirtualCodeInstance} from '@tsrx/typescript-plugin/src/language.js';
|
|
5
|
-
*/
|
|
6
|
-
/** @import {TSRXCompileError} from '@tsrx/ripple'; */
|
|
7
|
-
|
|
8
|
-
import { getVirtualCode, createLogging } from './utils.js';
|
|
9
|
-
|
|
10
|
-
const { log } = createLogging('[Ripple Compile Error Diagnostic Plugin]');
|
|
11
|
-
import { DiagnosticSeverity } from '@volar/language-server';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @returns {LanguageServicePlugin}
|
|
15
|
-
*/
|
|
16
|
-
export function createCompileErrorDiagnosticPlugin() {
|
|
17
|
-
log('Creating Ripple diagnostic plugin...');
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
name: 'ripple-diagnostics',
|
|
21
|
-
capabilities: {
|
|
22
|
-
diagnosticProvider: {
|
|
23
|
-
interFileDependencies: false,
|
|
24
|
-
workspaceDiagnostics: false,
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
create(/** @type {LanguageServiceContext} */ context) {
|
|
28
|
-
return {
|
|
29
|
-
provideDiagnostics(document, _token) {
|
|
30
|
-
log('Providing Ripple diagnostics for:', document.uri);
|
|
31
|
-
|
|
32
|
-
/** @type {Diagnostic[]} */
|
|
33
|
-
const diagnostics = [];
|
|
34
|
-
const { virtualCode, sourceMap } = getVirtualCode(document, context);
|
|
35
|
-
|
|
36
|
-
if (!virtualCode || virtualCode.languageId !== 'ripple') {
|
|
37
|
-
// skip if it's like embedded css
|
|
38
|
-
return diagnostics;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (!virtualCode.fatalErrors.length && !virtualCode.usageErrors.length) {
|
|
42
|
-
return diagnostics;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
for (const error of [...virtualCode.fatalErrors, ...virtualCode.usageErrors]) {
|
|
46
|
-
const diagnostic = parseCompilationErrorWithDocument(
|
|
47
|
-
error,
|
|
48
|
-
virtualCode,
|
|
49
|
-
sourceMap,
|
|
50
|
-
document,
|
|
51
|
-
);
|
|
52
|
-
diagnostics.push(diagnostic);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
log('Generated', diagnostics.length, 'diagnostics');
|
|
56
|
-
return diagnostics;
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @param {TSRXCompileError} error
|
|
65
|
-
* @param {TSRXVirtualCodeInstance} virtualCode
|
|
66
|
-
* @param {Mapper | undefined} sourceMap
|
|
67
|
-
* @param {TextDocument} document
|
|
68
|
-
* @returns {Diagnostic}
|
|
69
|
-
*/
|
|
70
|
-
function parseCompilationErrorWithDocument(error, virtualCode, sourceMap, document) {
|
|
71
|
-
if (error.type === 'fatal') {
|
|
72
|
-
return {
|
|
73
|
-
severity: DiagnosticSeverity.Error,
|
|
74
|
-
range: get_error_range_from_source(error, document),
|
|
75
|
-
message: error.message,
|
|
76
|
-
source: 'TSRX',
|
|
77
|
-
code: 'tsrx-compile-error',
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** @type {Position | null} */
|
|
82
|
-
let start = null;
|
|
83
|
-
/** @type {Position | null} */
|
|
84
|
-
let end = null;
|
|
85
|
-
|
|
86
|
-
if (error.pos) {
|
|
87
|
-
const start_offset = get_start_offset_from_error(error);
|
|
88
|
-
const end_offset = get_end_offset_from_error(error, start_offset);
|
|
89
|
-
// try to find exact mapping
|
|
90
|
-
// TODO: perhaps it's best to just switch to sourceMap entirely?
|
|
91
|
-
const mapping = virtualCode.findMappingBySourceRange(start_offset, end_offset);
|
|
92
|
-
|
|
93
|
-
if (mapping) {
|
|
94
|
-
start = document.positionAt(mapping.generatedOffsets[0]);
|
|
95
|
-
end = document.positionAt(mapping.generatedOffsets[0] + mapping.generatedLengths[0]);
|
|
96
|
-
} else if (sourceMap) {
|
|
97
|
-
// try to find the match even across multiple mappings
|
|
98
|
-
const result = sourceMap.toGeneratedRange(start_offset, end_offset, true).next().value;
|
|
99
|
-
|
|
100
|
-
if (result) {
|
|
101
|
-
const [gen_start_offset, gen_end_offset] = result;
|
|
102
|
-
start = document.positionAt(gen_start_offset);
|
|
103
|
-
end = document.positionAt(gen_end_offset);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (!start || !end) {
|
|
109
|
-
start = { line: 0, character: 0 };
|
|
110
|
-
end = { line: 0, character: 1 };
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
severity: DiagnosticSeverity.Error,
|
|
115
|
-
range: { start, end },
|
|
116
|
-
message: error.message,
|
|
117
|
-
source: 'TSRX',
|
|
118
|
-
code: 'tsrx-usage-error',
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @param {TSRXCompileError} error
|
|
124
|
-
* @param {TextDocument} document
|
|
125
|
-
* @returns {Range}
|
|
126
|
-
*/
|
|
127
|
-
function get_error_range_from_source(error, document) {
|
|
128
|
-
const start_offset = get_start_offset_from_error(error);
|
|
129
|
-
return {
|
|
130
|
-
start: document.positionAt(start_offset),
|
|
131
|
-
end: document.positionAt(get_end_offset_from_error(error, start_offset)),
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* @param {TSRXCompileError} error
|
|
137
|
-
* @param {number} [start_offset]
|
|
138
|
-
* @returns {number}
|
|
139
|
-
*/
|
|
140
|
-
function get_end_offset_from_error(error, start_offset) {
|
|
141
|
-
start_offset = start_offset ?? get_start_offset_from_error(error);
|
|
142
|
-
return error.end
|
|
143
|
-
? error.end
|
|
144
|
-
: error.raisedAt && (error.raisedAt ?? 0) > start_offset
|
|
145
|
-
? error.raisedAt
|
|
146
|
-
: start_offset + 1;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* @param {TSRXCompileError} error
|
|
151
|
-
* @returns {number}
|
|
152
|
-
*/
|
|
153
|
-
function get_start_offset_from_error(error) {
|
|
154
|
-
return error.pos ?? 0;
|
|
155
|
-
}
|