" EVi syntax file
" Language:	Agda
" Maintainer:	Derek Elkins <derek.a.elkins@gmail.com>
" URL:		https://github.com/derekelkins/agda-vim
" License:	
" Copyright (c) 2013, Derek Elkins
" All rights reserved.
" 
" Redistribution and use in source and binary forms, with or without
" modification, are permitted provided that the following conditions are met:
" 
" Redistributions of source code must retain the above copyright notice, this
" list of conditions and the following disclaimer.
" 
" Redistributions in binary form must reproduce the above copyright
" notice, this list of conditions and the following disclaimer in the
" documentation and/or other materials provided with the distribution.
" 
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
" Last Change:	2021 Oct 24

" This is reproduced from 
" http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Main.VIMEditing
" for convenience

if !exists('main_syntax')
  if exists('b:current_syntax')
    finish
  endif
  let main_syntax = 'agda'
elseif exists('b:current_syntax') && b:current_syntax == 'agda'
  finish
endif

let s:cpo_save = &cpo
set cpo&vim

" To tokenize, the best pattern I've found so far is this:
"   (^|\s|[.(){};])@<=token($|\s|[.(){};])@=
" The patterns @<= and @= look behind and ahead, respectively, without matching.

" `agda --vim` extends these groups:
"   agdaConstructor
"   agdaFunction
"   agdaInfixConstructor
"   agdaInfixFunction
"
syn iskeyword @,!-~,^\,,^\(,^\),^\",^\',192-255

syn match   agdaKeywords     "\v(^|\s|[.(){};])@<=(abstract|data|hiding|import|as|infix|infixl|infixr|module|mutual|open|primitive|private|public|record|renaming|rewrite|using|where|with|field|constructor|instance|syntax|pattern|inductive|coinductive|variable)($|\s|[.(){};])@="
syn match   agdaDubious      "\v(^|\s|[.(){};])@<=(postulate|codata)($|\s|[.(){};])@="
syn match   agdaOperator     "\v(^|\s|[.(){};])@<=(let|in|forall|λ|→|-\>|:|∀|\=|\||\\)($|\s|[.(){};])@="
syn match   agdaFunction     "\v(^|\s|[.(){};])@<=((Set|Prop)[0-9₀-₉ω]*)($|\s|[.(){};])@="
syn match   agdaNumber       "\v(^|\s|[.(){};])@<=-?[0-9]+($|\s|[.(){};])@="
syn match   agdaCharCode     contained "\\\([0-9]\+\|o[0-7]\+\|x[0-9a-fA-F]\+\|[\"\\'&\\abfnrtv]\|^[A-Z^_\[\\\]]\)"
syn match   agdaCharCode     contained "\v\\(NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL)"
syn match   agdaCharCodeErr  contained "\\&\|'''\+"
syn region  agdaString       start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=agdaCharCode
syn match   agdaHole         "\v(^|\s|[.(){};])@<=(\?)($|\s|[.(){};])@="
syn region  agdaX            matchgroup=agdaHole start="{!" end="!}" contains=ALL
syn match   agdaLineComment  "\v(^|\s|[.(){};])@<=--.*$" contains=@agdaInComment
syn region  agdaBlockComment start="{-"  end="-}" contains=agdaBlockComment,@agdaInComment
syn region  agdaPragma       start="{-#" end="#-}"
syn cluster agdaInComment    contains=agdaTODO,agdaFIXME,agdaXXX
syn keyword agdaTODO         contained TODO
syn keyword agdaFIXME        contained FIXME
syn keyword agdaXXX          contained XXX

hi def link agdaNumber           Number
hi def link agdaString           String
hi def link agdaConstructor      Constant
hi def link agdaCharCode         SpecialChar
hi def link agdaCharCodeErr      Error
hi def link agdaHole             WarningMsg
hi def link agdaDubious          WarningMsg
hi def link agdaKeywords         Structure
hi def link agdaFunction         Macro
hi def link agdaOperator         Operator
hi def link agdaInfixConstructor Operator
hi def link agdaInfixFunction    Operator
hi def link agdaLineComment      Comment
hi def link agdaBlockComment     Comment
hi def link agdaPragma           Comment
hi def      agdaTODO             cterm=bold,underline ctermfg=2 " green
hi def      agdaFIXME            cterm=bold,underline ctermfg=3 " yellow
hi def      agdaXXX              cterm=bold,underline ctermfg=1 " red


let b:current_syntax = 'agda'
if main_syntax == 'agda'
  unlet main_syntax
endif
let &cpo = s:cpo_save
unlet s:cpo_save
