Skip to content

Commit c8bd632

Browse files
committed
refactor: simplify util and setting prior
1 parent 28e89ac commit c8bd632

File tree

2 files changed

+75
-63
lines changed

2 files changed

+75
-63
lines changed

typescript/src/completionsAtPosition.ts

Lines changed: 61 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type tslib from 'typescript/lib/tsserverlibrary'
33
import * as emmet from '@vscode/emmet-helper'
44
import isInBannedPosition from './isInBannedPosition'
55
import { GetConfig } from './types'
6+
import { findChildContainingPosition } from './utils'
67

78
export type PrevCompletionMap = Record<string, { originalName?: string; documentationOverride?: string | tslib.SymbolDisplayPart[] }>
89

@@ -14,7 +15,12 @@ export const getCompletionsAtPosition = (
1415
languageService: ts.LanguageService,
1516
scriptSnapshot: ts.IScriptSnapshot,
1617
ts: typeof tslib,
17-
) => {
18+
):
19+
| {
20+
completions: tslib.CompletionInfo
21+
prevCompletionsMap: PrevCompletionMap
22+
}
23+
| undefined => {
1824
const prevCompletionsMap: PrevCompletionMap = {}
1925
const program = languageService.getProgram()
2026
const sourceFile = program?.getSourceFile(fileName)
@@ -25,6 +31,10 @@ export const getCompletionsAtPosition = (
2531
// 'raw prior',
2632
// prior?.entries.map(entry => entry.name),
2733
// )
34+
const ensurePrior = () => {
35+
if (!prior) prior = { entries: [], isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false }
36+
return true
37+
}
2838
const node = findChildContainingPosition(ts, sourceFile, position)
2939
if (['.jsx', '.tsx'].some(ext => fileName.endsWith(ext))) {
3040
// JSX Features
@@ -54,55 +64,56 @@ export const getCompletionsAtPosition = (
5464
// const { textSpan } = proxy.getSmartSelectionRange(fileName, position)
5565
// let existing = scriptSnapshot.getText(textSpan.start, textSpan.start + textSpan.length)
5666
// if (existing.includes('\n')) existing = ''
57-
if (!prior) prior = { entries: [], isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false }
58-
// if (existing.startsWith('.')) {
59-
// const className = existing.slice(1)
60-
// prior.entries.push({
61-
// kind: typescript.ScriptElementKind.label,
62-
// name: className,
63-
// sortText: '!5',
64-
// insertText: `<div className="${className}">$1</div>`,
65-
// isSnippet: true,
66-
// })
67-
// } else if (!existing[0] || existing[0].match(/\w/)) {
68-
if (c('jsxEmmet.type') === 'realEmmet') {
69-
const sendToEmmet = nodeText.split(' ').at(-1)!
70-
const emmetCompletions = emmet.doComplete(
71-
{
72-
getText: () => sendToEmmet,
73-
languageId: 'html',
74-
lineCount: 1,
75-
offsetAt: position => position.character,
76-
positionAt: offset => ({ line: 0, character: offset }),
77-
uri: '/',
78-
version: 1,
79-
},
80-
{ line: 0, character: sendToEmmet.length },
81-
'html',
82-
{},
83-
) ?? { items: [] }
84-
for (const completion of emmetCompletions.items)
85-
prior.entries.push({
86-
kind: ts.ScriptElementKind.label,
87-
name: completion.label.slice(1),
88-
sortText: '!5',
89-
// insertText: `${completion.label.slice(1)} ${completion.textEdit?.newText}`,
90-
insertText: completion.textEdit?.newText,
91-
isSnippet: true,
92-
sourceDisplay: completion.detail !== undefined ? [{ kind: 'text', text: completion.detail }] : undefined,
93-
// replacementSpan: { start: position - 5, length: 5 },
94-
})
95-
} else {
96-
const tags = c('jsxPseudoEmmet.tags')
97-
for (let [tag, value] of Object.entries(tags)) {
98-
if (value === true) value = `<${tag}>$1</${tag}>`
99-
prior.entries.push({
100-
kind: ts.ScriptElementKind.label,
101-
name: tag,
102-
sortText: '!5',
103-
insertText: value,
104-
isSnippet: true,
105-
})
67+
if (ensurePrior() && prior) {
68+
// if (existing.startsWith('.')) {
69+
// const className = existing.slice(1)
70+
// prior.entries.push({
71+
// kind: typescript.ScriptElementKind.label,
72+
// name: className,
73+
// sortText: '!5',
74+
// insertText: `<div className="${className}">$1</div>`,
75+
// isSnippet: true,
76+
// })
77+
// } else if (!existing[0] || existing[0].match(/\w/)) {
78+
if (c('jsxEmmet.type') === 'realEmmet') {
79+
const sendToEmmet = nodeText.split(' ').at(-1)!
80+
const emmetCompletions = emmet.doComplete(
81+
{
82+
getText: () => sendToEmmet,
83+
languageId: 'html',
84+
lineCount: 1,
85+
offsetAt: position => position.character,
86+
positionAt: offset => ({ line: 0, character: offset }),
87+
uri: '/',
88+
version: 1,
89+
},
90+
{ line: 0, character: sendToEmmet.length },
91+
'html',
92+
{},
93+
) ?? { items: [] }
94+
for (const completion of emmetCompletions.items)
95+
prior.entries.push({
96+
kind: ts.ScriptElementKind.label,
97+
name: completion.label.slice(1),
98+
sortText: '!5',
99+
// insertText: `${completion.label.slice(1)} ${completion.textEdit?.newText}`,
100+
insertText: completion.textEdit?.newText,
101+
isSnippet: true,
102+
sourceDisplay: completion.detail !== undefined ? [{ kind: 'text', text: completion.detail }] : undefined,
103+
// replacementSpan: { start: position - 5, length: 5 },
104+
})
105+
} else {
106+
const tags = c('jsxPseudoEmmet.tags')
107+
for (let [tag, value] of Object.entries(tags)) {
108+
if (value === true) value = `<${tag}>$1</${tag}>`
109+
prior.entries.push({
110+
kind: ts.ScriptElementKind.label,
111+
name: tag,
112+
sortText: '!5',
113+
insertText: value,
114+
isSnippet: true,
115+
})
116+
}
106117
}
107118
}
108119
}
@@ -235,16 +246,3 @@ const arrayMoveItemToFrom = <T>(array: T[], originalItem: ArrayPredicate<T>, ite
235246
}
236247

237248
const patchText = (input: string, start: number, end: number, newText: string) => input.slice(0, start) + newText + input.slice(end)
238-
239-
function findChildContainingPosition(
240-
typescript: typeof import('typescript/lib/tsserverlibrary'),
241-
sourceFile: tslib.SourceFile,
242-
position: number,
243-
): tslib.Node | undefined {
244-
function find(node: ts.Node): ts.Node | undefined {
245-
if (position >= node.getStart() && position < node.getEnd()) return typescript.forEachChild(node, find) || node
246-
247-
return
248-
}
249-
return find(sourceFile)
250-
}

typescript/src/utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type tslib from 'typescript/lib/tsserverlibrary'
2+
3+
export function findChildContainingPosition(
4+
typescript: typeof import('typescript/lib/tsserverlibrary'),
5+
sourceFile: tslib.SourceFile,
6+
position: number,
7+
): tslib.Node | undefined {
8+
function find(node: ts.Node): ts.Node | undefined {
9+
if (position >= node.getStart() && position < node.getEnd()) return typescript.forEachChild(node, find) || node
10+
11+
return
12+
}
13+
return find(sourceFile)
14+
}

0 commit comments

Comments
 (0)