Skip to content

Commit 8f3280f

Browse files
committed
feat: big feature! Args snippets for simple arrow callbacks (enabled by default).
Feature is experimental and doesn't support aliases for now
1 parent 0765633 commit 8f3280f

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

src/configurationType.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,9 @@ export type Configuration = {
153153
* @default false
154154
*/
155155
changeDtsFileDefinitionToJs: boolean
156+
/**
157+
* Experimental. Also includes optional args
158+
* @default true
159+
*/
160+
enableMethodSnippets: boolean
156161
}

src/extension.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as vscode from 'vscode'
2+
import { getActiveRegularEditor } from '@zardoy/vscode-utils'
3+
import {} from 'vscode-framework'
24

35
export const activate = async () => {
46
const tsExtension = vscode.extensions.getExtension('vscode.typescript-language-features')
@@ -21,4 +23,34 @@ export const activate = async () => {
2123
if (affectsConfiguration(process.env.IDS_PREFIX!)) syncConfig()
2224
})
2325
syncConfig()
26+
27+
api.onCompletionAccepted((item: vscode.CompletionItem & { document: vscode.TextDocument }) => {
28+
const enableMethodSnippets = vscode.workspace.getConfiguration(process.env.IDS_PREFIX, item.document).get('enableMethodSnippets')
29+
const { documentation = '' } = item
30+
const documentationString = documentation instanceof vscode.MarkdownString ? documentation.value : documentation
31+
const insertFuncArgs = /<!-- insert-func: (.*)-->/.exec(documentationString)?.[1]
32+
if (enableMethodSnippets && insertFuncArgs !== undefined) {
33+
const editor = getActiveRegularEditor()!
34+
const startPos = editor.selection.start
35+
const nextSymbol = editor.document.getText(new vscode.Range(startPos, startPos.translate(0, 1)))
36+
if (nextSymbol !== '(') {
37+
const snippet = new vscode.SnippetString('')
38+
snippet.appendText('(')
39+
const args = insertFuncArgs.split(',')
40+
for (const [i, arg] of args.entries()) {
41+
if (!arg) continue
42+
snippet.appendPlaceholder(arg)
43+
if (i !== args.length - 1) snippet.appendText(', ')
44+
}
45+
46+
snippet.appendText(')')
47+
void editor.insertSnippet(snippet, undefined, {
48+
undoStopAfter: false,
49+
undoStopBefore: false,
50+
})
51+
if (vscode.workspace.getConfiguration('editor.parameterHints').get('enabled'))
52+
void vscode.commands.executeCommand('editor.action.triggerParameterHints')
53+
}
54+
}
55+
})
2456
}

typescript/src/index.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import type { Configuration } from '../../src/configurationType'
66
import _ from 'lodash'
77
import { GetConfig } from './types'
88
import { getCompletionsAtPosition, PrevCompletionMap } from './completionsAtPosition'
9+
import { CompletionEntry } from 'typescript/lib/tsserverlibrary'
10+
import { getParameterListParts } from './completionGetMethodParameters'
11+
import { oneOf } from '@zardoy/utils'
912

1013
const thisPluginMarker = Symbol('__essentialPluginsMarker__')
1114

@@ -83,6 +86,35 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t
8386
data,
8487
)
8588
if (!prior) return
89+
if (c('enableMethodSnippets') && oneOf(prior.kind as string, ts.ScriptElementKind.constElement, 'property')) {
90+
const punctuationIndex = prior.displayParts.findIndex(({ kind }) => kind === 'punctuation')
91+
if (punctuationIndex !== 1) {
92+
const isParsableMethod = prior.displayParts
93+
// next is space
94+
.slice(punctuationIndex + 2)
95+
.map(({ text }) => text)
96+
.join('')
97+
.match(/\((.*)\) => /)
98+
if (isParsableMethod) {
99+
let firstArgMeet = false
100+
const args = prior.displayParts
101+
.filter(({ kind }, index, array) => {
102+
if (kind !== 'parameterName') return false
103+
if (array[index - 1]!.text === '(') {
104+
if (!firstArgMeet) {
105+
// bad parsing, as doesn't take second and more args
106+
firstArgMeet = true
107+
return true
108+
}
109+
return false
110+
}
111+
return true
112+
})
113+
.map(({ text }) => text)
114+
prior.documentation = [...(prior.documentation ?? []), { kind: 'text', text: `<!-- insert-func: ${args.join(',')}-->` }]
115+
}
116+
}
117+
}
86118
// if (prior.kind === typescript.ScriptElementKind.constElement && prior.displayParts.map(item => item.text).join('').match(/: \(.+\) => .+/)) prior.codeActions?.push({
87119
// description: '',
88120
// changes: []

0 commit comments

Comments
 (0)