vim的lsp配置
start at 2022/12/23?

虽然我本人不是特别喜欢用补全,但好像真的随着工作量的增大,只靠记忆和手速是干不过IDE的,所以我还是学习一下关于lsp的配置吧,以后以为效率低就找不到饭碗咯

虽然一只秉持能自己写插件就自己写的观念,但是写一个lsp之类的像AI一样我完全没接触过的领域,感觉我自己是完全写不出来,对我来说他们就像魔法一样

网上很多资料都是neovim的lsp配置,看的好烦啊,不知道为什么对neovim有一点抵触

主流的lsp插件有coc.nvim,但是它太庞大了,把vscode的应用给搬过来了,简直就是安装了一个生态系统,I dont like it

看上一款相对轻量的vim-lsp,之前一直没时间研究,今天来看看

安装LSP本体

先在windows上配置,如果windows上能配置好,linux上就轻而易举了

LSP,全称Language Server Protocol,最初用在微软的vscode,现在各大编辑器都开始使用了

原理很类似前后端分离,把补全想象成前后端,前端是编辑器,后端负责各种语法相关的工作,返回给前端

传统的补全都是一种编辑器自己写好一种语言的补全系统,如果想用其他编辑器用相同的语言补全系统,那么就需要再写一个补全系统了,LSP则只需要写好一个,各个编辑器向服务器端发送请求,服务器返回语法相关内容,所以只要编辑器处理好接口就行了,当然这个服务器不是真的跑在服务器上,而是跑在本地服务器上,所以不用担心个人隐私的泄露,其实也说不好,除非自己写一个LSP

image-20221220161204987

不想每次打开都加载,所以创了opt而不是start

进入opt的命令行中,执行

git clone git@github.com:prabirshrestha/vim-lsp.git
git clone git@github.com:mattn/vim-lsp-settings.git

第一个仓库是vim-lsp本体,第二个仓库是用来简便安装服务器的插件,只需要

:LspInstallServer

就能安装对应语言的lsp服务器

:LspUninstallServer server-name

来卸载服务器

安装后的服务器在以下位置

# windows:
%LOCALAPPDATA%\vim-lsp-settings\servers

# Linux
$HOME/.local/share/vim-lsp-settings/servers

You can change the directory to install servers by set g:lsp_settings_servers_dir option in full path.

先去试着安装了C++的补全,结果下载失败了,我猜要代理,然后自己去看了下插件怎么写的,发现这插件就是写一堆配置脚本嘛

image-20221220163412582

这是c的windows补全安装脚本

@echo off

setlocal
set VERSION=15.0.0
echo Downloading clang and LLVM...
curl -L -o LLVM-%VERSION%-win64.exe "https://github.com/llvm/llvm-project/releases/download/llvmorg-%VERSION%/LLVM-%VERSION%-win64.exe"
echo Running setup...

rem Run setup as regular user to avoid a UAC popup
set __COMPAT_LAYER=RUNASINVOKER
md tmp
.\LLVM-%VERSION%-win64.exe /S /D=%cd%\tmp
copy tmp\bin\clangd.exe clangd.exe
del LLVM-%VERSION%-win64.exe
rd /Q /S %cd%\tmp
.\clangd.exe --version

这版本还不是最新版本,最新版本是15.0.6,然后我自己去github上下,发现这个exe能有200+Mb,吓得马上给我停下来了,感觉还是自己装来的靠谱,还要换一下服务器的安装位置,装C盘是顶不住的

梳理了下我总共需要8种语言的补全:

  • python
  • c/c++
  • lua
  • java
  • go
  • rust
  • javascript
  • html

安装补全

一般都用asyncomplete.vim,老套路

git clone git@github.com:prabirshrestha/asyncomplete.vim.git

回归现实

2022/12/21 21:08

是时候回归现实了,昨天信誓旦旦的配了一天的lsp,最后还是没配出来

我试了LanguageClient-neovim,发现pyls的 hover 和 帮助文档 报错,最后用了ale,它自带了python的补全,用起来还可以,就是它老是报我的码风警报啊,为什么人人都要像你们规定的那样写代码啊!

