用vscode开发 ios/macos App
如何脱离 xcode 开发 iOS 是很多人在探索的方案。毕竟 xcode 编辑体验实在是太差了。
这里说的是脱离 xcode,而不是脱离 macOS。
SweetPad
这是今天要安利的工具 SweetPad。SweetPad 是 vscode 上的一个插件,插件可以实现在 vscode 中进行自动补全、调试、编译和运行、格式化、测试等功能。常见的开发场景中基本可以脱离 xcode 来使用。
如何脱离 xcode 开发 iOS 是很多人在探索的方案。毕竟 xcode 编辑体验实在是太差了。
这里说的是脱离 xcode,而不是脱离 macOS。
这是今天要安利的工具 SweetPad。SweetPad 是 vscode 上的一个插件,插件可以实现在 vscode 中进行自动补全、调试、编译和运行、格式化、测试等功能。常见的开发场景中基本可以脱离 xcode 来使用。

在使用 Neovim 之前,我也花费了大量的时间进行配置自己的 Neovim 体系,无论是插件,快捷键还是 UI,都花费了大量的心思。 但是维护一套自己的配置说实话很费时间,例如插件的更新,版本升级等。
LazyVim 是一款已经 集成了大量插件的 Neovim 软件。 基本做到了开箱即用,方便快捷,大量的默认配置减少了上手时间,唯一的缺点可能就是快捷键不是自己熟悉的那套,需要修改或者适应。
LazyVim 的安装其实很简单,首先打开官方的启动模板 LazyVim/starter。 点击右上角 Use this template ,将模板 fork 成为自己的仓库。 接下来就是备份本地原有的配置,将自己的仓库 clone 下来。
简单来说就是一个命令进行备份 另外一个命令进行 clone。 这部分可以直接参考官方网站对于安装的介绍文档。
安装完成之后,启动就是一个已经有了大量基础配置的 neovim 了,基本做到了开箱即用。
完成 LazyVim 的配置,记得看一下是否系统安装了 fzf。
在 LazyVim 的项目中,配置可以分成两大块:基础配置(config) 和 插件(plugins)。
config 配置主要是一些基础的配置,文件夹内区分了四个文件, 分别是基础配置(options.lua),快捷键配置(keymaps.lua),自动化命令(autocmds.lua)和 lazy 初始化配置。
默认 LazyVim 已经集成了很多插件,有的已经默认开启,有的需要手动开启。如果需要覆盖原有的插件配置或者安装新的插件, 可以在该文件夹下直接填写相关配置,最后在外层的 init.lua 中添加即可。
LazyVim 已经集成了大量的插件,并且默认了很多快捷键。默认的 Leader 为 空格。可以针对自己的习惯修改快捷键,也可以直接按下 Leader 来查看快捷键。
![]()
默认的快捷键我认为是比较合理,而且使用几次基本也会记住,这里我除了修改了一下 blink 候选提示的上下选择之后,并没有做其他修改。 默认的快捷键也可以在官方文档中找到 keymaps
LazyVim 一些默认的插件已经启用,但是除了默认插件,还有一些其他插件可以根据具体的情况按需使用。
通过 :LazyExtras 命令可以查看其他扩展插件。如果有自己使用的,需要的可以直接通过 x 进行启用。
需要注意的是启用后需要重新启动一些 neovim。
LazyVim 中自带了一些配置,例如 tab 为 2,在一些缩进比较多语言中,tab 为 2是比较友好的,例如 lua,但是对于一些项目,尤其是很团队合作的项目, tab 改成2 就会让代码一团乱。
在 options.lua 中新增一些 tab 相关的配置。
local opt = vim.opt
opt.expandtab = true
opt.tabstop = 4
opt.shiftwidth = 4
opt.softtabstop = 4
同时为了让 lua 还保持 tab 为2的缩进,在 autocmds.lua 中新增自动化命令。
vim.api.nvim_create_autocmd("FileType", {
pattern = { "lua" },
callback = function()
vim.opt_local.expandtab = true
vim.opt_local.tabstop = 2
vim.opt_local.shiftwidth = 2
vim.opt_local.softtabstop = 2
end,
})
还有一个就是中文拼写问题,默认的 spell 一直检查,尤其是在进行 markdown 的时候,大量的波浪线导致编辑的感官太差,可以新增命令来解决。
vim.api.nvim_create_autocmd("FileType", {
pattern = { "markdown", "txt" },
callback = function()
vim.opt_local.spell = false
end,
})
![]()
LazyVim 对 vscode 支持比较好,并且 vscode-neovim 也推荐使用 lazyvim。通过这个插件,可以让我们在 Vscode 中加载一些 Neovim 的插件,做到一个配置两处使用。
首先需要在 LazyExtras 中打开 Vscode 。 然后在 Vscode 中安装 Vscode Neovim 插件。
在 LazyVim 中可以通过 vim.g.vscode 来判断当前的运行环境。
首先是对快捷键进行配置,比如常用的重命名、格式化等。
local map = vim.keymap.set
if vim.g.vscode then
map("n", "<leader>cf", "<Cmd>lua require('vscode').call('editor.action.formatDocument')<CR>", { desc = "Format" })
map("v", "<leader>cf", "<Cmd>lua require('vscode').call('editor.action.formatSelection')<CR>", { desc = "Format" })
map("n", "<leader>cr", "<Cmd>lua require('vscode').call('editor.action.rename')<CR>", { desc = "Rename" })
end
针对 Golang 开发,首先就是语言的相关配置:
Mason 安装 gopls;LazyExtras 进行安装 test.core;Mason 安装 dlv。安装完成就可以进行编辑,运行,测试和调试。
可以通过 <Leader>tr 进行测试运行。
![]()
通过 <Leader>db 进行打断点。
通过 <Leader>dc 进行 Debug 运行。
![]()

