From: Mike D. Lowis Date: Wed, 30 May 2012 14:46:59 +0000 (-0400) Subject: Added doxygen plugin and syntax files X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=4cc3eb98113cf94b712f91961a24cbc9fc540586;p=archive%2Fvim_config.git Added doxygen plugin and syntax files --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c950738 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +undo/* diff --git a/plugin/DoxygenToolkit.vim b/plugin/DoxygenToolkit.vim new file mode 100644 index 0000000..71cc651 --- /dev/null +++ b/plugin/DoxygenToolkit.vim @@ -0,0 +1,1153 @@ +" 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 +" "\" + + +" 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) \\" +let s:licenseTag = s:licenseTag . "This program is free software; you can redistribute it and/or\" +let s:licenseTag = s:licenseTag . "modify it under the terms of the GNU General Public License\" +let s:licenseTag = s:licenseTag . "as published by the Free Software Foundation; either version 2\" +let s:licenseTag = s:licenseTag . "of the License, or (at your option) any later version.\\" +let s:licenseTag = s:licenseTag . "This program is distributed in the hope that it will be useful,\" +let s:licenseTag = s:licenseTag . "but WITHOUT ANY WARRANTY; without even the implied warranty of\" +let s:licenseTag = s:licenseTag . "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\" +let s:licenseTag = s:licenseTag . "GNU General Public License for more details.\\" +let s:licenseTag = s:licenseTag . "You should have received a copy of the GNU General Public License\" +let s:licenseTag = s:licenseTag . "along with this program; if not, write to the Free Software\" +let s:licenseTag = s:licenseTag . "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\" + +" 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! 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, "\", "\".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! 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! 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! 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! 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 = '.*\[[:blank:]]*(\([^()]*\)).*' "available only for 'cpp' type + + let l:classPattern = '\[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze.*\%('.l:endDocPattern.'\)' + let l:structPattern = '\[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze[^(),]*\%('.l:endDocPattern.'\)' + let l:enumPattern = '\\%(\%([[:blank:]]\+\zs'.l:someNamePattern.'\ze[[:blank:]]*\)\|\%(\zs\ze[[:blank:]]*\)\)\%('.l:endDocPattern.'\)' + let l:namespacePattern = '\[[: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 = '\[[:blank:]]\+\zs'.l:someNamePattern.'\ze.*:' + let l:functionPattern = '\[[:blank:]]\+\zs'.l:someNamePattern.'\ze.*:' + + let l:endDocPattern = '\%(\\|\[^:]*\)\@.*' ) != -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, '\' ) != -1 ) + let l:doc.type = 'enum' + elseif( match( l:lineBuffer, '\' ) != -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, ')[^)]*\%(;\|{\|\%([^:]:\%([^:]\|$\)\)\|\%(\\)\).*', '', '' ) + 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 DoxygenCommentFunc() +command! -nargs=0 DoxLic :call DoxygenLicenseFunc() +command! -nargs=0 DoxAuthor :call DoxygenAuthorFunc() +command! -nargs=1 DoxUndoc :call DoxygenUndocumentFunc() +command! -nargs=0 DoxBlock :call DoxygenBlockFunc() + diff --git a/syntax/axio.vim b/syntax/axio.vim new file mode 100644 index 0000000..481a0f7 --- /dev/null +++ b/syntax/axio.vim @@ -0,0 +1,16 @@ +" Vim syntax file +" Language: Axio +" Maintainer: Mike Lowis +" Last Change: 2012 March 25 + +" Quit when a (custom) syntax file was already loaded +if exists("b:current_syntax") + finish +endif + +syn keyword cConditional if else switch + + +hi def link cConditional Conditional + +let b:current_syntax = "axio" diff --git a/syntax/c.vim b/syntax/c.vim new file mode 100644 index 0000000..e57167b --- /dev/null +++ b/syntax/c.vim @@ -0,0 +1,374 @@ +" Vim syntax file +" Language: C +" Maintainer: Bram Moolenaar +" 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="$" 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 diff --git a/vimrc b/vimrc index 0f565f1..6e16b37 100644 --- a/vimrc +++ b/vimrc @@ -90,13 +90,16 @@ function! ReformatWhiteSpace() endif endfunction -function! UpdateStatus() +function! UpdateStatus(lmarg,rmarg) + " Reset our Globals let g:CurBuffer = '[' . bufnr('%') . ' ' . expand('%:t') . ((&modified) ? ' +]' : ']') let g:BufsLeft = "" let g:BufsRight = "" - let i = bufnr('$') - let my_left_len = (winwidth(0) - len(g:CurBuffer) - 20) + + let tot_margin = a:lmarg+ a:rmarg + let my_left_len = (winwidth(0) - len(g:CurBuffer) - tot_margin) let my_right_len = 0 + let i = bufnr('$') while(i > 0) if buflisted(i) && getbufvar(i, "&modifiable") && i != bufnr('%') @@ -112,11 +115,11 @@ function! UpdateStatus() endwhile if len(g:BufsLeft) < my_left_len - let my_right_len = winwidth(0) - (len(g:BufsLeft) + len(g:CurBuffer) + 20) + let my_right_len = winwidth(0) - (len(g:BufsLeft) + len(g:CurBuffer) + tot_margin) endif if len(g:BufsRight) < my_right_len - let my_left_len = winwidth(0) - (len(g:BufsRight) + len(g:CurBuffer) + 20) + let my_left_len = winwidth(0) - (len(g:BufsRight) + len(g:CurBuffer) + tot_margin) endif if len(g:BufsLeft) > my_left_len @@ -138,6 +141,10 @@ command! -range=% -nargs=0 ToFn execute ",s/;/\r{\r\r}\r/" let mapleader = ";" let g:mapleader = ";" +" ---- Move Cursor By Display Lines ---- +map j gj +map k gk + " ---- Quick Save ---- map w :w @@ -159,8 +166,6 @@ map :bp imap :bp map :bn imap :bn -map d :bd -imap d :bd " ---- Working With Windows ---- map h @@ -187,6 +192,11 @@ map fe :cs find e map ff :cs find f map fi :cs find i +" ---- CScope Mappings ---- +map dc :Dox +map da :DoxAuthor +map dl :DoxLic + " ---- Switch between header and C file ---- map :e %:p:s,.h$,.X123X,:s,.c$,.h,:s,.X123X$,.c, @@ -227,7 +237,16 @@ autocmd BufEnter * call LoadProject() autocmd BufWritePre * call ReformatWhiteSpace() " Update the buffer list in the status line -autocmd VimEnter,BufNew,BufEnter,BufWritePost,VimResized * call UpdateStatus() +autocmd VimEnter,BufNew,BufEnter,BufWritePost,VimResized,FocusLost,FocusGained,InsertLeave * call UpdateStatus(0,20) + +" Set filetypes +autocmd BufRead,BufNewFile *.md set filetype=markdown + +"============================================================================== +" Doxygen Comment Configuration +"============================================================================== +" File author tag +let g:DoxygenToolkit_authorName = "Michael D. Lowis" "============================================================================== " GVim