我正在寻找一种可能的解决方案,具体取决于上下文,例如在此高级文本示例中,在单个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,如前所述。