[m-rev.] for review: rewrite of vim syntax file

Sebastian Godelet sebastian.godelet at outlook.com
Tue Apr 7 20:56:52 AEST 2015


Hi,

Now the clause heads are marked as statements (aka yellow).
I've also added the ability to create a Vimball (.vba), in case
someone uses that for Vim plugin management. The documentation is now
in doc/mercury.txt, such that Vim can find it via :help Mercury.txt or
directly by typing :help mercury-syntax etc. I guess that is easier than
looking into the vim file.

On 07/04/2015 14:27, Paul Bone wrote:
> On Sun, Apr 05, 2015 at 10:20:41AM +0800, Sebastian Godelet wrote:
>> Hi Paul,
>>
>> thanks for looking into this so promptly. For what its worth, I've used
>> my Vim file for a couple of month now so in my opinion the syntax file
>> is rather stable (of course there is always room for improvement)
>
> That all sounds great.
>
> I've now been using this for a couple of days, there are many things which
> are "different', which is neither hear nor there.  The only thing that's
> possibly a problem is that the old configuration used to highlight clause
> heads (in yellow).  I'd like that back because I like the very clear
> beginnings and ends of clauses.  Is it configurable? can I turn it back on?
>
> Cheers.
>
>
-------------- next part --------------
Major rewrite of the Vim syntax file and plugin

This patch is a major rewrite of the Vim syntax file
(vim/syntax/mercury.vim), supporting following (optional) features:
 - highlighting of foreign code, including all doubly escaped characters
   such as "" or \\" in strings, etc.
 - recognising \uXXXX \OOO\ and formatting specifiers in Mercury strings
 - concealing of certain operators and infix functions such as /\,
   the `compose` function from std_util,
   and set-calculus related operators (`union`, ...)
 - supporting markup within comments, i.e. as function headers, `  ',
   ``'', URIs and Mercury file names, TODO, NOTE, XXX and so on.
 - support underlining of local variables within function or predicate
   bodies, which is a feature found in SWI-Prolog.
   Additionally one can use <C-K>r and <C-K>R to rename the underlined
   variable.
 - improved speed due to better overlong line detection and a sync on
   Mercury line comments '%-----' instead of sync start, which is
   noticeable for large files such as io.m.
 - Different way of supporting transparent comment highlighting, such
   that spell checking works only on comments in both fully highlighted
   and partially highlighted comments, this works best if comment
   markup is enables (see above).
   Without this, spell checking would have to be enabled for Mercury
   code as well which Vim is not good at.
 - Improved folding support if no user defined setting is in place
 - Matching parenthesis detection (here meaning (),[],{}) and marking
   unbalanced parens as err
 - highlighting of spurious whitespace for better patch management.

vim/.gitignore:
    Ignore mercury.vba file.

vim/Makefile:
    A makefile to create a Vimball (.vba) and install that.

vim/README:
    Moved installation instructions to vim/doc/mercury.txt and point to
    that file.

vim/doc/mercury.txt:
    Moved the documentation part from mercury.vim to a Vim documentation
    file.

vim/ftplugin/mercury.vim:
    Adds highlighting and renaming of currently selected variables,
    and enables ftplugin/mercuryhdr.sh on Windows.

vim/ftplugin/mercuryhdr.sh:
    Adhere to Mercury coding standards.

vim/syntax/mercury.vim:
    see above.
-------------- next part --------------
diff --git a/vim/.gitignore b/vim/.gitignore
new file mode 100644
index 0000000..8c2ad01
--- /dev/null
+++ b/vim/.gitignore
@@ -0,0 +1 @@
+mercury.vba
diff --git a/vim/Makefile b/vim/Makefile
new file mode 100644
index 0000000..f5037cd
--- /dev/null
+++ b/vim/Makefile
@@ -0,0 +1,34 @@
+# vim: ft=make noet
+FILES := doc/mercury.txt
+FILES += ftdetect/mercury.vim
+FILES += ftplugin/mercury.vim
+FILES += ftplugin/mercuryhdr.sh
+FILES += syntax/mercury.vim
+
+WC := wc
+SED := sed
+DATE := date
+VIM := vim
+RM := /bin/rm
+COUNT_LINES := $(WC) -l
+
+# NOTE: please do not modify the first line, since that is essential to
+# the Vimball plugin
+# Also note the tab character between $(FILE) and [[[1, that seems to be 
+# necessary as well
+mercury.vba: $(FILES)
+	@echo \" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.>$@
+	@echo UseVimball>>$@
+	@echo finish>>$@
+	@$(foreach FILE,$(FILES),  \
+		echo "$(FILE)	[[[1">>$@; \
+		$(COUNT_LINES) < $(FILE) | $(SED) "s/\s/\n/" >>$@; \
+		cat $(FILE) >>$@; )
+
+.PHONY: install
+install: mercury.vba
+	$(VIM) -c 'so %' -c 'q' $<
+
+.PHONY: clean
+clean:
+	$(RM) mercury.vba
diff --git a/vim/README b/vim/README
index 67f9016..9a564aa 100644
--- a/vim/README
+++ b/vim/README
@@ -1,50 +1,3 @@
 Mercury Syntax Highlighting Under Vim 6.0+
 
-1. Create a diretory `~/.vim':
-
-    $ mkdir ~/.vim
-
-2. Copy everything recursively from this directory into `~/.vim':
-
-    $ cp -r . ~/.vim
-
-3. Ensure you have the following lines in your `~/.vimrc' file:
-
-    filetype on
-    filetype plugin on
-    syntax enable
-
-4. It is advisable to have the following file encoding detection lines
-in your ~/.vimrc:
-
-    if has("multi_byte")
-      set encoding=utf-8
-      setglobal fileencoding=utf-8
-      if &termencoding == ""
-        let &termencoding = &encoding
-      endif
-    endif
-
-5. Optionally enable modeline detection.  This configures vim to use the
-"vim:" lines at the beginning of some source files to configure settings
-local to that file.
-
-    set modeline
-
-6. If you wish to change the colour scheme used by Vim's syntax highlighting,
-we suggest you put the necessary commands in `~/.vim/colors/mycolours.vim'
-and append the following to the above list of commands in your `~/.vimrc':
-
-    colors mycolours
-
-7. Vim will load `~/.vim/syntax/mercury.vim' and `~/.vim/ftplugin/mercury.vim'
-automatically when opening a .m or .moo file.
-
-The syntax file describes two options you may wish to alter from your
-`~/.vimrc' file.
-
-The ftplugin file defines a number of useful keyboard mappings you may wish to
-consider.
-
-If you want to add a custom extension for Mercury source files, then modify the
-ftdetect/mercury.vim file. Currently .m and .moo are recognised.
+Please consult doc/mercury.txt for installation and configuration information.
diff --git a/vim/doc/mercury.txt b/vim/doc/mercury.txt
new file mode 100644
index 0000000..d3b0765
--- /dev/null
+++ b/vim/doc/mercury.txt
@@ -0,0 +1,149 @@
+*Mercury.txt*       Mercury Language Support
+                    LastChange: 2015-04-07
+                    Author: Sebastian Godelet <sebastian.godelet at outlook.com>
+
+1. Overview                                         |mercury-overview|
+2. Installation                                     |mercury-installation|
+3. Filetype plugin                                  |mercury-ftplugin|
+4. Mercury commands plugin                          |mercury-commands|
+5. Syntax highlighting                              |mercury-syntax|
+
+=============================================================================
+1. Overview                                            *mercury-overview*
+
+Mercury Syntax Highlighting Under Vim 6.0+
+For using the conceal feature, please use Vim 7.3+ with the conceal feature
+enabled.
+
+=============================================================================
+2. Installation                                         *mercury-install*
+
+2.1. Create a directory `~/.vim' if not done so far: >
+
+    $ mkdir ~/.vim
+<
+2.2. There are two ways to install the support files:
+
+2.2.1 Manual: Copy everything recursively from this directory into `~/.vim' >
+
+    $ cp -r . ~/.vim
+<
+2.2.2 Using a Vimball: In this directory, invoke: >
+
+    $ make
+    $ make install
+
+3. Ensure you have the following lines in your `~/.vimrc' file: >
+
+    filetype on
+    filetype plugin on
+    syntax enable
+<
+4. It is advisable to have the following file encoding detection lines
+in your ~/.vimrc: >
+
+    if has("multi_byte")
+      set encoding=utf-8
+      setglobal fileencoding=utf-8
+      if &termencoding == ""
+        let &termencoding = &encoding
+      endif
+    endif
+<
+5. Optionally enable |modeline| detection.  This configures vim to use the
+% vim: lines at the beginning of some source files to configure settings
+local to that file. >
+
+    set modeline
+<
+6. If you wish to change the colour scheme used by Vim's |syntax-highlighting|,
+we suggest you put the necessary commands in `~/.vim/colors/mycolours.vim'
+and append the following to the above list of commands in your `~/.vimrc': >
+
+    colors mycolours
+<
+7. If you want to use Vim's |spell-checking| feature, please insert the
+following directive after the |encoding| setting from 4. >
+
+    " Spelling (comes after encoding, to reduce load time, see :help spell)
+    :setlocal spell spelllang=en_gb
+>
+=============================================================================
+3. Filetype plugin                                      *mercury-ftplugin*
+
+=============================================================================
+4. Mercury commands plugin                              *mercury-commands*
+
+mercury_commands |plugin| provides additional functionality via Vim commands:
+                                                                    *:Mmc*
+:Mmc [arg1]...      Invoke compiler (mmc), using current file when no
+                    arguments passed.
+                                                                    *:Merr*
+:Merr               Show last output from :Mmc.
+
+=============================================================================
+5. Syntax highlighting                                      *mercury-syntax*
+
+The |syntax-highlighting| for mercury can be customised in several ways,
+in your ~/.vimrc file, you can specify following options:
+
+The default highlighting for  Mercury comments is to only highlight the
+initial `%' and subsequent `line' punctuation characters, likewise
+the /* and */ from C-style comments.
+To highlight everything including the comment text, add: >
+
+    let mercury_highlight_full_comment = 1
+<
+By default, parts of lines that extend over 78 characters will be
+highlighted.  To avoid this behaviour, add: >
+
+    let mercury_no_highlight_overlong = 1
+<
+If folding is supported by the running Vim version, the setting of the
+preferred folding mode for Mercury (currently indent, as it is the fastest)
+can be disabled by >
+
+    let mercury_no_folding = 1
+<
+If you want to force the folding setting to indent (despite a different
+setting in the vimrc file), you can enforce it: >
+
+    let mercury_folding_force = 1
+<
+To facilitate better git patch management,
+spurious whitespace is marked as a warning, to suppress these, use: >
+
+    let mercury_no_highlight_trailing_whitespace = 1
+<
+For the same reasons, tabs are marked as a warning,
+if you want to disable this, please use: >
+
+    let mercury_no_highlight_tabs = 1
+<
+Highlighting of C, Java, C# and Erlang code is supported by default,
+disable (if you think loading huge files is slow) with: >
+
+    let mercury_no_highlight_foreign = 1
+<
+Enable highlighting of Tex specific directives used in comments,
+such as `' or ``'': >
+
+    let mercury_highlight_comment_special = 1
+<
+If you use Vim 7.3+ with conceal enabled but do not want any concealing
+of operators, use: >
+
+    let mercury_no_coneal = 1
+<
+To enable concealing for characters which require a good Unicode font
+and might be "too much" for some users, define: >
+
+    let mercury_conceal_extra = 1
+<
+If concealing of extra characters is enabled, one can additionally
+enable concealing for logical operators, such as <=> => <= some all
+by setting: >
+
+    let mercury_conceal_logical = 1
+<
+vim:tw=78:ts=4:ft=help:norl:et:
diff --git a/vim/ftplugin/mercury.vim b/vim/ftplugin/mercury.vim
index 917e46c..d1bef44 100644
--- a/vim/ftplugin/mercury.vim
+++ b/vim/ftplugin/mercury.vim
@@ -1,6 +1,7 @@
 " Vim syntax file
 " Language:     Mercury
-" Maintainer:   Ralph Becket <rafe at cs.mu.oz.au>
+" Maintainer:   Sebastian Godelet <sebastian.godelet at outlook.com>
+" Last Change:  2015-04-06
 " vim: ts=2 sw=2 et
 
 if exists("b:did_mercury_ftplugin")
@@ -17,33 +18,40 @@ setlocal tags+=$HOME/mercury/tags.library,$HOME/mercury/tags.compiler
 
   " Handy if you use `:make'.
   "
