首页 > 其他分享 >从零开始配置vim(28)——代码的编译、运行与调试

从零开始配置vim(28)——代码的编译、运行与调试

时间:2022-10-30 11:37:48浏览次数:55  
标签:python 配置 28 vim 从零开始 dap true 调试器

在前面几个章节,我们逐渐为 ​​Vim​​​ 配置了语法高亮、代码的跳转和自动补全功能。现在的 ​​Vim​​​ 已经可以作为代码编辑器来使用了。但是想将它作为日常发开的主力编辑器来用还需要很长一段路要走,其中一个就是要为它配置代码的一键编译与运行功能。这里我们仍然以 ​​C​​​ 和 ​​Python​​ 为例。一个是需要编译运行的一个是直接就可以运行的,这两个语言应该能代表大多数语言的情况。

自动运行

C 语言的配置

在之前 ​​vim​​​ 入门的一系列教程中我们介绍过 ​​vim​​​ 自带 ​​make​​​ 命令的运行机制以及如何进行自定义。对于其他语言要实现这个自动编译运行的效果我们核心的操作就是在修改 ​​make​​​ 命令。而 ​​C/C++​​​ 本身采用 ​​make​​​ 命令来进行编译和运行,所以这里 ​​C/C++​​​ 我们直接采用 vim 自带的 ​​:make​​ 命令

我们先创建一个 ​​C​​​ 的工程。让后使用上一节的生成 hello world 的代码片段生成一个基本的程序。然后提供一个供 ​​:make​​​ 命令使用的 ​​Makefile​​ 文件

main.out: main.o
gcc main.o -o main.out
main.o: main.c
gcc -c main.c
clean:
rm -rf *.o *.out
run:
./main.out

然后我们执行 ​​make​​​ 用来编译。如果出错了,可以使用 ​​quickfix​​ 相关命令跳转到对应位置。

我们一般的流程是 ​​:make​​​ 进行编译,然后使用 ​​:make run​​​ 来进行运行。把命令搞清楚了,下面就考虑如何加快这个流程,做到一键编译运行。我们的思路还是绑定快捷键。每种语言虽然定义相同的快捷键但是运行的命令不同,我们需要根据不同的语言类型绑定对应的命令。这个时候最好的办法就是在 ​​filetype​​ 的机制上完成绑定的操作。

我们在 ​​lua/lsp/cpp.lua​​ 中绑定快捷键。

local on_attach = function(client, bufnr)
lsp_set_keymap.set_keymap(bufnr)
-- 编译
vim.api.nvim_buf_set_keymap(bufnr, "n", "<F7>", "<cmd>make<CR>", {silent = true, noremap = true})
-- 编译运行
vim.api.nvim_buf_set_keymap(bufnr, "n", "<F5>", "<cmd>make run<CR>", {silent = true, noremap = true})
end

到此我们关于 ​​C/C++​​​ 的配置就完成了。可能显的有些简单但是已经初步可用了,小伙伴可以根据自己的需求来进一步修改这个配置。使用这个配置的前提是 ​​C/C++​​​ 的工程中有已经定义好的 ​​Makefile​​ 文件

从零开始配置vim(28)——代码的编译、运行与调试_python

Python的配置

之前我们在讲解命令的模式的提到过可以使用 ​​%​​​ 来代表当前 ​​buffer​​​ 所对应的文件。所以 ​​python​​​ 的配置就比较简单了。因为 ​​Python​​​ 不需要编译,所以这里直接绑定 ​​<F5>​​ 来运行

vim.api.nvim_buf_set_keymap(bufnr, "n", "<F5>", "<cmd>!python %<CR>", {silent = true, noremap = true})

从零开始配置vim(28)——代码的编译、运行与调试_vim_02

dap 配置

