mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
Add working autocomplete with caching
This commit is contained in:
parent
fe413cb474
commit
268d03fad5
7 changed files with 389 additions and 55 deletions
1
extensions/void/package-lock.json
generated
1
extensions/void/package-lock.json
generated
|
|
@ -6029,7 +6029,6 @@
|
|||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.0.tgz",
|
||||
"integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ms": {
|
||||
|
|
|
|||
|
|
@ -397,6 +397,13 @@ COMPLETION
|
|||
export default Sidebar;\`\`\`
|
||||
`
|
||||
|
||||
// used for ctrl+l
|
||||
const partialGenerationInstructions = ``
|
||||
|
||||
|
||||
// used for ctrl+k, autocomplete
|
||||
const fimInstructions = ``
|
||||
|
||||
|
||||
|
||||
export {
|
||||
|
|
|
|||
218
extensions/void/src/extension/AutcompleteProvider.ts
Normal file
218
extensions/void/src/extension/AutcompleteProvider.ts
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
import * as vscode from 'vscode';
|
||||
import { AbortRef, LLMMessage, sendLLMMessage } from '../common/sendLLMMessage';
|
||||
import { getVoidConfigFromPartial } from '../webviews/common/contextForConfig';
|
||||
|
||||
type AutocompletionStatus = 'pending' | 'finished' | 'error';
|
||||
type Autocompletion = {
|
||||
prefix: string,
|
||||
suffix: string,
|
||||
startTime: number,
|
||||
endTime: number | undefined,
|
||||
abortRef: AbortRef,
|
||||
status: AutocompletionStatus,
|
||||
promise: Promise<string> | undefined,
|
||||
result: string,
|
||||
}
|
||||
|
||||
const TIMEOUT_TIME = 10000
|
||||
|
||||
const toInlineCompletion = ({ prefix, suffix, autocompletion }: { prefix: string, suffix: string, autocompletion: Autocompletion }): vscode.InlineCompletionItem => {
|
||||
|
||||
const originalPrefix = autocompletion.prefix
|
||||
const generatedMiddle = autocompletion.result
|
||||
const fullPrefix = originalPrefix + generatedMiddle
|
||||
|
||||
// check if the currently generated text matches with the prefix
|
||||
let remainingText = ''
|
||||
if (fullPrefix.startsWith(prefix)) {
|
||||
|
||||
// example:
|
||||
// originalPrefix = abcd
|
||||
// generatedMiddle = efgh
|
||||
// originalSuffix = ijkl
|
||||
// the user has typed "ef" so prefix = abcdef
|
||||
// we want to return the rest of the generatedMiddle, which is "gh"
|
||||
|
||||
const index = (prefix.length - originalPrefix.length) - 1
|
||||
remainingText = generatedMiddle.substring(index + 1)
|
||||
}
|
||||
|
||||
console.log('----')
|
||||
console.log('fullPrefix', fullPrefix)
|
||||
console.log('----')
|
||||
console.log('----')
|
||||
console.log('prefix', prefix)
|
||||
console.log('----')
|
||||
console.log('completion: ', remainingText)
|
||||
|
||||
return new vscode.InlineCompletionItem(remainingText)
|
||||
|
||||
}
|
||||
|
||||
export class AutocompleteProvider implements vscode.InlineCompletionItemProvider {
|
||||
|
||||
private _extensionContext: vscode.ExtensionContext;
|
||||
|
||||
private _autocompletionsOfDocument: { [docUriStr: string]: Autocompletion[] } = {}
|
||||
|
||||
// used internally by vscode
|
||||
// fires after every keystroke
|
||||
async provideInlineCompletionItems(
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
context: vscode.InlineCompletionContext,
|
||||
token: vscode.CancellationToken,
|
||||
): Promise<vscode.InlineCompletionItem[]> {
|
||||
|
||||
const docUriStr = document.uri.toString()
|
||||
|
||||
const fullText = document.getText();
|
||||
const cursorOffset = document.offsetAt(position);
|
||||
const prefix = fullText.substring(0, cursorOffset);
|
||||
const suffix = fullText.substring(cursorOffset);
|
||||
|
||||
if (!this._autocompletionsOfDocument[docUriStr]) {
|
||||
this._autocompletionsOfDocument[docUriStr] = []
|
||||
}
|
||||
|
||||
const voidConfig = getVoidConfigFromPartial(this._extensionContext.globalState.get('partialVoidConfig') ?? {})
|
||||
|
||||
|
||||
// get autocompletion from cache
|
||||
let cachedAutocompletion: Autocompletion | undefined = undefined
|
||||
loop: for (const autocompletion of this._autocompletionsOfDocument[docUriStr]!) {
|
||||
const originalPrefix = autocompletion.prefix
|
||||
const generatedMiddle = autocompletion.result
|
||||
// if the user's change matches up with the generated text
|
||||
if ((originalPrefix + generatedMiddle).startsWith(prefix)) {
|
||||
cachedAutocompletion = autocompletion
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
|
||||
// if there is an autocompletion for this line, return it
|
||||
if (cachedAutocompletion) {
|
||||
|
||||
if (cachedAutocompletion.status === 'finished') {
|
||||
|
||||
const inlineCompletion = toInlineCompletion({ autocompletion: cachedAutocompletion, prefix, suffix, })
|
||||
return [inlineCompletion]
|
||||
|
||||
} else if (cachedAutocompletion.status === 'pending') {
|
||||
|
||||
try {
|
||||
// await the result; if it hasnt resolved in 10 seconds assume the request is dead
|
||||
await Promise.race([
|
||||
cachedAutocompletion.promise,
|
||||
new Promise<string>((resolve, reject) => setTimeout(() => reject('Request timed out'), TIMEOUT_TIME)),
|
||||
])
|
||||
const inlineCompletion = toInlineCompletion({ autocompletion: cachedAutocompletion, prefix, suffix, })
|
||||
return [inlineCompletion]
|
||||
|
||||
} catch (e) {
|
||||
console.error('Error creating autocompletion (1): ' + e)
|
||||
return []
|
||||
}
|
||||
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if there is no autocomplete for this line, create it and add it to cache
|
||||
let messages: LLMMessage[] = []
|
||||
switch (voidConfig.default.whichApi) {
|
||||
case 'ollama':
|
||||
messages = [
|
||||
{ role: 'user', content: `[SUFFIX]${suffix}[PREFIX]${prefix} ` }
|
||||
]
|
||||
break;
|
||||
case 'anthropic':
|
||||
case 'openAI':
|
||||
messages = [
|
||||
{ role: 'system', content: '' },
|
||||
{ role: 'user', content: `[SUFFIX]${suffix}[PREFIX]${prefix}` },
|
||||
]
|
||||
break;
|
||||
default:
|
||||
throw new Error(`We do not recommend using autocomplete with your selected provider (${voidConfig.default.whichApi}).`);
|
||||
}
|
||||
|
||||
const newAutocompletion: Autocompletion = {
|
||||
prefix: prefix,
|
||||
suffix: suffix,
|
||||
startTime: Date.now(),
|
||||
endTime: undefined,
|
||||
abortRef: { current: () => { } },
|
||||
status: 'pending',
|
||||
promise: undefined,
|
||||
result: '',
|
||||
}
|
||||
|
||||
|
||||
// set the parameters of `newAutocompletion` appropriately
|
||||
newAutocompletion.promise = new Promise((resolve, reject) => {
|
||||
|
||||
sendLLMMessage({
|
||||
messages: messages,
|
||||
onText: async (tokenStr, completionStr) => {
|
||||
// TODO filter out bad responses here
|
||||
newAutocompletion.result = completionStr
|
||||
},
|
||||
onFinalMessage: (finalMessage) => {
|
||||
console.log('finalMessage:', finalMessage);
|
||||
|
||||
// newAutocompletion.prefix = prefix
|
||||
// newAutocompletion.suffix = suffix
|
||||
// newAutocompletion.startTime = Date.now()
|
||||
newAutocompletion.endTime = Date.now()
|
||||
// newAutocompletion.abortRef = { current: () => { } }
|
||||
newAutocompletion.status = 'finished'
|
||||
// newAutocompletion.promise = undefined
|
||||
newAutocompletion.result = finalMessage
|
||||
|
||||
resolve(finalMessage)
|
||||
},
|
||||
onError: (e) => {
|
||||
newAutocompletion.endTime = Date.now()
|
||||
newAutocompletion.status = 'error'
|
||||
newAutocompletion.result = ''
|
||||
|
||||
reject(e)
|
||||
},
|
||||
voidConfig,
|
||||
abortRef: newAutocompletion.abortRef,
|
||||
})
|
||||
})
|
||||
|
||||
this._autocompletionsOfDocument[docUriStr]!.push(newAutocompletion)
|
||||
|
||||
|
||||
try {
|
||||
const result = await Promise.race([
|
||||
newAutocompletion.promise,
|
||||
new Promise<string>((resolve, reject) => setTimeout(() => reject('Request timed out'), TIMEOUT_TIME)),
|
||||
])
|
||||
|
||||
const inlineCompletion = toInlineCompletion({ autocompletion: newAutocompletion, prefix, suffix, })
|
||||
return [inlineCompletion]
|
||||
|
||||
} catch (e) {
|
||||
console.error('Error creating autocompletion (2): ' + e)
|
||||
return []
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
|
||||
this._extensionContext = context
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -48,8 +48,6 @@ export class DiffProvider implements vscode.CodeLensProvider {
|
|||
constructor(context: vscode.ExtensionContext) {
|
||||
this._extensionUri = context.extensionUri
|
||||
|
||||
console.log('Creating DisplayChangesProvider')
|
||||
|
||||
// this acts as a useEffect every time text changes
|
||||
vscode.workspace.onDidChangeTextDocument((e) => {
|
||||
|
||||
|
|
@ -167,7 +165,9 @@ export class DiffProvider implements vscode.CodeLensProvider {
|
|||
}
|
||||
const originalFile = this._originalFileOfDocument[docUriStr]
|
||||
if (!originalFile) {
|
||||
console.log('Error: No original file!')
|
||||
if (this._diffAreasOfDocument[docUriStr]?.length > 0) {
|
||||
console.log('Error: More than one diff area exists, but no original file was set.')
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +189,6 @@ export class DiffProvider implements vscode.CodeLensProvider {
|
|||
// add the diffs to `this._diffsOfDocument[docUriStr]`
|
||||
this.createDiffs(editor.document.uri, diffs, diffArea)
|
||||
|
||||
|
||||
// // print diffs
|
||||
// console.log('!ORIGINAL FILE:', JSON.stringify(originalFile))
|
||||
// console.log('!NEW FILE :', JSON.stringify(editor.document.getText().replace(/\r\n/g, '\n')))
|
||||
|
|
@ -451,6 +450,7 @@ export class DiffProvider implements vscode.CodeLensProvider {
|
|||
const diffareaRange = new vscode.Range(diffArea.startLine, 0, diffArea.endLine, Number.MAX_SAFE_INTEGER)
|
||||
workspaceEdit.replace(editor.document.uri, diffareaRange, newCode)
|
||||
await vscode.workspace.applyEdit(workspaceEdit)
|
||||
|
||||
}, THROTTLE_TIME)
|
||||
|
||||
}
|
||||
|
|
|
|||
130
extensions/void/src/extension/autocomplete.ts
Normal file
130
extensions/void/src/extension/autocomplete.ts
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
import * as vscode from 'vscode';
|
||||
import { AbortRef, OnFinalMessage, OnText, sendLLMMessage } from "../common/sendLLMMessage"
|
||||
import { VoidConfig } from '../webviews/common/contextForConfig';
|
||||
|
||||
type AutocompletionStatus = 'pending' | 'complete' | 'error';
|
||||
type Autocompletion = {
|
||||
prefix: string,
|
||||
suffix: string,
|
||||
startTime: number,
|
||||
endTime: number,
|
||||
abortRef: AbortRef,
|
||||
status: AutocompletionStatus,
|
||||
result: string,
|
||||
}
|
||||
|
||||
const recentEdits = []
|
||||
const autocompletionsOfDocument: { [docUriStr: string]: Autocompletion[] } = {}
|
||||
|
||||
|
||||
const showRecentAutocompletion = () => {
|
||||
console.log('showRecentAutocompletion')
|
||||
const editor = vscode.window.activeTextEditor
|
||||
if (!editor) return;
|
||||
|
||||
const docUriStr = editor.document.uri.toString();
|
||||
const autocompletions = autocompletionsOfDocument[docUriStr]
|
||||
if (!autocompletions || autocompletions.length === 0) return;
|
||||
|
||||
const completion = autocompletions[autocompletions.length - 1]
|
||||
if (completion.status === 'pending') return;
|
||||
if (completion.status === 'error') return;
|
||||
|
||||
const decorationType = vscode.window.createTextEditorDecorationType({
|
||||
after: { contentText: completion.result, color: '#888', }
|
||||
});
|
||||
const position = editor.document.positionAt(completion.prefix.length);
|
||||
const decorationOptions = [{ range: new vscode.Range(position, position) }];
|
||||
editor.setDecorations(decorationType, decorationOptions);
|
||||
|
||||
|
||||
}
|
||||
|
||||
export const setupAutocomplete = ({ voidConfig, abortRef }: { voidConfig: VoidConfig, abortRef: AbortRef }) => {
|
||||
|
||||
|
||||
vscode.workspace.onDidChangeTextDocument(e => {
|
||||
let shouldAutocomplete = true;
|
||||
// 1. determine if we should do an autocomplete
|
||||
// -check that we're not predicting too many changes at a time
|
||||
// -look at cache and see if current location has already been predicted
|
||||
// -check if the user's selection has overlap with the current prediction they are selecting
|
||||
|
||||
const editor = vscode.window.activeTextEditor
|
||||
if (!editor) return;
|
||||
if (e.document !== editor.document) return;
|
||||
if (e.contentChanges.length === 0) return;
|
||||
|
||||
const docUriStr = editor.document.uri.toString();
|
||||
|
||||
// get the prefix + suffix
|
||||
const change = e.contentChanges[e.contentChanges.length - 1];
|
||||
const fullText = editor.document.getText();
|
||||
const startOffset = editor.document.offsetAt(change.range.start);
|
||||
const cursorOffset = startOffset + (change.text.length > 0 ? change.text.length : 0);
|
||||
const prefix = fullText.substring(0, cursorOffset);
|
||||
const suffix = fullText.substring(cursorOffset);
|
||||
|
||||
// TODO do checks as mentioned above
|
||||
|
||||
if (!shouldAutocomplete) return;
|
||||
// 2. if we should do an autocomplete, get the relevant quantities
|
||||
// -LSP types of variables around the cursor
|
||||
// -LSP imports of variables around the cursor
|
||||
// -code context of recent edits
|
||||
|
||||
// 3. create an autocompletion
|
||||
|
||||
if (!autocompletionsOfDocument[docUriStr]) {
|
||||
autocompletionsOfDocument[docUriStr] = []
|
||||
}
|
||||
|
||||
let promptContent = ``;
|
||||
switch (voidConfig.default.whichApi) {
|
||||
case 'ollama':
|
||||
promptContent = `[SUFFIX]${suffix}[PREFIX]${prefix}`;
|
||||
break;
|
||||
case 'anthropic':
|
||||
case 'openAI':
|
||||
promptContent = `[SUFFIX]${suffix}[PREFIX]${prefix}`;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`We do not recommend using autocomplete with your selected provider (${voidConfig.default.whichApi}).`);
|
||||
}
|
||||
|
||||
const startTime = Date.now();
|
||||
sendLLMMessage({
|
||||
messages: [{ role: 'user', content: promptContent, }],
|
||||
onText: async (tokenStr, completionStr) => {
|
||||
// TODO filter out bad responses here
|
||||
},
|
||||
onFinalMessage: (finalMessage) => {
|
||||
console.log('finalMessage:', finalMessage);
|
||||
const autocompletion: Autocompletion = {
|
||||
prefix,
|
||||
suffix,
|
||||
abortRef,
|
||||
startTime,
|
||||
endTime: Date.now(),
|
||||
status: 'complete',
|
||||
result: finalMessage,
|
||||
}
|
||||
autocompletionsOfDocument[docUriStr].push(autocompletion)
|
||||
showRecentAutocompletion()
|
||||
},
|
||||
onError: (e) => {
|
||||
console.error('Error generating autocompletion:', e);
|
||||
},
|
||||
voidConfig,
|
||||
abortRef,
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
|
@ -5,31 +5,6 @@ import { searchDiffChunkInstructions, writeFileWithDiffInstructions } from '../c
|
|||
import { throttle } from 'lodash';
|
||||
import { readFileContentOfUri } from './extensionLib/readFileContentOfUri';
|
||||
|
||||
type Res<T> = ((value: T) => void)
|
||||
|
||||
const THRTOTLE_TIME = 100 // minimum time between edits
|
||||
const LINES_PER_CHUNK = 20 // number of lines to search at a time
|
||||
|
||||
const applyCtrlLChangesToFile = throttle(
|
||||
({ fileUri, newCurrentLine, oldCurrentLine, fullCompletedStr, oldFileStr, debug }: { fileUri: vscode.Uri, newCurrentLine: number, oldCurrentLine: number, fullCompletedStr: string, oldFileStr: string, debug?: string }) => {
|
||||
|
||||
// write the change to the file
|
||||
const WRITE_TO_FILE = (
|
||||
fullCompletedStr.split('\n').slice(0, newCurrentLine + 1).join('\n') // newFile[:newCurrentLine+1]
|
||||
+ oldFileStr.split('\n').slice(oldCurrentLine + 1).join('\n') // oldFile[oldCurrentLine+1:]
|
||||
)
|
||||
const workspaceEdit = new vscode.WorkspaceEdit()
|
||||
workspaceEdit.replace(fileUri, new vscode.Range(0, 0, Number.MAX_SAFE_INTEGER, 0), WRITE_TO_FILE)
|
||||
vscode.workspace.applyEdit(workspaceEdit)
|
||||
|
||||
// highlight the `newCurrentLine` in white
|
||||
// highlight the remaining part of the file in gray
|
||||
|
||||
},
|
||||
THRTOTLE_TIME, { trailing: true }
|
||||
)
|
||||
|
||||
|
||||
const applyCtrlK = async ({ fileUri, startLine, endLine, instructions, voidConfig, abortRef }: { fileUri: vscode.Uri, startLine: number, endLine: number, instructions: string, voidConfig: VoidConfig, abortRef: AbortRef }) => {
|
||||
|
||||
const fileStr = await readFileContentOfUri(fileUri)
|
||||
|
|
@ -47,24 +22,19 @@ const applyCtrlK = async ({ fileUri, startLine, endLine, instructions, voidConfi
|
|||
The user wants to apply the following instructions to the selection:
|
||||
${instructions}
|
||||
|
||||
Please rewrite the selection following the user's instructions.
|
||||
|
||||
Instructions to follow:
|
||||
Instructions:
|
||||
1. Follow the user's instructions
|
||||
2. You may ONLY CHANGE the selection, and nothing else in the file
|
||||
3. Make sure all brackets in the new selection are balanced the same was as in the original selection
|
||||
3. Be careful not to duplicate or remove variables, comments, or other syntax by mistake
|
||||
4. Be careful not to duplicate or remove variables, comments, or other syntax by mistake
|
||||
|
||||
Complete the following:
|
||||
Please rewrite the complete the following code, following the user's instructions.
|
||||
\`\`\`
|
||||
<PRE>${prefix}</PRE>
|
||||
<SUF>${suffix}</SUF>
|
||||
<MID>`;
|
||||
|
||||
|
||||
// TODO initialize stream
|
||||
|
||||
// update stream
|
||||
sendLLMMessage({
|
||||
messages: [{ role: 'user', content: promptContent, }],
|
||||
onText: async (tokenStr, completionStr) => {
|
||||
|
|
@ -97,4 +67,4 @@ Complete the following:
|
|||
|
||||
|
||||
|
||||
export { applyCtrlK }
|
||||
export { applyCtrlK }
|
||||
|
|
|
|||
|
|
@ -9,21 +9,23 @@ import { DiffProvider } from './DiffProvider';
|
|||
import { readFileContentOfUri } from './extensionLib/readFileContentOfUri';
|
||||
import { SidebarWebviewProvider } from './providers/SidebarWebviewProvider';
|
||||
import { CtrlKWebviewProvider } from './providers/CtrlKWebviewProvider';
|
||||
import { setupAutocomplete } from './autocomplete';
|
||||
import { AutocompleteProvider } from './AutcompleteProvider';
|
||||
|
||||
// this comes from vscode.proposed.editorInsets.d.ts
|
||||
declare module 'vscode' {
|
||||
export interface WebviewEditorInset {
|
||||
readonly editor: vscode.TextEditor;
|
||||
readonly line: number;
|
||||
readonly height: number;
|
||||
readonly webview: vscode.Webview;
|
||||
readonly onDidDispose: Event<void>;
|
||||
dispose(): void;
|
||||
}
|
||||
export namespace window {
|
||||
export function createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options?: vscode.WebviewOptions): WebviewEditorInset;
|
||||
}
|
||||
}
|
||||
// // this comes from vscode.proposed.editorInsets.d.ts
|
||||
// declare module 'vscode' {
|
||||
// export interface WebviewEditorInset {
|
||||
// readonly editor: vscode.TextEditor;
|
||||
// readonly line: number;
|
||||
// readonly height: number;
|
||||
// readonly webview: vscode.Webview;
|
||||
// readonly onDidDispose: Event<void>;
|
||||
// dispose(): void;
|
||||
// }
|
||||
// export namespace window {
|
||||
// export function createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options?: vscode.WebviewOptions): WebviewEditorInset;
|
||||
// }
|
||||
// }
|
||||
|
||||
const roundRangeToLines = (selection: vscode.Selection) => {
|
||||
let endLine = selection.end.character === 0 ? selection.end.line - 1 : selection.end.line // e.g. if the user triple clicks, it selects column=0, line=line -> column=0, line=line+1
|
||||
|
|
@ -112,7 +114,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
// Receive messages in the extension from the sidebar webview (messages are sent using `postMessage`)
|
||||
webview.onDidReceiveMessage(async (m: MessageFromSidebar) => {
|
||||
|
||||
const abortApplyRef: AbortRef = { current: null }
|
||||
const abortRef: AbortRef = { current: null }
|
||||
|
||||
if (m.type === 'requestFiles') {
|
||||
|
||||
|
|
@ -146,7 +148,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
const fileStr = await readFileContentOfUri(docUri)
|
||||
const voidConfig = getVoidConfigFromPartial(context.globalState.get('partialVoidConfig') ?? {})
|
||||
|
||||
await applyDiffLazily({ docUri, oldFileStr: fileStr, diffRepr: m.diffRepr, voidConfig, diffProvider, diffArea, abortRef: abortApplyRef })
|
||||
await applyDiffLazily({ docUri, oldFileStr: fileStr, diffRepr: m.diffRepr, voidConfig, diffProvider, diffArea, abortRef: abortRef })
|
||||
}
|
||||
else if (m.type === 'getPartialVoidConfig') {
|
||||
const partialVoidConfig = context.globalState.get('partialVoidConfig') ?? {}
|
||||
|
|
@ -180,6 +182,14 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
}
|
||||
)
|
||||
|
||||
// 6. Autocomplete
|
||||
const autocompleteProvider = new AutocompleteProvider(context);
|
||||
context.subscriptions.push(vscode.languages.registerInlineCompletionItemProvider('*', autocompleteProvider));
|
||||
|
||||
const voidConfig = getVoidConfigFromPartial(context.globalState.get('partialVoidConfig') ?? {})
|
||||
const abortRef: AbortRef = { current: null }
|
||||
|
||||
// setupAutocomplete({ voidConfig, abortRef })
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue