xref: /vim-8.2.3635/runtime/ftplugin/julia.vim (revision 6aa57295)
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