Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several additions and improvements #520

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,21 @@ Try `:help concealcursor` and `:help conceallevel` for details.

let g:vim_markdown_conceal = 0

To enable link concealment, add the following to your `.vimrc`:

let g:vim_markdown_conceal_links = 1

To disable delimiter concealment with special chars, add the following to
your `.vimrc`:

let g:vim_markdown_conceal_chars = 0

To disable math conceal with LaTeX math syntax enabled, add the following to your `.vimrc`:

let g:tex_conceal = ""
let g:vim_markdown_math = 1

- `g:vim_markdown_conceal_code_blocks`

Disabling conceal for code fences requires an additional setting:
To disable code fences concealment, add the following to your `.vimrc`:

let g:vim_markdown_conceal_code_blocks = 0

Expand Down Expand Up @@ -296,7 +303,9 @@ The following options control which syntax extensions will be turned on. They ar
* item1
* item2

vim-markdown automatically insert the indent. By default, the number of spaces of indent is 4. If you'd like to change the number as 2, just write:
vim-markdown automatically insert the indent. By default, the number of
spaces of indent is the value of `shiftwidth`. If you'd like to change the
number as 2, just write:

let g:vim_markdown_new_list_item_indent = 2

Expand Down Expand Up @@ -447,6 +456,13 @@ The main contributors of vim-markdown are:

If you feel that your name should be on this list, please make a pull request listing your contributions.

Includes code from:

- Changes default new_list_item_indent from 4 to sw from skewerr/vim-markdown.
- Fixing single '<' syntax from VVVFO/vim-markdown.
- Fixing syntax refresh for hovering windows tomtomjhj/vim-markdown.
- InsertToc from cdelledonne/vim-markdown.

## License

The MIT License (MIT)
Expand Down
74 changes: 37 additions & 37 deletions after/ftplugin/markdown.vim
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,43 @@ if get(g:, "vim_markdown_folding_style_pythonic", 0)
let l1 = getline(a:lnum)
"~~~~~ keep track of fenced code blocks ~~~~~
"If we hit a code block fence
if l1 =~ '````*' || l1 =~ '\~\~\~\~*'
" toggle the variable that says if we're in a code block
if b:fenced_block == 0
let b:fenced_block = 1
elseif b:fenced_block == 1
let b:fenced_block = 0
endif
" else, if we're caring about front matter
elseif g:vim_markdown_frontmatter == 1
" if we're in front matter and not on line 1
if b:front_matter == 1 && a:lnum > 2
let l0 = getline(a:lnum-1)
" if the previous line fenced front matter
if l0 == '---'
" we must not be in front matter
let b:front_matter = 0
endif
" else, if we're on line one
elseif a:lnum == 1
" if we hit a front matter fence
if l1 == '---'
" we're in the front matter
let b:front_matter = 1
endif
endif
endif

" if we're in a code block or front matter
if b:fenced_block == 1 || b:front_matter == 1
if a:lnum == 1
" fold any 'preamble'
return '>1'
else
" keep previous foldlevel
return '='
endif
endif
" if l1 =~ '````*' || l1 =~ '\~\~\~\~*'
" " toggle the variable that says if we're in a code block
" if b:fenced_block == 0
" let b:fenced_block = 1
" elseif b:fenced_block == 1
" let b:fenced_block = 0
" endif
" " else, if we're caring about front matter
" elseif g:vim_markdown_frontmatter == 1
" " if we're in front matter and not on line 1
" if b:front_matter == 1 && a:lnum > 2
" let l0 = getline(a:lnum-1)
" " if the previous line fenced front matter
" if l0 == '---'
" " we must not be in front matter
" let b:front_matter = 0
" endif
" " else, if we're on line one
" elseif a:lnum == 1
" " if we hit a front matter fence
" if l1 == '---'
" " we're in the front matter
" let b:front_matter = 1
" endif
" endif
" endif

" " if we're in a code block or front matter
" if b:fenced_block == 1 || b:front_matter == 1
" if a:lnum == 1
" " fold any 'preamble'
" return '>1'
" else
" " keep previous foldlevel
" return '='
" endif
" endif

let l2 = getline(a:lnum+1)
" if the next line starts with two or more '='
Expand Down
14 changes: 12 additions & 2 deletions doc/vim-markdown.txt
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,15 @@ Syntax Concealing ~
>
let g:vim_markdown_conceal = 0
<
To enable link concealment, add the following to your '.vimrc':

let g:vim_markdown_conceal_links = 1

To disable delimiter concealment with special chars, add the following to
your '.vimrc':

