vscode 搜索 历史记录 导出功能 保存的位置 试图实现

先说结论

C:\Users\...\AppData\Roaming\Code\User\workspaceStorage

这个文件夹下有一些digest英文字母文件夹

一般按修改时间排序就能找到自己所想要导出的项目

里边有俩文件

workspace.json就是纯文本

state.vscdb是个SQLite数据库,可以用DB Browser for SQLite打开

里边的workbench.search.history即保存了搜索历史记录

 

 

下拉列表

https://github.com/microsoft/vscode/issues/23099

首先看上边这个issues,是请求搜索历史的下拉列表,7年了还没实现,我自己研究研究吧

history.ts

https://github.com/microsoft/vscode/blob/main/src/vs/base/common/history.ts

这个文件 两个class

主要看上边这个class

 

下边的HistoryNavigator2,是SCM用的

https://github.com/microsoft/vscode/commit/4af42491069dcbf0881b7993ee18a180b790f861

https://github.com/microsoft/vscode/blob/9c3cc8b9948d52f04836997a7de01dbd9bb2a7bf/src/vs/workbench/contrib/interactive/browser/interactiveHistoryService.ts#L6

 

SCM 通常指的是版本控制系统(Source Code Management)

大概是指左侧栏的源代码管理里的搜索

 

 

相关代码

https://github.com/microsoft/vscode/blob/main/src/vs/base/browser/ui/inputbox/inputBox.ts

https://github.com/microsoft/vscode/blob/main/src/vs/workbench/parts/search/browser/searchWidget.ts

https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/interactive/browser/interactiveHistoryService.ts

 

HistoryInputBox

调用层次/调用关系:(vscode没法同时看call和called两个方向)(发现这个call hierarchy调用层次结构,识别的不对。。。会缺少一些调用方。用查找引用就能找到)

 

abstractTree.ts

src\vs\base\browser\ui\tree\abstractTree.ts

我仔细看了看,发现这个文件里的这个FindWidget不太对,对应的是

https://superuser.com/questions/1748097/vs-code-disable-tree-view-find-explorer-search

 

 

FindInput

vs\base\browser\ui\findinput\findInput.ts

extends的结果 调用层次结构识别不到

 

 

vs\workbench\contrib\search\browser\searchWidget.ts

 

vs\workbench\contrib\search\browser\searchView.ts

 

 

终于找到了(好像不太对)

  /**
   * 每当在给定范围和可选键上更新或删除数据时触发。
   *
   * @param scope the `StorageScope` to listen to changes
   * @param key the optional key to filter for or all keys of  the scope if `undefined`
   */
  onDidChangeValue
 
    this._register(this.storageService.onDidChangeValue(StorageScope.WORKSPACE, SearchHistoryService.SEARCH_HISTORY_KEY, this._register(new DisposableStore()))(() => {
      const restoredHistory = this.searchHistoryService.load();

      if (restoredHistory.include) {
        this.inputPatternIncludes.prependHistory(restoredHistory.include);
      }
      if (restoredHistory.exclude) {
        this.inputPatternExcludes.prependHistory(restoredHistory.exclude);
      }
      if (restoredHistory.search) {
        this.searchWidget.prependSearchHistory(restoredHistory.search);
      }
      if (restoredHistory.replace) {
        this.searchWidget.prependReplaceHistory(restoredHistory.replace);
      }
    }));
 
 

vs\workbench\contrib\search\common\searchHistoryService.ts

 
 
调用方意思就是,下边的子项函数会调用load
调用来自意思就是,load会调用下边的子项函数
 
 
 
export class SearchHistoryService implements ISearchHistoryService { // 前边带大写字母I的都是interface接口
  declare readonly _serviceBrand: undefined;

  public static readonly SEARCH_HISTORY_KEY = 'workbench.search.history';

  private readonly _onDidClearHistory = new Emitter<void>();
  readonly onDidClearHistory: Event<void> = this._onDidClearHistory.event;

  constructor(
    @IStorageService private readonly storageService: IStorageService
  ) { }

  clearHistory(): void {
    this.storageService.remove(SearchHistoryService.SEARCH_HISTORY_KEY, StorageScope.WORKSPACE);
    this._onDidClearHistory.fire();
  }