对于一个编辑器来说,如果要完成例如自动补全,查找相关定义等功能是需要进行大量的开发的。不同的编辑器为了不同的语言都需要进行开发,而 LSP 的存在就是将这个过程检化。LSP 的全称为 Language Server Protocol,定义了编辑器和语言服务之间使用的协议。只要相关语言支持 LSP,那么编辑器只要符合相关要求实现即可完成例如自动补全等功能,而且不同的编辑器使用的体验是一致的。
目前支持 LSP 的编辑器有很多,例如大名鼎鼎的 Vscode。当然 vim 8 以后版本和 neovim 也都支持,具体支持的编辑器/IDE 列表可以看 LSP 的官方网站,同时支持 LSP 的语言也可以找到 支持语言。
neovim 已经是支持 LSP 了,具体可以在相关的配置文档看到,该文档详细的描述了如何配置一个 LSP。相对来说,配置过程比较繁琐,所以官方又提供了另一个库 nvim-lspconfig。接下来我们就通过这个插件来配置 neovim 的 lsp。
与安装其他插件是一样的,只需要我们在 plugins_config.lua 中添加相关配置即可,这里不进行赘述了。安装完成后其实进行配置就可以启用 LSP 了,就是这么简单。例如支持 rust 的 LSP,只需要进行简单的配置。
lspconfig.rust_analyzer.setup {
settings = {
['rust-analyzer'] = {},
},
}
但是,nvim 只是 lsp 的客户端,那么就存在 lsp 的服务端。上面配置的 rust_analyzer 就是 rust 语言的服务端,就需要我们进行服务端的安装。rust_analyzer 的服务端地址是 rust-lang/rust-analyzer,需要将服务端下载并且安装好,这样每次编写rust的时候就会享受 lsp 的服务加成了。
但是这样做有几个问题,当然也不能算问题,只是不太方便。
面对上面的不方便,你可能已经想到很多解决方法,例如写个脚本进行一键安装和更新常用的 lsp 服务端。这样基本解决了上面说的所有问题。正如你想的那样,今天的第二位主角 williamboman/mason.nvim。
![]()
mason 是一个可以方便的管理 LSP 服务端,DAP 服务端,Linter 和 格式化工具的插件。安装它之后,上面所说的问题将不是问题。
为了让 mason 和 nvim-lspconfig 更好的配合,这里还需要安装另一个插件 williamboman/mason-lspconfig.nvim
同样的安装这里不多赘述,主要是进行相关的配置。这里为了区别其他的插件,我们在 lua 目录下建立新的文件夹 lsp,用来专门存放 lsp 的配置。
首先还是加载我们的插件。在 lsp 文件夹中新建 mason.lua 文件,在文件中新增下面的配置。配置主要是在加载插件。
-- mason.lua
local mason_status, mason = pcall(require, "mason")
if not mason_status then
vim.notify("没有找到 mason")
return
end
local nlsp_status, nvim_lsp = pcall(require, "lspconfig")
if not nlsp_status then
vim.notify("没有找到 lspconfig")
return
end
local mlsp_status, mason_lspconfig = pcall(require, "mason-lspconfig")
if not mlsp_status then
vim.notify("没有找到 mason-lspconfig")
return
end
mason.setup()
mason_lspconfig.setup({})
配置完成后,重新启动 nvim,此时就可以采用 mason 进行 LSP 的服务端进行管理了。只需要按下 :Mason 即可。你将会看到如下的界面。
![]()
通过界面上的帮助可以看到如何使用,通过数字可以选择不同的服务端项目,2 为 LSP , 3 为 DSP 等。今天只是使用 LSP,可以直接按 2,选择到 LSP 界面,进行 LSP 安装。仍旧是通过 j 和 k 进行滑动。第一个安装的 lsp 服务端为 lua 语言的服务端:lua-language-server。这个是 lua 语言的语言服务,有 lsp 之后,我们之后无论是配置 nvim 还是编写 lua 都会有 lsp 服务的加持。按下 i 进行安装。
稍等片刻,安装完成。接下来就是配置,让 nvim 知道我们的 lsp 已经安装,在合适的时候进行启动。
-- mason.lua
nvim_lsp.lua_ls.setup({
on_init = function(client)
local path = client.workspace_folders[1].name
if not vim.loop.fs_stat(path .. "/.luarc.json") and not vim.loop.fs_stat(path .. "/.luarc.jsonc") then
client.config.settings = vim.tbl_deep_extend("force", client.config.settings, {
Lua = {
runtime = {
version = "LuaJIT",
},
workspace = {
checkThirdParty = false,
library = {
vim.env.VIMRUNTIME,
},
},
},
})
client.notify("workspace/didChangeConfiguration", { settings = client.config.settings })
end
return true
end,
})
这样 lua 的 lsp 就配置成功了,当我们编写 lua 脚本的时候,如果发生错误就会有相关提醒。当然这只是 lsp 最基础的功能,例如代码跳转,代码补全等需要我们进行配置。
![]()
基本所有的 lsp 的配置都可以在 server_configurations.md 中找到,当然 lua_ls 也不例外,上面的配置就是直接从文档中复制的 😄。
当前的 LSP 配置已经支持代码跳转,code action 等功能。例如查看当前变量或者函数的文档,可以使用这个命令 :lua vim.lsp.buf.hover()。
![]()
相关的命令还有其他
| 功能 | 命令 |
|---|---|
| 文档显示 | :lua vim.lsp.buf.hover() |
| 查看定义 | :lua vim.lsp.buf.definition() |
| 重命名 | :lua vim.lsp.buf.rename() |
| 查询实现 | :lua vim.lsp.buf.implementation() |
| 查询引用 | :lua vim.lsp.buf.refreences() |
| 查询声明 | :lua vim.lsp.buf.declaration() |
| 格式化 | :lua vim.lsp.buf.format() |
| Code action | :lua vim.lsp.buf.code_action() |
对于这些基础功能来说,每次需要的时候都在命令模式下敲一堆,速度的确是很慢的。所以,可以将上述的命令定义为快捷键,这样每次只需要进行快捷键进行完成上述功能。
打开我们之前设置快捷键的配置文件 keybinding.lua,新增上述功能的配置。
-- keybinding.lua
-- lsp 快捷键设置
pluginKeys.lspKeybinding = function(mapbuf)
-- rename
mapbuf("n", "<leader>r", ":lua vim.lsp.buf.rename<CR>", opt)
-- code action
mapbuf("n", "<leader>ca", ":lua vim.lsp.buf.code_action()<CR>", opt)
-- go to definition
mapbuf("n", "gd", ":lua vim.lsp.buf.definition()<CR>", opt)
-- show hover
mapbuf("n", "gh", ":lua vim.lsp.buf.hover()<CR>", opt)
-- format
mapbuf("n", "<leader>=", ":lua vim.lsp.buf.format { async = true }<CR>", opt)
end
完成快捷键的配置,那么就可以将快捷键绑定到刚刚配置的 lsp 服务端了。
-- mason.lua
function LspKeybind(client, bufnr)
local function buf_set_keymap(...)
vim.api.nvim_buf_set_keymap(bufnr, ...)
end
-- 绑定快捷键
require("keybinding").lspKeybinding(buf_set_keymap)
end
接下来可以完成快捷键的绑定。
-- mason.lua
nvim_lsp.lua_ls.setup({
on_attach = LspKeybind,
on_init = function(client)
-- 省略其他配置
end,
})
这样就完成了 lua 的 lsp 的配置,在编写 lua 的时候就可以使用文档查看,code Action 等功能。
目前这些 lsp 的服务都要手动下载,对于一些日常使用的服务,我们可以通过配置,在第一次加载配置的时候,当机器上没有相关的服务的时候,自动下载,这样来说,基本实现了我们上述提出的问题。
-- mason.lua
mason_lspconfig.setup({
automatic_installation = true,
ensure_installed = { "lua_ls", "rust_analyzer" },
})
这样配置,如果我们本地没有安装 lua 和 rust 的 lsp,会自动进行下载安装。
直到目前,在 lsp 的加持下,其实编辑体验已经变得非常棒了,而且开发速率也会大幅提升,虽然 lsp 是支持自动补全功能的,但是上面其实一直没有提及。主要是单单靠 neovim 的功能还不够强大,需要插件的配置。
hrsh7th/nvim-cmp 是一个采用 lua 编写的补全引擎,通过 cmp 及 cmp 的相关插件,会将 neovim 的自动补全达到一个新的高度。
这里除了 nvim-cmp,再推荐几个 cmp 的相关插件。更多的相关插件可以在 wiki 中找到
同样不赘述安装。在 lsp 文件夹中新建 cmp.lua 文件夹。
-- cmp.lua
local status, cmp = pcall(require, "cmp")
if not status then
vim.notify("找不到 cmp")
return
end
剩下了就可以将之前的补全源进行配置。这里贴出我的补全源。
sources = cmp.config.sources({
{ name = "codeium" }, -- 需要安装 codeium.nvim
{ name = "nvim_lsp" },
-- For vsnip users.
{ name = "vsnip" },
}, {
{ name = "buffer" },
{ name = "path" },
}),
此时当我们进行输入的时候就可以看到自动补全的提示了。对于自动补全的提示,上下选择并且上屏,我们可以设置快捷键,来满足我们的使用习惯。
和之前设置快捷键一样,在 keybindings.lua 中添加相关配置。
-- keybindings.lua
pluginKeys.cmp = function(cmp)
return {
-- 出现补全
["<A-.>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
-- 取消
["<A-,>"] = cmp.mapping({
i = cmp.mapping.abort(),
c = cmp.mapping.close(),
}),
-- 上一个
["<C-k>"] = cmp.mapping.select_prev_item(),
-- 下一个
["<C-j>"] = cmp.mapping.select_next_item(),
-- 确认
["<CR>"] = cmp.mapping.confirm({
select = true,
behavior = cmp.ConfirmBehavior.Replace,
}),
}
end
最后在 cmp.lua 中使用这些快捷键即可。
cmp.setup({
-- 省略其他配置
mapping = require("keybindings").cmp(cmp),
})
这样便可以完成自动补全的配置了。
目前为止,已经完成 nvim 的 lsp 的相关配置,并且添加了自动补全。篇幅限制,剩下如何美化 lsp 提示,美化自动补全等我们下篇再说。
我的 neovim 相关配置,可以提供大家进行参考 youngxhui/nvim。

![]()
这已经是我第 N + 1 次尝试 vim 了。这是之前的 基础教程
个人认为学习 vim 的曲线是比较陡峭的,尤其是刚刚开始的时候,各种指令让人根本记不住。就连熟悉的 Ctrl c/v 大法都不能用了。
这里我安装的是 neovim
后来开始慢慢的尝试,发现要学会 vim 的各种命令,首先要明白各种命令代表着是什么意思。
| 命令 | 操作 | 解释 |
|---|---|---|
| a | 在光标尾部进行编辑 | append |
| i | 在光标首部进行编辑 | insert |
| o | 在光标下一行进行编辑 | - |
| y | 复制 | yank |
| p | 粘贴 | pates |
| u | 撤销 | undo |
| ctrl+r | 反撤销 | redu |
命令实在太多了,需要慢慢记忆和使用。
任何一款强大的编辑器都离不开插件系统的支持,有插件的支持可以使得任何文本编辑器逐渐媲美IDE。
在vim中安装插件要麻烦一点,毕竟原有的 vim 本身并没有插件系统,需要其他程序来实现。
neovim 在 windows 中的配置文件在 ~/AppData/Local/nvim 中的 init.vim (如果没有该文件自己新建一个即可)。
首先安装插件系统,对于 vim 中的插件系统是很多的。例如 Vundle、NeoBundle、VimPlug等。
我使用的是 vimPlug 。首先要安装 VimPlug 。对于 Vimplug 在windows上的安装只需要一行命令。
bash
iwr -useb https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim |`
ni "$(@($env:XDG_DATA_HOME, $env:LOCALAPPDATA)[$null -eq $env:XDG_DATA_HOME])/nvim-data/site/autoload/plug.vim" -Force
安装完成需要将下面配置添加到 init.vim 中的插件系统是很多的。例如
vim
call plug#begin('~/AppData/Local/nvim/plugged')
call plug#end()
插件将在这个块中进行配置。
新增插件后只需要保存后,通过命令 :PlugInstall 命令进行安装即可。
vim-go 是一个很好的插件,安装即可完成对 golang 的支持。其中第一次使用的时候需要安装一些配置。通过命令 :GoInstallBinaries 安装必要的包。等待安装完成后就有了基本的对 Golang 的支持了,比如运行代码等。通过 :GoRun 就可以完成代码的运行,但是目前还有问题,下方的输出会看不到多余的输出代码,这个问题还要继续研究研究。
vim-go 还有很多功能,日后逐渐熟悉了再介绍。
自从微软提出了 LSP 服务,自动补全变得比较统一。通过安装 coc-nvim 来进行自动补全。我这里主要是 Golang 的自动补全。
需要 nodejs 环境进行自动补全。 Coc 是 vim 的插件,同时 Coc 又有自己的插件(套娃组合)
通过 :CocInstall 进行安装服务。
在完成 Golang 的 LSP 服务后,就可以完成自动补全了。
效果如下所示
![]()
有自动补全的提示和文档提示。
重新系统学习 Golang。之前学习Golang都是用什么学什么,不系统,不全面,很多知识点一知半解。这次通过阅读 《Go程序设计语言》这本书来系统的学习一下。
这是我第一次知道 Golang 其实是可以从启动是直接输入参数的,之前看到很多库都是使用 flag,也让我一度认为启动时传入参数必须使用 flag,比较这也好理解,谁让 Golang 的 main 函数和 java 或者 c 不太一样呢?
|
|
Golang 直接 func main() ,想传入参数也不知道如何进行。
原来 Golang 是有个 os.Args 这个方法,Args的底层数据结构是一个字符串切片 var Args []string,这样就方便的获取到从命令行输入的参数。但是这里的 Args[0] 并不是传入的第一个元素,而是该程序的名字。
|
|
所以要获得该程序从命令行传入的参数应该为 Args[1:],这样可以获取全部传入的值。
首先指针未赋值初始化为 nil。
其他零值
官方对其他类型做出了规定 The Zero value
类型 初始值 bool false numeric 0 string "" pointers,functions,interfaces nil slices,channels,map nil
同时指针是可比较的,当且仅当指向同一个变量或者都为 nil 的时候才相同。
new() 函数通过传入一个类型,得到该类型的指针。同时每次执行new() 返回的指针值是不一样的。但是有一些例外:两个变量的类型不携带任何信息且是零值,它们有相同的地址,例如struct{}。 1.16 版本实现好像已经更改。
Go 的基本数据类型分为四类:基本类型,聚合类型,引用类型和接口类型。
字符串是不可变类型。这一点和 Java 是一致的,但是为什么呢?不可变意味着两个字符串可以安全地公用同一段底层内存,使得复制任何长度字符串的开销都低廉。
字符串可以与字节 slice 相互转换。
|
|
之前听过这样一句话,一个语言的成熟与否要看他对字符串的方法多不多。Golang 提供了以下包对字符串进行处理。bytes,strings,strconv,unicode。
对于数组来说, [3]int 和 [4]int 是两个不同的数组类型。数组的长度必须是常量表达式(要你有何用?)。
Golang 的数组还挺有意思的,例如下面这样
|
|
表示长度为 100 的数组,其中前99个都是 0,最后一个为 -1。
Golang 在数组和其他类型上都是值传递。需要引用传递使用指针。
|
|
Golang 中的数组和 PHP 的数组还有点相似,可以作为k-v使用,但是 k 只能是数。arr := []string{0: "1", 2: "2"} ,这个数组遍历后的结果为如下:
|
|
会多出一个新的索引 1 。
Slice 的底层为一个可变数组。
|
|
slice 无法用 == 比较,与 nil 可以,标准库中只有 bytes.Equal 比较两个 byte 的slice。 其他的就要自己实现了。(难道是因为没有泛型,作者要写多个实现?)
struct 结构体嵌套,而且匿名嵌套
|
|
这里的 Point 和 Circle 可以采用这种匿名方式。而调用可以直接调用,像下面这种情况,第3行和第4行为相同的调用。
|
|
但是不允许在同一个结构体中定义两个相同类型的匿名成员。
匿名函数可以作为函数的参数和返回值。
|
|
之前只用来作为资源关闭的操作,没想到还有 其他 操作。
defer后面可以为一个函数,通过函数调用来实现更多功能。
|
|
使用 defer 也有很多需要注意的地方。例如在循环中使用 defer。这个是无效的,并不能及时的回收资源,最好是将循环体和 defer 封装为一个函数,每次调用函数后会执行 defer。
宕机会引起程序异常退出。宕机代表的程序执行的终止,但是 Golang 提供了宕机恢复函数 recover。recover 会终止当前的宕机状态,并且返回宕机值。
Golang 中对方法和函数有定义,emmmm🦤,方法是特殊的函数。
|
|

对于一个编辑器来说,如果要完成例如自动补全,查找相关定义等功能是需要进行大量的开发的。不同的编辑器为了不同的语言都需要进行开发,而 LSP 的存在就是将这个过程检化。LSP 的全称为 Language Server Protocol,定义了编辑器和语言服务之间使用的协议。只要相关语言支持 LSP,那么编辑器只要符合相关要求实现即可完成例如自动补全等功能,而且不同的编辑器使用的体验是一致的。
目前支持 LSP 的编辑器有很多,例如大名鼎鼎的 Vscode。当然 vim 8 以后版本和 neovim 也都支持,具体支持的编辑器/IDE 列表可以看 LSP 的官方网站,同时支持 LSP 的语言也可以找到 支持语言。
neovim 已经是支持 LSP 了,具体可以在相关的配置文档看到,该文档详细的描述了如何配置一个 LSP。相对来说,配置过程比较繁琐,所以官方又提供了另一个库 nvim-lspconfig。接下来我们就通过这个插件来配置 neovim 的 lsp。
与安装其他插件是一样的,只需要我们在 plugins_config.lua 中添加相关配置即可,这里不进行赘述了。安装完成后其实进行配置就可以启用 LSP 了,就是这么简单。例如支持 rust 的 LSP,只需要进行简单的配置。
|
|
但是,nvim 只是 lsp 的客户端,那么就存在 lsp 的服务端。上面配置的 rust_analyzer 就是 rust 语言的服务端,就需要我们进行服务端的安装。rust_analyzer 的服务端地址是 rust-lang/rust-analyzer,需要将服务端下载并且安装好,这样每次编写rust的时候就会享受 lsp 的服务加成了。
但是这样做有几个问题,当然也不能算问题,只是不太方便。
面对上面的不方便,你可能已经想到很多解决方法,例如写个脚本进行一键安装和更新常用的 lsp 服务端。这样基本解决了上面说的所有问题。正如你想的那样,今天的第二位主角 williamboman/mason.nvim。
mason 是一个可以方便的管理 LSP 服务端,DAP 服务端,Linter 和 格式化工具的插件。安装它之后,上面所说的问题将不是问题。
为了让 mason 和 nvim-lspconfig 更好的配合,这里还需要安装另一个插件 williamboman/mason-lspconfig.nvim
同样的安装这里不多赘述,主要是进行相关的配置。这里为了区别其他的插件,我们在 lua 目录下建立新的文件夹-lsp,用来专门存放 lsp 的配置。
首先还是加载我们的插件。在 lsp 文件夹中新建 mason.lua 文件,在文件中新增下面的配置。配置主要是在加载插件。
|
|
配置完成后,重新启动 nvim,此时就可以采用 mason 进行 LSP 的服务端进行管理了。只需要按下 :Mason 即可。你将会看到如下的界面。
通过界面上的帮助可以看到如何使用,通过数字可以选择不同的服务端项目,2 为 LSP , 3 为 DSP 等。今天只是使用 LSP,可以直接按 2,选择到 LSP 界面,进行 LSP 安装。仍旧是通过 j 和 k 进行滑动。第一个安装的 lsp 服务端为 lua 语言的服务端:lua-language-server。这个是 lua 语言的语言服务,有 lsp 之后,我们之后无论是配置 nvim 还是编写 lua 都会有 lsp 服务的加持。按下 i 进行安装。
稍等片刻,安装完成。接下来就是配置,让 nvim 知道我们的 lsp 已经安装,在合适的时候进行启动。
|
|
这样 lua 的 lsp 就配置成功了,当我们编写 lua 脚本的时候,如果发生错误就会有相关提醒。当然这只是 lsp 最基础的功能,例如代码跳转,代码补全等需要我们进行配置。
基本所有的 lsp 的配置都可以在 server_configurations.md 中找到,当然 lua_ls 也不例外,上面的配置就是直接从文档中复制的 😄。
当前的 LSP 配置已经支持代码跳转,code action 等功能。例如查看当前变量或者函数的文档,可以使用这个命令 :lua vim.lsp.buf.hover()。
相关的命令还有其他
| 功能 | 命令 |
|---|---|
| 文档显示 | :lua vim.lsp.buf.hover() |
| 查看定义 | :lua vim.lsp.buf.definition() |
| 重命名 | :lua vim.lsp.buf.rename() |
| 查询实现 | :lua vim.lsp.buf.implementation() |
| 查询引用 | :lua vim.lsp.buf.refreences() |
| 查询声明 | :lua vim.lsp.buf.declaration() |
| 格式化 | :lua vim.lsp.buf.format() |
| Code action | :lua vim.lsp.buf.code_action() |
对于这些基础功能来说,每次需要的时候都在命令模式下敲一堆,速度的确是很慢的。所以,可以将上述的命令定义为快捷键,这样每次只需要进行快捷键进行完成上述功能。
打开我们之前设置快捷键的配置文件 keybinding.lua,新增上述功能的配置。
|
|
完成快捷键的配置,那么就可以将快捷键绑定到刚刚配置的 lsp 服务端了。
|
|
接下来可以完成快捷键的绑定。
|
|
这样就完成了 lua 的 lsp 的配置,在编写 lua 的时候就可以使用文档查看,code Action 等功能。
目前这些 lsp 的服务都要手动下载,对于一些日常使用的服务,我们可以通过配置,在第一次加载配置的时候,当机器上没有相关的服务的时候,自动下载,这样来说,基本实现了我们上述提出的问题。
|
|
这样配置,如果我们本地没有安装 lua 和 rust 的 lsp,会自动进行下载安装。
直到目前,在 lsp 的加持下,其实编辑体验已经变得非常棒了,而且开发速率也会大幅提升,虽然 lsp 是支持自动补全功能的,但是上面其实一直没有提及。主要是单单靠 neovim 的功能还不够强大,需要插件的配置。
hrsh7th/nvim-cmp 是一个采用 lua 编写的补全引擎,通过 cmp 及 cmp 的相关插件,会将 neovim 的自动补全达到一个新的高度。
这里除了 nvim-cmp,再推荐几个 cmp 的相关插件。更多的相关插件可以在 wiki 中找到
同样不赘述安装。在 lsp 文件夹中新建 cmp.lua 文件夹。
|
|
剩下了就可以将之前的补全源进行配置。
|
|
此时当我们进行输入的时候就可以看到自动补全的提示了。对于自动补全的提示,上下选择并且上屏,我们可以设置快捷键,来满足我们的使用习惯。
和之前设置快捷键一样,在 keybinding.lua 中添加相关配置。
|
|
最后在 cmp.lua 中使用这些快捷键即可。
|
|
这样便可以完成自动补全的配置了。
目前为止,已经完成 nvim 的 lsp 的相关配置,并且添加了自动补全。篇幅限制,剩下如何美化 lsp 提示,美化自动补全等我们下篇再说。