neovim-vim的分支版本

概述

NeoVim 旨在成为Vim的升级版,有不少对它的介绍,我就不赘述了。
NeoVim官网强调了它的四大特点:Powerful plugins(强大的插件)、Better out-of-the-box(更好的开箱即用)、First-class embedding(高度支持嵌入模式)、Drop-in replacement for Vim(直接替换Vim)。

配置

Windows:

Neovim与Vim在不同系统中的配置信息保存位置:

app 系统 配置文件 插件存储
Neovim Windows ~\Appdata/Local\nvim\init.lua ~\Appdata\nvim-data\
Neovim Linux ~/.config/nvim/init.lua ~/.local/share/nvim/
Vim Window ~/.vimrc 或 _vimrc ~\vimfiles\
Vim Linux ~/.vimrc ~/.vim/

在Neovim 0.5中,nvim支持使用lua作为初始化配置文件(init.lua)。init.vim与init.lua同时只能存在一个。

技巧

windows 10 兼容vim和neovim配置

在开发中难免会遇到两者交叉使用的过程中,为了尽量避免重复配置,所以这里做了映射(类似于linux的ln命令)。在windows 10以前的windows系统中,创建目录软链接可以使用mklink命令,但是这里需要再做一个文件的链接,所以需要使用windows 10的新命令New-Item

New-Item -Path '目标路径' -ItemType SymbolicLink -Value '源路径'
New-Item -Path 'C:\Program Files\Python39\python3.exe' -ItemType SymbolicLink -Value 'C:\Program Files\Python39\python.exe'
New-Item -Path 'C:\Users\user1\AppData\Local\nvim' -ItemType SymbolicLink -Value 'C:\Users\user1\.vim'
New-Item -Path 'C:\Users\user1\AppData\Local\nvim\init.vim' -ItemType SymbolicLink -Value 'C:\Users\user1\.vimrc'

windows 下 python 支持

  1. 安装python3
    使用python官方下载的包安装python3,这里不要使用Microsoft应用商店的方式安装,应用商店的文件夹权限受限。
  2. 安装python neovim支持
cmd
python -m pip install --upgrade neovim
  1. 修改neovim配置文件
if has("win32")
    let g:python3_host_prog = "C:/Program Files/Python39/python.exe"
endif

实际配置过程中,例如coc.vim需要neovim 0.4+,这里需要根据具体配置进行更新。

vim-plug 无法访问github

最近github的访问一直受阻,需要配合代理解决。
windows下可以使用Proxifier让neovim支持代理访问,linux可以通过设置环境变量ALL_PROXY完成代理设置。

ALL_PROXY="socks://127.0.0.1:1080" nvim-qt

vim-plug 部分插件更新失败

在刚开始更新vim插件的时候,vim-airline始终更新失败。后来在vim-airline的issue中发现,可能是文件冲突。在我的系统中,插件文件夹原先存在的vim-airline可能源于另外一个包,但是neovim执行更新的时候,无法解决这个冲突。所以只要手动删除这个文件夹,重新更新就可以了。

neovim 3.2-dev 隐藏标签栏

在3.2版本中,虽然通过gui选项隐藏了UI信息,但是上面多出来一个标签栏(tabline),这和airline插件有点功能重复了,而且不美观.所以可以通过命令传参的方式隐藏标签栏

nvim-qt --no-ext-tabline

共享剪贴板

neovim是不自带与系统剪贴板互通的功能,在neovim中输入:h clipboard可以看到

:Nvim has no direct connection to the system clipboard. Instead it depends on a |provider| which transparently uses shell commands to communicate with the system clipboard or any other clipboard "backend".

解决办法:
用包管理器安装一个用于管理系统剪贴板的命令行工具(xsel或xclip)即可!
这里选择使用xclip

emerge xclip

安装完成后重启neovim,然后在命令模式下输入"+yy 即可将当前光标说在行复制到系统剪贴板,这时候便可在其他任何接受文本输入的地方,按 ctrl+v 粘贴了.

全屏

最近在用neovim的时候,遇到一个小问题以前写的切换窗口/全屏的热键无效了.跟踪了下脚本,问题出现在v:windowid返回0.
后来google一下,发现遇到同样问题的人不在少数,主要症结还是由于neovim是允许多客户端存在,而并非每个UI都需要实现一遍neovim.所以就存在windowid绑定的问题,这里就不讨论细节了。
既然是由于windowid无法获取,那就找个工具获取当前neovim gui的windowid就可以了,这里找到一个工具叫xdotool可以做到。

xdotool getactivewindow
# 23455342

直接输出windowid,简单粗暴,后来发现wmctrl直接可以设置当前激活窗口的windowid。

wmctrl -r ":ACTIVE:" -b toggle,maximized_vert,maximized_horz

