-
Notifications
You must be signed in to change notification settings - Fork 297
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
getInlineCompletions, separate provider, update tests
- Loading branch information
Showing
18 changed files
with
1,950 additions
and
1,362 deletions.
There are no files selected for viewing
1,124 changes: 1,124 additions & 0 deletions
1,124
vscode/src/completions/getInlineCompletions.test.ts
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { describe, expect, test } from 'vitest' | ||
|
||
import { range } from '../testutils/textDocument' | ||
|
||
import { adjustRangeToOverwriteOverlappingCharacters } from './processInlineCompletions' | ||
import { documentAndPosition } from './testHelpers' | ||
import { InlineCompletionItem } from './types' | ||
|
||
describe('adjustRangeToOverwriteOverlappingCharacters', () => { | ||
test('no adjustment at end of line', () => { | ||
const item: InlineCompletionItem = { insertText: 'array) {' } | ||
const { position } = documentAndPosition('function sort(█') | ||
expect( | ||
adjustRangeToOverwriteOverlappingCharacters(item, { | ||
position, | ||
docContext: { currentLineSuffix: '' }, | ||
}) | ||
).toEqual<InlineCompletionItem>(item) | ||
}) | ||
|
||
test('handles non-empty currentLineSuffix', () => { | ||
const item: InlineCompletionItem = { insertText: 'array) {' } | ||
const { position } = documentAndPosition('function sort(█)') | ||
expect( | ||
adjustRangeToOverwriteOverlappingCharacters(item, { | ||
position, | ||
docContext: { currentLineSuffix: ')' }, | ||
}) | ||
).toEqual<InlineCompletionItem>({ | ||
...item, | ||
range: range(0, 14, 0, 15), | ||
}) | ||
}) | ||
|
||
test('handles whitespace in currentLineSuffix', () => { | ||
const item: InlineCompletionItem = { insertText: 'array) {' } | ||
const { position } = documentAndPosition('function sort(█)') | ||
expect( | ||
adjustRangeToOverwriteOverlappingCharacters(item, { | ||
position, | ||
docContext: { currentLineSuffix: ') ' }, | ||
}) | ||
).toEqual<InlineCompletionItem>({ | ||
...item, | ||
range: range(0, 14, 0, 16), | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import type { Position, TextDocument } from 'vscode' | ||
|
||
import { DocumentContext } from './document' | ||
import { truncateMultilineCompletion } from './multiline' | ||
import { collapseDuplicativeWhitespace, trimUntilSuffix } from './text-processing' | ||
import { InlineCompletionItem } from './types' | ||
|
||
export interface ProcessInlineCompletionsParams { | ||
document: Pick<TextDocument, 'languageId'> | ||
position: Position | ||
multiline: boolean | ||
docContext: DocumentContext | ||
} | ||
|
||
/** | ||
* This function implements post-processing logic that is applied regardless of | ||
* which provider is chosen. | ||
*/ | ||
export function processInlineCompletions( | ||
items: InlineCompletionItem[], | ||
{ document, position, multiline, docContext }: ProcessInlineCompletionsParams | ||
): InlineCompletionItem[] { | ||
// Shared post-processing logic | ||
const processedCompletions = items.map(item => processItem(item, { document, position, multiline, docContext })) | ||
|
||
// Filter results | ||
const visibleResults = filterCompletions(processedCompletions) | ||
|
||
// Remove duplicate results | ||
const uniqueResults = [...new Map(visibleResults.map(item => [item.insertText, item])).values()] | ||
|
||
// Rank results | ||
const rankedResults = rankCompletions(uniqueResults) | ||
|
||
return rankedResults | ||
} | ||
|
||
function processItem( | ||
item: InlineCompletionItem, | ||
{ | ||
document, | ||
position, | ||
multiline, | ||
docContext: { prefix, suffix, currentLineSuffix }, | ||
}: Pick<ProcessInlineCompletionsParams, 'document' | 'position' | 'multiline' | 'docContext'> | ||
): InlineCompletionItem { | ||
// Make a copy to avoid unexpected behavior. | ||
item = { ...item } | ||
|
||
if (typeof item.insertText !== 'string') { | ||
throw new TypeError('SnippetText not supported') | ||
} | ||
|
||
item = adjustRangeToOverwriteOverlappingCharacters(item, { position, docContext: { currentLineSuffix } }) | ||
if (multiline) { | ||
item.insertText = truncateMultilineCompletion(item.insertText, prefix, suffix, document.languageId) | ||
} | ||
item.insertText = trimUntilSuffix(item.insertText, prefix, suffix, document.languageId) | ||
item.insertText = collapseDuplicativeWhitespace(prefix, item.insertText) | ||
|
||
return item | ||
} | ||
|
||
/** | ||
* Return a copy of item with an adjusted range to overwrite duplicative characters after the | ||
* completion on the first line. | ||
* | ||
* For example, with position `function sort(█)` and completion `array) {`, the range should be | ||
* adjusted to span the `)` so it is overwritten by the `insertText` (so that we don't end up with | ||
* the invalid `function sort(array) {)`). | ||
*/ | ||
export function adjustRangeToOverwriteOverlappingCharacters( | ||
item: InlineCompletionItem, | ||
{ | ||
position, | ||
docContext: { currentLineSuffix }, | ||
}: Pick<ProcessInlineCompletionsParams, 'position'> & { | ||
docContext: Pick<DocumentContext, 'currentLineSuffix'> | ||
} | ||
): InlineCompletionItem { | ||
// TODO(sqs): This is a very naive implementation that will not work for many cases. It always | ||
// just clobbers the rest of the line. | ||
|
||
if (!item.range && currentLineSuffix !== '') { | ||
return { ...item, range: { start: position, end: position.translate(undefined, currentLineSuffix.length) } } | ||
} | ||
|
||
return item | ||
} | ||
|
||
function rankCompletions(completions: InlineCompletionItem[]): InlineCompletionItem[] { | ||
// TODO(philipp-spiess): Improve ranking to something more complex then just length | ||
return completions.sort((a, b) => b.insertText.split('\n').length - a.insertText.split('\n').length) | ||
} | ||
|
||
function filterCompletions(completions: InlineCompletionItem[]): InlineCompletionItem[] { | ||
return completions.filter(c => c.insertText.trim() !== '') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.