I can do this for markdown's tab-based code blocks with mkdCode color group. So my question is if it's possible to do the same for fenced once?

I use plasticboy/vim-markdown plugin.

Here's a minimal vim config to reproduce the behaviour ~/.config/nvim/test-init.vim:

filetype plugin indent on
call plug#begin()
Plug 'plasticboy/vim-markdown', {'for': 'markdown'}
call plug#end()
highlight mkdCode ctermbg=yellow

Here's the result I get with it:

enter image description here

It seems that after applying mkdCode background it rewrites by code highlighting.

  • Looks like you're using the vim-markdown plug-in. Yes, it should highlighting fenced code blocks with mkdCode too, see this rule which matches <code>```</code> on its own line to match start and end of the block... Is that not working for you? Can you show an example of it not working?
    – filbranden
    Commented Jun 7, 2020 at 14:12
  • 1
    @filbranden right, sorry I forgot to mention about the plugin, I've updated the question
    – imbolc
    Commented Jun 7, 2020 at 14:58

2 Answers 2


I use a technique I picked up on reddit from /u/fob3sg:

function! ColorCodeBlocks() abort " {{{1
  setlocal signcolumn=no

  sign define codeblock linehl=codeBlockBackground

  augroup code_block_background
    autocmd! * <buffer>
    autocmd InsertLeave  <buffer> call s:place_signs()
    autocmd BufEnter     <buffer> call s:place_signs()
    autocmd BufWritePost <buffer> call s:place_signs()
  augroup END

function! s:place_signs()
  let l:continue = 0
  let l:file = expand('%')

  execute 'sign unplace * file=' . l:file

  for l:lnum in range(1, line('$'))
    let l:line = getline(l:lnum)
    if l:continue || l:line =~# '^\s*```'
      execute printf('sign place %d line=%d name=codeblock file=%s',
            \ l:lnum, l:lnum, l:file)

    let l:continue = l:continue
          \ ? l:line !~# '^\s*```$'
          \ : l:line =~# '^\s*```'

This creates a function that (mis)uses the signcolumn feature to change the background color of code blocks. To use it, add something like this e.g. in your after/ftplugin/markdown.vim:

highlight codeBlockBackground ctermbg=yellow
call ColorCodeBlocks()

I find it actually works very well. Obviously, you can change the color to something that fits your colorscheme.

  • 1
    In order for this to work, you'll need to copy the function MarkdownBlocks from the linked reddit post and rename it to s:place_signs. Thanks! Commented May 11, 2021 at 20:40
  • 1
    Thanks, you're right. I've added the s:place_signs function to the answer now. Commented May 12, 2021 at 9:11
  • Unfortunately, this seems to remove the gutter, e.g. when using ALE, errors / warnings are no longer indicated next to the line where they appear. Any idea how to fix this?
    – Stefan
    Commented Sep 9, 2021 at 7:00
  • The gutter (i.e. signcolumn!) is removed because of the set signcolumn=no statement. Just comment that out/remove that line if you want to keep the gutter visible. Commented Sep 10, 2021 at 7:21
  • (Although, perhaps this method will clear the gutter because of the sign unplace .... One possibility here would be to rely on the sign groups, see :help sign-place and :help sign-unplace for more info.) Commented Sep 10, 2021 at 7:23

What you're seeing here is vim-markdown's support for highlighting embedded languages in fenced code blocks.

In short, vim-markdown will recognize the python in ```python and it will use Python syntax highlighting for that code block.

You can find the code that implements that here.

It will create a new syntax highlighting group mkdSnippetPYTHON and have that block include Python syntax rules.

In theory, you could change the background of that specific group:

highlight mkdSnippetPYTHON ctermbg=yellow

But I found that doesn't really work great, since Python keywords (such as if, while, def, etc.) and other highlighted terms (such as function names in a function definition) will have been styled by Python and will override your background setting, showing a normal background.

Note that this doesn't happen if you don't have a language in your fenced block, if you start it with only ``` or if you have it for a language that's invalid or not recognized. (If you really wanted to keep the python language tag but not use syntax highlighting here, perhaps mapping 'python' to an invalid value in g:vim_markdown_fenced_languages would be a somewhat hacky way to disable this behavior.)

  • 1
    Yeah, I've just played a bit with it too and couldn't find a simple solution to make the background consistent. But now I understand you it works, thanks :)
    – imbolc
    Commented Jun 8, 2020 at 2:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.