相对应的,在windows同样会有这个问题,windows下没有wmctrl,无奈只能手写一个。
在WSL2下,nvim-qt 支持调用windows 10下的程序,宿主系统已经被自动映射到了/mnt/下面,但是需要注意\需要进行转义,变成\\才可以。

vim ~/.vimrc
function! ToggleMaxWindow()
    call system("wmctrl -r \":ACTIVE:\" -b toggle,maximized_vert,maximized_horz");
endfunction
map <silent> <leader>mw :call ToggleMaxWindow()<cr>
" {{{ 检测系统类型
let g:osType = ""
if has("win32")
    let g:osType="windows"
else
    let a=system("uname -a")
    if a =~ "microsoft"
        let g:osType="wsl"
    elseif a =~ "linux"
        let g:osType="linux"
    elseif a =~ "microsoft"
        let g:osType="wsl"
    elseif a =~ "CYGWIN"
        let g:osType="cygwin"
    endif
endif
" }}}

"{{{ 改变窗口大小
function! ToggleMaxWindow()
    " gvim is ok,but neomvim not good
    "    "windows窗口控制:最大化窗口、还原窗口,最小化窗口
    "    nmap    <leader>mw    <ESC>:simalt ~x<CR>
    "    nmap    <leader>nw    <ESC>:simalt ~r<CR>
    "    nmap    <leader>sw    <ESC>:simalt ~n<CR>
    "call system("wid=`xdotool getactivewindow` && wmctrl -ir $wid -b toggle,maximized_vert,maximized_horz")
    
    if g:osType == "windows"
        " 调用windows程序,斜杠需要转义
        call system("D:\\code\\ToggleFullScreen\\Debug\\ToggleFullScreen.exe")
    elseif g:osType == "wsl"
        call system("/mnt/d/code/ToggleFullScreen/Debug/ToggleFullScreen.exe")
    elseif g:osType == "cygwin"
        call system("/cygdrive/d/code/ToggleFullScreen/Debug/ToggleFullScreen.exe")
    elseif g:osType == "linux"
        call system("wmctrl -r \":ACTIVE:\" -b toggle,maximized_vert,maximized_horz")
    endif
endfunction
map <silent> <leader>mw :call ToggleMaxWindow()<cr>
" }}}

后续还会遇到一个问题,窗口模式启动nvim-qt以后,如果在最大化情况下退出,程序会保存窗口大小。
主要原因还是nvim-qt自动保存的窗口配置,而且在每次启动时会读取这些配置。
要解决这个问题,需要2步:

  1. 启动时设置窗口尺寸:
vim ~/bin/qvim
#!/bin/bash
/path/of/nvim-qt --no-ext-tabline --geometry 800x600

--no-ext-tabline忽略标签栏
geometry为qt程序的配置属性,可以指定窗口大小

  1. 清空旧配置并去掉配置文件的写入权限:
cat /dev/null > ~/.config/nvim-qt/window-geometry.conf
chmod -w ~/.config/nvim-qt/window-geometry.conf

完成!

从windows运行窗口打开nvim-qt

在windows下,只有在path环境变量下的程序才可以直接输入程序名称打开。所以只要把nvim-qt的路径添加到系统path环境变量中就可以了。我这里还多创建了一个快捷方式qvim(类似gvim的名字),在快捷方式的执行命令中增加上面的参数。

禁用nvim-qt GUI弹出菜单

neovim-qt的图形化弹出菜单其实效果还可以接受,但是与neovim 0.4的浮动窗口联动时就出现问题了,悬浮窗口会跟弹出菜单重叠,所以需要禁用掉。

Linux:

vim ~/.config/nvim/ginit.vim
# GuiPopupmenu 0
call rpcnotify(0, "Gui", "Option", "Popupmenu", 0)

Windows:

if has("win32")
    call rpcnotify(0, "Gui", "Option", "Popupmenu", 0)
endif

windows下不支持ginit.vim文件,所以直接在默认配置文件中配置就可以了。
网上找到的绝大多数解决办法都是使用注释掉的那一行,原因可能在于nvim-qt的windows版本集成了GUI选项,而在linux版本,我是独立编译的nvim-qt,只能通过未注释的部分禁用。

相关链接

neovim 0.5 特性预览

neovim 0.5 介绍

关于按键映射1

关于按键映射2

neovim 0.5配置样例1

neovim 0.5配置样例2

neovim lua 文档

neovim lua 使用手册 中文

neovim lua API

neovim 文档

关于packer.nvim懒加载

总结

整体来说,Neovim在界面响应上的异步渲染要比以前的gvim流畅一些,但是毕竟刚起步,现在已经有很多插件都开始兼容vim和neovim的配置,neovim自然会越来越好,未来可期。