Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
"${workspaceFolder}/out/**/*.js"
],
"sourceMaps": true,
"cascadeTerminateToConfigurations": [
"Attach to TS Server",
],
"env": {
"TSS_DEBUG": "9223",
"TSS_REMOTE_DEBUG": "9223"
Expand All @@ -25,6 +28,7 @@
"request": "attach",
"restart": true,
"port": 9223,
"customDescriptionGenerator": "function (def) { return this?.__debugKind || this?.__debugFlags || def }",
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
Expand All @@ -49,6 +53,13 @@
"Launch Extension",
"Attach to TS Server"
]
}
},
{
"name": "Extension + Volar",
"configurations": [
"Launch Extension",
"Attach to Vue Semantic Server"
]
},
]
}
4 changes: 2 additions & 2 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ TOC:
- [Contributed Code Actions](#contributed-code-actions)
- [Even Even More](#even-even-more)

> *Note*: You can disable all optional features with `> Disable All Optional Features` setting right after install.
> *Note*: You can disable all optional features with `> Disable All Optional Features` command right after install.
>
> *Note*: Visit website for list of recommended settings: <https://ts-plugin.zardoy.com/>

Expand All @@ -42,7 +42,7 @@ Also is not supported in the web.

90% work done in this extension highly improves completions experience!

### Strict Emmet
### Strict JSX Emmet

(*enabled by default*) when react langs are in `emmet.excludeLanguages`

Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
{
"command": "replaceGlobalTypescriptWithLocalVersion",
"title": "Replace Global Typescript with Local Version"
},
{
"command": "getArgumentReferencesFromCurrentParameter",
"title": "Get Argument References from Current Parameter"
}
],
"keybindings": [
Expand Down Expand Up @@ -201,4 +205,4 @@
"runTest": false
}
}
}
}
10 changes: 8 additions & 2 deletions playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
import ts from 'typescript/lib/tsserverlibrary'
import { createLanguageService } from './typescript/src/dummyLanguageService'

let testString = 'const a: {/** @default test */a: 5} | {b: 6, /** yes */a: 9} = null as any;\nif ("||" in a) {}'
globalThis.ts = ts

let testString = /* ts */ `
const b = () => 5
const a = b()|| as
new Promise()
`
const replacement = '||'
const pos = testString.indexOf(replacement)
testString = testString.slice(0, pos) + testString.slice(pos + replacement.length)
Expand All @@ -16,7 +22,7 @@ const sourceFile = program?.getSourceFile(filePath)
if (!program || !sourceFile) throw new Error('No source file')

const typeChecker = program.getTypeChecker()
const node = findChildContainingPosition(ts, sourceFile, pos)
let node = findChildContainingPosition(ts, sourceFile, pos)
if (!node) throw new Error('No node')
const type = typeChecker.getTypeAtLocation(node)