-setlocal makeprg=mmake
+setlocal makeprg="mmc -m"
 
   " Don't wrap over-long lines.
   "
 setlocal wrapmargin=0
-setlocal textwidth=0
 
-  " These settings allow for neater coding styles, but
-  " should not be imposed on existing files that use,
-  " say, the default `tabstop=8, shiftwidth=8, noexpandtab'.
+  " if you want to follow the Mercury coding standard of 78 wide columns,
+  " enable following option in your ~/.vimrc:
   "
+  "     let g:mercury_coding_standard = 1
+  "
+if exists("mercury_coding_standard") && mercury_coding_standard
+  setlocal textwidth=78
+  if v:version >= 703
+    setlocal colorcolumn=+1
+    " Controls how autoindenting works.  See the Vim help pages for details.
+    set fo-=t " do not automatically wrap text
+    set fo+=c " auto wrap comments, using comment leader
+    set fo+=r " automatically insert the comment leader after <CR>
+    set fo+=q " enable tq feature
+  endif
+  setlocal tabstop=4
+  setlocal shiftwidth=4
+  setlocal expandtab
+endif
+
   " It is a good idea to have a modeline comment at the top
   " of your Mercury source files containing
   " ` vim: ft=mercury ff=unix ts=4 sw=4 et '
-  "
-" setlocal tabstop=8
-" setlocal shiftwidth=8
-" setlocal expandtab   
-
-  " Controls how autoindenting works.  See the Vim help pages for details.
-  "
-setlocal formatoptions=trcq
 
   " <C-X>l inserts a comment line.
   "
-nnoremap <C-X>l o0<C-D>%------------------------------------------------------------------------------%<CR><ESC>x
-inoremap <C-X>l --------------------------------------------------------------------------------<ESC>80<BAR>C%<CR>
+nnoremap <C-X>l o0<C-D>%--------------------------------------------------------------------------%<CR><ESC>x
+inoremap <C-X>l ----------------------------------------------------------------------------<ESC>78<BAR>C%<CR>
 
   " <F6> attempts to wrap a call up with { } braces for DCG escapes.
   "
@@ -54,13 +62,139 @@ nnoremap <F6> I{ <ESC>%a }<ESC>j
 nnoremap <F7> 0i% <ESC>j
 nnoremap <F8> :s/% //e<CR>j
 
+  " <F9> visually selects the current code block (e.g. predicate defintion,
+  " declaration, pragma, bascially everything from (:-|^atom) to terminal .
+  "
+inoremap <F9> <ESC>:call <SID>MarkCurrentPred()<CR>
+nnoremap <F9> :call <SID>MarkCurrentPred()<CR>
+
+  " <C-K>r is for renaming variables, and filling out the current name
+  " <C-K>R is for renaming variables, starting with an empty name
+  "
+inoremap <C-K>r <ESC> :call <SID>RenameCurrentVariable(1)<CR>
+nnoremap <C-K>r :call <SID>RenameCurrentVariable(1)<CR>
+
+inoremap <C-K>R <ESC> :call <SID>RenameCurrentVariable(0)<CR>
+nnoremap <C-K>R :call <SID>RenameCurrentVariable(0)<CR>
+
   " <C-X>h runs `$HOME/.vim/ftplugin/mercuryhdr.sh' which inserts all the
   " usual boilerplate for a new Mercury module.
   "
-nnoremap <C-X>h !!$HOME/.vim/ftplugin/mercuryhdr.sh %<CR>:set ft=mercury ff=unix ts=4 sw=4 et<CR>
+if has("win32")
+  nnoremap <C-X>h !!sh "\%userprofile\%\\.vim\\ftplugin\\mercuryhdr.sh" %<CR>:set ft=mercury ff=unix ts=4 sw=4 et<CR>
+else
+  nnoremap <C-X>h !!$HOME/.vim/ftplugin/mercuryhdr.sh %<CR>:set ft=mercury ff=unix ts=4 sw=4 et<CR>
+endif
 
   " Go to the bottom window and rerun the last mmake command.
   " Reload any .err buffers that have changed.
   "
-nnoremap ,m <C-W>b:!mmake<UP><CR>
+nnoremap ,m <C-W>b:!make<UP><CR>
 autocmd! FileChangedShell *.err vi!
