From: Hiroshi Shirosaki Date: Thu, 14 Jan 2016 04:35:10 +0000 (+0900) Subject: Merge pull request #241 from alexconst/fix/hash_comments X-Git-Url: https://git.madduck.net/etc/vim.git/commitdiff_plain/63aabf4b47fc944afc210b974574d158eb7a08d0?hp=e72e47d30d117acf0d91dde2258cab651d90f700 Merge pull request #241 from alexconst/fix/hash_comments Fix bug related to folding and hash comments --- diff --git a/README.md b/README.md index 6fd8a38..1a6fd1d 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ tar --strip=1 -zxf vim-markdown-master.tar.gz 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. @@ -76,7 +76,7 @@ To fold in a style like [python-mode](https://github.com/klen/python-mode), add 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 @@ -99,7 +99,7 @@ Tip: it can be changed on the fly with: 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 `` mappings. @@ -113,7 +113,7 @@ The following options control which syntax extensions will be turned on. They ar 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 @@ -121,7 +121,7 @@ let g:vim_markdown_math=1 Highlight YAML frontmatter as used by Jekyll: ```vim -let g:vim_markdown_frontmatter=1 +let g:vim_markdown_frontmatter = 1 ``` diff --git a/after/ftplugin/markdown.vim b/after/ftplugin/markdown.vim index 13f93ed..84b6a4f 100644 --- a/after/ftplugin/markdown.vim +++ b/after/ftplugin/markdown.vim @@ -7,7 +7,8 @@ " 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) diff --git a/doc/vim-markdown.txt b/doc/vim-markdown.txt index f88ae25..6e65ff4 100644 --- a/doc/vim-markdown.txt +++ b/doc/vim-markdown.txt @@ -68,7 +68,7 @@ Disable Folding ~ 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. @@ -82,7 +82,7 @@ Change fold style ~ 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* @@ -90,7 +90,7 @@ 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 '' mappings. @@ -107,7 +107,7 @@ LaTeX math ~ 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* @@ -115,7 +115,7 @@ YAML frontmatter ~ Highlight YAML frontmatter as used by Jekyll: > - let g:vim_markdown_frontmatter=1 + let g:vim_markdown_frontmatter = 1 < =============================================================================== *vim-markdown-mappings* diff --git a/ftplugin/markdown.vim b/ftplugin/markdown.vim index 61fdab4..7e2b35e 100644 --- a/ftplugin/markdown.vim +++ b/ftplugin/markdown.vim @@ -356,7 +356,7 @@ function! s:Toc(...) 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 @@ -579,3 +579,84 @@ command! -buffer Toc call s:Toc() 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 diff --git a/indent/markdown.vim b/indent/markdown.vim index 3f89b5c..e21f287 100755 --- a/indent/markdown.vim +++ b/indent/markdown.vim @@ -19,7 +19,8 @@ setlocal comments+=b:> 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) diff --git a/syntax/markdown.vim b/syntax/markdown.vim index 035199b..e28644a 100644 --- a/syntax/markdown.vim +++ b/syntax/markdown.vim @@ -115,6 +115,8 @@ syn cluster mkdNonListItem contains=@htmlTop,htmlItalic,htmlBold,htmlBoldItalic, "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 diff --git a/test/command-toc.vader b/test/command-toc.vader new file mode 100644 index 0000000..a61e04b --- /dev/null +++ b/test/command-toc.vader @@ -0,0 +1,165 @@ +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 diff --git a/test/folding.vader b/test/folding.vader index ee20975..adcae5f 100644 --- a/test/folding.vader +++ b/test/folding.vader @@ -28,11 +28,11 @@ Execute (fold level # in code block): 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, '--' diff --git a/test/header.md b/test/header.md deleted file mode 100644 index 7e19083..0000000 --- a/test/header.md +++ /dev/null @@ -1,82 +0,0 @@ -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 diff --git a/test/map.vader b/test/map.vader index e6d2dff..92947f5 100644 --- a/test/map.vader +++ b/test/map.vader @@ -112,16 +112,3 @@ Execute (]c): 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 diff --git a/test/python-folding.vader b/test/python-folding.vader index 43f8085..ca40c62 100644 --- a/test/python-folding.vader +++ b/test/python-folding.vader @@ -29,21 +29,25 @@ Execute (fold level # in code block): 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 diff --git a/test/syntax.vader b/test/syntax.vader index fb92ba8..105e595 100644 --- a/test/syntax.vader +++ b/test/syntax.vader @@ -223,6 +223,34 @@ Execute (indent code blocks after list): AssertNotEqual SyntaxOf('b'), 'mkdCode' AssertEqual SyntaxOf('c'), 'mkdCode' +Given markdown; +```c++ +#include +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; @@ -331,6 +359,115 @@ Execute (header title starts with #): 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;