From 93e69e3a93655a7cee76763390d6ada3c7e1d0d3 Mon Sep 17 00:00:00 2001 From: Doug Kearns Date: Wed, 20 Apr 2016 07:50:09 +1000 Subject: [PATCH 1/3] Add missing official runtime files --- compiler/se.vim | 31 ++++++++++ ftplugin/eiffel.vim | 103 +++++++++++++++++++++++++++------ syntax/lace.vim | 136 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 17 deletions(-) create mode 100644 compiler/se.vim create mode 100644 syntax/lace.vim diff --git a/compiler/se.vim b/compiler/se.vim new file mode 100644 index 0000000..c90ce81 --- /dev/null +++ b/compiler/se.vim @@ -0,0 +1,31 @@ +" Vim compiler file +" Compiler: se (Liberty Eiffel Compiler) +" Maintainer: Doug Kearns +" Last Change: 2013 Jun 29 +" URL: https://github.com/eiffelhub/vim-eiffel + +if exists("current_compiler") + finish +endif +let current_compiler = "se" + +if exists(":CompilerSet") != 2 " older Vim always used :setlocal + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +CompilerSet makeprg=se\ c + +CompilerSet errorformat=%W******\ Warning:\ %m, + \%E******\ Fatal\ Error:\ %m, + \%E******\ Error:\ %m, + \%ZLine\ %l\ column\ %c\ in\ %.%#\ (%f)\ %\\=:, + \%ZLine\ %l\ columns\ %c\\,\ %\\d%\\+\ %.%#\ (%f)\ %\\=:, + \%+C%*[^\ ]%.%#, + \%-GThe\ source\ lines\ involved, + \%-G%.%# + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/ftplugin/eiffel.vim b/ftplugin/eiffel.vim index 84ce6a1..e0afe16 100644 --- a/ftplugin/eiffel.vim +++ b/ftplugin/eiffel.vim @@ -1,28 +1,97 @@ -" Vim filetype plugin file +" Vim filetype plugin " Language: Eiffel -" Maintainer: Jocelyn Fiat -" (https://github.com/eiffelhub/vim-eiffel) -" URL: https://github.com/eiffelhub/vim-eiffel -" Last Change: Tue 22 Apr 2003 09:50:08 +" Maintainer: Doug Kearns +" Last Change: 2010 Aug 29 +" URL: https://github.com/eiffelhub/vim-eiffel -" Only do this when not done yet for this buffer -if exists("b:did_ftplugin") +if (exists("b:did_ftplugin")) finish endif - -" Don't load another plugin for this buffer let b:did_ftplugin = 1 -" Matchit handling +let s:cpo_save = &cpo +set cpo&vim + +setlocal comments=:-- +setlocal commentstring=--\ %s -" The following lines enable the macros/matchit.vim plugin for -" extended matching with the % key. +setlocal formatoptions-=t formatoptions+=croql -if exists("loaded_matchit") +if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") + let b:browsefilter = "Eiffel Source Files (*.e)\t*.e\n" . + \ "Eiffel Control Files (*.ecf, *.ace, *.xace)\t*.ecf;*.ace;*.xace\n" . + \ "All Files (*.*)\t*.*\n" +endif +if exists("loaded_matchit") && !exists("b:match_words") let b:match_ignorecase = 0 - if !exists("b:match_words") | - let b:match_words = '\<\%(do\|if\|from\|check\|inspect\)\>:' . '\<\%(else\|elseif\|until\|loop\|when\):'. '\' - endif + " Silly \%^ trick to match note at head of pair and in middle prevents + " 'g%' wrapping from 'note' to 'end' + let b:match_words = '\%^:' . + \ '\<\%(^note\|indexing\|class\|^obsolete\|inherit\|insert\|^create\|convert\|feature\|^invariant\)\>:' . + \ '^end\>,' . + \ '\<\%(do\|deferred\|external\|once\%(\s\+"\)\@!\|check\|debug\|if\|inspect\|from\|across\)\>:' . + \ '\%(\%(^\s\+\)\@<=\%(then\|until\|loop\)\|\%(then\|until\|loop\)\s\+[^ -]\|' . + \ '\<\%(ensure\%(\s\+then\)\=\|rescue\|_then\|elseif\|else\|when\|\s\@<=invariant\|_until\|_loop\|variant\|_as\|alias\)\>\):' . + \ '\s\@<=end\>' + let b:match_skip = 's:\' + noremap [% + noremap ]% + vnoremap a% +endif + +let b:undo_ftplugin = "setl fo< com< cms<" . + \ "| unlet! b:browsefilter b:match_ignorecase b:match_words b:match_skip" + +if !exists("g:no_plugin_maps") && !exists("g:no_eiffel_maps") + function! s:DoMotion(pattern, count, flags) abort + normal! m' + for i in range(a:count) + call search(a:pattern, a:flags) + endfor + endfunction + + let sections = '^\%(note\|indexing\|' . + \ '\%(\%(deferred\|expanded\|external\|frozen\)\s\+\)*class\|' . + \ 'obsolete\|inherit\|insert\|create\|convert\|feature\|' . + \ 'invariant\|end\)\>' + + nnoremap ]] :call DoMotion(sections, v:count1, 'W') + xnoremap ]] :exe "normal! gv"call DoMotion(sections, v:count1, 'W') + nnoremap [[ :call DoMotion(sections, v:count1, 'Wb') + xnoremap [[ :exe "normal! gv"call DoMotion(sections, v:count1, 'Wb') + + function! s:DoFeatureMotion(count, flags) + let view = winsaveview() + call cursor(1, 1) + let [features_start, _] = searchpos('^feature\>') + call search('^\s\+\a') " find the first feature + let spaces = indent(line('.')) + let [features_end, _] = searchpos('^\%(invariant\|note\|end\)\>') + call winrestview(view) + call s:DoMotion('\%>' . features_start . 'l\%<' . features_end . 'l^\s*\%' . (spaces + 1) . 'v\zs\a', a:count, a:flags) + endfunction + + nnoremap ]m :call DoFeatureMotion(v:count1, 'W') + xnoremap ]m :exe "normal! gv"call DoFeatureMotion(v:count1, 'W') + nnoremap [m :call DoFeatureMotion(v:count1, 'Wb') + xnoremap [m :exe "normal! gv"call DoFeatureMotion(v:count1, 'Wb') + + let comment_block_start = '^\%(\s\+--.*\n\)\@ ]- :call DoMotion(comment_block_start, 1, 'W') + xnoremap ]- :exe "normal! gv"call DoMotion(comment_block_start, 1, 'W') + nnoremap [- :call DoMotion(comment_block_end, 1, 'Wb') + xnoremap [- :exe "normal! gv"call DoMotion(comment_block_end, 1, 'Wb') + + let b:undo_ftplugin = b:undo_ftplugin . + \ "| silent! execute 'unmap [[' | silent! execute 'unmap ]]'" . + \ "| silent! execute 'unmap [m' | silent! execute 'unmap ]m'" . + \ "| silent! execute 'unmap [-' | silent! execute 'unmap ]-'" +endif + +let &cpo = s:cpo_save +unlet s:cpo_save -endif " exists("loaded_matchit") +" vim: nowrap sw=2 sts=2 ts=8 diff --git a/syntax/lace.vim b/syntax/lace.vim new file mode 100644 index 0000000..4e1cd17 --- /dev/null +++ b/syntax/lace.vim @@ -0,0 +1,136 @@ +" Vim syntax file +" Language: lace +" Maintainer: Jocelyn Fiat +" Last Change: 2001 May 09 +" URL: https://github.com/eiffelhub/vim-eiffel + +" Copyright Interactive Software Engineering, 1998 +" You are free to use this file as you please, but +" if you make a change or improvement you must send +" it to the maintainer at + + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" LACE is case insensitive, but the style guide lines are not. + +if !exists("lace_case_insensitive") + syn case match +else + syn case ignore +endif + +" A bunch of useful LACE keywords +syn keyword laceTopStruct system root default option visible cluster +syn keyword laceTopStruct external generate end +syn keyword laceOptionClause collect assertion debug optimize trace +syn keyword laceOptionClause profile inline precompiled multithreaded +syn keyword laceOptionClause exception_trace dead_code_removal +syn keyword laceOptionClause array_optimization +syn keyword laceOptionClause inlining_size inlining +syn keyword laceOptionClause console_application dynamic_runtime +syn keyword laceOptionClause line_generation +syn keyword laceOptionMark yes no all +syn keyword laceOptionMark require ensure invariant loop check +syn keyword laceClusterProp use include exclude +syn keyword laceAdaptClassName adapt ignore rename as +syn keyword laceAdaptClassName creation export visible +syn keyword laceExternal include_path object makefile + +" Operators +syn match laceOperator "\$" +syn match laceBrackets "[[\]]" +syn match laceExport "[{}]" + +" Constants +syn keyword laceBool true false +syn keyword laceBool True False +syn region laceString start=+"+ skip=+%"+ end=+"+ contains=laceEscape,laceStringError +syn match laceEscape contained "%[^/]" +syn match laceEscape contained "%/\d\+/" +syn match laceEscape contained "^[ \t]*%" +syn match laceEscape contained "%[ \t]*$" +syn match laceStringError contained "%/[^0-9]" +syn match laceStringError contained "%/\d\+[^0-9/]" +syn match laceStringError "'\(%[^/]\|%/\d\+/\|[^'%]\)\+'" +syn match laceCharacter "'\(%[^/]\|%/\d\+/\|[^'%]\)'" contains=laceEscape +syn match laceNumber "-\=\<\d\+\(_\d\+\)*\>" +syn match laceNumber "\<[01]\+[bB]\>" +syn match laceNumber "-\=\<\d\+\(_\d\+\)*\.\(\d\+\(_\d\+\)*\)\=\([eE][-+]\=\d\+\(_\d\+\)*\)\=" +syn match laceNumber "-\=\.\d\+\(_\d\+\)*\([eE][-+]\=\d\+\(_\d\+\)*\)\=" +syn match laceComment "--.*" contains=laceTodo + + +syn case match + +" Case sensitive stuff + +syn keyword laceTodo TODO XXX FIXME +syn match laceClassName "\<[A-Z][A-Z0-9_]*\>" +syn match laceCluster "[a-zA-Z][a-zA-Z0-9_]*\s*:" +syn match laceCluster "[a-zA-Z][a-zA-Z0-9_]*\s*(\s*[a-zA-Z][a-zA-Z0-9_]*\s*)\s*:" + +" Catch mismatched parentheses +syn match laceParenError ")" +syn match laceBracketError "\]" +syn region laceGeneric transparent matchgroup=laceBrackets start="\[" end="\]" contains=ALLBUT,laceBracketError +syn region laceParen transparent start="(" end=")" contains=ALLBUT,laceParenError + +" Should suffice for even very long strings and expressions +syn sync lines=40 + +" Define the default highlighting. +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_lace_syntax_inits") + if version < 508 + let did_lace_syntax_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + HiLink laceTopStruct PreProc + + HiLink laceOptionClause Statement + HiLink laceOptionMark Constant + HiLink laceClusterProp Label + HiLink laceAdaptClassName Label + HiLink laceExternal Statement + HiLink laceCluster ModeMsg + + HiLink laceEscape Special + + HiLink laceBool Boolean + HiLink laceString String + HiLink laceCharacter Character + HiLink laceClassName Type + HiLink laceNumber Number + + HiLink laceOperator Special + HiLink laceArray Special + HiLink laceExport Special + HiLink laceCreation Special + HiLink laceBrackets Special + HiLink laceConstraint Special + + HiLink laceComment Comment + + HiLink laceError Error + HiLink laceStringError Error + HiLink laceParenError Error + HiLink laceBracketError Error + HiLink laceTodo Todo + + delcommand HiLink +endif + +let b:current_syntax = "lace" + +" vim: ts=4 From fee44a7f50e5c214160ae72ba56f260b7ebfa569 Mon Sep 17 00:00:00 2001 From: Doug Kearns Date: Wed, 20 Apr 2016 08:23:41 +1000 Subject: [PATCH 2/3] Update the Eiffel syntax file Support modern features and drop support for obsolete syntax. Add folding support to class-level clauses, feature declarations, strings and comments. Add support for Liberty Eiffel with the eiffel_liberty config variable. --- doc/syntax.txt | 66 +++++++ syntax/eiffel.vim | 495 ++++++++++++++++++++++++++++++---------------- 2 files changed, 394 insertions(+), 167 deletions(-) create mode 100644 doc/syntax.txt diff --git a/doc/syntax.txt b/doc/syntax.txt new file mode 100644 index 0000000..a28b485 --- /dev/null +++ b/doc/syntax.txt @@ -0,0 +1,66 @@ +EIFFEL *eiffel.vim* *ft-eiffel-syntax* + +By default Eiffel Software's dialect of the language is assumed. +Alternatively, if you are using Liberty Eiffel support for its differences can +be enabled by setting the following variable in your startup file: > + + :let eiffel_liberty=1 + +While Eiffel is not case-sensitive, its style guidelines are, and the +syntax highlighting file encourages their use. This also allows for +highlighting class names differently. If you want to disable case-sensitive +highlighting, add the following line to your startup file: > + + :let eiffel_ignore_case=1 + +Case still matters for class names and TODO marks in comments. + +Setting this variable has no effect when *eiffel_liberty* is set as Liberty +Eiffel is always case-sensitive. + +Conversely, for even stricter checks, add one of the following lines: > + + :let eiffel_strict=1 + :let eiffel_pedantic=1 + +Setting eiffel_strict will only catch improper capitalization for the +five predefined words "Current", "Void", "Result", "Precursor", and +"NONE", to warn against their accidental use as feature or class names. + +Setting eiffel_pedantic will enforce adherence to the Eiffel style +guidelines fairly rigorously (like arbitrary mixes of upper- and +lowercase letters as well as outdated ways to capitalize keywords). + +If you want to use the lower-case version of "Current", "Void", +"Result", and "Precursor", you can use > + + :let eiffel_lower_case_predef=1 + +instead of completely turning case-sensitive highlighting off. + +Folding of multiline syntax regions can be enabled with: > + + :let eiffel_fold=1 + +and the specific regions that are considered foldable can be specified with: > + + :let eiffel_fold_groups=[group1,...] + +The following groups are supported: > + +Group Description ~ +*note* A class-level notes clause +*class* The class header along with any formal generic list +*obsolete* The class-level obsolete mark +*inherit* An inherit clause (also insert when *eiffel_liberty* is set) +*create* A creation clause +*convert* The converter clause +*feature* A feature clause +*feature-body* A feature declaration +*invariant* The class-level invariant clause + +The default value is "note,obsolete,inherit,create,convert,feature,feature-body,invariant" + +Comments and strings are always foldable. + +vim:tw=78:sw=4:ts=8:ft=help:norl: diff --git a/syntax/eiffel.vim b/syntax/eiffel.vim index 0d044df..6993f8d 100644 --- a/syntax/eiffel.vim +++ b/syntax/eiffel.vim @@ -3,211 +3,372 @@ " Maintainer: Jocelyn Fiat " Previous maintainer: Reimer Behrends " Contributions from: Thilo Six -" +" " URL: https://github.com/eiffelhub/vim-eiffel -" For version 5.x: Clear all syntax items -" For version 6.x: Quit when a syntax file was already loaded -if version < 600 - syntax clear -elseif exists("b:current_syntax") +" Prelude {{{1 +if exists("b:current_syntax") finish endif let s:keepcpo= &cpo set cpo&vim +" Whitespace errors {{{1 +if exists("eiffel_space_errors") + if !exists("eiffel_no_trail_space_error") + syn match eiffelSpaceError display excludenl "\s\+$" + endif + if !exists("eiffel_no_tab_space_error") + syn match eiffelSpaceError display " \+\t"me=e-1 + endif +endif -" Option handling - -if exists("eiffel_ignore_case") +" Case sensitivity {{{1 +if exists("eiffel_ignore_case") && !exists("eiffel_liberty") syn case ignore else syn case match if exists("eiffel_pedantic") || exists("eiffel_strict") - syn keyword eiffelError current void result precursor none - syn keyword eiffelError CURRENT VOID RESULT PRECURSOR None + syn keyword eiffelError current void result precursor + syn keyword eiffelError CURRENT VOID RESULT PRECURSOR + syn keyword eiffelError none None syn keyword eiffelError TRUE FALSE endif if exists("eiffel_pedantic") syn keyword eiffelError true false - syn match eiffelError "\<[a-z_]\+[A-Z][a-zA_Z_]*\>" - syn match eiffelError "\<[A-Z][a-z_]*[A-Z][a-zA-Z_]*\>" + syn match eiffelError "\<[a-z_]\+[A-Z][a-zA_Z_]*\>" + syn match eiffelError "\<[A-Z][a-z_]*[A-Z][a-zA-Z_]*\>" + else + syn keyword eiffelBoolean true false endif if exists("eiffel_lower_case_predef") syn keyword eiffelPredefined current void result precursor endif endif -if exists("eiffel_hex_constants") - syn match eiffelNumber "\d[0-9a-fA-F]*[xX]" -endif +syn cluster eiffelContained contains=eiffelPercentCode,eiffelPercentCodeError,eiffelTodo,eiffelCommentName,eiffelSpecialFeatureSet,eiffelSpecialNoteName,eiffelConstraint + +" Parentheses {{{1 +" TODO: only use this in feature do/once blocks? +" syn match eiffelParenError ")" +" syn region eiffelParen transparent start="(" end=")" contains=ALLBUT,eiffelParenError,@eiffelContained,@eiffelTopClauses +" syn cluster eiffelParen contains=eiffelParen,eiffelParenError + +" Brackets {{{1 +syn match eiffelBracketError "\]" +syn region eiffelBrackets transparent matchgroup=eiffelBracket start="\[" end="]" contains=ALLBUT,eiffelBracketError,@eiffelContained,@eiffelTopClauses + +" Keywords {{{1 +syn keyword eiffelDeclaration alias assign attribute deferred do external local unique +syn keyword eiffelDeclaration alias contained containedin=eiffelInheritClause +syn keyword eiffelDeclaration convert contained containedin=eiffelInheritClause,@eiffelFeature +syn match eiffelDeclaration "\<\%(obsolete\|note\)\>" contained containedin=@eiffelFeature +if exists("eiffel_liberty") + syn match eiffelDeclaration "\" contained containedin=@eiffelFeature +end +syn match eiffelDeclaration "\" +if !exists("eiffel_liberty") + syn keyword eiffelAttachment attached detachable + syn keyword eiffelProperty expanded reference contained containedin=eiffelFormalGeneric + syn keyword eiffelProperty separate +else + syn keyword eiffelError separate +end +syn keyword eiffelProperty expanded separate frozen +syn keyword eiffelProperty prefix infix contained containedin=eiffelInheritClause,@eiffelFeature +syn keyword eiffelInherit rename contained containedin=eiffelFormalGeneric +syn keyword eiffelInherit rename redefine undefine select export +syn keyword eiffelConditional if else elseif inspect when then +syn keyword eiffelRepeat from until loop +if !exists("eiffel_liberty") + syn keyword eiffelRepeat across all some +end +syn keyword eiffelException rescue retry +syn keyword eiffelKeyword as +syn match eiffelKeyword "\" contained containedin=@eiffelFeature -" Keyword definitions - -syn keyword eiffelTopStruct note indexing feature creation inherit -syn match eiffelTopStruct "\" -syn match eiffelKeyword "\" -syn match eiffelTopStruct "^end\>\(\s*--\s\+class\s\+\<[A-Z][A-Z0-9_]*\>\)\=" contains=eiffelClassName -syn match eiffelBrackets "[[\]]" -syn match eiffelBracketError "\]" -syn region eiffelGeneric transparent matchgroup=eiffelBrackets start="\[" end="\]" contains=ALLBUT,eiffelBracketError,eiffelGenericDecl,eiffelStringError,eiffelStringEscape,eiffelGenericCreate,eiffelTopStruct -if exists("eiffel_ise") - syn match eiffelAgent "\" - syn match eiffelConvert "\" - syn match eiffelCreate "\" - syn match eiffelTopStruct contained "\" - syn match eiffelTopStruct contained "\" - syn match eiffelGenericCreate contained "\" - syn match eiffelTopStruct "^create\>" - syn region eiffelGenericDecl transparent matchgroup=eiffelBrackets contained start="\[" end="\]" contains=ALLBUT,eiffelCreate,eiffelTopStruct,eiffelGeneric,eiffelBracketError,eiffelStringEscape,eiffelStringError,eiffelBrackets - syn region eiffelClassHeader start="^class\>" end="$" contains=ALLBUT,eiffelCreate,eiffelGenericCreate,eiffelGeneric,eiffelStringEscape,eiffelStringError,eiffelBrackets -endif -syn keyword eiffelDeclaration is do once deferred unique local attribute assign -syn keyword eiffelDeclaration attached detachable Unique -syn keyword eiffelProperty expanded obsolete separate frozen -syn keyword eiffelProperty prefix infix -syn keyword eiffelInheritClause rename redefine undefine select export as -syn keyword eiffelAll all -syn keyword eiffelKeyword external alias some -syn keyword eiffelStatement if else elseif inspect -syn keyword eiffelStatement when then -syn match eiffelAssertion "\" -syn match eiffelAssertion "\" -syn keyword eiffelAssertion check +syn match eiffelAssertion "\" +syn match eiffelAssertion "\" +syn match eiffelAssertion "\" contained containedin=@eiffelFeature +syn keyword eiffelAssertion variant check + +syn keyword eiffelAgent agent syn keyword eiffelDebug debug -syn keyword eiffelStatement across from until loop -syn keyword eiffelAssertion variant -syn match eiffelAssertion "\" -syn match eiffelTopStruct "^invariant\>" -syn keyword eiffelException rescue retry +syn match eiffelCreate "\" contained containedin=@eiffelFeature +syn match eiffelOnce '\\ze\s\+"' +if exists("eiffel_liberty") + syn match eiffelOnce '\\ze\s\+U"' +end +" Predefined names {{{1 syn keyword eiffelPredefined Current Void Result Precursor +syn keyword eiffelAnchor Current contained -" Operators -syn match eiffelOperator "\" -syn match eiffelOperator "\" -syn keyword eiffelOperator xor implies not -syn keyword eiffelOperator strip old -syn keyword eiffelOperator Strip -syn match eiffelOperator "\$" -syn match eiffelCreation "!" -syn match eiffelExport "[{}]" -syn match eiffelArray "<<" -syn match eiffelArray ">>" -syn match eiffelConstraint "->" -syn match eiffelOperator "[@#|&][^ \e\t\b%]*" - -" Special classes -syn keyword eiffelAnchored like -syn keyword eiffelBitType BIT +" Special names {{{1 +syn keyword eiffelSpecialFeatureSet all contained +syn keyword eiffelAnchored like nextgroup=eiffelAnchor skipwhite +syn keyword eiffelSpecialNoteName EIS -" Constants -if !exists("eiffel_pedantic") - syn keyword eiffelBool true false -endif -syn keyword eiffelBool True False -syn region eiffelString start=+"+ skip=+%"+ end=+"+ contains=eiffelStringEscape,eiffelStringError -syn match eiffelStringEscape contained "%[^/]" -syn match eiffelStringEscape contained "%/\d\+/" -syn match eiffelStringEscape contained "^[ \t]*%" -syn match eiffelStringEscape contained "%[ \t]*$" -syn match eiffelStringError contained "%/[^0-9]" -syn match eiffelStringError contained "%/\d\+[^0-9/]" -syn match eiffelBadConstant "'\(%[^/]\|%/\d\+/\|[^'%]\)\+'" -syn match eiffelBadConstant "''" -syn match eiffelCharacter "'\(%[^/]\|%/\d\+/\|[^'%]\)'" contains=eiffelStringEscape -syn match eiffelNumber "-\=\<\d\+\(_\d\+\)*\>" -syn match eiffelNumber "\<[01]\+[bB]\>" -syn match eiffelNumber "-\=\<\d\+\(_\d\+\)*\.\(\d\+\(_\d\+\)*\)\=\([eE][-+]\=\d\+\(_\d\+\)*\)\=" -syn match eiffelNumber "-\=\.\d\+\(_\d\+\)*\([eE][-+]\=\d\+\(_\d\+\)*\)\=" -syn match eiffelComment "--.*" contains=eiffelTodo - -syn case match - -" Case sensitive stuff - -syn keyword eiffelTodo contained TODO XXX FIXME -syn match eiffelClassName "\<[A-Z][A-Z0-9_]*\>" - -" Catch mismatched parentheses -syn match eiffelParenError ")" -syn region eiffelParen transparent start="(" end=")" contains=ALLBUT,eiffelParenError,eiffelStringError,eiffelStringEscape - -if exists("eiffel_fold") -" setlocal foldmethod=indent -" syn sync fromstart +" Operators {{{1 +if exists("eiffel_liberty") + syn match eiffelFreeOperator "[-+*/\=<>@#|&~]\%([.?{}]*[-+*/\=<>@#|&~]\)*" +else + syn match eiffelFreeOperator "[@#|&][^%[:space:][:cntrl:]]*" endif +syn match eiffelPredefinedOperator "\%(=\|/=\|\~\|/\~\)" +syn match eiffelStandardOperator "[-+*/^<>]" +syn match eiffelStandardOperator "\%(<=\|>=\|//\|\\\\\|\.\.\)" +syn match eiffelStandardOperatorWord "\" +syn match eiffelStandardOperatorWord "\" +syn keyword eiffelStandardOperatorWord xor implies not + +" postcondition 'operators' +if !exists("eiffel_liberty") + syn keyword eiffelOperator strip +end +syn keyword eiffelOperator old + +syn match eiffelAddress "\$" +syn match eiffelAssignment ":=" +if exists("eiffel_liberty") + syn match eiffelAssignment "[:?]:=" +end +syn match eiffelConstraint "->" +syn match eiffelTypeBrace "[{}]" + +" Class names {{{1 +syn match eiffelClassName "\C\<[A-Z][A-Z0-9_]*\>" nextgroup=eiffelFormalGeneric skipwhite contained containedin=eiffelClassClause +syn match eiffelClassName "\C\<[A-Z][A-Z0-9_]*\>" contained containedin=eiffelClients +syn match eiffelClassName "\C\<[A-Z][A-Z0-9_]*\>" nextgroup=eiffelActualGeneric skipwhite + +if exists("eiffel_liberty") + syn keyword eiffelError NONE containedin=ALLBUT,@eiffelString,@eiffelComment +end + +" actual generics, tuples, conversions +syn cluster eiffelTypeList contains=eiffelClassName,eiffelAttachment,eiffelTypeBrace,eiffelAnchored +" exports, create, feature +syn region eiffelClients matchgroup=eiffelTypeBrace start="{" end="}" contained contains=@eiffelComment "contains=eiffelClassName + +" Generics {{{1 +" TODO: remove contained eActualGeneric? Utilise eTypeList? +syn region eiffelFormalGeneric transparent matchgroup=eiffelBracket start="\[" end="]" contained contains=eiffelActualGeneric,eiffelClassName,eiffelTypeBrace,eiffelConstraint,eiffelAttachment,eiffelCreate,eiffelKeyword +syn region eiffelActualGeneric transparent matchgroup=eiffelBracket start="\[" end="]" contained contains=eiffelActualGeneric,eiffelClassName,eiffelTypeBrace,eiffelAttachment,eiffelAnchored + +" Constants and other manifest forms {{{1 +syn keyword eiffelBoolean True False + +syn cluster eiffelString contains=eiffelString,eiffelVerbatimString + +syn match eiffelStringError '"%\+"' + +syn match eiffelPercentCode contained "\c%/\%(\d\+\|0x\x\+\|0c\o\+\|0b[01]\+\)/" containedin=eiffelCharacter +syn match eiffelPercentCodeError contained "%." +syn match eiffelPercentCode contained "%[ABCDFHLNQRSTUV%'"()<>]" +syn match eiffelPercentCodeError contained "%/[^/]*/\=" +syn match eiffelPercentCode contained "%/\d\+/" +if exists("eiffel_liberty") + syn match eiffelPercentCode contained "\c%/0x\%(\x\x\)\+/" + syn match eiffelUnicodePercentCode contained "%/Ux\x\+\%(_\x\+\)*/" +else + syn match eiffelStringError '\= 508 || !exists("did_eiffel_syntax_inits") - if version < 508 - let did_eiffel_syntax_inits = 1 - command -nargs=+ HiLink hi link - else - command -nargs=+ HiLink hi def link - endif - - HiLink eiffelKeyword Statement - HiLink eiffelProperty Statement - HiLink eiffelInheritClause Statement - HiLink eiffelStatement Statement - HiLink eiffelDeclaration Statement - HiLink eiffelAssertion Statement - HiLink eiffelDebug Statement - HiLink eiffelException Statement - HiLink eiffelGenericCreate Statement - - HiLink eiffelAgent Statement - HiLink eiffelConvert Statement - - HiLink eiffelTopStruct PreProc - - HiLink eiffelAll Special - HiLink eiffelAnchored Special - HiLink eiffelBitType Special - - - HiLink eiffelBool Boolean - HiLink eiffelString String - HiLink eiffelCharacter Character - HiLink eiffelClassName Type - HiLink eiffelNumber Number - - HiLink eiffelStringEscape Special - - HiLink eiffelOperator Special - HiLink eiffelArray Special - HiLink eiffelExport Special - HiLink eiffelCreation Special - HiLink eiffelBrackets Special - HiLink eiffelGeneric Special - HiLink eiffelGenericDecl Special - HiLink eiffelConstraint Special - HiLink eiffelCreate Special - - HiLink eiffelPredefined Constant +syn region eiffelString start=+"+ skip=+%%\|%"+ end=+"+ contains=eiffelPercentCode,eiffelPercentCodeError oneline +syn region eiffelString start=+"\ze.*%\s*\n\s*%+ skip=+%%\|%"+ end=+"+ contains=eiffelPercentCode,eiffelPercentCodeError,eiffelStringLineWrap fold +if exists("eiffel_liberty") + syn region eiffelUnicodeString start=+U"+ skip=+%%\|%"+ end=+"+ contains=eiffelPercentCode,eiffelUnicodePercentCode,eiffelPercentCodeError oneline + syn region eiffelUnicodeString start=+U"\ze.*%\s*\n\s*%+ skip=+%%\|%"+ end=+"+ contains=eiffelPercentCode,eiffelUnicodePercentCode,eiffelPercentCodeError,eiffelStringLineWrap fold + syn cluster eiffelString add=eiffelUnicodeString +end - HiLink eiffelComment Comment +syn match eiffelPercentCodeError contained "\%(%%\)\+\n" +syn match eiffelStringLineWrap contained "%\s*\n\s*%" - HiLink eiffelError Error - HiLink eiffelBadConstant Error - HiLink eiffelStringError Error - HiLink eiffelParenError Error - HiLink eiffelBracketError Error +syn region eiffelVerbatimString start=+"\z([^"]*\)\[\s*$+ end=+^\s*]\z1"+ fold +syn region eiffelVerbatimString start=+"\z([^"]*\){\s*$+ end=+^\s*}\z1"+ fold - HiLink eiffelTodo Todo +syn match eiffelCharacterError "'[^']*'" - delcommand HiLink +syn match eiffelCharacter "'%\@!\p'" +syn match eiffelCharacter "\C'%[ABCDFHLNQRSTUV%'"()<>]'" contains=eiffelPercentCode +if exists("eiffel_liberty") + syn match eiffelCharacter "'\c%/\%(\d\+\|0x\x\x\)/'" contains=eiffelPercentCode +else + syn match eiffelCharacter "'\c%/\%(\d\+\|0x\x\+\|0c\o\+\|0b[01]\+\)/'" contains=eiffelPercentCode +end +syn cluster eiffelCharacter contains=eiffelCharacter,eiffelCharacterError + +if !exists("eiffel_liberty") + syn match eiffelInteger "\c-\=\<0b[01]\+\%(_[01]\+\)*\>" + syn match eiffelInteger "\c-\=\<0c\o\+\%(_\o\+\)*\>" +end +syn match eiffelInteger "-\=\<\d\+\%(_\d\+\)*\>" +syn match eiffelInteger "\c-\=\<0x\x\+\%(_\x\+\)*\>" +syn match eiffelReal "-\=\<\d\+\%(_\d\+\)*\.\%(\d\+\%(_\d\+\)*\)\=\%([eE][-+]\=\d\+\%(_\d\+\)*\)\=" +syn match eiffelReal "-\=\.\d\+\%(_\d\+\)*\%([eE][-+]\=\d\+\%(_\d\+\)*\)\=" +syn cluster eiffelNumber contains=eiffelInteger,eiffelReal + +syn region eiffelArray matchgroup=eiffelArrayDelimiter start="<<" end=">>" transparent fold + +syn cluster eiffelManifestType contains=eiffelClassName,eiffelAttachment,eiffelAnchored,eiffelTypeBrace +syn cluster eiffelConstant contains=eiffelBoolean,@eiffelCharacter,@eiffelNumber,@eiffelString,@eiffelManifestType + +" Folding support {{{1 +if has("folding") && exists("eiffel_fold") + setlocal foldtext=EiffelFoldText() + setlocal foldmethod=syntax endif +" join multiline class headers +function! EiffelFoldText() + let fdt = foldtext() + if getline(v:foldstart) =~ 'class\s*$' + let classname = substitute(getline(nextnonblank(v:foldstart + 1)), '\s*', '', '') + let fdt .= ' ' . classname + endif + return fdt +endfunction + +function! s:IsFoldable(name) + let default = "note,obsolete,inherit,create,convert,feature,feature-body,invariant" " exclude class headers + return index(split(get(g:, "eiffel_fold_groups", default), '\s*,\s*'), a:name, 0, 1) != -1 +endfunction + +" Top level clauses {{{1 +function! s:MakeTopClause(name, start, end, contains) + call add(a:end, '^end\>\ze\(\(^\(\s*--\|\s*$\)\@!\)\@!\_.\)*\%$') + execute "syn region eiffel" . a:name . "Clause transparent matchgroup=eiffelTopStruct" . + \ ' start="' . a:start . '"' + \ join(map(a:end, '"end=\"" . v:val . "\""')) . + \ " contains=" . a:contains . " " . (s:IsFoldable(a:name) ? "fold" : "") +endfunction + +syn cluster eiffelTopClauses contains=eiffelNoteClause,eiffelClassClause,eiffelObsoleteClause,eiffelInheritClause,eiffelCreateClause,eiffelConvertClause,eiffelFeatureClause,eiffelInvariantClause + +if exists("eiffel_liberty") + let s:inherit = 'inherit\|insert' + let s:note = '\%(note\|indexing\)' +else + let s:inherit = "inherit" + let s:note = "note" +end + +call s:MakeTopClause("Note", '\<' . s:note . '\>', + \ ['\ze\', + \ '\ze\', + \ '\ze\<\%(\%\(frozen\)\=\s*\%(expanded\)\=\s*\%(external\)\=\)\s\+class\>'], + \ "@eiffelConstant,eiffelSpecialNoteName,@eiffelComment") +call s:MakeTopClause("Class", '\', + \ ['\ze\<\%(obsolete\|' . s:inherit . '\|create\|convert\|feature\|invariant\)\>', '\ze;\=' . s:note . '\>'], + \ "@eiffelComment") +call s:MakeTopClause("Obsolete", '\', + \ ['\ze\<\%(' . s:inherit . '\|create\|convert\|feature\|invariant\)\>', '\ze;\=' . s:note . '\>'], + \ "@eiffelString,@eiffelComment") +call s:MakeTopClause("Inherit", '\<\%(' . s:inherit . '\)\>', + \ ['\ze\<\%(' . s:inherit . '\|create\|_convert\|feature\|invariant\)\>', '^\zeconvert\>', '\ze;\=' . s:note . '\>'], + \ "eiffelClassName,eiffelInherit,eiffelKeyword,eiffelClients,eiffelSpecialFeatureSet,@eiffelString,@eiffelComment") +call s:MakeTopClause("Create", '\', + \ ['\ze\<\%(create\|convert\|feature\|invariant\)\>', '\ze;\=' . s:note . '\>'], + \ "TOP,@eiffelTopClauses") +call s:MakeTopClause("Convert", '\', + \ ['\ze\<\%(feature\|invariant\)\>', '\ze;\=' . s:note . '\>'], + \ "eiffelTypeBrace,eiffelClassName,eiffelAttachment,@eiffelComment") +call s:MakeTopClause("Feature", '\', + \ ['\ze\%(\', '^\ze;\=' . s:note . '\>'], + \ "TOP,@eiffelTopClauses") +call s:MakeTopClause("Invariant", '\', + \ ['\ze;\=' . s:note . '\>'], + \ "TOP,@eiffelTopClauses") + +" Features {{{1 +syn cluster eiffelFeature contains=eiffelFeatureClause,eiffelFeature + +exec 'syn region eiffelFeature ' . + \ 'start="^\s\+\%' . (&sw + 1) . 'vfrozen\>" ' . + \ 'start="^\s\+\%' . (&sw + 1) . 'v\a\w*.\{-}\(:\|\_s*(\_s*\a\w*:\|\(\_s*--.*\|\_s\)*\<\(do\|once\|deferred\|external\|obsolete\|note\|require\|local\|attribute\)\>\)" ' . + \ 'end="\ze\n\_s*\%' . (&sw + 1) . 'v\a\w*" ' . + \ 'end="^\s\+\%' . (&sw * 2 + 1) . 'v\" ' . + \ 'end="\ze\n\%(\s*\n\)*\%(\%(feature\|invariant\|note\|end\)\>\)" ' . + \ 'contained containedin=eiffelFeatureClause contains=TOP,@eiffelTopClauses ' . (s:IsFoldable("feature-body") ? 'fold' : '') + +" Comments {{{1 +syn match eiffelComment "--.*" contains=eiffelTodo,eiffelCommentName,@Spell +syn match eiffelComment "\%(^end\s*\)\@<=--\sclass \u\w*\s*$" contains=eiffelClassName +" TODO: from memory, the official recommendation is to conceal quotes and italicize - desirable? +syn match eiffelCommentName "`[^']\+'" contained +syn match eiffelTodo "\C\%(TODO\|XXX\|FIXME\|NOTE\)" contained +syn region eiffelMultilineComment start="^\s*--.*\n\%(\s*--\)\@=" end="^\s*--.*\n\%(\s*--\)\@!" contains=eiffelComment transparent keepend fold +syn cluster eiffelComment contains=eiffelComment,eiffelMultilineComment + +" Syncing {{{1 +syn sync fromstart + +" Default highlighting {{{1 +hi def link eiffelKeyword Statement +hi def link eiffelProperty Statement +hi def link eiffelInherit Statement +hi def link eiffelConditional Statement +hi def link eiffelRepeat Statement +hi def link eiffelDeclaration Statement +hi def link eiffelAttachment Statement +hi def link eiffelAssertion Statement +hi def link eiffelDebug Statement +hi def link eiffelException Statement + +hi def link eiffelAgent Statement +hi def link eiffelCreate Statement +hi def link eiffelNote Statement +hi def link eiffelObsolete Statement +hi def link eiffelOnce Statement + +hi def link eiffelTopStruct PreProc + +hi def link eiffelAnchored Special +hi def link eiffelSpecialFeatureSet Special +hi def link eiffelSpecialNoteName Special + +hi def link eiffelClassName Type + +hi def link eiffelBoolean Boolean +hi def link eiffelCharacter Character +hi def link eiffelString String +hi def link eiffelUnicodeString eiffelString +hi def link eiffelVerbatimString eiffelString +hi def link eiffelInteger Number +hi def link eiffelReal Float + +hi def link eiffelPercentCode Special +hi def link eiffelStringLineWrap eiffelPercentCode +hi def link eiffelUnicodePercentCode eiffelPercentCode + +hi def link eiffelOperator Special +hi def link eiffelFreeOperator eiffelOperator +hi def link eiffelStandardOperatorWord eiffelOperator +hi def link eiffelArrayDelimiter Special +hi def link eiffelTypeBrace Special +hi def link eiffelBracket Special +hi def link eiffelAddress Special +hi def link eiffelConstraint Special + +hi def link eiffelPredefined Constant +hi def link eiffelAnchor eiffelPredefined + +hi def link eiffelComment Comment +hi def link eiffelCommentName SpecialComment +hi def link eiffelTodo Todo + +hi def link eiffelError Error +hi def link eiffelStringError Error +hi def link eiffelCharacterError Error +hi def link eiffelPercentCodeError Error +hi def link eiffelParenError Error +hi def link eiffelBracketError Error +hi def link eiffelSpaceError Error + +" Postscript {{{1 let b:current_syntax = "eiffel" let &cpo = s:keepcpo unlet s:keepcpo -" vim: ts=8 From b4480633a7e54fa736f432cf9376aa837b9a250e Mon Sep 17 00:00:00 2001 From: Doug Kearns Date: Fri, 22 Apr 2016 10:25:41 +1000 Subject: [PATCH 3/3] Make eiffelFeature transparent --- syntax/eiffel.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/syntax/eiffel.vim b/syntax/eiffel.vim index 6993f8d..94fa9ca 100644 --- a/syntax/eiffel.vim +++ b/syntax/eiffel.vim @@ -288,9 +288,9 @@ exec 'syn region eiffelFeature ' . \ 'start="^\s\+\%' . (&sw + 1) . 'vfrozen\>" ' . \ 'start="^\s\+\%' . (&sw + 1) . 'v\a\w*.\{-}\(:\|\_s*(\_s*\a\w*:\|\(\_s*--.*\|\_s\)*\<\(do\|once\|deferred\|external\|obsolete\|note\|require\|local\|attribute\)\>\)" ' . \ 'end="\ze\n\_s*\%' . (&sw + 1) . 'v\a\w*" ' . - \ 'end="^\s\+\%' . (&sw * 2 + 1) . 'v\" ' . - \ 'end="\ze\n\%(\s*\n\)*\%(\%(feature\|invariant\|note\|end\)\>\)" ' . - \ 'contained containedin=eiffelFeatureClause contains=TOP,@eiffelTopClauses ' . (s:IsFoldable("feature-body") ? 'fold' : '') + \ 'matchgroup=eiffelKeyword end="^\s\+\%' . (&sw * 2 + 1) . 'v\" ' . + \ 'matchgroup=NONE end="\ze\n\%(\s*\n\)*\%(\%(feature\|invariant\|note\|end\)\>\)" ' . + \ 'contained transparent containedin=eiffelFeatureClause contains=TOP,@eiffelTopClauses ' . (s:IsFoldable("feature-body") ? 'fold' : '') " Comments {{{1 syn match eiffelComment "--.*" contains=eiffelTodo,eiffelCommentName,@Spell