+
+  " Match all the occurances of the variable under the cursor
+  "
+augroup mercuryMatchVar
+  autocmd! CursorMoved,CursorMovedI,WinEnter <buffer> call s:HighlightMatchingVariables()
+augroup END
+
+fu! s:HighlightMatchingVariables()
+    " Avoid that we remove the popup menu.
+    " Return when there are no colors (looks like the cursor jumps).
+  if pumvisible() || (&t_Co < 8 && !has("gui_running"))
+    return
+  endif
+
+    " Get variable under cursor, or "" if empty
+  let l:variable = s:GetCurrentCursorVariable()
+
+  let l:lineL1PredStart = search("^[:a-z']", 'nWb')
+  let l:posEnd = searchpos('\v[.]($|\s+)', 'nW')
+
+    " We do not want to match a dot within strings or lists, etc.
+  while s:CurrentSynIsRegion(l:posEnd) > 0
+    let l:posEnd = searchpos('\v[.]($|\s+)%>' . l:posEnd[0] . 'l', 'nW')
+  endwhile
+
+  let l:lineL1PredEnd = l:posEnd[0]
+  if l:lineL1PredStart <= 0|let l:lineL1PredStart = line('w0')|endif
+  if l:lineL1PredEnd   <= 0|let l:lineL1PredEnd   = line('w$')|endif
+
+    " If we are still on the same spot, then abort
+  if exists('w:variable') && l:variable == w:variable &&
+        \ l:lineL1PredStart == w:lineL1PredStart &&
+        \ l:lineL1PredEnd   == w:lineL1PredEnd
+    return
+  elseif exists('w:variable_hl_on') && w:variable_hl_on
+    " Remove any previous match.
+    2match none
+    let w:variable_hl_on = 0
+  endif
+
+  let w:variable         = l:variable
+  let w:lineL1PredStart  = l:lineL1PredStart
+  let w:lineL1PredEnd    = l:lineL1PredEnd
+  let w:lineL1PredEndCol = l:posEnd[1]
+
+    " Abort if there is no variable under the cursor
+  if l:variable == ""|return|endif
+
+    " Underline all Variable occurances in the current (outer)
+    " predicate/function/pragma scope
+  let l:variableMatch = s:CreateVariableMatch(l:variable,
+        \ l:lineL1PredStart, l:lineL1PredEnd)
+  exe '2match Underlined ' . l:variableMatch
+  let w:variable_hl_on = 1
+endfu
+
+fu! s:CreateVariableMatch(variable, start, end)
+  return '/\v<' . escape(a:variable, '\') . '>' .
+        \ '%>' . (a:start - 1) . 'l' .
+        \ '%<' . (a:end   + 1) . 'l' . '/'
+endfu
+
+fu! s:CurrentSynIsRegion(pos)
+  if a:pos[0] == 0|return 0|endif
+  let l:id = synID(a:pos[0], a:pos[1], 0)
+  " TODO: Also check for mercuryString
+  return l:id == synIDtrans(l:id) ? 1 : 0
+endfu
+
+fu! s:GetCurrentCursorVariable()
+    " returns the variable under the cursor
+  let l:word = expand("<cword>")
+  if empty(matchstr(l:word, '\v^[A-Z]\c')) || l:word[0] ==# tolower(l:word[0])
+    return ""
+  else
+    return l:word
+  endif
+endfu
+
+fu! s:RenameCurrentVariable(keepName)
+  if !empty(w:variable)
+    call inputsave()
+    if a:keepName
+      let l:new = input('Enter a new variable name: ', w:variable)
+    else
+      let l:new = input('Enter a new variable name: ')
+    endif
+    call inputrestore()
+      " Allow for a silent return if the input is empty (most likely it means
+      " the user pressed ESC, or if input is unchanged
+    if empty(l:new) || l:new ==# w:variable
+      return
+    endif
+      " using the predicate range as a boundary for a global %s
+    let l:variableMatch = s:CreateVariableMatch(w:variable,
+          \ w:lineL1PredStart, w:lineL1PredEnd)
+    exe '%s' . l:variableMatch . escape(l:new, '\') . '/g'
+  else
+    echoerr 'Nothing selected to be renamed!'
+  endif
+endfu
+
+fu! s:MarkCurrentPred()
+  call setpos('.', [0, w:lineL1PredStart, 1])
+  normal! v
+  call setpos('.', [1, w:lineL1PredEnd, w:lineL1PredEndCol])
+endfu
diff --git a/vim/ftplugin/mercuryhdr.sh b/vim/ftplugin/mercuryhdr.sh
index 0005a24..7ba3b3a 100755
--- a/vim/ftplugin/mercuryhdr.sh
+++ b/vim/ftplugin/mercuryhdr.sh
@@ -1,35 +1,42 @@
 #!/bin/sh
-
+# vim: ft=sh ff=unix ts=4 sw=4 tw=78 et
+MODULE=$(echo $(basename "$1" ) | sed 's/\.m$//')
+FILE="${MODULE}.m"
 cat <<EOF
-%------------------------------------------------------------------------------%
-% $1
-% $([ -n "$USERNAME" ] && echo $USERNAME "")<$USER@$(hostname -d)>
-% $(date)
+%----------------------------------------------------------------------------%
 % vim: ft=mercury ff=unix ts=4 sw=4 et
-%
-%------------------------------------------------------------------------------%
-
-:- module $(echo $1 | sed 's/\./__/g;s/__m$//').
+%----------------------------------------------------------------------------%
+% File: $FILE
+% Copyright © $(date +%Y) $GIT_AUTHOR_NAME
+% Main author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+% Created on: $(date)
+% Stability: low
+%----------------------------------------------------------------------------%
+% TODO: module documentation
+%----------------------------------------------------------------------------%
+
+:- module $MODULE.
 
 :- interface.
 
-:- import_module io.
-
+% TODO: insert predicates & functions
 
+%----------------------------------------------------------------------------%
 
-:- pred main(io::di, io::uo) is det.
+% TODO: declare predicates & functions
 
-%------------------------------------------------------------------------------%
-%------------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
 :- implementation.
 
-:- import_module .
+% TODO: include/import/use modules
 
-%------------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
 
-main -->
+% TODO: implement predicates & functions
 
-%------------------------------------------------------------------------------%
-%------------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
+:- end_module $MODULE.
+%----------------------------------------------------------------------------%
 EOF
diff --git a/vim/syntax/mercury.vim b/vim/syntax/mercury.vim
index bce7bb1..4992559 100644
--- a/vim/syntax/mercury.vim
+++ b/vim/syntax/mercury.vim
@@ -1,7 +1,8 @@
-" Vim syntax file
+" vim: ft=vim ts=2 sw=2 et
 " Language:     Mercury
-" Maintainer:   Ralph Becket <rafe at cs.mu.oz.au>
-" vim: ts=2 sw=2 et
+" Maintainer:   Sebastian Godelet <sebastian.godelet at outlook.com>
+" Extensions:   *.m *.moo
+" Last Change:  2015-04-07
 
 if exists("b:current_syntax")
   finish
@@ -9,30 +10,23 @@ endif
 let b:current_syntax = "mercury"
 
   " Mercury is case sensitive.
-  "
 syn case match
+set synmaxcol=100
 
-  " The default highlighting for Mercury comments is to only highlight the
-  " initial `%' and subsequent `line' punctuation characters.  To highlight
-  " everything including the comment text, add
-  "
-  "   let mercury_highlight_full_comment = 1
-  "
-  " somewhere in your `.vimrc' file.
-  "
-  " By default, parts of lines that extend over 80 characters will be
-  " highlighted.  To avoid this behaviour, add
-  "
-  "   let mercury_no_highlight_overlong = 1
-  "
-  " somewhere in your `.vimrc' file.
-  "
-if exists("mercury_highlight_full_comment") && mercury_highlight_full_comment
-  syn region  mercuryComment      start=+%+ end=+.*$+                                           contains=mercuryToDo
-else
-  syn region  mercuryComment      start=+%[-=%*_]*+ end=+.*$+he=s-1                             contains=mercuryToDo
+if has("folding") && (!exists("mercury_no_folding") || !mercury_no_folding)
+    " folding is only changed (if not forced) if the Vim default (manual) is active,
+    " this avoids conflicts with existing user settings
+  if (&fdm == "manual") || (exists("mercury_folding_force") && mercury_folding_force)
+    set fdm=indent
+  endif
+    " the default foldminlines = 1 is not appropriate for Mercury,
+    " so we set it higher
+  if &foldminlines == 1
+    set foldminlines=10
+  endif
 endif
 
+syn match mercurySingleton      "\v<_([A-Z][a-z_A-Z0-9]*)?>"
 syn keyword mercuryKeyword      any_func
 syn keyword mercuryKeyword      any_pred
 syn keyword mercuryKeyword      atomic
@@ -68,7 +62,7 @@ syn keyword mercuryKeyword      require_complete_switch
 syn keyword mercuryKeyword      require_det
 syn keyword mercuryKeyword      require_erroneous
 syn keyword mercuryKeyword      require_failure
-syn keyword mercuryKeyword      require_multi 
+syn keyword mercuryKeyword      require_multi
 syn keyword mercuryKeyword      require_nondet
 syn keyword mercuryKeyword      require_semidet
 syn keyword mercuryKeyword      require_switch_arms_cc_multi
@@ -76,7 +70,7 @@ syn keyword mercuryKeyword      require_switch_arms_cc_nondet
 syn keyword mercuryKeyword      require_switch_arms_det
 syn keyword mercuryKeyword      require_switch_arms_erroneous
 syn keyword mercuryKeyword      require_switch_arms_failure
-syn keyword mercuryKeyword      require_switch_arms_multi 
+syn keyword mercuryKeyword      require_switch_arms_multi
 syn keyword mercuryKeyword      require_switch_arms_nondet
 syn keyword mercuryKeyword      require_switch_arms_semidet
 syn keyword mercuryKeyword      semidet
@@ -110,63 +104,586 @@ syn keyword mercuryCInterface   foreign_import_module
 syn keyword mercuryCInterface   foreign_proc
 syn keyword mercuryCInterface   foreign_type
 
-syn keyword mercuryCInterface   affects_liveness
-syn keyword mercuryCInterface     does_not_affect_liveness
-syn keyword mercuryCInterface     doesnt_affect_liveness
-syn keyword mercuryCInterface   attach_to_io_state 
-syn keyword mercuryCInterface   can_pass_as_mercury_type stable
-syn keyword mercuryCInterface   may_call_mercury will_not_call_mercury
-syn keyword mercuryCInterface   may_duplicate may_not_duplicate
-syn keyword mercuryCInterface   may_modify_trail will_not_modify_trail
-syn keyword mercuryCInterface   no_sharing unknown_sharing sharing
-syn keyword mercuryCInterface   promise_pure promise_semipure
-syn keyword mercuryCInterface   tabled_for_io local untrailed trailed 
-syn keyword mercuryCInterface   thread_safe not_thread_safe maybe_thread_safe
-syn keyword mercuryCInterface   will_not_throw_exception
+syn keyword mercuryForeignMod   affects_liveness
+syn keyword mercuryForeignMod     does_not_affect_liveness
+syn keyword mercuryForeignMod     doesnt_affect_liveness
+syn keyword mercuryForeignMod   attach_to_io_state
+syn keyword mercuryForeignMod   can_pass_as_mercury_type stable
+syn keyword mercuryForeignMod   may_call_mercury will_not_call_mercury
+syn keyword mercuryForeignMod   may_duplicate may_not_duplicate
+syn keyword mercuryForeignMod   may_modify_trail will_not_modify_trail
+syn keyword mercuryForeignMod   no_sharing unknown_sharing sharing
+syn keyword mercuryForeignMod   promise_pure promise_semipure
+syn keyword mercuryForeignMod   tabled_for_io local untrailed trailed
+syn keyword mercuryForeignMod   thread_safe not_thread_safe maybe_thread_safe
+syn keyword mercuryForeignMod   will_not_throw_exception
+syn keyword mercuryForeignMod   terminates
 
-syn keyword mercuryImpure       impure semipure
-
-syn keyword mercuryToDo         XXX TODO NOTE         
+syn keyword mercuryPurity       impure
+syn keyword mercuryPurity       promise_pure
+syn keyword mercuryPurity       promise_semipure
+syn keyword mercuryPurity       semipure
 
 syn keyword mercuryLogical      fail false true
 syn keyword mercuryLogical      if then else
-syn keyword mercuryLogical      impure_true 
+syn keyword mercuryLogical      impure_true
 syn keyword mercuryLogical      semidet_fail semidet_false
 syn keyword mercuryLogical      semidet_succeed semidet_true
 syn keyword mercuryLogical      some all not
 syn keyword mercuryLogical      try catch catch_any
 
-syn match   mercuryImplication  +<=>\|<=\|=>\|/\\\|\\/+
-syn match   mercuryNumCode      +0'.\|0[box][0-9a-fA-F]*+
-syn region  mercuryAtom         start=+'+ skip=+\\.+ end=+'+
-syn region  mercuryString       start=+"+ skip=+\\.+ end=+"+                              contains=mercuryStringFmt
-syn match   mercuryStringFmt    +\\[abfnrtv]\|\\x[0-9a-fA-F]*\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]+                                                                           contained
-syn	match   mercuryStringFmt    /\\[abfnrtv\\"]\|\\x[0-9a-fA-F]\+\\\|%[-+#*.0-9]*[dioxXucsfeEgGp]/ contained
-syn region  mercuryClauseHead   start=+^[a-zA-Z]+ end=+=\|:-\|\.\s*$\|-->+                    contains=mercuryComment,mercuryCComment,mercuryAtom,mercuryString
-syn region  mercuryCComment     start=+/\*+ end=+\*/+                                         contains=mercuryToDo
+syn keyword mercuryBool         yes no
+syn keyword mercuryOperator     div rem mod
+
+syn match   mercuryImplKeyword  "\v\$(file|grade|pred|module|line|\d+)>"
+syn match   mercuryOperator     "/"           " divide
+syn match   mercuryOperator     "//"          " (integer) divide
+syn match   mercuryDelimiter    ","           " list seperator or conjunction
+syn match   mercuryOperator     "-"           " substraction operator or unary minus
+syn match   mercuryOperator     "="           " unification
+syn match   mercuryOperator     "|"           " cons
+syn match   mercuryImplication  "->"          " 'then' arrow
+syn match   mercuryOperator     "-->"         " DCG clause
+syn match   mercuryOperator     "--->"        " 'typedef'
+syn match   mercuryOperator     "/\\"         " (binary) and
+syn match   mercuryOperator     "\\"          " (bitwise) complement
+syn match   mercuryOperator     "\\/"         " (binary) or
+syn match   mercuryLogical      "\\+"         " logical not
+syn match   mercuryOperator     "=\.\."       " Prolog univ
+syn match   mercuryOperator     "=<"          " greater equal or contravariant
+syn match   mercuryOperator     "=\\="        " not structual equal (for Prolog)
+syn match   mercuryOperator     "@"
+syn match   mercuryOperator     "@<"
+syn match   mercuryOperator     "@=<"
+syn match   mercuryOperator     "@>"
+syn match   mercuryOperator     "@>="
+syn match   mercuryOperator     ">="         " smaller equal or co-variant
+syn match   mercuryOperator     ">"          " greater
+syn match   mercuryOperator     ">>"         " right shift
+syn match   mercuryOperator     "<"          " smaller
+syn match   mercuryOperator     "<<"         " left shift
+syn match   mercuryOperator     "\\="        " not unify
+syn match   mercuryOperator     "\\=="       " not unify (for Prolog)
+syn match   mercuryOperator     "\~"
+syn match   mercuryOperator     "\~="
+syn match   mercuryOperator     ":="         " field update
+syn match   mercuryOperator     ":-"         " reverse implication
+syn match   mercuryOperator     "=:="        " Structural equality (for Prolog)
+syn match   mercuryOperator     "![:.]\?"    " State variable accessors
+syn match   mercuryImplication  ";"          " Disjunction
+syn match   mercuryOperator     "+"          " addition operator or unary plus
+syn match   mercuryOperator     "++"         " concatenation
+syn match   mercuryOperator     ":"
+syn match   mercuryOperator     "::"         " Type/Mode specifier
+syn match   mercuryOperator     "&"          " Parallel conjuction
+syn match   mercuryOperator     "?-"         " Prolog compatability
+syn match   mercuryOperator     "*"          " multiply
+syn match   mercuryOperator     "\^"         " field access
+syn match   mercuryOperator     /\v`[^`']+`/ " inlined operator
+syn match   mercuryImplication  "<=>\|<=\|=>"
+syn match   mercuryNumCode /\v<(0'.|0b[01]+|0o[0-7]+|0x\x+|[0-9]+)/
+syn match   mercuryFloat   /\v<([0-9]+\.[0-9]+([eE][-+]?[0-9]+)?)/
+syn region  mercuryAtom    start=+'+ skip=+\\'+   end=+'+ contains=
+      \ mercuryStringEsc, at mercuryFormatting,mercuryEscErr, at Spell
+syn region  mercuryString matchgroup=mercuryString
+      \ start=+"+ skip=/\v(\\x?\x+|\\)@<!\\"|""/ end=+"+ keepend contains=
+      \ mercuryStringFmt,mercuryStringEsc, at mercuryFormatting,
+      \ mercuryEscErr,mercuryStringEsc, at Spell
+syn match   mercuryStringFmt    /%[-+# *.0-9]*[dioxXucsfeEgGp]/       contained
+  " mercury*Esc are common to "mercuryAtom" and "mercuryString"
+syn match   mercuryEscErr       /\v\\([ \t]+$)@=/ contained " matching escaped newline
+syn match   mercuryEscErr       /\v\\[uUx]/ contained " must come before \\u\x{4}
+syn match   mercuryEscErr       /\v\\0/     contained " \0 literals are not allowed
+syn match   mercuryStringEsc    /\\$/       contained " matching escaped newline
+syn match   mercuryStringEsc    /\v\\[abfnrtv\\"]/     contained
+syn match   mercuryStringEsc    /\v\\u\x{4}/           contained
+syn match   mercuryStringEsc    /\v\\U00(10|0\x)\x{4}/ contained
+syn match   mercuryStringEsc    /\v\\x\x+\\/           contained
+syn match   mercuryStringEsc    /\v\\[0-7][0-7]+\\/    contained
+syn match   mercuryStringEsc    /\v""/ contained
+  " matching unbalanced brackets (before "mercuryTerm", "mercuryBlock", ...)
+  " TODO: Verify if contained is required
+syn match mercuryErrInAny       "(\|\[{\|}\|\]\|)"  " contained
+syn match mercuryTerminator     "\v\.(\s+|$)@=" " after mercuryErrInAny
+syn match mercuryOperator       "\.\."          " after mercuryTerminator
+
+  " see "https://github.com/Twinside/vim-haskellConceal"
+  " see "http://rapidtables.com/math/symbols/Basic_Math_Symbols.htm"
+if has("conceal") && (!exists("mercury_no_conceal") || !mercury_no_conceal)
+  hi clear Conceal
+  hi def link Conceal mercuryOperator
+  setlocal conceallevel=2
+
+    " A crude but simple "solution" to the compose operator problem
+  syn match mercuryOperator  "`compose`" conceal cchar=o
+
+  if exists("mercury_conceal_extra") && mercury_conceal_extra
+      " these characters only display properly on some machines if
+      " setglobal ambiw=double
+    if has("multi_byte") && (!has("win32") || (exists("ambiw") && ambiw == "double"))
+      syn match mercuryOperator  "/\\"          conceal cchar=∧
+      syn match mercuryOperator  "\\/"          conceal cchar=∨
+      syn match mercuryOperator  "`xor`"        conceal cchar=⊕
+      syn match mercuryOperator  "`member`"     conceal cchar=∈
+      syn match mercuryOperator  "`contains`"   conceal cchar=∋
+      syn match mercuryOperator  "`union`"      conceal cchar=∪
+      syn match mercuryOperator  "`intersect`"  conceal cchar=∩
+      syn match mercuryOperator  "`difference`" conceal cchar=∆
+      syn match mercuryOperator  "`insert`"     conceal cchar=⎀
+      syn match mercuryOperator  "`delete`"     conceal cchar=\
+      syn match mercuryOperator  "`subset`"     conceal cchar=⊆
+      syn match mercuryOperator  "`superset`"   conceal cchar=⊇
+    endif
+      " This avoids confusion of =< and =>
+    syn match mercuryOperator  ">="        conceal cchar=≥
+    syn match mercuryOperator  "=<"        conceal cchar=≤
+    syn match mercuryOperator  "\\=[=]\@!" conceal cchar=≠
+    syn match mercuryOperator  "`x`"       conceal cchar=×
+    syn match mercuryOperator  "//"        conceal cchar=÷
+
+       " unforunately, Vim does not allow different conceal colours,
+       " so these are not concealed by default
+    if exists("mercury_conceal_logical") && mercury_conceal_logical
+      syn match mercuryImplication "=>"   conceal cchar=⇒
+      syn match mercuryImplication "<="   conceal cchar=�
+      syn match mercuryImplication "<=>"  conceal cchar=⇔
+      syn keyword mercuryNumCode  inf     conceal cchar=∞
+      syn keyword mercuryLogical  some    conceal cchar=∃
+      syn keyword mercuryLogical  all     conceal cchar=∀
+      syn match mercuryLogical    "\\+"   conceal cchar=¬
+    endif
+  endif
+endif
+
+  " matching the `double star' after the multiplication operator
+syn match mercuryOperator "\v[*]{2}"
+  " All valid Mercury comments
+syn cluster mercuryComments contains=mercuryComment,mercuryCComment
+  " The clusters contain all valid Mercury code. The nesting is done to allow
+  " for matching of parenthesis, DCG terms and lists
+syn cluster mercuryTerms     contains=mercuryBlock,mercuryList,mercuryString,
+      \ mercuryDelimiter,mercuryAtom,mercuryNumCode,mercuryFloat,
+      \ @mercuryComments,mercuryKeyword,mercuryImplKeyword,
+      \ @mercuryFormatting,mercuryErrInAny,mercuryBool,mercuryOperator,
+      \ mercurySingleton,mercuryImplication,mercuryInlined,mercuryLogical,
+      \ mercuryPurity,mercuryDCGOrTuple
+
+syn region  mercuryList       matchgroup=mercuryBracket   start='\[' end=']'
+      \ transparent fold  contains=@mercuryTerms
+syn region  mercuryBlock      matchgroup=mercuryBracket   start='(' end=')'
+      \ transparent fold  contains=@mercuryTerms
+syn region  mercuryDCGOrTuple matchgroup=mercuryBracket   start='{' end='}'
+      \ transparent fold  contains=@mercuryTerms
+syn region  mercuryForeignModList matchgroup=mercuryBracket start='\[' end=']'
+      \ transparent fold  contained contains=mercuryForeignMod,
+      \ mercuryDelimiter, at mercuryComments, at mercuryFormatting,
+      \ mercuryString,mercuryOperator,mercuryBlock
+
+syn match mercuryClauseHead /\v^[a-zA-Z_]+[(]@=/
+
+if !exists("mercury_no_highlight_foreign") || !mercury_no_highlight_foreign
+    " Basic syntax highlighting for foreign code
+  syn cluster mercuryForeign contains=mercuryForeignModList,mercuryCInterface,
+        \ mercuryKeyword,mercuryOperator,
+        \ mercuryAtom, at mercuryComments,mercuryDelimiter,mercurySingleton,
+        \ @mercuryFormatting,mercuryForeignId
+
+  syn region  mercuryForeignCBlock       matchgroup=mercuryBracket start=/\v\(("C"|c)/rs=s+1 end=')'
+        \ transparent fold contained contains=@mercuryForeign,
+        \ mercuryCCode,mercuryBlock
+  syn region  mercuryForeignCSharpBlock  matchgroup=mercuryBracket start=/\v\(("C#"|csharp)/rs=s+1 end=')'
+        \ transparent fold contained contains=@mercuryForeign,
+        \ mercuryCSharpCode,mercuryBlock
+  syn region  mercuryForeignJavaBlock    matchgroup=mercuryBracket start=/\v\(("Java"|java)/rs=s+1 end=')'
+        \ transparent fold contained contains=@mercuryForeign,
+        \ mercuryJavaCode,mercuryBlock
+  syn region  mercuryForeignILBlock      matchgroup=mercuryBracket start=/\v\(("IL"|il)/rs=s+1 end=')'
+        \ transparent fold contained contains=@mercuryForeign,
+        \ mercuryILCode,mercuryBlock
+  syn region  mercuryForeignErlangBlock  matchgroup=mercuryBracket start=/\v\(("Erlang"|erlang)/rs=s+1 end=')'
+        \ transparent fold contained contains=@mercuryForeign,
+        \ mercuryErlangCode,mercuryBlock
+  syn cluster mercuryForeignBlock contains=mercuryForeignCBlock,
+        \ mercuryForeignCSharpBlock,mercuryForeignJavaBlock,
+        \ mercuryForeignErlangBlock,mercuryForeignILBlock
+  syn match   mercuryPragmaForeign /\v^\s*:-\s+pragma\s+foreign_(code|proc|decl|type|export(_enum)?|enum|import_module)/
+        \ transparent nextgroup=@mercuryForeignBlock
+
+    " C-Style syntax as a basis for C, C# and Java
+  syn keyword mercuryCLikeKeyword contained if else goto switch case for while
+  syn keyword mercuryCLikeKeyword contained do break continue return volatile
+  syn keyword mercuryCLikeKeyword contained extern typedef static default
+  syn keyword mercuryCLikeType contained void int char long byte unsigned signed
+  syn keyword mercuryCLikeType contained struct float double enum
+  syn match mercuryCLikeDelimiter ";\|," contained
+  syn match mercuryCLikeOperator "\v[-!+=*/><~?:%]" contained
+  syn match mercuryCLikeOperator "[-!+=*/><]\?=" contained
+  syn match mercuryCLikeOperator "--\|++" contained
+  syn match mercuryCLikeOperator "|\{1,2}\|&\{1,2}" contained
+  syn match mercuryCLikeBracket  "\[\|]" contained
+  syn match mercuryCLikeBracket  "\v[{}()]" contained
+  syn match mercuryCLikeCharEsc /\v\\\\([abfnrtv]|0[0-7]*|[xuU]\x+)?/ contained
+  syn match mercuryCLikeCharEsc +\\\\""+ contained
+  syn region mercuryCLikeChar start=+'+ end=+'+ contained contains=mercuryCLikeCharEsc
+  syn cluster mercuryCLike contains=mercuryCLikeKeyword,mercuryCLikeType
+  syn cluster mercuryCLike add=mercuryCLikeOperator,mercuryCComment,mercuryCLikeChar
+  syn cluster mercuryCLike add=mercuryNumCode,mercuryFloat,mercuryCLikeBracket
+  syn cluster mercuryCLike add=mercuryCLikeDelimiter,mercuryForeignIface
+  syn cluster mercuryCLike add=@mercuryFormatting
+
+    " C-Language formatting with Mercury types MR_*
+  syn keyword mercuryCType contained const size_t pid_t offset_t union
+  syn keyword mercuryCType contained MR_bool MR_Bool
+  syn keyword mercuryCType contained MR_Word MR_Integer MR_Unsigned
+  syn keyword mercuryCType contained MR_ArrayPtr MR_Float MR_file MercuryFile[Ptr]
+  syn keyword mercuryCType contained MR_String MR_ConstString MR_Char
+  syn match mercuryCType "\v<MR_((Pseudo)?TypeInfo|Construct_Info|TypeCtor(Desc|Info)|AllocSiteInfoPtr)|MercuryLock>" contained
+  syn match mercuryCType "\v<(MR_)?[u]?int(_least|_fast)?(8|16|32|64)_t>" contained
+  syn match mercuryForeignIface "\v<(MR_)?[U]?INT(_LEAST|_FAST)?(8|16|32|64)_(TYPE|LENGTH_MODIFIER)>" contained
+  syn keyword mercuryCKeyword contained typedef sizeof typeof offsetof
+  syn keyword mercuryCConst contained NULL EOF
+  syn keyword mercuryCConst contained CHAR_BIT CHAR_MAX CHAR_MIN
+  syn keyword mercuryCConst contained SCHAR_BIT SCHAR_MAX SCHAR_MIN
+  syn keyword mercuryCConst contained LONG_MAX ULONG_MAX LONG_MIN
+  syn keyword mercuryCConst contained LLONG_MAX ULLONG_MAX LLONG_MIN
+  syn keyword mercuryCConst contained INT_MAX UINT_MAX INT_MIN
+  syn keyword mercuryCConst contained SHRT_MAX USHRT_MAX SHRT_MIN
+  syn keyword mercuryCBool  contained MR_TRUE MR_FALSE
+  syn keyword mercuryCBool  contained MR_YES MR_NO
+  syn match mercuryForeignIface contained "\v<MR_[A-Z]+_LENGTH_MODIFIER>"
+  syn match mercuryForeignIface contained "\v<MR_THREAD_SAFE>"
+  syn match mercuryCFunc "\v<MR_(list_(empty|head|tail)|incr_hp((_atomic)?|((_type)?_msg))|assert|fatal_error|make_aligned_string)>" contained
+  syn match mercuryCPreProc "#\(if\(n\?def\)\?\|else\|elif\|endif\|define\|include\|error\|warning\|line\)" contained
+  syn match mercuryCPreProc    "\v(\\){1,2}$" contained
+  syn match mercuryCStringFmt  /%[I]\?[-+# *.0-9]*[dioxXucsfeEgGp]/ contained
+  syn region mercuryCString start=+""+ end=+""+ contained contains=mercuryCStringFmt,mercuryCLikeCharEsc, at Spell
+  syn region mercuryCString start=+\v\\"+ end=+\v\\"+ contained contains=mercuryCStringFmt,mercuryCLikeCharEsc, at Spell
+  syn cluster mercuryC contains=@mercuryCLike,mercuryCType,mercuryCKeyword
+  syn cluster mercuryC add=mercuryCPreProc,mercuryCString,mercuryCBool,mercuryCConst,mercuryCFunc
+
+    " C++-Style for Java and C# (bool, // comments, exception handling etc)
+  syn keyword mercuryCppLikeKeyword contained class new delete try catch finally
+        \ instanceof abstract throw[s] extends this super base synchronize[d]
+        \ override foreach in using import ref implements
+  syn keyword mercuryCppLikeBool contained true false
+  syn keyword mercuryCppLikeConst contained null[ptr]
+  syn match mercuryCppLikeOperator "@" contained
+  syn match mercuryCppLikeType "\v<((io|runtime)\.(\_\s+)?)?(MR_)[A-Za-z_0-9]+>" contained
+  syn keyword mercuryCppLikeMod contained public private protected internal virtual
+  syn keyword mercuryCppLikeMod contained final readonly volatile transient
+  syn cluster mercuryCppLike contains=@mercuryCLike,mercuryCPreProc,mercuryCString,mercuryCppLikeComment,mercuryCppLikeKeyword
+  syn cluster mercuryCppLike add=mercuryCppLikeBool,mercuryCppLikeMod,mercuryCppLikeConst,mercuryCppLikeType,mercuryCppLikeOperator
+
+    " Declaration for ISO C
+  syn region mercuryCCode      matchgroup=mercuryString start=+"+ skip=+""+ end=+"+ transparent fold contained contains=@mercuryC
+
+   " Declaration for C#
+  syn match mercuryCSharpStringFmt "{[0-9]}" contained
+  syn match mercuryCSharpStringFmtEsc "{{\|}}" contained
+  syn keyword mercuryCSharpType contained object string decimal bool uint
+  syn keyword mercuryCSharpType contained ulong sbyte ushort
+  syn match mercuryCSharpType contained "\v<mr_bool>\."he=e-1 nextgroup=mercuryCSharpBool
+  syn match mercuryCSharpBool contained "\v<(YES|NO)>"
+  syn match mercuryCSharpType "\v<System\.((IO|Text|Diagnostics)\.)?[A-Z][A-Za-z_0-9]+>"
+  syn region mercuryCSharpString start=+""+ end=+""+ contained contains=mercuryCLikeCharEsc,
+        \ mercuryCSharpStringFmt,mercuryCSharpStringFmtEsc, at Spell
+  syn region mercuryCSharpString start=+\v\\"+ end=+\v\\"+ contained contains=mercuryCLikeCharEsc,
+        \ mercuryCSharpStringFmt,mercuryCSharpStringFmtEsc, at Spell
+  syn cluster mercuryCSharp contains=@mercuryCppLike,mercuryCSharpString,mercuryCSharpType
+  syn region mercuryCSharpCode matchgroup=mercuryString start=+"+ skip=+""+ end=+"+ transparent fold contained
+        \ contains=@mercuryCSharp
+
+    " Declaration for Java
+  syn match mercuryJavaType "\v<([a-z_][A-Za-z0-9_]*\.(\_\s+)?)+[A-Z][A-Z_a-z0-9]+>" contained
+  syn match mercuryJavaType "\v<(String(Builder)?|Override|Object|Integer|Byte)>" contained
+  syn match mercuryJavaType "\v<(Short|Float|Double|Void|Boolean|Character|System|Runtime|boolean)>" contained
+  syn match mercuryJavaType "\v<bool>\."he=e-1 contained nextgroup=mercuryJavaBool
+  syn match mercuryJavaBool contained "\v<(YES|NO)>"
+  syn region mercuryJavaCode   matchgroup=mercuryString start=+"+ skip=+""+ end=+"+
+        \ transparent fold contained contains=@mercuryCppLike,mercuryCString,mercuryJavaType
+
+    " Declaration for .NET IL
+  syn match mercuryILType "\v<[u]?int(8|16|32|64)|float(32|64)>" contained
+  syn cluster mercuryIL contains=@mercuryCSharp,mercuryILType
+  syn region mercuryILCode matchgroup=mercuryString start=+"+ skip=+""+ end=+"+ transparent fold contained contains=@mercuryIL
+
+    " Declaration for Erlang
+  syn keyword mercuryErlangKeyword contained after and andalso band begin bnot bor bsl bsr bxor case
+        \ catch cond end fun if let not of orelse query receive throw try when xor
+  syn keyword mercuryErlangBool true false
+  syn match mercuryErlangExtNumLiteral "\v([2-9]|[12][0-9]|3[0-6])#[A-Za-z0-9]+" contained
+  syn match mercuryErlangOperator "\v[?]" contained
+  syn match mercuryErlangLogical "\v[,;.]" contained
+  syn region mercuryErlangString start=+""+ end=+""+ contained contains=@Spell
+  syn region mercuryErlangString start=+\v\\"+ end=+\v\\"+ contained contains=@Spell
+  syn cluster mercuryErlangTerms contains=mercuryErlangBlock,mercuryErlangList,
+        \ mercuryErlangString,mercuryCLikeChar,mercuryNumCode,
+        \ mercuryErlangExtNumLiteral,mercuryFloat,mercuryComment,mercuryKeyword,
+        \ mercuryErlangKeyword, mercuryErlangOperator, mercuryCComment,
+        \ mercuryErlangBool,mercuryOperator,mercurySingleton,mercuryImplication,
+        \ mercuryErlangDCGAction,mercuryErlangLogical, at mercuryFormatting
+  syn region  mercuryErlangList contained matchgroup=mercuryBracket
+        \ start='\[' end=']' transparent fold  contains=@mercuryErlangTerms
+  syn region  mercuryErlangBlock    contained matchgroup=mercuryBracket
+        \ start='(' end=')'  transparent fold  contains=@mercuryErlangTerms
+  syn region  mercuryErlangDCGAction contained matchgroup=mercuryBracket
+        \ start='{' end='}'  transparent fold  contains=@mercuryErlangTerms
+
+  syn cluster mercuryErlang contains=@mercuryErlangTerms,mercuryErlangDCGAction,
+        \ mercuryForeignIface
+
+  syn region mercuryErlangCode   matchgroup=mercuryString start=+"+ skip=+""+ end=+"+
+        \ transparent fold contained contains=@mercuryErlang
+
+    " Matching the foreign language name identifiers, this comes after all the
+    " code blocks, to match the identifiers in quotes
+  syn match mercuryForeignId /\v<(c|csharp|java|il|erlang)>/ contained
+  syn region mercuryForeignId contained matchgroup=mercuryString
+        \ start=+\v["](C#|Java|C|I[Ll]|Erlang)["]{-}+rs=s+1 end=+"+
+
+    " Matching foreign interface builtins and success indicator
+  syn keyword mercuryForeignIface contained SUCCESS_INDICATOR
+  syn match mercuryForeignIface "\v<builtin.[A-Z][A-Z_0-9]+>" contained
+  syn match mercuryForeignIface "\v<MR_(VERSION|FULLARCH|CYGWIN|WIN32|MINGW64|COMPARE_(LESS|EQUAL|GREATER)|ALLOC_ID)>" contained
+endif
+
+if !exists("mercury_no_highlight_trailing_whitespace") || !mercury_no_highlight_trailing_whitespace
+  syn match mercuryWhitespace "\v[ ]+[\n]@="
+  syn cluster mercuryFormatting add=mercuryWhitespace
+endif
+
+if !exists("mercury_no_highlight_tabs") || !mercury_no_highlight_tabs
+  syn match mercuryWhitespace "\t"
+  syn cluster mercuryFormatting add=mercuryWhitespace
+endif
+
+  " Comment handling
+syn match mercuryCommentFirstSpace contained "\v[%*]@<=[ ]{1}([\t ]*[\n])@!"
+      \ nextgroup=@mercuryCommentSpecialLines
+syn match mercuryCommentInfo contained "\v(Main |Original )?[Aa]uthor[s]?[^\n:]*[:]@="
+      \ nextgroup=mercuryCommentOp
+syn match mercuryCommentInfo contained "\v(File|Created on|Date|Source|Stability)[:]@="
+      \ nextgroup=mercuryCommentOp
+
+syn keyword mercuryToDo contained XXX TODO NOTE[_TO_IMPLEMENTORS] MISSING HACK
+      \ nextgroup=mercuryCommentOp
+syn keyword mercuryToDo contained HINT WARNING IMPORTANT
+      \ nextgroup=mercuryCommentOp
+
+  " End of special file markers
+syn match mercuryCommentOp contained ": " nextgroup=@mercuryStability
+
+syn match mercuryCopyrightYear "\v (19|20)[0-9][0-9]([, -]+(19|20)[0-9][0-9])*" contained
+if has("conceal") && (!exists("mercury_no_conceal") || !mercury_no_conceal)
+  syn match mercuryCopyrightSymbol "\v\([cC]\)|©" conceal cchar=© contained nextgroup=mercuryCopyrightYear
+else
+  syn match mercuryCopyrightSymbol "\v\([cC]\)|©" contained nextgroup=mercuryCopyrightYear
+endif
+syn match mercuryCommentInfo "\vCopyright " contained nextgroup=mercuryCopyrightSymbol
+
+  " Matching Vim modeline
+syn match mercuryModelineParam contained "\v<(sw|ts|tw|wm|ff|ft|et|expandtab)>"
+syn match mercuryModelineValue contained "\v<(mercury|unix)>"
+syn region mercuryModeline contained matchgroup=mercuryCommentToken start="vim:" end="\v[\n]@="
+      \ oneline contains=mercuryModelineParam,mercuryModelineValue,mercuryNumCode,
+      \ mercuryOperator
+
+  " Highlights the output of the Mercury error command (in extras)
+syn match mercuryCommentErr "\v(\* )@<=###[ ]@=" contained
+
+  " Indicates stability of the module with colours (red, yellow, green)
+syn keyword mercuryStabilityLow    contained low    nextgroup=mercuryStabilityTo
+syn keyword mercuryStabilityMedium contained medium nextgroup=mercuryStabilityTo
+syn keyword mercuryStabilityHigh   contained high
+syn match mercuryStabilityTo "\v-| to " contained nextgroup=@mercuryStability
+
+  " Matches file names, email, file and http addresses (on a best effort basis).
+  " This avoids spell checking on those,
+  " and could also be used for plug-in development to open a browser, etc.
+syn match mercuryCommentUri contained "\v<[-0-9a-zA-Z.+_]+[@][-0-9a-zA-Z.+_]+\.[a-zA-Z]{2,10}>"
+syn match mercuryCommentUri contained "\v<(http[s]?|file)://[^ ><]+>"
+syn match mercuryCommentUri contained "\v<([a-z][a-z0-9._]+[/])*[a-z][a-z0-9._]+[.]m>"
+
+syn cluster mercuryStability contains=mercuryStabilityLow,mercuryStabilityMedium,mercuryStabilityHigh
+syn cluster mercuryCommentSpecialLines contains=mercuryCommentInfo,mercuryModeLine
+syn cluster mercuryCommentDirectives contains=@Spell,mercuryToDo,mercuryCommentFirstSpace
+syn cluster mercuryCommentDirectives add=mercuryCommentUri
+
+if exists("mercury_highlight_comment_special") && mercury_highlight_comment_special
+  syn match mercuryCommentSlash "/" contained nextgroup=mercuryCommentArity
+  syn match mercuryCommentArity "\v\d+" contained
+  syn match mercuryCommentSingleQuote /\v'[A-Za-z._0-9()]+'/ contained nextgroup=mercuryCommentSlash
+
+    " Header means the line describing the Arguments of a predicate or function,
+    " terminated with a colon. This also stops spell check on the argument names,
+    " which Vim is not good at dealing with.
+  syn region mercuryCommentHeader contained matchgroup=mercuryString
+        \ start='\v[a-z][A-Za-z._0-9]*([(]([)]|[\[][a-z"])@!|\s*[=])@='
+        \ matchgroup=NONE keepend
+        \ end="\v([.])|([:][-]@!)|(<[a-z]@=)|[)%][ \t]*[\n]@="
+        \ contains=mercuryOperator,mercuryCommentHeaderBlock,
+        \ mercuryCommentHeaderList,mercuryCommentHeaderTuple,
+        \ mercuryErrInAny,mercuryCommentHeaderCont, at mercuryFormatting
+  syn match mercuryCommentHeaderCont contained "\v^[ \t]*[%]"
+  syn region mercuryCommentHeaderList contained matchgroup=mercuryBracket
+        \ start='\[' end=']' transparent fold
+        \ contains=@mercuryTerms,mercuryCommentHeaderCont
+  syn region mercuryCommentHeaderBlock contained matchgroup=mercuryBracket
+        \ start='(' end=')' transparent fold
+        \ contains=@mercuryTerms,mercuryCommentHeaderCont
+  syn region  mercuryCommentHeaderTuple contained matchgroup=mercuryBracket
+        \ start='{' end='}' transparent fold
+        \ contains=@mercuryTerms,mercuryCommentHeaderCont
+  syn region mercuryCommentTexSingleQuote contained oneline
+        \ start="\v`[^`]@=" end="\v'" nextgroup=mercuryCommentSlash
+  syn region mercuryCommentTexDblQuote start="``" end="''" oneline contained
+        \ contains=@Spell
+
+  syn cluster mercuryCommentSpecialLines add=mercuryCommentHeader
+  syn cluster mercuryCommentDirectives add=mercuryCommentSingleQuote
+  syn cluster mercuryCommentDirectives add=@mercuryCommentTex
+  syn cluster mercuryCommentTex contains=mercuryCommentTexDblQuote
+  syn cluster mercuryCommentTex contains=mercuryCommentTexSingleQuote
+endif
+
+if exists("mercury_highlight_full_comment") && mercury_highlight_full_comment
+  hi def link mercuryComment        Comment
+  hi def link mercuryCommentUri     Underlined
+  hi def link mercuryCComment       Comment
+  hi def link mercuryCppLikeComment Comment
+
+  syn region mercuryComment start=/%/ end=/\v[\n]@=/ oneline contains=
+        \ @mercuryCommentDirectives, at mercuryFormatting
+  syn region mercuryCComment start="/\*" end="\*/" fold contains=
+        \ @mercuryCommentDirectives, at mercuryFormatting,mercuryCommentErr
+  syn region mercuryCppLikeComment start="//" end=/\v[\n]@=/ oneline contained contains=
+        \ @mercuryCommentDirectives, at mercuryFormatting
+else
+    " NOTE: the regions itself are not highlighted, just their start/end
+    " tokens, this is needed in order to fake "transparent", which could be used
+    " instead but does not support @Spell as a side-effect
+  hi def link mercuryComment        Normal
+  hi def link mercuryCComment       Normal
+  hi def mercuryCommentUri     term=underline cterm=underline gui=underline
+  hi def link mercuryCppLikeComment Normal
+  hi def link mercuryLeadTrailStar  Comment
+
+  syn match mercuryLeadTrailStar contained "^\v[ \t]*[*]+|[*]+$" nextgroup=mercuryCommentFirstSpace
+  syn region mercuryComment matchgroup=mercuryCommentToken start=/%[-=%*_]*/ end=/\v[\n]@=/ oneline
+        \ contains=@mercuryCommentDirectives, at mercuryFormatting
+  syn region mercuryCComment matchgroup=mercuryCommentToken start="\v/\*" end="\v[*]+/" keepend fold
+        \ contains=@mercuryCommentDirectives,mercuryLeadTrailStar, at mercuryFormatting,
+        \ mercuryCommentErr
+  syn region mercuryCppLikeComment matchgroup=mercuryCommentToken start="//" end=/\v[\n]@=/ oneline
+        \ contained contains=@mercuryCommentDirectives, at mercuryFormatting
+endif
+
+  " Matching the Unix shebang
+syn region mercuryShebang matchgroup=mercuryCommentToken  start="^\%1l#!/" end=/\v.+$/
+      \ oneline
+
+  " Matching over-long lines
 if !exists("mercury_no_highlight_overlong") || !mercury_no_highlight_overlong
-  " The complicated regexp here matches an 80-column string,
-  " with proper treatment of tabs (assuming the tab size is 8):
-  " each row consists of 10 columns, and each column consists of either 8
-  " non-tab characters, or 0-7 non-tab characters followed by a tab.
-  syn match   mercuryFirst80 +^\([^	]\{8}\|[^	]\{0,7}	\)\{10}+                                contains=ALL
-  syn match   mercuryTooLong +^\([^	]\{8}\|[^	]\{0,7}	\)\{10}..*+                             contains=mercuryFirst80
+  syn match mercuryTooLong /\%80v[^")}\]%]*/
+  syn cluster mercuryFormatting add=mercuryTooLong
 endif
 
-syn sync fromstart
-
-hi link mercuryComment          Comment
-hi link mercuryCComment         Comment
-hi link mercuryNumCode          Special
-hi link mercuryImpure           Special
-hi link mercuryKeyword          Keyword
-hi link mercuryPragma           PreProc
-hi link mercuryCInterface       PreProc
-hi link mercuryToDo             Todo
-hi link mercuryLogical          Special
-hi link mercuryImplication      Special
-hi link mercuryClauseHead       Statement
-hi link mercuryString           String
-hi link mercuryStringFmt        Special
-hi link mercuryAtom             Constant
-hi link mercuryTooLong          ErrorMsg
+  " Clear all syntax (this is maybe not needed for newer versions of Vim
+syn sync clear
+  " sync on a comment start, this assumes that no line comment is within a
+  " C-style comment
+syn sync match mercurySync grouphere NONE "\v^[%]------"
+
+hi def link mercuryAccess           Identifier
+hi def link mercurySingleton        Identifier
+hi def link mercuryAtom             Constant
+hi def link mercuryBracket          Delimiter
+hi def link mercuryBool             Special
+hi def link mercuryClauseHead       Statement
+hi def link mercuryCommentErr       ErrorMsg
+hi def link mercuryCommentToken     Comment
+hi def link mercuryCommentInfo      Identifier
+if exists("mercury_highlight_comment_special") && mercury_highlight_comment_special
+  hi def link mercuryCommentSlash   Operator
+  hi def link mercuryCommentArity   Number
+  hi def link mercuryCommentHeaderCont Comment
+  hi def link mercuryCommentSingleQuote  String
+  hi def link mercuryCommentTexDblQuote  String
+  hi def link mercuryCommentTexSingleQuote  String
+endif
+hi def link mercuryCommentOp        Operator
+hi def link mercuryCopyrightSymbol  Operator
+hi def link mercuryCopyrightYear    Constant
+hi def link mercuryCInterface       mercuryPragma
+if !exists("mercury_no_highlight_foreign") || !mercury_no_highlight_foreign
+  hi def link mercuryForeignId        Identifier
+  hi def link mercuryCLikeBracket     mercuryBracket
+  hi def link mercuryCLikeOperator    mercuryOperator
+  hi def link mercuryCLikeChar        mercuryAtom
+  hi def link mercuryCLikeCharEsc     mercuryStringEsc
+  hi def link mercuryCLikeDelimiter   mercuryDelimiter
+  hi def link mercuryCLikeKeyword     Keyword
+  hi def link mercuryCLikeString      String
+  hi def link mercuryCppLikeType      Type
+  hi def link mercuryCLikeType        Type
+  hi def link mercuryCBool            mercuryBool
+  hi def link mercuryCConst           Constant
+  hi def link mercuryCFunc            Identifier
+  hi def link mercuryCKeyword         Keyword
+  hi def link mercuryCStringFmt       mercuryStringFmt
+  hi def link mercuryCType            Type
+  hi def link mercuryCPreProc         mercuryPragma
+  hi def link mercuryCppLikeBool      mercuryBool
+  hi def link mercuryCppLikeConst     Constant
+  hi def link mercuryCppLikeKeyword   Keyword
+  hi def link mercuryCppLikeMod       mercuryAccess
+  hi def link mercuryCppLikeOperator  mercuryOperator
+  hi def link mercuryCString          String
+  hi def link mercuryCSharpBool       mercuryBool
+  hi def link mercuryCSharpString     String
+  hi def link mercuryCSharpStringFmt  mercuryStringFmt
+  hi def link mercuryCSharpStringFmtEsc mercuryStringEsc
+  hi def link mercuryCSharpType       Type
+  hi def link mercuryJavaBool         mercuryBool
+  hi def link mercuryJavaType         Type
+  hi def link mercuryILType           Type
+  hi def link mercuryErlangKeyword    Keyword
+  hi def link mercuryErlangOperator   Operator
+  hi def link mercuryErlangBool       mercuryBool
+  hi def link mercuryErlangExtNumLiteral Number
+  hi def link mercuryErlangString     String
+  hi def link mercuryErlangLogical    mercuryLogical
+endif
+hi def link mercuryDelimiter        Delimiter
+hi def link mercuryPurity           Special
+hi def link mercuryImplKeyword      Identifier
+hi def link mercuryKeyword          Keyword
+hi def link mercuryModelineParam    Identifier
+hi def link mercuryModelineValue    Constant
+hi def link mercuryNumCode          Number
+hi def link mercuryFloat            Float
+hi def link mercuryPragma           PreProc
+hi def link mercuryForeignMod       mercuryForeignIface
+hi def link mercuryForeignOperator  Operator
+hi def link mercuryForeignIface     Identifier
+hi def link mercuryImplication      Special
+hi def link mercuryLogical          Special
+hi def link mercuryEscErr           ErrorMsg
+hi def link mercuryErrInAny         ErrorMsg
+hi def link mercuryOperator         Operator
+hi def link mercuryInlined          Operator
+hi def mercuryStabilityLow     ctermfg=red        guifg=red        term=bold
+      \ cterm=bold gui=bold
+hi def mercuryStabilityMedium  ctermfg=darkyellow guifg=darkyellow term=bold
+      \ cterm=bold gui=bold
+hi def mercuryStabilityHigh    ctermfg=darkgreen  guifg=darkgreen  term=bold
+      \ cterm=bold gui=bold
+hi def link mercuryStabilityTo      Delimiter
+hi def link mercuryString           String
+hi def link mercuryStringEsc        Identifier
+hi def link mercuryStringFmt        Special
+hi def link mercuryToDo             Todo
+hi def link mercuryTooLong          ErrorMsg
+hi def link mercuryWhitespace       mercuryTodo
+hi def link mercuryTerminator       Delimiter
+hi def link mercuryType             Type


More information about the reviews mailing list