aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
authorChristian Clason <c.clason@uni-graz.at>2021-08-08 23:50:28 +0200
committerChristian Clason <c.clason@uni-graz.at>2021-08-15 11:02:19 +0200
commit65f32f0f195fbf7df2478f31cab345d00a6673a4 (patch)
tree0859bb74f761aa2c0acb32bae805a744cb3128ec /runtime
parent0dc4bec69e3b275d9667c6928f15b0e8a01bd0fa (diff)
downloadrneovim-65f32f0f195fbf7df2478f31cab345d00a6673a4.tar.gz
rneovim-65f32f0f195fbf7df2478f31cab345d00a6673a4.tar.bz2
rneovim-65f32f0f195fbf7df2478f31cab345d00a6673a4.zip
vim-patch:6aa5729
Add Julia runtime files. https://github.com/vim/vim/commit/6aa57295cfbe8f21c15f0671e45fd53cf990d404
Diffstat (limited to 'runtime')
-rw-r--r--runtime/ftplugin/julia.vim92
-rw-r--r--runtime/indent/julia.vim491
-rw-r--r--runtime/syntax/julia.vim550
3 files changed, 1133 insertions, 0 deletions
diff --git a/runtime/ftplugin/julia.vim b/runtime/ftplugin/julia.vim
new file mode 100644
index 0000000000..32e364e436
--- /dev/null
+++ b/runtime/ftplugin/julia.vim
@@ -0,0 +1,92 @@
+" Vim filetype plugin file
+" Language: Julia
+" Maintainer: Carlo Baldassi <carlobaldassi@gmail.com>
+" Homepage: https://github.com/JuliaEditorSupport/julia-vim
+" Last Change: 2014 may 29
+" adapted from upstream 2021 Aug 4
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+
+let s:save_cpo = &cpo
+set cpo-=C
+
+setlocal include=^\\s*\\%(reload\\\|include\\)\\>
+setlocal suffixesadd=.jl
+setlocal comments=:#
+setlocal commentstring=#\ %s
+setlocal cinoptions+=#1
+setlocal define=^\\s*macro\\>
+setlocal fo-=t fo+=croql
+
+let b:julia_vim_loaded = 1
+
+let b:undo_ftplugin = "setlocal include< suffixesadd< comments< commentstring<"
+ \ . " define< fo< shiftwidth< expandtab< indentexpr< indentkeys< cinoptions< completefunc<"
+ \ . " | unlet! b:julia_vim_loaded"
+
+" MatchIt plugin support
+if exists("loaded_matchit")
+ let b:match_ignorecase = 0
+
+ " note: begin_keywords must contain all blocks, in order
+ " for nested-structures-skipping to work properly
+ " note: 'mutable struct' and 'struct' are defined separately because
+ " using \? puts the cursor on 'struct' instead of 'mutable' for some reason
+ 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\)\>'
+ " note: the following regex not only recognizes macros, but also local/global keywords.
+ " the purpose is recognizing things like `@inline myfunction()`
+ " or `global myfunction(...)` etc, for matchit and block movement functionality
+ let s:macro_regex = '\%(@\%([#(]\@!\S\)\+\|\<\%(local\|global\)\)\s\+'
+ let s:nomacro = '\%(' . s:macro_regex . '\)\@<!'
+ let s:yesmacro = s:nomacro . '\%('. s:macro_regex . '\)\+'
+ let b:julia_begin_keywordsm = '\%(' . s:yesmacro . b:julia_begin_keywords . '\)\|'
+ \ . '\%(' . s:nomacro . b:julia_begin_keywords . '\)'
+ let b:julia_end_keywords = '\<end\>'
+
+ " note: this function relies heavily on the syntax file
+ function! JuliaGetMatchWords()
+ let [l,c] = [line('.'),col('.')]
+ let attr = synIDattr(synID(l, c, 1),"name")
+ let c1 = c
+ while attr == 'juliaMacro' || expand('<cword>') =~# '\<\%(global\|local\)\>'
+ normal! W
+ if line('.') > l || col('.') == c1
+ call cursor(l, c)
+ return ''
+ endif
+ let attr = synIDattr(synID(l, col('.'), 1),"name")
+ let c1 = col('.')
+ endwhile
+ call cursor(l, c)
+ if attr == 'juliaConditional'
+ return b:julia_begin_keywordsm . ':\<\%(elseif\|else\)\>:' . b:julia_end_keywords
+ elseif attr =~# '\<\%(juliaRepeat\|juliaRepKeyword\)\>'
+ return b:julia_begin_keywordsm . ':\<\%(break\|continue\)\>:' . b:julia_end_keywords
+ elseif attr == 'juliaBlKeyword'
+ return b:julia_begin_keywordsm . ':' . b:julia_end_keywords
+ elseif attr == 'juliaException'
+ return b:julia_begin_keywordsm . ':\<\%(catch\|finally\)\>:' . b:julia_end_keywords
+ endif
+ return '\<\>:\<\>'
+ endfunction
+
+ let b:match_words = 'JuliaGetMatchWords()'
+
+ " we need to skip everything within comments, strings and
+ " the 'begin' and 'end' keywords when they are used as a range rather than as
+ " the delimiter of a block
+ let b:match_skip = 'synIDattr(synID(line("."),col("."),0),"name") =~# '
+ \ . '"\\<julia\\%(Comprehension\\%(For\\|If\\)\\|RangeKeyword\\|Comment\\%([LM]\\|Delim\\)\\|\\%([bs]\\|Shell\\|Printf\\|Doc\\)\\?String\\|StringPrefixed\\|DocStringM\\(Raw\\)\\?\\|RegEx\\|SymbolS\\?\\|Dotted\\)\\>"'
+
+ let b:undo_ftplugin = b:undo_ftplugin
+ \ . " | unlet! b:match_words b:match_skip b:match_ignorecase"
+ \ . " | unlet! b:julia_begin_keywords b:julia_end_keywords"
+ \ . " | delfunction JuliaGetMatchWords"
+
+endif
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
diff --git a/runtime/indent/julia.vim b/runtime/indent/julia.vim
new file mode 100644
index 0000000000..a90cff49e4
--- /dev/null
+++ b/runtime/indent/julia.vim
@@ -0,0 +1,491 @@
+" Vim indent file
+" Language: Julia
+" Maintainer: Carlo Baldassi <carlobaldassi@gmail.com>
+" Homepage: https://github.com/JuliaEditorSupport/julia-vim
+" Last Change: 2016 jun 16
+" Notes: originally based on Bram Molenaar's indent file for vim
+
+setlocal autoindent
+
+setlocal indentexpr=GetJuliaIndent()
+setlocal indentkeys+==end,=else,=catch,=finally,),],}
+setlocal indentkeys-=0#
+setlocal indentkeys-=:
+setlocal indentkeys-=0{
+setlocal indentkeys-=0}
+setlocal nosmartindent
+
+" Only define the function once.
+if exists("*GetJuliaIndent")
+ finish
+endif
+
+let s:skipPatternsBasic = '\<julia\%(Comment\%([LM]\|Delim\)\)\>'
+let s:skipPatterns = '\<julia\%(Comprehension\%(For\|If\)\|RangeKeyword\|Comment\%([LM]\|Delim\)\|\%([bs]\|Shell\|Printf\|Doc\)\?String\|StringPrefixed\|DocStringM\(Raw\)\?\|RegEx\|SymbolS\?\|Macro\|Dotted\)\>'
+
+function JuliaMatch(lnum, str, regex, st, ...)
+ let s = a:st
+ let e = a:0 > 0 ? a:1 : -1
+ let basic_skip = a:0 > 1 ? a:2 : 'all'
+ let skip = basic_skip ==# 'basic' ? s:skipPatternsBasic : s:skipPatterns
+ while 1
+ let f = match(a:str, '\C' . a:regex, s)
+ if e >= 0 && f >= e
+ return -1
+ endif
+ if f >= 0
+ let attr = synIDattr(synID(a:lnum,f+1,1),"name")
+ let attrT = synIDattr(synID(a:lnum,f+1,0),"name")
+ if attr =~# skip || attrT =~# skip
+ let s = f+1
+ continue
+ endif
+ endif
+ break
+ endwhile
+ return f
+endfunction
+
+function GetJuliaNestingStruct(lnum, ...)
+ " Auxiliary function to inspect the block structure of a line
+ let line = getline(a:lnum)
+ let s = a:0 > 0 ? a:1 : 0
+ let e = a:0 > 1 ? a:2 : -1
+ let blocks_stack = []
+ let num_closed_blocks = 0
+ while 1
+ let fb = JuliaMatch(a:lnum, line, '\<\%(if\|else\%(if\)\?\|while\|for\|try\|catch\|finally\|\%(staged\)\?function\|macro\|begin\|mutable\s\+struct\|\%(mutable\s\+\)\@<!struct\|\%(abstract\|primitive\)\s\+type\|let\|\%(bare\)\?module\|quote\|do\)\>', s, e)
+ let fe = JuliaMatch(a:lnum, line, '\<end\>', s, e)
+
+ if fb < 0 && fe < 0
+ " No blocks found
+ break
+ end
+
+ if fb >= 0 && (fb < fe || fe < 0)
+ " The first occurrence is an opening block keyword
+ " Note: some keywords (elseif,else,catch,finally) are both
+ " closing blocks and opening new ones
+
+ let i = JuliaMatch(a:lnum, line, '\<if\>', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ call add(blocks_stack, 'if')
+ continue
+ endif
+ let i = JuliaMatch(a:lnum, line, '\<elseif\>', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ if len(blocks_stack) > 0 && blocks_stack[-1] == 'if'
+ let blocks_stack[-1] = 'elseif'
+ elseif (len(blocks_stack) > 0 && blocks_stack[-1] != 'elseif') || len(blocks_stack) == 0
+ call add(blocks_stack, 'elseif')
+ let num_closed_blocks += 1
+ endif
+ continue
+ endif
+ let i = JuliaMatch(a:lnum, line, '\<else\>', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ if len(blocks_stack) > 0 && blocks_stack[-1] =~# '\<\%(else\)\=if\>'
+ let blocks_stack[-1] = 'else'
+ else
+ call add(blocks_stack, 'else')
+ let num_closed_blocks += 1
+ endif
+ continue
+ endif
+
+ let i = JuliaMatch(a:lnum, line, '\<try\>', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ call add(blocks_stack, 'try')
+ continue
+ endif
+ let i = JuliaMatch(a:lnum, line, '\<catch\>', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ if len(blocks_stack) > 0 && blocks_stack[-1] == 'try'
+ let blocks_stack[-1] = 'catch'
+ else
+ call add(blocks_stack, 'catch')
+ let num_closed_blocks += 1
+ endif
+ continue
+ endif
+ let i = JuliaMatch(a:lnum, line, '\<finally\>', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ if len(blocks_stack) > 0 && (blocks_stack[-1] == 'try' || blocks_stack[-1] == 'catch')
+ let blocks_stack[-1] = 'finally'
+ else
+ call add(blocks_stack, 'finally')
+ let num_closed_blocks += 1
+ endif
+ continue
+ endif
+
+ let i = JuliaMatch(a:lnum, line, '\<\%(bare\)\?module\>', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ if i == 0
+ call add(blocks_stack, 'col1module')
+ else
+ call add(blocks_stack, 'other')
+ endif
+ continue
+ endif
+
+ let i = JuliaMatch(a:lnum, line, '\<\%(while\|for\|function\|macro\|begin\|\%(mutable\s\+\)\?struct\|\%(abstract\|primitive\)\s\+type\|let\|quote\|do\)\>', s)
+ if i >= 0 && i == fb
+ if match(line, '\C\<\%(mutable\|abstract\|primitive\)', i) != -1
+ let s = i+11
+ else
+ let s = i+1
+ endif
+ call add(blocks_stack, 'other')
+ continue
+ endif
+
+ " Note: it should be impossible to get here
+ break
+
+ else
+ " The first occurrence is an 'end'
+
+ let s = fe+1
+ if len(blocks_stack) == 0
+ let num_closed_blocks += 1
+ else
+ call remove(blocks_stack, -1)
+ endif
+ continue
+
+ endif
+
+ " Note: it should be impossible to get here
+ break
+ endwhile
+ let num_open_blocks = len(blocks_stack) - count(blocks_stack, 'col1module')
+ return [num_open_blocks, num_closed_blocks]
+endfunction
+
+function GetJuliaNestingBrackets(lnum, c)
+ " Auxiliary function to inspect the brackets structure of a line
+ let line = getline(a:lnum)[0 : (a:c - 1)]
+ let s = 0
+ let brackets_stack = []
+ let last_closed_bracket = -1
+ while 1
+ let fb = JuliaMatch(a:lnum, line, '[([{]', s)
+ let fe = JuliaMatch(a:lnum, line, '[])}]', s)
+
+ if fb < 0 && fe < 0
+ " No brackets found
+ break
+ end
+
+ if fb >= 0 && (fb < fe || fe < 0)
+ " The first occurrence is an opening bracket
+
+ let i = JuliaMatch(a:lnum, line, '(', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ call add(brackets_stack, ['par',i])
+ continue
+ endif
+
+ let i = JuliaMatch(a:lnum, line, '\[', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ call add(brackets_stack, ['sqbra',i])
+ continue
+ endif
+
+ let i = JuliaMatch(a:lnum, line, '{', s)
+ if i >= 0 && i == fb
+ let s = i+1
+ call add(brackets_stack, ['curbra',i])
+ continue
+ endif
+
+ " Note: it should be impossible to get here
+ break
+
+ else
+ " The first occurrence is a closing bracket
+
+ let i = JuliaMatch(a:lnum, line, ')', s)
+ if i >= 0 && i == fe
+ let s = i+1
+ if len(brackets_stack) > 0 && brackets_stack[-1][0] == 'par'
+ call remove(brackets_stack, -1)
+ else
+ let last_closed_bracket = i + 1
+ endif
+ continue
+ endif
+
+ let i = JuliaMatch(a:lnum, line, ']', s)
+ if i >= 0 && i == fe
+ let s = i+1
+ if len(brackets_stack) > 0 && brackets_stack[-1][0] == 'sqbra'
+ call remove(brackets_stack, -1)
+ else
+ let last_closed_bracket = i + 1
+ endif
+ continue
+ endif
+
+ let i = JuliaMatch(a:lnum, line, '}', s)
+ if i >= 0 && i == fe
+ let s = i+1
+ if len(brackets_stack) > 0 && brackets_stack[-1][0] == 'curbra'
+ call remove(brackets_stack, -1)
+ else
+ let last_closed_bracket = i + 1
+ endif
+ continue
+ endif
+
+ " Note: it should be impossible to get here
+ break
+
+ endif
+
+ " Note: it should be impossible to get here
+ break
+ endwhile
+ let first_open_bracket = -1
+ let last_open_bracket = -1
+ let infuncargs = 0
+ if len(brackets_stack) > 0
+ let first_open_bracket = brackets_stack[0][1]
+ let last_open_bracket = brackets_stack[-1][1]
+ if brackets_stack[-1][0] == 'par' && IsFunctionArgPar(a:lnum, last_open_bracket+1)
+ let infuncargs = 1
+ endif
+ endif
+ return [first_open_bracket, last_open_bracket, last_closed_bracket, infuncargs]
+endfunction
+
+let s:bracketBlocks = '\<julia\%(\%(\%(Printf\)\?Par\|SqBra\%(Idx\)\?\|CurBra\)Block\|ParBlockInRange\|StringVars\%(Par\|SqBra\|CurBra\)\|Dollar\%(Par\|SqBra\)\|QuotedParBlockS\?\)\>'
+
+function IsInBrackets(lnum, c)
+ let stack = map(synstack(a:lnum, a:c), 'synIDattr(v:val, "name")')
+ call filter(stack, 'v:val =~# s:bracketBlocks')
+ return len(stack) > 0
+endfunction
+
+function IsInDocString(lnum)
+ let stack = map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")')
+ call filter(stack, 'v:val =~# "\\<juliaDocString\\(Delim\\|M\\\(Raw\\)\\?\\)\\?\\>"')
+ return len(stack) > 0
+endfunction
+
+function IsInContinuationImportLine(lnum)
+ let stack = map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")')
+ call filter(stack, 'v:val =~# "\\<juliaImportLine\\>"')
+ if len(stack) == 0
+ return 0
+ endif
+ return JuliaMatch(a:lnum, getline(a:lnum), '\<\%(import\|using\|export\)\>', indent(a:lnum)) == -1
+endfunction
+
+function IsFunctionArgPar(lnum, c)
+ if a:c == 0
+ return 0
+ endif
+ let stack = map(synstack(a:lnum, a:c-1), 'synIDattr(v:val, "name")')
+ return len(stack) >= 2 && stack[-2] ==# 'juliaFunctionDef'
+endfunction
+
+function JumpToMatch(lnum, last_closed_bracket)
+ " we use the % command to skip back (tries to ues matchit if possible,
+ " otherwise resorts to vim's default, which is buggy but better than
+ " nothing)
+ call cursor(a:lnum, a:last_closed_bracket)
+ let percmap = maparg("%", "n")
+ if exists("g:loaded_matchit") && percmap =~# 'Match\%(it\|_wrapper\)'
+ normal %
+ else
+ normal! %
+ end
+endfunction
+
+" Auxiliary function to find a line which does not start in the middle of a
+" multiline bracketed expression, to be used as reference for block
+" indentation.
+function LastBlockIndent(lnum)
+ let lnum = a:lnum
+ let ind = 0
+ while lnum > 0
+ let ind = indent(lnum)
+ if ind == 0
+ return [lnum, 0]
+ endif
+ if !IsInBrackets(lnum, 1)
+ break
+ endif
+ let lnum = prevnonblank(lnum - 1)
+ endwhile
+ return [max([lnum,1]), ind]
+endfunction
+
+function GetJuliaIndent()
+ " Do not alter doctrings indentation
+ if IsInDocString(v:lnum)
+ return -1
+ endif
+
+ " Find a non-blank line above the current line.
+ let lnum = prevnonblank(v:lnum - 1)
+
+ " At the start of the file use zero indent.
+ if lnum == 0
+ return 0
+ endif
+
+ let ind = -1
+ let st = -1
+ let lim = -1
+
+ " Multiline bracketed expressions take precedence
+ let align_brackets = get(g:, "julia_indent_align_brackets", 1)
+ let align_funcargs = get(g:, "julia_indent_align_funcargs", 0)
+ let c = len(getline(lnum)) + 1
+ while IsInBrackets(lnum, c)
+ let [first_open_bracket, last_open_bracket, last_closed_bracket, infuncargs] = GetJuliaNestingBrackets(lnum, c)
+
+ " First scenario: the previous line has a hanging open bracket:
+ " set the indentation to match the opening bracket (plus an extra space)
+ " unless we're in a function arguments list or alignment is disabled, in
+ " which case we just add an extra indent
+ if last_open_bracket != -1
+ if (!infuncargs && align_brackets) || (infuncargs && align_funcargs)
+ let st = last_open_bracket
+ let ind = virtcol([lnum, st + 1])
+ else
+ let ind = indent(lnum) + shiftwidth()
+ endif
+
+ " Second scenario: some multiline bracketed expression was closed in the
+ " previous line. But since we know we are still in a bracketed expression,
+ " we need to find the line where the bracket was opened
+ elseif last_closed_bracket != -1
+ call JumpToMatch(lnum, last_closed_bracket)
+ if line(".") == lnum
+ " something wrong here, give up
+ let ind = indent(lnum)
+ else
+ let lnum = line(".")
+ let c = col(".") - 1
+ if c == 0
+ " uhm, give up
+ let ind = 0
+ else
+ " we skipped a bracket set, keep searching for an opening bracket
+ let lim = c
+ continue
+ endif
+ endif
+
+ " Third scenario: nothing special: keep the indentation
+ else
+ let ind = indent(lnum)
+ endif
+
+ " Does the current line start with a closing bracket? Then depending on
+ " the situation we align it with the opening one, or we let the rest of
+ " the code figure it out (the case in which we're closing a function
+ " argument list is special-cased)
+ if JuliaMatch(v:lnum, getline(v:lnum), '[])}]', indent(v:lnum)) == indent(v:lnum) && ind > 0
+ if !align_brackets && !align_funcargs
+ call JumpToMatch(v:lnum, indent(v:lnum))
+ return indent(line("."))
+ elseif (align_brackets && getline(v:lnum)[indent(v:lnum)] != ')') || align_funcargs
+ return ind - 1
+ else " must be a ')' and align_brackets==1 and align_funcargs==0
+ call JumpToMatch(v:lnum, indent(v:lnum))
+ if IsFunctionArgPar(line("."), col("."))
+ let ind = -1
+ else
+ return ind - 1
+ endif
+ endif
+ endif
+
+ break
+ endwhile
+
+ if ind == -1
+ " We are not in a multiline bracketed expression. Thus we look for a
+ " previous line to use as a reference
+ let [lnum,ind] = LastBlockIndent(lnum)
+ let c = len(getline(lnum)) + 1
+ if IsInBrackets(lnum, c)
+ let [first_open_bracket, last_open_bracket, last_closed_bracket, infuncargs] = GetJuliaNestingBrackets(lnum, c)
+ let lim = first_open_bracket
+ endif
+ end
+
+ " Analyse the reference line
+ let [num_open_blocks, num_closed_blocks] = GetJuliaNestingStruct(lnum, st, lim)
+ " Increase indentation for each newly opened block in the reference line
+ let ind += shiftwidth() * num_open_blocks
+
+ " Analyse the current line
+ let [num_open_blocks, num_closed_blocks] = GetJuliaNestingStruct(v:lnum)
+ " Decrease indentation for each closed block in the current line
+ let ind -= shiftwidth() * num_closed_blocks
+
+ " Additional special case: multiline import/using/export statements
+
+ let prevline = getline(lnum)
+ " Are we in a multiline import/using/export statement, right below the
+ " opening line?
+ if IsInContinuationImportLine(v:lnum) && !IsInContinuationImportLine(lnum)
+ if get(g:, 'julia_indent_align_import', 1)
+ " if the opening line has a colon followed by non-comments, use it as
+ " reference point
+ let cind = JuliaMatch(lnum, prevline, ':', indent(lnum), lim)
+ if cind >= 0
+ let nonwhiteind = JuliaMatch(lnum, prevline, '\S', cind+1, -1, 'basic')
+ if nonwhiteind >= 0
+ " return match(prevline, '\S', cind+1) " a bit overkill...
+ return cind + 2
+ endif
+ else
+ " if the opening line is not a naked import/using/export statement, use
+ " it as reference
+ let iind = JuliaMatch(lnum, prevline, '\<import\|using\|export\>', indent(lnum), lim)
+ if iind >= 0
+ " assuming whitespace after using... so no `using(XYZ)` please!
+ let nonwhiteind = JuliaMatch(lnum, prevline, '\S', iind+6, -1, 'basic')
+ if nonwhiteind >= 0
+ return match(prevline, '\S', iind+6)
+ endif
+ endif
+ endif
+ endif
+ let ind += shiftwidth()
+
+ " Or did we just close a multiline import/using/export statement?
+ elseif !IsInContinuationImportLine(v:lnum) && IsInContinuationImportLine(lnum)
+ " find the starting line of the statement
+ let ilnum = 0
+ for iln in range(lnum-1, 1, -1)
+ if !IsInContinuationImportLine(iln)
+ let ilnum = iln
+ break
+ endif
+ endfor
+ if ilnum == 0
+ " something went horribly wrong, give up
+ let ind = indent(lnum)
+ endif
+ let ind = indent(ilnum)
+ endif
+
+ return ind
+endfunction
diff --git a/runtime/syntax/julia.vim b/runtime/syntax/julia.vim
new file mode 100644
index 0000000000..2c2d36a97a
--- /dev/null
+++ b/runtime/syntax/julia.vim
@@ -0,0 +1,550 @@
+" Vim syntax file
+" Language: julia
+" Maintainer: Carlo Baldassi <carlobaldassi@gmail.com>
+" Homepage: https://github.com/JuliaEditorSupport/julia-vim
+" Last Change: 2013 feb 11
+
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+if version < 704
+ " this is used to disable regex syntax like `\@3<='
+ " on older vim versions
+ function! s:d(x)
+ return ''
+ endfunction
+else
+ function! s:d(x)
+ return string(a:x)
+ endfunction
+endif
+
+scriptencoding utf-8
+
+let s:julia_spellcheck_strings = get(g:, "julia_spellcheck_strings", 0)
+let s:julia_spellcheck_docstrings = get(g:, "julia_spellcheck_docstrings", 1)
+let s:julia_spellcheck_comments = get(g:, "julia_spellcheck_comments", 1)
+
+let s:julia_highlight_operators = get(g:, "julia_highlight_operators", 1)
+
+" List of characters, up to \UFF, which cannot be used in identifiers.
+" (It includes operator characters; we don't consider them identifiers.)
+" This is used mostly in lookbehinds with `\@<=`, e.g. when we need to check
+" that that we're not in the middle of an identifier.
+" It doesn't include a few characters (spaces and all closing parentheses)
+" because those may or may not be valid in the lookbehind on a case-by-case
+" basis.
+let s:nonid_chars = '\U00-\U08' . '\U0A-\U1F'
+ \ . '\U21-\U28' . '\U2A-\U2F' . '\U3A-\U40' . '\U5B-\U5E' . '\U60' . '\U7B\U7C'
+ \ . '\U7E-\UA1' . '\UA7\UA8' . '\UAB-\UAD' . '\UAF\UB1\UB4' . '\UB6-\UB8' . '\UBB\UBF' . '\UD7\UF7'
+
+" The complete list
+let s:nonidS_chars = '[:space:])\U5D}' . s:nonid_chars
+
+
+" List of all valid operator chars up to \UFF (NOTE: they must all be included
+" in s:nonidS_chars, so that if we include that, then this is redundant)
+" It does not include '!' since it can be used in an identifier.
+" The list contains the following characters: '%&*+-/<=>\\^|~¬±×÷'
+let s:op_chars = '\U25\U26\U2A\U2B\U2D\U2F\U3C-\U3E\U5C\U5E\U7C\U7E\UAC\UB1\UD7\UF7'
+
+" List of all valid operator chars above \UFF
+" Written with ranges for performance reasons
+" The list contains the following characters: '…⁝⅋←↑→↓↔↚↛↜↝↞↠↢↣↤↦↩↪↫↬↮↶↷↺↻↼↽⇀⇁⇄⇆⇇⇉⇋⇌⇍⇎⇏⇐⇒⇔⇚⇛⇜⇝⇠⇢⇴⇵⇶⇷⇸⇹⇺⇻⇼⇽⇾⇿∈∉∊∋∌∍∓∔∗∘∙√∛∜∝∤∥∦∧∨∩∪∷∸∺∻∽∾≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊞⊟⊠⊡⊢⊣⊩⊬⊮⊰⊱⊲⊳⊴⊵⊶⊷⊻⊼⊽⋄⋅⋆⋇⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌿▷⟂⟈⟉⟑⟒⟕⟖⟗⟰⟱⟵⟶⟷⟹⟺⟻⟼⟽⟾⟿⤀⤁⤂⤃⤄⤅⤆⤇⤈⤉⤊⤋⤌⤍⤎⤏⤐⤑⤒⤓⤔⤕⤖⤗⤘⤝⤞⤟⤠⥄⥅⥆⥇⥈⥉⥊⥋⥌⥍⥎⥏⥐⥑⥒⥓⥔⥕⥖⥗⥘⥙⥚⥛⥜⥝⥞⥟⥠⥡⥢⥣⥤⥥⥦⥧⥨⥩⥪⥫⥬⥭⥮⥯⥰⦷⦸⦼⦾⦿⧀⧁⧡⧣⧤⧥⧴⧶⧷⧺⧻⨇⨈⨝⨟⨢⨣⨤⨥⨦⨧⨨⨩⨪⨫⨬⨭⨮⨰⨱⨲⨳⨴⨵⨶⨷⨸⨹⨺⨻⨼⨽⩀⩁⩂⩃⩄⩅⩊⩋⩌⩍⩎⩏⩐⩑⩒⩓⩔⩕⩖⩗⩘⩚⩛⩜⩝⩞⩟⩠⩡⩢⩣⩦⩧⩪⩫⩬⩭⩮⩯⩰⩱⩲⩳⩴⩵⩶⩷⩸⩹⩺⩻⩼⩽⩾⩿⪀⪁⪂⪃⪄⪅⪆⪇⪈⪉⪊⪋⪌⪍⪎⪏⪐⪑⪒⪓⪔⪕⪖⪗⪘⪙⪚⪛⪜⪝⪞⪟⪠⪡⪢⪣⪤⪥⪦⪧⪨⪩⪪⪫⪬⪭⪮⪯⪰⪱⪲⪳⪴⪵⪶⪷⪸⪹⪺⪻⪼⪽⪾⪿⫀⫁⫂⫃⫄⫅⫆⫇⫈⫉⫊⫋⫌⫍⫎⫏⫐⫑⫒⫓⫔⫕⫖⫗⫘⫙⫛⫷⫸⫹⫺⬰⬱⬲⬳⬴⬵⬶⬷⬸⬹⬺⬻⬼⬽⬾⬿⭀⭁⭂⭃⭄⭇⭈⭉⭊⭋⭌←↑→↓'
+let s:op_chars_wc = '\U2026\U205D\U214B\U2190-\U2194\U219A-\U219E\U21A0\U21A2-\U21A4\U21A6\U21A9-\U21AC\U21AE\U21B6\U21B7\U21BA-\U21BD\U21C0\U21C1\U21C4\U21C6\U21C7\U21C9\U21CB-\U21D0\U21D2\U21D4\U21DA-\U21DD\U21E0\U21E2\U21F4-\U21FF\U2208-\U220D\U2213\U2214\U2217-\U221D\U2224-\U222A\U2237\U2238\U223A\U223B\U223D\U223E\U2240-\U228B\U228D-\U229C\U229E-\U22A3\U22A9\U22AC\U22AE\U22B0-\U22B7\U22BB-\U22BD\U22C4-\U22C7\U22C9-\U22D3\U22D5-\U22FF\U233F\U25B7\U27C2\U27C8\U27C9\U27D1\U27D2\U27D5-\U27D7\U27F0\U27F1\U27F5-\U27F7\U27F9-\U27FF\U2900-\U2918\U291D-\U2920\U2944-\U2970\U29B7\U29B8\U29BC\U29BE-\U29C1\U29E1\U29E3-\U29E5\U29F4\U29F6\U29F7\U29FA\U29FB\U2A07\U2A08\U2A1D\U2A1F\U2A22-\U2A2E\U2A30-\U2A3D\U2A40-\U2A45\U2A4A-\U2A58\U2A5A-\U2A63\U2A66\U2A67\U2A6A-\U2AD9\U2ADB\U2AF7-\U2AFA\U2B30-\U2B44\U2B47-\U2B4C\UFFE9-\UFFEC'
+
+" Full operators regex
+let s:operators = '\%(' . '\.\%([-+*/^÷%|&⊻]\|//\|\\\|>>\|>>>\?\)\?=' .
+ \ '\|' . '[:<>]=\|||\|&&\||>\|<|\|[<>:]:\|<<\|>>>\?\|//\|[-=]>\|\.\.\.\?' .
+ \ '\|' . '\.\?[!' . s:op_chars . s:op_chars_wc . ']' .
+ \ '\)'
+
+
+" Characters that can be used to start an identifier. Above \UBF we don't
+" bother checking. (If a UTF8 operator is used, it will take precedence anyway.)
+let s:id_charsH = '\%([A-Za-z_\UA2-\UA6\UA9\UAA\UAE\UB0\UB5\UBA]\|[^\U00-\UBF]\)'
+" Characters that can appear in an identifier, starting in 2nd position. Above
+" \UBF we check for operators since we need to stop the identifier if one
+" appears. We don't check for invalid characters though.
+let s:id_charsW = '\%([0-9A-Za-z_!\UA2-\UA6\UA9\UAA\UAE-\UB0\UB2-\UB5\UB8-\UBA\UBC-\UBE]\|[^\U00-\UBF]\@=[^' . s:op_chars_wc . ']\)'
+
+" A valid julia identifier, more or less
+let s:idregex = '\%(' . s:id_charsH . s:id_charsW . '*\)'
+
+
+
+syn case match
+
+syntax cluster juliaExpressions contains=@juliaParItems,@juliaStringItems,@juliaKeywordItems,@juliaBlocksItems,@juliaTypesItems,@juliaConstItems,@juliaMacroItems,@juliaSymbolItems,@juliaOperatorItems,@juliaNumberItems,@juliaCommentItems,@juliaErrorItems,@juliaSyntaxRegions
+syntax cluster juliaExprsPrintf contains=@juliaExpressions,@juliaPrintfItems
+syntax cluster juliaExprsNodot contains=@juliaParItems,@juliaStringItems,@juliaMacroItems,@juliaSymbolItems,@juliaOperatorItems,@juliaCommentItems,juliaIdSymbol
+
+syntax cluster juliaParItems contains=juliaParBlock,juliaSqBraIdxBlock,juliaSqBraBlock,juliaCurBraBlock,juliaQuotedParBlock,juliaQuotedQMarkPar
+syntax cluster juliaKeywordItems contains=juliaKeyword,juliaWhereKeyword,juliaImportLine,juliaInfixKeyword,juliaRepKeyword
+syntax cluster juliaBlocksItems contains=juliaConditionalBlock,juliaWhileBlock,juliaForBlock,juliaBeginBlock,juliaFunctionBlock,juliaMacroBlock,juliaQuoteBlock,juliaTypeBlock,juliaImmutableBlock,juliaExceptionBlock,juliaLetBlock,juliaDoBlock,juliaModuleBlock,juliaStructBlock,juliaMutableStructBlock,juliaAbstractBlock,juliaPrimitiveBlock
+syntax cluster juliaTypesItems contains=juliaBaseTypeBasic,juliaBaseTypeNum,juliaBaseTypeC,juliaBaseTypeError,juliaBaseTypeIter,juliaBaseTypeString,juliaBaseTypeArray,juliaBaseTypeDict,juliaBaseTypeSet,juliaBaseTypeIO,juliaBaseTypeProcess,juliaBaseTypeRange,juliaBaseTypeRegex,juliaBaseTypeFact,juliaBaseTypeFact,juliaBaseTypeSort,juliaBaseTypeRound,juliaBaseTypeSpecial,juliaBaseTypeRandom,juliaBaseTypeDisplay,juliaBaseTypeTime,juliaBaseTypeOther
+
+syntax cluster juliaConstItems contains=juliaConstNum,juliaConstBool,juliaConstEnv,juliaConstMMap,juliaConstC,juliaConstGeneric,juliaConstIO,juliaPossibleEuler
+
+syntax cluster juliaMacroItems contains=juliaPossibleMacro,juliaDollarVar,juliaDollarPar,juliaDollarSqBra
+syntax cluster juliaSymbolItems contains=juliaPossibleSymbol
+syntax cluster juliaNumberItems contains=juliaNumbers
+syntax cluster juliaStringItems contains=juliaChar,juliaString,juliabString,juliasString,juliaShellString,juliaDocString,juliaRegEx
+syntax cluster juliaPrintfItems contains=juliaPrintfParBlock,juliaPrintfString
+syntax cluster juliaOperatorItems contains=juliaOperator,juliaRangeOperator,juliaCTransOperator,juliaTernaryRegion,juliaColon,juliaSemicolon,juliaComma
+syntax cluster juliaCommentItems contains=juliaCommentL,juliaCommentM
+syntax cluster juliaErrorItems contains=juliaErrorPar,juliaErrorEnd,juliaErrorElse,juliaErrorCatch,juliaErrorFinally
+
+syntax cluster juliaSyntaxRegions contains=juliaIdSymbol,juliaTypeOperatorR2,juliaTypeOperatorR3,juliaWhereR,juliaDotted
+
+syntax cluster juliaSpellcheckStrings contains=@spell
+syntax cluster juliaSpellcheckDocStrings contains=@spell
+syntax cluster juliaSpellcheckComments contains=@spell
+
+if !s:julia_spellcheck_docstrings
+ syntax cluster juliaSpellcheckDocStrings remove=@spell
+endif
+if !s:julia_spellcheck_strings
+ syntax cluster juliaSpellcheckStrings remove=@spell
+endif
+if !s:julia_spellcheck_comments
+ syntax cluster juliaSpellcheckComments remove=@spell
+endif
+
+syntax match juliaSemicolon display ";"
+syntax match juliaComma display ","
+syntax match juliaColon display ":"
+
+" A dot can introduce a sort of 'environment' such that words after it are not
+" recognized as keywords. This has low precedence so that it can be overridden
+" by operators
+syntax match juliaDotted transparent "\.\s*[^])}.]" contains=@juliaExprsNodot
+syntax match juliaDottedT contained transparent "\.\s*[^])}.]" contains=@juliaExprsNodot,juliaType
+
+syntax match juliaErrorPar display "[])}]"
+syntax match juliaErrorEnd display "\<end\>"
+syntax match juliaErrorElse display "\<\%(else\|elseif\)\>"
+syntax match juliaErrorCatch display "\<catch\>"
+syntax match juliaErrorFinally display "\<finally\>"
+syntax match juliaErrorSemicol display contained ";"
+
+syntax region juliaParBlock matchgroup=juliaParDelim start="(" end=")" contains=@juliaExpressions,juliaComprehensionFor
+syntax region juliaParBlockInRange matchgroup=juliaParDelim contained start="(" end=")" contains=@juliaExpressions,juliaParBlockInRange,juliaRangeKeyword,juliaComprehensionFor
+syntax region juliaSqBraIdxBlock matchgroup=juliaParDelim start="\[" end="\]" contains=@juliaExpressions,juliaParBlockInRange,juliaRangeKeyword,juliaComprehensionFor,juliaSymbolS,juliaQuotedParBlockS,juliaQuotedQMarkParS
+exec 'syntax region juliaSqBraBlock matchgroup=juliaParDelim start="\%(^\|\s\|' . s:operators . '\)\@'.s:d(3).'<=\[" end="\]" contains=@juliaExpressions,juliaComprehensionFor,juliaSymbolS,juliaQuotedParBlockS,juliaQuotedQMarkParS'
+syntax region juliaCurBraBlock matchgroup=juliaParDelim start="{" end="}" contains=juliaType,juliaDottedT,@juliaExpressions
+
+exec 'syntax match juliaType contained "\%(' . s:idregex . '\.\)*\zs' . s:idregex . '"'
+
+" This is a generic identifier followed by some symbol, either a type
+" operator (<: or >:), or an open parenthesis, or an open curly bracket.
+" It's used to recognize one of the contained regions looking for identifiers
+" only once. Once recognized, those regions no longer need to use the
+" expensive s:idregex.
+exec 'syntax match juliaIdSymbol transparent "' . s:idregex . '\%(\s*[<>]:\|\.\?(\|{\|\"\)\@=" contains=juliaFunctionCall,juliaParamType,juliaStringPrefixed,juliaTypeOperatorR1'
+
+syntax match juliaFunctionCall contained "[^{([:space:]<>\"]\+(\@=" nextgroup=juliaParBlock
+
+exec 'syntax match juliaFunctionDef contained transparent "\%(\<\%(function\|macro\)\)\@'.s:d(8).'<=\s\+\zs' . s:idregex . '\%(\.' . s:idregex . '\)*\ze\s*\%((\|\send\>\|$\)" contains=juliaFunctionName'
+exec 'syntax match juliaFunctionName contained "\%(\<\%(function\|macro\)\s\+\)\@'.s:d(20).'<=\%(' . s:idregex . '\.\)*\zs' . s:idregex . '"'
+
+exec 'syntax match juliaStructR contained transparent "\%(\<\%(\%(mutable\s\+\)\?struct\|\%(abstract\|primitive\)\s\+type\)\s\+\)\@'.s:d(20).'<=\%(' . s:idregex . '\.\)*' . s:idregex . '\>\(\s*(\)\@!" contains=juliaType'
+
+syntax match juliaKeyword display "\<\%(return\|local\|global\|const\)\>"
+syntax match juliaInfixKeyword display "\%(=\s*\)\@<!\<\%(in\|isa\)\>\S\@!\%(\s*=\)\@!"
+
+" The import/export/using keywords introduce a sort of special parsing
+" environment with its own rules
+exec 'syntax region juliaImportLine matchgroup=juliaKeyword excludenl start="\<\%(import\|using\|export\)\>" skip="\%(\%(\<\%(import\|using\|export\)\>\)\|^\)\@'.s:d(6).'<=$" end="$" end="\%([])}]\)\@=" contains=@juliaExpressions,juliaAsKeyword,@juliaContinuationItems,juliaMacroName'
+syntax match juliaAsKeyword display contained "\<as\>"
+
+syntax match juliaRepKeyword display "\<\%(break\|continue\)\>"
+syntax region juliaConditionalBlock matchgroup=juliaConditional start="\<if\>" end="\<end\>" contains=@juliaExpressions,juliaConditionalEIBlock,juliaConditionalEBlock fold
+syntax region juliaConditionalEIBlock matchgroup=juliaConditional transparent contained start="\<elseif\>" end="\<\%(end\|else\|elseif\)\>"me=s-1 contains=@juliaExpressions,juliaConditionalEIBlock,juliaConditionalEBlock
+syntax region juliaConditionalEBlock matchgroup=juliaConditional transparent contained start="\<else\>" end="\<end\>"me=s-1 contains=@juliaExpressions
+syntax region juliaWhileBlock matchgroup=juliaRepeat start="\<while\>" end="\<end\>" contains=@juliaExpressions fold
+syntax region juliaForBlock matchgroup=juliaRepeat start="\<for\>" end="\<end\>" contains=@juliaExpressions,juliaOuter fold
+syntax region juliaBeginBlock matchgroup=juliaBlKeyword start="\<begin\>" end="\<end\>" contains=@juliaExpressions fold
+syntax region juliaFunctionBlock matchgroup=juliaBlKeyword start="\<function\>" end="\<end\>" contains=@juliaExpressions,juliaFunctionDef fold
+syntax region juliaMacroBlock matchgroup=juliaBlKeyword start="\<macro\>" end="\<end\>" contains=@juliaExpressions,juliaFunctionDef fold
+syntax region juliaQuoteBlock matchgroup=juliaBlKeyword start="\<quote\>" end="\<end\>" contains=@juliaExpressions fold
+syntax region juliaStructBlock matchgroup=juliaBlKeyword start="\<struct\>" end="\<end\>" contains=@juliaExpressions,juliaStructR fold
+syntax region juliaMutableStructBlock matchgroup=juliaBlKeyword start="\<mutable\s\+struct\>" end="\<end\>" contains=@juliaExpressions,juliaStructR fold
+syntax region juliaLetBlock matchgroup=juliaBlKeyword start="\<let\>" end="\<end\>" contains=@juliaExpressions fold
+syntax region juliaDoBlock matchgroup=juliaBlKeyword start="\<do\>" end="\<end\>" contains=@juliaExpressions fold
+syntax region juliaModuleBlock matchgroup=juliaBlKeyword start="\<\%(bare\)\?module\>" end="\<end\>" contains=@juliaExpressions fold
+syntax region juliaExceptionBlock matchgroup=juliaException start="\<try\>" end="\<end\>" contains=@juliaExpressions,juliaCatchBlock,juliaFinallyBlock fold
+syntax region juliaCatchBlock matchgroup=juliaException transparent contained start="\<catch\>" end="\<end\>"me=s-1 contains=@juliaExpressions,juliaFinallyBlock
+syntax region juliaFinallyBlock matchgroup=juliaException transparent contained start="\<finally\>" end="\<end\>"me=s-1 contains=@juliaExpressions
+syntax region juliaAbstractBlock matchgroup=juliaBlKeyword start="\<abstract\s\+type\>" end="\<end\>" fold contains=@juliaExpressions,juliaStructR
+syntax region juliaPrimitiveBlock matchgroup=juliaBlKeyword start="\<primitive\s\+type\>" end="\<end\>" fold contains=@juliaExpressions,juliaStructR
+
+exec 'syntax region juliaComprehensionFor matchgroup=juliaComprehensionFor transparent contained start="\%([^[:space:],;:({[]\_s*\)\@'.s:d(80).'<=\<for\>" end="\ze[]);]" contains=@juliaExpressions,juliaComprehensionIf,juliaComprehensionFor'
+syntax match juliaComprehensionIf contained "\<if\>"
+
+exec 'syntax match juliaOuter contained "\<outer\ze\s\+' . s:idregex . '\>"'
+
+syntax match juliaRangeKeyword contained "\<\%(begin\|end\)\>"
+
+syntax match juliaBaseTypeBasic display "\<\%(\%(N\|Named\)\?Tuple\|Symbol\|Function\|Union\%(All\)\?\|Type\%(Name\|Var\)\?\|Any\|ANY\|Vararg\|Ptr\|Exception\|Module\|Expr\|DataType\|\%(LineNumber\|Quote\)Node\|\%(Weak\|Global\)\?Ref\|Method\|Pair\|Val\|Nothing\|Some\|Missing\)\>"
+syntax match juliaBaseTypeNum display "\<\%(U\?Int\%(8\|16\|32\|64\|128\)\?\|Float\%(16\|32\|64\)\|Complex\|Bool\|Char\|Number\|Signed\|Unsigned\|Integer\|AbstractFloat\|Real\|Rational\|\%(Abstract\)\?Irrational\|Enum\|BigInt\|BigFloat\|MathConst\|ComplexF\%(16\|32\|64\)\)\>"
+syntax match juliaBaseTypeC display "\<\%(FileOffset\|C\%(u\?\%(char\|short\|int\|long\(long\)\?\|w\?string\)\|float\|double\|\%(ptrdiff\|s\?size\|wchar\|off\|u\?intmax\)_t\|void\)\)\>"
+syntax match juliaBaseTypeError display "\<\%(\%(Bounds\|Divide\|Domain\|\%(Stack\)\?Overflow\|EOF\|Undef\%(Ref\|Var\)\|System\|Type\|Parse\|Argument\|Key\|Load\|Method\|Inexact\|OutOfMemory\|Init\|Assertion\|ReadOnlyMemory\|StringIndex\)Error\|\%(Interrupt\|Error\|ProcessExited\|Captured\|Composite\|InvalidState\|Missing\|\%(Process\|Task\)Failed\)Exception\|DimensionMismatch\|SegmentationFault\)\>"
+syntax match juliaBaseTypeIter display "\<\%(EachLine\|Enumerate\|Cartesian\%(Index\|Range\)\|LinSpace\|CartesianIndices\)\>"
+syntax match juliaBaseTypeString display "\<\%(DirectIndex\|Sub\|Rep\|Rev\|Abstract\|Substitution\)\?String\>"
+syntax match juliaBaseTypeArray display "\<\%(\%(Sub\)\?Array\|\%(Abstract\|Dense\|Strided\)\?\%(Array\|Matrix\|Vec\%(tor\|OrMat\)\)\|SparseMatrixCSC\|\%(AbstractSparse\|Bit\|Shared\)\%(Array\|Vector\|Matrix\)\|\%\(D\|Bid\|\%(Sym\)\?Trid\)iagonal\|Hermitian\|Symmetric\|UniformScaling\|\%(Lower\|Upper\)Triangular\|\%(Sparse\|Row\)Vector\|VecElement\|Conj\%(Array\|Matrix\|Vector\)\|Index\%(Cartesian\|Linear\|Style\)\|PermutedDimsArray\|Broadcasted\|Adjoint\|Transpose\|LinearIndices\)\>"
+syntax match juliaBaseTypeDict display "\<\%(WeakKey\|Id\|Abstract\)\?Dict\>"