我正在寻找一种可能的解决方案,具体取决于上下文,例如在此高级文本示例中,在单个vim缓冲区中应用两种不同的背景颜色。
一种用例是对标记文件中的代码片段进行不同的颜色编码,使它们更加突出。
但是,我从未见过这样的设置示例。
vim完全有可能吗?
我正在寻找一种可能的解决方案,具体取决于上下文,例如在此高级文本示例中,在单个vim缓冲区中应用两种不同的背景颜色。
一种用例是对标记文件中的代码片段进行不同的颜色编码,使它们更加突出。
但是,我从未见过这样的设置示例。
vim完全有可能吗?
Answers:
因为我很好奇它的工作原理,所以我一起研究了一些东西。
如对先前答案的评论中所述,唯一的方法是用空格填充区域。这正是我们所做的;在写之前,我们会删除这些空格,因此您不应该为此而烦扰其他人。
请注意,此示例是针对markdown文件类型的!
副作用:
'list'
启用后不显示背景首先,您需要将此添加到您的~/.vim/after/syntax/markdown.vim
:
syn clear markdownCodeBlock
syn region markdownCodeBlock start=" \|\t" end="$"
hi def markdownCodeBlock ctermbg=230 guibg=lightyellow
当然,您可以根据自己的喜好调整颜色;-)
然后,将其添加到您的vimrc中:
fun! MarkdownBlocks()
fun! s:fill(line)
" Remove all trailing whitespace
let l:line = substitute(a:line, " *$", "", "")
" Add trailing whitespace up to 'textwidth' length
return l:line . repeat(' ', (&tw > 0 ? &tw : 80) - strdisplaywidth(l:line))
endfun
" Get all lines in a list
let l:lines = getline(1, line('$'))
" Map s:fill() to the lines that are a code block
call map(l:lines, 'v:val[0] == "\t" || v:val[:3] == " " ? s:fill(v:val) : v:val')
" Reset the buffer to the lines
call setline(1, l:lines)
endfun
" Remove all the trailing spaces
fun! MarkdownBlocksClean()
let l:save_cursor = getpos(".")
silent %s/^\( \|\t\)\(.\{-}\)\( *\)$/\1\2/e
call setpos('.', l:save_cursor)
endfun
au BufWritePre *.markdown call MarkdownBlocksClean()
" Set spaces on loading the file, leaving insert mode, and after writing it
au FileType markdown call MarkdownBlocks()
au InsertLeave *.markdown call MarkdownBlocks()
au BufWritePost *.markdown call MarkdownBlocks()
我不会逐行解释代码,这些注释应该使代码的基本要义清楚;-)
对于语法突出显示的元素,当然可以使用其他背景色。只需在命令中定义guibg
和ctermbg
颜色即可hilight
。前者为GUI Vim设置背景颜色,后者为终端Vim设置背景颜色。
但是,这有一个重要的限制,即它只能为文件中实际存在的字符设置背景色。
这样做的结果是,背景色不能延伸超过一行文本的末端到窗口的边缘,因此示例中显示的代码块无法着色:
您还可以使用“签名”功能更改整个行的背景颜色。(参见linehl
中:help sign.txt
)
但是,请注意:
为此,需要编写代码在需要涂色的每一行上放置标志,并随着文件内容的更改而使这些标志保持更新,
默认情况下,放置标志时,标志列将显示在窗口的左侧。可以使用SignColumn
高亮组更改符号列的颜色,在Vim的最新版本中,可以将其完全删除。(请参阅:help 'signcolumn'
。)
例如,要使Carpetsmoker的解决方案使用(更健壮的)标志机制,您可以执行以下操作:
" Define a highlight group and a sign that uses it
highlight default markdownCodeBlock ctermbg=230 guibg=lightyellow
sign define codeblock linehl=markdownCodeBlock
" Use signs to highlight code blocks
function! MarkdownBlocks()
function! s:applySign(idx, val)
if a:val[0] == "\t" || a:val[:3] == " "
let l = a:idx + 1
execute "sign place " . l . " line=" . l . " name=codeblock file=" . expand("%:p")
endif
endfunction
" Remove old signs
execute "sign unplace * file=" . expand("%:p")
" Get all lines in a list
let l:lines = getline(1, line('$'))
" Add new signs
call map(l:lines, function('s:applySign'))
endfunction
" Set signs on loading the file, leaving insert mode, and after writing it
au FileType markdown call MarkdownBlocks()
au InsertLeave *.markdown call MarkdownBlocks()
au BufWritePost *.markdown call MarkdownBlocks()
与Carpetsmoker的版本相比,这在某种程度上简化了代码,并减少了警告。
@ChristianBrabandt的DynamicSigns插件使为此目的使用Sign功能更加容易:他在此答案中描述了如何使用Sign功能。
guibg
仅适用于gvim,对吗?
ctermbg
,如前所述。