@tsuzuri-lab/sed-language-server 0.1.1 → 0.2.0
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/README.md +49 -39
- package/package.json +8 -4
- package/src/analysis.js +275 -0
- package/src/server.js +49 -46
- package/vendor/tree-sitter-sed-gnu.wasm +0 -0
- package/vendor/tree-sitter-sed-posix.wasm +0 -0
- package/src/completion.js +0 -148
- package/src/definition.js +0 -46
- package/src/diagnostics.js +0 -1865
- package/src/document-structure.js +0 -774
- package/src/sed-syntax.js +0 -2321
- package/src/syntax-profile.js +0 -99
package/src/completion.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CompletionItemKind,
|
|
3
|
-
InsertTextFormat,
|
|
4
|
-
} from "vscode-languageserver/node";
|
|
5
|
-
import { getDocumentStructure } from "./document-structure.js";
|
|
6
|
-
import {
|
|
7
|
-
commandSpecificationsFor,
|
|
8
|
-
substituteFlagSpecificationsFor,
|
|
9
|
-
} from "./sed-syntax.js";
|
|
10
|
-
import {
|
|
11
|
-
defaultSyntaxProfile,
|
|
12
|
-
requireSyntaxProfile,
|
|
13
|
-
} from "./syntax-profile.js";
|
|
14
|
-
|
|
15
|
-
function plainCompletion(label, kind, documentation) {
|
|
16
|
-
return {
|
|
17
|
-
label,
|
|
18
|
-
kind,
|
|
19
|
-
insertText: label,
|
|
20
|
-
insertTextFormat: InsertTextFormat.PlainText,
|
|
21
|
-
documentation,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const commandCompletionsByProfile = new Map();
|
|
26
|
-
const substituteFlagCompletionsByProfile = new Map();
|
|
27
|
-
|
|
28
|
-
function commandCompletionsFor(syntaxProfile) {
|
|
29
|
-
let completions = commandCompletionsByProfile.get(syntaxProfile);
|
|
30
|
-
if (completions !== undefined) {
|
|
31
|
-
return completions;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
completions = [
|
|
35
|
-
plainCompletion(
|
|
36
|
-
";",
|
|
37
|
-
CompletionItemKind.Keyword,
|
|
38
|
-
"Insert an empty command and begin the next command.",
|
|
39
|
-
),
|
|
40
|
-
...commandSpecificationsFor(syntaxProfile).map(
|
|
41
|
-
({ command, documentation }) =>
|
|
42
|
-
plainCompletion(command, CompletionItemKind.Keyword, documentation),
|
|
43
|
-
),
|
|
44
|
-
];
|
|
45
|
-
commandCompletionsByProfile.set(syntaxProfile, completions);
|
|
46
|
-
return completions;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function substituteFlagCompletionsFor(syntaxProfile) {
|
|
50
|
-
let completions = substituteFlagCompletionsByProfile.get(syntaxProfile);
|
|
51
|
-
if (completions !== undefined) {
|
|
52
|
-
return completions;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
completions = [
|
|
56
|
-
...Array.from({ length: 9 }, (_, index) => {
|
|
57
|
-
const occurrence = String(index + 1);
|
|
58
|
-
return plainCompletion(
|
|
59
|
-
occurrence,
|
|
60
|
-
CompletionItemKind.Value,
|
|
61
|
-
`Replace only occurrence number ${occurrence}.`,
|
|
62
|
-
);
|
|
63
|
-
}),
|
|
64
|
-
...substituteFlagSpecificationsFor(syntaxProfile).map(
|
|
65
|
-
({ flag, documentation }) =>
|
|
66
|
-
plainCompletion(flag, CompletionItemKind.Keyword, documentation),
|
|
67
|
-
),
|
|
68
|
-
];
|
|
69
|
-
substituteFlagCompletionsByProfile.set(syntaxProfile, completions);
|
|
70
|
-
return completions;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export const completionProviderOptions = Object.freeze({});
|
|
74
|
-
|
|
75
|
-
function branchLabelEditRange(document, context, offset) {
|
|
76
|
-
const replacementRange = context.replacementRange ?? {
|
|
77
|
-
startOffset: offset,
|
|
78
|
-
endOffset: offset,
|
|
79
|
-
};
|
|
80
|
-
const startOffset = Math.min(replacementRange.startOffset, offset);
|
|
81
|
-
const endOffset = Math.max(replacementRange.endOffset, offset);
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
start: document.positionAt(startOffset),
|
|
85
|
-
end: document.positionAt(endOffset),
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function createCompletions(
|
|
90
|
-
document,
|
|
91
|
-
position,
|
|
92
|
-
options = defaultSyntaxProfile,
|
|
93
|
-
) {
|
|
94
|
-
const syntaxProfile = requireSyntaxProfile(options);
|
|
95
|
-
const structure = getDocumentStructure(document, syntaxProfile);
|
|
96
|
-
const offset = document.offsetAt(position);
|
|
97
|
-
const context = structure.contextDetailsAt(offset);
|
|
98
|
-
|
|
99
|
-
if (context?.kind === "command") {
|
|
100
|
-
return commandCompletionsFor(syntaxProfile).map((completion) => ({
|
|
101
|
-
...completion,
|
|
102
|
-
}));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (context?.kind === "substitute-flag") {
|
|
106
|
-
return substituteFlagCompletionsFor(syntaxProfile).map((completion) => ({
|
|
107
|
-
...completion,
|
|
108
|
-
}));
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (context?.kind !== "branch-label") {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const names = new Set();
|
|
116
|
-
const completions = [];
|
|
117
|
-
const editRange = branchLabelEditRange(document, context, offset);
|
|
118
|
-
for (const definition of structure.labelDefinitions) {
|
|
119
|
-
if (names.has(definition.name)) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
names.add(definition.name);
|
|
124
|
-
completions.push({
|
|
125
|
-
label: definition.name,
|
|
126
|
-
kind: CompletionItemKind.Reference,
|
|
127
|
-
insertTextFormat: InsertTextFormat.PlainText,
|
|
128
|
-
documentation: "Branch label defined in this document.",
|
|
129
|
-
textEdit: {
|
|
130
|
-
range: editRange,
|
|
131
|
-
newText: definition.name,
|
|
132
|
-
},
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
return completions;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export function createCompletionHandler(
|
|
139
|
-
documents,
|
|
140
|
-
getSyntaxProfile = () => defaultSyntaxProfile,
|
|
141
|
-
) {
|
|
142
|
-
return ({ textDocument, position }) => {
|
|
143
|
-
const document = documents.get(textDocument.uri);
|
|
144
|
-
return document === undefined
|
|
145
|
-
? null
|
|
146
|
-
: createCompletions(document, position, getSyntaxProfile());
|
|
147
|
-
};
|
|
148
|
-
}
|
package/src/definition.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { getDocumentStructure } from "./document-structure.js";
|
|
2
|
-
import { defaultSyntaxProfile } from "./syntax-profile.js";
|
|
3
|
-
|
|
4
|
-
export const definitionProvider = true;
|
|
5
|
-
|
|
6
|
-
function containsCursor(range, offset) {
|
|
7
|
-
return range.startOffset <= offset && offset <= range.endOffset;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function createDefinitionLocations(
|
|
11
|
-
document,
|
|
12
|
-
position,
|
|
13
|
-
syntaxProfile = defaultSyntaxProfile,
|
|
14
|
-
) {
|
|
15
|
-
const structure = getDocumentStructure(document, syntaxProfile);
|
|
16
|
-
const offset = document.offsetAt(position);
|
|
17
|
-
const reference = structure.labelReferences.find(({ range }) =>
|
|
18
|
-
containsCursor(range, offset),
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
if (reference === undefined) {
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return structure.labelDefinitions
|
|
26
|
-
.filter((definition) => definition.name === reference.name)
|
|
27
|
-
.map((definition) => ({
|
|
28
|
-
uri: document.uri,
|
|
29
|
-
range: {
|
|
30
|
-
start: document.positionAt(definition.range.startOffset),
|
|
31
|
-
end: document.positionAt(definition.range.endOffset),
|
|
32
|
-
},
|
|
33
|
-
}));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function createDefinitionHandler(
|
|
37
|
-
documents,
|
|
38
|
-
getSyntaxProfile = () => defaultSyntaxProfile,
|
|
39
|
-
) {
|
|
40
|
-
return ({ textDocument, position }) => {
|
|
41
|
-
const document = documents.get(textDocument.uri);
|
|
42
|
-
return document === undefined
|
|
43
|
-
? null
|
|
44
|
-
: createDefinitionLocations(document, position, getSyntaxProfile());
|
|
45
|
-
};
|
|
46
|
-
}
|