-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tabby-agent): add recent opened files frontend to code completio…
…n requests (#3238) * feat(backend): adding open recent file segments chore: add relevant snippets to client-open-api * feat(protocol): add OpenedFileRequest namespace and types * feat: add FileTracker to code completion and server initialization * feat(fileTracker): adding file tracking provider in lsp server refactor: Add LRUList class to track recently opened files This commit adds a new class called LRUList to track recently opened files in the FileTracker feature. The LRUList class provides methods for inserting, removing, updating, and retrieving files based on their URI. It also maintains a maximum size to limit the number of files stored. The LRUList class is used by the FileTracker feature to keep track of the most recently opened files. When a file is opened or its visibility changes, it is inserted or updated in the LRUList. The list is then pruned to remove the least recently used files if it exceeds the maximum size. This refactor improves the efficiency and organization of the FileTracker feature by separating the logic for tracking files into a dedicated class. * feat(vscode): implement FileTrackerProvider class for tracking visible editors This commit adds a new class called FileTrackerProvider in the vscode/src directory. The FileTrackerProvider class is responsible for collecting visible editors and their visible ranges. It filters out editors that do not have a file name starting with a forward slash ("/"). The collected editors are then sorted based on their URI, with the active editor being prioritized. The FileTrackerProvider class also provides a method to collect the active editor, which returns the URI and visible range of the currently active text editor. These changes are part of the ongoing development of the FileTracker feature, which aims to track and manage recently opened files in the vscode extension. Ref: feat(fileTracker): adding file tracking provider in lsp server * feat(vscode): implement FileTrackerProvider class for tracking visible editors * feat: update snippet count check in extract_snippets_from_segments * feat: adding configuration to recently opened file enable collection of snippets from recent opened files This commit enables the collection of snippets from recent opened files in the CompletionProvider class. It adds a new configuration option `collectSnippetsFromRecentOpenedFiles` to the default configuration, which is set to `true` by default. The maximum number of opened files to collect snippets from is set to 5. These changes are necessary to improve the code completion feature by including snippets from recently opened files. Ref: feat(recent-opened-files): enable collection of snippets from recent opened files * [autofix.ci] apply automated fixes * refactor: using lru-cache package and passing config * fix: fixing typo, remove unuse type * refactor: remove action and rename the notification * feat(config): add maxCharsPerOpenedFiles to default config data. * refactor: optimize code snippet collection algorithm in CompletionProvider. adding max chars size per opened files * chore: remove unused log chore: remove logger import --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
- Loading branch information
1 parent
dac6145
commit 5dfe7a1
Showing
11 changed files
with
379 additions
and
2 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { Connection, Range } from "vscode-languageserver"; | ||
import { Feature } from "../feature"; | ||
import { DidChangeActiveEditorNotification, DidChangeActiveEditorParams, ServerCapabilities } from "../protocol"; | ||
import { Configurations } from "../config"; | ||
import { LRUCache } from "lru-cache"; | ||
import { isRangeEqual } from "../utils/range"; | ||
|
||
interface OpenedFile { | ||
uri: string; | ||
//order by range, the left most is the most recent one | ||
lastVisibleRange: Range[]; | ||
invisible: boolean; | ||
isActive: boolean; | ||
} | ||
|
||
export class FileTracker implements Feature { | ||
private fileList = new LRUCache<string, OpenedFile>({ | ||
max: this.configurations.getMergedConfig().completion.prompt.collectSnippetsFromRecentOpenedFiles.maxOpenedFiles, | ||
}); | ||
|
||
constructor(private readonly configurations: Configurations) {} | ||
initialize(connection: Connection): ServerCapabilities | Promise<ServerCapabilities> { | ||
connection.onNotification(DidChangeActiveEditorNotification.type, (param: DidChangeActiveEditorParams) => { | ||
this.resolveChangedFile(param); | ||
}); | ||
return {}; | ||
} | ||
|
||
resolveChangedFile(param: DidChangeActiveEditorParams) { | ||
const { activeEditor, visibleEditors } = param; | ||
|
||
const visitedPaths = new Set<string>(); | ||
|
||
//get all visible editors | ||
if (visibleEditors) { | ||
visibleEditors.forEach((editor) => { | ||
const visibleFile = this.fileList.get(editor.uri); | ||
if (visibleFile) { | ||
visibleFile.lastVisibleRange = []; | ||
} | ||
}); | ||
|
||
visibleEditors.forEach((editor) => { | ||
let visibleFile = this.fileList.get(editor.uri); | ||
if (!visibleFile) { | ||
visibleFile = { | ||
uri: editor.uri, | ||
lastVisibleRange: [editor.range], | ||
invisible: false, | ||
isActive: false, | ||
}; | ||
this.fileList.set(editor.uri, visibleFile); | ||
} else { | ||
if (visitedPaths.has(visibleFile.uri)) { | ||
const idx = visibleFile.lastVisibleRange.findIndex((range) => isRangeEqual(range, editor.range)); | ||
if (idx === -1) { | ||
visibleFile.lastVisibleRange = [editor.range, ...visibleFile.lastVisibleRange]; | ||
} | ||
visibleFile.invisible = false; | ||
} else { | ||
visibleFile.invisible = false; | ||
visibleFile.lastVisibleRange = [editor.range]; | ||
} | ||
} | ||
visitedPaths.add(visibleFile.uri); | ||
}); | ||
} | ||
|
||
// //get active editor | ||
let file = this.fileList.get(activeEditor.uri); | ||
if (!file) { | ||
file = { | ||
uri: activeEditor.uri, | ||
lastVisibleRange: [activeEditor.range], | ||
invisible: false, | ||
isActive: true, | ||
}; | ||
this.fileList.set(activeEditor.uri, file); | ||
} else { | ||
if (visitedPaths.has(file.uri)) { | ||
const idx = file.lastVisibleRange.findIndex((range) => isRangeEqual(range, activeEditor.range)); | ||
if (idx === -1) { | ||
file.lastVisibleRange = [activeEditor.range, ...file.lastVisibleRange]; | ||
} | ||
} else { | ||
file.lastVisibleRange = [activeEditor.range]; | ||
} | ||
file.invisible = false; | ||
file.isActive = true; | ||
} | ||
visitedPaths.add(file.uri); | ||
|
||
//set invisible flag for all files that are not in the current file list | ||
Array.from(this.fileList.values()) | ||
.filter(this.isOpenedFile) | ||
.forEach((file) => { | ||
if (!visitedPaths.has(file.uri)) { | ||
file.invisible = true; | ||
} | ||
if (file.uri !== activeEditor.uri) { | ||
file.isActive = false; | ||
} | ||
}); | ||
} | ||
private isOpenedFile(file: unknown): file is OpenedFile { | ||
return (file as OpenedFile).uri !== undefined; | ||
} | ||
|
||
/** | ||
* Return All recently opened files by order. [recently opened, ..., oldest] without active file | ||
* @returns return all recently opened files by order | ||
*/ | ||
getAllFilesWithoutActive(): OpenedFile[] { | ||
return Array.from(this.fileList.values()) | ||
.filter(this.isOpenedFile) | ||
.filter((f) => !f.isActive); | ||
} | ||
} |
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 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
Oops, something went wrong.