Skip to content

Commit 4870127

Browse files
committed
feat: enableFileDefinitions (must have to enable, disabled by default) useful for path.join
feat: `removeModuleFileDefinitions` (disabled by default, enable if you need it) removes TS module declaration e.g. *.css
1 parent a12f1cd commit 4870127

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

src/configurationType.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ export type Configuration = {
123123
* @default true
124124
* */
125125
// 'importUpDefinition.enable': boolean
126+
/**
127+
* Remove definitions for TS module declarations e.g. *.css
128+
* Enable it if your first definition that receives focus is TS module declaration instead of target file itself
129+
* Might be really really useful in some cases
130+
* @default false
131+
*/
132+
removeModuleFileDefinitions: boolean
133+
/**
134+
* Enable definitions for strings that appears to be paths (relatively to file)
135+
* Also must have and should be enabled if you work with path.join a lot
136+
* @default false
137+
*/
138+
enableFileDefinitions: boolean
126139
/**
127140
* @default true
128141
* */

typescript/src/definitions.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
1+
import { join } from 'path'
12
import { GetConfig } from './types'
3+
import { findChildContainingExactPosition } from './utils'
24

35
export default (proxy: ts.LanguageService, info: ts.server.PluginCreateInfo, c: GetConfig) => {
46
proxy.getDefinitionAndBoundSpan = (fileName, position) => {
57
const prior = info.languageService.getDefinitionAndBoundSpan(fileName, position)
6-
if (!prior) return
8+
if (!prior) {
9+
if (c('enableFileDefinitions')) {
10+
const sourceFile = info.languageService.getProgram()!.getSourceFile(fileName)!
11+
const node = findChildContainingExactPosition(sourceFile, position)
12+
if (node && ts.isStringLiteral(node) && ['./', '../'].some(str => node.text.startsWith(str))) {
13+
const file = join(fileName, '..', node.text)
14+
if (info.languageServiceHost.fileExists?.(file)) {
15+
const start = node.pos + node.getLeadingTriviaWidth() + 1 // + 1 for quote
16+
const textSpan = {
17+
start,
18+
length: node.end - start - 1,
19+
}
20+
return {
21+
textSpan,
22+
definitions: [
23+
{
24+
containerKind: undefined as any,
25+
containerName: '',
26+
name: '',
27+
fileName: file,
28+
textSpan: { start: 0, length: 0 },
29+
kind: ts.ScriptElementKind.moduleElement,
30+
contextSpan: { start: 0, length: 0 },
31+
},
32+
],
33+
}
34+
}
35+
}
36+
}
37+
return
38+
}
739
if (__WEB__) {
840
// let extension handle it
941
// TODO failedAliasResolution
@@ -31,7 +63,18 @@ export default (proxy: ts.LanguageService, info: ts.server.PluginCreateInfo, c:
3163
const isFcDef = fileName.endsWith('node_modules/@types/react/index.d.ts') && containerName === 'FunctionComponent'
3264
return !isFcDef
3365
})
66+
// 11
3467
}
68+
69+
if (
70+
c('removeModuleFileDefinitions') &&
71+
prior.definitions?.length === 1 &&
72+
firstDef.kind === ts.ScriptElementKind.moduleElement &&
73+
firstDef.name.slice(1, -1).startsWith('*.')
74+
) {
75+
return
76+
}
77+
3578
return prior
3679
}
3780
}

0 commit comments

Comments
 (0)