let g:vim_markdown_conceal_chars = 0

To disable math conceal with LaTeX math syntax enabled, add the following
to your '.vimrc':
>
Expand All @@ -261,7 +270,7 @@ Syntax Concealing ~
*g:vim_markdown_conceal_code_blocks*
- 'g:vim_markdown_conceal_code_blocks'

Disabling conceal for code fences requires an additional setting:
To disable code fences concealment, add the following to your '.vimrc':
>
let g:vim_markdown_conceal_code_blocks = 0
<
Expand Down Expand Up @@ -408,7 +417,8 @@ Adjust new list item indent ~
* item2
<
vim-markdown automatically insert the indent. By default, the number of
spaces of indent is 4. If you'd like to change the number as 2, just write:
spaces of indent is the value of 'shiftwidth'. If you'd like to change the
number as 2, just write:
>
let g:vim_markdown_new_list_item_indent = 2
<
Expand Down
11 changes: 7 additions & 4 deletions ftplugin/markdown.vim
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ function! s:MarkdownHighlightSources(force)
" Look for code blocks in the current file
let filetypes = {}
for line in getline(1, '$')
let ft = matchstr(line, '```\s*\zs[0-9A-Za-z_+-]*\ze.*')
let ft = matchstr(line, '\(`\{3,1}\|\~\{3,}\)\s*\zs[0-9A-Za-z_+-]*\ze.*')
if !empty(ft) && ft !~ '^\d*$' | let filetypes[ft] = 1 | endif
endfor
if !exists('b:mkd_known_filetypes')
Expand Down Expand Up @@ -819,8 +819,11 @@ function! s:MarkdownHighlightSources(force)
else
let include = '@' . toupper(filetype)
endif
let command = 'syntax region %s matchgroup=%s start="^\s*```\s*%s.*$" matchgroup=%s end="\s*```$" keepend contains=%s%s'
execute printf(command, group, startgroup, ft, endgroup, include, has('conceal') && get(g:, 'vim_markdown_conceal', 1) && get(g:, 'vim_markdown_conceal_code_blocks', 1) ? ' concealends' : '')
let concealends = has('conceal') && get(g:, 'vim_markdown_conceal', 1) && get(g:, 'vim_markdown_conceal_code_blocks', 1) ? ' concealends' : ''
let command = 'syntax region %s start="^\s*\z(`\{3,}\)\s*%s.*$" end="\s*\z1`*\s*$" keepend contains=mkdCodeStart,mkdCodeEnd,%s%s'
execute printf(command, group, ft, include, concealends)
let command = 'syntax region %s start="^\s*\z(\~\{3,}\)\s*%s.*$" end="\s*\z1\~*\s*$" keepend contains=mkdCodeStart,mkdCodeEnd,%s%s'
execute printf(command, group, ft, include, concealends)
execute printf('syntax cluster mkdNonListItem add=%s', group)

let b:mkd_known_filetypes[ft] = 1
Expand Down Expand Up @@ -871,7 +874,7 @@ augroup Mkd
autocmd! * <buffer>
autocmd BufWinEnter <buffer> call s:MarkdownRefreshSyntax(1)
autocmd BufUnload <buffer> call s:MarkdownClearSyntaxVariables()
autocmd BufWritePost <buffer> call s:MarkdownRefreshSyntax(0)
autocmd BufWritePost,WinLeave <buffer> call s:MarkdownRefreshSyntax(0)
autocmd InsertEnter,InsertLeave <buffer> call s:MarkdownRefreshSyntax(0)
autocmd CursorHold,CursorHoldI <buffer> call s:MarkdownRefreshSyntax(0)
augroup END
2 changes: 1 addition & 1 deletion indent/markdown.vim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function GetMarkdownIndent()
if v:lnum > 2 && s:IsBlankLine(getline(v:lnum - 1)) && s:IsBlankLine(getline(v:lnum - 2))
return 0
endif
let list_ind = get(g:, "vim_markdown_new_list_item_indent", 4)
let list_ind = get(g:, "vim_markdown_new_list_item_indent", &shiftwidth)
" Find a non-blank line above the current line.
let lnum = s:PrevNonBlank(v:lnum - 1)
" At the start of the file use zero indent.
Expand Down
120 changes: 98 additions & 22 deletions syntax/markdown.vim
Original file line number Diff line number Diff line change
Expand Up @@ -34,38 +34,103 @@ syn spell toplevel
syn case ignore
syn sync linebreaks=1

