lazyvim折腾日记(5)

lazyvim 折腾日记(5)

前言

前面针对 dart 配置了 lazyvim 下的开发环境,但是针对其配置原理我认为还没有讲透,所以本章想讲一讲其原理

本文想阐明一个问题,如何使用一个 ide 实现多种语言的开发

问题所在

以前在做软件开发的时候,往往一个语言对应一个专用的 ide . 随着编程语言越来越多,这种模式 ide 与编程语言深度绑定的模式给开发者(编程人员及语言维护人员)都带来不少负担。

对于编程人员来讲,他需要因为不同的语言熟悉不同的 ide ,这个事显然是有学习门槛的

对于语言维护人员来讲,他不仅需要维护编程语言本身,还需要额外维护一个 ide

如果说有 i 种语言 l 种编辑器是必须要使用的,那么上述的两种人员总共需要了解 i*l 种内容

而为了减少不同 ide 对不同语言支持的复杂度,便提出了在语言及 ide 中间做一个抽象层,对于编程语言及 ide 来讲只需要关注抽象层的应用及实现,将语言与 ide 解绑。从而将 i*l 的复杂度减少到 i+l ,该抽象层就称之为 LSP 全称 language server protocol ,中文翻译为 语言服务器协议

基本概念

为了厘清相关概念,特做次章节

语言服务器

语言服务器 language server 是一个基于 LSP 的概念,在 LSP 语义里面,语言服务器是一个应用程序,该程序封装了语言特性。针对其抽象语法树提供解析引用,错误诊断等功能

我个人使用的语言服务器有

  1. java 语言服务器jdtls
  2. dart 语言服务器flutter
  3. rimels 语言服务器rimels
  4. markdown 语言服务器marksman

其中

jdtls 使用 java 编写,dart 语言服务器集成在 dart 或 flutter 里,rimels 使用 rust 编写,marksman 使用 C# 编写

在前面的几个章节中,我们已经针对 dart rimels 进行了相关的配置

语言客户端

语言客户端 language client 这个术语也是在 LSP 话语体系中出现的,与 language server 相对应,指的就是平时常用的 ide

我们常用的 ide(语言客户端) 基本都支持 lsp 协议 如:

  • vscode
  • nvim
  • emacs
  • sublime text
  • jetbrains 系列
  • etc......

基本覆盖了开发范畴,语言服务器主要负责对语言服务器传回的结果进行显示,如语法高亮,cmp 提醒等等

语言服务器协议

语言服务器协议 LSP 指的是在 语言服务器语言客户端 之间的抽象层,通过规范 语言服务器语言客户端 之间的交互行为, 实现编程语言与 ide 的解耦

该协议通过 JSON_RPC 协议规范了收发双方的通信规范。用户在对编程文件进行操作的时候,语言客户端发送代码位置,语法树等内容给语言服务器。语言服务器根据接收内容告诉语言客户端哪些地方该高亮,哪些地方可能需要 cmp 补全

原理图

通过这种高级抽象,实现了编程复杂度的减少

lsp减少的工作量

从而实现一个 ide 同时编辑多种语言的目的

目的

DAP

同时为了提供更为详细的开发功能,开发者需要针对诸如程序的运行时,堆栈等进行处理。针对 debug 这一流程,提出了 Dubug Adapter protocol 这一概念。参考 LSP 的概念,DAP 通过提供相关接口从而实现对特定语言或运行时的监控与调试

ide 的基本功能及原理

对于一个 ide 来讲,有几类特性是必须要给用户提供的

  1. 代码编辑和生成
  2. 代码理解和导航
  3. 代码分析和优化

上面针对以上三种特性逐一讲解

代码编辑和生成

在生成代码方面,有如下具体的内容

  • 语法高亮:根据语法树为代码添加颜色和样式,提高代码可读性
  • 代码片段自动完成(auto completion)
    • 基于上下文提供可能的代码选项
    • 变量名补全
  • 代码片段(code snippets)
    • 预定义模板代码(getter setter 功能函数etc)
  • 智能缩进

其中 auto completion 与 code snippets 的区别在于

  • 对象: auto completion 通常针对短语,代码片段针对大量代码块
  • 触发方式: auto completion 通常自动完成,而代码片段通常需要特定触发词(区别于 code action)

代码理解和导航

在代码理解方面,有如下具体内容

  • 定义跳转(go to definition)
  • 引用寻找(find references)
  • 符号搜索(symbol search)
    • 符号包括函数方法,类和接口,变量和常量等等
    • 举个例子
      • Lua: 查找 end 对应的 function
      • Java: 寻找接口
  • 代码大纲视图

代码分析和优化

代码分析和优化包括

  • 错误诊断(Diagnostics)
  • 代码质量检查(Linter)
    • 规范代码风格
    • 检查不良实践
  • 代码格式化
    • 统一代码风格,提高代码可读性
  • 代码性能分析
    • 识别代码性能特征
  • 静态代码分析
    • 在不运行代码的情况下分析源代码
    • 如:
      • 安全漏洞检测
      • 空指针检测
  • 代码度量(code Metrics)
    • 量化代码属性,提供可量化的代码质量和复杂度指标
    • 如:
      • 代码复杂度
      • 代码行数
      • 代码可维护性

总结

LSP 对以上内容都进行了定义,通过在开发流程配置 LSP 在 debug 流程配置 DAP 从而实现将某一文本编辑器折腾为 ide

这同时也是我折腾 lazyvim 的关键原因

总结

本篇文章涉及两个主题

  1. lsp 与 dap 的基本概念
  2. ide 的基本功能

通过本篇文章大概讲清 lazyvim 的折腾思路了

参考文献

  1. editing support for software languages:implementation practices in language server protocols

  2. language server protocol: an introduction to protocol, its use,and adoption for web modeling tools

  3. language server extension guide

  4. language server protocol

  5. debug adapter protocol

  6. a guide on neovim's lsp client

  7. 以及相当一部分内容来源于 tabnine

posted @ 2025-02-03 19:47  五花肉炒河粉  阅读(260)  评论(0)    收藏  举报