Expand Down
11 changes: 5 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/apiCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const sharedApiRequest = async (type: TriggerCharacterCommand, { offset,
if (!position) offset ??= document.offsetAt(activeTextEditor!.selection.active) + relativeOffset
const requestOffset = offset ?? document.offsetAt(position!)
const requestPos = position ?? document.positionAt(offset!)
const getData = async () => sendCommand(type, { document: document!, position: requestPos })
const getData = async () => sendCommand(type, { document: document!, position: requestPos, inputOptions: {} })
const CACHE_UNDEFINED_TIMEOUT = 1000
if (cacheableCommands.has(type as any)) {
const cacheEntry = operationsCache.get(type)
Expand Down
42 changes: 18 additions & 24 deletions src/codeActionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vscode from 'vscode'
import { defaultJsSupersetLangsWithVue } from '@zardoy/vscode-utils/build/langs'
import { registerExtensionCommand, showQuickPick, getExtensionSetting, getExtensionCommandId } from 'vscode-framework'
import { compact } from '@zardoy/utils'
import { RequestResponseTypes, RequestOptionsTypes } from '../typescript/src/ipcTypes'
import { RequestOutputTypes, RequestInputTypes } from '../typescript/src/ipcTypes'
import { sendCommand } from './sendCommand'
import { tsTextChangesToVscodeTextEdits, vscodeRangeToTs, tsTextChangesToVscodeSnippetTextEdits } from './util'

Expand All @@ -26,7 +26,7 @@ export default () => {
return
}

const fixAllEdits = await sendCommand<RequestResponseTypes['getFixAllEdits']>('getFixAllEdits', {
const fixAllEdits = await sendCommand('getFixAllEdits', {
document,
})
if (!fixAllEdits || token.isCancellationRequested) return
Expand Down Expand Up @@ -89,16 +89,13 @@ export default () => {
async resolveCodeAction(codeAction: ExtendedCodeAction, token) {
const { document } = codeAction
if (!document) throw new Error('Unresolved code action without document')
const result = await sendCommand<RequestResponseTypes['getExtendedCodeActionEdits'], RequestOptionsTypes['getExtendedCodeActionEdits']>(
'getExtendedCodeActionEdits',
{
document,
inputOptions: {
applyCodeActionTitle: codeAction.title,
range: vscodeRangeToTs(document, codeAction.diagnostics?.length ? codeAction.diagnostics[0]!.range : codeAction.requestRange),
},
const result = await sendCommand('getExtendedCodeActionEdits', {
document,
inputOptions: {
applyCodeActionTitle: codeAction.title,
range: vscodeRangeToTs(document, codeAction.diagnostics?.length ? codeAction.diagnostics[0]!.range : codeAction.requestRange),
},
)
})
if (!result) throw new Error('No code action edits. Try debug.')
const { edits = [], snippetEdits = [] } = result
const workspaceEdit = new vscode.WorkspaceEdit()
Expand All @@ -111,9 +108,9 @@ export default () => {
},
})

registerExtensionCommand('applyRefactor' as any, async (_, arg?: RequestResponseTypes['getTwoStepCodeActions']) => {
registerExtensionCommand('applyRefactor' as any, async (_, arg?: RequestOutputTypes['getTwoStepCodeActions']) => {
if (!arg) return
let sendNextData: RequestOptionsTypes['twoStepCodeActionSecondStep']['data'] | undefined
let sendNextData: RequestInputTypes['twoStepCodeActionSecondStep']['data'] | undefined
const { turnArrayIntoObject } = arg
if (turnArrayIntoObject) {
const { keysCount, totalCount, totalObjectCount } = turnArrayIntoObject
Expand Down Expand Up @@ -151,7 +148,7 @@ export default () => {
})

async function getPossibleTwoStepRefactorings(range: vscode.Range, document = vscode.window.activeTextEditor!.document) {
return sendCommand<RequestResponseTypes['getTwoStepCodeActions'], RequestOptionsTypes['getTwoStepCodeActions']>('getTwoStepCodeActions', {
return sendCommand('getTwoStepCodeActions', {
document,
position: range.start,
inputOptions: {
Expand All @@ -161,16 +158,13 @@ export default () => {
}

async function getSecondStepRefactoringData(range: vscode.Range, secondStepData?: any, document = vscode.window.activeTextEditor!.document) {
return sendCommand<RequestResponseTypes['twoStepCodeActionSecondStep'], RequestOptionsTypes['twoStepCodeActionSecondStep']>(
'twoStepCodeActionSecondStep',
{
document,
position: range.start,
inputOptions: {
range: vscodeRangeToTs(document, range),
data: secondStepData,
},
return sendCommand('twoStepCodeActionSecondStep', {
document,
position: range.start,
inputOptions: {
range: vscodeRangeToTs(document, range),
data: secondStepData,
},
)
})
}
}
3 changes: 1 addition & 2 deletions src/emmet.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as vscode from 'vscode'
import { compact } from '@zardoy/utils'
import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework'
import { EmmetResult } from '../typescript/src/ipcTypes'
import { sendCommand } from './sendCommand'
import { Configuration } from './configurationType'

Expand Down Expand Up @@ -29,7 +28,7 @@ export const registerEmmet = async () => {
const cursorOffset: number = document.offsetAt(position)

if (context.triggerKind !== vscode.CompletionTriggerKind.TriggerForIncompleteCompletions || !lastStartOffset) {
const result = await sendCommand<EmmetResult>('emmet-completions', { document, position })
const result = await sendCommand('emmet-completions', { document, position })
if (!result) {
lastStartOffset = undefined
return
Expand Down
23 changes: 15 additions & 8 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/* eslint-disable @typescript-eslint/no-require-imports */
import * as vscode from 'vscode'
import { defaultJsSupersetLangs } from '@zardoy/vscode-utils/build/langs'
import { Settings, extensionCtx, getExtensionSetting, getExtensionSettingId, registerExtensionCommand } from 'vscode-framework'
import { extensionCtx, getExtensionSetting, getExtensionSettingId } from 'vscode-framework'
import { pickObj } from '@zardoy/utils'
import { watchExtensionSettings } from '@zardoy/vscode-utils/build/settings'
import { ConditionalPick } from 'type-fest'
import webImports from './webImports'
import { sendCommand } from './sendCommand'
import { registerEmmet } from './emmet'
Expand All @@ -27,13 +26,21 @@ export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted
isActivated = true
let webWaitingForConfigSync = false

const getResolvedConfig = () => {
const configuration = vscode.workspace.getConfiguration()
const config: any = {
...configuration.get(process.env.IDS_PREFIX!),
editorSuggestInsertModeReplace: configuration.get('editor.suggest.insertMode') === 'replace',
}
mergeSettingsFromScopes(config, 'typescript', extensionCtx.extension.packageJSON)
return config
}

const syncConfig = () => {
if (!tsApi) return
console.log('sending configure request for typescript-essential-plugins')
const config: any = { ...vscode.workspace.getConfiguration().get(process.env.IDS_PREFIX!) }
// todo implement language-specific settings
mergeSettingsFromScopes(config, 'typescript', extensionCtx.extension.packageJSON)

const config = getResolvedConfig()
tsApi.configurePlugin('typescript-essential-plugins', config)

if (process.env.PLATFORM === 'node') {
Expand All @@ -50,7 +57,7 @@ export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted
}

vscode.workspace.onDidChangeConfiguration(async ({ affectsConfiguration }) => {
if (affectsConfiguration(process.env.IDS_PREFIX!)) {
if (affectsConfiguration(process.env.IDS_PREFIX!) || affectsConfiguration('editor.suggest.insertMode')) {
syncConfig()
if (
process.env.PLATFORM === 'node' &&
Expand All @@ -72,8 +79,8 @@ export const activateTsPlugin = (tsApi: { configurePlugin; onCompletionAccepted
if (!activeTextEditor || !vscode.languages.match(defaultJsSupersetLangs, activeTextEditor.document)) return
if (!webWaitingForConfigSync) return
// webWaitingForConfigSync = false
const config = vscode.workspace.getConfiguration().get(process.env.IDS_PREFIX!)
void sendCommand(`updateConfig${JSON.stringify(config)}` as any)
const config = getResolvedConfig()
void sendCommand(`updateConfig${JSON.stringify(config)}` as any, { inputOptions: {} })
}

vscode.window.onDidChangeActiveTextEditor(possiblySyncConfig)
Expand Down
48 changes: 26 additions & 22 deletions src/onCompletionAccepted.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,33 +62,37 @@ export default (tsApi: { onCompletionAccepted }) => {
const nextChar = editor.document.getText(new vscode.Range(startPos, startPos.translate(0, 1)))
if (!params || ['(', '.', '`'].includes(nextChar)) return

if (isAmbiguous && lastAcceptedAmbiguousMethodSnippetSuggestion !== suggestionName) {
lastAcceptedAmbiguousMethodSnippetSuggestion = suggestionName
return
}
if (getExtensionSetting('methodSnippetsInsertText') === 'disable') {
// handle insertion only if it wasn't handled by methodSnippetsInsertText already
if (isAmbiguous && lastAcceptedAmbiguousMethodSnippetSuggestion !== suggestionName) {
lastAcceptedAmbiguousMethodSnippetSuggestion = suggestionName
return
}

const replaceArguments = getExtensionSetting('methodSnippets.replaceArguments')

const snippet = new vscode.SnippetString('')
snippet.appendText('(')
// todo maybe when have optional (skipped), add a way to leave trailing , with tabstop (previous behavior)
for (const [i, param] of params.entries()) {
const replacer = replaceArguments[param.replace(/\?$/, '')]
if (replacer === null) continue
if (replacer) {
useReplacer(snippet, replacer)
} else {
snippet.appendPlaceholder(param)
const replaceArguments = getExtensionSetting('methodSnippets.replaceArguments')

const snippet = new vscode.SnippetString('')
snippet.appendText('(')
// todo maybe when have optional (skipped), add a way to leave trailing , with tabstop (previous behavior)
for (const [i, param] of params.entries()) {
const replacer = replaceArguments[param.replace(/\?$/, '')]
if (replacer === null) continue
if (replacer) {
useReplacer(snippet, replacer)
} else {
snippet.appendPlaceholder(param)
}

if (i !== params.length - 1) snippet.appendText(', ')
}

if (i !== params.length - 1) snippet.appendText(', ')
snippet.appendText(')')
void editor.insertSnippet(snippet, undefined, {
undoStopAfter: false,
undoStopBefore: false,
})
}

snippet.appendText(')')
void editor.insertSnippet(snippet, undefined, {
undoStopAfter: false,
undoStopBefore: false,
})
if (vscode.workspace.getConfiguration('editor.parameterHints').get('enabled') && params.length > 0) {
void vscode.commands.executeCommand('editor.action.triggerParameterHints')
}
Expand Down
Loading