jbwqfy.com
Open in
urlscan Pro
172.67.220.97
Public Scan
URL:
https://jbwqfy.com/
Submission: On July 29 via api from US — Scanned from US
Submission: On July 29 via api from US — Scanned from US
Form analysis
0 forms found in the DOMText Content
Eric's Blog 時光荏苒,歲月如梭 * 首頁 * 歸檔 * 分類 * 標簽 * 開源 * 想法 * 維基 * 相冊 * 友鏈 * 關于 * 關于 NEOVIM 插件开辟的指南 2024-07-29 Eric Wong 生活隨筆 neovim 今天,在 Neovim 中文电报群有人分享了一个仓库 nvim-best-practices@24e835c, 是關于 Neovim 插件开辟的一些“指南”,或可以说是“建议”,当然我也答复了我的想法,抱愧,说话有些过激。 花花里胡巧的限制,我只看了开首就看不下去了,举例,号令要分成子号令, 这个除华侈一层判定,没啥用。本来只定义一个FooInstall号令, 实际上在底层c就已判定出来对应的函数。成果遵循他如许, 需要在viml或lua这边判定下到底这个号令是做甚么的 跟谷歌的viml style guide相比差远了。别的手机上打开毫无浏览体验可谈。 里胡巧的限制,我只看了开首就看不下去了,举例,号令要分成子号令, 这个除华侈一层判定,没啥用。本来只定义一个FooInstall号令, 实际上在底层c就已判定出来对应的函数。成果遵循他如许, 需要在viml或lua这边判定下到底这个号令是做甚么的 跟谷歌的viml style guide相比差远了。别的手机上打开毫无浏览体验可谈。 开初本来不是出格在乎,只在群里答复一下就算了,由于习惯每小我都有,只要 “can work” 就没需要纠结对与错了,由于事实�成果也不会影响到本身的习惯。 可是随着浏览发现,竟然要把这一内容归并到 Neovim 主仓库。 那我感觉就对我本身包含后来的 Neovim 用户城市有很大年夜的影响。 是以我感觉有需要针对这个指南,写一些器材了。 逐行看一下,由于 Pull Request 的分支的一向在变动,并且是 force push,:(,是以原文在文┞仿中有直接文字體現。 *lua-plugin.txt* Nvim :h lua-plugin 很轻易让人误解,也很难将内容与这个关头词联想在一路。 若是是针对号令定义、按鍵映照定义的建议,那么就不局限于 Lua 了。 并且,这个不是某个 plugin 的文档,而是插件开辟的建议,:h plugin-dev 或 :h plugin-dev-guide 感覺加倍合適一些。 NVIM REFERENCE MANUAL Guide to developing Lua plugins for Nvim Type |gO| to see the table of contents. ============================================================================== Introduction *lua-plugin* This is a guide for getting started with Nvim plugin development. It is not intended as a set of rules, but as a collection of recommendations for good practices. For a guide to using Lua in Nvim, please refer to |lua-guide|. ============================================================================== Type safety *lua-plugin-type-safety* Lua, as a dynamically typed language, is great for configuration. It provides virtually immediate feedback. But for larger projects, this can be a double-edged sword, leaving your plugin susceptible to unexpected bugs at the wrong time. You can leverage LuaCATS https://luals.github.io/wiki/annotations/ annotations, along with lua-language-server https://luals.github.io/ to catch potential bugs in your CI before your plugin's users do. ------------------------------------------------------------------------------ Tools *lua-plugin-type-safety-tools* - lua-typecheck-action https://github.com/marketplace/actions/lua-typecheck-action - luacheck https://github.com/lunarmodules/luacheck for additional linting ============================================================================== User commands *lua-plugin-user-commands* Many users rely on command completion to discover available user commands. If a plugin pollutes the command namespace with lots of commands, this can quickly become overwhelming. Example: - `FooAction1 {arg}` - `FooAction2 {arg}` - `FooAction3` - `BarAction1` - `BarAction2` Instead of doing this, consider gathering subcommands under scoped commands and implementing completions for each subcommand. Example: - `Foo action1 {arg}` - `Foo action2 {arg}` - `Foo action3` - `Bar action1` - `Bar action2` 对这点,我实际上是持否定态度的。号令在定义时,其履行内容与字符串名字已进行了绑定。 在调用号令时,底层 c 逻辑就已判定出要去履行哪个函数。 若是利用子号令,无疑要增加一个号令功能的阐发,显得有些华侈。 若是一个插件只提拱了有限的几个号令, 比如:FooInstall、FooUninstall,很明顯便可以看出這兩個号令的功能,底子沒需要利用子号令。 當然,什麽樣情況下建議利用子号令呢?當多個号令的字面內容很是接近且難以區分時時,比如: * FooInstall1 * FooInstall2 這種情況下,建議用子号令,比如 FooInstall 1,FooInstall 2 或,Foo install 1, Foo install 2 ------------------------------------------------------------------------------ Subcommand completions example *lua-plugin-user-commands-completions-example* In this example, we want to provide: - Subcommand completions if the user has typed `:Foo ...` - Argument completions if they have typed `:Foo {subcommand}` First, define a type for each subcommand, which has: - An implementation: A function which is called when executing the subcommand. - An optional command completion callback, which takes the lead of the subcommand's arguments. >lua ---@class FooSubcommand ---@field impl fun(args:string[], opts: table) ---@field complete? fun(subcmd_arg_lead: string): string[] < Next, we define a table mapping subcommands to their implementations and completions: >lua ---@type table<string, FooSubcommand> local subcommand_tbl = { action1 = { impl = function(args, opts) -- Implementation (args is a list of strings) end, -- This subcommand has no completions }, action2 = { impl = function(args, opts) -- Implementation end, complete = function(subcmd_arg_lead) -- Simplified example local install_args = { "first", "second", "third", } return vim.iter(install_args) :filter(function(install_arg) -- If the user has typed `:Foo action2 fi`, -- this will match 'first' return install_arg:find(subcmd_arg_lead) ~= nil end) :totable() end, -- ... }, } < Then, create a Lua function to implement the main command: >lua ---@param opts table :h lua-guide-commands-create local function foo_cmd(opts) local fargs = opts.fargs local subcommand_key = fargs[1] -- Get the subcommand's arguments, if any local args = #fargs > 1 and vim.list_slice(fargs, 2, #fargs) or {} local subcommand = subcommand_tbl[subcommand_key] if not subcommand then vim.notify("Foo: Unknown command: " .. subcommand_key, vim.log.levels.ERROR) return end -- Invoke the subcommand subcommand.impl(args, opts) end < See also |lua-guide-commands-create|. Finally, we register our command, along with the completions: >lua -- NOTE: the options will vary, based on your use case. vim.api.nvim_create_user_command("Foo", foo_cmd, { nargs = "+", desc = "My awesome command with subcommand completions", complete = function(arg_lead, cmdline, _) -- Get the subcommand. local subcmd_key, subcmd_arg_lead = cmdline:match("^Foo[!]*%s(%S+)%s(.*)$") if subcmd_key and subcmd_arg_lead and subcommand_tbl[subcmd_key] and subcommand_tbl[subcmd_key].complete then -- The subcommand has completions. Return them. return subcommand_tbl[subcmd_key].complete(subcmd_arg_lead) end -- Check if cmdline is a subcommand if cmdline:match("^Foo[!]*%s+%w*$") then -- Filter subcommands that match local subcommand_keys = vim.tbl_keys(subcommand_tbl) return vim.iter(subcommand_keys) :filter(function(key) return key:find(arg_lead) ~= nil end) :totable() end end, bang = true, -- If you want to support ! modifiers }) < ============================================================================== Keymaps *lua-plugin-keymaps* Avoid creating keymaps automatically, unless they are not controversial. Doing so can easily lead to conflicts with user |mapping|s. NOTE: An example for uncontroversial keymaps are buffer-local |mapping|s for specific file types or floating windows. A common approach to allow keymap configuration is to define a declarative DSL https://en.wikipedia.org/wiki/Domain-specific_language via a `setup` function. However, doing so means that - You will have to implement and document it yourself. - Users will likely face inconsistencies if another plugin has a slightly different DSL. - |init.lua| scripts that call such a `setup` function may throw an error if the plugin is not installed or disabled. As an alternative, you can provide |<Plug>| mappings to allow users to define their own keymaps with |vim.keymap.set()|. - This requires one line of code in user configs. - Even if your plugin is not installed or disabled, creating the keymap won't throw an error. Another option is to simply expose a Lua function or |user-commands|. However, some benefits of |<Plug>| mappings over this are that you can - Enforce options like `expr = true`. - Expose functionality only for specific |map-modes|. - Expose different behavior for different |map-modes| with a single |<Plug>| mapping, without adding impurity or complexity to the underlying Lua implementation. NOTE: If you have a function that takes a large options table, creating lots of |<Plug>| mappings to expose all of its uses could become overwhelming. It may still be beneficial to create some for the most common ones. ------------------------------------------------------------------------------ Example *lua-plugin-plug-mapping-example* In your plugin: >lua vim.keymap.set("n", "<Plug>(SayHello)", function() print("Hello from normal mode") end, { noremap = true }) vim.keymap.set("v", "<Plug>(SayHello)", function() print("Hello from visual mode") end, { noremap = true }) < In the user's config: >lua vim.keymap.set({"n", "v"}, "<leader>h", "<Plug>(SayHello)") < ============================================================================== Initialization *lua-plugin-initialization* Newcomers to Lua plugin development will often put all initialization logic in a single `setup` function, which takes a table of options. If you do this, users will be forced to call this function in order to use your plugin, even if they are happy with the default configuration. Strictly separated configuration and smart initialization allow your plugin to work out of the box. NOTE: A well designed plugin has minimal impact on startup time. See also |lua-plugin-lazy-loading|. Common approaches to a strictly separated configuration are: - A Lua function, e.g. `setup(opts)` or `configure(opts)`, which only overrides the default configuration and does not contain any initialization logic. - A Vimscript compatible table (e.g. in the |vim.g| or |vim.b| namespace) that your plugin reads from and validates at initialization time. See also |lua-vim-variables|. Typically, automatic initialization logic is done in a |plugin| or |ftplugin| script. See also |'runtimepath'|. ============================================================================== Lazy loading *lua-plugin-lazy-loading* When it comes to initializing your plugin, assume your users may not be using a plugin manager that takes care of lazy loading for you. Making sure your plugin does not unnecessarily impact startup time is your responsibility. A plugin's functionality may evolve over time, potentially leading to breakage if users have to hack into the loading mechanisms. Furthermore, a plugin that implements its own lazy initialization properly will likely have less overhead than the mechanisms used by a plugin manager or user to load that plugin lazily. ------------------------------------------------------------------------------ Defer `require` calls *lua-plugin-lazy-loading-defer-require* |plugin| scripts should not eagerly `require` Lua modules. For example, instead of: >lua local foo = require("foo") vim.api.nvim_create_user_command("MyCommand", function() foo.do_something() end, { -- ... }) < which will eagerly load the `foo` module and any other modules it imports eagerly, you can lazy load it by moving the `require` into the command's implementation. >lua vim.api.nvim_create_user_command("MyCommand", function() local foo = require("foo") foo.do_something() end, { -- ... }) < NOTE: For a Vimscript alternative to `require`, see |autoload|. NOTE: In case you are worried about eagerly creating user commands, autocommands or keymaps at startup: Plugin managers that provide abstractions for lazy-loading plugins on such events will need to create these themselves. ------------------------------------------------------------------------------ Filetype-specific functionality *lua-plugin-lazy-loading-filetype* Consider making use of |filetype| for any functionality that is specific to a filetype, by putting the initialization logic in a `ftplugin/{filetype}.lua` script. ------------------------------------------------------------------------------ Example *lua-plugin-lazy-loading-filetype-example* A plugin tailored to Rust development might have initialization in `ftplugin/rust.lua`: >lua if not vim.g.loaded_my_rust_plugin then -- Initialize end -- NOTE: Using `vim.g.loaded_` prevents the plugin from initializing twice -- and allows users to prevent plugins from loading -- (in both Lua and Vimscript). vim.g.loaded_my_rust_plugin = true local bufnr = vim.api.nvim_get_current_buf() -- do something specific to this buffer, -- e.g. add a |<Plug>| mapping or create a command vim.keymap.set("n", "<Plug>(MyPluginBufferAction)", function() print("Hello") end, { noremap = true, buffer = bufnr, }) < ============================================================================== Configuration *lua-plugin-configuration* Once you have merged the default configuration with the user's config, you should validate configs. Validations could include: - Correct types, see |vim.validate()| - Unknown fields in the user config (e.g. due to typos). This can be tricky to implement, and may be better suited for a |health| check, to reduce overhead. ============================================================================== Troubleshooting *lua-plugin-troubleshooting* ------------------------------------------------------------------------------ Health checks *lua-plugin-troubleshooting-health* Provide health checks in `lua/{plugin}/health.lua`. Some things to validate: - User configuration - Proper initialization - Presence of Lua dependencies (e.g. other plugins) - Presence of external dependencies See also |vim.health| and |health-dev|. ------------------------------------------------------------------------------ Minimal config template *lua-plugin-troubleshooting-minimal-config* It can be useful to provide a template for a minimal configuration, along with a guide on how to use it to reproduce issues. ============================================================================== Versioning and releases *lua-plugin-versioning-releases* Consider - Using SemVer https://semver.org/ tags and releases to properly communicate bug fixes, new features, and breaking changes. - Automating versioning and releases in CI. - Publishing to luarocks https://luarocks.org, especially if your plugin has dependencies or components that need to be built; or if it could be a dependency for another plugin. ------------------------------------------------------------------------------ Further reading *lua-plugin-versioning-releases-further-reading* - Luarocks <3 Nvim https://github.com/nvim-neorocks/sample-luarocks-plugin 有点强推 Luarocks。 ------------------------------------------------------------------------------ Tools *lua-plugin-versioning-releases-tools* - luarocks-tag-release https://github.com/marketplace/actions/luarocks-tag-release - release-please-action https://github.com/marketplace/actions/release-please-action - semantic-release https://github.com/semantic-release/semantic-release 这些内容写在 wiki 或一些伶仃的文┞仿里足够了,归并到 Neovim 文档里面显得有些过了。实在不是每小我都用 git 或 github。 ============================================================================== Documentation *lua-plugin-documentation* Provide vimdoc (see |help-writing|), so that users can read your plugin's documentation in Nvim, by entering `:h {plugin}` in |command-mode|. ------------------------------------------------------------------------------ Tools *lua-plugin-documentation-tools* 以上两个 tag 完全可以归并,每个内容太少了点,最后这一大年夜段,看了满屏 tag。 - panvimdoc https://github.com/kdheepak/panvimdoc 閱讀全文 -------------------------------------------------------------------------------- * 新的知乎賬號 2024-07-27 Eric Wong 生活隨筆 zhihu * 關注的話題及問題 * 關于開源 * 關于评论与私信 2022 年 5 月,由于小我启事刊出了知乎账号。可是此刻看来,平常沟通交换免不了要打开知乎,寻觅一些讯息,是以从头弄了一个知乎账号(@Eric Wong)。 關于知乎的利用,实在我也纠结了很长一段时候。实在,里面我用得着的功能更多的是问答模块。關于文┞仿、想法、视频。感受跟博客功能堆叠了。一篇文┞仿总不克不及博客里面写一遍,再去知乎从头发一遍, 反复的工作太多。 關注的話題及問題 首要存眷的包含:開源软件、Vim、Neovim 等 關于開源 還是在利用老帳號的時候,我曾經答复過一個問題,为甚么要開源? 保护一个大年夜型開源项目是如何的体验? 關于评论与私信 很是抱愧,知乎网站打开的频率还是很是低的,而知乎也不像 Github 那样撑持邮件答复,是以几近是没法做到及时答复。 所以若是迟迟没有覆信的话,建议可以经过过程其他的编制联系我,比如邮件。 閱讀全文 -------------------------------------------------------------------------------- * NEOVIM 调色板插件 CPICKER.NVIM 2024-07-14 Eric Wong 辅助分享 neovim * 啓用插件 * 操纵界面 * 後續計劃 由于偶然需要点窜 Neovim 的高亮,触及到色彩调剂,以往利用的是外部辅助,往返切换很是麻烦。也找了一些 Neovim/Vim 的插件,可是利用的感受确切不尽如人意。 是以,本身实现了一个精练版本的调色板插件 cpicker.nvim,該插件存儲于 SpaceVim 的 bundle/cpicker.nvim 文件夹内。 为了便利伶仃利用,手动同步更新到 wsdjeg/cpicker.nvim。 啓用插件 若是是 SpaceVim 用户,只需要启用 tools#cpicker 模块便可: [[layers]] name = 'tools#cpicker' 对非 SpaceVim 用户,可以用插件办理器安装: Plug 'https://spacevim.org/git/repos/SpaceVim/' Plug 'wsdjeg/cpicker.nvim' 操纵界面 操纵快捷鍵: 按鍵 功能描述 h / <Left> 減小光標下的值 l / <Right> 增加光標下的值 <Enter> 複制光標下的顔色值 後續計劃 * 今朝撑持的格式包含:RGB、HSL、HSV、CMYK,計劃再增加一些经常利用的格式。 * 增加顔色同化調整面板 閱讀全文 -------------------------------------------------------------------------------- * NEOVIM 缓冲区(BUFFER)相干事务 2024-07-07 Eric Wong 學習筆記 neovim * 启事 * 獲取可用事务列表 * 事务的觸發時機 * BufAdd * BufNew * BufNewFile * 測試示例 启事 比来在利用 SpaceVim 的標簽栏(tabline)时发现,对新增的空内容的缓冲区(buffer),標簽栏上方实在不会列出。 查抄源码发现標簽栏跟踪缓冲区新增的代码只监听了:BufNewFile 跟 BufReadPost 事务。 vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufReadPost' }, { callback = vim.schedule_wrap(function(event) if vim.api.nvim_buf_is_valid(event.buf) and index(right_hide_bufs, event.buf) == -1 and index(visiable_bufs, event.buf) == -1 and index(left_hide_bufs, event.buf) == -1 then table.insert(right_hide_bufs, event.buf) end end), group = tabline_augroup, }) 測試發現 :enew 号令及 :new 号令並不會觸發這兩個事务。点窜源碼增加監聽 BufNew 事务。 固然题目是修复了,可是我感觉有需要清算下缓冲区相干事务的觸發時機。 獲取可用事务列表 可利用号令 :echo getcompletion('Buf', 'event') 快速查看当前 Neovim 版本撑持的缓冲区事务列表。 事务的觸發時機 BUFADD 1. 新增一個緩沖區至緩沖區列表 2. 将一个 unlisted 缓冲区添加进 listed 缓冲区列表 3. 点窜 listed 缓冲区列表中某个缓冲区的名称 BUFNEW 1. 新增一個緩沖區 2. 点窜緩沖區的名稱 BUFNEWFILE 1. 當開始編輯一個不存在的文件時 測試示例 通過一些實例來測試事务觸發的時機,測試代碼以下: 需要忽视掉落 *Cmd 事务,避免文件讀寫掉敗。 local log = require("spacevim.logger").derive("logevent") local group = vim.api.nvim_create_augroup("logevent", { clear = true }) vim.api.nvim_create_autocmd( vim.tbl_filter(function(e) return not vim.endswith(e, "Cmd") end, vim.fn.getcompletion("Buf", "event")), { callback = vim.schedule_wrap(function(event) log.debug(event.event .. event.buf) end), group = group, } ) 1. 執行号令::new [ logevent ] [13:20:39:562] [ Debug ] BufNew5 [ logevent ] [13:20:39:562] [ Debug ] BufAdd5 [ logevent ] [13:20:39:562] [ Debug ] BufAdd5 [ logevent ] [13:20:39:562] [ Debug ] BufLeave4 [ logevent ] [13:20:39:562] [ Debug ] BufEnter5 [ logevent ] [13:20:39:562] [ Debug ] BufWinEnter5 1. 執行号令::enew [ logevent ] [13:22:42:452] [ Debug ] BufNew6 [ logevent ] [13:22:42:452] [ Debug ] BufAdd6 [ logevent ] [13:22:42:452] [ Debug ] BufAdd6 [ logevent ] [13:22:42:452] [ Debug ] BufLeave4 [ logevent ] [13:22:42:452] [ Debug ] BufWinLeave4 [ logevent ] [13:22:42:452] [ Debug ] BufHidden4 [ logevent ] [13:22:42:452] [ Debug ] BufEnter6 [ logevent ] [13:22:42:452] [ Debug ] BufWinEnter6 1. 執行号令: :echo bufadd('') [ logevent ] [13:47:57:482] [ Debug ] BufNew6 1. echo nvim_create_buf(v:false, v:true) [ logevent ] [14:25:06:555] [ Debug ] BufNew5 1. echo nvim_create_buf(v:true, v:true) [ logevent ] [14:26:32:389] [ Debug ] BufNew11 [ logevent ] [14:26:32:389] [ Debug ] BufAdd11 [ logevent ] [14:26:32:389] [ Debug ] BufAdd11 當打開一個文件後,執行 :set nobuflisted, 在履行 :set buflisted [ logevent ] [14:38:15:888] [ Debug ] BufDelete4 [ logevent ] [14:38:19:857] [ Debug ] BufAdd4 [ logevent ] [14:38:19:857] [ Debug ] BufAdd4 打開一個存在的文件::e README.md [ logevent ] [14:44:15:717] [ Debug ] BufNew8 [ logevent ] [14:44:15:717] [ Debug ] BufAdd8 [ logevent ] [14:44:15:717] [ Debug ] BufAdd8 [ logevent ] [14:44:15:717] [ Debug ] BufLeave4 [ logevent ] [14:44:15:717] [ Debug ] BufWinLeave4 [ logevent ] [14:44:15:717] [ Debug ] BufHidden4 [ logevent ] [14:44:15:717] [ Debug ] BufReadPre8 [ logevent ] [14:44:15:717] [ Debug ] BufReadPost8 [ logevent ] [14:44:15:717] [ Debug ] BufReadPost8 [ logevent ] [14:44:15:717] [ Debug ] BufEnter8 [ logevent ] [14:44:15:717] [ Debug ] BufWinEnter8 打開一個不存在的新文件: :e newfile.txt [ logevent ] [14:45:56:519] [ Debug ] BufNew10 [ logevent ] [14:45:56:519] [ Debug ] BufAdd10 [ logevent ] [14:45:56:519] [ Debug ] BufAdd10 [ logevent ] [14:45:56:519] [ Debug ] BufLeave4 [ logevent ] [14:45:56:519] [ Debug ] BufWinLeave4 [ logevent ] [14:45:56:519] [ Debug ] BufHidden4 [ logevent ] [14:45:56:519] [ Debug ] BufNewFile10 [ logevent ] [14:45:56:519] [ Debug ] BufEnter10 [ logevent ] [14:45:56:519] [ Debug ] BufWinEnter10 閱讀全文 -------------------------------------------------------------------------------- * (NEO)VIM 括号补全插件比较 2024-06-27 Eric Wong 辅助分享 vim neovim * 启事 * 實現邏輯及功能比較 * auto-pairs * neopairs.vim * nvim-autopairs * 維護狀態 启事 輸入模式下,成對符號的自動補全一向是比較经常利用的功能。利用了很多年 delimitMate , 根基功能正常,可是偶然会呈现卡屏现象,等一段时候或按下 ctrl-c 可以結束卡屏,可是會輸入很多個 <Plug>delimitMate( 。 可是这一现象并没有法百分百重现。 想著這麽多年過去了,會不會有新的更好用的插件,因而搜了下,今朝已知的括號補全插件有: * delimitMate * neopairs.vim:需要 exists('#CompleteDone') == 1 * nvim-autopairs:需要 Neovim 0.7.0+ * mini.pairs * auto-pairs * autoclose.nvim * ultimate-autopair.nvim 實現邏輯及功能比較 AUTO-PAIRS 仓库中 Vim 脚本只有 plugin/auto-pairs.vim (673 行)。 监听 BufEnter 事务,映照 g:AutoPairs 所設定的成對符號。 NEOPAIRS.VIM 通過監聽 CompleteDone 事务,判定补全 item 的结尾是不是匹配设定的成对符号。 NVIM-AUTOPAIRS 是利用 Lua 实现的 Neovim 插件。在 nvim-autopairs.setup 函數裏利用以下三組事务監聽來實現補全。 local group = api.nvim_create_augroup('autopairs_buf', { clear = true }) api.nvim_create_autocmd({ 'BufEnter', 'BufWinEnter' }, { --- M.on_attach }) api.nvim_create_autocmd('BufDelete', { --- }) api.nvim_create_autocmd('FileType', { --- }) 在 M.on_attach 函數裏,首要有一個 expr 映照及一個 InsertCharPre 事务監聽: local enable_insert_auto = false -- 初始化是不是插入的 flag local expr_map = function(key) api.nvim_buf_set_keymap(bufnr, 'i', key, '', { expr = true --- 设定 expr 映照 }) end for _, rule in pairs(rules) do -- 按照每个法则映照快捷键,并计较是 enable_insert_auto 值 end if enable_insert_auto then api.nvim_create_autocmd('InsertCharPre', { --- 若是 enable_insert_auto 为 true, 则监听 InsertCharPre 事务 }) end 維護狀態 repo Github stars Issues pull requests last commit auto-pairs 4.1k 138 Open / 155 Closed 27 Open / 53 Closed Feb 27, 2019 delimitMate 2k 47 Open / 219 Closed 5 Open / 36 Closed Dec 14, 2020 nvim-autopairs 3k 12 Open / 287 Closed 1 Open / 157 Closed May 20 2024 neopairs.vim 31 0 Open / 4 Closed 0 Open / 0 Closed Mar 16, 2016 mini.pairs 仓库有2个:mini.nvim、mini.pairs。 由于 mini.nvim 仓库实际上是由几十个自力插件组合而成,其 Issues 跟 pull requests 列表应对到 mini.pairs 上到底有多少,没法评估。 auto-pairs 有一个较活跃的 fork 版本LunarWatcher/auto-pairs,今朝維護狀態正常: 閱讀全文 -------------------------------------------------------------------------------- * LUA 与 VIM SCRIPT 之间函数彼此调用 2024-06-11 Eric Wong 學習筆記 neovim * 启事 * 根基兼容邏輯 * Vim Script 中调用 Lua * Lua 中调用 Vim Script 函数 启事 在利用 Neovim 之前,一向利用的是 Vim Script 写 Vim 脚本。随着 Neovim 的呈现,和 Lua 的速度上风,因而将之前写的插件利用 Lua 进行重写了。 在这里记录一些从 Vim Script 切换到 Lua 碰到的一些题目,和前后兼容的写法。 根基兼容邏輯 個人比較垂青腳本的向後兼容,在非需要的情況下,對外的接口函數不會改變,通過以下一個示例大年夜致揭示了若何做到前後版本的腳本兼容。 比如,初期的 Vim Script 脚本实现的脚本以下: autoload/test.vim function! test#test(name) echo "hello " . name endfunction 那么,对 Neovim 新版本的撑持,可利用 Lua 实现近似的功能: lua/test.lua local M = {} function M.test(name) print('hello ' .. name) end return M 为了让前面的 test.vim 利用 Lua 函数,可以做以下点窜: function! test#test(name) if has('nvim') lua require('test').test(vim.api.nvim_eval('name')) else echo "hello " . name endif endfunction 以上函數存在一個問題,就是每次調用時,都會去檢測一次版本,可以將腳本点窜爲: if has('nvim') function! test#test(name) lua require('test').test(vim.api.nvim_eval('name')) endfunction else function! test#test(name) echo "hello " . name endfunction endif 這樣一來,版本檢測僅僅在這個腳本文件被讀取載入時才執行一次,在這之後 test#test(name) 這個函數的本體僅限于一行代碼。 lua require('test').test(vim.api.nvim_eval('name')) VIM SCRIPT 中调用 LUA 上述的示例中只有一種調用编制,即便用 :lua 号令,該号令利用有兩種编制。 lua print('hello') lua << EOF print('hello') EOF 别的,利用 :lua 号令,若是碰到 Vim Script 函数本来需要有返回值的话,比较麻烦,可利用 luaeval() 函數,比如: function! test#test(name) call luaeval("require('test').test(vim.api.nvim_eval('name'))") " 也可利用 return 返回值 return luaeval("require('test').test(vim.api.nvim_eval('name'))") endfunction Neovim 0.5.0 增加了 v:lua,可以加倍便利地在 Vim Script 中调用 Lua, 示例以下: function! test#test(name) " 这里可以直接利用参数,而不需要利用 nvim_eval return v:lua.require('test').test(a:name) endfunction LUA 中调用 VIM SCRIPT 函数 Neovim 供给了 vim.fn 和 nvim_call_function(fn, argv)。 -- built-in functions vim.fn.executable(var) -- User autoload function vim.fn['test#test'](name) 对 Vim 的 funcref 变量,可利用以下编制调用: function! s:test_hello(name) endfunction let s:fn = function('s:test_hello') function! test#run(fn) if type(a:fn) == 2 let fn = string(a:fn)[10:-3] elseif type(a:fn) == type('') let fn = a:fn endif call v:lua.require('test').run(fn) endf 閱讀全文 -------------------------------------------------------------------------------- 1/17 最新發布 * 關于 Neovim 插件开辟的指南 * 新的知乎賬號 * Neovim 调色板插件 cpicker.nvim * Neovim 缓冲区(buffer)相干事务 * (Neo)Vim 括号补全插件比较 * Lua 与 Vim Script 之间函数彼此调用 * 更新 Neovim 碰到的题目 * 修复 git clone 题目: gnutls_handshake() failed * 《熱辣滾燙》觀後感 * 从 Github 迁徙到 Gitlab 分類 * 生活隨筆 26 * 學習筆記 63 * 辅助分享 10 * 工作資料 2 標簽云 回憶 lisp 高中 vim 蘇大年夜 java lua love ruby spacevim blog ecl movie rust zig nodejs winrar zhihu neovim gallery life lifestyle fcitx gitlab git xxfseo.com