✨ feat(vscode): 代码阅读入口、文件树与预览编辑器
This commit is contained in:
1 parent
4d34b8c715
commit
2b823a32ca
24 files changed
+768
-72
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import type { ExtensionContext, Uri } from 'vscode'
|
||||
import type { CodeReaderApi } from './contract'
|
||||
import { commands, window, workspace } from 'vscode'
|
||||
import { PREVIEW_VIEW_TYPE, PreviewEditorProvider } from './editor/previewEditor'
|
||||
import { FileTreeProvider } from './explorer/fileTree'
|
||||
import { createPythonAdapter } from './languages/python'
|
||||
import { createTypeScriptAdapter } from './languages/typescript'
|
||||
import { CodeReaderRegistry } from './registry'
|
||||
import { bundledWasmDir, TreeSitterRuntime } from './runtime'
|
||||
import { pythonZhTranslator } from './translators/pythonZh'
|
||||
import { typescriptZhTranslator } from './translators/typescriptZh'
|
||||
|
||||
/** 当前语言插件覆盖的 languageId,给 editor/title 的 when 子句判断要不要显示「预览」。 */
|
||||
const LANGUAGE_IDS_CONTEXT = 'superpowers.codeReader.languageIds'
|
||||
const FILES_VIEW = 'superpowers.codeReader.files'
|
||||
const OPEN_COMMAND = 'superpowers.codeReader.open'
|
||||
/** VS Code 自带普通文本编辑器的 editor id。 */
|
||||
const TEXT_EDITOR = 'default'
|
||||
/**
|
||||
* VS Code 自带的「重新打开编辑器的方式」:在原标签页位置换成另一种编辑器。
|
||||
* 原文件有未保存改动也不弹保存框——改动在 TextDocument 里,不跟着标签页走。
|
||||
*/
|
||||
const REOPEN_WITH = 'reopenActiveEditorWith'
|
||||
|
||||
/** 按 VS Code 的判断(含 files.associations)取文件的 languageId;图片等二进制文件打不开成文本,返回 undefined。 */
|
||||
async function languageOf(uri: Uri): Promise<string | undefined> {
|
||||
try {
|
||||
return (await workspace.openTextDocument(uri)).languageId
|
||||
}
|
||||
catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
/** 侧栏点文件:语言受支持就用预览打开,否则用普通编辑器。 */
|
||||
async function openFile(uri: Uri, registry: CodeReaderRegistry): Promise<void> {
|
||||
const languageId = await languageOf(uri)
|
||||
if (languageId !== undefined && registry.languageFor(languageId))
|
||||
// 和 vscode.open 一样按「预览标签」打开(用户关了 workbench.editor.enablePreview 时 VS Code 自会固定)
|
||||
await commands.executeCommand('vscode.openWith', uri, PREVIEW_VIEW_TYPE, { preview: true })
|
||||
else
|
||||
await commands.executeCommand('vscode.open', uri)
|
||||
}
|
||||
|
||||
/**
|
||||
* 接入代码阅读:注册表、侧栏文件树、预览编辑器、编辑器右上角的「预览 / 编辑」切换。
|
||||
* 内置的语言插件和翻译插件与其他扩展一样通过返回的 API 注册。
|
||||
*/
|
||||
export function registerCodeReader(context: ExtensionContext): CodeReaderApi {
|
||||
const registry = new CodeReaderRegistry(context.globalState)
|
||||
const runtime = new TreeSitterRuntime(bundledWasmDir())
|
||||
const previews = new PreviewEditorProvider(context.extensionUri, registry, runtime)
|
||||
const files = new FileTreeProvider(OPEN_COMMAND)
|
||||
|
||||
context.subscriptions.push(
|
||||
registry.onDidChange(() => {
|
||||
void commands.executeCommand('setContext', LANGUAGE_IDS_CONTEXT, registry.languageIds())
|
||||
previews.refresh()
|
||||
}),
|
||||
window.registerCustomEditorProvider(PREVIEW_VIEW_TYPE, previews),
|
||||
files,
|
||||
window.createTreeView(FILES_VIEW, { treeDataProvider: files, showCollapseAll: true }),
|
||||
commands.registerCommand('superpowers.codeReader.refresh', () => files.refresh()),
|
||||
commands.registerCommand(OPEN_COMMAND, (uri: Uri) => openFile(uri, registry)),
|
||||
// 标题栏按钮传来的是 (文件 Uri, { groupId }),原样转给 VS Code 定位是哪一组的哪个标签
|
||||
commands.registerCommand('superpowers.codeReader.showPreview', (...args: unknown[]) =>
|
||||
commands.executeCommand(REOPEN_WITH, PREVIEW_VIEW_TYPE, ...args)),
|
||||
commands.registerCommand('superpowers.codeReader.showSource', (...args: unknown[]) =>
|
||||
commands.executeCommand(REOPEN_WITH, TEXT_EDITOR, ...args)),
|
||||
)
|
||||
|
||||
const api: CodeReaderApi = registry
|
||||
const wasmDir = bundledWasmDir()
|
||||
context.subscriptions.push(
|
||||
api.registerLanguage(createTypeScriptAdapter(wasmDir)),
|
||||
api.registerLanguage(createPythonAdapter(wasmDir)),
|
||||
api.registerTranslator(typescriptZhTranslator),
|
||||
api.registerTranslator(pythonZhTranslator),
|
||||
)
|
||||
return api
|
||||
}
|
||||
Reference in new issue
Block a user