在Vim的状态行中显示模式
我在Vim中开发了一个很好的可定制状态行,但是我在显示当前模式时遇到了实际问题 我使用字典指示通过状态行的左侧和右侧显示哪些选项:在Vim的状态行中显示模式,vim,Vim,我在Vim中开发了一个很好的可定制状态行,但是我在显示当前模式时遇到了实际问题 我使用字典指示通过状态行的左侧和右侧显示哪些选项: " Display Options {{{ let s:statusline_options = { \ 'active': { \ 'left': [ 'readonly', 'mode' , 'git' ], \ 'right': [ 'time', 'project'
" Display Options {{{
let s:statusline_options = {
\ 'active': {
\ 'left': [ 'readonly', 'mode' , 'git' ],
\ 'right': [ 'time', 'project' ],
\ },
\ 'components': {
\ 'readonly': 'Statusline_readonly()',
\ 'mode': 'Statusline_mode()',
\ 'git': 'Statusline_git()',
\ 'time': "strftime(%a\ %d\ %b\ %H:%M)",
\ 'project': 'Statusline_project()'
\ },
\ 'seperators': {
\ 'readonly': ' %s',
\ 'mode': '%s >',
\ 'git': ' %s',
\ 'time': ' < ',
\ 'project': '[%s] '
\ },
\ 'components_to_color': {
\ 'mode': 1,
\ 'project': 1
\ },
\ 'theme_colors': {
\ 'default': [ '#abb2bf', '#61afef', '#98c379' ],
\ 'onedark': [ '#abb2bf', '#61afef', '#98c379' ],
\ 'materialbox': [ '#1d272b', '#fb8c00', '#43a047']
\ },
\ 'mode_map': {
\ 'n': 'NORMAL', 'i': 'INSERT', 'R': 'REPLACE', 'v': 'VISUAL', 'V': 'VISUAL', "\<C-v>": 'V-BLOCK',
\ 'c': 'COMMAND', 's': 'SELECT', 'S': 'S-LINE', "\<C-s>": 'S-BLOCK', 't': 'TERMINAL'
\ },
\ }
" }}}
要包含在Statusline中的自定义函数以及键Statusline_mode()函数如下所示:
" Component Functions {{{
" Show the mode in the statuslin
function! Statusline_mode() abort
return get(s:statusline_options.mode_map, mode(), '')
endfunction
function! Statusline_project() abort
return GetCurrentSite(g:code_dir)
endfunction
function! Statusline_git() abort
let git = fugitive#head()
if git != ''
return ' '.fugitive#head()
else
return ''
endif
endfunction
function! Statusline_readonly() abort
if &readonly || !&modifiable
return ' '
else
return ''
endif
endfunction
" }}}
然后通过下面的命令组设置状态行:
" Set The Statusline {{{
augroup statusline
hi StatusLine guibg=NONE gui=NONE
autocmd!
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost
\ * let &l:statusline = StatuslineComponents('left') . '%=' . StatuslineComponents('right') |
\ call ChangeStatuslineColor()
augroup end
" }}}
我尝试过使用
InsertEnter
命令组,但这似乎不起作用。让我们从更简单的案例开始:
let &l:statusline = mode() . ' ' . StatuslineComponents('left') . '%=' . StatuslineComponents('right')
当定义'statusline'
时,会调用模式()
一次它从不更新,并且该值固定在n
要解决此问题,您需要在状态行更新时使用%{…}
项来计算表达式:
let &l:statusline = '%{mode()} ' . StatuslineComponents('left') . '%=' . StatuslineComponents('right')
现在回到你的完整案例。这是同样的问题:
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost
\ * let &l:statusline = StatuslineComponents('left') . '%=' . StatuslineComponents('right') |
\ call ChangeStatuslineColor()
虽然您会更新某些:autocmd
事件,但模式更改时不会触发任何事件,因此您始终会看到相同的模式。在任何情况下,正如:help mode()
告诉您的,正确的值只能从提到的statusline表达式中获得
作为解决此问题的第一步,我将完全删除:autocmd
,并将所有内容放入状态行表达式中:
let &statusline = "%{StatuslineComponents('left')}%=%{StatuslineComponents('right')}"
如果遇到性能问题,我会将慢速元素(但不是模式()
调用!)提取到窗口局部变量中,从状态行表达式中引用它们,并使用:autocmd
更新它们
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost * let w:left = StatuslineComponents('left')
let &statusline = "%{w:left}%=%{StatuslineComponents('right')}"
让我们从您更简约的案例开始:
let &l:statusline = mode() . ' ' . StatuslineComponents('left') . '%=' . StatuslineComponents('right')
当定义'statusline'
时,会调用模式()
一次它从不更新,并且该值固定在n
要解决此问题,您需要在状态行更新时使用%{…}
项来计算表达式:
let &l:statusline = '%{mode()} ' . StatuslineComponents('left') . '%=' . StatuslineComponents('right')
现在回到你的完整案例。这是同样的问题:
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost
\ * let &l:statusline = StatuslineComponents('left') . '%=' . StatuslineComponents('right') |
\ call ChangeStatuslineColor()
虽然您会更新某些:autocmd
事件,但模式更改时不会触发任何事件,因此您始终会看到相同的模式。在任何情况下,正如:help mode()
告诉您的,正确的值只能从提到的statusline表达式中获得
作为解决此问题的第一步,我将完全删除:autocmd
,并将所有内容放入状态行表达式中:
let &statusline = "%{StatuslineComponents('left')}%=%{StatuslineComponents('right')}"
如果遇到性能问题,我会将慢速元素(但不是模式()
调用!)提取到窗口局部变量中,从状态行表达式中引用它们,并使用:autocmd
更新它们
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost * let w:left = StatuslineComponents('left')
let &statusline = "%{w:left}%=%{StatuslineComponents('right')}"
真是一堵文字墙!如果我尝试这个
let&l:statusline=mode()。StatuslineComponents('left')。%='。StatuslineComponents(“右”)
没有区别。它似乎没有接收到模式转换,真是一堵文字墙!如果我尝试这个let&l:statusline=mode()。StatuslineComponents('left')。%='。StatuslineComponents(“右”)
没有区别。它似乎没有接受模式转换,这是一个真正全面的答案!了解更新状态行和不更新状态行之间的区别。在您的答案提出的最后一种形式中,情况会很好地更新,但是由StatuslineColor()
定义的突出显示组显示为字符串,例如\%Component\u Default
,而不是被解析。这可以通过欺骗来解决吗?%{…}
表达式本身不会进一步解析其他符号(即,它是非递归的);您不能通过其中的%#…#
添加突出显示。如果无法将突出显示内容移到%{…}
之外(例如,当您想根据某些条件更改突出显示时),则必须使用:set statusline=%!MyStatusLine
;该表达式可以返回其他符号/是递归的。Cp.:帮助“stl”
:当选项以“%!”开头时,它将被用作一个表达式—一个真正全面的答案!了解更新状态行和不更新状态行之间的区别。在您的答案提出的最后一种形式中,情况会很好地更新,但是由StatuslineColor()
定义的突出显示组显示为字符串,例如\%Component\u Default
,而不是被解析。这可以通过欺骗来解决吗?%{…}
表达式本身不会进一步解析其他符号(即,它是非递归的);您不能通过其中的%#…#
添加突出显示。如果无法将突出显示内容移到%{…}
之外(例如,当您想根据某些条件更改突出显示时),则必须使用:set statusline=%!MyStatusLine
;该表达式可以返回其他符号/是递归的。Cp.:帮助“stl”
:当选项以“%!”开头时,它将用作表达式