Skip to content

Commit 6cb12ba

Browse files
committed
fix(keywordsInsertText): when return is accepted and then Enter or ; typed remove redundant space
fixes #57
1 parent 3046778 commit 6cb12ba

File tree

4 files changed

+106
-38
lines changed

4 files changed

+106
-38
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
"@vscode/emmet-helper": "^2.8.4",
7575
"@vscode/test-electron": "^2.1.5",
7676
"@zardoy/utils": "^0.0.9",
77-
"@zardoy/vscode-utils": "^0.0.41",
77+
"@zardoy/vscode-utils": "^0.0.45",
7878
"chai": "^4.3.6",
7979
"chokidar": "^3.5.3",
8080
"chokidar-cli": "^3.0.0",

pnpm-lock.yaml

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/extension.ts

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-require-imports */
22
import * as vscode from 'vscode'
33
import { defaultJsSupersetLangs } from '@zardoy/vscode-utils/build/langs'
4-
import { getActiveRegularEditor } from '@zardoy/vscode-utils'
54
import { extensionCtx, getExtensionSettingId } from 'vscode-framework'
65
import { pickObj } from '@zardoy/utils'
76
import { Configuration } from './configurationType'
@@ -12,6 +11,7 @@ import experimentalPostfixes from './experimentalPostfixes'
1211
import migrateSettings from './migrateSettings'
1312
import figIntegration from './figIntegration'
1413
import apiCommands from './apiCommands'
14+
import onCompletionAccepted from './onCompletionAccepted'
1515

1616
export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted }) => {
1717
let webWaitingForConfigSync = false
@@ -46,38 +46,7 @@ export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted
4646
})
4747
syncConfig()
4848

49-
tsApi.onCompletionAccepted((item: vscode.CompletionItem & { document: vscode.TextDocument }) => {
50-
const enableMethodSnippets = vscode.workspace.getConfiguration(process.env.IDS_PREFIX, item.document).get('enableMethodSnippets')
51-
const { documentation = '' } = item
52-
const documentationString = documentation instanceof vscode.MarkdownString ? documentation.value : documentation
53-
const insertFuncArgs = /<!-- insert-func: (.*)-->/.exec(documentationString)?.[1]
54-
console.debug('insertFuncArgs', insertFuncArgs)
55-
if (enableMethodSnippets && insertFuncArgs !== undefined) {
56-
const editor = getActiveRegularEditor()!
57-
const startPos = editor.selection.start
58-
const nextSymbol = editor.document.getText(new vscode.Range(startPos, startPos.translate(0, 1)))
59-
if (!['(', '.'].includes(nextSymbol)) {
60-
const snippet = new vscode.SnippetString('')
61-
snippet.appendText('(')
62-
const args = insertFuncArgs.split(',')
63-
for (let [i, arg] of args.entries()) {
64-
if (!arg) continue
65-
// skip empty, but add tabstops if we explicitly want it!
66-
if (arg === ' ') arg = ''
67-
snippet.appendPlaceholder(arg)
68-
if (i !== args.length - 1) snippet.appendText(', ')
69-
}
70-
71-
snippet.appendText(')')
72-
void editor.insertSnippet(snippet, undefined, {
73-
undoStopAfter: false,
74-
undoStopBefore: false,
75-
})
76-
if (vscode.workspace.getConfiguration('editor.parameterHints').get('enabled'))
77-
void vscode.commands.executeCommand('editor.action.triggerParameterHints')
78-
}
79-
}
80-
})
49+
onCompletionAccepted(tsApi)
8150