let s:concealflag = 0
let s:conceal = ''
let s:concealends = ''
let s:concealcode = ''
if has('conceal') && get(g:, 'vim_markdown_conceal', 1)
let s:concealflag = 1
let s:conceal = ' conceal'
let s:concealends = ' concealends'
endif
if has('conceal') && get(g:, 'vim_markdown_conceal_code_blocks', 1)
if s:concealflag == 1 && get(g:, 'vim_markdown_conceal_code_blocks', 1)
let s:concealcode = ' concealends'
endif
if s:concealflag == 1 && get(g:, 'vim_markdown_conceal_links', 0)
let s:conceallink = ' conceal'
let s:conceallinkends = ' concealends'
else
let s:conceallink = ''
let s:conceallinkends = ''
endif

if &encoding ==# 'utf-8'
let s:cchars = {
\'newline': '↵',
\'image': '▨',
\'super': 'ⁿ',
\'sub': 'ₙ',
\'strike': 'x̶',
\'atx': '§',
\'codelang': 'λ',
\'codeend': '—',
\'abbrev': '→',
\'footnote': '†',
\'definition': ' ',
\'li': '•',
\'html_c_s': '‹',
\'html_c_e': '›'}
else
" ascii defaults
let s:cchars = {
\'newline': ' ',
\'image': 'i',
\'super': '^',
\'sub': '_',
\'strike': '~',
\'atx': '#',
\'codelang': 'l',
\'codeend': '-',
\'abbrev': 'a',
\'footnote': 'f',
\'definition': ' ',
\'li': '*',
\'html_c_s': '+',
\'html_c_e': '+'}
endif
function! s:ConcealChar(conceal_char)
if s:concealflag == 1 && get(g:, 'vim_markdown_conceal_chars', 1)
return ' conceal cchar='.s:cchars[a:conceal_char]
else
return ''
endif
endfunction

" additions to HTML groups
if get(g:, 'vim_markdown_emphasis_multiline', 1)
let s:oneline = ''
else
let s:oneline = ' oneline'
endif
syn region mkdItalic matchgroup=mkdItalic start="\%(\*\|_\)" end="\%(\*\|_\)"
syn region mkdBold matchgroup=mkdBold start="\%(\*\*\|__\)" end="\%(\*\*\|__\)"
syn region mkdBoldItalic matchgroup=mkdBoldItalic start="\%(\*\*\*\|___\)" end="\%(\*\*\*\|___\)"
execute 'syn region htmlItalic matchgroup=mkdItalic start="\%(^\|\s\)\zs\*\ze[^\\\*\t ]\%(\%([^*]\|\\\*\|\n\)*[^\\\*\t ]\)\?\*\_W" end="[^\\\*\t ]\zs\*\ze\_W" keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlItalic matchgroup=mkdItalic start="\%(^\|\s\)\zs_\ze[^\\_\t ]" end="[^\\_\t ]\zs_\ze\_W" keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBold matchgroup=mkdBold start="\%(^\|\s\)\zs\*\*\ze\S" end="\S\zs\*\*" keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBold matchgroup=mkdBold start="\%(^\|\s\)\zs__\ze\S" end="\S\zs__" keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBoldItalic matchgroup=mkdBoldItalic start="\%(^\|\s\)\zs\*\*\*\ze\S" end="\S\zs\*\*\*" keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBoldItalic matchgroup=mkdBoldItalic start="\%(^\|\s\)\zs___\ze\S" end="\S\zs___" keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlItalic matchgroup=mkdItalic '
\ . 'start="\%(\s\|_\|^\)\@<=\*\%(\s\|\*\|$\)\@!" end="\%(\s\|\*\)\@<!\*" '
\ . 'keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlItalic matchgroup=mkdItalic '
\ . 'start="\%(\s\|\*\|^\)\@<=_\%(\s\|_\|$\)\@!" end="\%(\s\|_\)\@<!_" '
\ . 'keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBold matchgroup=mkdBold '
\ . 'start="\%(\s\|__\|^\)\@<=\*\*\%(\s\|\*\|$\)\@!" end="\%(\s\|\*\*\)\@<!\*\*" '
\ . 'keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBold matchgroup=mkdBold '
\ . 'start="\%(\s\|\*\*\|^\)\@<=__\%(\s\|_\|$\)\@!" end="\%(\s\|__\)\@<!__" '
\ . 'keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBoldItalic matchgroup=mkdBoldItalic '
\ . 'start="\%(\s\|_\|^\)\@<=\*\*\*\%(\s\|\*\|$\)\@!" end="\%(\s\|\*\)\@<!\*\*\*" '
\ . 'keepend contains=@Spell' . s:oneline . s:concealends
execute 'syn region htmlBoldItalic matchgroup=mkdBoldItalic '
\ . 'start="\%(\s\|\*\|^\)\@<=___\%(\s\|_\|$\)\@!" end="\%(\s\|_\)\@<!___" '
\ . 'keepend contains=@Spell' . s:oneline . s:concealends

