From 91dc04a5e12a3d0c5be56768ded5971bc80e6f8e Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Tue, 16 Jan 2024 17:45:57 +0000 Subject: [PATCH] vim-patch:9.1.0013: Modula2 filetype support lacking (#27020) Problem: Modula2 filetype support lacking Solution: Improve the Modula-2 runtime support, add additional modula2 dialects, add compiler plugin, update syntax highlighting, include syntax tests, update Makefiles (Doug Kearns) closes: vim/vim#6796 closes: vim/vim#8115 https://github.com/vim/vim/commit/68a89470693c7687d4e736ca056c05de632e3ac7 - Luaify the detection script: - Split the `(*!m2foo*)` and `(*!m2foo+bar*)` detection into two Lua patterns, as Lua capture groups cannot be used with `?` and friends (as they only work on character classes). - Use `vim.api.nvim_buf_call()` (ew) to call `modula2#SetDialect()` to ensure `b:modula2` is set for the given bufnr. - Skip the syntax screendump tests. (A shame as they test some of the detection from `(*!m2foo+bar*)` tags, but I tested this locally and it seems to work) - Port the synmenu.vim changes from Vim9 script. (Also tested this locally) - (And also add the missing comma for `b:browsefilter` from earlier.) Co-authored-by: Doug Kearns --- runtime/autoload/modula2.vim | 31 ++ runtime/compiler/gm2.vim | 26 ++ runtime/doc/filetype.txt | 1 + runtime/doc/syntax.txt | 50 +++ runtime/ftplugin/modula2.vim | 35 ++- runtime/lua/vim/filetype.lua | 4 +- runtime/lua/vim/filetype/detect.lua | 55 +++- runtime/makemenu.vim | 6 +- runtime/synmenu.vim | 47 +-- runtime/syntax/modula2.vim | 71 +---- runtime/syntax/modula2/opt/iso.vim | 380 +++++++++++++++++++++++ runtime/syntax/modula2/opt/pim.vim | 377 +++++++++++++++++++++++ runtime/syntax/modula2/opt/r10.vim | 452 ++++++++++++++++++++++++++++ test/old/testdir/test_filetype.vim | 38 ++- 14 files changed, 1468 insertions(+), 105 deletions(-) create mode 100644 runtime/autoload/modula2.vim create mode 100644 runtime/compiler/gm2.vim create mode 100644 runtime/syntax/modula2/opt/iso.vim create mode 100644 runtime/syntax/modula2/opt/pim.vim create mode 100644 runtime/syntax/modula2/opt/r10.vim diff --git a/runtime/autoload/modula2.vim b/runtime/autoload/modula2.vim new file mode 100644 index 0000000000..284dc2768f --- /dev/null +++ b/runtime/autoload/modula2.vim @@ -0,0 +1,31 @@ +" Vim filetype plugin file +" Language: Modula-2 +" Maintainer: Doug Kearns +" Last Change: 2024 Jan 04 + +" Dialect can be one of pim, iso, r10 +function modula2#GetDialect() abort + + if exists("b:modula2.dialect") + return b:modula2.dialect + endif + + if exists("g:modula2_default_dialect") + let dialect = g:modula2_default_dialect + else + let dialect = "pim" + endif + + return dialect +endfunction + +function modula2#SetDialect(dialect, extension = "") abort + if exists("b:modula2") + unlockvar! b:modula2 + endif + + let b:modula2 = #{ dialect: a:dialect, extension: a:extension } + lockvar! b:modula2 +endfunction + +" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker: diff --git a/runtime/compiler/gm2.vim b/runtime/compiler/gm2.vim new file mode 100644 index 0000000000..5053912200 --- /dev/null +++ b/runtime/compiler/gm2.vim @@ -0,0 +1,26 @@ +" Vim compiler file +" Compiler: GNU Modula-2 Compiler +" Maintainer: Doug Kearns +" Last Change: 2024 Jan 04 + +if exists("current_compiler") + finish +endif +let current_compiler = "gm2" + +if exists(":CompilerSet") != 2 " older Vim always used :setlocal + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo&vim + +CompilerSet makeprg=gm2 +CompilerSet errorformat=%-G%f:%l:%c:\ error:\ compilation\ failed, + \%f:%l:%c:\ %trror:\ %m, + \%f:%l:%c:\ %tarning:\ %m, + \%f:%l:%c:\ %tote:\ %m, + \%-G%.%# + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index 6c2cddea54..29b929b8a5 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -146,6 +146,7 @@ variables can be used to overrule the filetype used for certain extensions: `*.cls` g:filetype_cls `*.csh` g:filetype_csh |ft-csh-syntax| `*.dat` g:filetype_dat + `*.def` g:filetype_def `*.f` g:filetype_f |ft-forth-syntax| `*.frm` g:filetype_frm |ft-form-syntax| `*.fs` g:filetype_fs |ft-forth-syntax| diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 8cbb958e35..9164171152 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -2206,6 +2206,56 @@ have the following in your vimrc: > let filetype_m = "mma" +MODULA2 *modula2.vim* *ft-modula2-syntax* + +Vim will recognise comments with dialect tags to automatically select a given +dialect. + +The syntax for a dialect tag comment is: > + + taggedComment := + '(*!' dialectTag '*)' + ; + + dialectTag := + m2pim | m2iso | m2r10 + ; + + reserved words + m2pim = 'm2pim', m2iso = 'm2iso', m2r10 = 'm2r10' + +A dialect tag comment is recognised by Vim if it occurs within the first 200 +lines of the source file. Only the very first such comment is recognised, any +additional dialect tag comments are ignored. + +Example: > + + DEFINITION MODULE FooLib; (*!m2pim*) + ... + +Variable g:modula2_default_dialect sets the default Modula-2 dialect when the +dialect cannot be determined from the contents of the Modula-2 file: if +defined and set to 'm2pim', the default dialect is PIM. + +Example: > + + let g:modula2_default_dialect = 'm2pim' + + +Highlighting is further configurable for each dialect via the following +variables. + +Variable Highlight ~ +*modula2_iso_allow_lowline* allow low line in identifiers +*modula2_iso_disallow_octals* disallow octal integer literals +*modula2_iso_disallow_synonyms* disallow "@", "&" and "~" synonyms + +*modula2_pim_allow_lowline* allow low line in identifiers +*modula2_pim_disallow_octals* disallow octal integer literals +*modula2_pim_disallow_synonyms* disallow "&" and "~" synonyms + +*modula2_r10_allow_lowline* allow low line in identifiers + MOO *moo.vim* *ft-moo-syntax* If you use C-style comments inside expressions and find it mangles your diff --git a/runtime/ftplugin/modula2.vim b/runtime/ftplugin/modula2.vim index 8c4a876c0f..9c1acc276a 100644 --- a/runtime/ftplugin/modula2.vim +++ b/runtime/ftplugin/modula2.vim @@ -11,32 +11,43 @@ let b:did_ftplugin = 1 let s:cpo_save = &cpo set cpo&vim -setlocal comments=s0:(*,mb:\ ,ex:*) -setlocal commentstring=(*%s*) +let s:dialect = modula2#GetDialect() + +if s:dialect ==# "r10" + setlocal comments=s:(*,m:\ ,e:*),:! + setlocal commentstring=!\ %s +else + setlocal commentstring=(*%s*) + setlocal comments=s:(*,m:\ ,e:*) +endif setlocal formatoptions-=t formatoptions+=croql +let b:undo_ftplugin = "setl com< cms< fo<" + if exists("loaded_matchit") && !exists("b:match_words") - " The second branch of the middle pattern is intended to match CASE labels + let b:match_ignorecase = 0 + " the second branch of the middle pattern is intended to match CASE labels let b:match_words = '\:\,' .. - \ '\<\%(BEGIN\|CASE\|FOR\|IF\|LOOP\|WHILE\|WITH\)\>' .. - \ ':' .. - \ '\<\%(ELSIF\|ELSE\)\>\|\%(^\s*\)\@<=\w\+\%(\s*\,\s*\w\+\)\=\s*\:=\@!' .. - \ ':' .. - \ '\' + \ '\<\%(BEGIN\|CASE\|FOR\|IF\|LOOP\|WHILE\|WITH\|RECORD\)\>' .. + \ ':' .. + \ '\<\%(ELSIF\|ELSE\)\>\|\%(^\s*\)\@<=\w\+\%(\s*\,\s*\w\+\)\=\s*\:=\@!' .. + \ ':' .. + \ '\,' .. + \ '(\*:\*),<\*:\*>' + let b:match_skip = 's:Comment\|Pragma' + let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_skip b:match_words" endif if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") - let b:browsefilter = "Modula-2 Source Files (*.def *.mod)\t*.def;*.mod\n" + let b:browsefilter = "Modula-2 Source Files (*.def, *.mod)\t*.def;*.mod\n" if has("win32") let b:browsefilter ..= "All Files (*.*)\t*\n" else let b:browsefilter ..= "All Files (*)\t*\n" endif + let b:undo_ftplugin ..= " | unlet! b:browsefilter" endif -let b:undo_ftplugin = "setl com< cms< fo< " .. - \ "| unlet! b:browsefilter b:match_words" - let &cpo = s:cpo_save unlet s:cpo_save diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 8cd5f19569..a83c74fd7c 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -341,7 +341,7 @@ local extension = { decl = detect.decl, dec = detect.decl, dcl = detect_seq(detect.decl, 'clean'), - def = 'def', + def = detect.def, desc = 'desc', directory = 'desktop', desktop = 'desktop', @@ -674,8 +674,6 @@ local extension = { mmp = 'mmp', mms = detect.mms, DEF = 'modula2', - m2 = 'modula2', - mi = 'modula2', lm3 = 'modula3', mojo = 'mojo', ['🔥'] = 'mojo', -- 🙄 diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index 6a14c73c92..ce3b873e40 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -419,6 +419,55 @@ function M.dtrace(_, bufnr) return 'd' end +--- @param bufnr integer +--- @return boolean +local function is_modula2(bufnr) + return matchregex(nextnonblank(bufnr, 1), [[\ -" Last Change: 2023 Aug 10 +" Maintainer: The Vim Project +" Last Change: 2024 Jan 04 " Former Maintainer: Bram Moolenaar " Define the SetSyn function, used for the Syntax menu entries. @@ -16,6 +16,9 @@ fun! SetSyn(name) let use_fvwm_2 = 1 let use_fvwm_1 = 0 let name = "fvwm" + elseif a:name =~ '^modula2:\w\+$' + let [name, dialect] = split(a:name, ":") + call modula2#SetDialect(dialect) else let name = a:name endif @@ -364,25 +367,27 @@ an 50.70.340 &Syntax.M.MMIX :cal SetSyn("mmix") an 50.70.350 &Syntax.M.Modconf :cal SetSyn("modconf") an 50.70.360 &Syntax.M.Model :cal SetSyn("model") an 50.70.370 &Syntax.M.Modsim\ III :cal SetSyn("modsim3") -an 50.70.380 &Syntax.M.Modula\ 2 :cal SetSyn("modula2") -an 50.70.390 &Syntax.M.Modula\ 3 :cal SetSyn("modula3") -an 50.70.400 &Syntax.M.Monk :cal SetSyn("monk") -an 50.70.410 &Syntax.M.Motorola\ S-Record :cal SetSyn("srec") -an 50.70.420 &Syntax.M.Mplayer\ config :cal SetSyn("mplayerconf") -an 50.70.430 &Syntax.M.MOO :cal SetSyn("moo") -an 50.70.440 &Syntax.M.Mrxvtrc :cal SetSyn("mrxvtrc") -an 50.70.450 &Syntax.M.MS-DOS/Windows.4DOS\ \.bat\ file :cal SetSyn("btm") -an 50.70.460 &Syntax.M.MS-DOS/Windows.\.bat\/\.cmd\ file :cal SetSyn("dosbatch") -an 50.70.470 &Syntax.M.MS-DOS/Windows.\.ini\ file :cal SetSyn("dosini") -an 50.70.480 &Syntax.M.MS-DOS/Windows.Message\ text :cal SetSyn("msmessages") -an 50.70.490 &Syntax.M.MS-DOS/Windows.Module\ Definition :cal SetSyn("def") -an 50.70.500 &Syntax.M.MS-DOS/Windows.Registry :cal SetSyn("registry") -an 50.70.510 &Syntax.M.MS-DOS/Windows.Resource\ file :cal SetSyn("rc") -an 50.70.520 &Syntax.M.Msql :cal SetSyn("msql") -an 50.70.530 &Syntax.M.MuPAD :cal SetSyn("mupad") -an 50.70.540 &Syntax.M.Murphi :cal SetSyn("murphi") -an 50.70.550 &Syntax.M.MUSHcode :cal SetSyn("mush") -an 50.70.560 &Syntax.M.Muttrc :cal SetSyn("muttrc") +an 50.70.380 &Syntax.M.Modula-2.R10\ (2010) :cal SetSyn("modula2:r10") +an 50.70.390 &Syntax.M.Modula-2.ISO\ (1994) :cal SetSyn("modula2:iso") +an 50.70.400 &Syntax.M.Modula-2.PIM\ (1985) :cal SetSyn("modula2:pim") +an 50.70.410 &Syntax.M.Modula-3 :cal SetSyn("modula3") +an 50.70.420 &Syntax.M.Monk :cal SetSyn("monk") +an 50.70.430 &Syntax.M.Motorola\ S-Record :cal SetSyn("srec") +an 50.70.440 &Syntax.M.Mplayer\ config :cal SetSyn("mplayerconf") +an 50.70.450 &Syntax.M.MOO :cal SetSyn("moo") +an 50.70.460 &Syntax.M.Mrxvtrc :cal SetSyn("mrxvtrc") +an 50.70.470 &Syntax.M.MS-DOS/Windows.4DOS\ \.bat\ file :cal SetSyn("btm") +an 50.70.480 &Syntax.M.MS-DOS/Windows.\.bat\/\.cmd\ file :cal SetSyn("dosbatch") +an 50.70.490 &Syntax.M.MS-DOS/Windows.\.ini\ file :cal SetSyn("dosini") +an 50.70.500 &Syntax.M.MS-DOS/Windows.Message\ text :cal SetSyn("msmessages") +an 50.70.510 &Syntax.M.MS-DOS/Windows.Module\ Definition :cal SetSyn("def") +an 50.70.520 &Syntax.M.MS-DOS/Windows.Registry :cal SetSyn("registry") +an 50.70.530 &Syntax.M.MS-DOS/Windows.Resource\ file :cal SetSyn("rc") +an 50.70.540 &Syntax.M.Msql :cal SetSyn("msql") +an 50.70.550 &Syntax.M.MuPAD :cal SetSyn("mupad") +an 50.70.560 &Syntax.M.Murphi :cal SetSyn("murphi") +an 50.70.570 &Syntax.M.MUSHcode :cal SetSyn("mush") +an 50.70.580 &Syntax.M.Muttrc :cal SetSyn("muttrc") an 50.80.100 &Syntax.NO.N1QL :cal SetSyn("n1ql") an 50.80.110 &Syntax.NO.Nanorc :cal SetSyn("nanorc") an 50.80.120 &Syntax.NO.Nastran\ input/DMAP :cal SetSyn("nastran") diff --git a/runtime/syntax/modula2.vim b/runtime/syntax/modula2.vim index 4a14cf1f6f..6a9f4af6aa 100644 --- a/runtime/syntax/modula2.vim +++ b/runtime/syntax/modula2.vim @@ -1,73 +1,16 @@ " Vim syntax file -" Language: Modula 2 -" Maintainer: pf@artcom0.north.de (Peter Funk) -" based on original work of Bram Moolenaar -" Last Change: 2001 May 09 +" Language: Modula-2 +" Maintainer: Doug Kearns +" Previous Maintainer: pf@artcom0.north.de (Peter Funk) +" Last Change: 2024 Jan 04 -" quit when a syntax file was already loaded if exists("b:current_syntax") finish endif -" Don't ignore case (Modula-2 is case significant). This is the default in vim - -" Especially emphasize headers of procedures and modules: -syn region modula2Header matchgroup=modula2Header start="PROCEDURE " end="(" contains=modula2Ident oneline -syn region modula2Header matchgroup=modula2Header start="MODULE " end=";" contains=modula2Ident oneline -syn region modula2Header matchgroup=modula2Header start="BEGIN (\*" end="\*)" contains=modula2Ident oneline -syn region modula2Header matchgroup=modula2Header start="END " end=";" contains=modula2Ident oneline -syn region modula2Keyword start="END" end=";" contains=ALLBUT,modula2Ident oneline - -" Some very important keywords which should be emphasized more than others: -syn keyword modula2AttKeyword CONST EXIT HALT RETURN TYPE VAR -" All other keywords in alphabetical order: -syn keyword modula2Keyword AND ARRAY BY CASE DEFINITION DIV DO ELSE -syn keyword modula2Keyword ELSIF EXPORT FOR FROM IF IMPLEMENTATION IMPORT -syn keyword modula2Keyword IN LOOP MOD NOT OF OR POINTER QUALIFIED RECORD -syn keyword modula2Keyword SET THEN TO UNTIL WHILE WITH - -syn keyword modula2Type ADDRESS BITSET BOOLEAN CARDINAL CHAR INTEGER REAL WORD -syn keyword modula2StdFunc ABS CAP CHR DEC EXCL INC INCL ORD SIZE TSIZE VAL -syn keyword modula2StdConst FALSE NIL TRUE -" The following may be discussed, since NEW and DISPOSE are some kind of -" special builtin macro functions: -syn keyword modula2StdFunc NEW DISPOSE -" The following types are added later on and may be missing from older -" Modula-2 Compilers (they are at least missing from the original report -" by N.Wirth from March 1980 ;-) Highlighting should apply nevertheless: -syn keyword modula2Type BYTE LONGCARD LONGINT LONGREAL PROC SHORTCARD SHORTINT -" same note applies to min and max, which were also added later to m2: -syn keyword modula2StdFunc MAX MIN -" The underscore was originally disallowed in m2 ids, it was also added later: -syn match modula2Ident " [A-Z,a-z][A-Z,a-z,0-9,_]*" contained - -" Comments may be nested in Modula-2: -syn region modula2Comment start="(\*" end="\*)" contains=modula2Comment,modula2Todo -syn keyword modula2Todo contained TODO FIXME XXX - -" Strings -syn region modula2String start=+"+ end=+"+ -syn region modula2String start="'" end="'" -syn region modula2Set start="{" end="}" - -" Define the default highlighting. -" Only when an item doesn't have highlighting yet - -hi def link modula2Ident Identifier -hi def link modula2StdConst Boolean -hi def link modula2Type Identifier -hi def link modula2StdFunc Identifier -hi def link modula2Header Type -hi def link modula2Keyword Statement -hi def link modula2AttKeyword PreProc -hi def link modula2Comment Comment -" The following is just a matter of taste (you want to try this instead): -" hi modula2Comment term=bold ctermfg=DarkBlue guifg=Blue gui=bold -hi def link modula2Todo Todo -hi def link modula2String String -hi def link modula2Set String - +let dialect = modula2#GetDialect() +exe "runtime! syntax/modula2/opt/" .. dialect .. ".vim" let b:current_syntax = "modula2" -" vim: ts=8 +" vim: nowrap sw=2 sts=2 ts=8 noet: diff --git a/runtime/syntax/modula2/opt/iso.vim b/runtime/syntax/modula2/opt/iso.vim new file mode 100644 index 0000000000..5bd24f6885 --- /dev/null +++ b/runtime/syntax/modula2/opt/iso.vim @@ -0,0 +1,380 @@ +" Vim syntax file +" Language: Modula-2 (ISO) +" Maintainer: B.Kowarsch +" Last Change: 2016 August 22 + +" ---------------------------------------------------- +" THIS FILE IS LICENSED UNDER THE VIM LICENSE +" see https://github.com/vim/vim/blob/master/LICENSE +" ---------------------------------------------------- + +" Remarks: +" Vim Syntax files are available for the following Modula-2 dialects: +" * for the PIM dialect : m2pim.vim +" * for the ISO dialect : m2iso.vim (this file) +" * for the R10 dialect : m2r10.vim + +" ----------------------------------------------------------------------------- +" This syntax description follows ISO standard IS-10514 (aka ISO Modula-2) +" with the addition of the following language extensions: +" * non-standard types LONGCARD and LONGBITSET +" * non-nesting code disabling tags ?< and >? at the start of a line +" ----------------------------------------------------------------------------- + +" Parameters: +" +" Vim's filetype script recognises Modula-2 dialect tags within the first 200 +" lines of Modula-2 .def and .mod input files. The script sets filetype and +" dialect automatically when a valid dialect tag is found in the input file. +" The dialect tag for the ISO dialect is (*!m2iso*). It is recommended to put +" the tag immediately after the module header in the Modula-2 input file. +" +" Example: +" DEFINITION MODULE Foolib; (*!m2iso*) +" +" Variable g:modula2_default_dialect sets the default Modula-2 dialect when the +" dialect cannot be determined from the contents of the Modula-2 input file: +" if defined and set to 'm2iso', the default dialect is ISO. +" +" Variable g:modula2_iso_allow_lowline controls support for lowline in identifiers: +" if defined and set to a non-zero value, they are recognised, otherwise not +" +" Variable g:modula2_iso_disallow_octals controls the rendering of octal literals: +" if defined and set to a non-zero value, they are rendered as errors. +" +" Variable g:modula2_iso_disallow_synonyms controls the rendering of @, & and ~: +" if defined and set to a non-zero value, they are rendered as errors. +" +" Variables may be defined in Vim startup file .vimrc +" +" Examples: +" let g:modula2_default_dialect = 'm2iso' +" let g:modula2_iso_allow_lowline = 1 +" let g:modula2_iso_disallow_octals = 1 +" let g:modula2_iso_disallow_synonyms = 1 + + +if exists("b:current_syntax") + finish +endif + +" Modula-2 is case sensitive +syn case match + + +" ----------------------------------------------------------------------------- +" Reserved Words +" ----------------------------------------------------------------------------- +syn keyword modula2Resword AND ARRAY BEGIN BY CASE CONST DEFINITION DIV DO ELSE +syn keyword modula2Resword ELSIF EXCEPT EXIT EXPORT FINALLY FOR FORWARD FROM IF +syn keyword modula2Resword IMPLEMENTATION IMPORT IN LOOP MOD NOT OF OR PACKEDSET +syn keyword modula2Resword POINTER QUALIFIED RECORD REPEAT REM RETRY RETURN SET +syn keyword modula2Resword THEN TO TYPE UNTIL VAR WHILE WITH + + +" ----------------------------------------------------------------------------- +" Builtin Constant Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2ConstIdent FALSE NIL TRUE INTERRUPTIBLE UNINTERRUPTIBLE + + +" ----------------------------------------------------------------------------- +" Builtin Type Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2TypeIdent BITSET BOOLEAN CHAR PROC +syn keyword modula2TypeIdent CARDINAL INTEGER LONGINT REAL LONGREAL +syn keyword modula2TypeIdent COMPLEX LONGCOMPLEX PROTECTION + + +" ----------------------------------------------------------------------------- +" Builtin Procedure and Function Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2ProcIdent CAP DEC EXCL HALT INC INCL +syn keyword modula2FuncIdent ABS CHR CMPLX FLOAT HIGH IM INT LENGTH LFLOAT MAX MIN +syn keyword modula2FuncIdent ODD ORD RE SIZE TRUNC VAL + + +" ----------------------------------------------------------------------------- +" Wirthian Macro Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2MacroIdent NEW DISPOSE + + +" ----------------------------------------------------------------------------- +" Unsafe Facilities via Pseudo-Module SYSTEM +" ----------------------------------------------------------------------------- +syn keyword modula2UnsafeIdent ADDRESS BYTE LOC WORD +syn keyword modula2UnsafeIdent ADR CAST TSIZE SYSTEM +syn keyword modula2UnsafeIdent MAKEADR ADDADR SUBADR DIFADR ROTATE SHIFT + + +" ----------------------------------------------------------------------------- +" Non-Portable Language Extensions +" ----------------------------------------------------------------------------- +syn keyword modula2NonPortableIdent LONGCARD LONGBITSET + + +" ----------------------------------------------------------------------------- +" User Defined Identifiers +" ----------------------------------------------------------------------------- +syn match modula2Ident "[a-zA-Z][a-zA-Z0-9]*\(_\)\@!" +syn match modula2LowLineIdent "[a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)\+" + + +" ----------------------------------------------------------------------------- +" String Literals +" ----------------------------------------------------------------------------- +syn region modula2String start=/"/ end=/"/ oneline +syn region modula2String start=/'/ end=/'/ oneline + + +" ----------------------------------------------------------------------------- +" Numeric Literals +" ----------------------------------------------------------------------------- +syn match modula2Num + \ "\(\([0-7]\+\)[BC]\@!\|[89]\)[0-9]*\(\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?\)\?" +syn match modula2Num "[0-9A-F]\+H" +syn match modula2Octal "[0-7]\+[BC]" + + +" ----------------------------------------------------------------------------- +" Punctuation +" ----------------------------------------------------------------------------- +syn match modula2Punctuation + \ "\.\|[,:;]\|\*\|[/+-]\|\#\|[=<>]\|\^\|\[\|\]\|(\(\*\)\@!\|[){}]" +syn match modula2Synonym "[@&~]" + + +" ----------------------------------------------------------------------------- +" Pragmas +" ----------------------------------------------------------------------------- +syn region modula2Pragma start="<\*" end="\*>" +syn match modula2DialectTag "(\*!m2iso\(+[a-z0-9]\+\)\?\*)" + +" ----------------------------------------------------------------------------- +" Block Comments +" ----------------------------------------------------------------------------- +syn region modula2Comment start="(\*\(!m2iso\(+[a-z0-9]\+\)\?\*)\)\@!" end="\*)" + \ contains = modula2Comment, modula2CommentKey, modula2TechDebtMarker +syn match modula2CommentKey "[Aa]uthor[s]\?\|[Cc]opyright\|[Ll]icense\|[Ss]ynopsis" +syn match modula2CommentKey "\([Pp]re\|[Pp]ost\|[Ee]rror\)\-condition[s]\?:" + + +" ----------------------------------------------------------------------------- +" Technical Debt Markers +" ----------------------------------------------------------------------------- +syn keyword modula2TechDebtMarker contained DEPRECATED FIXME +syn match modula2TechDebtMarker "TODO[:]\?" contained + +" ----------------------------------------------------------------------------- +" Disabled Code Sections +" ----------------------------------------------------------------------------- +syn region modula2DisabledCode start="^?<" end="^>?" + + +" ----------------------------------------------------------------------------- +" Headers +" ----------------------------------------------------------------------------- +" !!! this section must be second last !!! + +" new module header +syn match modula2ModuleHeader + \ "MODULE\( [A-Z][a-zA-Z0-9]*\)\?" + \ contains = modula2ReswordModule, modula2ModuleIdent + +syn match modula2ModuleIdent + \ "[A-Z][a-zA-Z0-9]*" contained + +syn match modula2ModuleTail + \ "END [A-Z][a-zA-Z0-9]*\.$" + \ contains = modula2ReswordEnd, modula2ModuleIdent, modula2Punctuation + +" new procedure header +syn match modula2ProcedureHeader + \ "PROCEDURE\( [a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*\)\?" + \ contains = modula2ReswordProcedure, + \ modula2ProcedureIdent, modula2ProcedureLowlineIdent, modula2IllegalChar, modula2IllegalIdent + +syn match modula2ProcedureIdent + \ "\([a-zA-Z]\)\([a-zA-Z0-9]*\)" contained + +syn match modula2ProcedureLowlineIdent + \ "[a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)\+" contained + +syn match modula2ProcedureTail + \ "END\( \([a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*\)[.;]$\)\?" + \ contains = modula2ReswordEnd, + \ modula2ProcedureIdent, modula2ProcedureLowLineIdent, + \ modula2Punctuation, modula2IllegalChar, modula2IllegalIdent + +syn keyword modula2ReswordModule contained MODULE +syn keyword modula2ReswordProcedure contained PROCEDURE +syn keyword modula2ReswordEnd contained END + + +" ----------------------------------------------------------------------------- +" Illegal Symbols +" ----------------------------------------------------------------------------- +" !!! this section must be last !!! + +" any '`' '!' '$' '%' or '\' +syn match modula2IllegalChar "[`!$%\\]" + +" any solitary sequence of '_' +syn match modula2IllegalChar "\<_\+\>" + +" any '?' at start of line if not followed by '<' +syn match modula2IllegalChar "^?\(<\)\@!" + +" any '?' not following '>' at start of line +syn match modula2IllegalChar "\(\(^>\)\|\(^\)\)\@" + + +" ----------------------------------------------------------------------------- +" Define Rendering Styles +" ----------------------------------------------------------------------------- + +" highlight default link modula2PredefIdentStyle Keyword +" highlight default link modula2ConstIdentStyle modula2PredefIdentStyle +" highlight default link modula2TypeIdentStyle modula2PredefIdentStyle +" highlight default link modula2ProcIdentStyle modula2PredefIdentStyle +" highlight default link modula2FuncIdentStyle modula2PredefIdentStyle +" highlight default link modula2MacroIdentStyle modula2PredefIdentStyle + +highlight default link modula2ConstIdentStyle Constant +highlight default link modula2TypeIdentStyle Type +highlight default link modula2ProcIdentStyle Function +highlight default link modula2FuncIdentStyle Function +highlight default link modula2MacroIdentStyle Function +highlight default link modula2UnsafeIdentStyle Question +highlight default link modula2NonPortableIdentStyle Question +highlight default link modula2StringLiteralStyle String +highlight default link modula2CommentStyle Comment +highlight default link modula2PragmaStyle PreProc +highlight default link modula2DialectTagStyle SpecialComment +highlight default link modula2TechDebtMarkerStyle SpecialComment +highlight default link modula2ReswordStyle Keyword +highlight default link modula2HeaderIdentStyle Function +highlight default link modula2UserDefIdentStyle Normal +highlight default link modula2NumericLiteralStyle Number +highlight default link modula2PunctuationStyle Delimiter +highlight default link modula2CommentKeyStyle SpecialComment +highlight default link modula2DisabledCodeStyle NonText + +" ----------------------------------------------------------------------------- +" Assign Rendering Styles +" ----------------------------------------------------------------------------- + +" headers +highlight default link modula2ModuleIdent modula2HeaderIdentStyle +highlight default link modula2ProcedureIdent modula2HeaderIdentStyle +highlight default link modula2ModuleHeader Normal +highlight default link modula2ModuleTail Normal +highlight default link modula2ProcedureHeader Normal +highlight default link modula2ProcedureTail Normal + +" lowline identifiers are rendered as errors if g:modula2_iso_allow_lowline is unset +if exists("g:modula2_iso_allow_lowline") + if g:modula2_iso_allow_lowline != 0 + highlight default link modula2ProcedureLowlineIdent modula2HeaderIdentStyle + else + highlight default link modula2ProcedureLowlineIdent Error + endif +else + highlight default link modula2ProcedureLowlineIdent modula2HeaderIdentStyle +endif + +" reserved words +highlight default link modula2Resword modula2ReswordStyle +highlight default link modula2ReswordModule modula2ReswordStyle +highlight default link modula2ReswordProcedure modula2ReswordStyle +highlight default link modula2ReswordEnd modula2ReswordStyle + +" predefined identifiers +highlight default link modula2ConstIdent modula2ConstIdentStyle +highlight default link modula2TypeIdent modula2TypeIdentStyle +highlight default link modula2ProcIdent modula2ProcIdentStyle +highlight default link modula2FuncIdent modula2FuncIdentStyle +highlight default link modula2MacroIdent modula2MacroIdentStyle + +" unsafe and non-portable identifiers +highlight default link modula2UnsafeIdent modula2UnsafeIdentStyle +highlight default link modula2NonPortableIdent modula2NonPortableIdentStyle + +" user defined identifiers +highlight default link modula2Ident modula2UserDefIdentStyle + +" lowline identifiers are rendered as errors if g:modula2_iso_allow_lowline is unset +if exists("g:modula2_iso_allow_lowline") + if g:modula2_iso_allow_lowline != 0 + highlight default link modula2LowLineIdent modula2UserDefIdentStyle + else + highlight default link modula2LowLineIdent Error + endif +else + highlight default link modula2LowLineIdent modula2UserDefIdentStyle +endif + +" literals +highlight default link modula2String modula2StringLiteralStyle +highlight default link modula2Num modula2NumericLiteralStyle + +" octal literals are rendered as errors if g:modula2_iso_disallow_octals is set +if exists("g:modula2_iso_disallow_octals") + if g:modula2_iso_disallow_octals != 0 + highlight default link modula2Octal Error + else + highlight default link modula2Octal modula2NumericLiteralStyle + endif +else + highlight default link modula2Octal modula2NumericLiteralStyle +endif + +" punctuation +highlight default link modula2Punctuation modula2PunctuationStyle + +" synonyms & and ~ are rendered as errors if g:modula2_iso_disallow_synonyms is set +if exists("g:modula2_iso_disallow_synonyms") + if g:modula2_iso_disallow_synonyms != 0 + highlight default link modula2Synonym Error + else + highlight default link modula2Synonym modula2PunctuationStyle + endif +else + highlight default link modula2Synonym modula2PunctuationStyle +endif + +" pragmas +highlight default link modula2Pragma modula2PragmaStyle +highlight default link modula2DialectTag modula2DialectTagStyle + +" comments +highlight default link modula2Comment modula2CommentStyle +highlight default link modula2CommentKey modula2CommentKeyStyle + +" technical debt markers +highlight default link modula2TechDebtMarker modula2TechDebtMarkerStyle + +" disabled code +highlight default link modula2DisabledCode modula2DisabledCodeStyle + +" illegal symbols +highlight default link modula2IllegalChar Error +highlight default link modula2IllegalIdent Error + + +let b:current_syntax = "modula2" + +" vim: ts=4 + +" END OF FILE diff --git a/runtime/syntax/modula2/opt/pim.vim b/runtime/syntax/modula2/opt/pim.vim new file mode 100644 index 0000000000..1626db91cf --- /dev/null +++ b/runtime/syntax/modula2/opt/pim.vim @@ -0,0 +1,377 @@ +" Vim syntax file +" Language: Modula-2 (PIM) +" Maintainer: B.Kowarsch +" Last Change: 2016 August 22 + +" ---------------------------------------------------- +" THIS FILE IS LICENSED UNDER THE VIM LICENSE +" see https://github.com/vim/vim/blob/master/LICENSE +" ---------------------------------------------------- + +" Remarks: +" Vim Syntax files are available for the following Modula-2 dialects: +" * for the PIM dialect : m2pim.vim (this file) +" * for the ISO dialect : m2iso.vim +" * for the R10 dialect : m2r10.vim + +" ----------------------------------------------------------------------------- +" This syntax description follows the 3rd and 4th editions of N.Wirth's Book +" Programming in Modula-2 (aka PIM) plus the following language extensions: +" * non-leading, non-trailing, non-consecutive lowlines _ in identifiers +" * widely supported non-standard types BYTE, LONGCARD and LONGBITSET +" * non-nesting code disabling tags ?< and >? at the start of a line +" ----------------------------------------------------------------------------- + +" Parameters: +" +" Vim's filetype script recognises Modula-2 dialect tags within the first 200 +" lines of Modula-2 .def and .mod input files. The script sets filetype and +" dialect automatically when a valid dialect tag is found in the input file. +" The dialect tag for the PIM dialect is (*!m2pim*). It is recommended to put +" the tag immediately after the module header in the Modula-2 input file. +" +" Example: +" DEFINITION MODULE Foolib; (*!m2pim*) +" +" Variable g:modula2_default_dialect sets the default Modula-2 dialect when the +" dialect cannot be determined from the contents of the Modula-2 input file: +" if defined and set to 'm2pim', the default dialect is PIM. +" +" Variable g:modula2_pim_allow_lowline controls support for lowline in identifiers: +" if defined and set to a non-zero value, they are recognised, otherwise not +" +" Variable g:modula2_pim_disallow_octals controls the rendering of octal literals: +" if defined and set to a non-zero value, they are rendered as errors. +" +" Variable g:modula2_pim_disallow_synonyms controls the rendering of & and ~: +" if defined and set to a non-zero value, they are rendered as errors. +" +" Variables may be defined in Vim startup file .vimrc +" +" Examples: +" let g:modula2_default_dialect = 'm2pim' +" let g:modula2_pim_allow_lowline = 1 +" let g:modula2_pim_disallow_octals = 1 +" let g:modula2_pim_disallow_synonyms = 1 + + +if exists("b:current_syntax") + finish +endif + +" Modula-2 is case sensitive +syn case match + + +" ----------------------------------------------------------------------------- +" Reserved Words +" ----------------------------------------------------------------------------- +syn keyword modula2Resword AND ARRAY BEGIN BY CASE CONST DEFINITION DIV DO ELSE +syn keyword modula2Resword ELSIF EXIT EXPORT FOR FROM IF IMPLEMENTATION IMPORT +syn keyword modula2Resword IN LOOP MOD NOT OF OR POINTER QUALIFIED RECORD REPEAT +syn keyword modula2Resword RETURN SET THEN TO TYPE UNTIL VAR WHILE WITH + + +" ----------------------------------------------------------------------------- +" Builtin Constant Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2ConstIdent FALSE NIL TRUE + + +" ----------------------------------------------------------------------------- +" Builtin Type Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2TypeIdent BITSET BOOLEAN CHAR PROC +syn keyword modula2TypeIdent CARDINAL INTEGER LONGINT REAL LONGREAL + + +" ----------------------------------------------------------------------------- +" Builtin Procedure and Function Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2ProcIdent CAP DEC EXCL HALT INC INCL +syn keyword modula2FuncIdent ABS CHR FLOAT HIGH MAX MIN ODD ORD SIZE TRUNC VAL + + +" ----------------------------------------------------------------------------- +" Wirthian Macro Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2MacroIdent NEW DISPOSE + + +" ----------------------------------------------------------------------------- +" Unsafe Facilities via Pseudo-Module SYSTEM +" ----------------------------------------------------------------------------- +syn keyword modula2UnsafeIdent ADDRESS PROCESS WORD +syn keyword modula2UnsafeIdent ADR TSIZE NEWPROCESS TRANSFER SYSTEM + + +" ----------------------------------------------------------------------------- +" Non-Portable Language Extensions +" ----------------------------------------------------------------------------- +syn keyword modula2NonPortableIdent BYTE LONGCARD LONGBITSET + + +" ----------------------------------------------------------------------------- +" User Defined Identifiers +" ----------------------------------------------------------------------------- +syn match modula2Ident "[a-zA-Z][a-zA-Z0-9]*\(_\)\@!" +syn match modula2LowLineIdent "[a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)\+" + + +" ----------------------------------------------------------------------------- +" String Literals +" ----------------------------------------------------------------------------- +syn region modula2String start=/"/ end=/"/ oneline +syn region modula2String start=/'/ end=/'/ oneline + + +" ----------------------------------------------------------------------------- +" Numeric Literals +" ----------------------------------------------------------------------------- +syn match modula2Num + \ "\(\([0-7]\+\)[BC]\@!\|[89]\)[0-9]*\(\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?\)\?" +syn match modula2Num "[0-9A-F]\+H" +syn match modula2Octal "[0-7]\+[BC]" + + +" ----------------------------------------------------------------------------- +" Punctuation +" ----------------------------------------------------------------------------- +syn match modula2Punctuation + \ "\.\|[,:;]\|\*\|[/+-]\|\#\|[=<>]\|\^\|\[\|\]\|(\(\*\)\@!\|[){}]" +syn match modula2Synonym "[&~]" + + +" ----------------------------------------------------------------------------- +" Pragmas +" ----------------------------------------------------------------------------- +syn region modula2Pragma start="(\*\$" end="\*)" +syn match modula2DialectTag "(\*!m2pim\(+[a-z0-9]\+\)\?\*)" + +" ----------------------------------------------------------------------------- +" Block Comments +" ----------------------------------------------------------------------------- +syn region modula2Comment start="(\*\(\$\|!m2pim\(+[a-z0-9]\+\)\?\*)\)\@!" end="\*)" + \ contains = modula2Comment, modula2CommentKey, modula2TechDebtMarker +syn match modula2CommentKey "[Aa]uthor[s]\?\|[Cc]opyright\|[Ll]icense\|[Ss]ynopsis" +syn match modula2CommentKey "\([Pp]re\|[Pp]ost\|[Ee]rror\)\-condition[s]\?:" + + +" ----------------------------------------------------------------------------- +" Technical Debt Markers +" ----------------------------------------------------------------------------- +syn keyword modula2TechDebtMarker contained DEPRECATED FIXME +syn match modula2TechDebtMarker "TODO[:]\?" contained + +" ----------------------------------------------------------------------------- +" Disabled Code Sections +" ----------------------------------------------------------------------------- +syn region modula2DisabledCode start="^?<" end="^>?" + + +" ----------------------------------------------------------------------------- +" Headers +" ----------------------------------------------------------------------------- +" !!! this section must be second last !!! + +" new module header +syn match modula2ModuleHeader + \ "MODULE\( [A-Z][a-zA-Z0-9]*\)\?" + \ contains = modula2ReswordModule, modula2ModuleIdent + +syn match modula2ModuleIdent + \ "[A-Z][a-zA-Z0-9]*" contained + +syn match modula2ModuleTail + \ "END [A-Z][a-zA-Z0-9]*\.$" + \ contains = modula2ReswordEnd, modula2ModuleIdent, modula2Punctuation + +" new procedure header +syn match modula2ProcedureHeader + \ "PROCEDURE\( [a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*\)\?" + \ contains = modula2ReswordProcedure, + \ modula2ProcedureIdent, modula2ProcedureLowlineIdent, modula2IllegalChar, modula2IllegalIdent + +syn match modula2ProcedureIdent + \ "\([a-zA-Z]\)\([a-zA-Z0-9]*\)" contained + +syn match modula2ProcedureLowlineIdent + \ "[a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)\+" contained + +syn match modula2ProcedureTail + \ "END\( \([a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*\)[.;]$\)\?" + \ contains = modula2ReswordEnd, + \ modula2ProcedureIdent, modula2ProcedureLowLineIdent, + \ modula2Punctuation, modula2IllegalChar, modula2IllegalIdent + +syn keyword modula2ReswordModule contained MODULE +syn keyword modula2ReswordProcedure contained PROCEDURE +syn keyword modula2ReswordEnd contained END + + +" ----------------------------------------------------------------------------- +" Illegal Symbols +" ----------------------------------------------------------------------------- +" !!! this section must be last !!! + +" any '`' '!' '@ ''$' '%' or '\' +syn match modula2IllegalChar "[`!@$%\\]" + +" any solitary sequence of '_' +syn match modula2IllegalChar "\<_\+\>" + +" any '?' at start of line if not followed by '<' +syn match modula2IllegalChar "^?\(<\)\@!" + +" any '?' not following '>' at start of line +syn match modula2IllegalChar "\(\(^>\)\|\(^\)\)\@" + + +" ----------------------------------------------------------------------------- +" Define Rendering Styles +" ----------------------------------------------------------------------------- + +" highlight default link modula2PredefIdentStyle Keyword +" highlight default link modula2ConstIdentStyle modula2PredefIdentStyle +" highlight default link modula2TypeIdentStyle modula2PredefIdentStyle +" highlight default link modula2ProcIdentStyle modula2PredefIdentStyle +" highlight default link modula2FuncIdentStyle modula2PredefIdentStyle +" highlight default link modula2MacroIdentStyle modula2PredefIdentStyle + +highlight default link modula2ConstIdentStyle Constant +highlight default link modula2TypeIdentStyle Type +highlight default link modula2ProcIdentStyle Function +highlight default link modula2FuncIdentStyle Function +highlight default link modula2MacroIdentStyle Function +highlight default link modula2UnsafeIdentStyle Question +highlight default link modula2NonPortableIdentStyle Question +highlight default link modula2StringLiteralStyle String +highlight default link modula2CommentStyle Comment +highlight default link modula2PragmaStyle PreProc +highlight default link modula2DialectTagStyle SpecialComment +highlight default link modula2TechDebtMarkerStyle SpecialComment +highlight default link modula2ReswordStyle Keyword +highlight default link modula2HeaderIdentStyle Function +highlight default link modula2UserDefIdentStyle Normal +highlight default link modula2NumericLiteralStyle Number +highlight default link modula2PunctuationStyle Delimiter +highlight default link modula2CommentKeyStyle SpecialComment +highlight default link modula2DisabledCodeStyle NonText + +" ----------------------------------------------------------------------------- +" Assign Rendering Styles +" ----------------------------------------------------------------------------- + +" headers +highlight default link modula2ModuleIdent modula2HeaderIdentStyle +highlight default link modula2ProcedureIdent modula2HeaderIdentStyle +highlight default link modula2ModuleHeader Normal +highlight default link modula2ModuleTail Normal +highlight default link modula2ProcedureHeader Normal +highlight default link modula2ProcedureTail Normal + +" lowline identifiers are rendered as errors if g:modula2_pim_allow_lowline is unset +if exists("g:modula2_pim_allow_lowline") + if g:modula2_pim_allow_lowline != 0 + highlight default link modula2ProcedureLowlineIdent modula2HeaderIdentStyle + else + highlight default link modula2ProcedureLowlineIdent Error + endif +else + highlight default link modula2ProcedureLowlineIdent Error +endif + +" reserved words +highlight default link modula2Resword modula2ReswordStyle +highlight default link modula2ReswordModule modula2ReswordStyle +highlight default link modula2ReswordProcedure modula2ReswordStyle +highlight default link modula2ReswordEnd modula2ReswordStyle + +" predefined identifiers +highlight default link modula2ConstIdent modula2ConstIdentStyle +highlight default link modula2TypeIdent modula2TypeIdentStyle +highlight default link modula2ProcIdent modula2ProcIdentStyle +highlight default link modula2FuncIdent modula2FuncIdentStyle +highlight default link modula2MacroIdent modula2MacroIdentStyle + +" unsafe and non-portable identifiers +highlight default link modula2UnsafeIdent modula2UnsafeIdentStyle +highlight default link modula2NonPortableIdent modula2NonPortableIdentStyle + +" user defined identifiers +highlight default link modula2Ident modula2UserDefIdentStyle + +" lowline identifiers are rendered as errors if g:modula2_pim_allow_lowline is unset +if exists("g:modula2_pim_allow_lowline") + if g:modula2_pim_allow_lowline != 0 + highlight default link modula2LowLineIdent modula2UserDefIdentStyle + else + highlight default link modula2LowLineIdent Error + endif +else + highlight default link modula2LowLineIdent Error +endif + +" literals +highlight default link modula2String modula2StringLiteralStyle +highlight default link modula2Num modula2NumericLiteralStyle + +" octal literals are rendered as errors if g:modula2_pim_disallow_octals is set +if exists("g:modula2_pim_disallow_octals") + if g:modula2_pim_disallow_octals != 0 + highlight default link modula2Octal Error + else + highlight default link modula2Octal modula2NumericLiteralStyle + endif +else + highlight default link modula2Octal modula2NumericLiteralStyle +endif + +" punctuation +highlight default link modula2Punctuation modula2PunctuationStyle + +" synonyms & and ~ are rendered as errors if g:modula2_pim_disallow_synonyms is set +if exists("g:modula2_pim_disallow_synonyms") + if g:modula2_pim_disallow_synonyms != 0 + highlight default link modula2Synonym Error + else + highlight default link modula2Synonym modula2PunctuationStyle + endif +else + highlight default link modula2Synonym modula2PunctuationStyle +endif + +" pragmas +highlight default link modula2Pragma modula2PragmaStyle +highlight default link modula2DialectTag modula2DialectTagStyle + +" comments +highlight default link modula2Comment modula2CommentStyle +highlight default link modula2CommentKey modula2CommentKeyStyle + +" technical debt markers +highlight default link modula2TechDebtMarker modula2TechDebtMarkerStyle + +" disabled code +highlight default link modula2DisabledCode modula2DisabledCodeStyle + +" illegal symbols +highlight default link modula2IllegalChar Error +highlight default link modula2IllegalIdent Error + + +let b:current_syntax = "modula2" + +" vim: ts=4 + +" END OF FILE diff --git a/runtime/syntax/modula2/opt/r10.vim b/runtime/syntax/modula2/opt/r10.vim new file mode 100644 index 0000000000..775f498dfb --- /dev/null +++ b/runtime/syntax/modula2/opt/r10.vim @@ -0,0 +1,452 @@ +" Vim syntax file +" Language: Modula-2 (R10) +" Maintainer: B.Kowarsch +" Last Change: 2020 June 18 (moved repository from bb to github) + +" ---------------------------------------------------- +" THIS FILE IS LICENSED UNDER THE VIM LICENSE +" see https://github.com/vim/vim/blob/master/LICENSE +" ---------------------------------------------------- + +" Remarks: +" Vim Syntax files are available for the following Modula-2 dialects: +" * for the PIM dialect : m2pim.vim +" * for the ISO dialect : m2iso.vim +" * for the R10 dialect : m2r10.vim (this file) + +" ----------------------------------------------------------------------------- +" This syntax description follows the Modula-2 Revision 2010 language report +" (Kowarsch and Sutcliffe, 2015) available at http://modula-2.info/m2r10. +" ----------------------------------------------------------------------------- + +" Parameters: +" +" Vim's filetype script recognises Modula-2 dialect tags within the first 200 +" lines of Modula-2 .def and .mod input files. The script sets filetype and +" dialect automatically when a valid dialect tag is found in the input file. +" The dialect tag for the R10 dialect is (*!m2r10*). It is recommended to put +" the tag immediately after the module header in the Modula-2 input file. +" +" Example: +" DEFINITION MODULE Foolib; (*!m2r10*) +" +" Variable g:modula2_default_dialect sets the default Modula-2 dialect when the +" dialect cannot be determined from the contents of the Modula-2 input file: +" if defined and set to 'm2r10', the default dialect is R10. +" +" Variable g:modula2_r10_allow_lowline controls support for lowline in identifiers: +" if defined and set to a non-zero value, they are recognised, otherwise not +" +" Variables may be defined in Vim startup file .vimrc +" +" Examples: +" let g:modula2_default_dialect = 'm2r10' +" let g:modula2_r10_allow_lowline = 1 + + +if exists("b:current_syntax") + finish +endif + +" Modula-2 is case sensitive +syn case match + + +" ----------------------------------------------------------------------------- +" Reserved Words +" ----------------------------------------------------------------------------- +" Note: MODULE, PROCEDURE and END are defined separately further below +syn keyword modula2Resword ALIAS AND ARGLIST ARRAY BEGIN CASE CONST COPY DEFINITION +syn keyword modula2Resword DIV DO ELSE ELSIF EXIT FOR FROM GENLIB IF IMPLEMENTATION +syn keyword modula2Resword IMPORT IN LOOP MOD NEW NOT OF OPAQUE OR POINTER READ +syn keyword modula2Resword RECORD RELEASE REPEAT RETAIN RETURN SET THEN TO TYPE +syn keyword modula2Resword UNTIL VAR WHILE WRITE YIELD + + +" ----------------------------------------------------------------------------- +" Schroedinger's Tokens +" ----------------------------------------------------------------------------- +syn keyword modula2SchroedToken CAPACITY COROUTINE LITERAL + + +" ----------------------------------------------------------------------------- +" Builtin Constant Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2ConstIdent NIL FALSE TRUE + + +" ----------------------------------------------------------------------------- +" Builtin Type Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2TypeIdent BOOLEAN CHAR UNICHAR OCTET +syn keyword modula2TypeIdent CARDINAL LONGCARD INTEGER LONGINT REAL LONGREAL + + +" ----------------------------------------------------------------------------- +" Builtin Procedure and Function Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2ProcIdent APPEND INSERT REMOVE SORT SORTNEW +syn keyword modula2FuncIdent CHR ORD ODD ABS SGN MIN MAX LOG2 POW2 ENTIER +syn keyword modula2FuncIdent PRED SUCC PTR COUNT LENGTH + + +" ----------------------------------------------------------------------------- +" Builtin Macro Identifiers +" ----------------------------------------------------------------------------- +syn keyword modula2MacroIdent NOP TMIN TMAX TSIZE TLIMIT + + +" ----------------------------------------------------------------------------- +" Builtin Primitives +" ----------------------------------------------------------------------------- +syn keyword modula2PrimitiveIdent SXF VAL STORE VALUE SEEK SUBSET + + +" ----------------------------------------------------------------------------- +" Unsafe Facilities via Pseudo-Module UNSAFE +" ----------------------------------------------------------------------------- +syn keyword modula2UnsafeIdent UNSAFE BYTE WORD LONGWORD OCTETSEQ +syn keyword modula2UnsafeIdent ADD SUB INC DEC SETBIT HALT +syn keyword modula2UnsafeIdent ADR CAST BIT SHL SHR BWNOT BWAND BWOR + + +" ----------------------------------------------------------------------------- +" Non-Portable Language Extensions +" ----------------------------------------------------------------------------- +syn keyword modula2NonPortableIdent ASSEMBLER ASM REG + + +" ----------------------------------------------------------------------------- +" User Defined Identifiers +" ----------------------------------------------------------------------------- +syn match modula2Ident "[a-zA-Z][a-zA-Z0-9]*\(_\)\@!" +syn match modula2LowLineIdent "[a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)\+" + +syn match modula2ReswordDo "\(TO\)\@&#,]\|\[\)\@<='" end=/'/ oneline + + +" ----------------------------------------------------------------------------- +" Numeric Literals +" ----------------------------------------------------------------------------- +syn match modula2Base2Num "0b[01]\+\('[01]\+\)*" +syn match modula2Base16Num "0[ux][0-9A-F]\+\('[0-9A-F]\+\)*" + +"| *** VMSCRIPT BUG ALERT *** +"| The regular expression below causes errors when split into separate strings +"| +"| syn match modula2Base10Num +"| \ "\(\(0[bux]\@!\|[1-9]\)[0-9]*\('[0-9]\+\)*\)" . +"| \ "\(\.[0-9]\+\('[0-9]\+\)*\(e[+-]\?[0-9]\+\('[0-9]\+\)*\)\?\)\?" +"| +"| E475: Invalid argument: modula2Base10Num "\(\(0[bux]\@!\|[1-9]\)[0-9]*\('[0-9]\+\)*\)" +"| . "\(\.[0-9]\+\('[0-9]\+\)*\(e[+-]\?[0-9]\+\('[0-9]\+\)*\)\?\)\?" +"| +"| However, the same regular expression works just fine as a sole string. +"| +"| As a consequence, we have no choice but to put it all into a single line +"| which greatly diminishes readability and thereby increases the opportunity +"| for error during maintenance. Ideally, regular expressions should be split +"| into small human readable pieces with interleaved comments that explain +"| precisely what each piece is doing. Vimscript imposes poor design. :-( + +syn match modula2Base10Num + \ "\(\(0[bux]\@!\|[1-9]\)[0-9]*\('[0-9]\+\)*\)\(\.[0-9]\+\('[0-9]\+\)*\(e[+-]\?[0-9]\+\('[0-9]\+\)*\)\?\)\?" + + +" ----------------------------------------------------------------------------- +" Punctuation +" ----------------------------------------------------------------------------- +syn match modula2Punctuation + \ "\.\|[,:;]\|\*\|[/+-]\|\#\|[=<>&]\|\^\|\[\|\]\|(\(\*\)\@!\|[){}]" + + +" ----------------------------------------------------------------------------- +" Pragmas +" ----------------------------------------------------------------------------- +syn region modula2Pragma start="<\*" end="\*>" + \ contains = modula2PragmaKey, modula2TechDebtPragma +syn keyword modula2PragmaKey contained MSG IF ELSIF ELSE END INLINE NOINLINE OUT +syn keyword modula2PragmaKey contained GENERATED ENCODING ALIGN PADBITS NORETURN +syn keyword modula2PragmaKey contained PURITY SINGLEASSIGN LOWLATENCY VOLATILE +syn keyword modula2PragmaKey contained FORWARD ADDR FFI FFIDENT + +syn match modula2DialectTag "(\*!m2r10\(+[a-z0-9]\+\)\?\*)" + + +" ----------------------------------------------------------------------------- +" Line Comments +" ----------------------------------------------------------------------------- +syn region modula2Comment start=/^!/ end=/$/ oneline + + +" ----------------------------------------------------------------------------- +" Block Comments +" ----------------------------------------------------------------------------- +syn region modula2Comment + \ start="\(END\s\)\@?" + + +" ----------------------------------------------------------------------------- +" Headers +" ----------------------------------------------------------------------------- +" !!! this section must be second last !!! + +" module header +syn match modula2ModuleHeader + \ "\(MODULE\|BLUEPRINT\)\( [A-Z][a-zA-Z0-9]*\)\?" + \ contains = modula2ReswordModule, modula2ReswordBlueprint, modula2ModuleIdent + +syn match modula2ModuleIdent + \ "[A-Z][a-zA-Z0-9]*" contained + +syn match modula2ModuleTail + \ "END [A-Z][a-zA-Z0-9]*\.$" + \ contains = modula2ReswordEnd, modula2ModuleIdent, modula2Punctuation + +" procedure, sole occurrence +syn match modula2ProcedureHeader + \ "PROCEDURE\(\s\[\|\s[a-zA-Z]\)\@!" contains = modula2ReswordProcedure + +" procedure header +syn match modula2ProcedureHeader + \ "PROCEDURE [a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*" + \ contains = modula2ReswordProcedure, + \ modula2ProcedureIdent, modula2ProcedureLowlineIdent, modula2IllegalChar, modula2IllegalIdent + +" procedure binding to operator +syn match modula2ProcedureHeader + \ "PROCEDURE \[[+-\*/\\=<>]\] [a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*" + \ contains = modula2ReswordProcedure, modula2Punctuation, + \ modula2ProcedureIdent, modula2ProcedureLowlineIdent, modula2IllegalChar, modula2IllegalIdent + +" procedure binding to builtin +syn match modula2ProcedureHeader + \ "PROCEDURE \[[A-Z]\+\(:\([#\*,]\|++\|--\)\?\)\?\] [a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*" + \ contains = modula2ReswordProcedure, + \ modula2Punctuation, modula2Resword, modula2SchroedToken, + \ modula2ProcIdent, modula2FuncIdent, modula2PrimitiveIdent, + \ modula2ProcedureIdent, modula2ProcedureLowlineIdent, modula2IllegalChar, modula2IllegalIdent + +syn match modula2ProcedureIdent + \ "\([a-zA-Z]\)\([a-zA-Z0-9]*\)" contained + +syn match modula2ProcedureLowlineIdent + \ "[a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)\+" contained + +syn match modula2ProcedureTail + \ "END [a-zA-Z][a-zA-Z0-9]*\(_[a-zA-Z0-9]\+\)*;$" + \ contains = modula2ReswordEnd, + \ modula2ProcedureIdent, modula2ProcedureLowLineIdent, + \ modula2Punctuation, modula2IllegalChar, modula2IllegalIdent + +syn keyword modula2ReswordModule contained MODULE +syn keyword modula2ReswordBlueprint contained BLUEPRINT +syn keyword modula2ReswordProcedure contained PROCEDURE +syn keyword modula2ReswordEnd contained END + + +" ----------------------------------------------------------------------------- +" Illegal Symbols +" ----------------------------------------------------------------------------- +" !!! this section must be last !!! + +" any '`' '~' '@' '$' '%' +syn match modula2IllegalChar "[`~@$%]" + +" any solitary sequence of '_' +syn match modula2IllegalChar "\<_\+\>" + +" any '?' at start of line if not followed by '<' +syn match modula2IllegalChar "^?\(<\)\@!" + +" any '?' not following '>' at start of line +syn match modula2IllegalChar "\(\(^>\)\|\(^\)\)\@" + + +" ----------------------------------------------------------------------------- +" Define Rendering Styles +" ----------------------------------------------------------------------------- + +" highlight default link modula2PredefIdentStyle Keyword +" highlight default link modula2ConstIdentStyle modula2PredefIdentStyle +" highlight default link modula2TypeIdentStyle modula2PredefIdentStyle +" highlight default link modula2ProcIdentStyle modula2PredefIdentStyle +" highlight default link modula2FuncIdentStyle modula2PredefIdentStyle +" highlight default link modula2MacroIdentStyle modula2PredefIdentStyle + +highlight default link modula2ConstIdentStyle Constant +highlight default link modula2TypeIdentStyle Type +highlight default link modula2ProcIdentStyle Function +highlight default link modula2FuncIdentStyle Function +highlight default link modula2MacroIdentStyle Function +highlight default link modula2PrimitiveIdentStyle Function +highlight default link modula2UnsafeIdentStyle Question +highlight default link modula2NonPortableIdentStyle Question +highlight default link modula2StringLiteralStyle String +highlight default link modula2CommentStyle Comment +highlight default link modula2PragmaStyle PreProc +highlight default link modula2PragmaKeyStyle PreProc +highlight default link modula2DialectTagStyle SpecialComment +highlight default link modula2TechDebtMarkerStyle SpecialComment +highlight default link modula2ReswordStyle Keyword +highlight default link modula2HeaderIdentStyle Function +highlight default link modula2UserDefIdentStyle Normal +highlight default link modula2NumericLiteralStyle Number +highlight default link modula2PunctuationStyle Delimiter +highlight default link modula2CommentKeyStyle SpecialComment +highlight default link modula2DisabledCodeStyle NonText + + +" ----------------------------------------------------------------------------- +" Assign Rendering Styles +" ----------------------------------------------------------------------------- + +" headers +highlight default link modula2ModuleIdent modula2HeaderIdentStyle +highlight default link modula2ProcedureIdent modula2HeaderIdentStyle +highlight default link modula2ModuleHeader modula2HeaderIdentStyle +highlight default link modula2ModuleTail Normal +highlight default link modula2ProcedureHeader Normal +highlight default link modula2ProcedureTail Normal + +" lowline identifiers are rendered as errors if g:modula2_r10_allow_lowline is unset +if exists("g:modula2_r10_allow_lowline") + if g:modula2_r10_allow_lowline != 0 + highlight default link modula2ProcedureLowlineIdent modula2HeaderIdentStyle + else + highlight default link modula2ProcedureLowlineIdent Error + endif +else + highlight default link modula2ProcedureLowlineIdent modula2HeaderIdentStyle +endif + +" reserved words +highlight default link modula2Resword modula2ReswordStyle +highlight default link modula2ReswordModule modula2ReswordStyle +highlight default link modula2ReswordProcedure modula2ReswordStyle +highlight default link modula2ReswordEnd modula2ReswordStyle +highlight default link modula2ReswordDo modula2ReswordStyle +highlight default link modula2ReswordTo modula2ReswordStyle +highlight default link modula2SchroedToken modula2ReswordStyle + +" predefined identifiers +highlight default link modula2ConstIdent modula2ConstIdentStyle +highlight default link modula2TypeIdent modula2TypeIdentStyle +highlight default link modula2ProcIdent modula2ProcIdentStyle +highlight default link modula2FuncIdent modula2FuncIdentStyle +highlight default link modula2MacroIdent modula2MacroIdentStyle +highlight default link modula2PrimitiveIdent modula2PrimitiveIdentStyle + +" unsafe and non-portable identifiers +highlight default link modula2UnsafeIdent modula2UnsafeIdentStyle +highlight default link modula2NonPortableIdent modula2NonPortableIdentStyle + +" user defined identifiers +highlight default link modula2Ident modula2UserDefIdentStyle + +" lowline identifiers are rendered as errors if g:modula2_r10_allow_lowline is unset +if exists("g:modula2_r10_allow_lowline") + if g:modula2_r10_allow_lowline != 0 + highlight default link modula2LowLineIdent modula2UserDefIdentStyle + else + highlight default link modula2LowLineIdent Error + endif +else + highlight default link modula2LowLineIdent modula2UserDefIdentStyle +endif + +" literals +highlight default link modula2String modula2StringLiteralStyle +highlight default link modula2Base2Num modula2NumericLiteralStyle +highlight default link modula2Base10Num modula2NumericLiteralStyle +highlight default link modula2Base16Num modula2NumericLiteralStyle + +" punctuation +highlight default link modula2Punctuation modula2PunctuationStyle + +" pragmas +highlight default link modula2Pragma modula2PragmaStyle +highlight default link modula2PragmaKey modula2PragmaKeyStyle +highlight default link modula2DialectTag modula2DialectTagStyle + +" comments +highlight default link modula2Comment modula2CommentStyle +highlight default link modula2CommentKey modula2CommentKeyStyle +highlight default link modula2ToDoTailComment modula2CommentStyle +highlight default link modula2StmtTailComment modula2CommentStyle + +" technical debt markers +highlight default link modula2ToDoHeader modula2TechDebtMarkerStyle +highlight default link modula2ToDoTail modula2TechDebtMarkerStyle +highlight default link modula2TechDebtPragma modula2TechDebtMarkerStyle + +" disabled code +highlight default link modula2DisabledCode modula2DisabledCodeStyle + +" illegal symbols +highlight default link modula2IllegalChar Error +highlight default link modula2IllegalIdent Error + + +let b:current_syntax = "modula2" + +" vim: ts=4 + +" END OF FILE diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index 9f493bb792..50e60de484 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -424,7 +424,6 @@ func s:GetFilenameChecks() abort \ 'mma': ['file.nb'], \ 'mmp': ['file.mmp'], \ 'modconf': ['/etc/modules.conf', '/etc/modules', '/etc/conf.modules', '/etc/modprobe.file', 'any/etc/conf.modules', 'any/etc/modprobe.file', 'any/etc/modules', 'any/etc/modules.conf'], - \ 'modula2': ['file.m2', 'file.mi'], \ 'modula3': ['file.m3', 'file.mg', 'file.i3', 'file.ig', 'file.lm3'], \ 'monk': ['file.isc', 'file.monk', 'file.ssc', 'file.tsc'], \ 'moo': ['file.moo'], @@ -1550,13 +1549,16 @@ func Test_mod_file() call writefile(['IMPLEMENTATION MODULE Module2Mod;'], 'modfile.MOD') split modfile.MOD call assert_equal('modula2', &filetype) + call assert_equal('pim', b:modula2.dialect) bwipe! " Modula-2 with comment and empty lines prior MODULE call writefile(['', '(* with', ' comment *)', '', 'MODULE Module2Mod;'], 'modfile.MOD') split modfile.MOD call assert_equal('modula2', &filetype) + call assert_equal('pim', b:modula2.dialect) bwipe! + call delete('modfile.MOD') " LambdaProlog module @@ -2284,4 +2286,38 @@ func Test_i_file() filetype off endfunc +func Test_def_file() + filetype on + + call writefile(['this is the fallback'], 'Xfile.def', 'D') + split Xfile.def + call assert_equal('def', &filetype) + bwipe! + + " Test dist#ft#FTdef() + + let g:filetype_def = 'modula2' + split Xfile.def + call assert_equal('modula2', &filetype) + call assert_equal('pim', b:modula2.dialect) + bwipe! + unlet g:filetype_def + + " Modula-2 + + call writefile(['(* a Modula-2 comment *)'], 'Xfile.def') + split Xfile.def + call assert_equal('modula2', &filetype) + call assert_equal('pim', b:modula2.dialect) + bwipe! + + call writefile(['IMPLEMENTATION MODULE Module2Mod;'], 'Xfile.def') + split Xfile.def + call assert_equal('modula2', &filetype) + call assert_equal('pim', b:modula2.dialect) + bwipe! + + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab