diff --git a/README.md b/README.md index c93d05a..1231d35 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A collection of language packs for Vim. > One to rule them all, one to find them, one to bring them all and in the darkness bind them. - It **won't affect your startup time**, as scripts are loaded only on demand\*. -- It **installs and updates 100+ times faster** than the 132 packages it consists of. +- It **installs and updates 100+ times faster** than the 133 packages it consists of. - Solid syntax and indentation support (other features skipped). Only the best language packs. - All unnecessary files are ignored (like enormous documentation from php support). - No support for esoteric languages, only most popular ones (modern too, like `slim`). @@ -110,6 +110,7 @@ If you need full functionality of any plugin, please use it directly with your p - [lilypond](https://github.com/anowlcalledjosh/vim-lilypond) (syntax, indent, compiler, ftplugin) - [liquid](https://github.com/tpope/vim-liquid) (syntax, indent, ftplugin) - [livescript](https://github.com/gkz/vim-ls) (syntax, indent, compiler, ftplugin) +- [llvm](https://github.com/rhysd/vim-llvm) (syntax, indent, ftplugin) - [lua](https://github.com/tbastos/vim-lua) (syntax, indent) - [mako](https://github.com/sophacles/vim-bundle-mako) (syntax, indent, ftplugin) - [markdown](https://github.com/plasticboy/vim-markdown) (syntax, indent) diff --git a/after/ftplugin/llvm.vim b/after/ftplugin/llvm.vim new file mode 100644 index 0000000..70f196c --- /dev/null +++ b/after/ftplugin/llvm.vim @@ -0,0 +1,477 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'llvm') != -1 + finish +endif + +" Copyright (c) 2018 rhysd +" +" Permission is hereby granted, free of charge, to any person obtaining a copy +" of this software and associated documentation files (the "Software"), to deal +" in the Software without restriction, including without limitation the rights +" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +" copies of the Software, and to permit persons to whom the Software is +" furnished to do so, subject to the following conditions: +" +" The above copyright notice and this permission notice shall be included in +" all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +" THE SOFTWARE. + +if get(g:, 'llvm_extends_official', 1) == 0 + finish +endif + +let g:llvm_ext_no_mapping = get(g:, 'llvm_ext_no_mapping', 0) +let g:llvm_ext_lli_executable = get(g:, 'llvm_ext_lli_executable', 'lli') + +let s:KIND_BLOCK_PREC = 0 +let s:KIND_BLOCK_FOLLOW = 1 +let s:KIND_FUNC_BEGIN = 2 +let s:KIND_FUNC_END = 3 + +function! s:section_delim_at(lnum) abort + let line = getline(a:lnum) + let m = matchlist(line, '^\([^:]\+\):\%( \+; preds = \(%.\+\)\)\=$') + if !empty(m) + if m[2] ==# '' + return [s:KIND_BLOCK_PREC, m[1]] + else + return [s:KIND_BLOCK_FOLLOW, m[1], split(m[2], ',\s*')] + endif + endif + if line =~# '^}$' + return [s:KIND_FUNC_END] + endif + if line =~# '^define\>' + return [s:KIND_FUNC_BEGIN] + endif + return [] +endfunction + +function! s:is_section_delim(line, func_delim) abort + let sec = s:section_delim_at(a:line) + if empty(sec) + return 0 + endif + let kind = sec[0] + return kind == s:KIND_BLOCK_PREC || kind == s:KIND_BLOCK_FOLLOW || kind == func_delim +endfunction + +function! s:next_section(stop_func_begin) abort + let func_delim = a:stop_func_begin ? s:KIND_FUNC_BEGIN : s:KIND_FUNC_END + let last = line('$') - 1 + let line = line('.') + while line < last + let line += 1 + if s:is_section_delim(line, func_delim) + call cursor(line, col('.')) + return + endif + endwhile +endfunction + +function! s:prev_section(stop_func_begin) abort + let func_delim = a:stop_func_begin ? s:KIND_FUNC_BEGIN : s:KIND_FUNC_END + let line = line('.') + while line > 1 + let line -= 1 + if s:is_section_delim(line, func_delim) + call cursor(line, col('.')) + return + endif + endwhile +endfunction + +if !g:llvm_ext_no_mapping + nnoremap ]] :call next_section(1) + nnoremap [[ :call prev_section(1) + nnoremap ][ :call next_section(0) + nnoremap [] :call prev_section(0) +endif + +function! s:function_range_at(linum) abort + let line = a:linum + while line >= 1 + let s = getline(line) + if s =~# '^define\>' + let start = line + break + elseif s =~# '^}$' + return [] + endif + let line -= 1 + endwhile + if line < 1 + return [] + endif + + let line = a:linum + let last = line('$') + while line <= last + let s = getline(line) + if s =~# '^}$' + let end = line + break + elseif s =~# '^define\>' + return [] + endif + let line += 1 + endwhile + if line > last + return [] + endif + + return [start, end] +endfunction + +function! s:blocks_graph_at(linum) abort + let func_range = s:function_range_at(a:linum) + if empty(func_range) + return {} + endif + let line = func_range[0] + 1 + let last = func_range[1] - 1 + let graph = {} + while line <= last + let block = s:section_delim_at(line) + if empty(block) + let line += 1 + continue + endif + let block_name = '%' . block[1] + if block[0] == s:KIND_BLOCK_PREC + let graph[block_name] = {'line': line, 'follows': [], 'preds': []} + elseif block[0] == s:KIND_BLOCK_FOLLOW + let graph[block_name] = {'line': line, 'follows': [], 'preds': block[2]} + for follow in block[2] + call add(graph[follow].follows, block_name) + endfor + else + echoerr 'unreachable' + endif + let line += 1 + endwhile + return graph +endfunction + +function! s:find_pred_block(linum) abort + let sec = s:section_delim_at(a:linum) + if empty(sec) || sec[0] != s:KIND_BLOCK_PREC && sec[0] != s:KIND_BLOCK_FOLLOW + throw 'No block is starting at line ' . a:linum + endif + if sec[0] != s:KIND_BLOCK_FOLLOW + throw printf("Block '%s' has no pred block", sec[1]) + endif + let block_name = '%' . sec[1] + let pred_block = sec[2][0] + + let graph = s:blocks_graph_at(a:linum) + if empty(graph) + throw 'No block is found in function at line ' . a:linum + endif + + if !has_key(graph, pred_block) + throw printf("Block '%s' (pred block of '%s') not found in function", pred_block, block_name) + endif + return graph[pred_block] +endfunction + +function! s:move_to_pred_block() abort + try + let b = s:find_pred_block(line('.')) + call cursor(b.line, col('.')) + catch + echohl ErrorMsg | echom v:exception | echohl None + endtry +endfunction + +function! s:find_following_block(linum) abort + let sec = s:section_delim_at(a:linum) + if empty(sec) || sec[0] != s:KIND_BLOCK_PREC && sec[0] != s:KIND_BLOCK_FOLLOW + throw 'No block is starting at line ' . a:linum + endif + let block_name = '%' . sec[1] + + let graph = s:blocks_graph_at(a:linum) + if empty(graph) + throw 'No block is found in function at line ' . a:linum + endif + + let follows = graph[block_name].follows + if empty(follows) + throw printf("Block '%s' has no following block", block_name) + endif + + echom printf("Block '%s' has %d following blocks: %s", block_name, len(follows), join(follows, ', ')) + + if !has_key(graph, follows[0]) + throw printf("Block '%s' is not defined in function at line %d", follows[0], a:linum) + endif + return graph[follows[0]] +endfunction + +function! s:move_to_following_block() abort + try + let b = s:find_following_block(line('.')) + call cursor(b.line, col('.')) + catch + echohl ErrorMsg | echom v:exception | echohl None + endtry +endfunction + +if !g:llvm_ext_no_mapping + nnoremap [b :call move_to_pred_block() + nnoremap ]b :call move_to_following_block() +endif + +function! s:get_func_identifiers(line) abort + let idx = stridx(a:line, '@') + if idx == -1 + " Invalid signature + return [] + endif + + " e.g. define internal i32 @foo(...) { -> @foo(...) { + let sig = a:line[idx:] + + let idx = stridx(sig, '(') + if idx == -1 + " Invalid signature + return [] + endif + + " @foo(...) { -> @foo + let idents = [sig[:idx-1]] + + " @foo(...) { -> ...) { + let params = sig[idx+1:] + + let idx = strridx(sig, ')') + if idx == -1 + return idents + endif + + " ...) { -> ... + let params = params[:idx-1] + + " Gather parameters in function signature + while params !=# '' + let m = matchlist(params, '^[^%]*\(%\%("[^"]\+"\|[[:alnum:]_.]\+\)\)\s*\(.*\)$') + if empty(m) + break + endif + let idents += [m[1]] + let params = m[2] + endwhile + + return idents +endfunction + +function! s:get_identifiers(line) abort + " Registers and type defs + let m = matchlist(a:line, '^\s*\(%\S\+\)\s\+=') + if !empty(m) + return [m[1]] + endif + + " Constants + let m = matchlist(a:line, '^\(@\S\+\)\s\+=.\+\') + if !empty(m) + return [m[1]] + endif + + " Labels for basic blocks + let m = matchlist(a:line, '^\([^:]\+\):\%(\s\+; preds = .\+\)\=$') + if !empty(m) + return ['%' . m[1]] + endif + + " Meta variables + let m = matchlist(a:line, '^\(!\S\+\)\s\+=') + if !empty(m) + return [m[1]] + endif + + " Attributes + let m = matchlist(a:line, '^attributes\s\+\(#\d\+\)\s\+=') + if !empty(m) + return [m[1]] + endif + + if a:line =~# '^\%(declare\|define\)\>' + return s:get_func_identifiers(a:line) + endif + + return [] +endfunction + +function! s:extract_identifier(word) abort + if strlen(a:word) <= 1 + return '' + endif + + let prefix = a:word[0] + if prefix ==# '@' || prefix ==# '%' || prefix ==# '!' + if prefix ==# '!' && a:word[1] ==# '{' + return '' + endif + + if a:word[1] == '"' + let idx = stridx(a:word, '"', 2) + if idx == -1 + return '' + endif + " @"foo" or %"foo" + return a:word[:idx] + else + " @foo or %foo + return matchstr(a:word, '^[@%!][[:alnum:]_.]\+') + endif + endif + + if prefix ==# '#' + return matchstr(a:word, '^#\d\+') + endif + + return '' +endfunction + +function! s:jump_to_identifier_at(linum, ident) abort + let line = getline(a:linum) + let column = stridx(line, a:ident) + 1 + if column == 0 + let column = col('.') + endif + call cursor(a:linum, column) +endfunction + +function! s:browser_open_command() abort + if exists('g:llvm_ext_browser_open_command') + return g:llvm_ext_browser_open_command + endif + if exists('s:browser_opener') + return s:browser_opener + endif + let s:browser_opener = '' + if has('mac') + let s:browser_opener = 'open' + elseif has('win32') || has('win64') + let s:browser_opener = 'cmd /q /c start ""' + else + for cmd in ['xdg-open', 'chromium', 'google-chrome', 'firefox'] + if executable(cmd) + let s:browser_opener = cmd + break + endif + endfor + endif + return s:browser_opener +endfunction + +function! s:open_browser(url) abort + let cmd = s:browser_open_command() + if cmd ==# '' + throw "Failed to open a browser. I don't know how to open a browser: Please set g:llvm_ext_browser_open_command" + endif + let cmdline = cmd . ' ' . shellescape(a:url) + let out = system(cmdline) + if v:shell_error + throw printf("Failed to open a browser with command '%s': %s", cmdline, out) + endif +endfunction + +function! s:goto_definition() abort + " Open language reference manual under the cursor in browser + let syn_name = synIDattr(synID(line('.'),col('.'),1),'name') + if syn_name ==# 'llvmStatement' + let word = expand('') + if word !=# '' + try + " Open browser assuming a word under the cursor is an instruction + call s:open_browser('https://llvm.org/docs/LangRef.html#' . word . '-instruction') + catch /^Failed to open a browser/ + echohl ErrorMsg | echom v:exception | echohl None + endtry + endif + return + endif + + " XXX: This does not support identifiers which contains spaces + let word = expand('') + if word ==# '' + echom 'No identifier found under the cursor' + return + endif + let ident = s:extract_identifier(word) + if ident ==# '' + echom 'No identifier found under the cursor' + return + endif + + " Definition tends to be near its usages. Look back at first. + let line = line('.') + while line > 0 + for found in s:get_identifiers(getline(line)) + if ident ==# found + call s:jump_to_identifier_at(line, ident) + return + endif + endfor + let line -= 1 + endwhile + + let line = line('.') + 1 + let last = line('$') + while line <= last + for found in s:get_identifiers(getline(line)) + if ident ==# found + call s:jump_to_identifier_at(line, ident) + return + endif + endfor + let line += 1 + endwhile + + echom "No definition for '" . ident . "' found" +endfunction + +if !g:llvm_ext_no_mapping + nnoremap K :call goto_definition() +endif + +function! s:run_lli(...) abort + if !has('job') || !has('channel') || !has('terminal') + echohl ErrorMsg + echomsg ':LLI requires terminal feature. Please update your Vim to 8.0+' + echohl None + return + endif + + if !executable(g:llvm_ext_lli_executable) + echohl ErrorMsg + echomsg g:llvm_ext_lli_executable . ' is not executable. Please set g:llvm_ext_lli_executable' + echohl None + return + endif + + if a:0 > 0 + let bufnr = term_start([g:llvm_ext_lli_executable, a:1]) + echo 'Run lli in termnal buffer(' . bufnr . ')' + return + endif + + let tmpfile = tempname() + call writefile(getline(1, '$'), tmpfile) + let Cleanup = {ch -> filereadable(tmpfile) ? delete(tmpfile) : 0} + let bufnr = term_start([g:llvm_ext_lli_executable, tmpfile], {'close_cb': Cleanup, 'exit_cb': Cleanup}) + echo 'Run lli in termnal buffer(' . bufnr . ')' +endfunction + +if !exists(':LLI') + command! -buffer -nargs=? -bar -complete=file LLI call run_lli() +endif diff --git a/after/syntax/llvm.vim b/after/syntax/llvm.vim new file mode 100644 index 0000000..aae8711 --- /dev/null +++ b/after/syntax/llvm.vim @@ -0,0 +1,26 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'llvm') != -1 + finish +endif + +" Copyright (c) 2018 rhysd +" +" Permission is hereby granted, free of charge, to any person obtaining a copy +" of this software and associated documentation files (the "Software"), to deal +" in the Software without restriction, including without limitation the rights +" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +" copies of the Software, and to permit persons to whom the Software is +" furnished to do so, subject to the following conditions: +" +" The above copyright notice and this permission notice shall be included in +" all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +" THE SOFTWARE. + +syn keyword llvmKeyword attributes +syn match llvmNoName /#\d\+\>/ diff --git a/build b/build index b928804..e34a48b 100755 --- a/build +++ b/build @@ -218,6 +218,7 @@ PACKS=" liquid:tpope/vim-liquid lilypond:anowlcalledjosh/vim-lilypond livescript:gkz/vim-ls + llvm:rhysd/vim-llvm lua:tbastos/vim-lua mako:sophacles/vim-bundle-mako markdown:plasticboy/vim-markdown:_SYNTAX diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index f1fc496..37fc555 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -714,6 +714,27 @@ autocmd BufNewFile,BufRead *Slakefile set filetype=ls augroup end endif +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'llvm') == -1 + augroup filetypedetect + " llvm, from llvm-lit.vim in rhysd/vim-llvm +au BufRead,BufNewFile lit.*cfg set filetype=python + augroup end +endif + +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'llvm') == -1 + augroup filetypedetect + " llvm, from llvm.vim in rhysd/vim-llvm +au BufRead,BufNewFile *.ll set filetype=llvm + augroup end +endif + +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'llvm') == -1 + augroup filetypedetect + " llvm, from tablegen.vim in rhysd/vim-llvm +au BufRead,BufNewFile *.td set filetype=tablegen + augroup end +endif + if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mako') == -1 augroup filetypedetect " mako, from mako.vim in sophacles/vim-bundle-mako diff --git a/ftplugin/llvm.vim b/ftplugin/llvm.vim new file mode 100644 index 0000000..0006c28 --- /dev/null +++ b/ftplugin/llvm.vim @@ -0,0 +1,16 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'llvm') != -1 + finish +endif + +" Vim filetype plugin file +" Language: LLVM Assembly +" Maintainer: The LLVM team, http://llvm.org/ + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +setlocal softtabstop=2 shiftwidth=2 +setlocal expandtab +setlocal comments+=:; diff --git a/ftplugin/tablegen.vim b/ftplugin/tablegen.vim new file mode 100644 index 0000000..94909ef --- /dev/null +++ b/ftplugin/tablegen.vim @@ -0,0 +1,16 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'llvm') != -1 + finish +endif + +" Vim filetype plugin file +" Language: LLVM TableGen +" Maintainer: The LLVM team, http://llvm.org/ + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +setlocal matchpairs+=<:> +setlocal softtabstop=2 shiftwidth=2 +setlocal expandtab diff --git a/indent/llvm.vim b/indent/llvm.vim new file mode 100644 index 0000000..90829c2 --- /dev/null +++ b/indent/llvm.vim @@ -0,0 +1,76 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'llvm') != -1 + finish +endif + +" Vim indent file +" Language: llvm +" Maintainer: The LLVM team, http://llvm.org/ +" What this indent plugin currently does: +" - If no other rule matches copy indent from previous non-empty, +" non-commented line +" - On '}' align the same as the line containing the matching '{' +" - If previous line ends with ':' increase indentation +" - If the current line ends with ':' indent at the same level as the +" enclosing '{'/'}' block +" Stuff that would be nice to add: +" - Continue comments on next line +" - If there is an opening+unclosed parenthesis on previous line indent to that +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal shiftwidth=2 expandtab + +setlocal indentkeys=0{,0},<:>,!^F,o,O,e +setlocal indentexpr=GetLLVMIndent() + +if exists("*GetLLVMIndent") + finish +endif + +function! FindOpenBrace(lnum) + call cursor(a:lnum, 1) + return searchpair('{', '', '}', 'bW') +endfun + +function! GetLLVMIndent() + " On '}' align the same as the line containing the matching '{' + let thisline = getline(v:lnum) + if thisline =~ '^\s*}' + call cursor(v:lnum, 1) + silent normal % + let opening_lnum = line('.') + if opening_lnum != v:lnum + return indent(opening_lnum) + endif + endif + + " Indent labels the same as the current opening block + if thisline =~ ':\s*$' + let blockbegin = FindOpenBrace(v:lnum) + if blockbegin > 0 + return indent(blockbegin) + endif + endif + + " Find a non-blank not-completely commented line above the current line. + let prev_lnum = prevnonblank(v:lnum - 1) + while prev_lnum > 0 && synIDattr(synID(prev_lnum, indent(prev_lnum)+1, 0), "name") =? "string\|comment" + let prev_lnum = prevnonblank(prev_lnum-1) + endwhile + " Hit the start of the file, use zero indent. + if prev_lnum == 0 + return 0 + endif + + let ind = indent(prev_lnum) + let prevline = getline(prev_lnum) + + " Add a 'shiftwidth' after lines that start a block or labels + if prevline =~ '{\s*$' || prevline =~ ':\s*$' + let ind = ind + &shiftwidth + endif + + return ind +endfunction diff --git a/syntax/llvm.vim b/syntax/llvm.vim new file mode 100644 index 0000000..87202ed --- /dev/null +++ b/syntax/llvm.vim @@ -0,0 +1,237 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'llvm') != -1 + finish +endif + +" Vim syntax file +" Language: llvm +" Maintainer: The LLVM team, http://llvm.org/ +" Version: $Revision$ + +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +syn case match + +" Types. +" Types also include struct, array, vector, etc. but these don't +" benefit as much from having dedicated highlighting rules. +syn keyword llvmType void half float double x86_fp80 fp128 ppc_fp128 +syn keyword llvmType label metadata x86_mmx +syn keyword llvmType type label opaque token +syn match llvmType /\/ + +" Instructions. +" The true and false tokens can be used for comparison opcodes, but it's +" much more common for these tokens to be used for boolean constants. +syn keyword llvmStatement add addrspacecast alloca and arcp ashr atomicrmw +syn keyword llvmStatement bitcast br catchpad catchswitch catchret call +syn keyword llvmStatement cleanuppad cleanupret cmpxchg eq exact extractelement +syn keyword llvmStatement extractvalue fadd fast fcmp fdiv fence fmul fpext +syn keyword llvmStatement fptosi fptoui fptrunc free frem fsub getelementptr +syn keyword llvmStatement icmp inbounds indirectbr insertelement insertvalue +syn keyword llvmStatement inttoptr invoke landingpad load lshr malloc max min +syn keyword llvmStatement mul nand ne ninf nnan nsw nsz nuw oeq oge ogt ole +syn keyword llvmStatement olt one or ord phi ptrtoint resume ret sdiv select +syn keyword llvmStatement sext sge sgt shl shufflevector sitofp sle slt srem +syn keyword llvmStatement store sub switch trunc udiv ueq uge ugt uitofp ule ult +syn keyword llvmStatement umax umin une uno unreachable unwind urem va_arg +syn keyword llvmStatement xchg xor zext + +" Keywords. +syn keyword llvmKeyword + \ acq_rel + \ acquire + \ addrspace + \ alias + \ align + \ alignstack + \ alwaysinline + \ appending + \ argmemonly + \ arm_aapcscc + \ arm_aapcs_vfpcc + \ arm_apcscc + \ asm + \ atomic + \ available_externally + \ blockaddress + \ builtin + \ byval + \ c + \ catch + \ caller + \ cc + \ ccc + \ cleanup + \ coldcc + \ comdat + \ common + \ constant + \ datalayout + \ declare + \ default + \ define + \ deplibs + \ dereferenceable + \ distinct + \ dllexport + \ dllimport + \ dso_local + \ dso_preemptable + \ except + \ external + \ externally_initialized + \ extern_weak + \ fastcc + \ filter + \ from + \ gc + \ global + \ hhvmcc + \ hhvm_ccc + \ hidden + \ initialexec + \ inlinehint + \ inreg + \ inteldialect + \ intel_ocl_bicc + \ internal + \ linkonce + \ linkonce_odr + \ localdynamic + \ localexec + \ local_unnamed_addr + \ minsize + \ module + \ monotonic + \ msp430_intrcc + \ musttail + \ naked + \ nest + \ noalias + \ nobuiltin + \ nocapture + \ noimplicitfloat + \ noinline + \ nonlazybind + \ nonnull + \ norecurse + \ noredzone + \ noreturn + \ nounwind + \ optnone + \ optsize + \ personality + \ private + \ protected + \ ptx_device + \ ptx_kernel + \ readnone + \ readonly + \ release + \ returned + \ returns_twice + \ sanitize_address + \ sanitize_memory + \ sanitize_thread + \ section + \ seq_cst + \ sideeffect + \ signext + \ syncscope + \ source_filename + \ speculatable + \ spir_func + \ spir_kernel + \ sret + \ ssp + \ sspreq + \ sspstrong + \ strictfp + \ swiftcc + \ tail + \ target + \ thread_local + \ to + \ triple + \ unnamed_addr + \ unordered + \ uselistorder + \ uselistorder_bb + \ uwtable + \ volatile + \ weak + \ weak_odr + \ within + \ writeonly + \ x86_64_sysvcc + \ win64cc + \ x86_fastcallcc + \ x86_stdcallcc + \ x86_thiscallcc + \ zeroext + +" Obsolete keywords. +syn keyword llvmError getresult begin end + +" Misc syntax. +syn match llvmNoName /[%@!]\d\+\>/ +syn match llvmNumber /-\?\<\d\+\>/ +syn match llvmFloat /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/ +syn match llvmFloat /\<0x\x\+\>/ +syn keyword llvmBoolean true false +syn keyword llvmConstant zeroinitializer undef null none +syn match llvmComment /;.*$/ +syn region llvmString start=/"/ skip=/\\"/ end=/"/ +syn match llvmLabel /[-a-zA-Z$._][-a-zA-Z$._0-9]*:/ +syn match llvmIdentifier /[%@][-a-zA-Z$._][-a-zA-Z$._0-9]*/ + +" Named metadata and specialized metadata keywords. +syn match llvmIdentifier /![-a-zA-Z$._][-a-zA-Z$._0-9]*\ze\s*$/ +syn match llvmIdentifier /![-a-zA-Z$._][-a-zA-Z$._0-9]*\ze\s*[=!]/ +syn match llvmType /!\zs\a\+\ze\s*(/ +syn match llvmConstant /\/ +syn match llvmConstant /\/ +syn match llvmConstant /\/ +syn match llvmConstant /\/ +syn match llvmConstant /\/ +syn match llvmConstant /\/ + +" Syntax-highlight lit test commands and bug numbers. +syn match llvmSpecialComment /;\s*PR\d*\s*$/ +syn match llvmSpecialComment /;\s*REQUIRES:.*$/ +syn match llvmSpecialComment /;\s*RUN:.*$/ +syn match llvmSpecialComment /;\s*CHECK:.*$/ +syn match llvmSpecialComment "\v;\s*CHECK-(NEXT|NOT|DAG|SAME|LABEL):.*$" +syn match llvmSpecialComment /;\s*XFAIL:.*$/ + +if version >= 508 || !exists("did_c_syn_inits") + if version < 508 + let did_c_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + HiLink llvmType Type + HiLink llvmStatement Statement + HiLink llvmNumber Number + HiLink llvmComment Comment + HiLink llvmString String + HiLink llvmLabel Label + HiLink llvmKeyword Keyword + HiLink llvmBoolean Boolean + HiLink llvmFloat Float + HiLink llvmNoName Identifier + HiLink llvmConstant Constant + HiLink llvmSpecialComment SpecialComment + HiLink llvmError Error + HiLink llvmIdentifier Identifier + + delcommand HiLink +endif + +let b:current_syntax = "llvm" diff --git a/syntax/tablegen.vim b/syntax/tablegen.vim new file mode 100644 index 0000000..8dd1c59 --- /dev/null +++ b/syntax/tablegen.vim @@ -0,0 +1,58 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'llvm') != -1 + finish +endif + +" Vim syntax file +" Language: TableGen +" Maintainer: The LLVM team, http://llvm.org/ +" Version: $Revision$ + +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" May be changed if you have a really slow machine +syntax sync minlines=100 + +syn case match + +syn keyword tgKeyword def let in code dag field include defm foreach +syn keyword tgType class int string list bit bits multiclass + +syn match tgNumber /\<\d\+\>/ +syn match tgNumber /\<\d\+\.\d*\>/ +syn match tgNumber /\<0b[01]\+\>/ +syn match tgNumber /\<0x[0-9a-fA-F]\+\>/ +syn region tgString start=/"/ skip=/\\"/ end=/"/ oneline + +syn region tgCode start=/\[{/ end=/}\]/ + +syn keyword tgTodo contained TODO FIXME +syn match tgComment /\/\/.*$/ contains=tgTodo +" Handle correctly imbricated comment +syn region tgComment2 matchgroup=tgComment2 start=+/\*+ end=+\*/+ contains=tgTodo,tgComment2 + +if version >= 508 || !exists("did_c_syn_inits") + if version < 508 + let did_c_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + HiLink tgKeyword Statement + HiLink tgType Type + HiLink tgNumber Number + HiLink tgComment Comment + HiLink tgComment2 Comment + HiLink tgString String + " May find a better Hilight group... + HiLink tgCode Special + HiLink tgTodo Todo + + delcommand HiLink +endif + +let b:current_syntax = "tablegen"