我们经常看到有人配置 ​​neovim​​​ 或者 ​​vim​​​ 的时候会介绍到 ​​dap​​​ ,那么什么是 ​​dap​​​ 呢? ​​dap​​​ 的全称是 ​​Debug Adapter Protocol​​​ 从名称上看它又是一个协议。它为多种调试器提供了一层统一的适配抽象层。有点类似于前面的介绍的 ​​lsp​​。只要在适配层提供接口的实现,那么在客户端,也就是代码编辑器这端可以不做任何修改的集成不同调试

联想到 ​​lsp​​​ 的配置,我们配置​​dap​​​ 首先需要的是有一个 ​​dap​​​ 的客户端,用来向调试器发送各种命令,例如下断点、显示变量名等等。另外想要能够调试也需要有具体的调试器,用来接收处理这些命令。现在思路有了,我们 这里先以 ​​Python​​​ 为例来介绍 ​​dap​​ 的基本配置。

首先是需要一个客户端,用于通过 ​​neovim​​下发各种调试命令并实时显示调试信息。

截止到 ​​0.7​​​ 版本 ​​NeoVim​​​ 并没有在内部集成 ​​dap​​​ 客户端的功能,需要我们单独安装相关插件来实现这部分的功能。这里我们使用的客户端是 ​​nvim-dap​​ 插件。

我们先使用 ​​use {'mfussenegger/nvim-dap'}​​ 来安装它。

接着我们来定义一下相关的快捷键,这里我喜欢使用 ​​Visual Studio​​​ 的快捷键。各位小伙伴可以自行选择自己喜欢的快捷键。这里我希望在插入模式和选择中也可以使用这些快捷键,由于 ​​vim.api.nvim_set_keymap​​​ 函数第一个参数只能有一个模式字符串,如果采用这个函数来定义快捷键,这里同样的代码我要写三次,为了简化代码,这里介绍一个新的函数 ​​vim.keymap.set​​​。它与 ​​vim.api.nvim_set_keymap​​ 函数支持的参数相同,只是它第一个表示模式的参数可以支持用字典来一次绑定到多个模式中。这样就简化了绑定快捷键的代码量。

vim.keymap.set({"i", "n", "v"}, "<F5>", "<cmd>lua require'dap'.continue()<CR>", {silent = true, noremap = true, buffer = bufnr})
vim.keymap.set({"i", "n", "v"}, "<F10>", "<cmd>lua require'dap'.step_over()<CR>", {silent = true, noremap = true, buffer = bufnr})
vim.keymap.set({"i", "n", "v"}, "<F11>", "<cmd>lua require'dap'.step_into()<CR>", {silent = true, noremap = true, buffer = bufnr})
vim.keymap.set({"i", "n", "v"}, "<F12>", "<cmd>lua require'dap'.step_over()<CR>", {silent = true, noremap = true, buffer = bufnr})
vim.keymap.set({"i", "n", "v"}, "<F9>", "<cmd>lua require'dap'.toggle_breakpoint()<CR>", {silent = true, noremap = true, buffer = bufnr})

这个函数是 0.7 以后的版本引进的,如果你的是0.7之前的版本,还是老老实实的多写几遍。另外我们这里绑定了 ​​<F5>​​​ 快捷键,因此之前我们在 ​​Python​​​ 中,绑定的直接运行的 ​​<F5>​​ 键的代码需要注释一下。

我们想要真正实现调试,还需要配合调试器使用。前面说 ​​dap​​​ 只是一层协议,需要客户端服务器按照这一层协议来实现相关功能,某些调试器可能自身支持这个协议,而某些可能不支持,这样就需要额外的配置来使调试器也能支持该协议。下面我们以 ​​Python​​ 为例先把整个调试环境搭建起来,先跑起来再说

​Lsp​​​ 在安装 ​​Server​​​ 的时候有 ​​nvim-lsp-installer​​​ 这样的插件来专门安装 ​​LSP server​​​ 的,那么 ​​dap​​​ 有没有类似的插件来安装 ​​dap​​​ 调试器相关的服务呢?有!我们使用 ​​mason​​​ 来管理 ​​dap​​ 的调试器。

