Skip to content

Commit

Permalink
Merge pull request #197 from zardoy/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
zardoy authored Feb 4, 2024
2 parents 9d4a010 + 1c0edd3 commit a636d1e
Show file tree
Hide file tree
Showing 18 changed files with 352 additions and 26 deletions.
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"typescript/lib/tsserverlibrary": {
"namespace": "ts",
"addImport": false
},
"typescript": {
"namespace": "ts",
"addImport": false
}
},
"typescript.preferences.autoImportFileExcludePatterns": [
Expand All @@ -24,5 +28,5 @@
"vitest.showFailMessages": true,
"vitest.include": [
"typescript/test/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"
]
],
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
{
"command": "migrateRequireToImports",
"title": "Migrate Require to Imports"
},
{
"command": "wrapIntoNewTag",
"title": "Wrap Into New Tag"
}
],
"keybindings": [
Expand Down Expand Up @@ -169,7 +173,7 @@
"@vue/language-server": "latest",
"@vue/language-service": "latest",
"@zardoy/utils": "^0.0.9",
"@zardoy/vscode-utils": "^0.0.47",
"@zardoy/vscode-utils": "^0.0.52",
"chai": "^4.3.6",
"change-case": "^4.1.2",
"chokidar": "^3.5.3",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

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

28 changes: 28 additions & 0 deletions src/configurationType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,34 @@ export type Configuration = {
// bigFilesThreshold: number
/** @default false */
enableHooksFile: boolean
/**
* @default false
*/
declareMissingPropertyQuickfixOtherFiles: boolean
/**
* @default {}
*/
filesAutoImport: {
[ext: string]: {
/**
* Override import path (default is "$path")
*/
importPath?: string
/**
* Start phrase that will trigger search for available files import
*/
prefix: string
/**
* @default camel
*/
nameCasing?: 'camel' | 'pascal' | 'constant' | 'snake'
/**
* @default $name
*/
nameTransform?: string
iconPost?: string
}
}
}

// scrapped using search editor. config: caseInsensitive, context lines: 0, regex: const fix\w+ = "[^ ]+"
Expand Down
33 changes: 33 additions & 0 deletions src/specialCommands.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as vscode from 'vscode'
import { getActiveRegularEditor } from '@zardoy/vscode-utils'
import { getExtensionCommandId, getExtensionSetting, registerExtensionCommand, VSCodeQuickPickItem } from 'vscode-framework'
import { registerTextEditorCommand } from '@zardoy/vscode-utils/build/commands'
import { showQuickPick } from '@zardoy/vscode-utils/build/quickPick'
import _ from 'lodash'
import { compact } from '@zardoy/utils'
import { offsetPosition } from '@zardoy/vscode-utils/build/position'
import { defaultJsSupersetLangs } from '@zardoy/vscode-utils/build/langs'
import { RequestInputTypes, RequestOutputTypes } from '../typescript/src/ipcTypes'
import { sendCommand } from './sendCommand'
import { tsRangeToVscode, tsRangeToVscodeSelection, tsTextChangesToVscodeTextEdits } from './util'
Expand Down Expand Up @@ -319,6 +321,37 @@ export default () => {
await vscode.workspace.applyEdit(edit)
})

registerTextEditorCommand('wrapIntoNewTag', async (editor, edit, fallbackCommand = 'editor.emmet.action.wrapWithAbbreviation') => {
const { selection } = editor
if (selection.start.isEqual(selection.end)) {
const range = editor.selection
const selectedText = '$TM_SELECTED_TEXT'

if (!defaultJsSupersetLangs.includes(editor.document.languageId)) {
if (fallbackCommand) {
await vscode.commands.executeCommand(fallbackCommand, ...fallbackCommand.split(' ').slice(1))
}

return
}

const data = (await sendCommand('getNodePath', {})) ?? []
const jsxElem = [...data].reverse().find(d => ['JsxElement', 'JsxSelfClosingElement', 'JsxFragment'].includes(d.kindName))
if (!jsxElem) return
const { start, end } = jsxElem
const startPos = editor.document.positionAt(start)
const startRange = new vscode.Range(startPos, startPos)
const endPos = editor.document.positionAt(end)
const endRange = new vscode.Range(endPos, endPos)
editor.selection = new vscode.Selection(startRange.start, endRange.end)
}

const line = editor.document.lineAt(editor.selection.start.line)
const currentIndent = line.text.slice(0, line.firstNonWhitespaceCharacterIndex)
await editor.insertSnippet(new vscode.SnippetString(`<\${1:div}$0>\n\t$TM_SELECTED_TEXT\n</\${1:div}>`), editor.selection)
return
})