8251
if (process.env.PLATFORM === 'web') {
8352
const possiblySyncConfig = async () => {

src/onCompletionAccepted.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import * as vscode from 'vscode'
2+
import { getActiveRegularEditor } from '@zardoy/vscode-utils'
3+
import { watchExtensionSettings } from '@zardoy/vscode-utils/build/settings'
4+
import { getExtensionSetting, Settings } from 'vscode-framework'
5+
import { oneOf } from '@zardoy/utils'
6+
7+
export default (tsApi: { onCompletionAccepted }) => {
8+
let justAcceptedReturnKeywordSuggestion = false
9+
10+
tsApi.onCompletionAccepted((item: vscode.CompletionItem & { document: vscode.TextDocument }) => {
11+
const enableMethodSnippets = vscode.workspace.getConfiguration(process.env.IDS_PREFIX, item.document).get('enableMethodSnippets')
12+
const { insertText, documentation = '', kind } = item
13+
if (kind === vscode.CompletionItemKind.Keyword && insertText === 'return ') {
14+
justAcceptedReturnKeywordSuggestion = true
15+
}
16+
17+
const documentationString = documentation instanceof vscode.MarkdownString ? documentation.value : documentation
18+
const insertFuncArgs = /<!-- insert-func: (.*)-->/.exec(documentationString)?.[1]
19+
console.debug('insertFuncArgs', insertFuncArgs)
20+
if (enableMethodSnippets && insertFuncArgs !== undefined) {
21+
const editor = getActiveRegularEditor()!
22+
const startPos = editor.selection.start
23+
const nextSymbol = editor.document.getText(new vscode.Range(startPos, startPos.translate(0, 1)))
24+
if (!['(', '.'].includes(nextSymbol)) {
25+
const snippet = new vscode.SnippetString('')
26+
snippet.appendText('(')
27+
const args = insertFuncArgs.split(',')
28+
for (let [i, arg] of args.entries()) {
29+
if (!arg) continue
30+
// skip empty, but add tabstops if we explicitly want it!
31+
if (arg === ' ') arg = ''
32+
snippet.appendPlaceholder(arg)
33+
if (i !== args.length - 1) snippet.appendText(', ')
34+
}
35+
36+
snippet.appendText(')')
37+
void editor.insertSnippet(snippet, undefined, {
38+
undoStopAfter: false,
39+
undoStopBefore: false,
40+
})
41+
if (vscode.workspace.getConfiguration('editor.parameterHints').get('enabled')) {
42+
void vscode.commands.executeCommand('editor.action.triggerParameterHints')
43+
}
44+
}
45+
}
46+
})
47+
48+
conditionallyRegister(
49+
'suggestions.keywordsInsertText',
50+
() =>
51+
vscode.workspace.onDidChangeTextDocument(({ document, contentChanges, reason }) => {
52+
if (!justAcceptedReturnKeywordSuggestion) return
53+
if (document !== vscode.window.activeTextEditor?.document) return
54+
try {
55+
if (oneOf(reason, vscode.TextDocumentChangeReason.Redo, vscode.TextDocumentChangeReason.Undo)) {
56+
return
57+
}
58+
59+
const char = contentChanges[0]?.text
60+
if (char?.length !== 1 || contentChanges.some(({ text }) => text !== char)) {
61+
return
62+
}
63+
64+
if (char === ';') {
65+
void vscode.window.activeTextEditor.edit(builder => {
66+
for (const { range } of contentChanges) {
67+
const pos = range.start
68+
builder.delete(new vscode.Range(pos.translate(0, -1), pos))
69+
}
70+
})
71+
}
72+
} finally {
73+
justAcceptedReturnKeywordSuggestion = false
74+
}
75+
}),
76+
val => val !== 'none',
77+
)
78+
}
79+
80+
const conditionallyRegister = <T extends keyof Settings>(
81+
settingKey: T,
82+
registerFn: () => vscode.Disposable,
83+
acceptSettingValue: (val: Settings[T]) => boolean = val => !!val,
84+
) => {
85+
let disposable: vscode.Disposable | undefined
86+
const changeRegisterState = () => {
87+
const registerState = acceptSettingValue(getExtensionSetting(settingKey))
88+
if (registerState) {
89+
if (!disposable) disposable = registerFn()
90+
} else {
91+
disposable?.dispose()
92+
disposable = undefined
93+
}
94+
}
95+
96+
changeRegisterState()
97+
watchExtensionSettings([settingKey], changeRegisterState)
98+
}

0 commit comments

Comments
 (0)