1" Vim filetype plugin file 2" Language: Julia 3" Maintainer: Carlo Baldassi <[email protected]> 4" Homepage: https://github.com/JuliaEditorSupport/julia-vim 5" Last Change: 2021 Aug 04 6" adapted from upstream 2021 Aug 4 7 8if exists("b:did_ftplugin") 9 finish 10endif 11let b:did_ftplugin = 1 12 13let s:save_cpo = &cpo 14set cpo-=C 15 16setlocal include=^\\s*\\%(reload\\\|include\\)\\> 17setlocal suffixesadd=.jl 18setlocal comments=:# 19setlocal commentstring=#\ %s 20setlocal cinoptions+=#1 21setlocal define=^\\s*macro\\> 22setlocal fo-=t fo+=croql 23 24let b:julia_vim_loaded = 1 25 26let b:undo_ftplugin = "setlocal include< suffixesadd< comments< commentstring<" 27 \ . " define< fo< shiftwidth< expandtab< indentexpr< indentkeys< cinoptions< completefunc<" 28 \ . " | unlet! b:julia_vim_loaded" 29 30" MatchIt plugin support 31if exists("loaded_matchit") 32 let b:match_ignorecase = 0 33 34 " note: begin_keywords must contain all blocks, in order 35 " for nested-structures-skipping to work properly 36 " note: 'mutable struct' and 'struct' are defined separately because 37 " using \? puts the cursor on 'struct' instead of 'mutable' for some reason 38 let b:julia_begin_keywords = '\%(\.\s*\|@\)\@<!\<\%(function\|macro\|begin\|mutable\s\+struct\|\%(mutable\s\+\)\@<!struct\|\%(abstract\|primitive\)\s\+type\|let\|do\|\%(bare\)\?module\|quote\|if\|for\|while\|try\)\>' 39 " note: the following regex not only recognizes macros, but also local/global keywords. 40 " the purpose is recognizing things like `@inline myfunction()` 41 " or `global myfunction(...)` etc, for matchit and block movement functionality 42 let s:macro_regex = '\%(@\%([#(]\@!\S\)\+\|\<\%(local\|global\)\)\s\+' 43 let s:nomacro = '\%(' . s:macro_regex . '\)\@<!' 44 let s:yesmacro = s:nomacro . '\%('. s:macro_regex . '\)\+' 45 let b:julia_begin_keywordsm = '\%(' . s:yesmacro . b:julia_begin_keywords . '\)\|' 46 \ . '\%(' . s:nomacro . b:julia_begin_keywords . '\)' 47 let b:julia_end_keywords = '\<end\>' 48 49 " note: this function relies heavily on the syntax file 50 function! JuliaGetMatchWords() 51 let [l,c] = [line('.'),col('.')] 52 let attr = synIDattr(synID(l, c, 1),"name") 53 let c1 = c 54 while attr == 'juliaMacro' || expand('<cword>') =~# '\<\%(global\|local\)\>' 55 normal! W 56 if line('.') > l || col('.') == c1 57 call cursor(l, c) 58 return '' 59 endif 60 let attr = synIDattr(synID(l, col('.'), 1),"name") 61 let c1 = col('.') 62 endwhile 63 call cursor(l, c) 64 if attr == 'juliaConditional' 65 return b:julia_begin_keywordsm . ':\<\%(elseif\|else\)\>:' . b:julia_end_keywords 66 elseif attr =~# '\<\%(juliaRepeat\|juliaRepKeyword\)\>' 67 return b:julia_begin_keywordsm . ':\<\%(break\|continue\)\>:' . b:julia_end_keywords 68 elseif attr == 'juliaBlKeyword' 69 return b:julia_begin_keywordsm . ':' . b:julia_end_keywords 70 elseif attr == 'juliaException' 71 return b:julia_begin_keywordsm . ':\<\%(catch\|finally\)\>:' . b:julia_end_keywords 72 endif 73 return '\<\>:\<\>' 74 endfunction 75 76 let b:match_words = 'JuliaGetMatchWords()' 77 78 " we need to skip everything within comments, strings and 79 " the 'begin' and 'end' keywords when they are used as a range rather than as 80 " the delimiter of a block 81 let b:match_skip = 'synIDattr(synID(line("."),col("."),0),"name") =~# ' 82 \ . '"\\<julia\\%(Comprehension\\%(For\\|If\\)\\|RangeKeyword\\|Comment\\%([LM]\\|Delim\\)\\|\\%([bs]\\|Shell\\|Printf\\|Doc\\)\\?String\\|StringPrefixed\\|DocStringM\\(Raw\\)\\?\\|RegEx\\|SymbolS\\?\\|Dotted\\)\\>"' 83 84 let b:undo_ftplugin = b:undo_ftplugin 85 \ . " | unlet! b:match_words b:match_skip b:match_ignorecase" 86 \ . " | unlet! b:julia_begin_keywords b:julia_end_keywords" 87 \ . " | delfunction JuliaGetMatchWords" 88 89endif 90 91let &cpo = s:save_cpo 92unlet s:save_cpo 93