diff --git a/user-guide/files/resources/extension-dev/yocode-1.png b/user-guide/files/resources/extension-dev/yocode-1.png new file mode 100644 index 0000000..6ce0a0d Binary files /dev/null and b/user-guide/files/resources/extension-dev/yocode-1.png differ diff --git a/user-guide/files/resources/extension-dev/yocode.png b/user-guide/files/resources/extension-dev/yocode.png new file mode 100644 index 0000000..61ea52e Binary files /dev/null and b/user-guide/files/resources/extension-dev/yocode.png differ diff --git a/user-guide/files/如何配置工程的构建-调试-运行.md b/user-guide/files/如何配置工程的构建-调试-运行.md new file mode 100644 index 0000000..3569758 --- /dev/null +++ b/user-guide/files/如何配置工程的构建-调试-运行.md @@ -0,0 +1,729 @@ +# 如何配置工程的构建、调试、运行 +## 目录结构 +- [概述](#概述) +- [task.json](#taskjson) + * [简单理解](#简单理解) + * [task.json文件创建方法](#taskjson文件创建方法) + * [简单例子](#简单例子) + * [关键字提示和补全](#关键字提示和补全) + * [主要关键字(或称为字段、属性)说明(按字母序)](#主要关键字或称为字段属性说明按字母序) + * [使用变量](#使用变量) + * [task.json例子](#taskjson例子) +- [launch.json](#launchjson) + * [对launch.json的简单理解](#对launchjson的简单理解) + * [launch.json文件创建方法](#launchjson文件创建方法) + * [launch.json的简单例子](#launchjson的简单例子) + * [关键字(或称为属性、参数、字段)说明](#关键字或称为属性参数字段说明) +- [变量](#变量) + * [变量简介](#变量简介) + * [主要预置变量说明](#主要预置变量说明) + * [环境变量](#环境变量) + * [配置类变量](#配置类变量) + * [命令变量](#命令变量) + * [输入变量](#输入变量) + * [查看变量值](#查看变量值) +- [附录](#附录) + * [task.json参考例子](#taskjson参考例子) + * [launch.json参考例子](#launchjson参考例子) +- [VSCode相关内容参考链接](#vscode相关内容参考链接) + +## 概述 +- 任意一个工程,如何在Kylin-IDE中构建、调试、运行? + * 针对一些特殊工程 + - 支持插件中做了自动化支持,构建、调试、运行可以通过支持插件直接操作,不需配置 + * 例如qt-support插件对qmake和cmake类型的qt工程的构建、调试、运行做了自动化处理,可以直接操作而不配置 + * 工程的一般配置方法 + - 继承了Code-OSS的相关功能,需要了解两个配置文件的使用方法:task.json和launch.json + - 调试参数定义在launch.json中;构建、打包、自动化测试、部署等过程定义在task.json中;运行可以定义在launch.json中也可以定义在task.json中 +- task.json和launch.json文件位置 + * 两个配置文件放置在工程根目录的.vscode/目录下(前缀带了“.”,表示是隐藏目录) + +## task.json +### 简单理解 +- ***定义了如何“按顺序执行命令”。工程的构建、打包、自动化测试、部署方法根据工程类型各不相同,可以使用各种系统工具,例如C代码可以使用make工具构建,java代码可以使用maven工具构建,可以使用jar命令打包,但这些过程都可以抽象为按顺序调用系统工具执行多个命令。task.json就是定义如何使用系统工具执行命令的过程,将“按顺序调用系统工具执行多个命令”按照格式定义了出来*** + * task.json中定义了一个任务列表,把整个工具调用过程拆分成了多个任务(task) + * 每一个task定义了一条命令(工具)的执行,这条命令也可以是命令的组合,由用户控制。即只要知晓项目构建过程使用的工具命令,就可以定义出task + * task之间可以定义依赖关系,即task的执行顺序 +*** + +### task.json文件创建方法 +- 方法一(推荐):安装Kylin Project Manager插件,在左侧的“项目操作区”中点击“配置当前项目”,根据选项做操作 +- 方法二:选择主菜单中的“终端”、“运行生成任务”、“...配置生成任务...”、“使用模板创建task.json文件”、“Others” +- 方法三:直接新建task.json文件,或从其他工程中拷贝一个task.json,放置于工程根目录的.vscode/目录下 + +### 简单例子 +- task.json简单例子 + * 例如,一个简单的C++工程hello-world,仅有一个C++代码文件hello.cpp + + ```cpp + #include + + int main(int argc, char *argv[]) + { + std::cout << "Hello world!" << std::endl; + } + ``` + * 其带调试信息的构建命令为:gcc -g hello.cpp -o hello + * 其task.json可以定义为: + ```json + { + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "linux": { + "command": "g++", + "args": [ + "-g", + "hello.cpp", + "-o", + "hello" + ] + } + }, + { + "label": "run", + "type": "shell", + "dependsOn": ["build"], + "linux": { + "command": "./hello" + } + } + ] + } + ``` + * 最关键的信息(关键字,或称为属性或字段) + - tasks:定义了任务列表,其中每个大括号中的内容定义了一个task + - label:定义了单个task的名称(或称为标签),名称很重要,当执行任务时,需要根据名称来选择到底执行哪个任务;依赖关系也通过名称来定义 + - command:定义了具体的命令,例如build任务定义了gcc -g hello.cpp -o hello命令,run任务定义了./hello命令。可以将命令和参数组合在一起,写入command字段,也可以将命令和参数分开写入command和args字段,两种方式执行命令方式不同,但效果类似,但不能混用(指:不能在commands中写一半命令,再在args中写另外一半命令参数) + - dependsOn:定义了任务之间的依赖关系,例如run任务依赖于build任务,即run任务需要在build任务执行完成之后才能执行 + +### 关键字提示和补全 +- 提示:鼠标放在已有字段上,会出现字段的含义提示 +- 补全:编辑时,关键字可以补全。默认的快捷键ctrl+space可以弹出关键字列表,但由于和系统切换输入法默认快捷键冲突,可以使用以下方式解决 + - 修改切换输入法快捷键(推荐):右键右下角输入法图标,选择配置,全局配置,修改切换输入法快捷键为右ctrl + - 修改Kylin-IDE快捷键:点击左下角齿轮图标,选择“键盘快捷方式”,在筛选框左侧点击第一个图标,用录制按键搜索快捷键,按下ctrl+space,将搜索结果中的“触发建议”快捷键改为希望的快捷键 + +### 主要关键字(或称为字段、属性)说明(按字母序) +* args: command(命令)的参数,每个参数以英文逗号分隔。若使用此参数,则command字段会被解读为可执行文件,故此时不要在command字段中添加命令参数 +* command:定义了具体的命令,例如build任务定义了gcc -g hello.cpp -o hello命令,run任务定义了./hello命令。可以将命令和参数组合在一起,写入command字段,也可以将命令和参数分开写入command和args字段,两种方式执行命令方式不同,但效果类似,但不能混用(指:不能在commands中写一半命令,再在args中写另外一半命令参数) +* dependsOn:在运行当前task前,先运行哪些task,或理解为当前task的依赖task。数组字段,可列多个,默认并行执行,若dependsOrder字段设置为sequence,则按列举顺序执行 +* dependsOrder:当dependsOn字段设置了多个依赖task,此字段决定多个依赖task是并行执行还是按列举顺序执行,值可为:parallel、sequence +* detail:提供关于当前task的详细描述,帮助用户理解这个任务的目的,在选择任务时会显示作为提示 +* echoCommand:用于在task执行时输出命令的详细信息。如果设置为 true,则在任务执行时会在输出面板中显示正在执行的命令。默认为true +* hide:控制task在task列表中的可见性。如果设置为 true,则该task不会在task列表中显示。当用户不希望直接执行某个task时,可以使用此参数 +* icon:为任务指定一个图标,可以使用图标来增强任务在UI中的可视化效果,帮助用户快速识别任务。其值是对象类型,在json中使用大括号,大括号内部的字段见下文 + - color:颜色 + - id:预置图标id +* inputs:输入变量相关内容,见下文变量中的输入变量相关章节 +* isBackground:指示task是否在后台运行,如果设置为true,则任务会在后台运行,Kylin-IDE不会等待其完成,适用于长时间运行的任务 +* label:定义了单个task的名称(或称为标签),名称很重要,当执行任务时,需要根据名称来选择到底执行哪个任务;依赖关系也通过名称来定义 +* linux:Kylin-IDE目前仅服务于类Linux操作系统,故此参数可以不用。用于指定在特定操作系统类型下执行,当程序在多平台运行时可以针对特定操作系统执行不同的命令。类似的还有windows(Windows)、osx(MacOS)。通常用于command字段外层 +* options:其值为对象类型,用大括号表示,可以设置env、cwd、shell三个字段,字段说明见下文。此关键字可以用在单个task内,设置task的属性,也可以用于单个task外,全局生效。也可以用于平台关键字内(linux、windows、osx),但Kylin-IDE目前仅服务于类Linux操作系统,故用于平台关键字内并无太大意义 + - env:设置环境变量。在此设置的环境变量仅对task中的脚本、进程起作用,对task中的字段、参数等无效 + - cwd:设置当前工作路径。例如,当两个task的工作路径不同时,可以为每个task设置cwd参数 + - shell:设置执行命令使用的shell + - 例子 + ```json + "options": { + "shell": { + "executable": "/bin/bash", // 指定使用的 shell + "args": ["-c"] // 传递给 shell 的参数 + }, + "cwd": "${workspaceFolder}/src", + "env": { + "MY_ENV_VAR":"some_value" + } + } + + ``` +* osx:见linux关键字 +* presentation:配置task执行时输出的显示方式 + - reveal:是否在集成的terminal(终端)中显示task执行的输出 + * always:总是显示在终端中,如果未打开终端则打开 + * never:如果未打开终端,则在终端显示输出 + * silent:如果未打开终端,仅在扫描到错误或警告时,在终端显示,否则不在终端显示 + - revealProblems:task运行时,是否先显示问题面板。此选项优先于reveal,如果设置了always会则先显示问题面板 + * always:总是显示问题面板,而不是终端 + * never:不主动显示问题面板 + * onProblem:仅在发现问题时显示问题面板 + - echo:是否显示执行的命令 + - focus:执行完成后,光标是否聚焦在终端输出 + - panel:多个task执行时,是否复用终端 + * shared:多个task执行时的信息共享显示在同一个终端中 + * dedicated:同一个task多次执行,信息显示在同一个终端中;不同task显示在不同终端中 + * new:每次task执行,都使用新终端 + - showReuseMessage:task执行完成后是否提示“终端将被任务重用,按任意键关闭。” + - clear:task执行前是否clear终端 + - close:task执行结束后终端是否退出 + - group:在同一个组(group)内的task,当需要新建终端时,终端分割(split)显示 + - 例子 + ```json + "presentation": { + "reveal": "always", // 总是显示终端输出 + "echo": true, // 显示命令 + "focus": true, // 自动聚焦到终端输出 + "panel": "shared" // 共享终端 + } + ``` +* problemMatcher:问题捕获器,捕获到的问题显示在问题面板中。task在执行时,它的输出可能会报出错误和警告,此功能用于捕获这些错误和警告,建立捕获到的错误警告和代码文件、代码位置、严重程度、问题信息的关系。Kylin-IDE已经集成了常见工具的问题捕获功能,但task执行工具各种各样,会出现未处理的工具或可以自己定义工具输出的问题捕获功能,此时可以通过自定义问题捕获器实现工具输出的问题捕获。问题捕获功能主要通过正则表达式定义和实现 + - 问题捕获的关键字用例子的方法说明 + - 例子,Kylin Clangd插件已提供了g++、gcc的问题捕获器功能,不需要自行定义,下文仅作为例子说明 + * 上文简单的hello.cpp中,故意在cout上方写一行错误的代码 + ```cpp + #include + + int main(int argc, char *argv[]) + { + printf + std::cout << "Hello world!" << std::endl; + } + ``` + * 执行上文的build任务,使用g++构建时会提示: + ``` + hello.cpp:5:7: error: expected ‘;’ before ‘std’ + ``` + * 可以在build任务中添加如下问题捕获器,将会显示在问题面板中 + ```json + "problemMatcher": { + //问题捕获器的所有者,通常是特定的语言或工具,例如cpp、javascript + "owner": "cpp", + //文件位置,是当前工作区的相对路径(也可以设置为绝对路径),与下文的file相关 + "fileLocation": ["relative", "${workspaceFolder}"], + //source的值会显示在问题的最后方,提示问题是哪个问题捕获器发现的 + "source": "g++", + //问题捕获器针对工具输出格式的模式(pattern)定义 + "pattern": { + //针对g++的输出信息格式的正则表达式(hello.cpp:5:7: error: expected ‘;’ before ‘std’) + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + //问题出现的文件,会被第1个匹配组捕获,是文件的相对路径 + "file": 1, + //问题出现的行号,会被第2个匹配组捕获 + "line": 2, + //问题出现的列号,会被第3个匹配组捕获 + "column": 3, + // The fourth match group matches the problem's severity. Can be ignored. Then all problems are captured as errors. + //问题严重程度,会被第4个匹配组捕获。可以不加此参数,所有问题按error处理 + "severity": 4, + //问题具体信息,会被第5个匹配组捕获 + "message": 5 + } + } + ``` +* runOptions:设置task运行时机、如何运行 + - runOn:task运行时机 + * default:仅在主动选择时运行,默认是此值 + * folderOpen:当打开文件夹时运行 + - reevaluateOnRerun:在命令面板中执行Rerun Last Task命令时,是否重新计算变量值。true表示重新计算(默认为true),false表示不重新计算 + - instanceLimit:允许当前task有几个运行实例,即同一个task可以同时运行几个。有些task执行时间较长,并且可以重复执行,此字段用于设置限制,以避免系统资源消耗过大 +* tasks:task列表 +* type:表示task的类型,类型不同,可选的字段会有区别。主要的值是shell、process,这两个值适合用户自定义task,此外还有npm、typescript、用于javascript自动化任务的gulp、grunt、jake + - shell:命令(command)将作为shell命令执行(bash等) + - process:command字段将作为一个程序名执行,不能使用shell的一些特性,例如管道“|”等 +* version:task.json格式版本,目前为2.0.0 +* windows:见linux关键字 + +### 使用变量 +- task.json中部分字段可以使用变量,变量在task.json中的task运行时会替换为变量指代的内容,详细内容见下文“变量章节” + +### task.json例子 +- 下文附录章节中有一个比较全的例子供参考 +- 后续会针对典型场景补充task.json的例子,以方便参考和复制 + +## launch.json +### 对launch.json的简单理解 +* launch.json文件用于定义项目的调试参数 +* 需要理解launch.json中的type关键字 + - 调试功能通常由调试插件提供,调试插件可以包含多种调试功能(例如一个C调试插件,可以支持gdb,也可以同时支持lldb,对两种调试器做支持),type关键字对应的是调试功能而不是调试插件,type关键字可以看做是调试功能的一个id标识 + - 当点击调试时,需要让Kylin-IDE知晓应该使用哪个插件的哪个调试功能来进行调试,type字段起到了关联调试功能的作用 + - launch.json中可设置的参数和type相关(即和调试插件中的调试功能相关),具体参数由调试插件定义,也有一些公共参数,下文会进行介绍 +* 需要理解launch.json中的configurations关键字 + - configurations表示当前项目的调试配置列表,它的值是一个数组类型,表示可以有多个调试配置。例如一个项目中可能有多个调试目标,有C语言编写的二进制程序和Java语言编写的二进制程序,可以写多个调试配置 + - 列表中的每个调试配置条目都需要明确type字段,表示调用哪个调试插件的哪个调试功能 + - 列表中的每个调试配置条目都需要明确name字段,表示当前执行哪个调试配置。选择执行哪个调试配置,可以点击左侧活动栏的调试图标,在侧边栏上方的绿色三角按钮(启动调试按钮)后方下拉列表中选择,下拉列表中显示的是调试配置的name字段 +* 要掌握调试设置,需要了解launch.json的基本配置,也需要了解具体调试插件的配置,至少知晓常用调试插件常用参数的配置 +* Kylin-IDE的主程序kylin-ide仅包含基础功能,编辑、调试功能需要安装插件,若未安装对应调试插件,无法在launch.json中调用其调试功能 +### launch.json文件创建方法 +- 创建方法 + * 方法一:点击左侧活动栏运行调试图标,选择“创建launch.json文件”,在弹出的选择列表中选择调试类型,此列表对应type字段,但显示的是type字段在代码中的标签(label),可根据编程语言和调试器进行选择,选择后会创建一个对应type类型的例子模板,在此基础上继续编辑 + * 方法二:安装Kylin Project Manager插件,在左侧的“项目操作区”中点击“调试”,也会进入到和方法一中一样的launch.json创建流程 + * 方法三:直接在.vscode目录下新建一个launch.json文件,或从其他类似项目代码中复制一个launch.json文件,然后再进行修改 + * 注意,若无launch.json时,按F5键启动调试或从运行菜单启动调试,也会弹出调试类型选择框,但此时并非创建launch.json的过程,而是有些调试功能支持无launch.json直接尝试对当前代码文件启动调试或运行。此时,弹出的调试类型选择列表通常会参考当前打开的代码文件,例如,若当前打开的是C++代码,会显示C++相关的调试类型;若没有打开文件,则会显示所有可选调试类型 +- 已有launch.json文件,想在configurations中再添加一个调试配置条目 + * 方法一:打开launch.json文件,在右下角有一个“添加配置”按钮,点击它会弹出一些调试类型模板列表,选择需要的或相近的类型,在此基础上做修改 + * 方法二:从其他项目代码中复制一个类似的调试配置条目,然后进行修改 +### launch.json的简单例子 +- 仍使用上文简单的C++项目(或称为工程)hello-world为例,创建launch.json,若使用Kylin Native Debug插件提供的gdb调试功能,则调试类型列表中选择GDB,将会在工程根目录的.vscode目录中创建launch.json,然后修改如下。具体参数说明见下文 + ```json + { + "version": "0.2.0", + "configurations": [ + { + "name": "C++ debug", + "type": "gdb", + "request": "launch", + "target": "./hello", + "cwd": "${workspaceRoot}", + "valuesFormatting": "parseText" + } + ] + } + ``` + +### 关键字(或称为属性、参数、字段)说明 +* 关键字提示:点击ctrl+space会弹出可选参数列表;将鼠标放在字段上会显示提示 + - 与切换输入法快捷键冲突问题解决方法,见上文task.json的“关键字提示和补全” +* 公共关键字 + - version:launch.json文件的格式版本,当前为2.0.0 + - configurations:调试配置列表,值为数组类型,可以有多个调试配置 + - compounds:组合调试,可以把多个调试配置组合在一起进行调试,值为数组类型,可以配置多个。子字段如下 + * name:compounds列表中单个compound条目的名称,会显示在绿色三角按钮(启动调试按钮)后方的下拉框中 + * configurations:值为数组,两个或以上并行运行的调试配置的name + * preLaunchTask:在调试组启动前执行的task.json中的某个任务 + * stopAll:手动停止一个调试,是否停止调试组内的所有调试 + - type:此关键字的理解可以看前文。调试类型,可以看作调试功能的id。一个调试插件可以有多个调试类型。type字段设置正确,才能调用对应的调试插件的调试功能。launch.json中支持的参数也与type有关 + - name:调试配置列表中(configurations)可以有多个调试配置条目,每个调试配置条目都有一个name字段用来表示此条目,方便选择启动哪个调试配置。选择启动哪个调试配置的方法是:点击左侧活动栏的调试图标,在侧边栏上方的绿色三角按钮(启动调试按钮)后方下拉列表中选择,下拉列表中显示的是调试配置的name字段 + - request:值可选launch、attach,两种调试类型 + * launch:表示目标程序启动时就以调试模式启动 + * attach:表示目标程序已经开始运行,再使用调试器连接到程序进程 + - presentation(测试):配置调试启动按钮(绿色三角按钮)后方的调试配置选择下拉框显示格式,内部有以下关键字 + * order:下拉框列表条目顺序,值为整数,数越小顺序越靠前,如果数值一样,则写在前面的靠前 + * group:下拉框列表条目分组,同一组的配置会显示在一起 + * hidden:不在下拉框列表中显示 + - preLaunchTask:在启动调试前,先执行task.json中定义的某个task,例如在调试前先编译一下代码。也可以设置为${defaultBuildTask},表示默认的build task。值可以是字符串或对象类型,若填写字符串则应为task.json中task的label,如果是对象则应配置grunt任务 + - postDebugTask:在调试结束后执行task.json中定义的某个task。值可以是字符串或对象类型,若填写字符串则应为task.json中task的label,如果是对象则应配置grunt任务 + - internalConsoleOptions:控制是否直接显示调试面板(调试控制台),里面有调试器具体输出信息和交互输入框。neverOpen表示不直接显示调试面板(可以手动选择显示);openOnFirstSessionStart表示仅在第一次调试时显示;openOnSessionStart表示启动调试后显示 + - debugServer(测试,不写入正文):仅在调试插件时使用 + - serverReadyAction(测试,不写入正文) +* 平台相关关键字 + - Kylin-IDE目前仅服务于类Linux操作系统,故此参数可以不用。可以定义特定平台下的特殊处理,可选值:linux、windows、osx +* 较常见的、很多调试插件支持的关键字(注意不是所有插件都支持) + - program(target):要调试的程序文件路径 + - args:调试程序参数,值为数组类型 + - env:环境变量 + - envFile:dotenv文件路径 + - cwd:当前工作路径,当需要解析相对路径等时需要 + - port:当attach到一个程序时设置的端口 + - stopAtEntry:程序启动后停在入口(类似于在程序最开始加了断点) +* 插件具体关键字 + - 可以查看插件的介绍文档和Readme + - 后续会补充Kylin-IDE推荐调试插件的launch.json的参数和配置方法 +* 变量替换 + - launch.json中部分字段可以使用变量,变量在launch.json中的调试运行时会替换为变量指代的内容,详细内容见下文“变量章节” + +## 变量 +### 变量简介 +- 在配置task.json或launch.json时,在某些key、value中可以使用一些变量,变量分为如下五种类型。注意,task.json中并不是所有关键字中都支持变量替换,支持变量替换的主要关键字是command、args、options + * 预置变量,预置变量的引用语法是:${预置变量名称} + * 环境变量,环境变量的引用语法是:${env:环境变量名称} + * 配置类型变量,配置类型变量的引用语法是:${config:配置类型变量} + * 命令变量,命令变量的引用语法是:${command:命令ID} + * 输入变量,输入变量的引用语法是:${input:输入变量ID} +### 主要预置变量说明 +* 引用语法是:${预置变量名称},会使用预置变量的值替换预置变量 +* ${userHome} - 用户家目录路径 +* ${workspaceFolder} - 在Kylin-IDE中当前打开的文件夹路径,是工作区根目录 +* ${workspaceFolderBasename} - 当前打开的文件夹名称,不带名称之前的路径 +* ${file} - 当前打开的文件 +* ${fileWorkspaceFolder} - 当前打开的文件的工作区文件夹路径 +* ${relativeFile} - 当前打开的文件相对于workspaceFolder的路径(相对路径) +* ${relativeFileDirname} - 当前打开的文件所属的文件夹相对于workspaceFolder的路径(相对路径) +* ${fileBasename} - 当前打开的文件的名称,不含路径 +* ${fileBasenameNoExtension} - 当前打开的文件的名称,不带后缀 +* ${fileExtname} - 当前打开文件的后缀(带".") +* ${fileDirname} - 当前打开的文件所属文件夹的路径 +* ${fileDirnameBasename} - 当前打开的文件所属文件夹的名称,不带路径 +* ${cwd} - 当前工作路径 +* ${lineNumber} - 光标或选中内容的当前行号 +* ${selectedText} - 当前选中的文本内容,需要有选中的文本才可获取到 +* ${execPath} - Kylin-IDE的可执行文件路径 +* ${defaultBuildTask} - 默认build task的名称 +* ${pathSeparator} - 操作系统使用的路径分隔符 + +### 环境变量 +* task执行时或启动调试时,有可能需要主动获取系统环境变量;注意是获取,如需设置task执行时的环境变量,请使用options关键字中的env字段。会使用环境变量的值替换环境变量 +* 环境变量的引用语法是:${env:环境变量名称} +* 例子:${env:PATH} +* 查看当前操作系统环境变量的方法(类Linux系统):在终端中执行env命令,可以查看当前环境变量。可以使用echo命令显示某个环境变量的值,例如 echo $PATH + +### 配置类变量 +* 通过配置类变量可以获取Kylin-IDE配置参数值。会使用配置的值替换配置类变量 +* 配置类型变量的引用语法是:${config:Name} +* 例子:${config:editor.fontSize} +* 查找配置的方法,打开命令面板(ctrl+shift+P),输入搜索关键字“json”,有3个相关内容 + - 默认配置(较全):Preference:Open Default Settings + - 用户设置:Preference:Open User Settings + - 工作区设置:Preference:Open Workspace Settings + +### 命令变量 +* 通过命令变量可以执行Kylin-IDE中定义的命令以及插件中定义的的命令。当命令的返回值是字符串时会使用命令的字符串返回值替换命令变量,否则不会替换 +* 引用语法是:${command:命令ID} +* 查找命令的方法 + - 目前暂没有全面的查找方法,以下是几种查找部分命令的方法 + - 命令面板查找:ctrl+shift+P打开命令面板,搜索关键字,可以查询到命令的说明,根据说明可以尝试拼出命令 + - 插件暴露命令查找:点击最左侧活动栏插件图标,进入插件列表,点击插件条目,在插件详情页点击功能贡献,在命令栏目中可以找到插件暴露出的命令 + - 快捷键命令查找:ctrl+shift+P打开命令面板,输入json,找到Open Default Keyboard Shortcuts,打开json文件后可以在其中查找到一些命令 + +### 输入变量 +* 场景:task或launch中命令的执行需要一些输入型的或动态可变的参数。此时可以使用输入变量 +* 引用语法是:${input:输入变量ID},通过inputs关键字对输入变量进行设置,大体如下 + ```json + { + "version": "2.0.0", + "tasks": [ + { + "label": "task name", + "command": "${input:输入变量ID}" + // ... + } + ], + "inputs": [ + { + "id": "输入变量ID", + "type": "type of input variable" + //configuration + } + ] + } + ``` +* 输入变量的类型,即inputs关键字中的type字段类型,可选3种,每种类型的具体配置字段有区别 + - promptString:弹出输入框,接收用户输入的字符串。具体配置字段如下 + * description:提示用描述,会显示在输入框中做提示 + * default:默认值,当用户未输入任何值时,使用默认值 + * password:如果设置为true,则输入内容为密码格式,不显示具体内容 + - pickString:弹出选择列表,接收用户的选择。具体配置字段如下 + * description:提示用描述,会显示以作提示 + * options:数组类型,用户选择条目。每一个用户条目可以是一个字符串,也可以是一个对象,对象中可以包含label和value字段,显示时会显示为label: value + * default:用户如未作选择,则采用此默认值 + - command:执行命令。具体配置字段如下 + * command:Kylin-IDE和插件定义的命令 + * args:命令使用的参数,字符串或对象 + - 例子 + ```json + { + "version": "2.0.0", + "tasks": [ + { + "label": "ls command", + "type": "shell", + "command": "ls", + "args": ["${input:paramStr}", "${input:folderPath}"] + }, + { + "label": "password type e.g.", + "type": "shell", + "command": "ls ${input:paramStr} ${input:folderPassw}", + }, + { + "label": "command e.g.", + "type": "shell", + "command": "echo ${input:command1}", + }, + ], + "inputs": [ + { + "type": "pickString", + "id": "paramStr", + "description": "ls命令的参数", + "options": [ + { + "label": "xxx1", + "value": "-l" + }, + "-lh", + "-la", + ], + "default": "-l" + }, + { + "type": "promptString", + "id": "folderPath", + "description": "ls查看的文件夹的路径", + "default": "${workspaceFolder}" + }, + { + "type": "promptString", + "id": "folderPassw", + "description": "password类型字符串例子", + "password": true, + "default": "" + }, + { + "type": "command", + "id": "command1", + "command": "search.action.openEditor" + }, + ] + } + ``` +### 查看变量值 +- 在task.json中,可以在command中使用echo命令打印变量值 + +## 附录 +- 例子使用的工程和调试插件:上文使用的简单的C++工程,在工程根目录创建了aaa目录;调试插件使用的是Cpp Debug + +### task.json参考例子 +```json +{ + + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "process", + "command": "g++", + "args": [ + "-g", + "hello.cpp", + "-o", + "hello" + ], + "icon": { + "color": "terminal.ansiGreen", + "id": "account" + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared", + "group": "abc" + }, + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": { + "owner": "cpp", + "fileLocation": ["relative", "${workspaceFolder}"], + "source": "g++", + "pattern": { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + } + } + }, + { + "label": "run", + "type": "shell", + "dependsOn": [ + "build", + "test1", + "test2" + ], + "command": "./hello", + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "new" + }, + "runOptions": { + "instanceLimit": 1 + } + }, + { + "label": "test1", + "type": "shell", + "command": "top", + "args": [ + "-n", + "10" + ], + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "new", + "group": "abc" + }, + "promptOnClose": true, + "runOptions": { + "reevaluateOnRerun": false, + "instanceLimit": 2 + } + }, + { + "label": "test2", + "type": "process", + "command": "top", + "args": [ + "-n", + "10" + ], + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "new", + "group": "abc" + }, + "promptOnClose": true, + "runOptions": { + "reevaluateOnRerun": false, + "instanceLimit": 1 + } + }, + { + "label": "test variable", + "type": "shell", + "command": "echo ${command:search.action.openEditor} ", + "detail": "测试variable", + "options": { + "cwd": "${workspaceFolder}/aaa/bbb", + } + }, + { + "label": "ls command", + "type": "shell", + "command": "ls", + "args": ["${input:paramStr}", "${input:folderPath}"] + }, + { + "label": "ls command 2", + "type": "shell", + "command": "ls ${input:paramStr} ${input:folderPath}", + }, + { + "label": "ls command 3", + "type": "shell", + "command": "ls ${input:paramStr} ${input:folderPassw}", + }, + { + "label": "ls command 4", + "type": "shell", + "command": "echo ${input:command1}", + }, + ], + "inputs": [ + { + "type": "pickString", + "id": "paramStr", + "description": "ls命令的参数", + "options": [ + { + "label": "xxx1", + "value": "-l" + }, + "-lh", + "-la", + ], + "default": "-l" + }, + { + "type": "promptString", + "id": "folderPath", + "description": "ls查看的文件夹的路径", + "default": "${workspaceFolder}" + }, + { + "type": "promptString", + "id": "folderPassw", + "description": "ls查看的文件夹的路径", + "password": true, + "default": "${workspaceFolder}" + }, + { + "type": "command", + "id": "command1", + "command": "search.action.openEditor", + }, + ] +} +``` +### launch.json参考例子 +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C++ Launch Application", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/hello", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "presentation": { + "hidden": false, + "group": "", + "order": -2 + }, + }, + { + "name": "ok-debug", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/hello", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceFolder}", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "presentation": { + "hidden": false, + "group": "", + "order": -1 + }, + "preLaunchTask":"build", + "postDebugTask": "build", + "internalConsoleOptions":"openOnSessionStart", + "linux": { + + }, + + }, + { + "name": "ng", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/hello", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceFolder}", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "presentation": { + "hidden": false, + "group": "test", + "order": 2 + } + }, + ], + "compounds": [ + { + "name": "Compound-ok-ng", + "configurations": ["ok-debug","ng"], + "stopAll": true + } + ] +} +``` + + +## VSCode相关内容参考链接 +- https://code.visualstudio.com/docs/editor/tasks +- https://code.visualstudio.com/docs/editor/variables-reference +- https://code.visualstudio.com/docs/editor/debugging \ No newline at end of file diff --git a/user-guide/files/插件开发.md b/user-guide/files/插件开发.md new file mode 100644 index 0000000..2a14df4 --- /dev/null +++ b/user-guide/files/插件开发.md @@ -0,0 +1,168 @@ +# 插件开发 +- 插件api继承了Code-OSS,本部分给出插件开发的简单例子,详细开发方法可以参考VSCode文档。本文会逐渐向最佳实践方向补充 +- 需要特殊说明的是package.json文件中engines字段中的vscode版本(用engines.vscode表示) + + 此字段很重要,影响到插件的兼容性,和IDE基础平台的版本相关 + - engines.vscode的值,表示插件使用api的最低版本 + - kylin-ide版本 < 1.1.0;kylin-code < 0.3.0 基于Code-OSS 1.68.0(插件api版本是这个版本) + - kylin-ide版本 >= 1.1.0;kylin-code >= 0.3.0 基于Code-OSS 1.85.2(插件api版本是这个版本) + - 故如果需要兼容早期版本,engines.vscode应填写1.68.0或^1.68.0(^ 是一个版本范围符号,表示允许安装该版本的最新小版本(minor version)和补丁版本(patch version),但不允许安装下一个大版本(major version),^1.68.0表示:>=1.68.0 <2.0.0) + - 如果仅考虑兼容目前的版本,engines.vscode应填写1.85.2或^1.85.2 + - 如果插件需要考虑申威等社区不特别活跃的架构,engines.vscode应尽量向低版本填写,最好填写1.68.0或^1.68.0,因为特殊架构上可能因缺少编译依赖只能构建低版本kylin-ide(至少基于1.68.0的kylin-ide能够支持申威架构) + +## 环境准备 + - 安装IDE基础平台kylin-ide(或者在openKylin上安装kylin-code) + - 安装nodejs + + 版本选择 + 1. 尽量使用nodejs lts版本,推荐使用18或16 + 2. 如果使用了开源代码,需要检查开源代码构建需要的nodejs版本范围 + + [安装方法参见nodejs环境配置](./JavaScript开发.md#nodejs环境配置)。可以采用nodejs环境配置中方法2(从官网或国内镜像网站下载安装nodejs)或者方法3(nvm安装nodejs)来安装nodejs + - nodejs软件包管理工具npm、yarn + + npm 为nodejs的包管理器,通常安装nodejs时,npm也会安装到环境中 + - 配置npm源为国内镜像网站,比如淘宝镜像网站 + - 打开终端,输入命令`npm config set registry https://registry.npmmirror.com` + - 输入命令`npm config get registry`,查看npm源是否配置成功 + + yarn同样为nodejs的包管理器,通过npm安装 + - 安装配置完成npm后,在终端输入命令`npm install -g yarn`,安装yarn + - 输入命令`yarn -v`,查看yarn版本是否安装成功 + - 配置yarn源为国内镜像网站,比如淘宝镜像网站 + - 打开终端,输入命令`yarn config set registry https://registry.npmmirror.com` + - 输入命令`yarn config get registry`,查看yarn源是否配置成功 + - 安装脚手架yo和代码生成器generate-code + + 打开终端,输入命令`npm install -g yo generate-code` + - 安装vsce插件打包工具 + + 打开终端,输入命令`npm install -g vsce`,安装vsce + +## 快速开始 +### 1.创建hello-world 插件 + - 打开终端,输入命令`yo code`,创建插件项目。根据提示输入插件名称、插件ID、插件描述等信息,如图所示![yocode-1](./resources/extension-dev/yocode-1.png) +### 2.编辑插件 + - 打开插件项目,终端执行`kylin-ide hello-world` + - hello-world插件主要文件介绍 + - .vscode文件夹:插件配置文件夹 + - launch.json:调试配置文件 + - tasks.json:运行配置文件 + - package.json:插件配置文件 + - src/extension.ts:插件入口源码文件 + - tsconfig.json:tsconfig.json文件是TypeScript的配置文件,用于配置TypeScript的编译选项。 + - 修改插件package.json文件中engines字段中的vscode版本(见文档开头的说明) + + #### 2.1 package.json介绍 + package.json文件是插件的配置文件,用于描述插件的基本信息、依赖、命令等。 + - name:插件名称 + - displayName:插件展示名称 + - description:插件描述 + - version:插件版本 + - publisher:插件发布者 + - engines.vscode:插件支持的vscode最小版本。 + - main:编译后的插件入口文件 + - package.json示例 + ```json + { + "name": "hello-world", //插件名称 + "displayName": "hello-world",//插件展示名称 + "description": "hello-world",//插件描述 + "version": "0.0.1",//插件版本 + "publisher": "kylin",//插件发布者 + "engines": { + "vscode": "^1.68.0"//插件支持的vscode版本,兼容1.68.0及以上版本 + }, + "categories": [ // 插件分类 + "Other" + ], + "activationEvents": [],//插件激活事件 + "main": "./out/extension.js",//插件编译后的入口文件 + "contributes": { + "commands": [ //注册命令 + { + "command": "hello-world.helloWorld", + "title": "Hello World" + } + ] + }, + "scripts": { + "vscode:prepublish": "npm run compile", + "compile": "tsc -p ./", + "watch": "tsc -watch -p ./", + "pretest": "npm run compile && npm run lint", + "lint": "eslint src --ext ts", + "test": "vscode-test" + }, + "devDependencies": { //开发依赖 + "@types/vscode": "^1.68.0", //与engine.vscode版本一致 + "@types/mocha": "^10.0.7", + "@types/node": "20.x", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.11.0", + "eslint": "^8.57.0", + "typescript": "^5.4.5", + "@vscode/test-cli": "^0.0.9", + "@vscode/test-electron": "^2.4.0" + } + } + ``` + #### 2.2 src/extension.ts介绍 + src/extension.ts文件是插件的入口文件,用于注册插件命令、监听插件事件等。 + - activate函数:插件激活时执行的函数 + - deactivate函数:插件停用时执行的函数 + +### 3.编译插件 + 可以使用npm或者yarn来编译插件,以npm为例: + - 打开终端,进入插件项目目录 + - 执行命令`npm install`,解析package.json中devDependencies内容,安装插件依赖 + - 执行命令`npm run compile`,编译插件,插件的源码会被编译成JavaScript代码,存储在out文件夹中。 + - 或者点击终端 ->运行任务->npm:watch,实时编译插件。监听插件源码,当源码发生变化,自动编译,npm:watch任务本质是执行`npm run watch`命令。在.vscode/tasks.json文件中定义了npm:watch任务。 + `npm run [keywords]` 是执行package.json中scripts中定义的命令,比如`npm run compile`就是执行package.json中scripts中定义的compile命令。 + + tasks.json内容: + ```json + { + "version": "2.0.0", + "tasks": [ + { + "type": "npm",//任务类型,由内置插件提供,不要更改 + "script": "watch",//对应package.json中scripts中定义的watch命令 + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} + ``` + +### 4.调试插件 + IDE基础平台内置了对typeScript和JavaScript的调试支持,插件开发使用typescript或者JavaScript语言,所以可以直接进行调试,无需额外安装其他插件。调试插件需要创建调试配置文件launch.json,launch.json文件被存储在.vscode文件夹内。使用yo code创建的插件,默认已经创建了launch.json文件,无需手动创建。 + launch.json文件内容如下: + ```json + { + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", //调试任务名称 + "type": "extensionHost",//调试类型 + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/out/**/*.js" + ], + "preLaunchTask": "${defaultBuildTask}" + } + ] + } +``` + - 在src/extension.ts源码文件添加断点 + - 点击菜单中运行->启动调试,调试插件 +### 5.插件打包 + 插件打包是将编译后的插件打包成vsix文件 + - 执行命令`vsce package`,打包插件 + - 打包完成后,在插件目录下会生成一个.vsix文件,该文件就是插件的安装包。 + +## VSCode插件开发相关链接 +- https://code.visualstudio.com/api \ No newline at end of file diff --git a/user-guide/目录.md b/user-guide/目录.md index 2a8a22c..a21c8af 100644 --- a/user-guide/目录.md +++ b/user-guide/目录.md @@ -17,6 +17,8 @@ #### [离线插件管理](./files/离线插件管理.md) +#### [如何配置工程的构建、调试、运行](./files/如何配置工程的构建-调试-运行.md) + #### [项目管理](./files/项目管理.md) #### [Qt开发](./files/Qt开发.md) @@ -31,6 +33,8 @@ #### [JavaScript开发](./files/JavaScript开发.md) +#### [插件开发](./files/插件开发.md) + #### [死锁检测](./files/死锁检测.md) #### [历史调试](./files/历史调试.md)