1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
" Highlighting code blocks in .aichat files
" Inspired and based on https://github.com/preservim/vim-markdown
if exists('g:vim_markdown_fenced_languages')
let s:filetype_dict = {}
for s:filetype in g:vim_markdown_fenced_languages
let key = matchstr(s:filetype, '[^=]*')
let val = matchstr(s:filetype, '[^=]*$')
let s:filetype_dict[key] = val
endfor
else
let s:filetype_dict = {
\ 'c++': 'cpp',
\ 'viml': 'vim',
\ 'bash': 'sh',
\ 'ini': 'dosini',
\ 'js': 'javascript',
\ 'jsx': 'javascriptreact',
\ 'ts': 'typescript',
\ 'tsx': 'typescriptreact',
\ }
endif
function! s:MarkdownHighlightSources(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, '\(`\{3,}\|\~\{3,}\)\s*\zs[0-9A-Za-z_+-]*\ze.*')
if !empty(ft) && ft !~# '^\d*$' | let filetypes[ft] = 1 | endif
endfor
if !exists('b:aichat_known_filetypes')
let b:aichat_known_filetypes = {}
endif
if !exists('b:aichat_included_filetypes')
" set syntax file name included
let b:aichat_included_filetypes = {}
endif
if !a:force && (b:aichat_known_filetypes == filetypes || empty(filetypes))
return
endif
" Now we're ready to actually highlight the code blocks.
let startgroup = 'aichatCodeStart'
let endgroup = 'aichatCodeEnd'
for ft in keys(filetypes)
if a:force || !has_key(b:aichat_known_filetypes, ft)
if has_key(s:filetype_dict, ft)
let filetype = s:filetype_dict[ft]
else
let filetype = ft
endif
let group = 'aichatSnippet' . toupper(substitute(filetype, '[+-]', '_', 'g'))
if !has_key(b:aichat_included_filetypes, filetype)
let include = s:SyntaxInclude(filetype)
let b:aichat_included_filetypes[filetype] = 1
else
let include = '@' . toupper(filetype)
endif
let command_backtick = 'syntax region %s matchgroup=%s start="^\s*`\{3,}\s*%s.*$" matchgroup=%s end="\s*`\{3,}\s*$" keepend contains=%s'
let command_tilde = 'syntax region %s matchgroup=%s start="^\s*\~\{3,}\s*%s.*$" matchgroup=%s end="\s*\~\{3,}\s*$" keepend contains=%s'
execute printf(command_backtick, group, startgroup, ft, endgroup, include)
execute printf(command_tilde, group, startgroup, ft, endgroup, include)
execute printf('syntax cluster aichatNonListItem add=%s', group)
let b:aichat_known_filetypes[ft] = 1
endif
endfor
endfunction
function! s:SyntaxInclude(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:IsHighlightSourcesEnabledForBuffer()
" Enable for markdown buffers, and for liquid buffers with markdown format
return &filetype =~# 'aichat' || get(b:, 'liquid_subtype', '') =~# 'aichat'
endfunction
function! s:MarkdownRefreshSyntax(force)
if g:vim_ai_chat_default['ui']['code_syntax_enabled']
call s:MarkdownHighlightSources(a:force)
endif
endfunction
function! s:MarkdownClearSyntaxVariables()
if exists('b:aichat_included_filetypes')
unlet! b:aichat_included_filetypes
endif
endfunction
augroup Aichat
autocmd BufWinEnter *.aichat call s:MarkdownRefreshSyntax(1)
autocmd BufUnload *.aichat call s:MarkdownClearSyntaxVariables()
autocmd BufWritePost *.aichat call s:MarkdownRefreshSyntax(0)
autocmd InsertEnter,InsertLeave *.aichat call s:MarkdownRefreshSyntax(0)
autocmd CursorHold,CursorHoldI *.aichat call s:MarkdownRefreshSyntax(0)
augroup END
|