]> git.madduck.net Git - etc/vim.git/blob - autoload/vital/_lsp/VS/Vim/Syntax/Markdown.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Squashed '.vim/bundle/vim-lsp/' content from commit 04428c92
[etc/vim.git] / autoload / vital / _lsp / VS / Vim / Syntax / Markdown.vim
1 " ___vital___
2 " NOTE: lines between '" ___vital___' is generated by :Vitalize.
3 " Do not modify the code nor insert new lines before '" ___vital___'
4 function! s:_SID() abort
5   return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
6 endfunction
7 execute join(['function! vital#_lsp#VS#Vim#Syntax#Markdown#import() abort', printf("return map({'apply': ''}, \"vital#_lsp#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
8 delfunction s:_SID
9 " ___vital___
10 "
11 " apply
12 "
13 " TODO: Refactor
14 "
15 function! s:apply(...) abort
16   let l:args = get(a:000, 0, {})
17   let l:text = has_key(l:args, 'text') ? l:args.text : getbufline('%', 1, '$')
18   let l:text = type(l:text) == v:t_list ? join(l:text, "\n") : l:text
19
20   call s:_execute('syntax sync clear')
21   if !exists('b:___VS_Vim_Syntax_Markdown')
22     " Avoid automatic highlighting by built-in runtime syntax.
23     if !has_key(g:, 'markdown_fenced_languages')
24       call s:_execute('runtime! syntax/markdown.vim')
25     else
26       let l:markdown_fenced_languages = g:markdown_fenced_languages
27       unlet g:markdown_fenced_languages
28       call s:_execute('runtime! syntax/markdown.vim')
29       let g:markdown_fenced_languages = l:markdown_fenced_languages
30     endif
31
32     " Remove markdownCodeBlock because we support it manually.
33     call s:_clear('markdownCodeBlock') " runtime
34     call s:_clear('mkdCode') " plasticboy/vim-markdown
35
36     " Modify markdownCode (`codes...`)
37     call s:_clear('markdownCode')
38     syntax region markdownCode matchgroup=Conceal start=/\%(``\)\@!`/ matchgroup=Conceal end=/\%(``\)\@!`/ containedin=TOP keepend concealends
39
40     " Modify markdownEscape (_bold\_text_) @see nvim's syntax/lsp_markdown.vim
41     call s:_clear('markdownEscape')
42     syntax region markdownEscape matchgroup=markdownEscape start=/\\\ze[\\\x60*{}\[\]()#+\-,.!_>~|"$%&'\/:;<=?@^ ]/ end=/./ containedin=ALL keepend oneline concealends
43
44     " Add syntax for basic html entities.
45     syntax match vital_vs_vim_syntax_markdown_entities_lt /&lt;/ containedin=ALL conceal cchar=<
46     syntax match vital_vs_vim_syntax_markdown_entities_gt /&gt;/ containedin=ALL conceal cchar=>
47     syntax match vital_vs_vim_syntax_markdown_entities_amp /&amp;/ containedin=ALL conceal cchar=&
48     syntax match vital_vs_vim_syntax_markdown_entities_quot /&quot;/ containedin=ALL conceal cchar="
49     syntax match vital_vs_vim_syntax_markdown_entities_nbsp /&nbsp;/ containedin=ALL conceal cchar= 
50
51     let b:___VS_Vim_Syntax_Markdown = {}
52     let b:___VS_Vim_Syntax_Markdown.marks = {}
53     let b:___VS_Vim_Syntax_Markdown.filetypes = {}
54   endif
55
56   for [l:mark, l:filetype] in items(s:_get_filetype_map(l:text))
57     try
58       let l:mark_group = substitute(toupper(l:mark), '\.', '_', 'g')
59       if has_key(b:___VS_Vim_Syntax_Markdown.marks, l:mark_group)
60         continue
61       endif
62       let b:___VS_Vim_Syntax_Markdown.marks[l:mark_group] = v:true
63
64       let l:filetype_group = substitute(toupper(l:filetype), '\.', '_', 'g')
65       if !has_key(b:___VS_Vim_Syntax_Markdown.filetypes, l:filetype_group)
66         call s:_execute('syntax include @%s syntax/%s.vim', l:filetype_group, l:filetype)
67         let b:___VS_Vim_Syntax_Markdown.filetypes[l:filetype_group] = v:true
68       endif
69
70       call s:_execute('syntax region %s matchgroup=Conceal start=/%s/ matchgroup=Conceal end=/%s/ contains=@%s containedin=TOP keepend concealends',
71       \   l:mark_group,
72       \   printf('```\s*%s\s*', l:mark),
73       \   '```\s*\%(' . "\n" . '\|$\)',
74       \   l:filetype_group
75       \ )
76     catch /.*/
77       unsilent echomsg printf('Fail to apply "syntax/%s.vim". Add "let g:markdown_fenced_languages = ["%s=$FILETYPE"]" to enable syntax', l:filetype, l:filetype)
78     endtry
79   endfor
80 endfunction
81
82 "
83 " _clear
84 "
85 function! s:_clear(group) abort
86   try
87     execute printf('silent! syntax clear %s', a:group)
88   catch /.*/
89   endtry
90 endfunction
91
92 "
93 "  _execute
94 "
95 function! s:_execute(command, ...) abort
96   let b:current_syntax = ''
97   unlet b:current_syntax
98
99   let g:main_syntax = ''
100   unlet g:main_syntax
101
102   execute call('printf', [a:command] + a:000)
103 endfunction
104
105 "
106 " _get_filetype_map
107 "
108 function! s:_get_filetype_map(text) abort
109   let l:filetype_map = {}
110   for l:mark in s:_find_marks(a:text)
111     let l:filetype_map[l:mark] = s:_get_filetype_from_mark(l:mark)
112   endfor
113   return l:filetype_map
114 endfunction
115
116 "
117 " _find_marks
118 "
119 function! s:_find_marks(text) abort
120   let l:marks = {}
121
122   " find from buffer contents.
123   let l:text = a:text
124   let l:pos = 0
125   while 1
126     let l:match = matchstrpos(l:text, '```\s*\zs\w\+', l:pos, 1)
127     if empty(l:match[0])
128       break
129     endif
130     let l:marks[l:match[0]] = v:true
131     let l:pos = l:match[2]
132   endwhile
133
134   return keys(l:marks)
135 endfunction
136
137 "
138 " _get_filetype_from_mark
139 "
140 function! s:_get_filetype_from_mark(mark) abort
141   for l:config in get(g:, 'markdown_fenced_languages', [])
142     if l:config !~# '='
143       if l:config ==# a:mark
144         return a:mark
145       endif
146     else
147       let l:config = split(l:config, '=')
148       if l:config[0] ==# a:mark
149         return l:config[1]
150       endif
151     endif
152   endfor
153   return a:mark
154 endfunction
155