首页 > 解决方案 > init.lua 中的 Autocmd InsertEnter 到高亮光标不起作用

问题描述

我正在从一个经过良好测试和使用多年的迁移init.vim到一个新的init.lua. 最后两行没有显示错误,但它们不起作用。这个想法是在我输入时显示下划线insert mode并在normal mode.

init.lua

vim.cmd('highlight Cursorline cterm=NONE gui=NONE guibg=NONE')
vim.cmd('autocmd InsertEnter * highlight Cursorline cterm=underline gui=underline') -- Does not work
vim.cmd('autocmd InsertLeave * highlight Cursorline cterm=NONE gui=NONE')           -- Does not work

满的init.lua

-- General setting
vim.api.nvim_set_option('mouse', 'a')
vim.api.nvim_set_option('laststatus', 2)
vim.api.nvim_set_option('title', true)
vim.api.nvim_set_option('cursorline', true)
vim.api.nvim_set_option('clipboard', 'unnamedplus') -- Register * as clipboard
vim.api.nvim_set_option('ignorecase', true)         -- Search ignore case
vim.api.nvim_set_option('splitright', true)
vim.api.nvim_set_option('splitbelow', true)

-- Search
vim.api.nvim_set_option('hlsearch', true)           -- Highlight search
vim.api.nvim_set_option('incsearch', true)          -- set incremental search

-- UTF-8
vim.api.nvim_set_option('encoding', 'utf-8')
vim.api.nvim_set_option('fileencoding', 'utf-8')
--vim.api.nvim_set_option('termencoding', 'utf-8')

-- Tabs
vim.api.nvim_set_option('expandtab', false)
vim.api.nvim_set_option('tabstop', 4)
vim.api.nvim_set_option('shiftwidth', 4)
vim.api.nvim_set_option('textwidth', 100)
--vim.api.nvim_set_option('', )

-- Colors
vim.api.nvim_set_option('termguicolors', true)
vim.api.nvim_set_option('syntax', 'on')
vim.api.nvim_command('colorscheme oceanicnext')

-- SHORTCUTS --------------------------------------------------
-- General shortcuts
vim.api.nvim_set_keymap('n', 'cc', ':!make', {})
vim.api.nvim_set_keymap('n', '<S-s><S-s>', ':w<cr>', {})
vim.api.nvim_set_keymap('n', 'ls', ':buffers<cr>', {})
vim.api.nvim_set_keymap('n', 'gb', ':w<cr>:buffers<cr>:b<space>', {})
vim.api.nvim_set_keymap('n', '<space>', '/', {})