遇到的问题都太奇葩,google不到,也不想issue,之后再回来配轻量的补全系统,感觉网上说的是真的,vim的配置时间比使用vim写代码的时间还要多,今天又干了些不知道在干什么的事情(因为在U管上看到一个vimer的界面觉得挺好的,很好奇是怎么做到的shotcut

本来以为可以设置换行长度,后来发现换行和折行是有区别的,以后开博细水一下

结果花了半天勉强做到这样( 颜色似乎是反了,不过懒得找snazzy的hi了,感觉也还般配

image-20221221212239253

我甚至还特地写了一个自己之前完全没想到过的用方向来调节RGB参数的vim脚本

vim9script

# R 
# G 
# B 

# source % to test
var R = 0
var G = 0
var B = 0

noremap <expr> l (line('.') <= 5 && line('.') >= 3) ? ":call PlusColor()<CR>" 
\ : "l"
noremap <expr> h (line('.') <= 5 && line('.') >= 3) ? ":call SulpColor()<CR>" 
\ : "h"

def Tran(xxx: number): string
    var rt = ""
    var lts = "0123456789abcdef"
    var tmp = xxx
    while tmp > 0
        rt = lts[tmp % 16] .. rt
        tmp = tmp / 16
    endwhile
    if len(rt) == 1
        rt = "0" .. rt
    elseif len(rt) == 0
        rt = "00"
    endif
    return rt
enddef

def Paint()
    exec "hi ColorColumn guibg=" .. "#" .. Tran(R) .. Tran(G) .. Tran(B)
    echo "#" .. Tran(R) .. Tran(G) .. Tran(B)
enddef

def g:PlusColor()
    var nowLine = line('.')
    if nowLine == 3
        R += R == 255 ? 0 : 1
    elseif nowLine == 4
        G += G == 255 ? 0 : 1
    elseif nowLine == 5
        B += B == 255 ? 0 : 1
    endif
    Paint()
enddef

def g:SulpColor()
    var nowLine = line('.')
    if nowLine == 3
        R -= R == 0 ? 0 : 1
    elseif nowLine == 4
        G -= G == 0 ? 0 : 1
    elseif nowLine == 5
        B -= B == 0 ? 0 : 1
    endif
    Paint()
enddef

顺便,纪念一下233!

xzczxsad

好了,回归正题,我决定用coc了!

因为 TheCW 有教学,还问了下vimzh电报群

image-20221221212653958

有些时候,我们害怕改变
但其实,我们只是需要一个理由罢了

COC

COC,全称为 Call of Cthulhu Conquer of Completion

注意,安装COC要求node.js环境,node >= 14.14

同样放在opt文件夹里

git clone https://github.com/neoclide/coc.nvim.git

git完之后启动vim,查看coc能不能用

:CocInfo

image-20221222154923472

网上一查,是没看清楚官方文档,不能直接clone master分支,要clone release分支

git clone --branch release https://github.com/neoclide/coc.nvim.git --depth=1

装的比master快10倍啊,装完之后

:packadd coc.nvim
:CocStart
:CocInfo

image-20221222161652809

环境应该没问题了,开始配置

说是配置,无非就是在coc的生态系统里下载插件,

# 下载插件
:CocInstall xxx
# 卸载插件
:CocUninstall xxx

当然,你可以把要配置的放在一个coc会处理的全局变量里

let g:coc_global_extensions = ["coc-marketplace"]

每次载入coc的时候如果没有有插件安装,它会自动帮你装上

然后我罗列一下我需要Install的coc插件

插件名 作用 用法
coc-marketplace 检索其他插件,能fzf :CocList marketplace<C-j><C-k>上下
coc-vimlsp 补全 vimscript LSP,开了就有,这东西不认我的vim9script
coc-tsserver 补全 javascript 和 typescript 开箱即用
coc-pyright 补全 python 官方文档,拆箱即用,意外的不报我不喜欢符号左右空格和用tab,哈哈哈哈哈。coc-python已经不维护了,不要用
coc-sumneko-lua 补全 lua 没搞好
coc-rls 补全 rust 到时候学rust的时候再配
coc-html 补全 html 先不去管,到时候要用的时候再配
coc-clangd 补全 c/c++ 要装好clang,流氓软件一样的,装clang一定要装LLVM,暂时不C系了,先不装
coc-java 补全 java jdk版本17,要点配置,配置的时候记得看官方文档,注意一下JAVA项目如果手动维护的话是非常麻烦的,虽然有了补全但还不是完全体
coc-xml 补全 xml,spring开发的时候用 到时候再配
coc-go 补全 golang 到时候再配
coc-sql 补全 sql 官方文档
coc-sh 补全 bash 官方文档
coc-highlight 当前相同的代码词高亮 官方文档
coc-explorer 文件管理系统,我以后一定会自己写一个的(真香 :CocCommand explorer
coc-translator 给我翻译翻译什么叫惊喜 记得看官方文档,engines参数调一个有道就行了
coc-git 应该显示当前行的修改状态吧 官方文档,还没配过

每次手动载入插件都很麻烦,就给我的mask里加了一层

image-20221222164007207

这个mask也是我写的插件,用来加载和切换配置都很方便,以后水一篇介绍吧

配java的环境变量记得还要改JAVA_HOME的,别只改了个Path就结束了

很多lsp插件都是装个协议,打开指定格式的文件的时候才会帮你下载服务器,装完之后最好先打开对应的文件测试一下管不管用,确实比自己配要方便的多啊,遇到问题是小概率事件

下面放点我折腾两天下来的配置吧

plugs.vim

"*****coc.nvim
let g:coc_global_extensions = []
let g:flagHLSame=0
let g:coc_explorer_global_presets={
 \ '.vim': {
 \		'root-uri': $HOME .. "/vimfiles",
 \		'position': 'right'
 \ }
 \}
"let b:coc_suggest_disable=1

" useless: because of the source order
"hi CocHighlightText guifg=#00cc00 gui=underline
au BufRead,BufNewFile * :let b:coc_suggest_disable=1

function SwHLSame()
    if g:flagHLSame==0
        autocmd CursorHold * silent call CocActionAsync('highlight')
        let g:flagHLSame=1
    else
        autocmd! CursorHold * 
        let g:flagHLSame=0
    end
endfunction

coc-settings.json

{
    "coc.preferences.extensionUpdateCheck": "daily",
    "suggest.noselect": true,
    "suggest.enablePreselect": false,
    "coc.preferences.formatOnSaveFiletypes": [
        "json"
    ],
    "translator.engines": [
        "youdao"
    ],
    "java.configuration.runtimes": [
        {
            "name": "JavaSE-17",
            "path": "C:/Program Files/Java/jdk-17.0.5",
            "default": true
        }
    ],
    "Lua.telemetry.enable": true,
    "suggest.autoTrigger": "always",
    "suggest.completionItemKindLabels": {
        "function": " \uf794 ",
        "variable": " \ue261 ",
        "class": " \uf503 ",
        "keyword": " \uf084 ",
        "file": " \uf15c ",
        "folder": " \uf74a ",
        "snippet": "{\uf9b1}",
        "text": " \uf49e ",
        "value": " \u91c "
    },
    "diagnostic.signOffset": 1,
    "diagnostic.errorSign": "\uf00d",
    "diagnostic.warningSign": "\ufa35",
    "diagnostic.infoSign": "\uf05a",
    "diagnostic.hintSign": "\uf834",
    "diagnostic.displayByAle": false,
    "diagnostic.refreshOnInsertMode": false,
    "diagnostic.refreshAfterSave": false,
    "diagnostic.checkCurrentLine": true,
    "diagnostic.virtualText": true,
    "diagnostic.virtualTextPrefix": ">>>",
    "explorer.icon.enableNerdfont": true,
    "explorer.icon.customIcons": {}
}

上面的suggest.completionItemKindLabels有些因为是用字符方式的,所以复制过来的时候乱码了,你只需要去coc-config.txt里面找这个词条就有所有项目(好像不全

mask.vim

    "coc": [
        "packadd coc.nvim",
        "CocStart",
        "inoremap <expr> <C-Space> coc#refresh()",
        "inoremap <expr> <Tab> pumvisible() ? coc#pum#next(1) : \"\<Tab>\"",
        "inoremap <expr> <S-Tab> pumvisible() ? coc#pum#prev(1) : \"\<S-Tab>\"",
        "nnoremap <Leader>K :call CocActionAsync('doHover')<CR>",
        # has some bug
        "nmap <silent> <Leader>rn <Plug>(coc-rename)",
        "nmap <silent> - <Plug>(coc-diagnostic-prev)",
        "nmap <silent> = <Plug>(coc-diagnostic-next)",
        "nmap <silent> <Leader>g <Plug>(coc-definition)",
        "nmap <Leader>tr <Plug>(coc-translator-p)",
        "vmap <Leader>tr <Plug>(coc-translator-pv)",
        "nnoremap <Leader>s :call SwHLSame()<CR>",
        # switch the complete
        "nnoremap <Leader>q :let b:coc_suggest_disable=1-b:coc_suggest_disable<CR>",
        "nnoremap <Leader>tt :CocCommand explorer --quit-on-open<CR>",
        "nnoremap <Leader>tl :CocCommand explorer --position right --width 33<CR>",
        "nnoremap <Leader>tv :CocCommand explorer --preset .vim<CR>",
        "echo '[M] COC Loaded.'",
    ],

下面看看效果吧

image-20221223171842237

补全效果

image-20221223171809110

错误提示

image-20221223172140326

文件浏览器

编译vim 和 闲话

感觉差不多了,再配下去要全职vimer了,还要提一嘴,如果你用的也是vim,并且是官网下载的gvim9.0的话,上面的错误信息你只会以popup窗口的形式展示,因为这个特性需要vim:9.0.0067才能用,而官网是vim:9.0.0

image-20221223172400229

你需要去github上下载最新的vim源码自己编译,编译说明src文件夹里面都有,照着说明来就行了,还有gvim默认都是用C://windows/gvim.bat打开的,编译完不要只改了Path里的路径,bat也改一下,记得用管理员权限

为什么自己编译的GVIM中文支持这么差,还有乱码

complieGvim

体验了一把 gentoo 装软件的体验

已经玩够了,差不多要收收心学后端了,又要学spring,又要字节青训学golang,还要教学妹点python的OI技巧

明天就要回家了,家里人都🐏了,回家肯定要🐏了啊

再吐槽一点点

ssds

vimlsp不认识vim9script

YDYL5M@T3COCV3J5G{}FBY5

真的是要配置疯了,下午到凌晨

20221223172932

你说的对,但是vim是一款...

无所谓了,2022年过的真是不爽啊!

2022/12/23
> CLICK TO back <