" Comments
syn region mkdComment start=/<!--\s\=/ end=/\s\=-->/ keepend contains=mkdCommentStart,mkdCommentEnd,@Spell
execute 'syn match mkdCommentStart /<!--/ contained' . s:ConcealChar('html_c_s')
execute 'syn match mkdCommentEnd /-->/ contained' . s:ConcealChar('html_c_e')

" [link](URL) | [link][id] | [link][] | ![image](URL)
syn region mkdFootnotes matchgroup=mkdDelimiter start="\[^" end="\]"
execute 'syn region mkdID matchgroup=mkdDelimiter start="\[" end="\]" contained oneline' . s:conceal
execute 'syn region mkdURL matchgroup=mkdDelimiter start="(" end=")" contained oneline' . s:conceal
execute 'syn region mkdLink matchgroup=mkdDelimiter start="\\\@<!!\?\[\ze[^]\n]*\n\?[^]\n]*\][[(]" end="\]" contains=@mkdNonListItem,@Spell nextgroup=mkdURL,mkdID skipwhite' . s:concealends
execute 'syn region mkdID matchgroup=mkdDelimiter start="\[" end="\]" contained oneline' . s:conceallink
execute 'syn region mkdURL matchgroup=mkdDelimiter start="(" end=")" contained oneline' . s:conceallink
execute 'syn region mkdLink matchgroup=mkdDelimiter start="\\\@<!!\?\[\ze[^]\n]*\n\?[^]\n]*\][[(]" end="\]" contains=@mkdNonListItem,@Spell nextgroup=mkdURL,mkdID skipwhite' . s:conceallinkends

" Autolink without angle brackets.
" mkd inline links: protocol optional user:pass@ sub/domain .com, .co.uk, etc optional port path/querystring/hash fragment
Expand All @@ -86,25 +151,31 @@ syn region mkdLinkTitle matchgroup=mkdDelimiter start=+'+ end=+'+ contained
syn region mkdLinkTitle matchgroup=mkdDelimiter start=+(+ end=+)+ contained

"HTML headings
syn region htmlH1 matchgroup=mkdHeading start="^\s*#" end="$" contains=mkdLink,mkdInlineURL,@Spell
syn region htmlH2 matchgroup=mkdHeading start="^\s*##" end="$" contains=mkdLink,mkdInlineURL,@Spell
syn region htmlH3 matchgroup=mkdHeading start="^\s*###" end="$" contains=mkdLink,mkdInlineURL,@Spell
syn region htmlH4 matchgroup=mkdHeading start="^\s*####" end="$" contains=mkdLink,mkdInlineURL,@Spell
syn region htmlH5 matchgroup=mkdHeading start="^\s*#####" end="$" contains=mkdLink,mkdInlineURL,@Spell
syn region htmlH6 matchgroup=mkdHeading start="^\s*######" end="$" contains=mkdLink,mkdInlineURL,@Spell
syn region htmlH1 start="^\s*#" end="$" keepend contains=mkdAtx,mkdLink,mkdInlineURL,@Spell
syn region htmlH2 start="^\s*##" end="$" keepend contains=mkdAtx,mkdLink,mkdInlineURL,@Spell
syn region htmlH3 start="^\s*###" end="$" keepend contains=mkdAtx,mkdLink,mkdInlineURL,@Spell
syn region htmlH4 start="^\s*####" end="$" keepend contains=mkdAtx,mkdLink,mkdInlineURL,@Spell
syn region htmlH5 start="^\s*#####" end="$" keepend contains=mkdAtx,mkdLink,mkdInlineURL,@Spell
syn region htmlH6 start="^\s*######" end="$" keepend contains=mkdAtx,mkdLink,mkdInlineURL,@Spell
syn match htmlH1 /^.\+\n=\+$/ contains=mkdLink,mkdInlineURL,@Spell
syn match htmlH2 /^.\+\n-\+$/ contains=mkdLink,mkdInlineURL,@Spell
execute 'syn match mkdAtx /#/ contained' . s:ConcealChar('atx')