-- LaTeX shortcuts
vim.api.nvim_command('augroup filetype_tex')
    -- Begin End block
    vim.api.nvim_command('autocmd filetype tex inoremap <C-B> <ESC>YpkI\\begin{<ESC>A}<ESC>jI\\end{<ESC>A}<esc>kA')

    -- Greek letters
    vim.api.nvim_set_keymap('i','<C-g>a','\\alpha',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-g>b','\\beta',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-g>e','\\epsilon',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-g>g','\\gamma',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-g>l','\\lambda',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-g>m','\\mu',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-g>o','\\omega',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-g>s','\\sigma',{noremap=true})

    -- Pretty letter for sets
    vim.api.nvim_set_keymap('i','<C-b>c','\\mathbb{C}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-b>k','\\mathbb{K}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-b>n','\\mathbb{N}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-b>r','\\mathbb{R}',{noremap=true})

    -- Vectors
    vim.api.nvim_set_keymap('i','<C-e>0','\\vec{0}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-e>e','\\vec{e}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-e>u','\\vec{u}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-e>v','\\vec{v}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-e>w','\\vec{w}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-e>x','\\vec{x}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-e>y','\\vec{y}',{noremap=true})
    vim.api.nvim_set_keymap('i','<C-e>z','\\vec{z}',{noremap=true})
vim.api.nvim_command('augroup end')


-- Relative line numbers
vim.api.nvim_set_option('number', true)
vim.api.nvim_set_option('relativenumber', true)
vim.cmd('augroup numbertoggle')
vim.cmd('autocmd!')
vim.cmd('autocmd BufEnter,FocusGained,InsertLeave * :set relativenumber')
vim.cmd('autocmd BufLeave,FocusLost,InsertEnter   * :set norelativenumber')
vim.cmd('autocmd BufLeave,FocusLost,InsertEnter   * :set number')
vim.cmd('augroup end')

-- Change aspect if in insert mode or not
vim.cmd('highlight Cursorline cterm=NONE gui=NONE guibg=NONE')
vim.cmd('autocmd InsertEnter * highlight Cursorline cterm=underline gui=underline')
vim.cmd('autocmd InsertLeave * highlight Cursorline cterm=NONE gui=NONE')

标签: vimluaneovimautocmd

解决方案


有一个错误,但它不是自动命令。你可以告诉你:set cursorline在 Vim 中你的高亮是否有效。

此时您可能会感到困惑,因为您已经拥有:

vim.api.nvim_set_option('cursorline', true)

在你的 init.nvim 中。应该工作吧?

好吧,事实证明不是。看看这个:

:echo &cursorline
:lua vim.api.nvim_set_option('cursorline', true)
:echo &cursorline

在 nvim 0.5.0-beta (几周前构建,nvim 没有明确说明确切时间)中,它的输出是两个零 - 不是 0 和 1。如中所示,nvim_set_option('cursorline', true)没有效果。真正的苏。

让我们看一下:h 'cursorline'

                        'cursorline' 'cul' 'nocursorline' 'nocul'
'cursorline' 'cul'      boolean (default off)
                        local to window
                        {not available when compiled without the +syntax
                        feature}
        Highlight the text line of the cursor with CursorLine hl-CursorLine.
        Useful to easily spot the cursor.  Will make screen redrawing slower.
        When Visual mode is active the highlighting isn't used to make it
        easier to see the selected text.

仔细看看local to window- 这就是你的代码不起作用的原因。我不会假装理解为什么(因为我不经常使用 nvim,而且我个人觉得 lua api 一团糟),但nvim_set_options不适用于窗口变量。有趣的是,如果您尝试将 int 而不是 bool 传递给cursorline,该方法将抛出错误,但仍然无法像您期望的那样设置它。我会在文章的最后回到这一点。

让我们看另一个带有任意变量的例子;'foldmarker'

:echo &foldmarker
> {{{,}}}
:lua vim.api.nvim_set_option('foldmarker', 'literally,anythingelse')
> (completes, no error)
:echo &foldmarker
> {{{,}}}
:lua vim.api.nvim_win_set_option(0, 'foldmarker', 'literally,anythingelse')
> (completes, no error)
:echo &foldmarker
> literally,anythingelse

作为对读者的练习,第一步也可以完成'paste''paste'是一个全局变量,因此可能nvim_win_set_option(0, 'paste', true)会抛出

有趣的是,这适用于正常的:set

:set foldmarker&
:echo &foldmarker
> {{{,}}}
:set foldmarker=literally,anythingelse
:echo &foldmarker
> literally,anythingelse

这意味着,修复代码所需要做的就是:

vim.api.nvim_win_set_option(0, 'cursorline', true)

或者:

vim.api.nvim_command('set cursorline')

TL;DR:之所以有效,是因为您现在实际上是在设置cursorline. 无法设置窗口选项vim.api.nvim_set_option(name, value)(我不知道为什么)。您的自动命令很好,但它们不起作用,因为cursorline已关闭。这也与亮点本身无关;清除高亮只会隐藏光标线,不会禁用光标线选项。这也意味着您的 autocmds 和 highlight 在这种情况下很好,但是您对窗口变量使用了错误的 API 函数导致了这个问题。

最后一点建议:检查您正在设置的变量的文档。如果它显示窗口,则必须使用nvim_win_set_option,如果它是缓冲区,则需要nvim_buf_set_option. 这些也包含在 nanotee 的nvim lua 指南中 - 它还涵盖了额外变量的含义。


我不完全确定这种行为是否构成错误,或者它只是不直观的 API 设计,但我发现了一个与'number'在完成其余答案后研究错误报告时相关的错误,这可能表明这是预期的行为。不过,我不会将它作为一个错误报告,或者打开一个问题来询问这是否是有意的,所以这是我这边的温和猜测。然而,手头的证据仍然使它看起来像它的意图。

这也意味着如果您使用API ,您必须确保知道要设置的变量类型。*_set_option()如果它真的是为了让nvim_set_option()窗口选项静默失败,你必须手动检查以确保你在正确的变量上使用了正确的函数,因为 API 函数不会告诉你什么时候这样做错误的。或者只是使用vim.api.nvim_command()- Vim:set确实正确设置了窗口变量。


推荐阅读