// registerExtensionCommand('insertImportFlatten', () => {
// // got -> default, got
// type A = ts.Type
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { uniq } from 'rambda'
import { findChildContainingExactPosition, getChangesTracker, getPositionHighlights, isValidInitializerForDestructure, makeUniqueName } from '../../../utils'

export default (node: ts.Node, sourceFile: ts.SourceFile, formatOptions: ts.FormatCodeSettings | undefined, languageService: ts.LanguageService) => {
Expand Down Expand Up @@ -56,7 +57,7 @@ export default (node: ts.Node, sourceFile: ts.SourceFile, formatOptions: ts.Form

if (!nodeToReplaceWithBindingPattern || propertyNames.length === 0) return

const bindings = propertyNames.map(({ initial, unique }) => {
const bindings = uniq(propertyNames).map(({ initial, unique }) => {
return ts.factory.createBindingElement(undefined, unique ? initial : undefined, unique ?? initial)
})

Expand Down
48 changes: 46 additions & 2 deletions typescript/src/codeActions/extended/declareMissingProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,52 @@ export default {
codes: [2339],
kind: 'quickfix',
title: 'Declare missing property',
tryToApply({ sourceFile, node }) {
tryToApply({ sourceFile, node, c, languageService }) {
const param = matchParents(node, ['Identifier', 'BindingElement', 'ObjectBindingPattern', 'Parameter'])
const objAccess = matchParents(node, ['Identifier', 'PropertyAccessExpression'])
const missingPropName = (node as ts.Identifier).text
if (objAccess) {
const checker = languageService.getProgram()!.getTypeChecker()!
const type = checker.getContextualType(objAccess.expression) || checker.getTypeAtLocation(objAccess.expression)
const props = type
.getProperties()
.map(type => {
const node = type.declarations?.find(declaration => {
return c('declareMissingPropertyQuickfixOtherFiles') || declaration.getSourceFile().fileName === sourceFile.fileName
})
if (node === undefined) return undefined!
return { name: type.name, node }
})
.filter(Boolean)
// TARGET PROP
const propInsertAfter = props.find(prop => missingPropName.startsWith(prop.name)) ?? props.at(-1)
if (propInsertAfter) {
const propInsertParent = propInsertAfter.node.parent
const sameParentLiteralProps = props.filter(
prop => prop.node.parent === propInsertParent && ts.isPropertyAssignment(prop.node) && !ts.isIdentifier(prop.node.initializer),
)
const insertObject =
sameParentLiteralProps.length > 0 &&
sameParentLiteralProps.every(sameParentProp => ts.isObjectLiteralExpression((sameParentProp.node as ts.PropertyAssignment).initializer))
const insertPos = propInsertAfter.node.end
const insertComma = sourceFile.getFullText().slice(insertPos - 1, insertPos) !== ','
const getLine = pos => sourceFile.getLineAndCharacterOfPosition(pos).line
const insertNewLine = getLine(propInsertAfter.node.pos) !== getLine(propInsertAfter.node.end)
const insertText = `${insertComma ? ',' : ''}${insertNewLine ? '\n' : ' '}${missingPropName}`
const snippet = insertObject ? `: {${insertNewLine ? '\n\t' : ''}$0${insertNewLine ? '\n' : ''}}` : `$0`
return {
snippetEdits: [
{
newText: `${tsFull.escapeSnippetText(insertText)}${snippet}`,
span: {
length: 0,
start: insertPos,
},
},
],
}
}
}
if (param) {
// special react pattern
if (ts.isArrowFunction(param.parent) && ts.isVariableDeclaration(param.parent.parent)) {
Expand All @@ -20,7 +64,7 @@ export default {
const hasMembers = param.type.members.length > 0
const insertPos = param.type.members.at(-1)?.end ?? param.type.end - 1
const insertComma = hasMembers && sourceFile.getFullText().slice(insertPos - 1, insertPos) !== ','
let insertText = (node as ts.Identifier).text
let insertText = missingPropName
if (insertComma) insertText = `, ${insertText}`
// alternatively only one snippetEdit could be used with tsFull.escapeSnippetText(insertText) + $0
return {
Expand Down
4 changes: 4 additions & 0 deletions typescript/src/codeActions/getCodeActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { compact } from '@zardoy/utils'
import { Except } from 'type-fest'
import { findChildContainingExactPosition, findChildContainingPosition } from '../utils'
import { ApplyExtendedCodeActionResult, IpcExtendedCodeAction } from '../ipcTypes'
import { GetConfig } from '../types'
import objectSwapKeysAndValues from './custom/objectSwapKeysAndValues'
import changeStringReplaceToRegex from './custom/changeStringReplaceToRegex'
import splitDeclarationAndInitialization from './custom/splitDeclarationAndInitialization'
Expand Down Expand Up @@ -56,6 +57,7 @@ export type ApplyExtendedCodeAction = (options: {
/** undefined when no edits is requested */
formatOptions: ts.FormatCodeSettings | undefined
languageService: ts.LanguageService
c: GetConfig
// languageServiceHost: ts.LanguageServiceHost
}) => ApplyExtendedCodeActionResult | boolean | undefined

Expand All @@ -80,6 +82,7 @@ export const getExtendedCodeActions = <T extends string | undefined>(
// languageServiceHost: ts.LanguageServiceHost,
formatOptions: ts.FormatCodeSettings | undefined,
applyCodeActionTitle: T,
config: GetConfig,
filterErrorCodes?: number[],
): T extends undefined ? ExtendedCodeAction[] : ApplyExtendedCodeActionResult => {
const range = typeof positionOrRange !== 'number' && positionOrRange.pos !== positionOrRange.end ? positionOrRange : undefined
Expand All @@ -93,6 +96,7 @@ export const getExtendedCodeActions = <T extends string | undefined>(
position,
range,
sourceFile,
c: config,
}
if (applyCodeActionTitle) {
const codeAction = extendedCodeActions.find(codeAction => codeAction.title === applyCodeActionTitle)
Expand Down
19 changes: 17 additions & 2 deletions typescript/src/completionEntryDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,29 @@ export default function completionEntryDetails(
const sourceFile = program?.getSourceFile(fileName)
if (!program || !sourceFile) return

const { documentationOverride, documentationAppend, detailPrepend } = prevCompletionsMap[entryName] ?? {}
const { documentationOverride, documentationAppend, detailPrepend, textChanges } = prevCompletionsMap[entryName] ?? {}
if (documentationOverride) {
return {
const prior: ts.CompletionEntryDetails = {
name: entryName,
kind: ts.ScriptElementKind.alias,
kindModifiers: '',
displayParts: typeof documentationOverride === 'string' ? [{ kind: 'text', text: documentationOverride }] : documentationOverride,
}
if (textChanges) {
prior.codeActions = [
// ...(prior.codeActions ?? []),
{
description: 'Includes Text Changes',
changes: [
{
fileName,
textChanges,
},
],
},
]
}
return prior
}
let prior = languageService.getCompletionEntryDetails(
fileName,
Expand Down
Loading

0 comments on commit a636d1e

Please sign in to comment.