Skip to main content

4 posts tagged with "vim"

View All Tags

· 3 min read

熟悉vim的童鞋可能用过很多vim的插件,但是如何实现的呢?

今天以lua的视角来体验一下lua插件的开发过程:

file structure

1.首先,任意位置创建如下目录

.
└── lua
└── luaPlugin
└── init.lua

init.lua中我们随便写点什么:

2.如何使这个插件生效呢?

我们需要把插件添加到lua的runtime path中:

# 插件根目录中运行
vim --cmd "set rtp+=./"

接着我们就可以打开vim运行这个插件了

可以看到"hello world"已正常输出

需要注意的是无论你require多少次"hello world"只会输出一次

export function

我们可能会经常看到如下类似的配置:引入一个模块,调用一个function,然后配置leader key

这里暂不讨论lua是如何配置的

init.lua中我们先来定义一个lua function然后导出:

print("hello world")

local function some_function( ... )
-- body
print("hello from function")
end

--important
return {
some_function = some_function
}

接着熟悉的配方,熟悉的套路,先set path下:

# 插件根目录中运行 
vim --cmd "set rtp+=./"

接着调用function:

可以看到"hello world""hello from function"都输出了:前者是首次加载时才会输出,可以用于初始化;后者是function的调用,每次调用都会执行

interact with vim

更新lua code如下:

local function run_jest( ... )
-- body
local file = vim.fn.expand("%:p")
print("my file is " .. file)
end

--important
return {
run_jest = run_jest
}

然后调用function

可以看到路径可以正常输出:

新增一句,打开一个新的terminal

vim运行:

可以看到没有任何问题

在此基础上, 我们进行深层次的操作,在打开的terminal中输出hello world

local function run_jest( ... )
-- body
local file = vim.fn.expand("%:p")
print("my file is " .. file)
vim.cmd("vsplit | terminal")
local command = ':call jobsend(b:terminal_job_id, "echo hello world\\n")'
vim.cmd(command)
end

--important
return {
run_jest = run_jest
}

运行

新开的terminal正常输出"hello world"(这里有很大的发挥空间,输出测试结果,打印日志信息等)

· 2 min read

Neovim uses interprocess communications for stuff like that. You have to implement the neovim remote plugin protocol in go (or use a library, if that exists) and then write a server program that does what you want by communicating with nvim.

Neovim 使用进程间通信来处理类似的事情。 你必须在 go 中实现 neovim 远程插件协议(或使用相关库),然后编写一个服务器程序,通过与 nvim 通信来执行你想要的操作。

目前支持的库有:

下面来看看如何去实现?

package main

import (
"strings"
"github.com/neovim/go-client/nvim/plugin"
)

func hello(args []string) (string, error) {
return "Hello " + strings.Join(args, " "), nil
}

func main() {
plugin.Main(func(p *plugin.Plugin) error {
p.HandleFunction(&plugin.FunctionOptions{Name: "Hello"}, hello)
return nil
})
}
  1. 首先将以上代码进行编译go build -o hello,然后将二进制文件放入$GOPATH/bin目录中
  2. 任意位置编写个vim文件,以test.vim为例:
if exists('g:loaded_hello')
finish
endif
let g:loaded_hello = 1

function! s:Requirehello(host) abort
" 'hello' is the binary created by compiling the program above.
return jobstart(['hello'], {'rpc': v:true})
endfunction

call remote#host#Register('hello', 'x', function('s:Requirehello'))
" The following lines are generated by running the program
" command line flag --manifest hello
call remote#host#RegisterPlugin('hello', '0', [
\ {'type': 'function', 'name': 'Hello', 'sync': 1, 'opts': {}},
\ ])

" vim:ts=4:sw=4:et
  1. init.lua加入这句即可vim.cmd('source ~/some/path/test.vim')
  2. 打开vim使用 :echo Hello('world')

来看看效果:

· One min read
  • gf:文件跳转 go to file, 选中代码中的路径,gf就可以实现文件跳转
  • gd:代码跳转
  • bf: 回退至原文件 back to file
  • ctrl+o: 回退至原文件
  • ctrl+i :再次打开之前跳转的文件
  • :sp ./{filename} 分屏打开当前目录下的filename
  • ctrl+w+k:光标移动至分屏上方窗口
  • ctrl+w+j:光标移动至分屏下方窗口
  • v模式下移动光标,按y进行复制,按p进行粘贴。
  • :e file: 写文件, 如果你记得文件名也可以实现跳转
  • :w : save

· One min read
  • :w: 格式化代码
  • normal状态下ciw:改一个单词
  • normal状态下ci":修改当前或下1个""里的内容
  • normal状态下ci(:修改()里的内容, 注意光标必须移到()中方可生效
  • normal状态下ci):修改()里的内容,注意光标必须移到()中方可生效
  • normal状态下gd: 且换到方法的定义处
  • buff切换: ctrl+p(:bf)切换下一个buff、ctrl+n (:bn) 切换上一个buff
  • ,e: 查看配置文件
  • 关闭当前buff: :bw
  • b w:当前单词间的切换
  • gd:跳转到方法的定义处(:GoDoc
  • :ReplaceTo: 快速替换 ,r
  • `:GoRename": 全局替换