diff --git a/package.json b/package.json index b910517..a5936a6 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,13 @@ "name": "fabelous-autocoder", "displayName": "Fabelous Autocoder", "description": "A simple to use Ollama autocompletion engine with options exposed and streaming functionality", - "version": "0.1.69", + "version": "0.1.764", "icon": "icon.png", "publisher": "fabel", "license": "CC BY-ND 4.0", "bugs": { "url": "https://gitea.fabelous.app/fabel/Fabelous-Autocoder/issues" }, - "sponsor": { - "url": "https://ko-fi.com/natehedge" - }, "repository": { "type": "git", "url": "https://gitea.fabelous.app/fabel/Fabelous-Autocoder" @@ -26,7 +23,6 @@ ], "keywords": [ "ollama", - "gpt", "coding", "autocomplete", "open source", @@ -35,7 +31,7 @@ "llm" ], "galleryBanner": { - "color": "#f5ead1" + "color": "#133773" }, "activationEvents": [ "onStartupFinished" @@ -60,12 +56,6 @@ "default": "", "description": "The model to use for generating completions" }, - "fabelous-autocoder.message header": { - "type": "string", - "editPresentation": "multilineText", - "default": "The following is a complete {LANG} file named {FILE_NAME} in the project {PROJECT_NAME}. Anything NOT code is written as a CODE COMMENT. \n\n```\n", - "description": "Pseudo-system prompt, optimized for code completion. It is recommended to keep the format the same if modified. Leave blank for no formatting (raw)." - }, "fabelous-autocoder.max tokens predicted": { "type": "integer", "default": 1000, diff --git a/src/extension.ts b/src/extension.ts index 6867cb8..12078e7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -38,65 +38,29 @@ vscode.workspace.onDidChangeConfiguration(updateVSConfig); function getContextLines(document: vscode.TextDocument, position: vscode.Position): string { const lines = []; - const lineCount = document.lineCount; - - const startLine = Math.max(0, position.line - promptWindowSize / 2); - const endLine = Math.min(lineCount - 1, position.line + promptWindowSize / 2); - + const startLine = Math.max(0, position.line - 1); + const endLine = position.line; + for (let i = startLine; i <= endLine; i++) { lines.push(document.lineAt(i).text); } - + return lines.join("\n"); } -function createFIMPrompt(prefix: string, suffix: string, language: string): string { - return `${prefix}${suffix}\n\`\`\`${language}\n`; + +function createFIMPrompt(prefix: string, language: string): string { + return `${prefix}${language}\n`; } -function removeMatchingPrefix(generatedContent: string): string { - const functionHeaderPatterns = [ - // Java, C#, TypeScript, JavaScript - /^(public|private|protected)?\s*(static\s+)?(async\s+)?\w+(\s*<[^>]+>)?\s+\w+\s*\([^)]*\)\s*{/m, - // Python - /^def\s+\w+\s*\([^)]*\):/m, - // C++, C - /^(\w+\s+)*\w+\s+\w+\s*\([^)]*\)\s*{/m, - // Go - /^func\s+\w+\s*\([^)]*\)(\s+\w+)?\s*{/m, - // Rust - /^(pub\s+)?(fn|async fn)\s+\w+\s*(<[^>]+>)?\s*\([^)]*\)(\s*->\s*\w+)?\s*{/m - ]; - - const lines = generatedContent.split('\n'); - const firstNonEmptyLineIndex = lines.findIndex(line => line.trim() !== ''); - - if (firstNonEmptyLineIndex === -1) { - return '\n' + generatedContent; - } - - const firstLine = lines[firstNonEmptyLineIndex]; - for (const pattern of functionHeaderPatterns) { - if (pattern.test(firstLine)) { - lines.splice(firstNonEmptyLineIndex, 1); - return '\n' + lines.join('\n'); - } - } - - return '\n' + generatedContent; - } async function autocompleteCommand(textEditor: vscode.TextEditor, cancellationToken?: vscode.CancellationToken) { const document = textEditor.document; const position = textEditor.selection.active; const context = getContextLines(document, position); - const lines = context.split("\n"); - const currentLineIndex = position.line - Math.max(0, position.line - promptWindowSize / 2); - const prefix = lines.slice(0, currentLineIndex + 1).join("\n"); - const suffix = lines.slice(currentLineIndex + 1).join("\n"); - const fimPrompt = createFIMPrompt(prefix, suffix, document.languageId); + const fimPrompt = createFIMPrompt(context, document.languageId); vscode.window.withProgress( { @@ -141,16 +105,21 @@ async function autocompleteCommand(textEditor: vscode.TextEditor, cancellationTo // Remove any FIM tags and leading/trailing whitespace completionText = completionText.replace(/||/g, '').trim(); - - completionText = removeMatchingPrefix(completionText); + // Remove the context lines + const startLine = Math.max(0, position.line - 1); + const endLine = position.line; + const rangeToReplace = new vscode.Range( + new vscode.Position(startLine, 0), + new vscode.Position(endLine, document.lineAt(endLine).text.length) + ); // Apply the edit const edit = new vscode.WorkspaceEdit(); - edit.insert(document.uri, position, completionText); + edit.replace(document.uri, rangeToReplace, completionText); await vscode.workspace.applyEdit(edit); // Move the cursor to the end of the inserted text - const newPosition = position.translate(0, completionText.length); + const newPosition = new vscode.Position(startLine + completionText.split('\n').length - 1, completionText.split('\n').pop()!.length); textEditor.selection = new vscode.Selection(newPosition, newPosition); progress.report({ message: "Fabelous completion finished." }); @@ -165,6 +134,7 @@ async function autocompleteCommand(textEditor: vscode.TextEditor, cancellationTo ); } + async function provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, cancellationToken: vscode.CancellationToken) { const item = new vscode.CompletionItem("Fabelous autocompletion"); item.insertText = new vscode.SnippetString('${1:}'); @@ -176,11 +146,7 @@ async function provideCompletionItems(document: vscode.TextDocument, position: v } const context = getContextLines(document, position); - const lines = context.split("\n"); - const currentLineIndex = position.line - Math.max(0, position.line - promptWindowSize / 2); - const prefix = lines.slice(0, currentLineIndex + 1).join("\n"); - const suffix = lines.slice(currentLineIndex + 1).join("\n"); - const fimPrompt = createFIMPrompt(prefix, suffix, document.languageId); + const fimPrompt = createFIMPrompt(context, document.languageId); try { const response_preview = await axios.post(apiEndpoint, { @@ -200,19 +166,6 @@ async function provideCompletionItems(document: vscode.TextDocument, position: v cancellationToken.onCancellationRequested(() => c("Autocompletion request terminated by completion cancel")); }) }); - - if (response_preview.data.response.trim() !== "") { - let previewText = response_preview.data.response.replace(/||/g, '').trimStart(); - - // Remove matching prefix and repeated function header - const existingContent = document.getText(); - previewText = removeMatchingPrefix(existingContent); - - if (previewText.trim() !== "") { - item.label = previewText; - item.insertText = previewText; - } - } } catch (error) { console.error("Error fetching preview:", error); }