  load(): ISearchHistoryValues {
    let result: ISearchHistoryValues | undefined;
    const raw = this.storageService.get(SearchHistoryService.SEARCH_HISTORY_KEY, StorageScope.WORKSPACE);
 
 

@IStorageService

export const IStorageService = createDecorator<IStorageService>('storageService');
这块装饰器createDecorator太复杂了,以及SearchHistoryService什么时候创建/初始化的的问题,涉及到vscode整个的设计、依赖注入,我看了看没太看懂
具体可见下边的链接
 
https://imwangfu.com/2022/05/vscode-di2.html
https://zhuanlan.zhihu.com/p/96902077
 
 
 

vs\workbench\contrib\search\browser\search.contribution.ts

 
registerSingleton(ISearchHistoryService, SearchHistoryService, InstantiationType.Delayed);
这种情况,调用层次识别不到
 
这段代码看起来是在某个依赖注入容器中注册一个单例服务的操作。让我解释一下其中的各个部分:
- `registerSingleton`: 这是一个函数或方法,用于在依赖注入容器中注册一个单例服务。通常,依赖注入容器用于管理应用程序中的依赖关系,并在需要时提供相应的实例。
- `ISearchHistoryService`: 这是一个接口(或抽象类)的引用,它定义了一个搜索历史服务的契约或合同。在依赖注入中,通常会使用接口或抽象类来描述服务的行为,而具体的实现则通过实现该接口或继承该抽象类来完成。
- `SearchHistoryService`: 这是实现了 `ISearchHistoryService` 接口的具体服务类的引用。它是实际提供服务的类,其中包含了实现了搜索历史功能的代码。
- `InstantiationType.Delayed`: 这是一个参数,用于指定服务的实例化方式。在这种情况下,`Delayed` 可能表示延迟实例化,即在需要时才会创建服务的实例。这种实例化方式可以帮助优化性能,避免在应用程序启动时就创建所有的服务实例。
综合起来,这段代码的作用是在依赖注入容器中注册一个单例服务,该服务实现了 `ISearchHistoryService` 接口,并使用延迟实例化方式。这样,在应用程序中的其他地方就可以通过依赖注入容器获取 `ISearchHistoryService` 接口的实例,并使用其中定义的方法来访问搜索历史记录。
 
 
 

ticino.blob.core.windows.net

动态语言有个优点就是好调试,c/c++还得整个编译一个带调试符号的版本exe,否则符号信息/函数名全没了,就剩下汇编。js编译后好歹还会剩下一些高级语言的特征。
而且vscode这里的调试sourcemap还能自动加载官方提供的,不必像vue那样重新编译一遍出来符号,官方不提供sourcemap。
 
 
 
 

typescript 继承 编译为js

 
export class Component extends Themable {
 
this._register(storageService.onWillSaveState(() => {
 
// Ask the component to persist state into the memento
this.saveState();
 
 
export class ViewPaneContainer extends Component implements IViewPaneContainer {
    protected override saveState(): void {
        this.panes.forEach((view) => view.saveState());
        this.storageService.store(this.visibleViewsStorageId, this.length, StorageScope.WORKSPACE, StorageTarget.MACHINE);
    }
 
这里ViewPaneContainer继承了Component,在js实际运行时,调用栈是这样的(调用栈这里显示的没有替换为sourcemap的原始函数名)
 
是Component的saveState函数调用了ViewPaneContainer的saveState函数(跟我以前java中的重写不太一样,应该是js原生不支持继承所以转换成了这样)

调用层次结构

 
还是就是vscode的调用层次结构,对这种 接口/抽象类 类型的成员变量.调用一个方法(实际是多态,父类型引用指向子类型的实例,子类重写该方法),这种情况,根本识别不出来
 
(parameter) view: ViewPane
this.panes.forEach((view) => view.saveState());
 
export abstract class ViewPane extends Pane implements IView {
 
export class SearchView extends ViewPane {
 
 
 
 
 

vs\workbench\contrib\search\common\searchHistoryService.ts

vs\platform\storage\common\storage.ts

 
export interface ISearchHistoryService {
  readonly _serviceBrand: undefined;
  onDidClearHistory: Event<void>;
  clearHistory(): void;
  load(): ISearchHistoryValues;
  save(history: ISearchHistoryValues): void;
}
 
 
在save上点击查找所有实现,找不到重写的save方法。需要点击查找所有引用
 
 
 
 
 
 
 

vs\platform\storage\common\storageService.ts

 
对于override导致的多态,导致调用层次结构无法识别的问题。反向是能识别的,但是正向识别不了,大概是因为由于多态,不确定在多个重写的方法中到底用哪个。
 
 
 

vs\base\parts\storage\common\storage.ts

 
 
 
 this.pendingInserts.set(key, valueStr);
 
posted @ 2024-03-12 13:00  hrdom  阅读(627)  评论(0编辑  收藏  举报