VS Code源码学习(一):运行&创建菜单&简单命令实现

219 阅读3分钟
  1. windows安装

1.在安装之前注意安装python3.8-3.11,node-gyp兼容性最好,安装时选择add path && customer init

2.注意node版本>= 20.18.1 ,注意在visual studio安装时,单个组件选择x86 Spectre修补漏洞

  • MSVC v143 - VS 2022 C++ x64/x86 Spectre-mitigated libs (Latest) (use ARM64 for Windows on ARM, but the x64/x86 may still be needed)
  • C++ ATL for latest build tools with Spectre Mitigations
  • C++ MFC for latest build tools with Spectre Mitigations

3.安装@vscode/ripgrep时总是报错properties undefined,找到存放zip包的文件目录,检查此目录的权限,完全控制,且不勾选只读。

4.有问题参考How-to-Contribute

  1. 运行图形界面

1.npm run watch

2.运行 .\scripts\code.bat .\scripts\code-cli.bat 得到图形化界面

3.调试

  • 打开vscode存储库文件夹
  • VS Code从调试视图中的启动下拉菜单中选择启动配置,然后按F5
  • 更改内容需要查看最新内容就按刷新

  1. 开始学习代码

  1. 菜单如何建造

  1. VS Code的菜单系统是基于命令(Command)的,所以通常需要先注册命令,然后才能将其添加到菜单中
  2. 本地化(localization)是很重要的部分,应该使用localize函数来支持多语言
  3. 菜单项可以通过order属性来控制顺序
  4. 可以使用when子句来控制菜单项的可见性
  5. 菜单项可以分组(group)来更好地组织
// 1. 首先在某个合适的地方定义MenuId
export const MenuId = {
    // ... 其他MenuId
    MenubarToolsMenu: new MenuId('MenubarToolsMenu')
};

// 2. 注册主菜单项
MenuRegistry.appendMenuItem(MenuId.MenubarMainMenu, {
    submenu: MenuId.MenubarToolsMenu,
    title: {
        value: 'Tools',
        original: 'Tools',
        mnemonicTitle: localize({ key: 'mTools', comment: ['&& denotes a mnemonic'] }, "&&Tools")
    },
    order: 7  // 在其他菜单后面
});

// 3. 添加子菜单项
MenuRegistry.appendMenuItem(MenuId.MenubarToolsMenu, {
    group: '1_tools',
    command: {
        id: 'tools.someCommand',
        title: localize('tools.command', "Some Tool Command")
    },
    order: 1

});

2. ### 创建一个命令

  1. 命令注册: 使用registerAction2注册一个新的命令

  2. 命令配置:

    1. id: 命令的唯一标识符
    2. title: 命令的显示名称
    3. category: 命令的分类
    4. f1: 是否在命令面板中显示
    5. keybinding: 快捷键绑定
    6. menu: 在哪个菜单中显示
  3. 命令实现: 在run方法中实现具体的命令逻辑

  4. 参照newFile功能添加hello world

/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import { KeyMod, KeyCode } from '../../../../base/common/keyCodes.js';
import { localize2 } from '../../../../nls.js';
import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js';
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { INotificationService, } from '../../../../platform/notification/common/notification.js';

// 定义命令的分类
const category = localize2('tools', "Hello World");

// 注册命令
registerAction2(class extends Action2 {
    constructor() {
        super({
            id: 'tools.someCommand', // 命令的唯一标识符
            title: localize2('tools.someCommand', "Show tools someCommand"), // 命令的标题
            category, // 命令的分类
            f1: true, // 是否在命令面板(F1)中显示
            keybinding: { // 快捷键绑定
                primary: KeyMod.CtrlCmd | KeyCode.KeyH,
                weight: KeybindingWeight.WorkbenchContrib,
                when: undefined // 可以添加显示条件
            },
            menu: { // 菜单配置
                id: MenuId.MenubarHelpMenu, // 将命令添加到帮助菜单
                group: 'navigation', // 菜单分组
                order: 1 // 排序
            }
        });
    }

    // 命令执行的具体逻辑
    async run(accessor: ServicesAccessor): Promise<void> {
        const notificationService = accessor.get(INotificationService);
        notificationService.info('Hello World!');
    }
});


import './contrib/tools/browser/tools.contribution.js';