"define Markdown groups
syn match mkdLineBreak / \+$/
syn region mkdBlockquote start=/^\s*>/ end=/$/ contains=mkdLink,mkdInlineURL,mkdLineBreak,@Spell
execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/\(\([^\\]\|^\)\\\)\@<!`/ end=/`/' . s:concealcode
execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/\(\([^\\]\|^\)\\\)\@<!``/ skip=/[^`]`[^`]/ end=/``/' . s:concealcode
execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/^\s*\z(`\{3,}\)[^`]*$/ end=/^\s*\z1`*\s*$/' . s:concealcode
execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/\(\([^\\]\|^\)\\\)\@<!\~\~/ end=/\(\([^\\]\|^\)\\\)\@<!\~\~/' . s:concealcode
execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/^\s*\z(\~\{3,}\)\s*[0-9A-Za-z_+-]*\s*$/ end=/^\s*\z1\~*\s*$/' . s:concealcode
execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start="<pre\(\|\_s[^>]*\)\\\@<!>" end="</pre>"' . s:concealcode
execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start="<code\(\|\_s[^>]*\)\\\@<!>" end="</code>"' . s:concealcode
" TODO: use matchgroup for start and end when working with concealment of
" start/end groups
execute 'syn region mkdCode matchgroup=mkdCodeStart start=/^\s*\z(`\{3,}\)\s*[0-9A-Za-z_+-]*\s*$/ matchgroup=mkdCodeEnd end=/^\s*\z1`*\s*$/' . s:concealcode
execute 'syn region mkdCode start=/^\s*\z(\~\{3,}\)\s*[0-9A-Za-z_+-]*\s*$/ end=/^\s*\z1\~*\s*$/ keepend contains=mkdCodeStart,mkdCodeEnd' . s:concealcode
execute 'syn match mkdCodeStart /\(\_^\n\_^\(>\s\)\?\([ ]\{4,}\|\t\)\=\)\@<=\(\~\{3,}\~*\|`\{3,}`*\)/ nextgroup=mkdCodeLang contained' . s:ConcealChar('codelang')
execute 'syn match mkdCodeEnd /\(`\{3,}`*\|\~\{3,}\~*\)\(\_$\n\(>\s\)\?\_$\)\@=/ contained' . s:ConcealChar('codeend')
syn match mkdCodeLang /\(\s\?\)\@<=.\+\(\_$\)\@=/ contained
syn region mkdFootnote start="\[^" end="\]"
syn match mkdCode /^\s*\n\(\(\s\{8,}[^ ]\|\t\t\+[^\t]\).*\n\)\+/
syn match mkdCode /\%^\(\(\s\{4,}[^ ]\|\t\+[^\t]\).*\n\)\+/
Expand Down Expand Up @@ -155,14 +226,18 @@ if get(g:, 'vim_markdown_strikethrough', 0)
HtmlHiLink mkdStrike htmlStrike
endif

syn cluster mkdNonListItem contains=@htmlTop,htmlItalic,htmlBold,htmlBoldItalic,mkdFootnotes,mkdInlineURL,mkdLink,mkdLinkDef,mkdLineBreak,mkdBlockquote,mkdCode,mkdRule,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,mkdMath,mkdStrike
syn cluster mkdNonListItem contains=htmlItalic,htmlBold,htmlBoldItalic,mkdComment,mkdFootnotes,mkdInlineURL,mkdLink,mkdLinkDef,mkdLineBreak,mkdBlockquote,mkdCode,mkdRule,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,mkdMath,mkdStrike

"highlighting for Markdown groups
HtmlHiLink mkdString String
HtmlHiLink mkdComment Comment
HtmlHiLink mkdCommentStart Comment
HtmlHiLink mkdCommentEnd Comment
HtmlHiLink mkdCode String
HtmlHiLink mkdCodeDelimiter String
HtmlHiLink mkdCodeStart String
HtmlHiLink mkdCodeEnd String
HtmlHiLink mkdCodeLang Comment
HtmlHiLink mkdFootnote Comment
HtmlHiLink mkdBlockquote Comment
HtmlHiLink mkdListItem Identifier
Expand All @@ -177,6 +252,7 @@ HtmlHiLink mkdLinkDef mkdID
HtmlHiLink mkdLinkDefTarget mkdURL
HtmlHiLink mkdLinkTitle htmlString
HtmlHiLink mkdDelimiter Delimiter
HtmlHiLink mkdAtx Statement

let b:current_syntax = "mkd"

Expand Down
Loading