✨ feat(vscode): 代码阅读预览里工作区外的库文件也能问 AI,问答记进第一个工作区文件夹,重写注释不对库文件开放
This commit is contained in:
1 parent
cecae0e244
commit
39dfd9b084
24 files changed
+463
-79
No files matched your search
@@ -1,7 +1,9 @@
|
||||
import type { FileDeleteEvent, FileRenameEvent, WorkspaceFolder } from 'vscode'
|
||||
import type { PathMap, PathMapFile } from './pathMap'
|
||||
import { homedir } from 'node:os'
|
||||
import * as path from 'node:path'
|
||||
import { Disposable, EventEmitter, RelativePattern, Uri, window, workspace } from 'vscode'
|
||||
import { changedKeys, detachedFiles, dropEntries, entriesUnder, moveEntries, placeEntries, readPathMap, removeFiles, toPathKey, writePathMap } from './pathMap'
|
||||
import { changedKeys, detachedFiles, dropEntries, entriesUnder, moveEntries, outsideKey, outsidePath, placeEntries, readPathMap, removeFiles, toPathKey, writePathMap } from './pathMap'
|
||||
|
||||
/** 一个文件 / 目录在哪个工作区文件夹里、键是什么。 */
|
||||
export interface PathLocation {
|
||||
@@ -16,6 +18,41 @@ export function locate(uri: Uri): PathLocation | undefined {
|
||||
return folder && key !== undefined ? { folder, key } : undefined
|
||||
}
|
||||
|
||||
/** 一份文件的问答记在哪(见 [locateQa]),和问的时候怎么跟模型说这份文件。 */
|
||||
export interface QaLocation extends PathLocation {
|
||||
/** 发给模型时这份文件写成什么:工作区里的写相对路径(同 key),工作区外的写绝对路径 */
|
||||
promptPath: string
|
||||
/** 工作区外的文件所在的目录:claude 在 folder 里跑,要另外放行读这个目录;工作区里的文件没有 */
|
||||
outsideDir?: string
|
||||
}
|
||||
|
||||
/** 家目录的 `Uri.path`:工作区外的文件在它下面时,键写成 `~/…`(见 [outsideKey])。 */
|
||||
function homePath(): string {
|
||||
return Uri.file(homedir()).path
|
||||
}
|
||||
|
||||
/**
|
||||
* 一份文件的问答记在哪。工作区里的同 [locate]。
|
||||
* 工作区外的(比如 ⌘ 点进去的库源码)记在第一个工作区文件夹,固定用第一个,同一个库文件每次都落在同一处;键见 [outsideKey]。
|
||||
* 没打开工作区文件夹、`uri` 就是工作区文件夹本身、`uri` 不是工作区里那种文件(比如 `git:` 的)时返回 `undefined`。
|
||||
*/
|
||||
export function locateQa(uri: Uri): QaLocation | undefined {
|
||||
if (workspace.getWorkspaceFolder(uri)) {
|
||||
const at = locate(uri)
|
||||
return at && { ...at, promptPath: at.key }
|
||||
}
|
||||
const folder = workspace.workspaceFolders?.[0]
|
||||
if (!folder || uri.scheme !== folder.uri.scheme || uri.authority !== folder.uri.authority)
|
||||
return undefined
|
||||
return { folder, key: outsideKey(uri.path, homePath()), promptPath: uri.fsPath, outsideDir: path.dirname(uri.fsPath) }
|
||||
}
|
||||
|
||||
/** 表里的 `key` 指的那个文件 / 目录:工作区外的键(`~/…`、绝对路径)还原成磁盘上的位置,别的在 `folder` 下面。 */
|
||||
export function keyUri(folder: WorkspaceFolder, key: string): Uri {
|
||||
const outside = outsidePath(key, homePath())
|
||||
return outside === undefined ? Uri.joinPath(folder.uri, ...key.split('/')) : folder.uri.with({ path: outside })
|
||||
}
|
||||
|
||||
/**
|
||||
* 每个工作区文件夹一份的按路径记的表(见 pathMap):内存里留一份给界面同步取用。
|
||||
* 在 VS Code 里改名、挪位置,条目跟着走;删掉就一起删。外部改了文件(git pull、手改)按文件重读。
|
||||
@@ -130,7 +167,7 @@ export class FolderStore<T> implements Disposable {
|
||||
const keys = changedKeys(this.maps.get(id) ?? {}, map)
|
||||
this.maps.set(id, map)
|
||||
if (keys.length > 0)
|
||||
this.changed.fire(keys.map(key => Uri.joinPath(folder.uri, ...key.split('/'))))
|
||||
this.changed.fire(keys.map(key => keyUri(folder, key)))
|
||||
}
|
||||
|
||||
private enqueue(task: () => Promise<void>): Promise<void> {
|
||||
|
||||
Reference in new issue
Block a user