├── README └── plugin └── DoxygenToolkit.vim /README: -------------------------------------------------------------------------------- 1 | This is a mirror of http://www.vim.org/scripts/script.php?script_id=987 2 | 3 | Currently five purposes have been defined : 4 | 5 | Generates a doxygen license comment. The tag text is configurable. 6 | 7 | Generates a doxygen author skeleton. The tag text is configurable. 8 | 9 | Generates a doxygen comment skeleton for a C, C++ or Python function or class, 10 | including @brief, @param (for each named argument), and @return. The tag 11 | text as well as a comment block header and footer are configurable. 12 | (Consequently, you can have \brief, etc. if you wish, with little effort.) 13 | 14 | Ignore code fragment placed in a block defined by #ifdef ... #endif (C/C++). The 15 | block name must be given to the function. All of the corresponding blocks 16 | in all the file will be treated and placed in a new block DOX_SKIP_BLOCK (or 17 | any other name that you have configured). Then you have to update 18 | PREDEFINED value in your doxygen configuration file with correct block name. 19 | You also have to set ENABLE_PREPROCESSING to YES. 20 | 21 | Generate a doxygen group (begining and ending). The tag text is 22 | configurable. 23 | 24 | Use: 25 | - Type of comments (C/C++: /// or /** ... */, Python: ## and # ) : 26 | In vim, default C++ comments are : /** ... */. But if you prefer to use /// 27 | Doxygen comments just add 'let g:DoxygenToolkit_commentType = "C++"' 28 | (without quotes) in your .vimrc file 29 | 30 | - License : 31 | In vim, place the cursor on the line that will follow doxygen license 32 | comment. Then, execute the command :DoxLic. This will generate license 33 | comment and leave the cursor on the line just after. 34 | 35 | - Author : 36 | In vim, place the cursor on the line that will follow doxygen author 37 | comment. Then, execute the command :DoxAuthor. This will generate the 38 | skeleton and leave the cursor just after @author tag if no variable 39 | define it, or just after the skeleton. 40 | 41 | - Function / class comment : 42 | In vim, place the cursor on the line of the function header (or returned 43 | value of the function) or the class. Then execute the command :Dox. This 44 | will generate the skeleton and leave the cursor after the @brief tag. 45 | 46 | - Ignore code fragment (C/C++ only) : 47 | In vim, if you want to ignore all code fragment placed in a block such as : 48 | #ifdef DEBUG 49 | ... 50 | #endif 51 | You only have to execute the command :DoxUndoc(DEBUG) ! 52 | 53 | - Group : 54 | In vim, execute the command :DoxBlock to insert a doxygen block on the 55 | following line. 56 | 57 | Limitations: 58 | - Assumes that the function name (and the following opening parenthesis) is 59 | at least on the third line after current cursor position. 60 | - Not able to update a comment block after it's been written. 61 | - Blocks delimiters (header and footer) are only included for function 62 | comment. 63 | - Assumes that cindent is used. 64 | - Comments in function parameters (such as void foo(int bar /* ... */, baz)) 65 | are not yet supported. 66 | 67 | 68 | Example: 69 | Given: 70 | int 71 | foo(char mychar, 72 | int myint, 73 | double* myarray, 74 | int mask = DEFAULT) 75 | { //... 76 | } 77 | 78 | Issuing the :Dox command with the cursor on the function declaration would 79 | generate 80 | 81 | /** 82 | * @brief 83 | * 84 | * @param mychar 85 | * @param myint 86 | * @param myarray 87 | * @param mask 88 | * 89 | * @return 90 | */ 91 | 92 | 93 | To customize the output of the script, see the g:DoxygenToolkit_* 94 | variables in the script's source. These variables can be set in your 95 | .vimrc. 96 | 97 | For example, my .vimrc contains: 98 | let g:DoxygenToolkit_briefTag_pre="@Synopsis " 99 | let g:DoxygenToolkit_paramTag_pre="@Param " 100 | let g:DoxygenToolkit_returnTag="@Returns " 101 | let g:DoxygenToolkit_blockHeader="--------------------------------------------------------------------------" 102 | let g:DoxygenToolkit_blockFooter="----------------------------------------------------------------------------" 103 | let g:DoxygenToolkit_authorName="Mathias Lorente" 104 | let g:DoxygenToolkit_licenseTag="My own license" <-- !!! Does not end with "\" 105 | -------------------------------------------------------------------------------- /plugin/DoxygenToolkit.vim: -------------------------------------------------------------------------------- 1 | " DoxygenToolkit.vim 2 | " Brief: Usefull tools for Doxygen (comment, author, license). 3 | " Version: 0.2.13 4 | " Date: 2010/10/16 5 | " Author: Mathias Lorente 6 | " 7 | " TODO: add automatically (option controlled) in/in out flags to function 8 | " parameters 9 | " TODO: (Python) Check default paramareters defined as list/dictionnary/tuple 10 | " 11 | " Note: Correct insertion position and 'xxx_post' parameters. 12 | " - Insert position is correct when g:DoxygenToolkit_compactOneLineDoc = "yes" 13 | " and let g:DoxygenToolkit_commentType = "C++" are set. 14 | " - When you define: 15 | " g:DoxygenToolkit_briefTag_pre = "@brief " 16 | " g:DoxygenToolkit_briefTag_post = "<++>" 17 | " g:DoxygenToolkit_briefTag_funcName = "yes" 18 | " Documentation generated with these parameters is something like: 19 | " /// @brief foo <++> 20 | " You can configure similarly parameters to get something like: 21 | " /// @brief foo <++> 22 | " /// @param bar <++> 23 | " /// @param baz <++> 24 | " 25 | " Note: Position the cursor at the right position for one line documentation. 26 | " 27 | " Note: Remove trailing blank characters where they are not needed. 28 | " 29 | " Note: 'extern' keyword added in list of values to ignore for return type. 30 | " 31 | " Note: Correct bugs related to templates and add support for throw statement 32 | " (many thanks to Dennis Lubert): 33 | " - Template parameter of different type from class and typename are 34 | " recognized. 35 | " - Indentation mistake while detecting template. 36 | " - New option are available: g:DoxygenToolkit_throwTag_pre and 37 | " g:DoxygenToolkit_throwTag_post 38 | " 39 | " Note: Add support for documentation of template parameters. 40 | " Thanks to Dennis (plasmahh) and its suggestions. 41 | " - New option are available: g:DoxygenToolkit_templateParamTag_pre 42 | " and g:DoxygenToolkit_templateParamTag_post 43 | " 44 | " Note: Solve almost all compatibility problem with c/c++ IDE 45 | " 46 | " Note: Bug correction and improve compatibility with c/c++ IDE 47 | " - Documentation of function with struct parameters are now allowed. 48 | " - Comments are written in two steps to avoid conflicts with c/c++ IDE. 49 | " 50 | " Note: Bug correction (thanks to Jhon Do) 51 | " - DoxygenToolkit_briefTag_funcName and other xxx_xxName parameters 52 | " should work properly now. 53 | " 54 | " Note: Bug correction (thanks to Anders Bo Rasmussen) 55 | " - C++: now functions like void foo(type &bar); are correctly documented. 56 | " The parameter's name is bar (and no more &bar). 57 | " 58 | " Note: Added @version tag into the DocBlock generated by DoxygenAuthorFunc() 59 | " (thanks to Dave Walter). 60 | " The version string can be defines into your .vimrc file with 61 | " g:DoxygenToolkit_versionString or it will be asked the first time the 62 | " function is called (same behavior as @author tag). Example: 63 | " /// \file foo.cpp 64 | " /// \brief 65 | " /// \author Dave Walter 66 | " /// \version 1.0 67 | " /// \date 2009-03-26 68 | " 69 | " Note: Comments are now allowed in function declaration. Example: 70 | " - C/C++: void func( int foo, // first param 71 | " int bar /* second param */ ); 72 | " 73 | " - Python: def func( foo, # first param 74 | " bar ) # second param 75 | " 76 | " Note: Bug correction (many thanks to Alexey Radkov) 77 | " - C/C++: following function/method are now correctly documented: 78 | " - operator(), 79 | " - constructor with initialization parameter(s), 80 | " - pure virtual method, 81 | " - const method. 82 | " - Python: 83 | " - Single line function are now correctly documented. 84 | " 85 | " Note: The main function has been rewritten (I hope it is cleaner). 86 | " - There is now support for function pointer as parameter (C/C++). 87 | " - You can configure the script to get one line documentation (for 88 | " attribute instance for example, you need to set 89 | " g:DoxygenToolkit_compactOneLineDoc to "yes"). 90 | " 91 | " - NEW: Support Python scripts: 92 | " - Function/method are not scanned, so by default they are considered 93 | " as if they always return something (modify this behavior by defining 94 | " g:DoxygenToolkit_python_autoFunctionReturn to "no") 95 | " - self parameter is automatically ignored when scanning function 96 | " parameters (you can change this behavior by defining 97 | " g:DoxygenToolkit_python_autoRemoveSelfParam to "no") 98 | " 99 | " Note: Number of lines scanned is now configurable. Default value is still 10 100 | " lines. (Thanks to Spencer Collyer for this improvement). 101 | " 102 | " Note: Bug correction : function that returns null pointer are correctly 103 | " documented (Thanks to Ronald WAHL for his report and patch). 104 | " 105 | " Note: Remove header and footer from doxygen documentation 106 | " - Generated documentation with block header/footer activated (see 107 | " parameters g:DoxygenToolkit_blockHeader and 108 | " g:DoxygenToolkit_blockFooter) do not integrate header and footer 109 | " anymore. 110 | " Thanks to Justin RANDALL for this. 111 | " Now comments are as following: 112 | " /* --- My Header --- */ // --- My Header --- 113 | " /** /// @brief ... 114 | " * @brief ... or // --- My Footer --- 115 | " */ 116 | " /* -- My Footer --- */ 117 | " 118 | " Note: Changes to customize cinoptions 119 | " - New option available for cinoptions : g:DoxygenToolkit_cinoptions 120 | " (default value is still c1C1) 121 | " Thanks to Arnaud GODET for this. Now comment can have the following 122 | " look: 123 | " /** /** 124 | " * and not only * 125 | " */ */ 126 | " Note: Changes for linux kernel comment style 127 | " - New option are available for brief tag and parameter tag ! Now there is 128 | " a pre and a post tag for each of these tag. 129 | " - You can define 'let g:DoxygenToolkit_briefTag_funcName = "yes"' to add 130 | " the name of commented function between pre-brief tag and post-brief tag. 131 | " - With these new features you can get something like: 132 | " /** 133 | " * @brief MyFunction - 134 | " * 135 | " * @param foo: 136 | " * @param bar: 137 | " */ 138 | " Note: Changes suggested by Soh Kok Hong: 139 | " - Fixed indentation in comments 140 | " ( no more /** /** 141 | " * but * 142 | " */ */ ) 143 | " Note: Changes made by Jason Mills: 144 | " - Fixed \n bug which resulted in comments being screwed up 145 | " - Added use of doxygen /// comments. 146 | " Note: Changes made by Mathias Lorente on 05/25/04 147 | " - Fixed filename bug when including doxygen author comment whereas file 148 | " has not been open directly on commamd line. 149 | " - Now /// or /** doxygen comments are correctly integrated (except for 150 | " license). 151 | " Note: Changes made by Mathias Lorente on 08/02/04 152 | " - Now include only filename in author comment (no more folder...) 153 | " - Fixed errors with function with no indentation. 154 | " 155 | " 156 | " Currently five purposes have been defined : 157 | " 158 | " Generates a doxygen license comment. The tag text is configurable. 159 | " 160 | " Generates a doxygen author skeleton. The tag text is configurable. 161 | " 162 | " Generates a doxygen comment skeleton for a C, C++ or Python function or class, 163 | " including @brief, @param (for each named argument), and @return. The tag 164 | " text as well as a comment block header and footer are configurable. 165 | " (Consequently, you can have \brief, etc. if you wish, with little effort.) 166 | " 167 | " Ignore code fragment placed in a block defined by #ifdef ... #endif (C/C++). The 168 | " block name must be given to the function. All of the corresponding blocks 169 | " in all the file will be treated and placed in a new block DOX_SKIP_BLOCK (or 170 | " any other name that you have configured). Then you have to update 171 | " PREDEFINED value in your doxygen configuration file with correct block name. 172 | " You also have to set ENABLE_PREPROCESSING to YES. 173 | " 174 | " Generate a doxygen group (begining and ending). The tag text is 175 | " configurable. 176 | " 177 | " Use: 178 | " - Type of comments (C/C++: /// or /** ... */, Python: ## and # ) : 179 | " In vim, default C++ comments are : /** ... */. But if you prefer to use /// 180 | " Doxygen comments just add 'let g:DoxygenToolkit_commentType = "C++"' 181 | " (without quotes) in your .vimrc file 182 | " 183 | " - License : 184 | " In vim, place the cursor on the line that will follow doxygen license 185 | " comment. Then, execute the command :DoxLic. This will generate license 186 | " comment and leave the cursor on the line just after. 187 | " 188 | " - Author : 189 | " In vim, place the cursor on the line that will follow doxygen author 190 | " comment. Then, execute the command :DoxAuthor. This will generate the 191 | " skeleton and leave the cursor just after @author tag if no variable 192 | " define it, or just after the skeleton. 193 | " 194 | " - Function / class comment : 195 | " In vim, place the cursor on the line of the function header (or returned 196 | " value of the function) or the class. Then execute the command :Dox. This 197 | " will generate the skeleton and leave the cursor after the @brief tag. 198 | " 199 | " - Ignore code fragment : 200 | " In vim, if you want to ignore all code fragment placed in a block such as : 201 | " #ifdef DEBUG 202 | " ... 203 | " #endif 204 | " You only have to execute the command :DoxUndoc(DEBUG) ! 205 | " 206 | " - Group : 207 | " In vim, execute the command :DoxBlock to insert a doxygen block on the 208 | " following line. 209 | " 210 | " Limitations: 211 | " - Assumes that the function name (and the following opening parenthesis) is 212 | " at least on the third line after current cursor position. 213 | " - Not able to update a comment block after it's been written. 214 | " - Blocks delimiters (header and footer) are only included for function 215 | " comment. 216 | " - Assumes that cindent is used. 217 | " - Comments in function parameters (such as void foo(int bar /* ... */, baz)) 218 | " are not yet supported. 219 | " 220 | " 221 | " Example: 222 | " Given: 223 | " int 224 | " foo(char mychar, 225 | " int myint, 226 | " double* myarray, 227 | " int mask = DEFAULT) 228 | " { //... 229 | " } 230 | " 231 | " Issuing the :Dox command with the cursor on the function declaration would 232 | " generate 233 | " 234 | " /** 235 | " * @brief 236 | " * 237 | " * @param mychar 238 | " * @param myint 239 | " * @param myarray 240 | " * @param mask 241 | " * 242 | " * @return 243 | " */ 244 | " 245 | " 246 | " To customize the output of the script, see the g:DoxygenToolkit_* 247 | " variables in the script's source. These variables can be set in your 248 | " .vimrc. 249 | " 250 | " For example, my .vimrc contains: 251 | " let g:DoxygenToolkit_briefTag_pre="@Synopsis " 252 | " let g:DoxygenToolkit_paramTag_pre="@Param " 253 | " let g:DoxygenToolkit_returnTag="@Returns " 254 | " let g:DoxygenToolkit_blockHeader="--------------------------------------------------------------------------" 255 | " let g:DoxygenToolkit_blockFooter="----------------------------------------------------------------------------" 256 | " let g:DoxygenToolkit_authorName="Mathias Lorente" 257 | " let g:DoxygenToolkit_licenseTag="My own license" <-- Does not end with 258 | " "\" 259 | 260 | 261 | " Verify if already loaded 262 | "if exists("loaded_DoxygenToolkit") 263 | " echo 'DoxygenToolkit Already Loaded.' 264 | " finish 265 | "endif 266 | let loaded_DoxygenToolkit = 1 267 | "echo 'Loading DoxygenToolkit...' 268 | let s:licenseTag = "Copyright (C) \\" 269 | let s:licenseTag = s:licenseTag . "This program is free software; you can redistribute it and/or\" 270 | let s:licenseTag = s:licenseTag . "modify it under the terms of the GNU General Public License\" 271 | let s:licenseTag = s:licenseTag . "as published by the Free Software Foundation; either version 2\" 272 | let s:licenseTag = s:licenseTag . "of the License, or (at your option) any later version.\\" 273 | let s:licenseTag = s:licenseTag . "This program is distributed in the hope that it will be useful,\" 274 | let s:licenseTag = s:licenseTag . "but WITHOUT ANY WARRANTY; without even the implied warranty of\" 275 | let s:licenseTag = s:licenseTag . "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\" 276 | let s:licenseTag = s:licenseTag . "GNU General Public License for more details.\\" 277 | let s:licenseTag = s:licenseTag . "You should have received a copy of the GNU General Public License\" 278 | let s:licenseTag = s:licenseTag . "along with this program; if not, write to the Free Software\" 279 | let s:licenseTag = s:licenseTag . "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\" 280 | 281 | " Common standard constants 282 | if !exists("g:DoxygenToolkit_briefTag_pre") 283 | let g:DoxygenToolkit_briefTag_pre = "@brief " 284 | endif 285 | if !exists("g:DoxygenToolkit_briefTag_post") 286 | let g:DoxygenToolkit_briefTag_post = "" 287 | endif 288 | if !exists("g:DoxygenToolkit_templateParamTag_pre") 289 | let g:DoxygenToolkit_templateParamTag_pre = "@tparam " 290 | endif 291 | if !exists("g:DoxygenToolkit_templateParamTag_post") 292 | let g:DoxygenToolkit_templateParamTag_post = "" 293 | endif 294 | if !exists("g:DoxygenToolkit_paramTag_pre") 295 | let g:DoxygenToolkit_paramTag_pre = "@param " 296 | endif 297 | if !exists("g:DoxygenToolkit_paramTag_post") 298 | let g:DoxygenToolkit_paramTag_post = "" 299 | endif 300 | if !exists("g:DoxygenToolkit_returnTag") 301 | let g:DoxygenToolkit_returnTag = "@return " 302 | endif 303 | if !exists("g:DoxygenToolkit_throwTag_pre") 304 | let g:DoxygenToolkit_throwTag_pre = "@throw " " @exception is also valid 305 | endif 306 | if !exists("g:DoxygenToolkit_throwTag_post") 307 | let g:DoxygenToolkit_throwTag_post = "" 308 | endif 309 | if !exists("g:DoxygenToolkit_blockHeader") 310 | let g:DoxygenToolkit_blockHeader = "" 311 | endif 312 | if !exists("g:DoxygenToolkit_blockFooter") 313 | let g:DoxygenToolkit_blockFooter = "" 314 | endif 315 | if !exists("g:DoxygenToolkit_licenseTag") 316 | let g:DoxygenToolkit_licenseTag = s:licenseTag 317 | endif 318 | if !exists("g:DoxygenToolkit_fileTag") 319 | let g:DoxygenToolkit_fileTag = "@file " 320 | endif 321 | if !exists("g:DoxygenToolkit_authorTag") 322 | let g:DoxygenToolkit_authorTag = "@author " 323 | endif 324 | if !exists("g:DoxygenToolkit_dateTag") 325 | let g:DoxygenToolkit_dateTag = "@date " 326 | endif 327 | if !exists("g:DoxygenToolkit_versionTag") 328 | let g:DoxygenToolkit_versionTag = "@version " 329 | endif 330 | if !exists("g:DoxygenToolkit_undocTag") 331 | let g:DoxygenToolkit_undocTag = "DOX_SKIP_BLOCK" 332 | endif 333 | if !exists("g:DoxygenToolkit_blockTag") 334 | let g:DoxygenToolkit_blockTag = "@name " 335 | endif 336 | if !exists("g:DoxygenToolkit_classTag") 337 | let g:DoxygenToolkit_classTag = "@class " 338 | endif 339 | 340 | if !exists("g:DoxygenToolkit_cinoptions") 341 | let g:DoxygenToolkit_cinoptions = "c1C1" 342 | endif 343 | if !exists("g:DoxygenToolkit_startCommentTag ") 344 | let g:DoxygenToolkit_startCommentTag = "/** " 345 | let g:DoxygenToolkit_startCommentBlock = "/* " 346 | endif 347 | if !exists("g:DoxygenToolkit_interCommentTag ") 348 | let g:DoxygenToolkit_interCommentTag = "* " 349 | endif 350 | if !exists("g:DoxygenToolkit_interCommentBlock ") 351 | let g:DoxygenToolkit_interCommentBlock = "* " 352 | endif 353 | if !exists("g:DoxygenToolkit_endCommentTag ") 354 | let g:DoxygenToolkit_endCommentTag = "*/" 355 | let g:DoxygenToolkit_endCommentBlock = "*/" 356 | endif 357 | if exists("g:DoxygenToolkit_commentType") 358 | if ( g:DoxygenToolkit_commentType == "C++" ) 359 | let g:DoxygenToolkit_startCommentTag = "/// " 360 | let g:DoxygenToolkit_interCommentTag = "/// " 361 | let g:DoxygenToolkit_endCommentTag = "" 362 | let g:DoxygenToolkit_startCommentBlock = "// " 363 | let g:DoxygenToolkit_interCommentBlock = "// " 364 | let g:DoxygenToolkit_endCommentBlock = "" 365 | else 366 | let g:DoxygenToolkit_commentType = "C" 367 | endif 368 | else 369 | let g:DoxygenToolkit_commentType = "C" 370 | endif 371 | 372 | " Compact documentation 373 | " /** 374 | " * \brief foo ---> /** \brief foo */ 375 | " */ 376 | if !exists("g:DoxygenToolkit_compactOneLineDoc") 377 | let g:DoxygenToolkit_compactOneLineDoc = "no" 378 | endif 379 | " /** 380 | " * \brief foo /** 381 | " * * \brief foo 382 | " * \param bar ---> * \param bar 383 | " * * \return 384 | " * \return */ 385 | " */ 386 | if !exists("g:DoxygenToolkit_compactDoc") 387 | let g:DoxygenToolkit_compactDoc = "no" 388 | endif 389 | 390 | " Necessary '\<' and '\>' will be added to each item of the list. 391 | let s:ignoreForReturn = ['template', 'explicit', 'inline', 'static', 'virtual', 'void\([[:blank:]]*\*\)\@!', 'const', 'volatile', 'struct', 'extern'] 392 | if !exists("g:DoxygenToolkit_ignoreForReturn") 393 | let g:DoxygenToolkit_ignoreForReturn = s:ignoreForReturn[:] 394 | else 395 | let g:DoxygenToolkit_ignoreForReturn += s:ignoreForReturn 396 | endif 397 | unlet s:ignoreForReturn 398 | 399 | " Maximum number of lines to check for function parameters 400 | if !exists("g:DoxygenToolkit_maxFunctionProtoLines") 401 | let g:DoxygenToolkit_maxFunctionProtoLines = 10 402 | endif 403 | 404 | " Add name of function/class/struct... after pre brief tag if you want 405 | if !exists("g:DoxygenToolkit_briefTag_className") 406 | let g:DoxygenToolkit_briefTag_className = "no" 407 | endif 408 | if !exists("g:DoxygenToolkit_briefTag_structName") 409 | let g:DoxygenToolkit_briefTag_structName = "no" 410 | endif 411 | if !exists("g:DoxygenToolkit_briefTag_enumName") 412 | let g:DoxygenToolkit_briefTag_enumName = "no" 413 | endif 414 | if !exists("g:DoxygenToolkit_briefTag_namespaceName") 415 | let g:DoxygenToolkit_briefTag_namespaceName = "no" 416 | endif 417 | if !exists("g:DoxygenToolkit_briefTag_funcName") 418 | let g:DoxygenToolkit_briefTag_funcName = "no" 419 | endif 420 | 421 | " Keep empty line (if any) between comment and function/class/... 422 | if !exists("g:DoxygenToolkit_keepEmptyLineAfterComment") 423 | let g:DoxygenToolkit_keepEmptyLineAfterComment = "no" 424 | endif 425 | 426 | " PYTHON specific 427 | """"""""""""""""" 428 | " Remove automatically self parameter from function to avoid its documantation 429 | if !exists("g:DoxygenToolkit_python_autoRemoveSelfParam") 430 | let g:DoxygenToolkit_python_autoRemoveSelfParam = "yes" 431 | endif 432 | " Consider functions as if they always return something (default: yes) 433 | if !exists("g:DoxygenToolkit_python_autoFunctionReturn") 434 | let g:DoxygenToolkit_python_autoFunctionReturn = "yes" 435 | endif 436 | 437 | 438 | """""""""""""""""""""""""" 439 | " Doxygen license comment 440 | """""""""""""""""""""""""" 441 | function! DoxygenLicenseFunc() 442 | call s:InitializeParameters() 443 | 444 | " Test authorName variable 445 | if !exists("g:DoxygenToolkit_authorName") 446 | let g:DoxygenToolkit_authorName = input("Enter name of the author (generally yours...) : ") 447 | endif 448 | mark d 449 | let l:date = strftime("%Y") 450 | exec "normal O".strpart( s:startCommentBlock, 0, 1 ) 451 | exec "normal A".strpart( s:startCommentBlock, 1 ).substitute( g:DoxygenToolkit_licenseTag, "\", "\".s:interCommentBlock, "g" ) 452 | if( s:endCommentBlock != "" ) 453 | exec "normal o".s:endCommentBlock 454 | endif 455 | if( g:DoxygenToolkit_licenseTag == s:licenseTag ) 456 | exec "normal %jA".l:date." - ".g:DoxygenToolkit_authorName 457 | endif 458 | exec "normal `d" 459 | 460 | call s:RestoreParameters() 461 | endfunction 462 | 463 | 464 | """""""""""""""""""""""""" 465 | " Doxygen author comment 466 | """""""""""""""""""""""""" 467 | function! DoxygenAuthorFunc() 468 | call s:InitializeParameters() 469 | 470 | " Test authorName variable 471 | if !exists("g:DoxygenToolkit_authorName") 472 | let g:DoxygenToolkit_authorName = input("Enter name of the author (generally yours...) : ") 473 | endif 474 | 475 | " Test versionString variable 476 | if !exists("g:DoxygenToolkit_versionString") 477 | let g:DoxygenToolkit_versionString = input("Enter version string : ") 478 | endif 479 | 480 | " Get file name 481 | let l:fileName = expand('%:t') 482 | 483 | " Begin to write skeleton 484 | let l:insertionMode = s:StartDocumentationBlock() 485 | exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_fileTag.l:fileName 486 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_briefTag_pre 487 | mark d 488 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_authorTag.g:DoxygenToolkit_authorName 489 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_versionTag.g:DoxygenToolkit_versionString 490 | let l:date = strftime("%Y-%m-%d") 491 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_dateTag.l:date 492 | if ( g:DoxygenToolkit_endCommentTag != "" ) 493 | exec "normal o".s:endCommentTag 494 | endif 495 | 496 | " Move the cursor to the rigth position 497 | exec "normal `d" 498 | 499 | call s:RestoreParameters() 500 | startinsert! 501 | endfunction 502 | 503 | 504 | """""""""""""""""""""""""" 505 | " Doxygen undocument function 506 | " C/C++ only! 507 | """""""""""""""""""""""""" 508 | function! DoxygenUndocumentFunc(blockTag) 509 | call s:InitializeParameters() 510 | let l:search = "#ifdef " . a:blockTag 511 | " Save cursor position and go to the begining of the file 512 | mark d 513 | exec "normal gg" 514 | 515 | while ( search(l:search, 'W') != 0 ) 516 | exec "normal O#ifndef " . g:DoxygenToolkit_undocTag 517 | exec "normal j^%" 518 | if ( g:DoxygenToolkit_endCommentTag == "" ) 519 | exec "normal o#endif // " . g:DoxygenToolkit_undocTag 520 | else 521 | exec "normal o#endif /* " . g:DoxygenToolkit_undocTag . " */" 522 | endif 523 | endwhile 524 | 525 | exec "normal `d" 526 | call s:RestoreParameters() 527 | endfunction 528 | 529 | 530 | 531 | """""""""""""""""""""""""" 532 | " DoxygenBlockFunc 533 | """""""""""""""""""""""""" 534 | function! DoxygenBlockFunc() 535 | call s:InitializeParameters() 536 | 537 | let l:insertionMode = s:StartDocumentationBlock() 538 | exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_blockTag 539 | mark d 540 | exec "normal o".s:interCommentTag."@{ ".s:endCommentTag 541 | exec "normal o".strpart( s:startCommentTag, 0, 1 ) 542 | exec "normal A".strpart( s:startCommentTag, 1 )." @} ".s:endCommentTag 543 | exec "normal `d" 544 | 545 | call s:RestoreParameters() 546 | startinsert! 547 | endfunction 548 | 549 | 550 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 551 | " Main comment function for class, attribute, function... 552 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 553 | function! DoxygenCommentFunc() 554 | 555 | " Initialize default templates. 556 | " Assure compatibility with Python for classes (cf. endDocPattern). 557 | let l:emptyLinePattern = '^[[:blank:]]*$' 558 | let l:someNamePattern = '[_[:alpha:]][_[:alnum:]]*' 559 | 560 | if( s:CheckFileType() == "cpp" ) 561 | let l:someNameWithNamespacePattern = l:someNamePattern.'\%(::'.l:someNamePattern.'\)*' 562 | let l:endDocPattern = ';\|{\|\%([^:]\zs:\ze\%([^:]\|$\)\)' 563 | let l:commentPattern = '\%(/*\)\|\%(//\)\' 564 | let l:templateParameterPattern = "<[^<>]*>" 565 | let l:throwPattern = '.*\[[:blank:]]*(\([^()]*\)).*' "available only for 'cpp' type 566 | 567 | let l:classPattern = '\[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze.*\%('.l:endDocPattern.'\)' 568 | let l:structPattern = '\[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze[^(),]*\%('.l:endDocPattern.'\)' 569 | let l:enumPattern = '\\%(\%([[:blank:]]\+\zs'.l:someNamePattern.'\ze[[:blank:]]*\)\|\%(\zs\ze[[:blank:]]*\)\)\%('.l:endDocPattern.'\)' 570 | let l:namespacePattern = '\[[:blank:]]\+\zs'.l:someNamePattern.'\ze[[:blank:]]*\%('.l:endDocPattern.'\)' 571 | 572 | let l:types = { "class": l:classPattern, "struct": l:structPattern, "enum": l:enumPattern, "namespace": l:namespacePattern } 573 | else 574 | let l:commentPattern = '#\|^[[:blank:]]*"""' 575 | 576 | let l:classPattern = '\[[:blank:]]\+\zs'.l:someNamePattern.'\ze.*:' 577 | let l:functionPattern = '\[[:blank:]]\+\zs'.l:someNamePattern.'\ze.*:' 578 | 579 | let l:endDocPattern = '\%(\\|\[^:]*\)\@.*' ) != -1 ) 628 | let l:endReadPattern = l:throwPattern 629 | let l:throwCompleted = 1 630 | let l:readError = "Cannot reach end of throw statement" 631 | else 632 | let l:endDocFound = 1 633 | endif 634 | else 635 | let l:endDocFound = 1 636 | endif 637 | continue 638 | endif 639 | exec "normal j" 640 | let l:lineBuffer = l:lineBuffer.' '.getline( line( "." )) 641 | let l:count = l:count + 1 642 | endwhile 643 | " Error message when the end of the function(/...) has not been found 644 | if( l:endDocFound == 0 ) 645 | if( match( l:lineBuffer, l:emptyLinePattern ) != -1 ) 646 | " Fall here when only comments have been found. 647 | call s:WarnMsg( "Nothing to document here!" ) 648 | else 649 | call s:WarnMsg( l:readError ) 650 | endif 651 | exec "normal `d" 652 | return 653 | endif 654 | 655 | " Trim the buffer 656 | let l:lineBuffer = substitute( l:lineBuffer, "^[[:blank:]]*\|[[:blank:]]*$", "", "g" ) 657 | 658 | " Check whether it is a template definition 659 | call s:ParseFunctionTemplateParameters( l:lineBuffer, l:doc ) 660 | " Remove any template parameter. 661 | if( s:CheckFileType() == "cpp" ) 662 | while( match( l:lineBuffer, l:templateParameterPattern ) != -1 ) 663 | let l:lineBuffer = substitute( l:lineBuffer, l:templateParameterPattern, "", "g" ) 664 | endwhile 665 | endif 666 | 667 | " Look for the type 668 | for key in keys( l:types ) 669 | "call s:WarnMsg( "[DEBUG] buffer:_".l:lineBuffer."_, test:_".l:types[key] ) 670 | let l:name = matchstr( l:lineBuffer, l:types[key] ) 671 | if( l:name != "" ) 672 | let l:doc.type = key 673 | let l:doc.name = l:name 674 | 675 | " Python only. Functions are detected differently for C/C++. 676 | if( key == "function" ) 677 | "call s:WarnMsg( "HERE !!!".l:lineBuffer ) 678 | call s:ParseFunctionParameters( l:lineBuffer, l:doc ) 679 | endif 680 | break 681 | endif 682 | endfor 683 | 684 | if( l:doc.type == "" ) 685 | " Should be a function/method (cpp only) or an attribute. 686 | " (cpp only) Can also be an unnamed enum/namespace... (or something else ?) 687 | if( s:CheckFileType() == "cpp" ) 688 | if( match( l:lineBuffer, '(' ) == -1 ) 689 | if( match( l:lineBuffer, '\' ) != -1 ) 690 | let l:doc.type = 'enum' 691 | elseif( match( l:lineBuffer, '\' ) != -1 ) 692 | let l:doc.type = 'namespace' 693 | else 694 | " TODO here we get a class attribute of something like that. 695 | " We probably just need a \brief statement... 696 | let l:doc.type = 'attribute' 697 | " TODO Retrieve the name of the attribute. 698 | " Do we really need it? I'm not sure for the moment. 699 | endif 700 | else 701 | let l:doc.type = 'function' 702 | call s:ParseFunctionParameters( l:lineBuffer, l:doc ) 703 | if( l:throwCompleted == 1 ) 704 | call s:ParseThrowParameters( l:lineBuffer, l:doc, l:throwPattern ) 705 | endif 706 | endif 707 | 708 | " This is an attribute for Python 709 | else 710 | let l:doc.type = 'attribute' 711 | endif 712 | endif 713 | 714 | " Remove the function/class/... name when it is not necessary 715 | 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" ) ) 716 | let l:doc.name = "None" 717 | 718 | " Remove namespace from the name of the class/function... 719 | elseif( s:CheckFileType() == "cpp" ) 720 | let l:doc.name = substitute( l:doc.name, '\%('.l:someNamePattern.'::\)', '', 'g' ) 721 | endif 722 | 723 | " Below, write what we have found 724 | """"""""""""""""""""""""""""""""" 725 | 726 | call s:InitializeParameters() 727 | if( s:CheckFileType() == "python" && l:doc.type == "function" && g:DoxygenToolkit_python_autoFunctionReturn == "yes" ) 728 | let l:doc.returns = "yes" 729 | endif 730 | 731 | " Header 732 | exec "normal `d" 733 | if( g:DoxygenToolkit_blockHeader != "" ) 734 | exec "normal O".strpart( s:startCommentBlock, 0, 1 ) 735 | exec "normal A".strpart( s:startCommentBlock, 1 ).g:DoxygenToolkit_blockHeader.s:endCommentBlock 736 | exec "normal `d" 737 | endif 738 | 739 | " Brief 740 | if( g:DoxygenToolkit_compactOneLineDoc =~ "yes" && l:doc.returns != "yes" && len( l:doc.params ) == 0 ) 741 | let s:compactOneLineDoc = "yes" 742 | exec "normal O".strpart( s:startCommentTag, 0, 1 ) 743 | exec "normal A".strpart( s:startCommentTag, 1 ).g:DoxygenToolkit_briefTag_pre 744 | else 745 | let s:compactOneLineDoc = "no" 746 | let l:insertionMode = s:StartDocumentationBlock() 747 | exec "normal ".l:insertionMode.s:interCommentTag.g:DoxygenToolkit_briefTag_pre 748 | endif 749 | if( l:doc.name != "None" ) 750 | exec "normal A".l:doc.name." " 751 | endif 752 | exec "normal A".g:DoxygenToolkit_briefTag_post 753 | 754 | " Mark the line where the cursor will be positionned. 755 | mark d 756 | 757 | " Arguments/parameters 758 | if( g:DoxygenToolkit_compactDoc =~ "yes" ) 759 | let s:insertEmptyLine = 0 760 | else 761 | let s:insertEmptyLine = 1 762 | endif 763 | for param in l:doc.templates 764 | if( s:insertEmptyLine == 1 ) 765 | exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" ) 766 | let s:insertEmptyLine = 0 767 | endif 768 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_templateParamTag_pre.param.g:DoxygenToolkit_templateParamTag_post 769 | endfor 770 | for param in l:doc.params 771 | if( s:insertEmptyLine == 1 ) 772 | exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" ) 773 | let s:insertEmptyLine = 0 774 | endif 775 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_paramTag_pre.param.g:DoxygenToolkit_paramTag_post 776 | endfor 777 | 778 | " Returned value 779 | if( l:doc.returns == "yes" ) 780 | if( g:DoxygenToolkit_compactDoc != "yes" ) 781 | exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" ) 782 | endif 783 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_returnTag 784 | endif 785 | 786 | " Exception (throw) values (cpp only) 787 | if( len( l:doc.throws ) > 0 ) 788 | if( g:DoxygenToolkit_compactDoc =~ "yes" ) 789 | let s:insertEmptyLine = 0 790 | else 791 | let s:insertEmptyLine = 1 792 | endif 793 | for param in l:doc.throws 794 | if( s:insertEmptyLine == 1 ) 795 | exec "normal o".substitute( s:interCommentTag, "[[:blank:]]*$", "", "" ) 796 | let s:insertEmptyLine = 0 797 | endif 798 | exec "normal o".s:interCommentTag.g:DoxygenToolkit_throwTag_pre.param.g:DoxygenToolkit_throwTag_post 799 | endfor 800 | endif 801 | 802 | " End (if any) of documentation block. 803 | if( s:endCommentTag != "" ) 804 | if( s:compactOneLineDoc =~ "yes" ) 805 | let s:execCommand = "A" 806 | exec "normal A " 807 | exec "normal $md" 808 | else 809 | let s:execCommand = "o" 810 | endif 811 | exec "normal ".s:execCommand.s:endCommentTag 812 | endif 813 | 814 | " Footer 815 | if ( g:DoxygenToolkit_blockFooter != "" ) 816 | exec "normal o".strpart( s:startCommentBlock, 0, 1 ) 817 | exec "normal A".strpart( s:startCommentBlock, 1 ).g:DoxygenToolkit_blockFooter.s:endCommentBlock 818 | endif 819 | exec "normal `d" 820 | 821 | call s:RestoreParameters() 822 | if( s:compactOneLineDoc =~ "yes" && s:endCommentTag != "" ) 823 | startinsert 824 | else 825 | startinsert! 826 | endif 827 | 828 | " DEBUG purpose only 829 | "call s:WarnMsg( "Found a ".l:doc.type." named ".l:doc.name." (env: ".s:CheckFileType().")." ) 830 | "if( l:doc.type == "function" ) 831 | " let l:funcReturn = "returns something." 832 | " if( l:doc.returns == "" ) 833 | " let l:funcReturn = "doesn't return anything." 834 | " endif 835 | " call s:WarnMsg( " - which ".l:funcReturn ) 836 | " call s:WarnMsg( " - which has following parameter(s):" ) 837 | " for param in l:doc.params 838 | " call s:WarnMsg( " - ".param ) 839 | " endfor 840 | "endif 841 | 842 | endfunction 843 | 844 | 845 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 846 | " Write the beginning of the documentation block: 847 | " - C and Python format: insert '/**' and '##' respectively then a linefeed, 848 | " - C++ insert '///' and continue on the same line 849 | " 850 | " This function return the insertion mode which should be used for the next 851 | " call to 'normal'. 852 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 853 | function! s:StartDocumentationBlock() 854 | " For C++ documentation format we do not need first empty line 855 | if( s:startCommentTag != s:interCommentTag ) 856 | "exec "normal O".s:startCommentTag 857 | exec "normal O".strpart( s:startCommentTag, 0, 1 ) 858 | exec "normal A".substitute( strpart( s:startCommentTag, 1 ), "[[:blank:]]*$", "", "" ) 859 | let l:insertionMode = "o" 860 | else 861 | let l:insertionMode = "O" 862 | endif 863 | return l:insertionMode 864 | endfunction 865 | 866 | 867 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 868 | " Remove comments from the given buffer. 869 | " - Remove everything after '//' or '#'. 870 | " - Remove everything between '/*' and '*/' or keep '/*' if '*/' is not present. 871 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 872 | function! s:RemoveComments( lineBuffer ) 873 | if( s:CheckFileType() == "cpp" ) 874 | " Remove C++ (//) comment. 875 | let l:lineBuffer = substitute( a:lineBuffer, '[[:blank:]]*\/\/.*$', '', '') 876 | " Remove partial C (/* ...) comment: /* foo bar --> /* 877 | " '/*' is preserved until corresponding '*/' is found. Other part of the 878 | " comment is discarded to prevent the case where it contains characters 879 | " corresponding to the endDoc string. 880 | let l:lineBuffer = substitute( l:lineBuffer, '\%(\/\*\zs.*\ze\)\&\%(\%(\/\*.*\*\/\)\@!\)', '', '') 881 | " Remove C (/* ... */) comment. 882 | let l:lineBuffer = substitute( l:lineBuffer, '\/\*.\{-}\*\/', '', 'g') 883 | else 884 | let l:lineBuffer = substitute( a:lineBuffer, '[[:blank:]]*#.*$', '', '') 885 | endif 886 | return l:lineBuffer 887 | endfunction 888 | 889 | 890 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 891 | " Retrieve file type. 892 | " - Default type is still 'cpp'. 893 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 894 | function! s:CheckFileType() 895 | if( &filetype == "python" ) 896 | let l:fileType = "python" 897 | else 898 | let l:fileType = "cpp" 899 | endif 900 | return l:fileType 901 | endfunction 902 | 903 | 904 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 905 | " Parse the buffer and set the doc parameter. 906 | " - Functions which return pointer to function are not supported. 907 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 908 | function! s:ParseFunctionParameters( lineBuffer, doc ) 909 | "call s:WarnMsg( 'IN__'.a:lineBuffer ) 910 | let l:paramPosition = matchend( a:lineBuffer, 'operator[[:blank:]]*([[:blank:]]*)' ) 911 | if ( l:paramPosition == -1 ) 912 | let l:paramPosition = stridx( a:lineBuffer, '(' ) 913 | else 914 | let l:paramPosition = stridx( a:lineBuffer, '(', l:paramPosition ) 915 | endif 916 | 917 | 918 | " (cpp only) First deal with function name and returned value. 919 | " Function name has already been retrieved for Python and we need to parse 920 | " all the function definition to know whether a value is returned or not. 921 | if( s:CheckFileType() == "cpp" ) 922 | let l:functionBuffer = strpart( a:lineBuffer, 0, l:paramPosition ) 923 | " Remove unnecessary elements 924 | for ignored in g:DoxygenToolkit_ignoreForReturn 925 | let l:functionBuffer = substitute( l:functionBuffer, '\<'.ignored.'\>', '', 'g' ) 926 | endfor 927 | let l:functionReturnAndName = split( l:functionBuffer, '[[:blank:]*]' ) 928 | if( len( l:functionReturnAndName ) > 1 ) 929 | let a:doc.returns = 'yes' 930 | endif 931 | let a:doc.name = l:functionReturnAndName[-1] 932 | endif 933 | 934 | " Work on parameters. 935 | let l:parametersBuffer = strpart( a:lineBuffer, l:paramPosition + 1 ) 936 | " Remove trailing closing bracket and everything that follows and trim. 937 | if( s:CheckFileType() == "cpp" ) 938 | let l:parametersBuffer = substitute( l:parametersBuffer, ')[^)]*\%(;\|{\|\%([^:]:\%([^:]\|$\)\)\|\%(\\)\).*', '', '' ) 939 | else 940 | let l:parametersBuffer = substitute( l:parametersBuffer, ')[^)]*:.*', '', '' ) 941 | endif 942 | let l:parametersBuffer = substitute( l:parametersBuffer, '^[[:blank:]]*\|[[:blank:]]*$', '', '' ) 943 | 944 | " Remove default parameter values (if any). 945 | let l:index = stridx( l:parametersBuffer, '=' ) 946 | let l:startIndex = l:index 947 | while( l:index != -1 ) 948 | " Look for the next colon... 949 | let l:colonIndex = stridx( l:parametersBuffer, ',', l:startIndex ) 950 | if( l:colonIndex == -1 ) 951 | let l:colonIndex = strlen( l:parametersBuffer ) 952 | endif 953 | let l:paramBuffer = strpart( l:parametersBuffer, l:index, l:colonIndex - l:index ) 954 | if( s:CountBrackets( l:paramBuffer ) == 0 ) 955 | " Everything in [l:index, l:colonIndex[ can be removed. 956 | let l:parametersBuffer = substitute( l:parametersBuffer, l:paramBuffer, '', '' ) 957 | let l:index = stridx( l:parametersBuffer, '=' ) 958 | let l:startIndex = l:index 959 | else 960 | " Parameter initialization contains brakets and colons... 961 | let l:startIndex = l:colonIndex + 1 962 | endif 963 | endwhile 964 | 965 | "call s:WarnMsg( "[DEBUG]: ".l:parametersBuffer ) 966 | " Now, work on each parameter. 967 | let l:params = [] 968 | let l:index = stridx( l:parametersBuffer, ',' ) 969 | while( l:index != -1 ) 970 | let l:paramBuffer = strpart( l:parametersBuffer, 0, l:index ) 971 | if( s:CountBrackets( l:paramBuffer ) == 0 ) 972 | let l:params = add( l:params, s:ParseParameter( l:paramBuffer ) ) 973 | let l:parametersBuffer = strpart( l:parametersBuffer, l:index + 1 ) 974 | let l:index = stridx( l:parametersBuffer, ',' ) 975 | else 976 | let l:index = stridx( l:parametersBuffer, ',', l:index + 1 ) 977 | endif 978 | endwhile 979 | if( strlen( l:parametersBuffer ) != 0 ) 980 | let l:params = add( l:params, s:ParseParameter( l:parametersBuffer ) ) 981 | endif 982 | 983 | if( s:CheckFileType() == "cpp" ) 984 | call filter( l:params, 'v:val !~ "void"' ) 985 | else 986 | if( g:DoxygenToolkit_python_autoRemoveSelfParam == "yes" ) 987 | call filter( l:params, 'v:val !~ "self"' ) 988 | endif 989 | endif 990 | 991 | for param in l:params 992 | call add( a:doc.params, param ) 993 | "call s:WarnMsg( '[DEBUG]:OUT_'.param ) 994 | endfor 995 | endfunction 996 | 997 | 998 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 999 | " Parse given parameter and return its name. 1000 | " It is easy to do unless you use function's pointers... 1001 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1002 | function! s:ParseParameter( param ) 1003 | let l:paramName = "Unknown" 1004 | let l:firstIndex = stridx( a:param, '(' ) 1005 | 1006 | if( l:firstIndex == -1 ) 1007 | let l:paramName = split( a:param, '[[:blank:]*&]' )[-1] 1008 | else 1009 | if( l:firstIndex != 0 ) 1010 | let l:startIndex = 0 1011 | else 1012 | let l:startIndex = stridx( a:param, ')' ) 1013 | if( l:startIndex == -1 ) " Argggg... 1014 | let l:paramName = a:param 1015 | else 1016 | let l:startIndex += 1 1017 | while( s:CountBrackets( strpart( a:param, 0, l:startIndex ) ) != 0 ) 1018 | let l:startIndex = stridx( a:param, ')', l:startIndex + 1 ) + 1 1019 | if( l:startIndex == -1) " Argggg... 1020 | let l:paramName = a:param 1021 | endif 1022 | endwhile 1023 | endif 1024 | endif 1025 | 1026 | if( l:startIndex != -1 ) 1027 | let l:startIndex = stridx( a:param, '(', l:startIndex ) + 1 1028 | let l:endIndex = stridx( a:param, ')', l:startIndex + 1 ) 1029 | let l:param = strpart( a:param, l:startIndex, l:endIndex - l:startIndex ) 1030 | let l:paramName = substitute( l:param, '^[[:blank:]*]*\|[[:blank:]*]*$', '', '' ) 1031 | else 1032 | " Something really wrong has happened. 1033 | let l:paramName = a:param 1034 | endif 1035 | endif 1036 | 1037 | return l:paramName 1038 | endfunction 1039 | 1040 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1041 | " Extract template parameter name for function/class/method 1042 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1043 | function! s:ParseFunctionTemplateParameters( lineBuffer, doc ) 1044 | if( match( a:lineBuffer, '^[[:blank:]]*template' ) == 0 ) 1045 | let l:firstIndex = stridx( a:lineBuffer, '<' ) 1046 | if( l:firstIndex != -1 ) 1047 | let l:lastIndex = stridx( a:lineBuffer, '>', l:firstIndex + 1 ) 1048 | if( l:lastIndex != -1 ) 1049 | " Keep only template parameters 1050 | let l:parameters = strpart( a:lineBuffer, l:firstIndex + 1, l:lastIndex - l:firstIndex - 1) 1051 | " Split on separator (,) 1052 | let l:params = split( l:parameters, '\,' ) 1053 | for param in l:params 1054 | " Extract template parameter name 1055 | let l:paramName = split( split( param, '=' )[0], '[[:blank:]]' )[-1] 1056 | call add( a:doc.templates, l:paramName ) 1057 | endfor 1058 | endif 1059 | endif 1060 | endif 1061 | endfunction 1062 | 1063 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1064 | " Extract throw parameter name 1065 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1066 | function! s:ParseThrowParameters( lineBuffer, doc, throwPattern ) 1067 | let l:throwParams = substitute( a:lineBuffer, a:throwPattern, '\1', "" ) 1068 | for param in split( l:throwParams, "," ) 1069 | call add( a:doc.throws, substitute( param, '[[:blank:]]', '', "" ) ) 1070 | endfor 1071 | endfunction 1072 | 1073 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1074 | " Define start/end documentation format and backup generic parameters. 1075 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1076 | function! s:InitializeParameters() 1077 | if( s:CheckFileType() == "cpp" ) 1078 | let s:startCommentTag = g:DoxygenToolkit_startCommentTag 1079 | let s:interCommentTag = g:DoxygenToolkit_interCommentTag 1080 | let s:endCommentTag = g:DoxygenToolkit_endCommentTag 1081 | let s:startCommentBlock = g:DoxygenToolkit_startCommentBlock 1082 | let s:interCommentBlock = g:DoxygenToolkit_interCommentBlock 1083 | let s:endCommentBlock = g:DoxygenToolkit_endCommentBlock 1084 | else 1085 | let s:startCommentTag = "## " 1086 | let s:interCommentTag = "# " 1087 | let s:endCommentTag = "" 1088 | let s:startCommentBlock = "# " 1089 | let s:interCommentBlock = "# " 1090 | let s:endCommentBlock = "" 1091 | endif 1092 | 1093 | " Backup standard comment expension and indentation 1094 | let s:commentsBackup = &comments 1095 | let &comments = "" 1096 | let s:cinoptionsBackup = &cinoptions 1097 | let &cinoptions = g:DoxygenToolkit_cinoptions 1098 | " Compatibility with c/c++ IDE plugin 1099 | let s:timeoutlenBackup = &timeoutlen 1100 | let &timeoutlen = 0 1101 | endfunction 1102 | 1103 | 1104 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1105 | " Restore previously backuped parameters. 1106 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1107 | function! s:RestoreParameters() 1108 | " Restore standard comment expension and indentation 1109 | let &comments = s:commentsBackup 1110 | let &cinoptions = s:cinoptionsBackup 1111 | " Compatibility with c/c++ IDE plugin 1112 | let &timeoutlen = s:timeoutlenBackup 1113 | endfunction 1114 | 1115 | 1116 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1117 | " Count opened/closed brackets in the given buffer. 1118 | " Each opened bracket increase the counter by 1. 1119 | " Each closed bracket decrease the counter by 1. 1120 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1121 | function! s:CountBrackets( buffer ) 1122 | let l:count = len( split( a:buffer, '(', 1 ) ) 1123 | let l:count -= len( split( a:buffer, ')', 1 ) ) 1124 | return l:count 1125 | endfunction 1126 | 1127 | 1128 | """"""""""""""""""""""""""""""""""" 1129 | " Simple warning message function 1130 | """"""""""""""""""""""""""""""""""" 1131 | function! s:WarnMsg( msg ) 1132 | echohl WarningMsg 1133 | echo a:msg 1134 | echohl None 1135 | return 1136 | endfunction 1137 | 1138 | """""""""""""""""""""""""" 1139 | " Shortcuts... 1140 | """""""""""""""""""""""""" 1141 | command! -nargs=0 Dox :call DoxygenCommentFunc() 1142 | command! -nargs=0 DoxLic :call DoxygenLicenseFunc() 1143 | command! -nargs=0 DoxAuthor :call DoxygenAuthorFunc() 1144 | command! -nargs=1 DoxUndoc :call DoxygenUndocumentFunc() 1145 | command! -nargs=0 DoxBlock :call DoxygenBlockFunc() 1146 | 1147 | --------------------------------------------------------------------------------