Skip to content

Commit f11a40d

Browse files
authored
feat: provide definition for catalogs (#78)
* feat: provide definition for catalogs * fix * fix: normalize catalog names
1 parent 0db276a commit f11a40d

File tree

7 files changed

+59
-7
lines changed

7 files changed

+59
-7
lines changed

playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"ofetch": "^2.0.0-alpha.1",
1515
"array-includes": "latest",
1616
"axios": "",
17-
"is-number": "catalog:",
17+
"is-number": "catalog:dev",
1818
"lodash": "catalog:"
1919
}
2020
}

src/core/extractors/yaml.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { BaseExtractor, DependencyInfo, OffsetRange, WorkspaceCatalogExtractor, WorkspaceCatalogInfo, YamlNode } from '#types/extractor'
22
import type { Pair, Scalar, YAMLMap } from 'yaml'
3+
import { normalizeCatalogName } from '#utils/dependency'
34
import { isMap, isPair, isScalar, parseDocument } from 'yaml'
45

56
const CATALOG_SECTION = 'catalog'
@@ -48,7 +49,7 @@ export class YamlExtractor implements WorkspaceCatalogExtractor, BaseExtractor<Y
4849

4950
#traverseCatalogs(root: YAMLMap, callback: CatalogEntryVisitor): boolean {
5051
const catalog = root.items.find((i) => isScalar(i.key) && i.key.value === CATALOG_SECTION)
51-
if (this.#traverseCatalog(catalog, { category: 'catalog' }, callback))
52+
if (this.#traverseCatalog(catalog, { category: 'catalog', categoryName: '' }, callback))
5253
return true
5354

5455
const catalogs = root.items.find((i) => isScalar(i.key) && i.key.value === CATALOGS_SECTION)
@@ -92,7 +93,7 @@ export class YamlExtractor implements WorkspaceCatalogExtractor, BaseExtractor<Y
9293
const catalogs: Record<string, Record<string, string>> = {}
9394

9495
for (const dependency of dependencies) {
95-
const categoryName = dependency.category === 'catalog' ? 'default' : dependency.categoryName || 'default'
96+
const categoryName = normalizeCatalogName(dependency.categoryName!)
9697
catalogs[categoryName] ??= {}
9798
catalogs[categoryName][dependency.rawName] = dependency.rawSpec
9899
}

src/core/workspace.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ async function getPackageManager(uri: Uri): Promise<PackageManager> {
3838
class WorkspaceContext {
3939
folder: WorkspaceFolder
4040
packageManager: PackageManager = 'npm'
41+
workspaceFileUri?: Uri
4142
#catalogs?: PromiseWithResolvers<CatalogsInfo | undefined>
4243
#invalidatedPaths = new Set<string>()
4344

@@ -61,10 +62,10 @@ class WorkspaceContext {
6162
if (this.packageManager !== 'npm') {
6263
this.#catalogs = Promise.withResolvers()
6364
const workspaceFilename = workspaceFileMapping[this.packageManager]
64-
const workspaceFile = Uri.joinPath(this.folder.uri, workspaceFilename)
65+
this.workspaceFileUri = Uri.joinPath(this.folder.uri, workspaceFilename)
6566
this.#catalogs.resolve(
66-
await accessOk(workspaceFile)
67-
? (await this.loadWorkspaceCatalogInfo(workspaceFile))?.catalogs
67+
await accessOk(this.workspaceFileUri)
68+
? (await this.loadWorkspaceCatalogInfo(this.workspaceFileUri))?.catalogs
6869
: undefined,
6970
)
7071
}

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { commands, displayName, version } from './generated-meta'
66
import { useCodeActions } from './providers/code-actions'
77
import { useCompletionItem } from './providers/completion-item'
88
import { useDecorators } from './providers/decorators'
9+
import { useDefinition } from './providers/definition'
910
import { useDiagnostics } from './providers/diagnostics'
1011
import { useDocumentLink } from './providers/document-link'
1112
import { useHover } from './providers/hover'
@@ -22,6 +23,7 @@ export const { activate, deactivate } = defineExtension(() => {
2223
useDecorators()
2324
useCodeActions()
2425
useDocumentLink()
26+
useDefinition()
2527

2628
useCommands({
2729
[commands.openInBrowser]: openInBrowser,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { DefinitionProvider, Position, TextDocument } from 'vscode'
2+
import { getResolvedDependencyByOffset, getWorkspaceContext } from '#core/workspace'
3+
import { offsetRangeToRange } from '#utils/ast'
4+
import { normalizeCatalogName } from '#utils/dependency'
5+
import { Location, workspace } from 'vscode'
6+
7+
export class CatalogDefinitionProvider implements DefinitionProvider {
8+
async provideDefinition(document: TextDocument, position: Position) {
9+
const offset = document.offsetAt(position)
10+
const info = await getResolvedDependencyByOffset(document.uri, offset)
11+
if (!info?.rawSpec.startsWith('catalog:'))
12+
return
13+
14+
const ctx = await getWorkspaceContext(document.uri)
15+
if (!ctx?.workspaceFileUri)
16+
return
17+
18+
const catalogInfo = await ctx.loadWorkspaceCatalogInfo(ctx.workspaceFileUri)
19+
if (!catalogInfo)
20+
return
21+
22+
const target = catalogInfo.dependencies.find(
23+
(dep) =>
24+
dep.rawName === info.resolvedName
25+
&& dep.categoryName != null && info.categoryName != null
26+
&& normalizeCatalogName(dep.categoryName) === normalizeCatalogName(info.categoryName),
27+
)
28+
if (!target)
29+
return
30+
31+
const workspaceDocument = await workspace.openTextDocument(ctx.workspaceFileUri)
32+
33+
return new Location(
34+
ctx.workspaceFileUri,
35+
offsetRangeToRange(workspaceDocument, target.specRange),
36+
)
37+
}
38+
}

src/providers/definition/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { PACKAGE_JSON_BASENAME } from '#constants'
2+
import { useDisposable } from 'reactive-vscode'
3+
import { languages } from 'vscode'
4+
import { CatalogDefinitionProvider } from './catalog'
5+
6+
export function useDefinition() {
7+
useDisposable(
8+
languages.registerDefinitionProvider({ pattern: `**/${PACKAGE_JSON_BASENAME}` }, new CatalogDefinitionProvider()),
9+
)
10+
}

src/utils/dependency.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const DEFAULT_CATALOG_NAME = 'default'
1111
const GIT_PATTERN = /^(?:git\+|git:\/\/|github:|gitlab:|bitbucket:|ssh:\/\/git@)/i
1212
const HTTP_PATTERN = /^https?:/i
1313

14-
function normalizeCatalogName(name: string): string {
14+
export function normalizeCatalogName(name: string): string {
1515
return name.trim() || DEFAULT_CATALOG_NAME
1616
}
1717

0 commit comments

Comments
 (0)