Skip to content

Commit 2f5fc91

Browse files
committed
divide links into its own file.
feat: links: support concurruntly pattern
1 parent 02e227c commit 2f5fc91

File tree

3 files changed

+75
-71
lines changed

3 files changed

+75
-71
lines changed

src/extension.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ import { startMainNpmScript } from './commands/startMainNpmScript'
1515
import { startNpmScript } from './commands/startNpmScript'
1616
import { registerClipboardDetection } from './core/clipboardDetection'
1717
import { activateStatusbar } from './features/statusbar'
18-
import { registerPackageJsonAutoComplete } from './packageJsonComplete'
18+
import { registerPackageJsonCompletions } from './packageJsonComplete'
1919
import { startSpecialCommand } from './commands/startSpecialCommand'
2020
import { registerRunOnSave } from './features/runOnSave'
2121
import openWorkspacePackageJson from './commands/openWorkspacePackageJson'
22+
import { registerPackageJsonLinks } from './packageJsonLinks'
2223

2324
// TODO command for package diff
2425

@@ -49,7 +50,8 @@ export const activate = () => {
4950
registerOpenPackageAtCommands()
5051
registerCodeActions()
5152
registerClipboardDetection()
52-
registerPackageJsonAutoComplete()
53+
registerPackageJsonCompletions()
54+
registerPackageJsonLinks()
5355
activateStatusbar()
5456
registerRunOnSave()
5557
openWorkspacePackageJson()

src/packageJsonComplete.ts

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,12 @@ import picomatch from 'picomatch/posix'
99
import { compact } from '@zardoy/utils'
1010
import { getBinCommands, runBinCommand } from './commands/runBinCommand'
1111

12-
const selector = { language: 'json', pattern: '**/package.json' }
13-
export const registerPackageJsonAutoComplete = () => {
14-
registerCompletions()
15-
registerLinks()
16-
}
12+
export const packageJsonSelector = { language: 'json', pattern: '**/package.json' }
1713

18-
const registerCompletions = () => {
14+
export const registerPackageJsonCompletions = () => {
1915
if (!getExtensionSetting('packageJsonIntellisense')) return
2016
vscode.languages.registerCompletionItemProvider(
21-
selector,
17+
packageJsonSelector,
2218
{
2319
async provideCompletionItems(document, position, token, context) {
2420
if (!document.uri.path.endsWith('package.json')) return []
@@ -121,67 +117,6 @@ const registerCompletions = () => {
121117
)
122118
}
123119

124-
const registerLinks = () => {
125-
vscode.languages.registerDocumentLinkProvider(selector, {
126-
provideDocumentLinks(document, token) {
127-
const root = parseTree(document.getText())!
128-
const scriptsRootNode = findNodeAtLocation(root, ['scripts'])
129-
const scriptsNodes = scriptsRootNode?.children
130-
const links: vscode.DocumentLink[] = []
131-
const nodeObjectMap = (nodes: Node[], type: 'prop' | 'value') => {
132-
const indexGetter = type === 'prop' ? 0 : 1
133-
return compact(nodes.map(value => value.type === 'property' && value.children![indexGetter]))
134-
}
135-
136-
// #region scripts links
137-
if (getExtensionSetting('packageJsonLinks') && scriptsNodes)
138-
for (const scriptNode of nodeObjectMap(scriptsNodes, 'value')) {
139-
const script = getNodeValue(scriptNode)
140-
let match: RegExpExecArray | null
141-
while ((match = scriptLinksCommandRegex.exec(script))) {
142-
const scriptRefName = match.groups!.NAME!
143-
// if (!(scriptRefName in scriptsObject)) continue
144-
const targetScriptNode = scriptsNodes.find(node => node.children![0]!.value === scriptRefName)?.children?.[1]
145-
if (!targetScriptNode) continue
146-
const getNodeStringStart = (node: Node) => node.offset + 1
147-
const startOffset = getNodeStringStart(scriptNode) + match.index + match[1]!.length
148-
const positions = [startOffset, startOffset + scriptRefName.length].map(offset => document.positionAt(offset)) as [
149-
vscode.Position,
150-
vscode.Position,
151-
]
152-
const { line: targetScriptLine, character: targetScriptCharacter } = document.positionAt(getNodeStringStart(targetScriptNode))
153-
const fragment = `L${targetScriptLine + 1},${targetScriptCharacter + 1}`
154-
links.push({
155-
range: new vscode.Range(...positions),
156-
tooltip: 'Reveal script',
157-
target: document.uri.with({ fragment }),
158-
})
159-
}
160-
161-
scriptLinksCommandRegex.lastIndex = 0
162-
}
163-
// #endregion
164-
165-
if (getExtensionSetting('packageJsonScriptNameLink') && scriptsNodes)
166-
for (const scriptNode of nodeObjectMap(scriptsNodes, 'prop')) {
167-
const startOffset = scriptNode.offset + 1
168-
const scriptName: string = scriptNode.value
169-
const positions = [startOffset, startOffset + scriptName.length].map(offset => document.positionAt(offset)) as [
170-
vscode.Position,
171-
vscode.Position,
172-
]
173-
links.push({
174-
range: new vscode.Range(...positions),
175-
tooltip: 'Run Script',
176-
target: vscode.Uri.parse(`command:${getExtensionCommandId('runNpmScript')}?${JSON.stringify(scriptName)}`),
177-
})
178-
}
179-
180-
return links
181-
},
182-
})
183-
}
184-
185120
const listFilesCompletions = async (baseDocument: vscode.TextDocument, stringContents: string, completionRange: vscode.Range, glob = '*') => {
186121
const folderPath = stringContents.split('/').slice(0, -1).join('/')
187122
const filesList = await vscode.workspace.fs.readDirectory(Utils.joinPath(baseDocument.uri, '..', folderPath))
@@ -210,4 +145,3 @@ const pathAutoComplete = {
210145
}
211146

212147
const scriptCompletionCommandRegex = /^(pnpm|yarn)|(pnpm|yarn|npm) run$/
213-
const scriptLinksCommandRegex = /((^|&&)\s?((pnpm|yarn)|(pnpm|yarn|npm) run) )(?<NAME>[A-z\d-]+)/g

src/packageJsonLinks.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { parseTree, findNodeAtLocation, getNodeValue, Node } from 'jsonc-parser'
2+
import { compact } from 'lodash'
3+
import * as vscode from 'vscode'
4+
import { getExtensionSetting, getExtensionCommandId } from 'vscode-framework'
5+
import { packageJsonSelector } from './packageJsonComplete'
6+
7+
const scriptLinksCommandRegex = /((^|&&|")\s?((pnpm|yarn)|(pnpm|yarn|npm) run) )(?<NAME>[A-z\d-]+)/g
8+
9+
export const registerPackageJsonLinks = () => {
10+
vscode.languages.registerDocumentLinkProvider(packageJsonSelector, {
11+
provideDocumentLinks(document, token) {
12+
const root = parseTree(document.getText())!
13+
const scriptsRootNode = findNodeAtLocation(root, ['scripts'])
14+
const scriptsNodes = scriptsRootNode?.children
15+
const links: vscode.DocumentLink[] = []
16+
const nodeObjectMap = (nodes: Node[], type: 'prop' | 'value') => {
17+
const indexGetter = type === 'prop' ? 0 : 1
18+
return compact(nodes.map(value => value.type === 'property' && value.children![indexGetter]))
19+
}
20+
21+
// #region scripts links
22+
if (getExtensionSetting('packageJsonLinks') && scriptsNodes)
23+
for (const scriptNode of nodeObjectMap(scriptsNodes, 'value')) {
24+
const script = getNodeValue(scriptNode)
25+
let match: RegExpExecArray | null
26+
while ((match = scriptLinksCommandRegex.exec(script))) {
27+
const scriptRefName = match.groups!.NAME!
28+
// if (!(scriptRefName in scriptsObject)) continue
29+
const targetScriptNode = scriptsNodes.find(node => node.children![0]!.value === scriptRefName)?.children?.[1]
30+
if (!targetScriptNode) continue
31+
const getNodeStringStart = (node: Node) => node.offset + 1
32+
const startOffset = getNodeStringStart(scriptNode) + match.index + match[1]!.length
33+
const positions = [startOffset, startOffset + scriptRefName.length].map(offset => document.positionAt(offset)) as [
34+
vscode.Position,
35+
vscode.Position,
36+
]
37+
const { line: targetScriptLine, character: targetScriptCharacter } = document.positionAt(getNodeStringStart(targetScriptNode))
38+
const fragment = `L${targetScriptLine + 1},${targetScriptCharacter + 1}`
39+
links.push({
40+
range: new vscode.Range(...positions),
41+
tooltip: 'Reveal script',
42+
target: document.uri.with({ fragment }),
43+
})
44+
}
45+
46+
scriptLinksCommandRegex.lastIndex = 0
47+
}
48+
// #endregion
49+
50+
if (getExtensionSetting('packageJsonScriptNameLink') && scriptsNodes)
51+
for (const scriptNode of nodeObjectMap(scriptsNodes, 'prop')) {
52+
const startOffset = scriptNode.offset + 1
53+
const scriptName: string = scriptNode.value
54+
const positions = [startOffset, startOffset + scriptName.length].map(offset => document.positionAt(offset)) as [
55+
vscode.Position,
56+
vscode.Position,
57+
]
58+
links.push({
59+
range: new vscode.Range(...positions),
60+
tooltip: 'Run Script',
61+
target: vscode.Uri.parse(`command:${getExtensionCommandId('runNpmScript')}?${JSON.stringify(scriptName)}`),
62+
})
63+
}
64+
65+
return links
66+
},
67+
})
68+
}

0 commit comments

Comments
 (0)