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

Form analysis 0 forms found in the DOM

Text 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