use { "williamboman/mason.nvim" }

当初我推荐过 ​​nvim-lsp-installer​​​ 插件作为下载、管理 ​​lsp server​​​ 的工具。后来只是知道作者发布了新的管理工具,因为比较新怕出问题就没怎么关注,后来有好多小伙伴在评论区推荐,我仔细看了一下发现它已经支持 ​​dap​​​ 服务的管理了。那还是使用它吧 ​​^_^​​。

我们可以使用 ​​Mason​​​ 打开一个带界面的 ​​Lsp​​​ 和 ​​DAP​​​ 的服务管理窗口,可以使用 数字键在上面进行跳转,找到想要的服务之后直接使用 ​​i​​ 来安装

从零开始配置vim(28)——代码的编译、运行与调试_调试器_03

也可以使用 ​​MasonInstall​​ 来安装想要的服务。

我们先在插件配置中删除与 ​​nvim-lsp-installer​​​ 相关的配置,包括 ​​packer​​​ 中对它的引用和 ​​plugins-config​​ 目录中的配置。

下一步就是配置 ​​dap​​​ 的客户端与 服务端的联动,这需要配置 ​​nvim-dap​​ 插件,根据官方的描述我们主要配置两个部分,第一个部分叫做适配器,主要配置我们加载哪个调试器,以及如何加载调试器。这一步需要提供如下的配置框架

local dap = require('dap')
dap.adapters.language = {
}

​language​​​ 是具体的调试器例如 ​​debugpy​​​ 这里的 ​​language​​​ 就是 ​​python​​​了。既然与语言相关,我们自然的想到要用 ​​ftplugin​​​目录。为了方便管理,这里与 ​​lsp​​​ 配置的组织形式类似,我们将所有关于 ​​dap​​​ 的配置都放到 ​​lua/dap​​​目录中。并且按语言名称来命名,例如关于 ​​python​​​ 的 ​​dap​​​ 配置我们放到 ​​lua/dap/python.lua​​​ 中。然后在 ​​ftplugin/python.lua​​ 中加载这个配置文件即。

require("dap/python")

然后在 ​​python.lua​​ 文件中写入以下配置

local dap = require('dap')
dap.adapters.python = {
type = 'executable';
command = '/usr/bin/python3.8';
args = { '-m', 'debugpy.adapter' };
}

其中各个参数的含义如下:

  • ​type​​​ : 表示启动调试器的方式, ​​executable​​​ 表示由客户端自行启动调试器; ​​server​​ 表示 调试器已经单独启动了,后续客户端只需要将调试请求发送到服务器即可。
  • ​command​​: 表示启动调试器的命令
  • ​args​​: 表示启动调试器的命令行参数

由于 ​​python​​​ 调试工具 ​​debugpy​​​ 是一个 ​​Python​​​ 的第三方模块,因此这里我们使用 ​​python -m debugpy.adapter​​ 来启动这个调试器。

接着我们需要针对语言来配置如何进行调试。它的配置都放在一个名为 ​​dap.configurations.language​​​ 的 字典中。​​language​​​ 代表的是当前文件的文件类型名, 所以针对 ​​Python​​​ 来说这里需要填写的是 ​​dap.configurations.python​​。它的配置如下所示:

dap.configurations.python = {
{
type = "python";
request = "launch";
name = "launch file";
program = "${file}";
pythonPath = function ()
return "/usr/bin/python3.8"
end
},
}

