Add the following line to your `.vimrc` to disable the folding configuration:
```vim
-let g:vim_markdown_folding_disabled=1
+let g:vim_markdown_folding_disabled = 1
```
This option only controls Vim Markdown specific folding configuration.
the following to your `.vimrc`:
```vim
-let g:vim_markdown_folding_style_pythonic=1
+let g:vim_markdown_folding_style_pythonic = 1
```
### Set header folding level
Add the following line to your `.vimrc` to disable default key mappings:
```vim
-let g:vim_markdown_no_default_key_mappings=1
+let g:vim_markdown_no_default_key_mappings = 1
```
You can also map them by yourself with `<Plug>` mappings.
Used as `$x^2$`, `$$x^2$$`, escapable as `\$x\$` and `\$\$x\$\$`.
```vim
-let g:vim_markdown_math=1
+let g:vim_markdown_math = 1
```
#### YAML frontmatter
Highlight YAML frontmatter as used by Jekyll:
```vim
-let g:vim_markdown_frontmatter=1
+let g:vim_markdown_frontmatter = 1
```
" original version from Steve Losh's gist: https://gist.github.com/1038710
function! s:is_mkdCode(lnum)
- return synIDattr(synID(a:lnum, 1, 0), 'name') == 'mkdCode'
+ let name = synIDattr(synID(a:lnum, 1, 0), 'name')
+ return (name =~ '^mkd\%(Code$\|Snippet\)' || name != '' && name !~ '^\%(mkd\|html\)')
endfunction
if get(g:, "vim_markdown_folding_style_pythonic", 0)
Add the following line to your '.vimrc' to disable the folding configuration:
>
- let g:vim_markdown_folding_disabled=1
+ let g:vim_markdown_folding_disabled = 1
<
This option only controls Vim Markdown specific folding configuration.
To fold in a style like python-mode [6], add the following to your '.vimrc':
>
- let g:vim_markdown_folding_style_pythonic=1
+ let g:vim_markdown_folding_style_pythonic = 1
<
-------------------------------------------------------------------------------
*vim-markdown-disable-default-key-mappings*
Add the following line to your '.vimrc' to disable default key mappings:
>
- let g:vim_markdown_no_default_key_mappings=1
+ let g:vim_markdown_no_default_key_mappings = 1
<
You can also map them by yourself with '<Plug>' mappings.
Used as '$x^2$', '$$x^2$$', escapable as '\$x\$' and '\$\$x\$\$'.
>
- let g:vim_markdown_math=1
+ let g:vim_markdown_math = 1
<
-------------------------------------------------------------------------------
*vim-markdown-yaml-frontmatter*
Highlight YAML frontmatter as used by Jekyll:
>
- let g:vim_markdown_frontmatter=1
+ let g:vim_markdown_frontmatter = 1
<
===============================================================================
*vim-markdown-mappings*
let d.text = substitute(d.text, '\v[ ]*#*$', '', '')
" setex headers
else
- let l:next_line = getbufline(bufname(d.bufnr), d.lnum+1)
+ let l:next_line = getbufline(d.bufnr, d.lnum+1)
if match(l:next_line, "=") > -1
let l:level = 0
elseif match(l:next_line, "-") > -1
command! -buffer Toch call s:Toc('horizontal')
command! -buffer Tocv call s:Toc('vertical')
command! -buffer Toct call s:Toc('tab')
+
+" Heavily based on vim-notes - http://peterodding.com/code/vim/notes/
+let s:filetype_dict = {
+ \ 'c++': 'cpp',
+ \ 'viml': 'vim'
+\ }
+
+function! s:Markdown_highlight_sources(force)
+ " Syntax highlight source code embedded in notes.
+ " Look for code blocks in the current file
+ let filetypes = {}
+ for line in getline(1, '$')
+ let ft = matchstr(line, '```\zs[0-9A-Za-z_+-]*')
+ if !empty(ft) && ft !~ '^\d*$' | let filetypes[ft] = 1 | endif
+ endfor
+ if !exists('b:mkd_known_filetypes')
+ let b:mkd_known_filetypes = {}
+ endif
+ if !a:force && (b:mkd_known_filetypes == filetypes || empty(filetypes))
+ return
+ endif
+
+ " Now we're ready to actually highlight the code blocks.
+ let startgroup = 'mkdCodeStart'
+ let endgroup = 'mkdCodeEnd'
+ for ft in keys(filetypes)
+ if a:force || !has_key(b:mkd_known_filetypes, ft)
+ if has_key(s:filetype_dict, ft)
+ let filetype = s:filetype_dict[ft]
+ else
+ let filetype = ft
+ endif
+ let group = 'mkdSnippet' . toupper(substitute(filetype, "[+-]", "_", "g"))
+ let include = s:syntax_include(filetype)
+ let command = 'syntax region %s matchgroup=%s start="^\s*```%s$" matchgroup=%s end="\s*```$" keepend contains=%s%s'
+ execute printf(command, group, startgroup, ft, endgroup, include, has('conceal') ? ' concealends' : '')
+ execute printf('syntax cluster mkdNonListItem add=%s', group)
+
+ let b:mkd_known_filetypes[ft] = 1
+ endif
+ endfor
+endfunction
+
+function! s:syntax_include(filetype)
+ " Include the syntax highlighting of another {filetype}.
+ let grouplistname = '@' . toupper(a:filetype)
+ " Unset the name of the current syntax while including the other syntax
+ " because some syntax scripts do nothing when "b:current_syntax" is set
+ if exists('b:current_syntax')
+ let syntax_save = b:current_syntax
+ unlet b:current_syntax
+ endif
+ try
+ execute 'syntax include' grouplistname 'syntax/' . a:filetype . '.vim'
+ execute 'syntax include' grouplistname 'after/syntax/' . a:filetype . '.vim'
+ catch /E484/
+ " Ignore missing scripts
+ endtry
+ " Restore the name of the current syntax
+ if exists('syntax_save')
+ let b:current_syntax = syntax_save
+ elseif exists('b:current_syntax')
+ unlet b:current_syntax
+ endif
+ return grouplistname
+endfunction
+
+
+function! s:Markdown_refresh_syntax(force)
+ if &filetype == 'markdown' && line('$') > 1
+ call s:Markdown_highlight_sources(a:force)
+ endif
+endfunction
+
+augroup Mkd
+ autocmd!
+ au BufWinEnter * call s:Markdown_refresh_syntax(1)
+ au BufWritePost * call s:Markdown_refresh_syntax(0)
+ au InsertEnter,InsertLeave * call s:Markdown_refresh_syntax(0)
+ au CursorHold,CursorHoldI * call s:Markdown_refresh_syntax(0)
+augroup END
if exists("*GetMarkdownIndent") | finish | endif
function! s:is_mkdCode(lnum)
- return synIDattr(synID(a:lnum, 1, 0), 'name') == 'mkdCode'
+ let name = synIDattr(synID(a:lnum, 1, 0), 'name')
+ return (name =~ '^mkd\%(Code$\|Snippet\)' || name != '' && name !~ '^\%(mkd\|html\)')
endfunction
function! s:is_li_start(line)
"highlighting for Markdown groups
HtmlHiLink mkdString String
HtmlHiLink mkdCode String
+HtmlHiLink mkdCodeStart String
+HtmlHiLink mkdCodeEnd String
HtmlHiLink mkdFootnote Comment
HtmlHiLink mkdBlockquote Comment
HtmlHiLink mkdLineContinue Comment
--- /dev/null
+Given markdown;
+# a
+
+Execute (Toc does not set nomodifiable on other files):
+ " Sanity check.
+ Assert &modifiable
+
+ :Toc
+ :lclose
+ :edit a
+
+ Assert &modifiable
+
+Given markdown;
+header 1
+========
+
+test
+
+header 2
+--------
+
+test
+
+### header 3
+
+test
+
+Execute (Toc setex headers):
+ :Toc
+
+Expect (setex headers):
+ header 1
+ header 2
+ header 3
+
+Given markdown;
+# header 1
+
+test
+
+## header 2
+
+test
+
+### header 3
+
+test
+
+Execute (Toc atx headers):
+ :Toc
+
+Expect (atx headers):
+ header 1
+ header 2
+ header 3
+
+Given markdown;
+ATX tests.
+
+# h1 space
+
+#h1 nospace
+
+# h1 2 spaces
+
+# h1 trailing hash #
+
+## h2 space
+
+##h2 nospace
+
+## h2 trailing hash ##
+
+### h3 space
+
+###h3 nospace
+
+### h3 trailing hash ###
+
+#### h4
+
+##### h5
+
+###### h6
+
+---
+
+Relative positions.
+
+# h1 before h2
+
+## h2 between h1s
+
+# h1 after h2
+
+---
+
+Setex tests.
+
+setex h1
+========
+
+setex h2
+--------
+
+setex h1 single punctuation
+=
+
+setex h1 punctuation longer than header
+================================
+
+Prevent list vs Setex confusion:
+
+- not Setex
+- because list
+
+---
+
+Mixed tests.
+
+setex h1 before atx
+===================
+
+## atx h2
+
+### atx h3
+
+# atx h1
+
+setex h2
+------------------
+
+### atx h3 2
+
+Execute (Toc multiple headers):
+ :Toc
+
+Expect (multiple headers):
+ h1 space
+ h1 nospace
+ h1 2 spaces
+ h1 trailing hash
+ h2 space
+ h2 nospace
+ h2 trailing hash
+ h3 space
+ h3 nospace
+ h3 trailing hash
+ h4
+ h5
+ h6
+ h1 before h2
+ h2 between h1s
+ h1 after h2
+ setex h1
+ setex h2
+ setex h1 single punctuation
+ setex h1 punctuation longer than header
+ setex h1 before atx
+ atx h2
+ atx h3
+ atx h1
+ setex h2
+ atx h3 2
AssertEqual foldlevel(12), 2, 'foobar'
Given markdown;
-
-==+ Fold Level 1
-
---+ Fold Level 2
-
-Execute (fold level ==+, --+):
- AssertEqual foldlevel(2), 1, '==+'
- AssertEqual foldlevel(4), 2, '--+'
+Fold Level 1
+============
+Fold Level 2
+------------
+
+Execute (fold level ==, --):
+ AssertEqual foldlevel(2), 1, '=='
+ AssertEqual foldlevel(4), 2, '--'
+++ /dev/null
-This file is used for tests which require there to be multiple headers in different relative positions to each other.
-
-Each header should have an unique text that identifies it.
-
----
-
-ATX tests.
-
-# h1 space
-
-#h1 nospace
-
-# h1 2 spaces
-
-# h1 trailing hash #
-
-## h2 space
-
-##h2 nospace
-
-## h2 trailing hash ##
-
-### h3 space
-
-###h3 nospace
-
-### h3 trailing hash ###
-
-#### h4
-
-##### h5
-
-###### h6
-
----
-
-Relative positions.
-
-# h1 before h2
-
-## h2 between h1s
-
-# h1 after h2
-
----
-
-Setex tests.
-
-setex h1
-========
-
-setex h2
---------
-
-setex h1 single punctuation
-=
-
-setex h1 punctuation longer than header
-================================
-
-Prevent list vs Setex confusion:
-
-- not Setex
-- because list
-
----
-
-Mixed tests.
-
-setex h1 before atx
-===================
-
-## atx h2
-
-### atx h3
-
-# atx h1
-
-setex h2
-------------------
-
-### atx h3 2
AssertEqual line('.'), 3
normal ]c
AssertEqual line('.'), 1
-
-Given markdown;
-# a
-
-Execute (Toc does not set nomodifiable on other files):
- " Sanity check.
- Assert &modifiable
-
- :Toc
- :lclose
- :edit a
-
- Assert &modifiable
AssertEqual foldlevel(12), 1, 'foobar'
Execute (fold text of chapters):
- AssertEqual foldtextresult(3), '## Chapter 1 ' . repeat('-', winwidth(0) - 18) . ' 6'
- AssertEqual foldtextresult(10), '## Chapter 2 ' . repeat('-', winwidth(0) - 18) . ' 2'
+ let b:width = winwidth(0)
+ let b:hyphen = repeat('-', b:width - 18 > 2 ? b:width - 18 : b:width - 9 > 0 ? 3 : 2)
+ AssertEqual foldtextresult(3), strpart('## Chapter 1', 0, b:width - 9) . ' ' . b:hyphen . ' 6'
+ AssertEqual foldtextresult(10), strpart('## Chapter 2', 0, b:width - 9) . ' ' . b:hyphen . ' 2'
Given markdown;
Fold text 1
-==+ Fold Level 1
+===========
Fold text 2
---+ Fold Level 2
+-----------
-Execute (fold level ==+, --+):
- AssertEqual foldlevel(2), 0, '==+'
- AssertEqual foldlevel(4), 1, '--+'
+Execute (fold level ==, --):
+ AssertEqual foldlevel(2), 0, '=='
+ AssertEqual foldlevel(4), 1, '--'
-Execute (fold text of ==+, --+):
- AssertEqual foldtextresult(3), 'Fold text 2 ' . repeat('-', winwidth(0) - 17) . ' 1'
+Execute (fold text of ==, --):
+ let b:width = winwidth(0)
+ let b:hyphen = repeat('-', b:width - 17 > 2 ? b:width - 17 : b:width - 9 > 0 ? 3 : 2)
+ AssertEqual foldtextresult(3), strpart('Fold text 2', 0, b:width - 9) . ' ' . b:hyphen . ' 1'
Given markdown;
Headline
AssertNotEqual SyntaxOf('b'), 'mkdCode'
AssertEqual SyntaxOf('c'), 'mkdCode'
+Given markdown;
+```c++
+#include <iostream>
+code
+```
+
+```ruby
+def a
+end
+```
+
+Execute (fenced code block syntax with a language specifier):
+ let b:func = Markdown_GetFunc('vim-markdown/ftplugin/markdown.vim', 'Markdown_refresh_syntax')
+ call b:func(0)
+ AssertEqual SyntaxOf('include'), 'cInclude'
+ AssertEqual SyntaxOf('code'), 'mkdSnippetCPP'
+ AssertEqual SyntaxOf('def'), 'rubyDefine'
+
+Given markdown;
+```a+b-
+code
+```
+
+Execute (fenced code block syntax with an unknown language specifier):
+ let b:func = Markdown_GetFunc('vim-markdown/ftplugin/markdown.vim', 'Markdown_refresh_syntax')
+ call b:func(0)
+ AssertEqual SyntaxOf('code'), 'mkdSnippetA_B_'
+
# Math
Given markdown;
AssertEqual SyntaxOf('a'), 'htmlH1'
AssertEqual SyntaxOf('b'), 'htmlH2'
+Given markdown;
+# h1 space
+
+#h1 nospace
+
+# h1 2 spaces
+
+# h1 trailing hash #
+
+## h2 space
+
+##h2 nospace
+
+## h2 trailing hash ##
+
+### h3 space
+
+###h3 nospace
+
+### h3 trailing hash ###
+
+#### h4
+
+##### h5
+
+###### h6
+
+Execute (atx headers):
+ AssertEqual SyntaxOf('# h1 space'), 'htmlH1'
+ AssertEqual SyntaxOf('#h1 nospace'), 'htmlH1'
+ AssertEqual SyntaxOf('# h1 2 spaces'), 'htmlH1'
+ AssertEqual SyntaxOf('# h1 trailing hash #'), 'htmlH1'
+ AssertEqual SyntaxOf('## h2 space'), 'htmlH2'
+ AssertEqual SyntaxOf('##h2 nospace'), 'htmlH2'
+ AssertEqual SyntaxOf('## h2 trailing hash ##'), 'htmlH2'
+ AssertEqual SyntaxOf('### h3 space'), 'htmlH3'
+ AssertEqual SyntaxOf('###h3 nospace'), 'htmlH3'
+ AssertEqual SyntaxOf('### h3 trailing hash ###'), 'htmlH3'
+ AssertEqual SyntaxOf('#### h4'), 'htmlH4'
+ AssertEqual SyntaxOf('##### h5'), 'htmlH5'
+ AssertEqual SyntaxOf('###### h6'), 'htmlH6'
+
+Given markdown;
+# h1 before h2
+
+## h2 between h1s
+
+# h1 after h2
+
+Execute (atx headers relative positions):
+ AssertEqual SyntaxOf('# h1 before h2'), 'htmlH1'
+ AssertEqual SyntaxOf('## h2 between h1s'), 'htmlH2'
+ AssertEqual SyntaxOf('# h1 after h2'), 'htmlH1'
+
+Given markdown;
+setex h1
+========
+
+setex h2
+--------
+
+setex h1 single punctuation
+=
+
+setex h1 punctuation longer than header
+================================
+
+Execute (setex headers):
+ AssertEqual SyntaxOf('setex h1'), 'htmlH1'
+ AssertEqual SyntaxOf('^========$'), 'htmlH1'
+ AssertEqual SyntaxOf('setex h2'), 'htmlH2'
+ AssertEqual SyntaxOf('--------'), 'htmlH2'
+ AssertEqual SyntaxOf('setex h1 single punctuation'), 'htmlH1'
+ AssertEqual SyntaxOf('^=$'), 'htmlH1'
+ AssertEqual SyntaxOf('setex h1 punctuation longer than header'), 'htmlH1'
+ AssertEqual SyntaxOf('^================================$'), 'htmlH1'
+
+Given markdown;
+- not Setex
+- because list
+
+Execute (prevent list vs Setex confusion):
+ AssertNotEqual SyntaxOf('- not Setex'), 'htmlH2'
+ AssertNotEqual SyntaxOf('- becuase list'), 'htmlH2'
+
+Given markdown;
+setex h1 before atx
+===================
+
+## atx h2
+
+### atx h3
+
+# atx h1
+
+setex h2
+------------------
+
+### atx h3 2
+
+Execute (mixed atx and setex headers):
+ AssertEqual SyntaxOf('setex h1 before atx'), 'htmlH1'
+ AssertEqual SyntaxOf('==================='), 'htmlH1'
+ AssertEqual SyntaxOf('## atx h2'), 'htmlH2'
+ AssertEqual SyntaxOf('### atx h3'), 'htmlH3'
+ AssertEqual SyntaxOf('# atx h1'), 'htmlH1'
+ AssertEqual SyntaxOf('setex h2'), 'htmlH2'
+ AssertEqual SyntaxOf('------------------'), 'htmlH2'
+
# List
Given markdown;