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

自动运行

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 文件

Python的配置

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

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

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 打开一个带界面的 LspDAP 的服务管理窗口,可以使用 数字键在上面进行跳转,找到想要的服务之后直接使用 i 来安装

也可以使用 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目录中。并且按语言名称来命名,例如关于 pythondap 配置我们放到 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 指定的方式来打开一个新的调试器进程。并且将对应的调试命令发送到调试器完成调试工作。



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

从零开始配置vim(28)——代码的编译、运行与调试的更多相关文章

  1. QT安装以及使用(QT支持linux和windows,也支持C/C++代码的编译运行,比vs简洁多)

    Windows: 0. QT Versionqt-win-opensource-4.7.4-mingwqt-creator-win-opensource-2.4.1 1. 系统Windows 7 &a ...

  2. xmake新增智能代码扫描编译模式

    最近给xmake增加了一个新特性,对于一份工程源码,可以不用编写makefile,也不用编写各种make相关的工程描述文件(例如:xmake.lua,makefile.am, cmakelist.tx ...

  3. VScode,code::blocksC语言编译运行出现不支持的16位应用程序解决方法

    最近,莫名其妙c代码就是编译运行不了,老是提示不支持的16位应用程序 然后网上找了各种教程 只有这个成功了(害得我还升了下系统) 实现进入Windows设置 然后点更新和安全--恢复 然后点高级启动- ...

  4. Vim配置:在win10下用vim编译运行C/C++(异步插件管理,一键运行)

    为什么用Vim 重新调配vim,追求尽量简单些. 安装 官网下载 PC: MS-DOS and MS-Windows下的 For modern MS-Windows systems (starting ...

  5. vim颜色选择+按<F9>自动编译运行+其他基本配置(ubuntu)

    (以下是ubuntu上的配置........ 但如果你是在window上的,直接用一下配置吧(懒得介绍了)=.= syntax on filetype indent plugin on set rul ...

  6. Maven配置插件跳过测试代码的编译和运行

    Maven配置插件跳过测试代码的编译和运行: <!-- 编译插件 --> <plugin> <groupId>org.apache.maven.plugins< ...

  7. EditPlus配置[C++] [Python] [Java] 编译运行环境

    以前一直用Codeblocks写C++,eclipse写Java,再在eclipse里面集成PyDev写Python,首先无法忍受代码自动补全功能(这个功能也许你万分喜欢),也无法忍受如此重量级的ID ...

  8. 使用Maven编译运行Storm入门代码(Storm starter)(转)

    Storm 官方提供了入门代码(Storm starter),即 Storm安装教程 中所运行的实例(storm-starter-topologies-0.9.6.jar),该入门代码位于 /usr/ ...

  9. Sublime Text 3配置C++编译运行

    2016.9.8更新: linux(Ubuntu16.04)下的配置,编译后用终端运行,解决了不能输入的问题 { "encoding": "utf-8", &q ...

  10. Learning Lua Programming (3) iMac下搭建Lua脚本最好的编码环境(代码补全,编译运行)

    这篇文章参考自http://blog.sina.com.cn/s/blog_991afe570101rdgf.html,十分感谢原作者的伟大创造,本人亲测可行. 这篇文章记录一下如何在MAC系统环境下 ...

随机推荐

  1. 取消 SQL Server 密码复杂度

    可以先设置一个复杂密码,安装完成后,进入数据库,执行下列命令,关闭复杂密码策略及修改简单密码 ALTER LOGIN sa WITH PASSWORD = '新密码', CHECK_POLICY = ...

  2. compilation.templatesPlugin is not a function

    ERROR Failed to compile with 1 error TypeError: compilation.templatesPlugin is not a function - SetV ...

  3. SpringBoot Jar 包太大 瘦身 【初试】

    SpringBoot Jar 包太大 瘦身,建议使用时,参考: SpringBoot Jar 包太大 瘦身 [终极版] 29M, 排除少量JAR包方式 打包,排除指定jar 包 <build&g ...

  4. 数据存入已有Excel

    import openpyxl filepath = r'.\UCB2Create_course\SuccsessCourse.xlsx' wb = openpyxl.load_workbook(fi ...

  5. 深入浅出 WebRTC AEC(声学回声消除)

    前言:近年来,音视频会议产品提升着工作协同的效率,在线教育产品突破着传统教育形式的种种限制,娱乐互动直播产品丰富着生活社交的多样性,背后都离不开音视频通信技术的优化与创新,其中音频信息内容传递的流畅性 ...

  6. 【辅助工具】Apifox

    注意事项 需要刷新权限 请求方式需要对应

  7. 蓝桥杯历年省赛试题汇总 C/C++ B组

    B组 省赛 部分 A组的题目可以在这里查看 → 刷题笔记: 蓝桥杯 题目提交网站:Here 2012 第三届 微生物增殖 古堡算式 海盗比酒量 奇怪的比赛 方阵旋转 大数乘法 放旗子 密码发生器 夺冠 ...

  8. 六、docker数据卷

    系列导航 一.docker入门(概念) 二.docker的安装和镜像管理 三.docker容器的常用命令 四.容器的网络访问 五.容器端口转发 六.docker数据卷 七.手动制作docker镜像 八 ...

  9. 小白学标准库之 log

    日常开发中,日志 log 几乎是必不可少.本文旨在介绍 log 的使用和内部实现等. 1. log 使用及实现 package main import ( "fmt" " ...

  10. C++ list容器

    一.前言 list容器,又称为双向链表容器,即该容器的底层是以双向链表的形式实现的,因此list容器中的元素可以分散存储在内存空间里,而不是必须存储在一整块连续的内存空间中. list容器中各个元素的 ...