-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.ts
111 lines (100 loc) · 3.25 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import type ts from "typescript";
function init(modules: {
typescript: typeof import("typescript/lib/tsserverlibrary");
}) {
const ts = modules.typescript;
function create(info: ts.server.PluginCreateInfo) {
const moveUpPatterns: string[] = info.config.moveUpPatterns ?? [
"@/",
"\\.{1,2}/", // matches `../` or `./`
];
const moveDownPatterns: string[] = info.config.moveDownPatterns ?? [];
const moveUpRegexes: RegExp[] = moveUpPatterns.map(
(pattern) => new RegExp(pattern),
);
const moveDownRegexes: RegExp[] = moveDownPatterns.map(
(pattern) => new RegExp(pattern),
);
// Diagnostic logging
info.project.projectService.logger.info(
"TSSortImportSuggestionsPlugin: Started",
);
// Set up decorator object
const proxy: ts.LanguageService = Object.create(null);
for (let k of Object.keys(info.languageService) as Array<
keyof ts.LanguageService
>) {
const x = info.languageService[k]!;
// @ts-expect-error - JS runtime trickery which is tricky to type tersely
proxy[k] = (...args: Array<{}>) => x.apply(info.languageService, args);
}
// Override completions
proxy.getCompletionsAtPosition = (
fileName,
position,
options,
...restArgs
) => {
const prior = info.languageService.getCompletionsAtPosition(
fileName,
position,
options,
...restArgs,
);
if (!prior) return;
prior.entries = prior.entries.map((e) => {
const newEntry = { ...e };
const source = e.source;
if (source) {
if (moveUpRegexes.some((re) => re.test(source))) {
// Move this item to the bottom of its previous group, e.g. sortText: `12` -> `111`
newEntry.sortText =
e.sortText.slice(0, -1) +
String.fromCharCode(e.sortText.slice(-1).charCodeAt(0) - 1) +
"1";
} else if (moveDownRegexes.some((re) => re.test(source))) {
// Move this item to the bottom of its group
// Ref: https://github.com/microsoft/TypeScript/blob/60f93aa83ae644092ace6d729d0f10c42715292f/src/services/completions.ts#L406-L430
newEntry.sortText = newEntry.sortText + "1";
}
}
return newEntry;
});
return prior;
};
proxy.getCodeFixesAtPosition = (
fileName: string,
start: number,
end: number,
errorCodes: readonly number[],
formatOptions: ts.FormatCodeSettings,
preferences: ts.UserPreferences,
) => {
const prior = info.languageService.getCodeFixesAtPosition(
fileName,
start,
end,
errorCodes,
formatOptions,
preferences,
);
const newFixes = [...prior].sort((a, b) => {
const aSort = moveUpRegexes.some((re) => re.test(a.description))
? -1
: moveDownRegexes.some((re) => re.test(a.description))
? 1
: 0;
const bSort = moveUpRegexes.some((re) => re.test(b.description))
? -1
: moveDownRegexes.some((re) => re.test(b.description))
? 1
: 0;
return aSort - bSort;
});
return newFixes;
};
return proxy;
}
return { create };
}
export = init;