Skip to content

Commit af7cc6a

Browse files
committed
feat: caseSensitiveCompletions (disabled by default)!
feat: `disableFuzzyCompletions` (disabled by default) - filter completions that start with entered text
1 parent 4870127 commit af7cc6a

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

README.MD

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ const usersList = []
6464
usersList.map // -> usersList.map((user) => )
6565
```
6666

67+
### Case-sensitive Completions
68+
69+
(*disabled by default*)
70+
71+
Filter out completions that start with different casing.
72+
6773
### Remove Definition From References
6874

6975
(*enabled by default*)

src/configurationType.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@ export type Configuration = {
245245
* Wether to disable our and builtin method snippets within jsx attributes
246246
* @default true
247247
*/
248-
// TODO add smart setting
249248
'disableMethodSnippets.jsxAttributes': boolean
250249
/**
251250
* Support `@ts-diagnostic-disable` top-level comment for disabling spefici semantic diagnostics
@@ -271,10 +270,24 @@ export type Configuration = {
271270
*/
272271
patchOutline: boolean
273272
/**
274-
* Exclude covered strings/enum cases in switch
273+
* Exclude covered strings/enum cases in switch in completions
275274
* @default true
276275
*/
277276
switchExcludeCoveredCases: boolean
277+
/**
278+
* Make completions case-sensetive (see https://github.com/microsoft/TypeScript/issues/46622)
279+
* Might be enabled by default in future. Experimental as for now compares only start of completions.
280+
* Might require completion retrigger if was triggered by not quick suggestions.
281+
* @default false
282+
*/
283+
caseSensitiveCompletions: boolean
284+
/**
285+
* Might be useful to enable for a moment. Note, that you can bind shortcuts within VSCode to quickly toggle settings like this
286+
* Also experimental and wasnt tested in all cases
287+
* Like described in `caseSensitiveCompletions` might require completion retrigger
288+
* @default false
289+
*/
290+
disableFuzzyCompletions: boolean
278291
/**
279292
* Disable useless highlighting,
280293
* @default disable

typescript/src/completionsAtPosition.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import defaultHelpers from './completions/defaultHelpers'
2020
import objectLiteralCompletions from './completions/objectLiteralCompletions'
2121
import filterJsxElements from './completions/filterJsxComponents'
2222
import markOrRemoveGlobalCompletions from './completions/markOrRemoveGlobalCompletions'
23+
import { oneOf } from '@zardoy/utils'
2324

2425
export type PrevCompletionMap = Record<string, { originalName?: string; documentationOverride?: string | ts.SymbolDisplayPart[] }>
2526

@@ -92,11 +93,50 @@ export const getCompletionsAtPosition = (
9293

9394
if (!prior) return
9495

96+
if (c('caseSensitiveCompletions')) {
97+
const fullText = sourceFile.getFullText()
98+
const currentWord = fullText.slice(0, position).match(/[\w\d]+$/)
99+
if (currentWord) {
100+
const firstEnteredChar = fullText.at(currentWord.index!) ?? ''
101+
/** @returns -1 - lowercase, 1 - uppercase, 0 - ignore */
102+
const getCharCasing = (char: string) => {
103+
if (char.toLocaleUpperCase() !== char) return -1
104+
if (char.toLocaleLowerCase() !== char) return 1
105+
return 0
106+
}
107+
const typedStartCasing = getCharCasing(firstEnteredChar)
108+
// check wether it is actually a case char and not a number for example
109+
if (typedStartCasing !== 0) {
110+
prior.entries = prior.entries.filter(entry => {
111+
const entryCasing = getCharCasing(entry.name.at(0) ?? '')
112+
if (entryCasing === 0) return true
113+
return entryCasing === typedStartCasing
114+
})
115+
}
116+
}
117+
}
118+
119+
if (c('disableFuzzyCompletions')) {
120+
const fullText = sourceFile.getFullText()
121+
const currentWord = fullText.slice(0, position).match(/[\w\d]+$/)
122+
if (currentWord) {
123+
prior.entries = prior.entries.filter(entry => {
124+
if (entry.name.startsWith(currentWord[0])) return true
125+
return false
126+
})
127+
}
128+
}
129+
95130
if (c('fixSuggestionsSorting')) prior.entries = fixPropertiesSorting(prior.entries, leftNode, sourceFile, program) ?? prior.entries
96131
if (node) prior.entries = boostKeywordSuggestions(prior.entries, position, node) ?? prior.entries
97132

98133
const entryNames = new Set(prior.entries.map(({ name }) => name))
99-
if (c('removeUselessFunctionProps.enable')) prior.entries = prior.entries.filter(e => !['Symbol', 'caller', 'prototype'].includes(e.name))
134+
if (c('removeUselessFunctionProps.enable')) {
135+
prior.entries = prior.entries.filter(entry => {
136+
if (oneOf(entry.kind, ts.ScriptElementKind.warning)) return true
137+
return !['Symbol', 'caller', 'prototype'].includes(entry.name)
138+
})
139+
}
100140
if (['bind', 'call', 'caller'].every(name => entryNames.has(name)) && c('highlightNonFunctionMethods.enable')) {
101141
const standardProps = new Set(['Symbol', 'apply', 'arguments', 'bind', 'call', 'caller', 'length', 'name', 'prototype', 'toString'])
102142
// TODO lift up!

typescript/test/completions.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,26 @@ test('Switch Case Exclude Covered', () => {
261261
}
262262
})
263263

264+
test('Case-sensetive completions', () => {
265+
settingsOverride['caseSensitiveCompletions'] = true
266+
const [_positivePositions, _negativePositions, numPositions] = fileContentsSpecialPositions(/* ts */ `
267+
const a = {
268+
TestItem: 5,
269+
testItem: 5,
270+
'3t': true
271+
// not sure of these
272+
// TestItemFoo: 5,
273+
// TestItemfoo: 5,
274+
}
275+
a.t/*0*/
276+
a['t/*0*/']
277+
`)
278+
for (const pos of numPositions) {
279+
const { entryNames } = getCompletionsAtPosition(pos) ?? {}
280+
expect(entryNames, pos.toString()).toEqual(['3t', 'testItem'])
281+
}
282+
})
283+
264284
test('Object Literal Completions', () => {
265285
const [_positivePositions, _negativePositions, numPositions] = fileContentsSpecialPositions(/* ts */ `
266286
interface Options {

0 commit comments

Comments
 (0)