summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/ftplugin/odin.vim20
-rw-r--r--runtime/indent/odin.vim119
-rw-r--r--runtime/syntax/odin.vim103
3 files changed, 242 insertions, 0 deletions
diff --git a/runtime/ftplugin/odin.vim b/runtime/ftplugin/odin.vim
new file mode 100644
index 0000000000..9d94a57808
--- /dev/null
+++ b/runtime/ftplugin/odin.vim
@@ -0,0 +1,20 @@
+vim9script
+
+# Vim filetype plugin file
+# Language: Odin
+# Maintainer: Maxim Kim <habamax@gmail.com>
+# Website: https://github.com/habamax/vim-odin
+# Last Change: 2024-01-15
+
+if exists("b:did_ftplugin")
+ finish
+endif
+b:did_ftplugin = 1
+
+b:undo_ftplugin = 'setlocal commentstring<'
+ \ .. '| setlocal comments<'
+ \ .. '| setlocal suffixesadd<'
+
+setlocal suffixesadd=.odin
+setlocal commentstring=//%s
+setlocal comments=s1:/*,mb:*,ex:*/,://
diff --git a/runtime/indent/odin.vim b/runtime/indent/odin.vim
new file mode 100644
index 0000000000..e3318c4d6e
--- /dev/null
+++ b/runtime/indent/odin.vim
@@ -0,0 +1,119 @@
+vim9script
+
+# Vim indent plugin file
+# Language: Odin
+# Maintainer: Maxim Kim <habamax@gmail.com>
+# Website: https://github.com/habamax/vim-odin
+# Last Change: 2024-01-15
+
+if exists("b:did_indent")
+ finish
+endif
+b:did_indent = 1
+
+b:undo_indent = 'setlocal cindent< cinoptions< cinkeys< indentexpr<'
+
+setlocal cindent
+setlocal cinoptions=L0,m1,(s,j1,J1,l1,+0,:0,#1
+setlocal cinkeys=0{,0},0),0],!^F,:,o,O
+
+setlocal indentexpr=GetOdinIndent(v:lnum)
+
+def PrevLine(lnum: number): number
+ var plnum = lnum - 1
+ var pline: string
+ while plnum > 1
+ plnum = prevnonblank(plnum)
+ pline = getline(plnum)
+ # XXX: take into account nested multiline /* /* */ */ comments
+ if pline =~ '\*/\s*$'
+ while getline(plnum) !~ '/\*' && plnum > 1
+ plnum -= 1
+ endwhile
+ if getline(plnum) =~ '^\s*/\*'
+ plnum -= 1
+ else
+ break
+ endif
+ elseif pline =~ '^\s*//'
+ plnum -= 1
+ else
+ break
+ endif
+ endwhile
+ return plnum
+enddef
+
+def GetOdinIndent(lnum: number): number
+ var plnum = PrevLine(lnum)
+ var pline = getline(plnum)
+ var pindent = indent(plnum)
+ # workaround of cindent "hang"
+ # if the previous line looks like:
+ # : #{}
+ # : #whatever{whateverelse}
+ # and variations where : # { } are in the string
+ # cindent(lnum) hangs
+ if pline =~ ':\s\+#.*{.*}'
+ return pindent
+ endif
+
+ var indent = cindent(lnum)
+ var line = getline(lnum)
+
+ if line =~ '^\s*#\k\+'
+ if pline =~ '[{:]\s*$'
+ indent = pindent + shiftwidth()
+ else
+ indent = pindent
+ endif
+ elseif pline =~ 'switch\s.*{\s*$'
+ indent = pindent
+ elseif pline =~ 'case\s*.*,\s*\(//.*\)\?$' # https://github.com/habamax/vim-odin/issues/8
+ indent = pindent + matchstr(pline, 'case\s*')->strcharlen()
+ elseif line =~ '^\s*case\s\+.*,\s*$'
+ indent = pindent - shiftwidth()
+ elseif pline =~ 'case\s*.*:\s*\(//.*\)\?$'
+ if line !~ '^\s*}\s*$' && line !~ '^\s*case[[:space:]:]'
+ indent = pindent + shiftwidth()
+ endif
+ elseif pline =~ '^\s*@.*' && line !~ '^\s*}'
+ indent = pindent
+ elseif pline =~ ':[:=].*}\s*$'
+ indent = pindent
+ elseif pline =~ '^\s*}\s*$'
+ if line !~ '^\s*}' && line !~ 'case\s*.*:\s*$'
+ indent = pindent
+ else
+ indent = pindent - shiftwidth()
+ endif
+ elseif pline =~ '\S:\s*$'
+ # looking up for a case something,
+ # whatever,
+ # anything:
+ # ... 20 lines before
+ for idx in range(plnum - 1, plnum - 21, -1)
+ if plnum < 1
+ break
+ endif
+ if getline(idx) =~ '^\s*case\s.*,\s*$'
+ indent = indent(idx) + shiftwidth()
+ break
+ endif
+ endfor
+ elseif pline =~ '{[^{]*}\s*$' && line !~ '^\s*[})]\s*$' # https://github.com/habamax/vim-odin/issues/2
+ indent = pindent
+ elseif pline =~ '^\s*}\s*$' # https://github.com/habamax/vim-odin/issues/3
+ # Find line with opening { and check if there is a label:
+ # If there is, return indent of the closing }
+ cursor(plnum, 1)
+ silent normal! %
+ var brlnum = line('.')
+ var brline = getline('.')
+ if plnum != brlnum && (brline =~ '^\s*\k\+:\s\+for' || brline =~ '^\s*\k\+\s*:=')
+ indent = pindent
+ endif
+ endif
+
+ return indent
+enddef
diff --git a/runtime/syntax/odin.vim b/runtime/syntax/odin.vim
new file mode 100644
index 0000000000..6bf06f69e7
--- /dev/null
+++ b/runtime/syntax/odin.vim
@@ -0,0 +1,103 @@
+vim9script
+
+# Vim indent plugin file
+# Language: Odin
+# Maintainer: Maxim Kim <habamax@gmail.com>
+# Website: https://github.com/habamax/vim-odin
+# Last Change: 2024-01-15
+
+if exists("b:current_syntax")
+ finish
+endif
+
+syntax keyword odinKeyword using transmute cast distinct opaque where dynamic
+syntax keyword odinKeyword struct enum union const bit_field bit_set
+syntax keyword odinKeyword package proc map import export foreign
+syntax keyword odinKeyword size_of offset_of type_info_of typeid_of type_of align_of
+syntax keyword odinKeyword return defer
+syntax keyword odinKeyword or_return or_else
+syntax keyword odinKeyword inline no_inline
+
+syntax keyword odinConditional if when else do for switch case continue break
+syntax keyword odinType string cstring bool b8 b16 b32 b64 rune any rawptr
+syntax keyword odinType f16 f32 f64 f16le f16be f32le f32be f64le f64be
+syntax keyword odinType u8 u16 u32 u64 u128 u16le u32le u64le u128le u16be
+syntax keyword odinType u32be u64be u128be uint uintptr i8 i16 i32 i64 i128
+syntax keyword odinType i16le i32le i64le i128le i16be i32be i64be i128be
+syntax keyword odinType int complex complex32 complex64 complex128 matrix typeid
+syntax keyword odinType quaternion quaternion64 quaternion128 quaternion256
+syntax keyword odinBool true false
+syntax keyword odinNull nil
+syntax match odinUninitialized '\s\+---\(\s\|$\)'
+
+syntax keyword odinOperator in notin not_in
+syntax match odinOperator "?" display
+syntax match odinOperator "->" display
+
+syntax match odinTodo "TODO" contained
+syntax match odinTodo "XXX" contained
+syntax match odinTodo "FIXME" contained
+syntax match odinTodo "HACK" contained
+
+syntax region odinRawString start=+`+ end=+`+
+syntax region odinChar start=+'+ skip=+\\\\\|\\'+ end=+'+
+syntax region odinString start=+"+ skip=+\\\\\|\\'+ end=+"+ contains=odinEscape
+syntax match odinEscape display contained /\\\([nrt\\'"]\|x\x\{2}\)/
+
+syntax match odinProcedure "\v<\w*>(\s*::\s*proc)@="
+
+syntax match odinAttribute "@\ze\<\w\+\>" display
+syntax region odinAttribute
+ \ matchgroup=odinAttribute
+ \ start="@\ze(" end="\ze)"
+ \ transparent oneline
+
+syntax match odinInteger "\-\?\<\d\+\>" display
+syntax match odinFloat "\-\?\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=" display
+syntax match odinHex "\<0[xX][0-9A-Fa-f]\+\>" display
+syntax match odinDoz "\<0[zZ][0-9a-bA-B]\+\>" display
+syntax match odinOct "\<0[oO][0-7]\+\>" display
+syntax match odinBin "\<0[bB][01]\+\>" display
+
+syntax match odinAddressOf "&" display
+syntax match odinDeref "\^" display
+
+syntax match odinMacro "#\<\w\+\>" display
+
+syntax match odinTemplate "$\<\w\+\>"
+
+syntax region odinLineComment start=/\/\// end=/$/ contains=@Spell,odinTodo
+syntax region odinBlockComment start=/\/\*/ end=/\*\// contains=@Spell,odinTodo,odinBlockComment
+syn sync ccomment odinBlockComment
+
+highlight def link odinKeyword Statement
+highlight def link odinConditional Conditional
+highlight def link odinOperator Operator
+
+highlight def link odinString String
+highlight def link odinRawString String
+highlight def link odinChar Character
+highlight def link odinEscape Special
+
+highlight def link odinProcedure Function
+
+highlight def link odinMacro PreProc
+
+highlight def link odinLineComment Comment
+highlight def link odinBlockComment Comment
+
+highlight def link odinTodo Todo
+
+highlight def link odinAttribute Statement
+highlight def link odinType Type
+highlight def link odinBool Boolean
+highlight def link odinNull Constant
+highlight def link odinUninitialized Constant
+highlight def link odinInteger Number
+highlight def link odinFloat Float
+highlight def link odinHex Number
+highlight def link odinOct Number
+highlight def link odinBin Number
+highlight def link odinDoz Number
+
+b:current_syntax = "odin"