各参数的含义如下:

  • ​name​​ : 是一个字符串它表示当前配置的名称,你可以理解为一个id
  • ​type​​​: 使用哪个调试器,跟我们之前配置的 ​​dap.adapters​​相关
  • ​request​​​:调试的方式,支持 ​​attach​​​ 附加到一个已有的进程或者 ​​launch​​​ 启动一个新进程。由于在上一步我们指定由客户端来启动调试器,因此这里应该选择 ​​launch​​ 来启动一个新调试进程
  • ​program​​​: 需要调试的代码, ​​${file}​​​ 表示当前 ​​buffer​​ 所对应文件
  • ​pythonPath​​​: 执行该文件需要使用的 ​​python​​ 解析器路径

这样我们在某一个打开的文件上按下 ​​<F5>​​​ 的时候,它会通过 ​​pythonPath​​​ 指定的解析器来执行脚本,并且会按照配置中 ​​request​​ 指定的方式来打开一个新的调试器进程。并且将对应的调试命令发送到调试器完成调试工作。

从零开始配置vim(28)——代码的编译、运行与调试_调试器_04


好了,到此为止我们配置了最基本、最简单的​​dap​​​ 调试。现在只是有一个勉强能用的调试工具,距离好用还差的很远,下一篇里面我们首先会对 ​​dap​​​ 功能进行增强,美化,并讨论如何针对 ​​C/C++​​ 这种编译型的语言进行调试。最后感谢各位给我提意见的小伙伴,谢谢大家!



标签:python,配置,28,vim,从零开始,dap,true,调试器
From: https://blog.51cto.com/u_11090813/5807468

相关文章

  • 【XSY1976】【BZOJ2286】【SDOI2011】消耗战(虚树,dp)
    这题的dp思想还是比较容易想的,关键是如何保证时间复杂度,这时就用到了虚树的技巧。1.虚树是什么?(虚树的性质)不妨设现在询问给出了\(k\)个点,我们命名这些节点为关键节点。......
  • 在Neovim中配置基于事件触发的自动保存
    tags:VimTips配置采用纯​​lua​​​脚本的方式进行​​vim​​中自动保存的配置,参考了StackOverflow的一个回答​1​​,如下:vim.api.nvim_create_autocmd({"Ins......
  • java学习 2022年10月29日13:26:28
    packagecn.tedu.type1;publicclassForDemo{publicstaticvoidmain(String[]args){outer:for(intj=1;j<10;j++){for(inti=0;i......
  • 修改Octave编辑器为vim
    Octave的默认编辑器一般是emacs,该编辑器虽然强大,但是对于新手来说并不友好,并且我在macOS中使用时,发现Octave中的emacs的快捷键有失效的现象,因此为了避免麻烦,自己修改了......
  • 代码随想录day28 | 93. 复原 IP 地址 78.子集 90. 子集 II
    93.复原IP地址题目|文章思路1.先判断每个部分是不是符合要求2.如果符合要求则加入path,递归下一层3.当遍历到字符串末尾,如果有四层,则加入结果,否则直接返回。实现......
  • 2022年 10月28 日 学习第一天
    注释书写注释是非常好的习惯,必须坚持下去、 平时写代码一定要注意规范 Java中的注释有三种单行注释——在新的一行,用//后面跟着注释。只能注释一行文字多行......
  • 第一个程序-2022-10-28
    HelloWorld1.新建文件夹,存放代码命名:code安装NOTEPAD++软件在code文件夹中建立文件:hello.java注意后缀名用notepad++打开编辑语句:publicclasshello{......
  • 2022-10-28学习内容
    1.SharedPreferences用法1.1activity_share_write.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/and......
  • 【CFgym102870J】Junction of Orz Pandas(思维,容斥)
    暴力做法就不会做……考虑容斥,用所有数\(\leqa_i\)的方案减去所有数\(<a_i\)的方案得到最大值为\(a_i\)的方案,\(b_i\)同理容斥,时间复杂度\(O(2^{n+m}nm)\)。直......
  • 中文美句_Oct.28
    "我爱在黎明前起床,在山顶牧场上召唤太阳,云雀的歌声便是我异想天开的翅膀,朝露便是我晨起的浴缸。   ......