--- /dev/null
+" DoxygenToolkit.vim
+" Brief: Usefull tools for Doxygen (comment, author, license).
+" Version: 0.2.13
+" Date: 2010/10/16
+" Author: Mathias Lorente
+"
+" TODO: add automatically (option controlled) in/in out flags to function
+" parameters
+" TODO: (Python) Check default paramareters defined as list/dictionnary/tuple
+"
+" Note: Correct insertion position and 'xxx_post' parameters.
+" - Insert position is correct when g:DoxygenToolkit_compactOneLineDoc = "yes"
+" and let g:DoxygenToolkit_commentType = "C++" are set.
+" - When you define:
+" g:DoxygenToolkit_briefTag_pre = "@brief "
+" g:DoxygenToolkit_briefTag_post = "<++>"
+" g:DoxygenToolkit_briefTag_funcName = "yes"
+" Documentation generated with these parameters is something like:
+" /// @brief foo <++>
+" You can configure similarly parameters to get something like:
+" /// @brief foo <++>
+" /// @param bar <++>
+" /// @param baz <++>
+"
+" Note: Position the cursor at the right position for one line documentation.
+"
+" Note: Remove trailing blank characters where they are not needed.
+"
+" Note: 'extern' keyword added in list of values to ignore for return type.
+"
+" Note: Correct bugs related to templates and add support for throw statement
+" (many thanks to Dennis Lubert):
+" - Template parameter of different type from class and typename are
+" recognized.
+" - Indentation mistake while detecting template.
+" - New option are available: g:DoxygenToolkit_throwTag_pre and
+" g:DoxygenToolkit_throwTag_post
+"
+" Note: Add support for documentation of template parameters.
+" Thanks to Dennis (plasmahh) and its suggestions.
+" - New option are available: g:DoxygenToolkit_templateParamTag_pre
+" and g:DoxygenToolkit_templateParamTag_post
+"
+" Note: Solve almost all compatibility problem with c/c++ IDE
+"
+" Note: Bug correction and improve compatibility with c/c++ IDE
+" - Documentation of function with struct parameters are now allowed.
+" - Comments are written in two steps to avoid conflicts with c/c++ IDE.
+"
+" Note: Bug correction (thanks to Jhon Do)
+" - DoxygenToolkit_briefTag_funcName and other xxx_xxName parameters
+" should work properly now.
+"
+" Note: Bug correction (thanks to Anders Bo Rasmussen)
+" - C++: now functions like void foo(type &bar); are correctly documented.
+" The parameter's name is bar (and no more &bar).
+"
+" Note: Added @version tag into the DocBlock generated by DoxygenAuthorFunc()
+" (thanks to Dave Walter).
+" The version string can be defines into your .vimrc file with
+" g:DoxygenToolkit_versionString or it will be asked the first time the
+" function is called (same behavior as @author tag). Example:
+" /// \file foo.cpp
+" /// \brief
+" /// \author Dave Walter
+" /// \version 1.0
+" /// \date 2009-03-26
+"
+" Note: Comments are now allowed in function declaration. Example:
+" - C/C++: void func( int foo, // first param
+" int bar /* second param */ );
+"
+" - Python: def func( foo, # first param
+" bar ) # second param
+"
+" Note: Bug correction (many thanks to Alexey Radkov)
+" - C/C++: following function/method are now correctly documented:
+" - operator(),
+" - constructor with initialization parameter(s),
+" - pure virtual method,
+" - const method.
+" - Python:
+" - Single line function are now correctly documented.
+"
+" Note: The main function has been rewritten (I hope it is cleaner).
+" - There is now support for function pointer as parameter (C/C++).
+" - You can configure the script to get one line documentation (for
+" attribute instance for example, you need to set
+" g:DoxygenToolkit_compactOneLineDoc to "yes").
+"
+" - NEW: Support Python scripts:
+" - Function/method are not scanned, so by default they are considered
+" as if they always return something (modify this behavior by defining
+" g:DoxygenToolkit_python_autoFunctionReturn to "no")
+" - self parameter is automatically ignored when scanning function
+" parameters (you can change this behavior by defining
+" g:DoxygenToolkit_python_autoRemoveSelfParam to "no")
+"
+" Note: Number of lines scanned is now configurable. Default value is still 10
+" lines. (Thanks to Spencer Collyer for this improvement).
+"
+" Note: Bug correction : function that returns null pointer are correctly
+" documented (Thanks to Ronald WAHL for his report and patch).
+"
+" Note: Remove header and footer from doxygen documentation
+" - Generated documentation with block header/footer activated (see
+" parameters g:DoxygenToolkit_blockHeader and
+" g:DoxygenToolkit_blockFooter) do not integrate header and footer
+" anymore.
+" Thanks to Justin RANDALL for this.
+" Now comments are as following:
+" /* --- My Header --- */ // --- My Header ---
+" /** /// @brief ...
+" * @brief ... or // --- My Footer ---
+" */
+" /* -- My Footer --- */
+"
+" Note: Changes to customize cinoptions
+" - New option available for cinoptions : g:DoxygenToolkit_cinoptions
+" (default value is still c1C1)
+" Thanks to Arnaud GODET for this. Now comment can have the following
+" look:
+" /** /**
+" * and not only *
+" */ */
+" Note: Changes for linux kernel comment style
+" - New option are available for brief tag and parameter tag ! Now there is
+" a pre and a post tag for each of these tag.
+" - You can define 'let g:DoxygenToolkit_briefTag_funcName = "yes"' to add
+" the name of commented function between pre-brief tag and post-brief tag.
+" - With these new features you can get something like:
+" /**
+" * @brief MyFunction -
+" *
+" * @param foo:
+" * @param bar:
+" */
+" Note: Changes suggested by Soh Kok Hong:
+" - Fixed indentation in comments
+" ( no more /** /**
+" * but *
+" */ */ )
+" Note: Changes made by Jason Mills:
+" - Fixed \n bug which resulted in comments being screwed up
+" - Added use of doxygen /// comments.
+" Note: Changes made by Mathias Lorente on 05/25/04
+" - Fixed filename bug when including doxygen author comment whereas file
+" has not been open directly on commamd line.
+" - Now /// or /** doxygen comments are correctly integrated (except for
+" license).
+" Note: Changes made by Mathias Lorente on 08/02/04
+" - Now include only filename in author comment (no more folder...)
+" - Fixed errors with function with no indentation.
+"
+"
+" Currently five purposes have been defined :
+"
+" Generates a doxygen license comment. The tag text is configurable.
+"
+" Generates a doxygen author skeleton. The tag text is configurable.
+"
+" Generates a doxygen comment skeleton for a C, C++ or Python function or class,
+" including @brief, @param (for each named argument), and @return. The tag
+" text as well as a comment block header and footer are configurable.
+" (Consequently, you can have \brief, etc. if you wish, with little effort.)
+"
+" Ignore code fragment placed in a block defined by #ifdef ... #endif (C/C++). The
+" block name must be given to the function. All of the corresponding blocks
+" in all the file will be treated and placed in a new block DOX_SKIP_BLOCK (or
+" any other name that you have configured). Then you have to update
+" PREDEFINED value in your doxygen configuration file with correct block name.
+" You also have to set ENABLE_PREPROCESSING to YES.
+"
+" Generate a doxygen group (begining and ending). The tag text is
+" configurable.
+"
+" Use:
+" - Type of comments (C/C++: /// or /** ... */, Python: ## and # ) :
+" In vim, default C++ comments are : /** ... */. But if you prefer to use ///
+" Doxygen comments just add 'let g:DoxygenToolkit_commentType = "C++"'
+" (without quotes) in your .vimrc file
+"
+" - License :
+" In vim, place the cursor on the line that will follow doxygen license
+" comment. Then, execute the command :DoxLic. This will generate license
+" comment and leave the cursor on the line just after.
+"
+" - Author :
+" In vim, place the cursor on the line that will follow doxygen author
+" comment. Then, execute the command :DoxAuthor. This will generate the
+" skeleton and leave the cursor just after @author tag if no variable
+" define it, or just after the skeleton.
+"
+" - Function / class comment :
+" In vim, place the cursor on the line of the function header (or returned
+" value of the function) or the class. Then execute the command :Dox. This
+" will generate the skeleton and leave the cursor after the @brief tag.
+"
+" - Ignore code fragment :
+" In vim, if you want to ignore all code fragment placed in a block such as :
+" #ifdef DEBUG
+" ...
+" #endif
+" You only have to execute the command :DoxUndoc(DEBUG) !
+"
+" - Group :
+" In vim, execute the command :DoxBlock to insert a doxygen block on the
+" following line.
+"
+" Limitations:
+" - Assumes that the function name (and the following opening parenthesis) is
+" at least on the third line after current cursor position.
+" - Not able to update a comment block after it's been written.
+" - Blocks delimiters (header and footer) are only included for function
+" comment.
+" - Assumes that cindent is used.
+" - Comments in function parameters (such as void foo(int bar /* ... */, baz))
+" are not yet supported.
+"
+"
+" Example:
+" Given:
+" int
+" foo(char mychar,
+" int myint,
+" double* myarray,
+" int mask = DEFAULT)
+" { //...
+" }
+"
+" Issuing the :Dox command with the cursor on the function declaration would
+" generate
+"
+" /**
+" * @brief
+" *
+" * @param mychar
+" * @param myint
+" * @param myarray
+" * @param mask
+" *
+" * @return
+" */
+"
+"
+" To customize the output of the script, see the g:DoxygenToolkit_*
+" variables in the script's source. These variables can be set in your
+" .vimrc.
+"
+" For example, my .vimrc contains:
+" let g:DoxygenToolkit_briefTag_pre="@Synopsis "
+" let g:DoxygenToolkit_paramTag_pre="@Param "
+" let g:DoxygenToolkit_returnTag="@Returns "
+" let g:DoxygenToolkit_blockHeader="--------------------------------------------------------------------------"
+" let g:DoxygenToolkit_blockFooter="----------------------------------------------------------------------------"
+" let g:DoxygenToolkit_authorName="Mathias Lorente"
+" let g:DoxygenToolkit_licenseTag="My own license" <-- Does not end with
+" "\<enter>"
+
+
+" Verify if already loaded
+"if exists("loaded_DoxygenToolkit")
+" echo 'DoxygenToolkit Already Loaded.'
+" finish
+"endif
+let loaded_DoxygenToolkit = 1
+"echo 'Loading DoxygenToolkit...'
+let s:licenseTag = "Copyright (C) \<enter>\<enter>"
+let s:licenseTag = s:licenseTag . "This program is free software; you can redistribute it and/or\<enter>"
+let s:licenseTag = s:licenseTag . "modify it under the terms of the GNU General Public License\<enter>"
+let s:licenseTag = s:licenseTag . "as published by the Free Software Foundation; either version 2\<enter>"
+let s:licenseTag = s:licenseTag . "of the License, or (at your option) any later version.\<enter>\<enter>"
+let s:licenseTag = s:licenseTag . "This program is distributed in the hope that it will be useful,\<enter>"
+let s:licenseTag = s:licenseTag . "but WITHOUT ANY WARRANTY; without even the implied warranty of\<enter>"
+let s:licenseTag = s:licenseTag . "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\<enter>"
+let s:licenseTag = s:licenseTag . "GNU General Public License for more details.\<enter>\<enter>"
+let s:licenseTag = s:licenseTag . "You should have received a copy of the GNU General Public License\<enter>"
+let s:licenseTag = s:licenseTag . "along with this program; if not, write to the Free Software\<enter>"
+let s:licenseTag = s:licenseTag . "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\<enter>"
+
+" Common standard constants
+if !exists("g:DoxygenToolkit_briefTag_pre")
+ let g:DoxygenToolkit_briefTag_pre = "@brief "
+endif
+if !exists("g:DoxygenToolkit_briefTag_post")
+ let g:DoxygenToolkit_briefTag_post = ""
+endif
+if !exists("g:DoxygenToolkit_templateParamTag_pre")
+ let g:DoxygenToolkit_templateParamTag_pre = "@tparam "
+endif
+if !exists("g:DoxygenToolkit_templateParamTag_post")
+ let g:DoxygenToolkit_templateParamTag_post = ""
+endif
+if !exists("g:DoxygenToolkit_paramTag_pre")
+ let g:DoxygenToolkit_paramTag_pre = "@param "
+endif
+if !exists("g:DoxygenToolkit_paramTag_post")
+ let g:DoxygenToolkit_paramTag_post = ""
+endif
+if !exists("g:DoxygenToolkit_returnTag")
+ let g:DoxygenToolkit_returnTag = "@return "
+endif
+if !exists("g:DoxygenToolkit_throwTag_pre")
+ let g:DoxygenToolkit_throwTag_pre = "@throw " " @exception is also valid
+endif
+if !exists("g:DoxygenToolkit_throwTag_post")
+ let g:DoxygenToolkit_throwTag_post = ""
+endif
+if !exists("g:DoxygenToolkit_blockHeader")
+ let g:DoxygenToolkit_blockHeader = ""
+endif
+if !exists("g:DoxygenToolkit_blockFooter")
+ let g:DoxygenToolkit_blockFooter = ""
+endif
+if !exists("g:DoxygenToolkit_licenseTag")
+ let g:DoxygenToolkit_licenseTag = s:licenseTag
+endif
+if !exists("g:DoxygenToolkit_fileTag")
+ let g:DoxygenToolkit_fileTag = "@file "
+endif
+if !exists("g:DoxygenToolkit_authorTag")
+ let g:DoxygenToolkit_authorTag = "@author "
+endif
+if !exists("g:DoxygenToolkit_dateTag")
+ let g:DoxygenToolkit_dateTag = "@date "
+endif
+if !exists("g:DoxygenToolkit_versionTag")
+ let g:DoxygenToolkit_versionTag = "@version "
+endif
+if !exists("g:DoxygenToolkit_undocTag")
+ let g:DoxygenToolkit_undocTag = "DOX_SKIP_BLOCK"
+endif
+if !exists("g:DoxygenToolkit_blockTag")
+ let g:DoxygenToolkit_blockTag = "@name "
+endif
+if !exists("g:DoxygenToolkit_classTag")
+ let g:DoxygenToolkit_classTag = "@class "
+endif
+
+if !exists("g:DoxygenToolkit_cinoptions")
+ let g:DoxygenToolkit_cinoptions = "c1C1"
+endif
+if !exists("g:DoxygenToolkit_startCommentTag ")
+ let g:DoxygenToolkit_startCommentTag = "/** "
+ let g:DoxygenToolkit_startCommentBlock = "/* "
+endif
+if !exists("g:DoxygenToolkit_interCommentTag ")
+ let g:DoxygenToolkit_interCommentTag = "* "
+endif
+if !exists("g:DoxygenToolkit_interCommentBlock ")
+ let g:DoxygenToolkit_interCommentBlock = "* "
+endif
+if !exists("g:DoxygenToolkit_endCommentTag ")
+ let g:DoxygenToolkit_endCommentTag = "*/"
+ let g:DoxygenToolkit_endCommentBlock = "*/"
+endif
+if exists("g:DoxygenToolkit_commentType")
+ if ( g:DoxygenToolkit_commentType == "C++" )
+ let g:DoxygenToolkit_startCommentTag = "/// "
+ let g:DoxygenToolkit_interCommentTag = "/// "
+ let g:DoxygenToolkit_endCommentTag = ""
+ let g:DoxygenToolkit_startCommentBlock = "// "
+ let g:DoxygenToolkit_interCommentBlock = "// "
+ let g:DoxygenToolkit_endCommentBlock = ""
+ else
+ let g:DoxygenToolkit_commentType = "C"
+ endif
+else
+ let g:DoxygenToolkit_commentType = "C"
+endif
+
+" Compact documentation
+" /**
+" * \brief foo ---> /** \brief foo */
+" */
+if !exists("g:DoxygenToolkit_compactOneLineDoc")
+ let g:DoxygenToolkit_compactOneLineDoc = "no"
+endif
+" /**
+" * \brief foo /**
+" * * \brief foo
+" * \param bar ---> * \param bar
+" * * \return
+" * \return */
+" */
+if !exists("g:DoxygenToolkit_compactDoc")
+ let g:DoxygenToolkit_compactDoc = "no"
+endif
+
+" Necessary '\<' and '\>' will be added to each item of the list.
+let s:ignoreForReturn = ['template', 'explicit', 'inline', 'static', 'virtual', 'void\([[:blank:]]*\*\)\@!', 'const', 'volatile', 'struct', 'extern']
+if !exists("g:DoxygenToolkit_ignoreForReturn")
+ let g:DoxygenToolkit_ignoreForReturn = s:ignoreForReturn[:]
+else
+ let g:DoxygenToolkit_ignoreForReturn += s:ignoreForReturn
+endif
+unlet s:ignoreForReturn
+
+" Maximum number of lines to check for function parameters
+if !exists("g:DoxygenToolkit_maxFunctionProtoLines")
+ let g:DoxygenToolkit_maxFunctionProtoLines = 10
+endif
+
+" Add name of function/class/struct... after pre brief tag if you want
+if !exists("g:DoxygenToolkit_briefTag_className")
+ let g:DoxygenToolkit_briefTag_className = "no"
+endif
+if !exists("g:DoxygenToolkit_briefTag_structName")
+ let g:DoxygenToolkit_briefTag_structName = "no"
+endif
+if !exists("g:DoxygenToolkit_briefTag_enumName")
+ let g:DoxygenToolkit_briefTag_enumName = "no"
+endif
+if !exists("g:DoxygenToolkit_briefTag_namespaceName")
+ let g:DoxygenToolkit_briefTag_namespaceName = "no"
+endif
+if !exists("g:DoxygenToolkit_briefTag_funcName")
+ let g:DoxygenToolkit_briefTag_funcName = "no"
+endif
+
+" Keep empty line (if any) between comment and function/class/...
+if !exists("g:DoxygenToolkit_keepEmptyLineAfterComment")
+ let g:DoxygenToolkit_keepEmptyLineAfterComment = "no"
+endif
+
+" PYTHON specific
+"""""""""""""""""
+" Remove automatically self parameter from function to avoid its documantation
+if !exists("g:DoxygenToolkit_python_autoRemoveSelfParam")
+ let g:DoxygenToolkit_python_autoRemoveSelfParam = "yes"
+endif
+" Consider functions as if they always return something (default: yes)
+if !exists("g:DoxygenToolkit_python_autoFunctionReturn")
+ let g:DoxygenToolkit_python_autoFunctionReturn = "yes"
+endif
+
+
+""""""""""""""""""""""""""
+" Doxygen license comment
+""""""""""""""""""""""""""
+function! <SID>DoxygenLicenseFunc()
+ call s:InitializeParameters()
+
+ " Test authorName variable
+ if !exists("g:DoxygenToolkit_authorName")
+ let g:DoxygenToolkit_authorName = input("Enter name of the author (generally yours...) : ")
+ endif
+ mark d
+ let l:date = strftime("%Y")
+ exec "normal O".strpart( s:startCommentBlock, 0, 1 )
+ exec "normal A".strpart( s:startCommentBlock, 1 ).substitute( g:DoxygenToolkit_licenseTag, "\<enter>", "\<enter>".s:interCommentBlock, "g" )
+ if( s:endCommentBlock != "" )
+ exec "normal o".s:endCommentBlock
+ endif
+ if( g:DoxygenToolkit_licenseTag == s:licenseTag )
+ exec "normal %jA".l:date." - ".g:DoxygenToolkit_authorName
+ endif
+ exec "normal `d"
+
+ call s:RestoreParameters()
+endfunction
+
+
+""""""""""""""""""""""""""
+" Doxygen author comment
+""""""""""""""""""""""""""
+function! <SID>DoxygenAuthorFunc()
+ call s:InitializeParameters()
+
+ " Test authorName variable
+ if !exists("g:DoxygenToolkit_authorName")
+ let g:DoxygenToolkit_authorName = input("Enter name of the author (generally yours...) : ")
+ endif
+
+ " Test versionString variable
+ if !exists("g:DoxygenToolkit_versionString")
+ let g:DoxygenToolkit_versionString = input("Enter version string : ")
+ endif
+
+ " Test versionString variable
+ if !exists("g:DoxygenToolkit_dateString")
+ let g:DoxygenToolkit_dateString = strftime("%Y-%m-%d")
+ endif
+
+ " Get file name
+ let l:fileName = expand('%:t')
+
+ " Begin to write skeleton
+ let l:insertionMode = s:StartDocumentationBlock()
+ exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_fileTag.l:fileName
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_briefTag_pre
+ mark d
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_authorTag.g:DoxygenToolkit_authorName
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_versionTag.g:DoxygenToolkit_versionString
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_dateTag.g:DoxygenToolkit_dateString
+ if exists("g:DoxygenToolkit_authorExtra") && exists("g:DoxygenToolkit_extraTag")
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_extraTag.g:DoxygenToolkit_authorExtra
+ endif
+ if ( g:DoxygenToolkit_endCommentTag != "" )
+ exec "normal o".s:endCommentTag
+ endif
+
+ " Move the cursor to the rigth position
+ exec "normal `d"
+
+ call s:RestoreParameters()
+ startinsert!
+endfunction
+
+
+""""""""""""""""""""""""""
+" Doxygen undocument function
+" C/C++ only!
+""""""""""""""""""""""""""
+function! <SID>DoxygenUndocumentFunc(blockTag)
+ call s:InitializeParameters()
+ let l:search = "#ifdef " . a:blockTag
+ " Save cursor position and go to the begining of the file
+ mark d
+ exec "normal gg"
+
+ while ( search(l:search, 'W') != 0 )
+ exec "normal O#ifndef " . g:DoxygenToolkit_undocTag
+ exec "normal j^%"
+ if ( g:DoxygenToolkit_endCommentTag == "" )
+ exec "normal o#endif // " . g:DoxygenToolkit_undocTag
+ else
+ exec "normal o#endif /* " . g:DoxygenToolkit_undocTag . " */"
+ endif
+ endwhile
+
+ exec "normal `d"
+ call s:RestoreParameters()
+endfunction
+
+
+
+""""""""""""""""""""""""""
+" DoxygenBlockFunc
+""""""""""""""""""""""""""
+function! <SID>DoxygenBlockFunc()
+ call s:InitializeParameters()
+
+ let l:insertionMode = s:StartDocumentationBlock()
+ exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_blockTag
+ mark d
+ exec "normal o".s:interCommentTag."@{ ".s:endCommentTag
+ exec "normal o".strpart( s:startCommentTag, 0, 1 )
+ exec "normal A".strpart( s:startCommentTag, 1 )." @} ".s:endCommentTag
+ exec "normal `d"
+
+ call s:RestoreParameters()
+ startinsert!
+endfunction
+
+
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Main comment function for class, attribute, function...
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! <SID>DoxygenCommentFunc()
+
+ " Initialize default templates.
+ " Assure compatibility with Python for classes (cf. endDocPattern).
+ let l:emptyLinePattern = '^[[:blank:]]*$'
+ let l:someNamePattern = '[_[:alpha:]][_[:alnum:]]*'
+
+ if( s:CheckFileType() == "cpp" )
+ let l:someNameWithNamespacePattern = l:someNamePattern.'\%(::'.l:someNamePattern.'\)*'
+ let l:endDocPattern = ';\|{\|\%([^:]\zs:\ze\%([^:]\|$\)\)'
+ let l:commentPattern = '\%(/*\)\|\%(//\)\'
+ let l:templateParameterPattern = "<[^<>]*>"
+ let l:throwPattern = '.*\<throw\>[[:blank:]]*(\([^()]*\)).*' "available only for 'cpp' type
+
+ let l:classPattern = '\<class\>[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze.*\%('.l:endDocPattern.'\)'
+ let l:structPattern = '\<struct\>[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze[^(),]*\%('.l:endDocPattern.'\)'
+ let l:enumPattern = '\<enum\>\%(\%([[:blank:]]\+\zs'.l:someNamePattern.'\ze[[:blank:]]*\)\|\%(\zs\ze[[:blank:]]*\)\)\%('.l:endDocPattern.'\)'
+ let l:namespacePattern = '\<namespace\>[[:blank:]]\+\zs'.l:someNamePattern.'\ze[[:blank:]]*\%('.l:endDocPattern.'\)'
+
+ let l:types = { "class": l:classPattern, "struct": l:structPattern, "enum": l:enumPattern, "namespace": l:namespacePattern }
+ else
+ let l:commentPattern = '#\|^[[:blank:]]*"""'
+
+ let l:classPattern = '\<class\>[[:blank:]]\+\zs'.l:someNamePattern.'\ze.*:'
+ let l:functionPattern = '\<def\>[[:blank:]]\+\zs'.l:someNamePattern.'\ze.*:'
+
+ let l:endDocPattern = '\%(\<class\>\|\<def\>[^:]*\)\@<!$'
+
+ let l:types = { "class": l:classPattern, "function": l:functionPattern }
+ endif
+
+ let l:lineBuffer = getline( line( "." ) )
+ let l:count = 1
+ let l:endDocFound = 0
+
+ let l:doc = { "type": "", "name": "None", "params": [], "returns": "" , "templates": [], "throws": [] }
+
+ " Mark current line for future use
+ mark d
+
+ " Look for function/method/... to document
+ " We look only on the first three lines!
+ while( match( l:lineBuffer, l:emptyLinePattern ) != -1 && l:count < 4 )
+ exec "normal j"
+ let l:lineBuffer = l:lineBuffer.' '.getline( line( "." ) )
+ let l:count = l:count + 1
+ endwhile
+ " Error message when the buffer is still empty.
+ if( match( l:lineBuffer, l:emptyLinePattern ) != -1 )
+ call s:WarnMsg( "Nothing to document here!" )
+ exec "normal `d"
+ return
+ endif
+
+ " Remove unwanted lines (ie: jump to the first significant line)
+ if( g:DoxygenToolkit_keepEmptyLineAfterComment == "no" )
+ " This erase previous mark
+ mark d
+ endif
+
+ " Look for the end of the function/class/... to document
+ " TODO does not work when function/class/... is commented out!
+ let l:readError = "Cannot reach end of function/class/... declaration!"
+ let l:count = 0
+ let l:throwCompleted = 0
+ let l:endReadPattern = l:endDocPattern
+ while( l:endDocFound == 0 && l:count < g:DoxygenToolkit_maxFunctionProtoLines )
+ let l:lineBuffer = s:RemoveComments( l:lineBuffer )
+ " Valid only for cpp. For Python it must be 'class ...:' or 'def ...:' or
+ " '... EOL'.
+ if( match( l:lineBuffer, l:endReadPattern ) != -1 )
+ " Look for throw statement at the end
+ if( s:CheckFileType() == "cpp" && l:throwCompleted == 0 )
+ " throw statement can have already been read or can be on next line
+ if( match( l:lineBuffer.' '.getline( line ( "." ) + 1 ), '.*\<throw\>.*' ) != -1 )
+ let l:endReadPattern = l:throwPattern
+ let l:throwCompleted = 1
+ let l:readError = "Cannot reach end of throw statement"
+ else
+ let l:endDocFound = 1
+ endif
+ else
+ let l:endDocFound = 1
+ endif
+ continue
+ endif
+ exec "normal j"
+ let l:lineBuffer = l:lineBuffer.' '.getline( line( "." ))
+ let l:count = l:count + 1
+ endwhile
+ " Error message when the end of the function(/...) has not been found
+ if( l:endDocFound == 0 )
+ if( match( l:lineBuffer, l:emptyLinePattern ) != -1 )
+ " Fall here when only comments have been found.
+ call s:WarnMsg( "Nothing to document here!" )
+ else
+ call s:WarnMsg( l:readError )
+ endif
+ exec "normal `d"
+ return
+ endif
+
+ " Trim the buffer
+ let l:lineBuffer = substitute( l:lineBuffer, "^[[:blank:]]*\|[[:blank:]]*$", "", "g" )
+
+ " Check whether it is a template definition
+ call s:ParseFunctionTemplateParameters( l:lineBuffer, l:doc )
+ " Remove any template parameter.
+ if( s:CheckFileType() == "cpp" )
+ while( match( l:lineBuffer, l:templateParameterPattern ) != -1 )
+ let l:lineBuffer = substitute( l:lineBuffer, l:templateParameterPattern, "", "g" )
+ endwhile
+ endif
+
+ " Look for the type
+ for key in keys( l:types )
+ "call s:WarnMsg( "[DEBUG] buffer:_".l:lineBuffer."_, test:_".l:types[key] )
+ let l:name = matchstr( l:lineBuffer, l:types[key] )
+ if( l:name != "" )
+ let l:doc.type = key
+ let l:doc.name = l:name
+
+ " Python only. Functions are detected differently for C/C++.
+ if( key == "function" )
+ "call s:WarnMsg( "HERE !!!".l:lineBuffer )
+ call s:ParseFunctionParameters( l:lineBuffer, l:doc )
+ endif
+ break
+ endif
+ endfor
+
+ if( l:doc.type == "" )
+ " Should be a function/method (cpp only) or an attribute.
+ " (cpp only) Can also be an unnamed enum/namespace... (or something else ?)
+ if( s:CheckFileType() == "cpp" )
+ if( match( l:lineBuffer, '(' ) == -1 )
+ if( match( l:lineBuffer, '\<enum\>' ) != -1 )
+ let l:doc.type = 'enum'
+ elseif( match( l:lineBuffer, '\<namespace\>' ) != -1 )
+ let l:doc.type = 'namespace'
+ else
+ " TODO here we get a class attribute of something like that.
+ " We probably just need a \brief statement...
+ let l:doc.type = 'attribute'
+ " TODO Retrieve the name of the attribute.
+ " Do we really need it? I'm not sure for the moment.
+ endif
+ else
+ let l:doc.type = 'function'
+ call s:ParseFunctionParameters( l:lineBuffer, l:doc )
+ if( l:throwCompleted == 1 )
+ call s:ParseThrowParameters( l:lineBuffer, l:doc, l:throwPattern )
+ endif
+ endif
+
+ " This is an attribute for Python
+ else
+ let l:doc.type = 'attribute'
+ endif
+ endif
+
+ " Remove the function/class/... name when it is not necessary
+ if( ( l:doc.type == "class" && g:DoxygenToolkit_briefTag_className != "yes" ) || ( l:doc.type == "struct" && g:DoxygenToolkit_briefTag_structName != "yes" ) || ( l:doc.type == "enum" && g:DoxygenToolkit_briefTag_enumName != "yes" ) || ( l:doc.type == "namespace" && g:DoxygenToolkit_briefTag_namespaceName != "yes" ) || ( l:doc.type == "function" && g:DoxygenToolkit_briefTag_funcName != "yes" ) )
+ let l:doc.name = "None"
+
+ " Remove namespace from the name of the class/function...
+ elseif( s:CheckFileType() == "cpp" )
+ let l:doc.name = substitute( l:doc.name, '\%('.l:someNamePattern.'::\)', '', 'g' )
+ endif
+
+ " Below, write what we have found
+ """""""""""""""""""""""""""""""""
+
+ call s:InitializeParameters()
+ if( s:CheckFileType() == "python" && l:doc.type == "function" && g:DoxygenToolkit_python_autoFunctionReturn == "yes" )
+ let l:doc.returns = "yes"
+ endif
+
+ " Header
+ exec "normal `d"
+ if( g:DoxygenToolkit_blockHeader != "" )
+ exec "normal O".strpart( s:startCommentBlock, 0, 1 )
+ exec "normal A".strpart( s:startCommentBlock, 1 ).g:DoxygenToolkit_blockHeader.s:endCommentBlock
+ exec "normal `d"
+ endif
+
+ " Brief
+ if( g:DoxygenToolkit_compactOneLineDoc =~ "yes" && l:doc.returns != "yes" && len( l:doc.params ) == 0 )
+ let s:compactOneLineDoc = "yes"
+ exec "normal O".strpart( s:startCommentTag, 0, 1 )
+ exec "normal A".strpart( s:startCommentTag, 1 ).g:DoxygenToolkit_briefTag_pre
+ else
+ let s:compactOneLineDoc = "no"
+ let l:insertionMode = s:StartDocumentationBlock()
+ exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_briefTag_pre
+ endif
+ if( l:doc.name != "None" )
+ exec "normal A".l:doc.name." "
+ endif
+ exec "normal A".g:DoxygenToolkit_briefTag_post
+
+ " Mark the line where the cursor will be positionned.
+ mark d
+
+ " Arguments/parameters
+ if( g:DoxygenToolkit_compactDoc =~ "yes" )
+ let s:insertEmptyLine = 0
+ else
+ let s:insertEmptyLine = 1
+ endif
+ for param in l:doc.templates
+ if( s:insertEmptyLine == 1 )
+ exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )
+ let s:insertEmptyLine = 0
+ endif
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_templateParamTag_pre.param.g:DoxygenToolkit_templateParamTag_post
+ endfor
+ for param in l:doc.params
+ if( s:insertEmptyLine == 1 )
+ exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )
+ let s:insertEmptyLine = 0
+ endif
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_paramTag_pre.param.g:DoxygenToolkit_paramTag_post
+ endfor
+
+ " Returned value
+ if( l:doc.returns == "yes" )
+ if( g:DoxygenToolkit_compactDoc != "yes" )
+ exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )
+ endif
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_returnTag
+ endif
+
+ " Exception (throw) values (cpp only)
+ if( len( l:doc.throws ) > 0 )
+ if( g:DoxygenToolkit_compactDoc =~ "yes" )
+ let s:insertEmptyLine = 0
+ else
+ let s:insertEmptyLine = 1
+ endif
+ for param in l:doc.throws
+ if( s:insertEmptyLine == 1 )
+ exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" )
+ let s:insertEmptyLine = 0
+ endif
+ exec "normal o".s:interCommentTag.g:DoxygenToolkit_throwTag_pre.param.g:DoxygenToolkit_throwTag_post
+ endfor
+ endif
+
+ " End (if any) of documentation block.
+ if( s:endCommentTag != "" )
+ if( s:compactOneLineDoc =~ "yes" )
+ let s:execCommand = "A"
+ exec "normal A "
+ exec "normal $md"
+ else
+ let s:execCommand = "o"
+ endif
+ exec "normal ".s:execCommand.s:endCommentTag
+ endif
+
+ " Footer
+ if ( g:DoxygenToolkit_blockFooter != "" )
+ exec "normal o".strpart( s:startCommentBlock, 0, 1 )
+ exec "normal A".strpart( s:startCommentBlock, 1 ).g:DoxygenToolkit_blockFooter.s:endCommentBlock
+ endif
+ exec "normal `d"
+
+ call s:RestoreParameters()
+ if( s:compactOneLineDoc =~ "yes" && s:endCommentTag != "" )
+ startinsert
+ else
+ startinsert!
+ endif
+
+ " DEBUG purpose only
+ "call s:WarnMsg( "Found a ".l:doc.type." named ".l:doc.name." (env: ".s:CheckFileType().")." )
+ "if( l:doc.type == "function" )
+ " let l:funcReturn = "returns something."
+ " if( l:doc.returns == "" )
+ " let l:funcReturn = "doesn't return anything."
+ " endif
+ " call s:WarnMsg( " - which ".l:funcReturn )
+ " call s:WarnMsg( " - which has following parameter(s):" )
+ " for param in l:doc.params
+ " call s:WarnMsg( " - ".param )
+ " endfor
+ "endif
+
+endfunction
+
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Write the beginning of the documentation block:
+" - C and Python format: insert '/**' and '##' respectively then a linefeed,
+" - C++ insert '///' and continue on the same line
+"
+" This function return the insertion mode which should be used for the next
+" call to 'normal'.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:StartDocumentationBlock()
+ " For C++ documentation format we do not need first empty line
+ if( s:startCommentTag != s:interCommentTag )
+ "exec "normal O".s:startCommentTag
+ exec "normal O".strpart( s:startCommentTag, 0, 1 )
+ exec "normal A".substitute( strpart( s:startCommentTag, 1 ), "[[:blank:]]*$", "", "" )
+ let l:insertionMode = "o"
+ else
+ let l:insertionMode = "O"
+ endif
+ return l:insertionMode
+endfunction
+
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Remove comments from the given buffer.
+" - Remove everything after '//' or '#'.
+" - Remove everything between '/*' and '*/' or keep '/*' if '*/' is not present.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:RemoveComments( lineBuffer )
+ if( s:CheckFileType() == "cpp" )
+ " Remove C++ (//) comment.
+ let l:lineBuffer = substitute( a:lineBuffer, '[[:blank:]]*\/\/.*$', '', '')
+ " Remove partial C (/* ...) comment: /* foo bar --> /*
+ " '/*' is preserved until corresponding '*/' is found. Other part of the
+ " comment is discarded to prevent the case where it contains characters
+ " corresponding to the endDoc string.
+ let l:lineBuffer = substitute( l:lineBuffer, '\%(\/\*\zs.*\ze\)\&\%(\%(\/\*.*\*\/\)\@!\)', '', '')
+ " Remove C (/* ... */) comment.
+ let l:lineBuffer = substitute( l:lineBuffer, '\/\*.\{-}\*\/', '', 'g')
+ else
+ let l:lineBuffer = substitute( a:lineBuffer, '[[:blank:]]*#.*$', '', '')
+ endif
+ return l:lineBuffer
+endfunction
+
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Retrieve file type.
+" - Default type is still 'cpp'.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:CheckFileType()
+ if( &filetype == "python" )
+ let l:fileType = "python"
+ else
+ let l:fileType = "cpp"
+ endif
+ return l:fileType
+endfunction
+
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Parse the buffer and set the doc parameter.
+" - Functions which return pointer to function are not supported.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:ParseFunctionParameters( lineBuffer, doc )
+ "call s:WarnMsg( 'IN__'.a:lineBuffer )
+ let l:paramPosition = matchend( a:lineBuffer, 'operator[[:blank:]]*([[:blank:]]*)' )
+ if ( l:paramPosition == -1 )
+ let l:paramPosition = stridx( a:lineBuffer, '(' )
+ else
+ let l:paramPosition = stridx( a:lineBuffer, '(', l:paramPosition )
+ endif
+
+
+ " (cpp only) First deal with function name and returned value.
+ " Function name has already been retrieved for Python and we need to parse
+ " all the function definition to know whether a value is returned or not.
+ if( s:CheckFileType() == "cpp" )
+ let l:functionBuffer = strpart( a:lineBuffer, 0, l:paramPosition )
+ " Remove unnecessary elements
+ for ignored in g:DoxygenToolkit_ignoreForReturn
+ let l:functionBuffer = substitute( l:functionBuffer, '\<'.ignored.'\>', '', 'g' )
+ endfor
+ let l:functionReturnAndName = split( l:functionBuffer, '[[:blank:]*]' )
+ if( len( l:functionReturnAndName ) > 1 )
+ let a:doc.returns = 'yes'
+ endif
+ let a:doc.name = l:functionReturnAndName[-1]
+ endif
+
+ " Work on parameters.
+ let l:parametersBuffer = strpart( a:lineBuffer, l:paramPosition + 1 )
+ " Remove trailing closing bracket and everything that follows and trim.
+ if( s:CheckFileType() == "cpp" )
+ let l:parametersBuffer = substitute( l:parametersBuffer, ')[^)]*\%(;\|{\|\%([^:]:\%([^:]\|$\)\)\|\%(\<throw\>\)\).*', '', '' )
+ else
+ let l:parametersBuffer = substitute( l:parametersBuffer, ')[^)]*:.*', '', '' )
+ endif
+ let l:parametersBuffer = substitute( l:parametersBuffer, '^[[:blank:]]*\|[[:blank:]]*$', '', '' )
+
+ " Remove default parameter values (if any).
+ let l:index = stridx( l:parametersBuffer, '=' )
+ let l:startIndex = l:index
+ while( l:index != -1 )
+ " Look for the next colon...
+ let l:colonIndex = stridx( l:parametersBuffer, ',', l:startIndex )
+ if( l:colonIndex == -1 )
+ let l:colonIndex = strlen( l:parametersBuffer )
+ endif
+ let l:paramBuffer = strpart( l:parametersBuffer, l:index, l:colonIndex - l:index )
+ if( s:CountBrackets( l:paramBuffer ) == 0 )
+ " Everything in [l:index, l:colonIndex[ can be removed.
+ let l:parametersBuffer = substitute( l:parametersBuffer, l:paramBuffer, '', '' )
+ let l:index = stridx( l:parametersBuffer, '=' )
+ let l:startIndex = l:index
+ else
+ " Parameter initialization contains brakets and colons...
+ let l:startIndex = l:colonIndex + 1
+ endif
+ endwhile
+
+ "call s:WarnMsg( "[DEBUG]: ".l:parametersBuffer )
+ " Now, work on each parameter.
+ let l:params = []
+ let l:index = stridx( l:parametersBuffer, ',' )
+ while( l:index != -1 )
+ let l:paramBuffer = strpart( l:parametersBuffer, 0, l:index )
+ if( s:CountBrackets( l:paramBuffer ) == 0 )
+ let l:params = add( l:params, s:ParseParameter( l:paramBuffer ) )
+ let l:parametersBuffer = strpart( l:parametersBuffer, l:index + 1 )
+ let l:index = stridx( l:parametersBuffer, ',' )
+ else
+ let l:index = stridx( l:parametersBuffer, ',', l:index + 1 )
+ endif
+ endwhile
+ if( strlen( l:parametersBuffer ) != 0 )
+ let l:params = add( l:params, s:ParseParameter( l:parametersBuffer ) )
+ endif
+
+ if( s:CheckFileType() == "cpp" )
+ call filter( l:params, 'v:val !~ "void"' )
+ else
+ if( g:DoxygenToolkit_python_autoRemoveSelfParam == "yes" )
+ call filter( l:params, 'v:val !~ "self"' )
+ endif
+ endif
+
+ for param in l:params
+ call add( a:doc.params, param )
+ "call s:WarnMsg( '[DEBUG]:OUT_'.param )
+ endfor
+endfunction
+
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Parse given parameter and return its name.
+" It is easy to do unless you use function's pointers...
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:ParseParameter( param )
+ let l:paramName = "Unknown"
+ let l:firstIndex = stridx( a:param, '(' )
+
+ if( l:firstIndex == -1 )
+ let l:paramName = split( a:param, '[[:blank:]*&]' )[-1]
+ else
+ if( l:firstIndex != 0 )
+ let l:startIndex = 0
+ else
+ let l:startIndex = stridx( a:param, ')' )
+ if( l:startIndex == -1 ) " Argggg...
+ let l:paramName = a:param
+ else
+ let l:startIndex += 1
+ while( s:CountBrackets( strpart( a:param, 0, l:startIndex ) ) != 0 )
+ let l:startIndex = stridx( a:param, ')', l:startIndex + 1 ) + 1
+ if( l:startIndex == -1) " Argggg...
+ let l:paramName = a:param
+ endif
+ endwhile
+ endif
+ endif
+
+ if( l:startIndex != -1 )
+ let l:startIndex = stridx( a:param, '(', l:startIndex ) + 1
+ let l:endIndex = stridx( a:param, ')', l:startIndex + 1 )
+ let l:param = strpart( a:param, l:startIndex, l:endIndex - l:startIndex )
+ let l:paramName = substitute( l:param, '^[[:blank:]*]*\|[[:blank:]*]*$', '', '' )
+ else
+ " Something really wrong has happened.
+ let l:paramName = a:param
+ endif
+ endif
+
+ return l:paramName
+endfunction
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Extract template parameter name for function/class/method
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:ParseFunctionTemplateParameters( lineBuffer, doc )
+ if( match( a:lineBuffer, '^[[:blank:]]*template' ) == 0 )
+ let l:firstIndex = stridx( a:lineBuffer, '<' )
+ if( l:firstIndex != -1 )
+ let l:lastIndex = stridx( a:lineBuffer, '>', l:firstIndex + 1 )
+ if( l:lastIndex != -1 )
+ " Keep only template parameters
+ let l:parameters = strpart( a:lineBuffer, l:firstIndex + 1, l:lastIndex - l:firstIndex - 1)
+ " Split on separator (,)
+ let l:params = split( l:parameters, '\,' )
+ for param in l:params
+ " Extract template parameter name
+ let l:paramName = split( split( param, '=' )[0], '[[:blank:]]' )[-1]
+ call add( a:doc.templates, l:paramName )
+ endfor
+ endif
+ endif
+ endif
+endfunction
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Extract throw parameter name
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:ParseThrowParameters( lineBuffer, doc, throwPattern )
+ let l:throwParams = substitute( a:lineBuffer, a:throwPattern, '\1', "" )
+ for param in split( l:throwParams, "," )
+ call add( a:doc.throws, substitute( param, '[[:blank:]]', '', "" ) )
+ endfor
+endfunction
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Define start/end documentation format and backup generic parameters.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:InitializeParameters()
+ if( s:CheckFileType() == "cpp" )
+ let s:startCommentTag = g:DoxygenToolkit_startCommentTag
+ let s:interCommentTag = g:DoxygenToolkit_interCommentTag
+ let s:endCommentTag = g:DoxygenToolkit_endCommentTag
+ let s:startCommentBlock = g:DoxygenToolkit_startCommentBlock
+ let s:interCommentBlock = g:DoxygenToolkit_interCommentBlock
+ let s:endCommentBlock = g:DoxygenToolkit_endCommentBlock
+ else
+ let s:startCommentTag = "## "
+ let s:interCommentTag = "# "
+ let s:endCommentTag = ""
+ let s:startCommentBlock = "# "
+ let s:interCommentBlock = "# "
+ let s:endCommentBlock = ""
+ endif
+
+ " Backup standard comment expension and indentation
+ let s:commentsBackup = &comments
+ let &comments = ""
+ let s:cinoptionsBackup = &cinoptions
+ let &cinoptions = g:DoxygenToolkit_cinoptions
+ " Compatibility with c/c++ IDE plugin
+ let s:timeoutlenBackup = &timeoutlen
+ let &timeoutlen = 0
+endfunction
+
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Restore previously backuped parameters.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:RestoreParameters()
+ " Restore standard comment expension and indentation
+ let &comments = s:commentsBackup
+ let &cinoptions = s:cinoptionsBackup
+ " Compatibility with c/c++ IDE plugin
+ let &timeoutlen = s:timeoutlenBackup
+endfunction
+
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Count opened/closed brackets in the given buffer.
+" Each opened bracket increase the counter by 1.
+" Each closed bracket decrease the counter by 1.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+function! s:CountBrackets( buffer )
+ let l:count = len( split( a:buffer, '(', 1 ) )
+ let l:count -= len( split( a:buffer, ')', 1 ) )
+ return l:count
+endfunction
+
+
+"""""""""""""""""""""""""""""""""""
+" Simple warning message function
+"""""""""""""""""""""""""""""""""""
+function! s:WarnMsg( msg )
+ echohl WarningMsg
+ echo a:msg
+ echohl None
+ return
+endfunction
+
+""""""""""""""""""""""""""
+" Shortcuts...
+""""""""""""""""""""""""""
+command! -nargs=0 Dox :call <SID>DoxygenCommentFunc()
+command! -nargs=0 DoxLic :call <SID>DoxygenLicenseFunc()
+command! -nargs=0 DoxAuthor :call <SID>DoxygenAuthorFunc()
+command! -nargs=1 DoxUndoc :call <SID>DoxygenUndocumentFunc(<q-args>)
+command! -nargs=0 DoxBlock :call <SID>DoxygenBlockFunc()
+
--- /dev/null
+" Vim syntax file
+" Language: C
+" Maintainer: Bram Moolenaar <Bram@vim.org>
+" Last Change: 2009 Nov 17
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+ finish
+endif
+
+" A bunch of useful C keywords
+syn keyword cStatement goto break return continue asm
+syn keyword cLabel case default
+syn keyword cConditional if else switch
+syn keyword cRepeat while for do
+
+syn keyword cTodo contained TODO FIXME XXX
+
+" It's easy to accidentally add a space after a backslash that was intended
+" for line continuation. Some compilers allow it, which makes it
+" unpredicatable and should be avoided.
+syn match cBadContinuation contained "\\\s\+$"
+
+" cCommentGroup allows adding matches for special things in comments
+syn cluster cCommentGroup contains=cTodo,cBadContinuation
+
+" String and Character constants
+" Highlight special characters (those which have a backslash) differently
+syn match cSpecial display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)"
+if !exists("c_no_utf")
+ syn match cSpecial display contained "\\\(u\x\{4}\|U\x\{8}\)"
+endif
+if exists("c_no_cformat")
+ syn region cString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,@Spell
+ " cCppString: same as cString, but ends at end of line
+ syn region cCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,@Spell
+else
+ if !exists("c_no_c99") " ISO C99
+ syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
+ else
+ syn match cFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([bdiuoxXDOUfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
+ endif
+ syn match cFormat display "%%" contained
+ syn region cString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,cFormat,@Spell
+ " cCppString: same as cString, but ends at end of line
+ syn region cCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,cFormat,@Spell
+endif
+
+syn match cCharacter "L\='[^\\]'"
+syn match cCharacter "L'[^']*'" contains=cSpecial
+if exists("c_gnu")
+ syn match cSpecialError "L\='\\[^'\"?\\abefnrtv]'"
+ syn match cSpecialCharacter "L\='\\['\"?\\abefnrtv]'"
+else
+ syn match cSpecialError "L\='\\[^'\"?\\abfnrtv]'"
+ syn match cSpecialCharacter "L\='\\['\"?\\abfnrtv]'"
+endif
+syn match cSpecialCharacter display "L\='\\\o\{1,3}'"
+syn match cSpecialCharacter display "'\\x\x\{1,2}'"
+syn match cSpecialCharacter display "L'\\x\x\+'"
+
+"when wanted, highlight trailing white space
+if exists("c_space_errors")
+ if !exists("c_no_trail_space_error")
+ syn match cSpaceError display excludenl "\s\+$"
+ endif
+ if !exists("c_no_tab_space_error")
+ syn match cSpaceError display " \+\t"me=e-1
+ endif
+endif
+
+" This should be before cErrInParen to avoid problems with #define ({ xxx })
+if exists("c_curly_error")
+ syntax match cCurlyError "}"
+ syntax region cBlock start="{" end="}" contains=ALLBUT,cCurlyError,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBracket,cCppString,@Spell fold
+else
+ syntax region cBlock start="{" end="}" transparent fold
+endif
+
+"catch errors caused by wrong parenthesis and brackets
+" also accept <% for {, %> for }, <: for [ and :> for ] (C99)
+" But avoid matching <::.
+syn cluster cParenGroup contains=cParenError,cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cBitField,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom
+if exists("c_no_curly_error")
+ syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell
+ " cCppParen: same as cParen but ends at end-of-line; used in cDefine
+ syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
+ syn match cParenError display ")"
+ syn match cErrInParen display contained "^[{}]\|^<%\|^%>"
+elseif exists("c_no_bracket_error")
+ syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cCppString,@Spell
+ " cCppParen: same as cParen but ends at end-of-line; used in cDefine
+ syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
+ syn match cParenError display ")"
+ syn match cErrInParen display contained "[{}]\|<%\|%>"
+else
+ syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cErrInBracket,cCppBracket,cCppString,@Spell
+ " cCppParen: same as cParen but ends at end-of-line; used in cDefine
+ syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cErrInBracket,cParen,cBracket,cString,@Spell
+ syn match cParenError display "[\])]"
+ syn match cErrInParen display contained "[\]{}]\|<%\|%>"
+ syn region cBracket transparent start='\[\|<::\@!' end=']\|:>' contains=ALLBUT,@cParenGroup,cErrInParen,cCppParen,cCppBracket,cCppString,@Spell
+ " cCppBracket: same as cParen but ends at end-of-line; used in cDefine
+ syn region cCppBracket transparent start='\[\|<::\@!' skip='\\$' excludenl end=']\|:>' end='$' contained contains=ALLBUT,@cParenGroup,cErrInParen,cParen,cBracket,cString,@Spell
+ syn match cErrInBracket display contained "[);{}]\|<%\|%>"
+endif
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match cNumbers display transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctalError,cOctal
+" Same, but without octal error (for comments)
+syn match cNumbersCom display contained transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctal
+syn match cNumber display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
+"hex number
+syn match cNumber display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
+" Flag the first zero of an octal number as something special
+syn match cOctal display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=cOctalZero
+syn match cOctalZero display contained "\<0"
+syn match cFloat display contained "\d\+f"
+"floating point number, with dot, optional exponent
+syn match cFloat display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
+"floating point number, starting with a dot, optional exponent
+syn match cFloat display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+"floating point number, without dot, with exponent
+syn match cFloat display contained "\d\+e[-+]\=\d\+[fl]\=\>"
+if !exists("c_no_c99")
+ "hexadecimal floating point number, optional leading digits, with dot, with exponent
+ syn match cFloat display contained "0x\x*\.\x\+p[-+]\=\d\+[fl]\=\>"
+ "hexadecimal floating point number, with leading digits, optional dot, with exponent
+ syn match cFloat display contained "0x\x\+\.\=p[-+]\=\d\+[fl]\=\>"
+endif
+
+" flag an octal number with wrong digits
+syn match cOctalError display contained "0\o*[89]\d*"
+syn case match
+
+if exists("c_comment_strings")
+ " A comment can contain cString, cCharacter and cNumber.
+ " But a "*/" inside a cString in a cComment DOES end the comment! So we
+ " need to use a special type of cString: cCommentString, which also ends on
+ " "*/", and sees a "*" at the start of the line as comment again.
+ " Unfortunately this doesn't very well work for // type of comments :-(
+ syntax match cCommentSkip contained "^\s*\*\($\|\s\+\)"
+ syntax region cCommentString contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=cSpecial,cCommentSkip
+ syntax region cComment2String contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=cSpecial
+ syntax region cCommentL start="//" skip="\\$" end="$" keepend contains=@cCommentGroup,cComment2String,cCharacter,cNumbersCom,cSpaceError,@Spell
+ if exists("c_no_comment_fold")
+ " Use "extend" here to have preprocessor lines not terminate halfway a
+ " comment.
+ syntax region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cCommentString,cCharacter,cNumbersCom,cSpaceError,@Spell extend
+ else
+ syntax region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cCommentString,cCharacter,cNumbersCom,cSpaceError,@Spell fold extend
+ endif
+else
+ syn region cCommentL start="//" skip="\\$" end="$" keepend contains=@cCommentGroup,cSpaceError,@Spell
+ if exists("c_no_comment_fold")
+ syn region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cSpaceError,@Spell extend
+ else
+ syn region cComment matchgroup=cCommentStart start="/\*" end="\*/" contains=@cCommentGroup,cCommentStartError,cSpaceError,@Spell fold extend
+ endif
+endif
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match cCommentError display "\*/"
+syntax match cCommentStartError display "/\*"me=e-1 contained
+
+syn keyword cOperator sizeof
+if exists("c_gnu")
+ syn keyword cStatement __asm__
+ syn keyword cOperator typeof __real__ __imag__
+endif
+syn keyword cType int long short char void
+syn keyword cType signed unsigned float double
+if !exists("c_no_ansi") || exists("c_ansi_typedefs")
+ syn keyword cType size_t ssize_t off_t wchar_t ptrdiff_t sig_atomic_t fpos_t
+ syn keyword cType clock_t time_t va_list jmp_buf FILE DIR div_t ldiv_t
+ syn keyword cType mbstate_t wctrans_t wint_t wctype_t
+endif
+if !exists("c_no_c99") " ISO C99
+ syn keyword cType bool complex
+ syn keyword cType int8_t int16_t int32_t int64_t
+ syn keyword cType uint8_t uint16_t uint32_t uint64_t
+ syn keyword cType int_least8_t int_least16_t int_least32_t int_least64_t
+ syn keyword cType uint_least8_t uint_least16_t uint_least32_t uint_least64_t
+ syn keyword cType int_fast8_t int_fast16_t int_fast32_t int_fast64_t
+ syn keyword cType uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t
+ syn keyword cType intptr_t uintptr_t
+ syn keyword cType intmax_t uintmax_t
+endif
+if exists("c_gnu")
+ syn keyword cType __label__ __complex__ __volatile__
+endif
+
+syn keyword cStructure struct union enum typedef
+syn keyword cStorageClass static register auto volatile extern const
+if exists("c_gnu")
+ syn keyword cStorageClass inline __attribute__
+endif
+if !exists("c_no_c99")
+ syn keyword cStorageClass inline restrict
+endif
+
+if !exists("c_no_ansi") || exists("c_ansi_constants") || exists("c_gnu")
+ if exists("c_gnu")
+ syn keyword cConstant __GNUC__ __FUNCTION__ __PRETTY_FUNCTION__ __func__
+ endif
+ syn keyword cConstant __LINE__ __FILE__ __DATE__ __TIME__ __STDC__
+ syn keyword cConstant __STDC_VERSION__
+ syn keyword cConstant CHAR_BIT MB_LEN_MAX MB_CUR_MAX
+ syn keyword cConstant UCHAR_MAX UINT_MAX ULONG_MAX USHRT_MAX
+ syn keyword cConstant CHAR_MIN INT_MIN LONG_MIN SHRT_MIN
+ syn keyword cConstant CHAR_MAX INT_MAX LONG_MAX SHRT_MAX
+ syn keyword cConstant SCHAR_MIN SINT_MIN SLONG_MIN SSHRT_MIN
+ syn keyword cConstant SCHAR_MAX SINT_MAX SLONG_MAX SSHRT_MAX
+ if !exists("c_no_c99")
+ syn keyword cConstant __func__
+ syn keyword cConstant LLONG_MIN LLONG_MAX ULLONG_MAX
+ syn keyword cConstant INT8_MIN INT16_MIN INT32_MIN INT64_MIN
+ syn keyword cConstant INT8_MAX INT16_MAX INT32_MAX INT64_MAX
+ syn keyword cConstant UINT8_MAX UINT16_MAX UINT32_MAX UINT64_MAX
+ syn keyword cConstant INT_LEAST8_MIN INT_LEAST16_MIN INT_LEAST32_MIN INT_LEAST64_MIN
+ syn keyword cConstant INT_LEAST8_MAX INT_LEAST16_MAX INT_LEAST32_MAX INT_LEAST64_MAX
+ syn keyword cConstant UINT_LEAST8_MAX UINT_LEAST16_MAX UINT_LEAST32_MAX UINT_LEAST64_MAX
+ syn keyword cConstant INT_FAST8_MIN INT_FAST16_MIN INT_FAST32_MIN INT_FAST64_MIN
+ syn keyword cConstant INT_FAST8_MAX INT_FAST16_MAX INT_FAST32_MAX INT_FAST64_MAX
+ syn keyword cConstant UINT_FAST8_MAX UINT_FAST16_MAX UINT_FAST32_MAX UINT_FAST64_MAX
+ syn keyword cConstant INTPTR_MIN INTPTR_MAX UINTPTR_MAX
+ syn keyword cConstant INTMAX_MIN INTMAX_MAX UINTMAX_MAX
+ syn keyword cConstant PTRDIFF_MIN PTRDIFF_MAX SIG_ATOMIC_MIN SIG_ATOMIC_MAX
+ syn keyword cConstant SIZE_MAX WCHAR_MIN WCHAR_MAX WINT_MIN WINT_MAX
+ endif
+ syn keyword cConstant FLT_RADIX FLT_ROUNDS
+ syn keyword cConstant FLT_DIG FLT_MANT_DIG FLT_EPSILON
+ syn keyword cConstant DBL_DIG DBL_MANT_DIG DBL_EPSILON
+ syn keyword cConstant LDBL_DIG LDBL_MANT_DIG LDBL_EPSILON
+ syn keyword cConstant FLT_MIN FLT_MAX FLT_MIN_EXP FLT_MAX_EXP
+ syn keyword cConstant FLT_MIN_10_EXP FLT_MAX_10_EXP
+ syn keyword cConstant DBL_MIN DBL_MAX DBL_MIN_EXP DBL_MAX_EXP
+ syn keyword cConstant DBL_MIN_10_EXP DBL_MAX_10_EXP
+ syn keyword cConstant LDBL_MIN LDBL_MAX LDBL_MIN_EXP LDBL_MAX_EXP
+ syn keyword cConstant LDBL_MIN_10_EXP LDBL_MAX_10_EXP
+ syn keyword cConstant HUGE_VAL CLOCKS_PER_SEC NULL
+ syn keyword cConstant LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY
+ syn keyword cConstant LC_NUMERIC LC_TIME
+ syn keyword cConstant SIG_DFL SIG_ERR SIG_IGN
+ syn keyword cConstant SIGABRT SIGFPE SIGILL SIGHUP SIGINT SIGSEGV SIGTERM
+ " Add POSIX signals as well...
+ syn keyword cConstant SIGABRT SIGALRM SIGCHLD SIGCONT SIGFPE SIGHUP
+ syn keyword cConstant SIGILL SIGINT SIGKILL SIGPIPE SIGQUIT SIGSEGV
+ syn keyword cConstant SIGSTOP SIGTERM SIGTRAP SIGTSTP SIGTTIN SIGTTOU
+ syn keyword cConstant SIGUSR1 SIGUSR2
+ syn keyword cConstant _IOFBF _IOLBF _IONBF BUFSIZ EOF WEOF
+ syn keyword cConstant FOPEN_MAX FILENAME_MAX L_tmpnam
+ syn keyword cConstant SEEK_CUR SEEK_END SEEK_SET
+ syn keyword cConstant TMP_MAX stderr stdin stdout
+ syn keyword cConstant EXIT_FAILURE EXIT_SUCCESS RAND_MAX
+ " Add POSIX errors as well
+ syn keyword cConstant E2BIG EACCES EAGAIN EBADF EBADMSG EBUSY
+ syn keyword cConstant ECANCELED ECHILD EDEADLK EDOM EEXIST EFAULT
+ syn keyword cConstant EFBIG EILSEQ EINPROGRESS EINTR EINVAL EIO EISDIR
+ syn keyword cConstant EMFILE EMLINK EMSGSIZE ENAMETOOLONG ENFILE ENODEV
+ syn keyword cConstant ENOENT ENOEXEC ENOLCK ENOMEM ENOSPC ENOSYS
+ syn keyword cConstant ENOTDIR ENOTEMPTY ENOTSUP ENOTTY ENXIO EPERM
+ syn keyword cConstant EPIPE ERANGE EROFS ESPIPE ESRCH ETIMEDOUT EXDEV
+ " math.h
+ syn keyword cConstant M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI M_PI_2 M_PI_4
+ syn keyword cConstant M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2
+endif
+if !exists("c_no_c99") " ISO C99
+ syn keyword cConstant true false
+endif
+
+" Accept %: for # (C99)
+syn region cPreCondit start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError
+syn match cPreCondit display "^\s*\(%:\|#\)\s*\(else\|endif\)\>"
+if !exists("c_no_if0")
+ if !exists("c_no_if0_fold")
+ syn region cCppOut start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2 fold
+ else
+ syn region cCppOut start="^\s*\(%:\|#\)\s*if\s\+0\+\>" end=".\@=\|$" contains=cCppOut2
+ endif
+ syn region cCppOut2 contained start="0" end="^\s*\(%:\|#\)\s*\(endif\>\|else\>\|elif\>\)" contains=cSpaceError,cCppSkip
+ syn region cCppSkip contained start="^\s*\(%:\|#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(%:\|#\)\s*endif\>" contains=cSpaceError,cCppSkip
+endif
+syn region cIncluded display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn match cIncluded display contained "<[^>]*>"
+syn match cInclude display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded
+"syn match cLineSkip "\\$"
+syn cluster cPreProcGroup contains=cPreCondit,cIncluded,cInclude,cDefine,cErrInParen,cErrInBracket,cUserLabel,cSpecial,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cString,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cParen,cBracket,cMulti
+syn region cDefine start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
+syn region cPreProc start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
+
+" Highlight User Labels
+syn cluster cMultiGroup contains=cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cBitField,cOctalZero,cCppOut,cCppOut2,cCppSkip,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cCppParen,cCppBracket,cCppString
+syn region cMulti transparent start='?' skip='::' end=':' contains=ALLBUT,@cMultiGroup,@Spell
+" Avoid matching foo::bar() in C++ by requiring that the next char is not ':'
+syn cluster cLabelGroup contains=cUserLabel
+syn match cUserCont display "^\s*\I\i*\s*:$" contains=@cLabelGroup
+syn match cUserCont display ";\s*\I\i*\s*:$" contains=@cLabelGroup
+syn match cUserCont display "^\s*\I\i*\s*:[^:]"me=e-1 contains=@cLabelGroup
+syn match cUserCont display ";\s*\I\i*\s*:[^:]"me=e-1 contains=@cLabelGroup
+
+syn match cUserLabel display "\I\i*" contained
+
+" Avoid recognizing most bitfields as labels
+syn match cBitField display "^\s*\I\i*\s*:\s*[1-9]"me=e-1 contains=cType
+syn match cBitField display ";\s*\I\i*\s*:\s*[1-9]"me=e-1 contains=cType
+
+if exists("c_minlines")
+ let b:c_minlines = c_minlines
+else
+ if !exists("c_no_if0")
+ let b:c_minlines = 50 " #if 0 constructs can be long
+ else
+ let b:c_minlines = 15 " mostly for () constructs
+ endif
+endif
+if exists("c_curly_error")
+ syn sync fromstart
+else
+ exec "syn sync ccomment cComment minlines=" . b:c_minlines
+endif
+
+" Define the default highlighting.
+" Only used when an item doesn't have highlighting yet
+hi def link cFormat cSpecial
+hi def link cCppString cString
+hi def link cCommentL cComment
+hi def link cCommentStart cComment
+hi def link cLabel Label
+hi def link cUserLabel Label
+hi def link cConditional Conditional
+hi def link cRepeat Repeat
+hi def link cCharacter Character
+hi def link cSpecialCharacter cSpecial
+hi def link cNumber Number
+hi def link cOctal Number
+hi def link cOctalZero PreProc " link this to Error if you want
+hi def link cFloat Float
+hi def link cOctalError cError
+hi def link cParenError cError
+hi def link cErrInParen cError
+hi def link cErrInBracket cError
+hi def link cCommentError cError
+hi def link cCommentStartError cError
+hi def link cSpaceError cError
+hi def link cSpecialError cError
+hi def link cCurlyError cError
+hi def link cOperator Operator
+hi def link cStructure Structure
+hi def link cStorageClass StorageClass
+hi def link cInclude Include
+hi def link cPreProc PreProc
+hi def link cDefine Macro
+hi def link cIncluded cString
+hi def link cError Error
+hi def link cStatement Statement
+hi def link cPreCondit PreCondit
+hi def link cType Type
+hi def link cConstant Constant
+hi def link cCommentString cString
+hi def link cComment2String cString
+hi def link cCommentSkip cComment
+hi def link cString String
+hi def link cComment Comment
+hi def link cSpecial SpecialChar
+hi def link cTodo Todo
+hi def link cBadContinuation Error
+hi def link cCppSkip cCppOut
+hi def link cCppOut2 cCppOut
+hi def link cCppOut Comment
+
+let b:current_syntax = "c"
+
+" vim: ts=8