最近更新 Windows 系统后,使用 ALT-Tab 快捷键切换窗口,每次切换回终端,输入法就会自动变成中文模式,非常影响 Neovim 的操作。
比如:每次切换到浏览器,复制下相关内容后,到 nvim 里面来想黏贴,通常使用 "+p
快捷键就可以了,但是由于当前输入法变成了中文模式,
就变成输入了 “+
, Normal 模式下 “
无用,+
直接给换到下一行。p
按键不会直接输入到终端,反而会弹出输入法候选框。
此外,由于自动切换到了中文输入,当想执行 Neovim 命令时,比如 :w<Cr>
的时候,同样的按键顺序,就会变成了:w
, 未保存,同时相当于 Normal 模式下执行了一次 w
光标向前移动一个词位置。
网上类似的讨论有很多:
https://www.v2ex.com/t/1120452
https://chunyujin.top/chunyujin/8728f196
但是并没有讲到真实的原因。在以前的系统里面(Win7),通常语言设置会有两个键盘,一个叫做美式键盘(一个灰色小的键盘图标), 另外一个键盘通常就是我们的输入法,比如搜狗的红色小图标,日常最常用的快捷键是 ctrl-space 来切换的是键盘,而不是某个输入法的中英文模式。 有时候,还不止两个键盘,比如同时安装了搜狗拼音、搜狗五笔,那么加上默认的美式键盘,就是三个键盘。通常使用 ctrl-space 来回切换,ctrl-shift 轮换。 虽然,以前搜狗输入也好,微软输入法也好,大多数提供了内置的中英文输入切换,通常快捷键是 shift 键。 而在最新版的 Windows 系统中,微软做了一件非常恶心的的事情,就是默认不给你安装美式键盘,只给你安装一个微软输入法, 并且把默认的键盘切换按键ctrl-space改为win-space,同时无法改回,只能在微软输入法里面设置ctrl-space切换自己的中英文模式。
设置 - 时间和语言 - 语言和区域 - 首选语言 - 添加语言 - 找到 English(United States)添加。
此时就有两个键盘,使用 win-space 可以切换键盘。
美式键盘只做英文输入,微软拼音只做中文输入,关闭管软拼音的英文模式。
完成以上操作后就可以使用命令行工具 im-select 进行键盘切换了。
打开命令行窗口:分别在两个键盘模式下执行一次下载的 im-select.exe 可以看到输出如下:
关于这个命令的说明:
im-select.exe 1033
切换至美式键盘,im-select.exe 2052
切换至微软拼音。local augroup = vim.api.nvim_create_augroup('wsdjeg', { clear = true })
local create_autocmd = vim.api.nvim_create_autocmd
-- 这里指定下载的 im-select.exe 的绝对路径,
-- 当然,你也可以将这个命令丢 PATH 里,个人不喜欢污染 PATH
local imselect = 'C:\\Users\\wsdjeg\\Downloads\\im-select.exe'
create_autocmd({ 'InsertLeave', 'FocusGained', 'CmdlineLeave', 'VimEnter' }, {
pattern = { '*' },
group = augroup,
callback = function(_)
-- 切换至美式键盘
vim.system({ imselect, '1033' })
end,
})
create_autocmd({ 'FocusLost' }, {
pattern = { '*' },
group = augroup,
callback = function(_)
-- 切换至微软拼音
vim.system({ imselect, '2052' })
end,
})
如果不想增加美式键盘,那么可以使用 im-select-mspy,对应的 Neovim 配置如下:
local augroup = vim.api.nvim_create_augroup('wsdjeg', { clear = true })
-- download im-select-mspy from https://github.com/daipeihust/im-select/raw/refs/heads/master/win-mspy/out/x64/im-select-mspy.exe
local imselect = 'C:\\Users\\wsdjeg\\Downloads\\im-select-mspy.exe'
local function imselect_cn()
vim.system({ imselect, '-k=ctrl+space', '中文模式' })
end
local function imselect_en()
vim.system({ imselect, '-k=ctrl+space', '英语模式' })
end
-- 使用 table 存储不同 buffer 的 Insert 模式下的输入法
local buffer_im = {}
create_autocmd({ 'InsertLeave' }, {
pattern = { '*' },
group = augroup,
callback = function(ev)
vim.system({ imselect }, { text = true }, function(o)
-- 这里说明下,再 Windows Terminal 内执行该命令输出的内容默认编码是 `cp936`,
-- 需要转码成 utf-8,同时,输出内容尾部有换行符,使用 trim 函数去除。
buffer_im[ev.buf] = vim.trim(vim.iconv(o.stdout, 'cp936', 'utf-8'))
end)
imselect_en()
end,
})
create_autocmd({ 'InsertEnter' }, {
pattern = { '*' },
group = augroup,
callback = function(ev)
local c = '英语模式'
if buffer_im[ev.buf] and buffer_im[ev.buf] ~= '英语模式' then
-- 此处设置快捷键,可以在输入法按键设置里面查看,我选择的是使用 ctrl-space 切换中英文
-- 默认我记得是 shift,同时这个命令默认也是 `-k=shift`
vim.system({ imselect, '-k=ctrl+space', buffer_im[ev.buf] })
end
end,
})
create_autocmd({ 'FocusGained', 'CmdlineLeave', 'VimEnter' }, {
pattern = { '*' },
group = augroup,
callback = function(_)
imselect_en()
end,
})
create_autocmd({ 'FocusLost' }, {
pattern = { '*' },
group = augroup,
callback = function(_)
imselect_cn()
end,
})
Neovim 和 Vim 一样,支持使用 v:oldfiles
获取最近浏览的文件名称列表。但是 Neovim 这一变量在 Windows 系统下面存在文件名称格式不一致的问题。
比如,一些使用 v:oldfiles
的插件,如 telescope.nvim、dashboard.nvim 等,其列表内会出现一些重复的文件。
D:/hello.txt
D:\hello.txt
d:/hello.txt
d:\hello.txt
为了避免上述原因,我做了一个插件 mru.nvim。
Windows 系统下统一的文件名格式,上述四种文件名称统一显示为 D:/hello.txt
。
可以预设置多个正则表达式,当文件名称匹配上时,阻止其被加入文件浏览历史记录。
require('mru').setup({
ignore_path_regexs = { '/.git/', '/nvim/runtime/doc/' },
})
比如,在使用一些启动屏插件(dashboard.nvim)时,会在启动时显示近期打开过的文件, 如果前面打开过一些非文本类文件,比如图片类的,这类文件可以从浏览历史中去除掉。
require('mru').setup({
ignore_path_regexs = { '/.git/', '.mp3$', '.png$' },
})
提供了 telescope.nvim 拓展,可以使用 :Telescope mru
打开。
使用 nvim-plug 插件管理器进行安装:
require('plug').add({
{
'wsdjeg/mru.nvim',
config = function()
require('mru').setup({
enable_cache = true,
mru_cache_file = vim.fn.stdpath('data') .. '/nvim-mru.json',
events = { 'BufEnter', 'BufWritePost' }, -- events to update mru file list
ignore_path_regexs = { '/.git/' },
enable_logger = true, -- require wsdjeg/logger.nvim
})
end,
},
})
当然,如果并未使用 telescope,也可以自行拓展,使用 require('mru').get()
获取历史记录文件名称列表。以 leaderf 为例:
function! s:nmru(...) abort
return v:lua.require('mru').get()
endfunction
function! s:nmru_acp(line, args) abort
exe 'e' a:line
endfunction
" function() wrapper
if v:version > 703 || v:version == 703 && has('patch1170')
function! s:_SID() abort
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
endfunction
let s:_s = '<SNR>' . s:_SID() . '_'
function! s:_function(fstr, ...) abort
if a:0 > 1
return function(substitute(a:fstr, 's:', s:_s, 'g'))
else
return function(a:fstr)
endif
endfunction
else
function! s:_SID() abort
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
endfunction
let s:_s = '<SNR>' . s:_SID() . '_'
function! s:_function(fstr) abort
return function(substitute(a:fstr, 's:', s:_s, 'g'))
endfunction
endif
let g:Lf_Extensions = {
\ 'nmru': {
\ 'source': string(s:_function('s:nmru', 1))[10:-3],
\ 'accept': string(s:_function('s:nmru_acp', 1))[10:-3],
\ 'supports_name_only': 1,
\ 'supports_multi': 0,
\ },
\}
以上为 VimL 写的 LeaderF 拓展,尝试了使用 Lua 来写,可读性更简单,但是似乎不起作用:
local function mru()
return require('mru').get()
end
local function mru_acp(line, args)
vim.cmd('e ' .. line)
end
vim.g.Lf_Extensions = {
nvimmru = {
source = mru,
accept = mru_acp,
supports_name_only = true,
supports_multi = false,
},
}
以前偶尔也会录制一些动图,使用的是 LICEcap,这也是一个开源项目,但是不能录制成视频。 在网上搜到不少的录视频的软件,比较火热的是班迪录屏,但是我还是倾向于免费开源方案。
Neovim 增加了一个 vim.on_key
,这个函数在按键按下后会触发。借助这个函数及 Neovim 的悬浮窗口,
实现了一个按键弹窗提示的效果插件 record-key.nvim。
默认的着色是 Normal
高亮组,如果需要突出显示,可以设置为:
require('record-key').setup({
timeout = 3000,
max_count = 7,
winhighlight = 'NormalFloat:Todo,FloatBorder:WinSeparator',
})
record-screen.nvim 是一个 Neovim 屏幕录制的插件, 借助 ffmpeg 这个命令和 Neovim 的异步机制。
前面的设置是只录制桌面图像,但是在日常视频录制的过程中,还是会涉及到其他的一些设备,比如麦克风、摄像头、音响等等。
首先使用 ffmpeg -list_devices true -f dshow -i dummy
命令获取设备列表:
ffmpeg version 7.1.1-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers
built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-lcms2 --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-libdvdnav --enable-libdvdread --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.101 / 61. 19.101
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
[dshow @ 000001f024fc6d40] "Integrated Camera" (video)
[dshow @ 000001f024fc6d40] Alternative name "@device_pnp_\\?\usb#vid_13d3&pid_5419&mi_00#7&17d116b8&1&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 000001f024fc6d40] "麦克风阵列 (Realtek(R) Audio)" (audio)
[dshow @ 000001f024fc6d40] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{253B9838-6E9C-47DB-A420-848E63B3931C}"
[in#0 @ 000001f024fad380] Error opening input: Immediate exit requested
Error opening input file dummy.
从上述的输出内容,不难看出,目前支持的设备仅仅有摄像头Integrated Camera
和麦克风麦克风阵列 (Realtek(R) Audio)
,并没有扬声器,解决方法如下:
一、鼠标右键点击桌面右下角音量图标
二、打开更多音量设置
三、点击录制、右击立体声混声启用
这时候再执行 ffmpeg -list_devices true -f dshow -i dummy
输出为:
ffmpeg version 7.1.1-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers
built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-lcms2 --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-libdvdnav --enable-libdvdread --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.101 / 61. 19.101
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
[dshow @ 0000020942ff6cc0] "Integrated Camera" (video)
[dshow @ 0000020942ff6cc0] Alternative name "@device_pnp_\\?\usb#vid_13d3&pid_5419&mi_00#7&17d116b8&1&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 0000020942ff6cc0] "麦克风阵列 (Realtek(R) Audio)" (audio)
[dshow @ 0000020942ff6cc0] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{253B9838-6E9C-47DB-A420-848E63B3931C}"
[dshow @ 0000020942ff6cc0] "立体声混音 (Realtek(R) Audio)" (audio)
[dshow @ 0000020942ff6cc0] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{A04F0465-843E-4E64-891D-31A28192D215}"
[in#0 @ 0000020942fdd340] Error opening input: Immediate exit requested
Error opening input file dummy.
可以看到有三个设备:
Integrated Camera
麦克风阵列 (Realtek(R) Audio)
立体声混音 (Realtek(R) Audio)
当然,也可以安装开源项目 rdp/screen-capture-recorder-to-video-windows-free, 安装完成后,`` 命令输出如下:
ffmpeg version 7.1.1-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers
built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-lcms2 --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-libdvdnav --enable-libdvdread --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.101 / 61. 19.101
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
[dshow @ 0000020d0d8f6d40] "Integrated Camera" (video)
[dshow @ 0000020d0d8f6d40] Alternative name "@device_pnp_\\?\usb#vid_13d3&pid_5419&mi_00#7&17d116b8&1&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 0000020d0d8f6d40] "screen-capture-recorder" (video)
[dshow @ 0000020d0d8f6d40] Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\{4EA69364-2C8A-4AE6-A561-56E4B5044439}"
[dshow @ 0000020d0d8f6d40] "立体声混音 (Realtek(R) Audio)" (audio)
[dshow @ 0000020d0d8f6d40] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{A04F0465-843E-4E64-891D-31A28192D215}"
[dshow @ 0000020d0d8f6d40] "virtual-audio-capturer" (audio)
[dshow @ 0000020d0d8f6d40] Alternative name "@device_sw_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\{8E146464-DB61-4309-AFA1-3578E927E935}"
[dshow @ 0000020d0d8f6d40] "麦克风阵列 (Realtek(R) Audio)" (audio)
[dshow @ 0000020d0d8f6d40] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{253B9838-6E9C-47DB-A420-848E63B3931C}"
[in#0 @ 0000020d0d8dd380] Error opening input: Immediate exit requested
Error opening input file dummy.
此时多出了两个设备:
screen-capture-recorder
virtual-audio-capturer
如果仅仅需要录制桌面,而不需要录制摄像头和声音,可以使用如下配置:
require('record-screen').setup({
command = 'ffmpeg',
argvs = {
'-f',
'gdigrab',
'-i',
'desktop',
'-pix_fmt',
'yuv420p',
'-f',
'mp4',
},
})
require('record-screen').setup({
cmd = 'ffmpeg',
argvs = {
'-f',
'dshow',
'-i',
'audio=麦克风阵列 (Realtek(R) Audio)',
'-f',
'dshow',
'-i',
'audio=立体声混音 (Realtek(R) Audio)',
'-filter_complex',
'amix=inputs=2:duration=first:dropout_transition=2',
'-f',
'gdigrab',
'-r',
'60',
'-draw_mouse',
'1',
'-i',
'desktop',
'-pix_fmt',
'yuv420p',
'-f',
'mp4',
},
})
录制视频时,偶尔会遇到类似于 real-time buffer frame dropped
这样的错误提示,
参考issue 136
提到的解决方案,增加参数 -rtbufsize 1500M
使用 nvim-plug 插件管理器:
require('plug').add({
{
'wsdjeg/record-key.nvim',
cmds = { 'RecordKeyToggle' },
config_before = function()
vim.keymap.set(
'n',
'<leader>rk',
'<cmd>RecordKeyToggle<cr>',
{ silent = true }
)
end,
},
{
'wsdjeg/record-screen.nvim',
depends = {
{ 'wsdjeg/job.nvim' },
{ 'wsdjeg/notify.nvim' },
},
config = function()
require('plugins.record-screen')
end,
},
})
插件详细配置参考文件 nvim-config/lua/plugins/record-screen.lua
通过这个配置文件,我新建了一个用户自定义命令 :RecordScreen
,支持如下参数:
-camera
: 录制摄像头-speaker
: 录制扬声器--microphone
: 录制麦克风使用 :RecordScreen stop
停止录屏。
在使用 Neovim 打开某个文件时,我希望 Neovim 自动把当前目录切换到该文件所在的项目根目录。 其实,能实现这一功能的有不少的插件,我最早使用的是 vim-rooter,但是后来因为切换到了 Neovim, 因此使用 Lua 重写了该功能,这个功能早期是 SpaceVim 的内置的, 在 SpaceVim 项目停止维护后独立成单独的插件:rooter.nvim。
可以使用任意插件管理器进行安装,比如 nvim-plug
require('plug').add({
{
'wsdjeg/rooter.nvim',
config = function()
require('rooter').setup({})
end,
},
})
以下是默认的配置:
require('rooter').setup({
root_patterns = { '.git/' },
outermost = true,
enable_cache = true,
project_non_root = '', -- this can be '', 'home' or 'current'
enable_logger = true, -- enable runtime log via logger.nvim
})
project_non_root
: 配置打开非项目文件时的行为outermost
: 若设为 true
,那么通过 root_patterns
检索到的多个目录时,取最外层目录。rooter.nvim 自带 telescope.nvim 拓展,可以使用 :Telescope project
列出过往打开过的项目。
在插件运行过程中产生的日志信息,可以使用 logger.nvim 进行查看。 如果有这一需求,那么在安装 rooter.nvim 时,需要添加相应的依赖插件。
require('plug').add({
{
'wsdjeg/rooter.nvim',
config = function()
require('rooter').setup({})
end,
depends = {
{
'wsdjeg/logger.nvim',
},
},
},
})
通过 reg_callback
可以设置 callback 函数,该函数会在项目切换时被调用。
local function update_ctags_option()
local project_root = vim.fn.getcwd()
local dir = require('util').unify_path(require('tags').cache_dir)
.. require('util').path_to_fname(project_root)
table.insert(tags, dir .. '/tags')
vim.o.tags = table.concat(tags, ',')
end
require('rooter').reg_callback(update_gtags_option)
logger.nvim
提供了一个基础的日志框架,不同的插件可以共用一个日志系统。
和安装其他插件一样,可以使用nvim-plug安装:
require('plug').add({
'wsdjeg/logger.nvim',
config = function()
require('logger').setup({
-- the level only can be:
-- 0 : log debug, info, warn, error messages
-- 1 : log info, warn, error messages
-- 2 : log warn, error messages
-- 3 : log error messages
level = 0,
})
end,
})
比如新建了一个插件 fyz.nvim
,此时可以添加一个文件 lua/fyz/log.lua
:
local M = {}
local logger
function M.info(msg)
if not logger then
pcall(function()
logger = require('logger').derive('fyz')
logger.info('hello world')
end)
else
logger.info('hello world')
end
end
return M
在自己的插件中就可以使用:
local log = require('fyz.log')
log.info('this is log from fyz.nvim')
可以使用 logger.viewRuntimeLog()
查看所有的日志输出,其中就会有如下一行:
[ fyz ] [23:22:50:576] [ Info ] this is log from fyz.nvim
关于任务(Tasks)管理,实际上早在 2020 年的时候就已经给 SpaceVim 增加了 Tasks 支持,参考的是 Vscode Tasks Manager 的实现。 最早的版本使用 Vim Script 实现的,大约在 2023 年的时候增加了 Lua 实现版本, 不过这些都是在 SpaceVim 内置的插件。
现在,SpaceVim 已经不再维护,而这些常用的功能,我也会陆续剥离出来单独形成插件,这篇文章主要介绍 tasks.nvim
可以使用任意插件管理器进行安装,这里以 nvim-plug 为例:
require('plug').add({
{
'wsdjeg/tasks.nvim',
depends = {
{
'wsdjeg/code-runner.nvim',
},
},
config = function()
require('tasks').setup({
global_tasks = '~/.tasks.toml',
local_tasks = '.tasks.toml',
provider = { 'npm' },
})
end,
},
})
tasks.nvim
提供了三个常用命令:
:TasksEdit
:用于打开 tasks 配置文件,默认打开的是项目配置文件,加上感叹号(:TasksEdit!
)则打开全局配置文件。:TasksList
:使用分屏列出所有 tasks:TasksSelect
:选择某个 task 并执行当然,如果你也安装了 telescope.nvim
那么,可以使用 :Telescope tasks
模糊搜索可用的 tasks.