├── .gitignore ├── CHANGES.TXT ├── LICENSE.TXT ├── README ├── addon-info.json ├── autoload ├── tskeleton.vim └── tskeleton │ ├── abbreviations.vim │ ├── completefunc.vim │ ├── functions.vim │ ├── mini.vim │ ├── omnicomplete.vim │ ├── skeleton.vim │ ├── snippets.vim │ └── tags.vim ├── doc └── tskeleton.txt ├── etc └── tpl_tskeleton.txt ├── plugin └── tskeleton.vim ├── skeletons └── README_tskeleton.txt └── syntax └── tskeleton.vim /.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | Makefile 3 | TODO.TXT 4 | TODO_archived.viki 5 | *.vba 6 | *.vmb 7 | *.zip 8 | .last_* 9 | test 10 | test_* 11 | tmp 12 | var 13 | -------------------------------------------------------------------------------- /CHANGES.TXT: -------------------------------------------------------------------------------- 1 | 1.0 2 | - Initial release 3 | 4 | 1.1 5 | - User-defined tags 6 | - Modifiers <+NAME:MODIFIERS+> (c=capitalize, u=toupper, l=tolower, 7 | s//=substitute) 8 | - Skeleton bits 9 | - the default markup for tags has changed to <+TAG+> (for 10 | "compatibility" with imaps.vim), the cursor position is marked as 11 | <+CURSOR+> (but this can be changed by setting g:tskelMarkerLeft, 12 | g:tskelMarkerRight, and g:tskelMarkerCursor) 13 | - in the not so simple mode, skeleton bits can contain vim code that 14 | is evaluated after expanding the template tags (see 15 | .../skeletons/bits/vim/if for an example) 16 | - function TSkeletonExpandBitUnderCursor(), which is mapped to 17 | # 18 | - utility function: TSkeletonIncreaseRevisionNumber() 19 | 20 | 1.2 21 | - new pseudo tags: bit (recursive code skeletons), call (insert 22 | function result) 23 | - before & after sections in bit definitions may contain function 24 | definitions 25 | - fixed: no bit name given in s:SelectBit() 26 | - don't use ={motion} to indent text, but simply shift it 27 | 28 | 1.3 29 | - TSkeletonCleanUpBibEntry (mapped to tc for bib files) 30 | - complete set of bibtex entries 31 | - fixed problem with [&bg]: tags 32 | - fixed typo that caused some slowdown 33 | - other bug fixes 34 | - a query must be enclosed in question marks as in <+?Which ID?+> 35 | - the "test_tSkeleton" skeleton can be used to test if tSkeleton is 36 | working 37 | - and: after/before blocks must not contain function definitions 38 | 39 | 1.4 40 | - Popup menu with possible completions if 41 | TSkeletonExpandBitUnderCursor() is called for an unknown code 42 | skeleton (if there is only one possible completion, this one is 43 | automatically selected) 44 | - Make sure not to change the alternate file and not to distort the 45 | window layout 46 | - require genutils 47 | - Syntax highlighting for code skeletons 48 | - Skeleton bits can now be expanded anywhere in the line. This makes 49 | it possible to sensibly use small bits like date or time. 50 | - Minor adjustments 51 | - g:tskelMapLeader for easy customization of key mapping (changed the 52 | map leader to "#" in order to avoid a conflict with Align; 53 | set g:tskelMapLeader to "t" to get the old mappings) 54 | - Utility function: TSkeletonGoToNextTag(); imaps.vim like key 55 | bindings via TSkeletonMapGoToNextTag() 56 | 57 | 1.5 58 | - Menu of small skeleton "bits" 59 | - TSkeletonLateExpand() (mapped to #x) 60 | - Disabled # mapping (use it as a prefix only) 61 | - Fixed copy & paste error (loaded_genutils) 62 | - g:tskelDir defaults to $HOME ."/vimfiles/skeletons/" on Win32 63 | - Some speed-up 64 | 65 | 2.0 66 | - You can define "groups of bits" (e.g. in php mode, all html bits are 67 | available too) 68 | - context sensitive expansions (only very few examples yet); this 69 | causes some slowdown; if it is too slow, delete the files in 70 | .vim/skeletons/map/ 71 | - one-line "mini bits" defined in either 72 | ./vim/skeletons/bits/{&filetype}.txt or in $PWD/.tskelmini 73 | - Added a few LaTeX, HTML and many Viki skeleton bits 74 | - Added EncodeURL.vim 75 | - Hierarchical bits menu by calling a bit "SUBMENU.BITNAME" (the 76 | "namespace" is flat though; the prefix has no effect on the bit 77 | name; see the "bib" directory for an example) 78 | - the bit file may have an ampersand (&) in their names to define the 79 | keyboard shortcut 80 | - Some special characters in bit names may be encoded as hex (%XX as 81 | in URLs) 82 | - Insert mode: map g:tskelMapInsert ('', which happens to be 83 | the key on a German qwertz keyboard) to 84 | TSkeletonExpandBitUnderCursor() 85 | - New tag in skeleton bits 86 | - g:tskelKeyword_{&filetype} variable to define keywords by regexp 87 | (when 'iskeyword' isn't flexible enough) 88 | - removed the g:tskelSimpleBits option 89 | - Fixed some problems with the menu 90 | - Less use of globpath() 91 | 92 | 2.1 93 | - Don't accidentally remove torn off menus; rebuild the menu less 94 | often 95 | - Maintain insert mode (don't switch back to normal mode) in 96 | imap 97 | - If no menu support is available, use the s:Query function to let 98 | the user select among eligible bits (see also g:tskelQueryType) 99 | - Create a normal and an insert mode menu 100 | - Fixed selection of eligible bits 101 | - Ensure that g:tskelDir ends with a (back)slash 102 | - Search for 'skeletons/' in &runtimepath & set g:tskelDir accordingly 103 | - If a template is named "#.suffix", an autocmd is created 104 | automatically. 105 | - Set g:tskelQueryType to 'popup' only if gui is win32 or gtk. 106 | - Minor tweak for vim 7.0 compatibility 107 | 108 | 2.2 109 | - Don't display query menu, when there is only one eligible bit 110 | - EncodeURL.vim now correctly en/decoded urls 111 | - UTF8 compatibility -- use col() instead of virtcol() (thanks to Elliot 112 | Shank) 113 | 114 | 2.3 115 | - Support for current versions of genutils (> 2.0) 116 | 117 | 2.4 118 | - Changed the default value for g:tskelDateFormat from "%d-%b-%Y" to 119 | '%Y-%m-%d' 120 | - 2 changes to TSkeletonGoToNextTag(): use select mode (as does 121 | imaps.vim, set g:tskelSelectTagMode to 'v' to get the old behaviour), 122 | move the cursor one char to the left before searching for the next tag 123 | (thanks to M Stubenschrott) 124 | - added a few AutoIt3 skeletons 125 | - FIX: handle tabs properly 126 | - FIX: problem with filetypes containing non-word characters 127 | - FIX: check the value of &selection 128 | - Enable normal tags for late expansion 129 | 130 | 3.0 131 | - Partial rewrite for vim7 (drop vim6 support) 132 | - Now depends on tlib (vimscript #1863) 133 | - "query" now uses a more sophisticated version from autoload/tlib.vim 134 | - The default value for g:tskelQueryType is "query". 135 | - Experimental (proof of concept) code completion for vim script 136 | (already sourced user-defined functions only). Use :delf 137 | TSkelFiletypeBits_functions_vim to disable this as it can take some 138 | time on initialization. 139 | - Experimental (proof of concept) tags-based code completion for ruby. 140 | Use :delf TSkelProcessTag_ruby to disable this. It's only partially 141 | useful as it simply works on method names and knows nothing about 142 | classes, modules etc. But it gives you an argument list to fill in. It 143 | shouldn't be too difficult to adapt this for other filetypes for which 144 | such an approach could be more useful. 145 | - The code makes it now possible to somehow plug in custom bit types by 146 | defining TSkelFiletypeBits_{NAME}(dict, filetype), or 147 | TSkelFiletypeBits_{NAME}_{FILETYPE}(dict, filetype), 148 | TSkelBufferBits_{NAME}(dict, filetype), 149 | TSkelBufferBits_{NAME}_{FILETYPE}(dict, filetype). 150 | - FIX s:RetrieveAgent_read(): Delete last line, which should fix the 151 | problem with extraneous return characters in recursively included 152 | skeleton bits. 153 | - FIX: bits containing backslashes 154 | - FIX TSkeletonGoToNextTag(): Moving cursor when no tag was found. 155 | - FIX: Minibits are now properly displayed in the menu. 156 | 157 | 3.1 158 | - Tag-based code completion for vim 159 | - Made the supported skeleton types configurable via g:tskelTypes 160 | - FIX: Tag-based skeletons the name of which contain blanks 161 | - FIX: Undid shortcut that prevented the <+bit:+> tag from working 162 | - Preliminary support for using keys like for insert mode 163 | expansion. 164 | 165 | 3.2 166 | - "tags" & "functions" types are disabled by default due to a noticeable 167 | delay on initialization; add 'tags' and 'functions' to g:tskelTypes to 168 | re-enable them (with the new caching strategy, it's usable, but can 169 | produce much noise; but this depends of course on the way you handle 170 | tags) 171 | - Improved caching strategy: cache filetype bits in 172 | skeletons/cache_bits; cache buffer-specific bits in 173 | skeletons/cache_bbits/&filetype/path (set g:tskelUseBufferCache to 0 to 174 | turn this off; this speeds up things quite a lot but creates many files 175 | on the long run, so you might want to purge the cache from time to time) 176 | - embedded tags are now extracted on initialization and not 177 | when the skeleton is expanded (I'm not sure yet if it is better this 178 | way) 179 | - CHANGE: dropped support for the ~/.vim/skeletons/prefab subdirectory; 180 | you'll have to move the templates, if any, to ~/.vim/skeletons 181 | - FIX: :TSkeletonEdit, :TSkeletonSetup command-line completion 182 | - FIX: Problem with fold markers in bits when &fdm was marker 183 | - FIX: Problems with PrepareBits() 184 | - FIX: Problems when the skeletons/menu/ subdirectory didn't exist 185 | - TSkeletonExecInDestBuffer(code): speed-up 186 | - Moved functions from EncodeURL.vim to tlib.vim 187 | - Updated the manual 188 | - Renamed the skeletons/menu subdirectory to skeletons/cache_menu 189 | 190 | 3.3 191 | - New :TSkeletonEditBit command 192 | - FIX: Embedded tags in file templates didn't work 193 | 194 | 3.4 195 | - Automatically reset bits information after editing a bit. 196 | - Automatically define autocommands for templates with the form "NAME 197 | PATTERN" (where "#" in the pattern is replaced with "*"), i.e. the 198 | template file "text #%2ffoo%2f#.txt" will define a template for all new 199 | files matching "*/foo/*.txt"; the filetype will be set to "text" 200 | - These "auto templates" must be located in 201 | ~/.vim/skeletons/templates/GROUP/ 202 | - TSkeletonCB_FILENAME(), TSkeletonCB_DIRNAME() 203 | - FIX: TSkeletonGoToNextTag() didn't work properly with ### type of 204 | markers. 205 | - FIX: TSkeletonLateExpand(): tag at first column 206 | - FIX: In templates, empty lines sometimes were not inserted in the 207 | document 208 | - FIX: Build menu on SessionLoadPost event. 209 | - FIX: Protect against autocommands that move the cursor on a BufEnter 210 | event 211 | - FIX: Some special characters in the skeleton bit expansion were escaped 212 | twice with backslashes. 213 | - Require tlib 0.9 214 | - Make sure &foldmethod=manual in the scratch buffer 215 | 216 | 3.5 217 | - FIX: Minor problem with auto-templates 218 | 219 | 4.0 220 | - Renamed g:tskelPattern* variables to g:tskelMarker* 221 | - If g:tskelMarkerHiGroup is non-empty, place holders will be 222 | highlighted in this group. 223 | - Re-enable 'mini' in g:tskelTypes. 224 | - Calling TSkeletonBit with no argument, brings up the menu. 225 | - Require tlib 0.12 226 | - CHANGE: The cache is now stored in ~/vimfiles/cache/ (use 227 | tlib#cache#Filename) 228 | - INCOMPATIBLE CHANGE: Use autoload/tskeleton.vim 229 | - FIX: Problem with cache name 230 | - FIX: Problem in s:IsDefined() 231 | - FIX: TSkeletonEditBit completion didn't work before expanding a bit. 232 | - FIX: Command-line completion when tSkeleton wasn't invoked yet (and 233 | menu wasn't built). 234 | 235 | 4.1 236 | - Automatically define iabbreviations by adding [bg]:tskelAbbrevPostfix 237 | (default: '#') to the bit name (i.e., a bit with the file "foo.bar" will 238 | by default create the menu entry "TSkel.foo.bar" for the bit "bar" and 239 | the abbreviation "bar#"). If this causes problems, set 240 | g:tskelAutoAbbrevs to 0. 241 | - Bits can have a section that defines the abbreviation. 242 | - New type 'abbreviations': This will make your abbreviations accessible 243 | as a template (in case you can't remember their names) 244 | - New experimental section (a vim expression) that 245 | checks if a bit is eligible in the current context. 246 | - New <+input()+> tag. 247 | - New <+execute()+> tag. 248 | - New <+let(VAR=VALUE)+> tag. 249 | - <+include(NAME)+> as synonym for <+bit:NAME+>. 250 | - Experimental <+if()+> ... <+elseif()+> ... <+else+> ... <+endif+>, 251 | <+for(var in list)+> ... <+endfor+> tags. 252 | - Special tags <+nop+>, <+joinline+>, <+nl+> to prevent certain 253 | problems. 254 | - These special tags have to be lower case. 255 | - Made tskeleton#GoToNextTag() smarter in recognizing something like: 256 | <+/DEFAULT+>. 257 | - Defined ## and # (see g:tskelMapLeader) as 258 | visual command (the user will be queried for the name of a skeleton) 259 | - Some functions have moved and changed names. It should now be possible 260 | to plug-in custom template expanders (or re-use others). 261 | - Use append() via tlib#buffer#InsertText() to insert bits. This could 262 | cause old problems to reappear although it seems to work fine. 263 | - The markup should now be properly configurable (per buffer; you can 264 | set template-specific markers in the tskel:here_before section). 265 | - Require tlib 0.14 266 | - The default value for g:tskelUseBufferCache is 0 as many people might 267 | find the accumulation of cached information somewhat surprising. Unless 268 | you use tag/functions type of skeleton bit, it's unnecessary anyway. 269 | - Removed the dependency on genutils. 270 | - The g:tskelMarkerCursor variable was removed and replaced with 271 | g:tskelMarkerCursor_mark and g:tskelMarkerCursor_rx. 272 | 273 | 4.2 274 | - Enable <+CURSOR/foo+>. After expansion "foo" will be selected. 275 | - New (old) default values: removed 'abbreviations' from g:tskelTypes 276 | and set g:tskelAutoAbbrevs to 0 in order to minimize surprises. 277 | - Enabled tex-Skeletons for the viki filetype 278 | - FIX: Place the cursor at the end of an inserted bit that contains no 279 | cursor marker (which was the original behaviour). 280 | - Split html bits into html and html_common; the java group includes 281 | html_common. 282 | - CHANGE: Made bit names case-sensitive 283 | - NEW: select() tag (similar to the query tag) 284 | 285 | 4.3 286 | - bbcode group 287 | - tskelKeyword_{&ft} and tskelGroup_{&ft} variables can be buffer-local 288 | - Case-sensitivity can be configured via [bg]:tskelCaseSensitive and 289 | [bg]:tskelCaseSensitive_{&filetype} 290 | - Make sure tlib is loaded even if it is installed in a different 291 | rtp-directory 292 | 293 | 4.4 294 | - Make sure tlib is loaded even if it is installed in a different 295 | rtp-directory 296 | 297 | 4.5 298 | - Call s:InitBufferMenu() earlier. 299 | - C modifier: Consider _ whitespace 300 | - g:tskelMarkerExtra (extra markers for tskeleton#GoToNextTag) 301 | 302 | 4.6 303 | - Minibits: Allow single words as bit definition: "word" expands to 304 | "word<+CURSOR+>" 305 | - Require tlib 0.29 306 | 307 | 4.7 308 | - TSkeletonSetup: allow full filenames as argument 309 | - Auto templates: don't cd into the templates directory 310 | - tskeleton#ExpandBitUnderCursor(): Third argument is a dictionary. 311 | - TSkeletonMapHyperComplete() (default: ): Map a magic key that 312 | expands skeletons or, if no matching templates were found, completions, 313 | tags, words etc. 314 | - FIX: Problem with <+name/expandsion+> kind of tags when located at the 315 | beginning or end of a line 316 | - s:GetBitDefs() 317 | - Improved tskeleton#Complete() (for use as completefunc or omnifunc) 318 | - FIX: Cursor positioning after expanding templates without a <+CURSOR+> 319 | tag 320 | - Don't build the menu for tSkeleton scratch buffers 321 | 322 | 4.8 323 | - Moved the definition of some variables from plugin/tSkeleton.vim to 324 | autoload/tskeleton.vim 325 | - If g:tskelMapLeader is empty, don't define maps. 326 | - Don't build a menu if g:tskelMenuPrefix == ''. 327 | - If g:tskelDontSetup is defined and g:tskelMenuPrefix == '', 328 | autoload/tskeleton.vim won't be loaded on startup. 329 | - Don't create g:tskelBitsDir if it doesn't exist 330 | 331 | 4.9 332 | - "Mini bits": Load all .tskelmini files from the current file's 333 | directory upwards 334 | - s:InsertDefault handles <+CURSOR+> tags 335 | - tskeleton#HyperComplete_query(): Set w:tskeleton_hypercomplete 336 | - FIX: g:tskelHyperType = "pum" didn't work properly. 337 | 338 | version: "4.10" 339 | - Improved integration with stakeholders.vim 340 | - s:SelectTagMode(): CursorSet() should respect value of g:tskelSelectTagMode 341 | - tskeleton#GoToNextTag(): Missed last character for <++> tags if &sel wasn't "exclusive" 342 | - FIX: further &selection-related issues 343 | MD5 checksum: d126a6069b3d4452c0402f3db12286a0 344 | 345 | version: "4.11" 346 | - .gitignore 347 | - Don't assume users have the set of standard templates installed (distributed separatedly) 348 | MD5 checksum: b3f679c5dd30e9baca8965605ce4b364 349 | 350 | version: "4.12" 351 | - C modifier in place holders prevented parsing of subsequent modifiers (fix #3) 352 | - skeletons/README 353 | MD5 checksum: 8d2aefc5b25058d211c1f427fc564bec 354 | 355 | version: "4.13" 356 | - g:tskeleton#conceal_cchar: Conceal placeholders 357 | - Use noautocmd 358 | - Call tskeleton#PrepareBits() on FileType events 359 | - debug 360 | - s:EvalBitProcess(): Remove whole line comments (i.e. tskel:before/after sections may contain comments) 361 | - Add TSkelPlaceHolder to all syntax clusters 362 | - s:Eol(): No special treatment for insertmode 363 | - Cache syntax clusters 364 | MD5 checksum: c484c1da8c23e9abe02dde370cd094a1 365 | 366 | version: "5.00" 367 | - Support for $ENVIRONMENT_VARIABLES\n\ 368 | - tskeleton#FillIn(): Make sure folding is disabled when expanding tags\n\ 369 | - g:tskelNewBufferIsDirty: Optionally, mark new files from templates as modified\n\ 370 | - g:tskelNewBufferIsDirty: Set based on the value of &hidden\n\ 371 | - Adding user setting for a \"COMPANY\" tag.\n\ 372 | - Call TSkeletonMapGoToNextTag() if g:tskelMapGoToNextTag\n\ 373 | - The expansion of type of tags was inserted at the wrong column\n\ 374 | - tskeleton#Placeholders(): Make sure filetype is not empty\n\ 375 | - Echo v:exception when catching errors\n\ 376 | - Experimental: Also cache parsed bits/minibits\n\ 377 | - Experimental: partial support for snippets (\xC3\xA0 la snipMate)\n\ 378 | - Allow 0-9 in place holders\n\ 379 | - Use g:snippets_dir if set\n\ 380 | - snippets: slightly improved parsing\n\ 381 | - Improved support for snippets\n\ 382 | - g:tskelBitsDir is a path now (comma-separated list)\n\ 383 | - tskeleton#GoToNextTag(): support for numbered place holders\n\ 384 | - FIX: Escape menu items\n\ 385 | - FIX: tskeleton#FetchMiniBits(): undefined a:filename (after previous commit)\n\ 386 | - New defaults: enable snippets; enable stakeholders if loaded; enable g:tskelMapGoToNextTag\n\ 387 | - Move tskeleton#ProcessTag_functions_with_parentheses() to tags.vim\n\ 388 | - tskeleton#functions#FiletypeBits_vim(): Don't add items to menu\n\ 389 | - snippets: Put snippets in Snippets submenu\n\ 390 | - skeleton#GetDestBuffer(); postprocess attribute for bits => make snippet's `...` syntax work\n\ 391 | - Setup stakeholders right after inserting the snippet in the destination buffer\n\ 392 | - Replace g:tskelBitsDir with g:tskelGlobalBitsPath and g:tskelLocalBitsDirs (skeletons can be directory/project local)\n\ 393 | - g:tskelMapGoToNextTag is a key/map now\n\ 394 | - g:tskeleton#max_basename: Remove len of the cache dir name from the max filesize\n\ 395 | - FIX: Unknown variable r\n\ 396 | - tskeleton#TagRx(): better support for embedded strings\n\ 397 | - duplicate help tags (fixes #6)\n\ 398 | - addon-info\n\ 399 | - tskeleton#EditBit(): Re-enable editing non-existing bits\n\ 400 | - tskeleton#EditBit(): reset bit defs for correct filetype\n\ 401 | - tskeleton#GoToNextTag(): correct selection if &sel != exclusive (fixes #7)\n\ 402 | - tskeleton#FillIn(): Ensure &sel is \"exclusive\" (fixes #8)\n\ 403 | MD5 checksum: a87f571652f29bd910cb47fb91153094" 404 | 405 | - Help template 406 | - TSkeletonSetup: Optional bang (always fill in buffer) 407 | - FIX #9: TSkeletonSetup: doesn't require escaping whitespace 408 | - FIX #10: RetrieveBit: Chomp at most one newline (require tlib 1.10) 409 | - FIX #11: Don't include :HiLink in doc 410 | MD5 checksum: 40554c506d28c41491f3e219301829d8 411 | version: "5.01" 412 | 413 | version: "5.02" 414 | - Check version of stakeholders if g:tskeleton#enable_stakeholders is true. 415 | MD5 checksum: c7f28770f5153dd8b072d9fd2b1308ef 416 | 417 | -------------------------------------------------------------------------------- /LICENSE.TXT: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | 3 | tskeleton provides file templates and code skeletons ("snippets" or "bits"). 4 | These templates may contain special tags that are replaced with some computed 5 | value (e.g., variables, user input ...), vimscript code, or place holders/jump 6 | positions (see |tskeleton-jump-positions|). 7 | 8 | Basic usage: 9 | Type `:new filename.ext`. If a skeleton for the respective filetype is 10 | defined (see |tskeleton-skeletons|), it will be read into the buffer. 11 | 12 | Type a partial name of a snippet (at least the first letter) and press 13 | (in insert mode) (see |tskeleton-key-bindings| for alternative 14 | key maps). If the name identifies a snippet/bit, it will be replaced with 15 | its expansion text. If there are several snippets beginning with that 16 | "name", you will be asked to select one from a list of matching 17 | snippets. 18 | 19 | can be configured to expand snippets but also (albeit disabled 20 | by default) abbreviations, functions (VIM script only), tags, word, 21 | 'completefunc' and 'omnifunc' items (see |g:tskelTypes| and 22 | |g:tskelHyperComplete| for details.) 23 | 24 | Press to jump to the next place holder (see 25 | |tskeleton#GoToNextTag()|). 26 | 27 | 28 | Demo -- tskeleton and the stakeholders (vimscript #3326) plugin: 29 | http://vimsomnia.blogspot.com/2010/11/tskeleton-and-stakeholders-vim-plugins.html 30 | 31 | 32 | Git: 33 | https://github.com/tomtom/tskeleton_vim 34 | 35 | 36 | For similar plugins see: http://vim.wikia.com/wiki/Snippet_Plugin_Comparison 37 | 38 | Limitations of tskeleton: 39 | - Place holders cannot be nested. 40 | - tskeleton was originally written for vim 6.0. I'd expect it to be 41 | less snappy than more modern and simpler plugins, although it 42 | tries to provide acceptable performance on slower computers by 43 | caching frequently reused data. 44 | 45 | Advantages of tskeleton with respect to some other plugins: 46 | - tskeleton provides for more complex templates (see 47 | |tskeleton-place-holder|) including conditional expansion, loops, 48 | inclusion of other templates, user queries etc. 49 | - Easy creation of camel case, all upper/lower case letter names etc. (see 50 | |tskeleton-modifiers|). 51 | 52 | It depends: 53 | - A place holder is some text in the buffer, i.e. tskeleton uses less magic 54 | when handling jump positions. As long as users don't replace all place 55 | holders, the buffer's contents most likely isn't valid code and an 56 | interpreter/compiler will most likely refuse to load it even if the 57 | code is never executed. 58 | 59 | 60 | ----------------------------------------------------------------------- 61 | *tskeleton-install* 62 | Install~ 63 | 64 | Edit the vba file and type: 65 | 66 | :so % 67 | 68 | See :help vimball for details. 69 | 70 | It is recommended to use tskeleton in conjunction with the stakeholders plugin 71 | (vimscript #3326): 72 | 73 | http://www.vim.org/scripts/script.php?script_id=3326 74 | https://github.com/tomtom/stakeholders_vim 75 | 76 | If you don't already have some skeletons, you may want to download 77 | tskeleton-Samples.zip from: 78 | 79 | http://www.vim.org/scripts/script.php?script_id=1160 80 | 81 | or from 82 | 83 | https://github.com/tomtom/tskeletons 84 | 85 | Copy the files to your local vimfiles directory (see also |add-global-plugin|). 86 | The directory structure should look like this: 87 | 88 | ~/.vim/skeletons/ 89 | FILE TEMPLATES ... 90 | map/ 91 | MAP FILES FOR CONDITIONAL EXPANSION 92 | bits/ 93 | &filetype.txt (single line templates) 94 | general/ 95 | GENERAL CODE SKELETONS ... 96 | &filetype/ 97 | FILETYPE SPECIFIC CODE SKELETONS: ONE SKELETON PER FILE ... 98 | 99 | 100 | *tskeleton-snippets* 101 | tskeleton also provides partial support for snipMate snippets (see 102 | https://github.com/honza/snipmate-snippets). The following limitations apply: 103 | - tskeleton cannot handle nested tags/place holders 104 | 105 | 106 | *tskeleton-cache* 107 | In order to speed up things, tskeleton caches intermediate results. 108 | Those files are created in |g:tlib_cache|. By default, the old files 109 | will be removed from the cache every |g:tlib#cache#purge_every_days| 110 | days. In order to disable purging (e.g. if you purge the cache directory 111 | by means of a cron script), set |g:tlib#cache#purge_every_days| to -1. 112 | 113 | 114 | ----------------------------------------------------------------------- 115 | *tskeleton-usage* 116 | *tskeleton-skeletons* 117 | File templates~ 118 | 119 | The file skeletons are stored in the skeletons subdirectory. Which 120 | template is used for which new file is controlled by |:autocmd|s. This 121 | provides greater flexibility than a &filetype based approach as you can 122 | select templates on the basis of a filename pattern or a specific 123 | directory. 124 | 125 | Currently, the following file types are supported by default: 126 | 127 | - batch.bat 128 | - deplate.txt 129 | - latex.tex 130 | - php.inc.php 131 | - php.php 132 | - plugin.vim 133 | - ruby.rb 134 | - shell.sh 135 | - text.txt 136 | 137 | In order to add support for a new filetype, save a skeleton file to 138 | ~/.vim/skeletons/file.suffix and add something like this to your .vimrc 139 | file: > 140 | 141 | autocmd BufNewFile *.suffix TSkeletonSetup template.suffix 142 | autocmd BufNewFile /here/*.suffix TSkeletonSetup othertemplate.suffix 143 | 144 | 145 | Alternatively, you can store templates as: > 146 | 147 | ~/.vim/skeletons/templates/GROUP/FILETYPE PATTERN 148 | 149 | where GROUP is an arbitrary name for a collection of auto templates, 150 | FILETYPE is a know vim filetype, and the pattern is an encoded pattern (# == 151 | *, %XX=Char XXh) for auto-generated autocmds. 152 | 153 | Example: Templates file names for some vim-related files: > 154 | 155 | ~/.vim/skeletons/templates/vim/help #%2fvimfiles%2fdoc%2f#.txt 156 | ~/.vim/skeletons/templates/vim/vim #%2fvimfiles#%2fftplugin%2f#.vim 157 | ~/.vim/skeletons/templates/vim/vim #%2fvimfiles#%2fsyntax%2f#.vim 158 | 159 | < 160 | *tskeleton-place-holder* 161 | 162 | Tags (which look like <+...+>) serve two purposes: 163 | 164 | - marker for jump positions (see |tskeleton#GoToNextTag()|) 165 | - dynamic content expansion 166 | 167 | You can use tags to define cursor jump positions. tskeleton also 168 | supports some special tags that are expanded when inserting the 169 | skeleton. 170 | 171 | A list of special tags: 172 | *tSkeletion-<+FILE NAME ROOT+>* 173 | <+FILE NAME ROOT+> 174 | The file name root 175 | *tSkeletion-<+FILE NAME+>* 176 | <+FILE NAME+> 177 | The file name 178 | *tSkeletion-<+FILE SUFFIX+>* 179 | <+FILE SUFFIX+> 180 | The file suffix 181 | *tSkeletion-<+FILE DIRNAME+>* 182 | <+FILE DIRNAME+> 183 | The file's directory 184 | *tSkeletion-<+NOTE+>* 185 | <+NOTE+> 186 | A note 187 | *tSkeletion-<+DATE+>* 188 | <+DATE+> 189 | The current date (the format is controlled via 190 | g:tskelDateFormat) 191 | *tSkeletion-<+AUTHOR+>* 192 | <+AUTHOR+> 193 | The author's name (g:tskelUserName) 194 | *tSkeletion-<+EMAIL+>* 195 | <+EMAIL+> 196 | The author's e-mail (g:tskelUserEmail) 197 | *tSkeletion-<+COMPANY+>* 198 | <+COMPANY+> 199 | The author's company (g:tskelUserCompany) 200 | *tSkeletion-<+WEBSITE+>* 201 | <+WEBSITE+> 202 | The author's homepage (g:tskelUserWWW) 203 | *tSkeletion-<+LICENSE+>* 204 | <+LICENSE+> 205 | The name of the license this file is released under 206 | (g:tskelLicense) 207 | 208 | In order to define your own tag, you have to define a function called 209 | TSkeleton_TAGNAME() that returns the text to be filled in. 210 | 211 | *tskeleton-tags* 212 | tskeleton also supports the following pseudo-tags: 213 | 214 | <+CURSOR+> *tSkeletion-<+CURSOR+>* 215 | Where to place the cursor after insertion 216 | 217 | <+&NAME+> *tSkeletion-<+&+>* 218 | A vim option 219 | 220 | <+g:NAME+> *tSkeletion-<+g:+>* 221 | A global variable 222 | 223 | <+b:NAME+> *tSkeletion-<+b:+>* 224 | A buffer local variable 225 | 226 | <+?QUERY?+> *tSkeletion-<+?+>* 227 | Query[1] the user 228 | 229 | <+?VAR|QUERY?+> 230 | Query[1] the user and propose some choices from the variable VAR 231 | 232 | *tSkeletion-<+bit+>* 233 | <+bit:BIT+>, <+bit:BIT|"DEFAULT"+>, <+bit:BIT|COMMANDS+> 234 | Insert a bit; if the bit isn't defined for the current filetype, 235 | use DEFAULT; if DEFAULT matches ".*" insert it as a string; 236 | otherwise interpret it as a command sequence to be fed to normal 237 | 238 | <+tskel:TSKELETON+> *tSkeletion-<+tskel+>* 239 | Same as the above 240 | 241 | <+call:FUNCTION(ARGS)+> *tSkeletion-<+call+>* 242 | Insert the result value of some function 243 | 244 | <+include(TSKELETON)+> *tSkeletion-<+include+>* 245 | Another synonym for the above. 246 | 247 | <+execute(EX COMMAND)+> *tSkeletion-<+execute+>* 248 | Run a vim command. 249 | 250 | [1] If the query ends with a colon, the second question mark will be 251 | removed. Up to verson 2.4 VAR is a string, separating the items by an 252 | "\n". From 3.0 on, VAR is a list. 253 | 254 | NOTE: Flow control and loop tags are experimental and it's more than 255 | just likely that the output doesn't meet your expectations. 256 | 257 | Flow control: *tSkeletion-<+if+>* 258 | <+if(CONDITION)+> 259 | <+elseif(CONDITION)+> 260 | <+else+> 261 | <+endif+> 262 | 263 | Loops: *tSkeletion-<+for+>* 264 | <+for(VAR in LIST)+> 265 | <+endfor+>, <+endfor(VAR)+> 266 | If you nest for loops, you have to add the variable name to the 267 | endfor tag. And no, this isn't the most clever way to do this. 268 | 269 | Variables: *tSkeletion-<+let+>* 270 | <+let(VAR=VALUE)+> 271 | The variable will be unset or restored to its original value 272 | after processing the current template. 273 | VAR may have some modifiers attached: 274 | VAR? ... Set only if undefined 275 | VAR& ... Don't restore original variable 276 | 277 | Interaction: *tSkeletion-<+input+>* 278 | <+input(VAR, QUERY, [DEFAULT], [COMPLETION])+> 279 | This will insert the user input and set the variable VAR (unless 280 | empty), which can be used throughout the template. The variable 281 | will be removed after finishing the current template. If the 282 | variable was previously defined, the original value will be 283 | restored. 284 | If VAR ends with '!', no text will be inserted in the buffer. In 285 | this case any whitespace (including one newline) after the tag 286 | will be removed. See also the notes on |tSkeletion-<+input+>|. 287 | 288 | *tSkeletion-<+select+>* 289 | <+select(VAR, LIST, [TYPE='s'], [SEPARATOR=', '])+> 290 | Let the user select an item from a list. 291 | VAR is a string. 292 | TYPE is either 's' (single selection) or 'm' (multiple selection) -- 293 | see also |tlib#input#List()|. 294 | If TYPE is 'm', the results are joined with SEPARATOR. 295 | Example: > 296 | before(<+select("s:type", [":all", ":each"])+>) 297 | before(<+select("s:type", ["A", "B", "C", "D"], "m", "-")+>) 298 | < 299 | 300 | Other: *tSkeletion-<+nl+>* 301 | <+nl+> 302 | Insert a newline 303 | 304 | <+joinline+> *tSkeletion-<+joinline+>* 305 | Join with next line. Delete any whitespace. 306 | 307 | <+nop+> *tSkeletion-<+nop+>* 308 | Insert nothing (could be necessary in conjunction with the "for" 309 | tag) 310 | 311 | A wiki like table could then be constructed using a skeleton like this: > 312 | 313 | 314 | let s:my_rows = input('Rows: ') 315 | let s:my_cols = input('Columns: ') 316 | 317 | 318 | unlet! s:my_rows s:my_cols 319 | 320 | <+CURSOR+><+for(i in range(s:my_rows))+> 321 | |<+for(j in range(s:my_cols))+> <+CELL+> |<+endfor(j)+><+nop+> 322 | <+endfor(i)+> 323 | 324 | or: > 325 | 326 | <+input('s:my_rows?!', 'Rows: ')+> 327 | <+input('s:my_cols?!', 'Cols: ')+> 328 | <+for(i in range(s:my_rows))+> 329 | |<+for(j in range(s:my_cols))+> <+CURSOR+> |<+endfor(j)+><+nop+> 330 | <+endfor(i)+> 331 | 332 | NOTE: The <+nop+> is necessary in order to prevent the <+endfor+> tag to 333 | "eat" the newline. If we include this bit from another bit that already 334 | sets s:my_rows and/or s:my_cols, the user won't be queried again (because of 335 | the "?" in the input statement). E.g. > 336 | 337 | <+let(s:my_rows = 3)+> 338 | <+let(s:my_cols = 3)+> 339 | <+include(table)+> 340 | 341 | *tSkeletion-backslash* 342 | Any special tag can be preceded with a backslash in order to prevent 343 | expansion. Examples: > 344 | 345 | <+\if(foo=1)+> 346 | 347 | surprisingly expands to > 348 | 349 | <+if(foo=1)+> 350 | 351 | It's best to use global variables with "if" and "for" tags as the body 352 | is most likely evaluated in a different buffer in a hypothetically 353 | unknown context. 354 | 355 | 356 | *tskeleton-jump-positions* 357 | Unknown tags are kept in the expanded skeleton. These tags can be used 358 | as cursor jump marks. This syntax was originally used by imap (vimscript 359 | #244 or vimscript #475). If you don't want to install imap, you can also 360 | use |TSkeletonMapGoToNextTag()|. 361 | 362 | Nameless tags (<++>) will disappear when they are selected. 363 | 364 | Example:> 365 | 366 | case <+CURSOR+> in 367 | <+PATTERN+>) 368 | <+BODY+> 369 | ;; 370 | *) 371 | <+DEFAULT+> 372 | ;; 373 | esac 374 | <++> 375 | 376 | When you insert this skeleton, the cursor will be placed at 377 | "<+CURSOR+>". If you press , the cursor will jump to "<+PATTERN+>" 378 | (the tag will remain selected). If you press three times, the 379 | cursor will jump to "<++>" (the tag will be deleted). 380 | 381 | Check out the "test_tskeleton" skeleton for examples. 382 | 383 | 384 | *tskeleton-modifiers* 385 | Tags can be modified using modifiers, like in: > 386 | 387 | <+TAG NAME:MODIFIER+> 388 | 389 | Known modifiers: 390 | 391 | l :: lower case 392 | u :: upper case 393 | c :: capitalize 394 | C :: transform to CamelCase 395 | s/FROM/TO/ :: replace text (actually a s//g); this has to be the 396 | last modifier; the pattern separator can be selected 397 | arbitrarily 398 | 399 | Example for a ruby class template: > 400 | 401 | class <+FILE NAME ROOT:cs*\W*_*+> 402 | <+CURSOR+> 403 | end 404 | <++> 405 | 406 | ----------------------------------------------------------------------- 407 | *tskeleton-code-skeletons* 408 | *tskeleton-bits* 409 | Bits/Code Skeletons~ 410 | 411 | Smaller skeleton bits are stored in SKELETONS/bits/FILETYPE/ or 412 | SKELETONS/bits/general/. I.e., code skeletons can be filetype specific 413 | or generally available. 414 | 415 | The filenames of the bits may be grouped in submenus as in: 416 | 417 | ../tex/&Define.%5Cnew&command 418 | ../tex/&Define.%5Cnew&environment 419 | 420 | This will create skeletons for \newcommand and \newenvironment but will 421 | group the skeletons under the TSkel.Define. menu with the respective 422 | accelerators. 423 | 424 | *tskeleton-Types* *g:tskelTypes* 425 | *tskeleton#Initialize()* 426 | tskeleton supports several types of code templates: 427 | 428 | - skeleton (standard tskeleton functionality) 429 | - abbreviations (VIM abbreviations) 430 | - functions (VIM script functions extracted from :function) 431 | - mini ("mini" bits, one-liners etc.) 432 | - tags (tags-based code templates, requires ctags, I presume) 433 | 434 | Not all types are enabled by default. User have to select, which types 435 | they want to use, by setting the g:tskelTypes at start-up. When changing 436 | the variable, users might have to call tskeleton#Initialize(). 437 | 438 | *tskeleton-Skeleton* 439 | Smaller skeleton bits are stored in SKELETONS/bits/FILETYPE/ or 440 | SKELETONS/bits/general/. I.e., code skeletons can be filetype specific 441 | or generally available. 442 | 443 | Skeleton bits can be filled in by typing: > 444 | 445 | :TSkeletonBit NAME 446 | 447 | For this command, command line completion is implemented. Calling this 448 | command will insert the contents of the respective file below the 449 | current line. 450 | 451 | NOTE: Bit names should not contain ampersand (as these are interpreted 452 | as menu accelerators) and periods (which are used to construct 453 | submenus). Other special characters can be included by encoding them in 454 | hex form as %XX as it is done in URLs. Example: "%5Csection" becomes 455 | "\section". 456 | 457 | *tskeleton-key-bindings* 458 | The default key bindings for inserting code skeletons are: 459 | 460 | ... In insert mode, expand name before the cursor 461 | ## ... Expand name under cursor 462 | #t ... Insert code skeleton via command line 463 | ... In insert mode, expand the bit before the cursor (on 464 | a German keyboard this happens to be ) 465 | 466 | *g:tskelKeyword_{&filetype}* 467 | A bit name usually is the |word| under the cursor. If this doesn't fit 468 | your needs, you can define g:tskelKeyword_{&filetype} to define what 469 | makes up a skeleton name. Example: > 470 | 471 | let g:tskelKeyword_viki = '\(#\|{\)\?[^#{[:blank:]]\{-}' 472 | 473 | 474 | *tskeleton-embedded-code* 475 | Code skeletons may contain vim code that is evaluated before or after 476 | expanding the tags. The before/after blocks are fed to |:exec| and must 477 | not contain function definitions. 478 | 479 | NOTE: The "parser" is quite primitive. These tags have to start as 480 | single statement in a line at column 1, and they have to appear in the 481 | following order: 482 | 483 | ** 484 | Display an explanatory message after template expansion 485 | 486 | ** 487 | Execute code before template expansion in the target buffer 488 | 489 | ** 490 | Execute code after template expansion in the target buffer 491 | 492 | ** 493 | Execute code before template expansion in the template buffer 494 | 495 | ** 496 | Execute code after template expansion in the template buffer 497 | 498 | ** 499 | Make the bit available via |:abbreviate| under the enclosed name. 500 | 501 | ** 502 | Use this menu name instead of the default one. 503 | 504 | ** 505 | An expression that checks whether a bit is eligible in the 506 | current context. 507 | 508 | BibTeX example: > 509 | 510 | 511 | Insert a collection entry 512 | 513 | 514 | let b:tskelArticleID = input("ID of bibentry: ") 515 | if b:tskelArticleID == "" | let b:tskelArticleID = "<+CURSOR+>" | endif 516 | 517 | 518 | unlet b:tskelArticleID 519 | 520 | @INCOLLECTION{<+b:tskelArticleID+>, 521 | author = {<+CURSOR+>}, 522 | title = {<+ARTICLE TITLE+>}, 523 | crossref = {<+CROSSREF+>}, 524 | pages = {<+PAGES+>}, 525 | abstract = {[[~/Docs/Abstracts/<+b:tskelArticleID+>.txt]]}, 526 | } 527 | <++> 528 | 529 | In the above example, we query the user for an ID and insert this ID as 530 | entry key and as an abstract's file name. 531 | 532 | The before/after blocks are evaluated in the destination buffer. The 533 | variants here_before/here_after are evaluated in the scratch buffer for 534 | the current code skeleton. 535 | 536 | *tskeleton-groups* 537 | *g:tskelBitGroup_{&filetype}* 538 | Groups~ 539 | 540 | Some filetype's bits might be of use for other filetypes too. You can 541 | make them accessible by defining a g:tskelBitGroup_{&filetype} variable. 542 | E.g., in php mode all html bits are made accessible by setting this 543 | variable (the default): > 544 | 545 | let g:tskelBitGroup_php = ['php', 'html'] 546 | 547 | Bits of type "general" are always available. 548 | 549 | *tskeleton-context* 550 | *tskeleton-map* 551 | Maps -- Context-sensitive expansion~ 552 | 553 | To some extent, tskeleton is capable of offering the user only a small 554 | selection of eligible bits for a specific context if a map file 555 | ($VIMFILES/skeletons/map/{&filetype}) is provided. Such a map file is made up 556 | of regular expressions matching a specific context (before the cursor 557 | only) and a blank-separated list of eligible bits. The regexp and the 558 | list are separated by whitespace: > 559 | 560 | REGEXP BIT1 BIT2 ... BITn 561 | 562 | Example: > 563 | 564 | ]\\|\\n\\)* name= action= method= 565 | 566 | If an eligible bit is undefined, the name is inserted as is. I.e. you 567 | don't have to define skeletons for all these options and argument names. 568 | 569 | 570 | *tskeleton-minibits* 571 | Minibits~ 572 | 573 | Mini bits are kept in the files: 574 | 575 | - $CWD/.tskelmini 576 | - $VIMFILES/skeletons/bits/{&filetype}.txt 577 | 578 | These files contain whitespace-separated pairs of bit names and their 579 | expansions. These files are meant to keep expansions of accronyms and 580 | abbreviations and the like. Example: > 581 | 582 | IMHO In my humble opinion 583 | AFAIK As far as I know 584 | 585 | *tskeleton-menu* 586 | *g:tskelMenuPrefix* 587 | Menu~ 588 | 589 | If g:tskelMenuPrefix is non-empty, tskeleton will display a menu 590 | containing all eligible bits for a certain filetype. 591 | 592 | The menu can be hierarchical and certain entries may have shortcuts by 593 | properly naming the bits. Example: > 594 | 595 | &Environment.&Quote 596 | &Environment.Q&uotation 597 | 598 | This will create the submenu "Environment" that can be selected by 599 | typing "e" (on Windows) and two entries, the first of which can be 600 | selected by typing "q" and the second by typing "u". 601 | 602 | Be aware that the actual bit names are Quote and Quotation (i.e. the 603 | submenu and the ampersand are stripped off). 604 | 605 | 606 | ----------------------------------------------------------------------- 607 | *tskeleton-utilities* 608 | Utilities~ 609 | 610 | *tskeleton#IncreaseRevisionNumber()* 611 | The function tskeleton#IncreaseRevisionNumber() provides a way to 612 | automatically update a revision number in the form > 613 | 614 | @Revision: 1.0.393 615 | 616 | In order to use this function, add something like this to your |vimrc| 617 | file: > 618 | 619 | autocmd BufWritePre * call tskeleton#IncreaseRevisionNumber() 620 | 621 | *:TSkeletonCleanUpBibEntry* 622 | The TSkeletonCleanUpBibEntry command can be used to purge the current bibtex 623 | entry from expendable fields (i.e., lines matching <+.\{-}+>). 624 | 625 | For bibtex files, this command is bound to: tc 626 | 627 | *TSkeletonMapGoToNextTag()* 628 | *tskeleton#GoToNextTag()* 629 | If g:tskelMapGoToNextTag is true, the map will be enabled. (That 630 | is the key that was also used by the imaps.vim plugin.) Press to 631 | jump between tags. 632 | 633 | This function provides one or two extras over the version of imaps.vim. 634 | An explanation: 635 | 636 | - ###, +++, ???, !!! are used as markers too. 637 | - If a marker is empty (e.g. <++>), the marker will be removed (as 638 | imaps.vim does). 639 | - If a marker matches <+NAME/DEFAULT+>, the marker will be replaced 640 | with DEFAULT. 641 | - If a snippet contains numbered placeholders (e.g. <+1+>), these 642 | will be selected first in increasing number. 643 | 644 | 645 | 646 | 647 | Dependencies: 648 | tlib (>= 1.10) :: http://github.com/tomtom/tlib_vim 649 | 650 | License: GPLv3 or later 651 | 652 | 653 | -------------------------------------------------------------------------------- /addon-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "tskeleton", 3 | "version" : "dev", 4 | "author" : "Tom Link ", 5 | "maintainer" : "Tom Link ", 6 | "repository" : {"type": "git", "url": "git://github.com/tomtom/tskeleton_vim.git"}, 7 | "dependencies" : { 8 | "tlib": {"type": "git", "url": "git://github.com/tomtom/tlib_vim.git"} 9 | }, 10 | "description" : "tskeleton -- File Templates and Code Skeletons" 11 | } 12 | -------------------------------------------------------------------------------- /autoload/tskeleton/abbreviations.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @Website: http://www.vim.org/account/profile.php?user_id=4037 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Revision: 63 5 | 6 | 7 | function! tskeleton#abbreviations#Reset() "{{{3 8 | let s:abbrevs = tlib#cmd#OutputAsList('abbrev') 9 | endf 10 | 11 | 12 | function! tskeleton#abbreviations#Initialize() "{{{3 13 | call tskeleton#abbreviations#Reset() 14 | endf 15 | 16 | 17 | function! tskeleton#abbreviations#GetAbbreviations() "{{{3 18 | if !exists('s:abbrev') 19 | call tskeleton#abbreviations#Reset() 20 | endif 21 | return s:abbrev 22 | endf 23 | 24 | 25 | function! tskeleton#abbreviations#BufferBits(dict, filetype) "{{{3 26 | call filter(s:abbrevs, 'v:val =~ ''^[i!]''') 27 | let rx = '^\(.\)\s\+\(\S\+\)\s\+\(.\+\)$' 28 | for abbr in sort(s:abbrevs) 29 | let matches = matchlist(abbr, rx) 30 | " TLogVAR abbr, rx, matches 31 | let name = matches[2] 32 | " TLogVAR name 33 | " TLogDBG has_key(a:dict, name.g:tskelAbbrevPostfix) 34 | let text = matches[3] 35 | if text !~ printf(tlib#rx#Escape(tskeleton#ExpandedAbbreviationTemplate()), '.\{-}') 36 | let a:dict[name] = { 37 | \ 'text': text, 38 | \ 'abbrev_type': matches[1], 39 | \ 'abbrev': '', 40 | \ 'menu': 'Abbreviation.'. escape(name, '.\'), 41 | \ 'type': 'abbreviations' 42 | \ } 43 | endif 44 | endfor 45 | endf 46 | 47 | 48 | function! tskeleton#abbreviations#Retrieve(bit, indent, ft) "{{{3 49 | let def = tskeleton#BitDef(a:bit) 50 | let text = def.text 51 | " let text .= tskeleton#CursorMarker() 52 | " TLogVAR a:bit, a:def 53 | " if text[0] == '@' 54 | " exec 'norm! i'. text[1:-1] 55 | " else 56 | " exec 'norm! i'. text 57 | " endif 58 | exec 'norm i'. a:bit 59 | call tlib#buffer#InsertText0(tskeleton#CursorMarker()) 60 | return line('.') 61 | endf 62 | 63 | 64 | -------------------------------------------------------------------------------- /autoload/tskeleton/completefunc.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @Website: http://www.vim.org/account/profile.php?user_id=4037 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Revision: 13 5 | 6 | 7 | function! tskeleton#completefunc#Initialize() "{{{3 8 | endf 9 | 10 | 11 | function! tskeleton#completefunc#FiletypeBits(dict, type) "{{{3 12 | " TAssert IsDictionary(a:dict) 13 | " TAssert IsString(a:type) 14 | call tskeleton#Complete_use_completefunc('', a:dict) 15 | endf 16 | 17 | -------------------------------------------------------------------------------- /autoload/tskeleton/functions.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @Website: http://www.vim.org/account/profile.php?user_id=4037 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Revision: 7 5 | 6 | 7 | function! tskeleton#functions#Initialize() "{{{3 8 | endf 9 | 10 | 11 | function! tskeleton#functions#FiletypeBits_vim(dict, filetype) "{{{3 12 | " TAssert IsDictionary(a:dict) 13 | " TAssert IsString(a:filetype) 14 | let fnl = tlib#cmd#OutputAsList('fun') 15 | call map(fnl, 'matchstr(v:val, ''^\S\+\s\+\zs.\+$'')') 16 | call filter(fnl, 'v:val[0:4] != ''''') 17 | for f in sort(fnl) 18 | let fn = matchstr(f, '^.\{-}\ze(') 19 | let fr = substitute(f, '(\(.\{-}\))$', '\=tskeleton#ReplacePrototypeArgs(submatch(1), ''\V...'')', "g") 20 | " TLogDBG fn ." -> ". fr 21 | " let a:dict[fn] = {'text': fr, 'menu': 'Function.'. fn, 'type': 'tskeleton'} 22 | let a:dict[fn] = {'text': fr, 'type': 'tskeleton'} 23 | endfor 24 | endf 25 | 26 | 27 | -------------------------------------------------------------------------------- /autoload/tskeleton/mini.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @Website: http://www.vim.org/account/profile.php?user_id=4037 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Revision: 19 5 | 6 | 7 | function! tskeleton#mini#Initialize() "{{{3 8 | endf 9 | 10 | 11 | function! tskeleton#mini#FiletypeBits(dict, type) "{{{3 12 | " TLogVAR a:dict, a:type 13 | let files = findfile('.tskelmini', expand('%:p:h') .';', -1) 14 | " TLogVAR files 15 | for file in reverse(files) 16 | " TLogVAR file 17 | call tskeleton#FetchMiniBits(a:dict, '', file, 1) 18 | endfor 19 | endf 20 | 21 | 22 | -------------------------------------------------------------------------------- /autoload/tskeleton/omnicomplete.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @Website: http://www.vim.org/account/profile.php?user_id=4037 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Revision: 16 5 | 6 | 7 | function! tskeleton#omnicomplete#Initialize() "{{{3 8 | endf 9 | 10 | 11 | function! tskeleton#omnicomplete#FiletypeBits(dict, type) "{{{3 12 | " TAssert IsDictionary(a:dict) 13 | " TAssert IsString(a:type) 14 | call tskeleton#Complete_use_omnifunc('', a:dict) 15 | endf 16 | 17 | 18 | -------------------------------------------------------------------------------- /autoload/tskeleton/skeleton.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @Website: http://www.vim.org/account/profile.php?user_id=4037 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Revision: 61 5 | 6 | 7 | function! tskeleton#skeleton#Initialize() "{{{3 8 | endf 9 | 10 | function! tskeleton#skeleton#FiletypeBits(dict, type) "{{{3 11 | " TLogVAR a:type 12 | " TAssert IsDictionary(a:dict) 13 | " TAssert IsString(a:type) 14 | call tskeleton#FetchMiniBits(a:dict, tskeleton#BitsPath(), a:type .'.txt', 0) 15 | call s:ScanPath(a:dict, a:type, tskeleton#BitsPath()) 16 | endf 17 | 18 | 19 | function! tskeleton#skeleton#BufferBits(dict, type) "{{{3 20 | " TLogVAR a:type 21 | if !exists('b:tskel_bufferbits_path') 22 | let b:tskel_bufferbits_path = '' 23 | for dir0 in g:tskelLocalBitsDirs 24 | let dirs1 = finddir(dir0, '.;', -1) 25 | " TLogVAR dirs1 26 | let dirs1 = map(dirs1, 'escape(fnamemodify(v:val, ":p"), ",")') 27 | let dirs = join(dirs1, ',') 28 | if empty(b:tskel_bufferbits_path) 29 | let b:tskel_bufferbits_path = dirs 30 | else 31 | let b:tskel_bufferbits_path .= ','. dirs 32 | endif 33 | endfor 34 | endif 35 | if !empty(b:tskel_bufferbits_path) 36 | call s:ScanPath(a:dict, a:type, b:tskel_bufferbits_path) 37 | endif 38 | endf 39 | 40 | 41 | function! s:ScanPath(dict, type, path) "{{{3 42 | let bf = s:GlobBits(a:path, a:type, 2) 43 | " let cx = tskeleton#CursorMarker('rx') 44 | " let cm = tskeleton#CursorMarker() 45 | for f in bf 46 | " TLogVAR f 47 | if !isdirectory(f) && filereadable(f) 48 | let cache_name = tskeleton#MaybePathshorten(f) 49 | let cfile = tlib#cache#Filename('tskel_skel', tlib#url#Encode(cache_name), 1) 50 | let ftime = getftime(f) 51 | let bitdef = tlib#cache#Value(cfile, 'tskeleton#skeleton#Generator', ftime, [f], {'in_memory': g:tskeleton#use_in_memory_cache}) 52 | " TLogVAR bitdef 53 | let a:dict[bitdef.cname] = bitdef 54 | endif 55 | endfor 56 | endf 57 | 58 | 59 | function! tskeleton#skeleton#Generator(filename) "{{{3 60 | let fname = fnamemodify(a:filename, ":t") 61 | let [cname, mname] = tskeleton#PurifyBit(fname) 62 | " TLogVAR cname 63 | let body = join(readfile(a:filename), "\n") 64 | let [body, meta] = tskeleton#ExtractMeta(body) 65 | " if body !~ cx 66 | " let body .= cm 67 | " endif 68 | if has_key(meta, 'menu') && !empty(meta.menu) 69 | let mname = meta.menu 70 | endif 71 | return {'cname': cname, 'text': body, 'menu': mname, 'meta': meta, 'bitfile': a:filename, 'type': 'tskeleton'} 72 | endf 73 | 74 | 75 | " s:GlobBits(path, ?mode=1) 76 | function! s:GlobBits(path, type, ...) "{{{3 77 | let mode = a:0 >= 1 ? a:1 : 1 78 | let pt = a:type .'/*' 79 | let rvs = globpath(a:path, pt) 80 | let rvs = substitute(rvs, '\\', '/', 'g') 81 | let rv = sort(split(rvs, "\n")) 82 | let stop_rx = tlib#var#Get('tskelBitsIgnore', 'bg') 83 | if !empty(stop_rx) 84 | call filter(rv, 'v:val !~ stop_rx') 85 | endif 86 | if mode == 0 87 | call map(rv, 'fnamemodify(v:val, ":t")') 88 | elseif mode == 1 89 | call map(rv, 'tskeleton#PurifyBit(fnamemodify(v:val, ":t"))[0]') 90 | elseif mode == 2 91 | else 92 | echoerr 'tSkeleton: Unknown mode: '. mode 93 | endif 94 | " TAssert IsList(rv) 95 | return rv 96 | endf 97 | 98 | 99 | -------------------------------------------------------------------------------- /autoload/tskeleton/snippets.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 3 | " @Revision: 106 4 | 5 | let s:version = 1 6 | 7 | if !exists('g:tskeleton#snippets#force') 8 | " If true, allow snippets to overwrite other skeletons. 9 | let g:tskeleton#snippets#force = 0 "{{{2 10 | endif 11 | 12 | 13 | function! tskeleton#snippets#Initialize() "{{{3 14 | if !exists('#tSkeleton#BufWritePost#*.snippets,*.snippet') 15 | autocmd tSkeleton BufWritePost *.snippets,*.snippet call tskeleton#snippets#FiletypeBits({}, expand('%:t:r')) 16 | endif 17 | endf 18 | 19 | 20 | function! tskeleton#snippets#FiletypeBits(dict, type) "{{{3 21 | " TLogVAR a:type 22 | " TAssert IsDictionary(a:dict) 23 | " TAssert IsString(a:type) 24 | let type = a:type == 'general' ? '_' : a:type 25 | let bf = split(globpath(&rtp, 'snippets/'. type .'.snippets'), '\n') 26 | let bf = map(bf, 'fnamemodify(v:val, ":p")') 27 | if exists('g:snippets_dir') 28 | " TLogVAR g:snippets_dir 29 | let sfiles = split(globpath(g:snippets_dir, 'snippets/'. type .'.snippets'), '\n') 30 | " TLogVAR sfiles 31 | for sfile in sfiles 32 | let sfile = fnamemodify(sfile, ':p') 33 | if index(bf, sfile) == -1 34 | call add(bf, sfile) 35 | endif 36 | endfor 37 | endif 38 | " let cx = tskeleton#CursorMarker('rx') 39 | " let cm = tskeleton#CursorMarker() 40 | for f in bf 41 | " TLogVAR f 42 | if !isdirectory(f) && filereadable(f) 43 | let cache_name = s:version .'_'. tskeleton#MaybePathshorten(f) 44 | let cfile = tlib#cache#Filename('tskel_snip', tlib#url#Encode(cache_name), 1) 45 | let ftime = getftime(f) 46 | let snippets = tlib#cache#Value(cfile, 'tskeleton#snippets#Generator', ftime, [f], {'in_memory': g:tskeleton#use_in_memory_cache}) 47 | " TLogVAR snippets 48 | call extend(a:dict, snippets, g:tskeleton#snippets#force ? 'force' : 'keep') 49 | endif 50 | endfor 51 | endf 52 | 53 | 54 | function! tskeleton#snippets#Generator(filename) "{{{3 55 | let snippets = {} 56 | let lines = readfile(a:filename) 57 | let def = {} 58 | let indent = '' 59 | let state = 'find' 60 | let max = len(lines) 61 | let lnum = 0 62 | while lnum < max 63 | let line = lines[lnum] 64 | " TLogVAR state, lnum, line 65 | if state == 'find' 66 | if line =~ '^#' 67 | " ignore 68 | elseif line =~ '^snippet\s' 69 | let ml = matchlist(line, '^snippet!\?\s\+\(\S\+\)\%(\s\+\(.\+\)\)\?$') 70 | if empty(ml) 71 | echohl WarningMsg 72 | echom 'tskeleton#snippets: Cannot parse snippet:' line 73 | echohl NONE 74 | else 75 | let name = ml[1] 76 | let mname = escape(empty(ml[2]) ? name : ml[2], '.') 77 | " TLogVAR name, mname 78 | let def = { 79 | \ 'cname': name, 80 | \ 'menu': 'Snippets.'. mname, 81 | \ 'mname': mname, 82 | \ 'text': '', 83 | \ 'type': 'tskeleton', 84 | \ 'meta': {}, 85 | \ 'preprocess': 'tskeleton#snippets#Preprocess', 86 | \ 'bitfile': a:filename 87 | \ } 88 | let state = 'PARSE' 89 | endif 90 | else 91 | " shouldn't be here 92 | endif 93 | elseif state ==? 'parse' 94 | if line =~ '^\s' || empty(line) 95 | if state ==# 'PARSE' 96 | " let s:first_pos = 1 97 | let state = 'parse' 98 | let indent = matchstr(line, '^\s\+') 99 | endif 100 | let pre = empty(def.text) ? '' : "\n" 101 | let body = s:ConvertSnippet(strpart(line, strlen(indent))) 102 | let def.text .= pre . body 103 | else 104 | if !empty(def) 105 | " TLogVAR def 106 | let snippets[def.cname] = def 107 | endif 108 | let state = 'find' 109 | let lnum -= 1 110 | endif 111 | endif 112 | let lnum += 1 113 | endwh 114 | if !empty(def) 115 | " TLogVAR def 116 | let snippets[def.cname] = def 117 | endif 118 | " TLogVAR snippets 119 | return snippets 120 | endf 121 | 122 | 123 | function! s:ConvertSnippet(line) "{{{3 124 | " TLogVAR a:line 125 | let line = substitute(a:line, 126 | \ '\$\(\([0-9]\)$\|\([0-9]\)\|{\([0-9]\)}$\|{\([0-9]\)}\|{\([0-9]:[^}]\+\)}$\|{\([0-9]:[^}]\+\)}\)', 127 | \ '\=s:ConvertPos(a:line, submatch(2), submatch(3), submatch(4), submatch(5), submatch(6), submatch(7))', 128 | \ 'g') 129 | return line 130 | endf 131 | 132 | 133 | function! s:ConvertEval(arg) "{{{3 134 | return printf('<+call:eval(%s)+>', string(a:arg)) 135 | endf 136 | 137 | 138 | function! Filename(...) "{{{3 139 | let bufnr = tskeleton#GetDestBuffer() 140 | let rv = bufnr == -1 ? expand('%:t:r') : fnamemodify(bufname(bufnr), ':t:r') 141 | if a:0 > 0 142 | if !empty(a:1) 143 | let rv = substitute(a:1, '\$1', escape(rv, '\&~'), 'g') 144 | elseif a:0 >= 2 145 | let rv = a:2 146 | endif 147 | endif 148 | return rv 149 | endf 150 | 151 | 152 | function! s:ConvertPos(line, simpleeol, simple, exteol, ext, extnoteeol, extnote) "{{{3 153 | " TLogVAR a:simpleeol, a:simple, a:exteol, a:ext, a:extnoteeol, a:extnote 154 | if !empty(a:simpleeol) 155 | " return '<++>' 156 | return printf('<+%s+>', s:Name(a:simple)) 157 | elseif !empty(a:simple) 158 | return printf('<+%s+>', s:Name(a:simple)) 159 | elseif !empty(a:exteol) 160 | " return '<++>' 161 | return printf('<+%s+>', s:Name(a:exteol)) 162 | elseif !empty(a:ext) 163 | return printf('<+%s+>', s:Name(a:ext)) 164 | elseif !empty(a:extnoteeol) 165 | " return printf('<+/%s+>', matchstr(a:extnoteeol, '^\d\+:\zs.*$')) 166 | return printf('<+%s/%s+>', s:Name(matchstr(a:extnoteeol, '^\d\+')), matchstr(a:extnoteeol, '^\d\+:\zs.*$')) 167 | elseif !empty(a:extnote) 168 | return printf('<+%s/%s+>', s:Name(matchstr(a:extnote, '^\d\+')), matchstr(a:extnote, '^\d\+:\zs.*$')) 169 | else 170 | throw "tskeleton/Snippets: Internal error when parsing ". a:line 171 | endif 172 | endf 173 | 174 | 175 | function! s:Name(num) "{{{3 176 | if a:num == 1 177 | return 'CURSOR' 178 | else 179 | return a:num 180 | endif 181 | endf 182 | 183 | 184 | function! tskeleton#snippets#Preprocess(text) "{{{3 185 | sandbox let text = substitute(a:text, '`\([^`]\+\)`', '\=eval(submatch(1))', 'g') 186 | return text 187 | endf 188 | 189 | 190 | -------------------------------------------------------------------------------- /autoload/tskeleton/tags.vim: -------------------------------------------------------------------------------- 1 | " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) 2 | " @Website: http://www.vim.org/account/profile.php?user_id=4037 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Revision: 18 5 | 6 | 7 | let s:tag_defs = {} 8 | 9 | 10 | function! tskeleton#tags#Initialize() "{{{3 11 | endf 12 | 13 | 14 | function! s:SortBySource(a, b) 15 | let ta = s:sort_tag_defs[a:a] 16 | let tb = s:sort_tag_defs[a:b] 17 | let fa = ta.source 18 | let fb = tb.source 19 | if fa == fb 20 | return ta.menu == tb.menu ? 0 : ta.menu > tb.menu ? 1 : -1 21 | else 22 | return fa > fb ? 1 : -1 23 | endif 24 | endf 25 | 26 | 27 | function! s:SortByFilename(tag1, tag2) 28 | let f1 = a:tag1['filename'] 29 | let f2 = a:tag2['filename'] 30 | return f1 == f2 ? 0 : f1 > f2 ? 1 : -1 31 | endf 32 | 33 | 34 | function! tskeleton#tags#BufferBits(dict, filetype) "{{{3 35 | " TAssert IsDictionary(a:dict) 36 | " TAssert IsString(a:filetype) 37 | " TLogVAR a:filetype 38 | if exists('*tskeleton#tags#Process_'. a:filetype) 39 | let td_id = join(map(tagfiles(), 'fnamemodify(v:val, ":p")'), '\n') 40 | " TLogVAR td_id 41 | if !empty(td_id) 42 | let tag_defs = get(s:tag_defs, td_id, {}) 43 | " TLogDBG len(tag_defs) 44 | if empty(tag_defs) 45 | echom 'tSkeleton: Building tags menu for '. expand('%') 46 | let tags = taglist('.') 47 | call sort(tags, 's:SortByFilename') 48 | call filter(tags, 'tskeleton#tags#Process_{a:filetype}(tag_defs, v:val)') 49 | let s:tag_defs[td_id] = tag_defs 50 | echo 51 | redraw 52 | endif 53 | call extend(a:dict, tag_defs, 'keep') 54 | let menu_prefix = tlib#var#Get('tskelMenuPrefix_tags', 'bg') 55 | if !empty(menu_prefix) 56 | let s:sort_tag_defs = tag_defs 57 | let tagnames = sort(keys(tag_defs), 's:SortBySource') 58 | " TLogVAR tagnames 59 | " call filter(tagnames, 'tskeleton#NewBufferMenuItem(b:tskelBufferMenu, v:val)') 60 | call filter(tagnames, 'tskeleton#NewBufferMenuItem(b:tskelBufferMenu, v:val)') 61 | endif 62 | endif 63 | endif 64 | endf 65 | 66 | 67 | function! tskeleton#tags#Process_vim(dict, tag) 68 | return s:ProcessTag_functions_with_parentheses('f', a:dict, a:tag, '\V...') 69 | endf 70 | 71 | 72 | function! tskeleton#tags#Process_ruby(dict, tag) 73 | return s:ProcessTag_functions_with_parentheses('f', a:dict, a:tag, '\*\a\+\s*$') 74 | endf 75 | 76 | 77 | function! tskeleton#tags#Process_c(dict, tag) 78 | return s:ProcessTag_functions_with_parentheses('f', a:dict, a:tag, '') 79 | endf 80 | 81 | 82 | function! tskeleton#tags#Process_java(dict, tag) 83 | return s:ProcessTag_functions_with_parentheses('f', a:dict, a:tag, '\V...') 84 | endf 85 | 86 | 87 | function! s:ProcessTag_functions_with_parentheses(kinds, dict, tag, restargs) 88 | if empty(a:kinds) || stridx(a:kinds, a:tag['kind']) != -1 89 | let source0 = fnamemodify(a:tag['filename'], ':p') 90 | let source = source0 91 | let xname = a:tag['name'] 92 | if has_key(a:tag, 'signature') 93 | let args0 = a:tag.signature 94 | else 95 | let args0 = matchstr(a:tag['cmd'], '(.\{-})') 96 | endif 97 | let args = matchstr(args0, '(\zs.\{-}\ze)') 98 | let bname0 = xname . args0 .'@' 99 | let bname = bname0 . fnamemodify(source, ':t') 100 | if has_key(a:dict, bname) 101 | if fnamemodify(get(a:dict[bname], 'source', ''), ':p') == source0 102 | return '' 103 | else 104 | let bname = bname0 . source 105 | endif 106 | endif 107 | let xname .= tskeleton#ReplacePrototypeArgs(args, a:restargs) 108 | let a:dict[bname] = {'text': xname, 'source': source, 'type': 'tskeleton'} 109 | let menu_prefix = tlib#var#Get('tskelMenuPrefix_tags', 'bg') 110 | if !empty(menu_prefix) 111 | let smenu = join(map(split(source, '[\/]'), 'escape(v:val, ".")'), '.') 112 | let mname = menu_prefix . smenu .'.'. escape(bname, '.') 113 | " TLogDBG xname .' -- '. xname 114 | let a:dict[bname]['menu'] = mname 115 | endif 116 | return bname 117 | endif 118 | return '' 119 | endf 120 | 121 | 122 | -------------------------------------------------------------------------------- /doc/tskeleton.txt: -------------------------------------------------------------------------------- 1 | *tskeleton.txt* tskeleton -- File Templates and Code Skeletons 2 | 3 | Author: Tom Link, micathom AT gmail com?subject=vim 4 | 5 | 6 | tskeleton provides file templates and code skeletons ("snippets" or "bits"). 7 | These templates may contain special tags that are replaced with some computed 8 | value (e.g., variables, user input ...), vimscript code, or place holders/jump 9 | positions (see |tskeleton-jump-positions|). 10 | 11 | Basic usage: 12 | Type `:new filename.ext`. If a skeleton for the respective filetype is 13 | defined (see |tskeleton-skeletons|), it will be read into the buffer. 14 | 15 | Type a partial name of a snippet (at least the first letter) and press 16 | (in insert mode) (see |tskeleton-key-bindings| for alternative 17 | key maps). If the name identifies a snippet/bit, it will be replaced with 18 | its expansion text. If there are several snippets beginning with that 19 | "name", you will be asked to select one from a list of matching 20 | snippets. 21 | 22 | can be configured to expand snippets but also (albeit disabled 23 | by default) abbreviations, functions (VIM script only), tags, word, 24 | 'completefunc' and 'omnifunc' items (see |g:tskelTypes| and 25 | |g:tskelHyperComplete| for details.) 26 | 27 | Press to jump to the next place holder (see 28 | |tskeleton#GoToNextTag()|). 29 | 30 | 31 | Demo -- tskeleton and the stakeholders (vimscript #3326) plugin: 32 | http://vimsomnia.blogspot.com/2010/11/tskeleton-and-stakeholders-vim-plugins.html 33 | 34 | 35 | Git: 36 | https://github.com/tomtom/tskeleton_vim 37 | 38 | 39 | For similar plugins see: http://vim.wikia.com/wiki/Snippet_Plugin_Comparison 40 | 41 | Limitations of tskeleton: 42 | - Place holders cannot be nested. 43 | - tskeleton was originally written for vim 6.0. I'd expect it to be 44 | less snappy than more modern and simpler plugins, although it 45 | tries to provide acceptable performance on slower computers by 46 | caching frequently reused data. 47 | 48 | Advantages of tskeleton with respect to some other plugins: 49 | - tskeleton provides for more complex templates (see 50 | |tskeleton-place-holder|) including conditional expansion, loops, 51 | inclusion of other templates, user queries etc. 52 | - Easy creation of camel case, all upper/lower case letter names etc. (see 53 | |tskeleton-modifiers|). 54 | 55 | It depends: 56 | - A place holder is some text in the buffer, i.e. tskeleton uses less magic 57 | when handling jump positions. As long as users don't replace all place 58 | holders, the buffer's contents most likely isn't valid code and an 59 | interpreter/compiler will most likely refuse to load it even if the 60 | code is never executed. 61 | 62 | 63 | ----------------------------------------------------------------------- 64 | *tskeleton-install* 65 | Install~ 66 | 67 | Edit the vba file and type: 68 | 69 | :so % 70 | 71 | See :help vimball for details. 72 | 73 | It is recommended to use tskeleton in conjunction with the stakeholders plugin 74 | (vimscript #3326): 75 | 76 | http://www.vim.org/scripts/script.php?script_id=3326 77 | https://github.com/tomtom/stakeholders_vim 78 | 79 | If you don't already have some skeletons, you may want to download 80 | tskeleton-Samples.zip from: 81 | 82 | http://www.vim.org/scripts/script.php?script_id=1160 83 | 84 | or from 85 | 86 | https://github.com/tomtom/tskeletons 87 | 88 | Copy the files to your local vimfiles directory (see also |add-global-plugin|). 89 | The directory structure should look like this: 90 | 91 | ~/.vim/skeletons/ 92 | FILE TEMPLATES ... 93 | map/ 94 | MAP FILES FOR CONDITIONAL EXPANSION 95 | bits/ 96 | &filetype.txt (single line templates) 97 | general/ 98 | GENERAL CODE SKELETONS ... 99 | &filetype/ 100 | FILETYPE SPECIFIC CODE SKELETONS: ONE SKELETON PER FILE ... 101 | 102 | 103 | *tskeleton-snippets* 104 | tskeleton also provides partial support for snipMate snippets (see 105 | https://github.com/honza/snipmate-snippets). The following limitations apply: 106 | - tskeleton cannot handle nested tags/place holders 107 | 108 | 109 | *tskeleton-cache* 110 | In order to speed up things, tskeleton caches intermediate results. 111 | Those files are created in |g:tlib_cache|. By default, the old files 112 | will be removed from the cache every |g:tlib#cache#purge_every_days| 113 | days. In order to disable purging (e.g. if you purge the cache directory 114 | by means of a cron script), set |g:tlib#cache#purge_every_days| to -1. 115 | 116 | 117 | ----------------------------------------------------------------------- 118 | *tskeleton-usage* 119 | *tskeleton-skeletons* 120 | File templates~ 121 | 122 | The file skeletons are stored in the skeletons subdirectory. Which 123 | template is used for which new file is controlled by |:autocmd|s. This 124 | provides greater flexibility than a &filetype based approach as you can 125 | select templates on the basis of a filename pattern or a specific 126 | directory. 127 | 128 | Currently, the following file types are supported by default: 129 | 130 | - batch.bat 131 | - deplate.txt 132 | - latex.tex 133 | - php.inc.php 134 | - php.php 135 | - plugin.vim 136 | - ruby.rb 137 | - shell.sh 138 | - text.txt 139 | 140 | In order to add support for a new filetype, save a skeleton file to 141 | ~/.vim/skeletons/file.suffix and add something like this to your .vimrc 142 | file: > 143 | 144 | autocmd BufNewFile *.suffix TSkeletonSetup template.suffix 145 | autocmd BufNewFile /here/*.suffix TSkeletonSetup othertemplate.suffix 146 | 147 | 148 | Alternatively, you can store templates as: > 149 | 150 | ~/.vim/skeletons/templates/GROUP/FILETYPE PATTERN 151 | 152 | where GROUP is an arbitrary name for a collection of auto templates, 153 | FILETYPE is a know vim filetype, and the pattern is an encoded pattern (# == 154 | *, %XX=Char XXh) for auto-generated autocmds. 155 | 156 | Example: Templates file names for some vim-related files: > 157 | 158 | ~/.vim/skeletons/templates/vim/help #%2fvimfiles%2fdoc%2f#.txt 159 | ~/.vim/skeletons/templates/vim/vim #%2fvimfiles#%2fftplugin%2f#.vim 160 | ~/.vim/skeletons/templates/vim/vim #%2fvimfiles#%2fsyntax%2f#.vim 161 | 162 | < 163 | *tskeleton-place-holder* 164 | 165 | Tags (which look like <+...+>) serve two purposes: 166 | 167 | - marker for jump positions (see |tskeleton#GoToNextTag()|) 168 | - dynamic content expansion 169 | 170 | You can use tags to define cursor jump positions. tskeleton also 171 | supports some special tags that are expanded when inserting the 172 | skeleton. 173 | 174 | A list of special tags: 175 | *tSkeletion-<+FILE NAME ROOT+>* 176 | <+FILE NAME ROOT+> 177 | The file name root 178 | *tSkeletion-<+FILE NAME+>* 179 | <+FILE NAME+> 180 | The file name 181 | *tSkeletion-<+FILE SUFFIX+>* 182 | <+FILE SUFFIX+> 183 | The file suffix 184 | *tSkeletion-<+FILE DIRNAME+>* 185 | <+FILE DIRNAME+> 186 | The file's directory 187 | *tSkeletion-<+NOTE+>* 188 | <+NOTE+> 189 | A note 190 | *tSkeletion-<+DATE+>* 191 | <+DATE+> 192 | The current date (the format is controlled via 193 | g:tskelDateFormat) 194 | *tSkeletion-<+AUTHOR+>* 195 | <+AUTHOR+> 196 | The author's name (g:tskelUserName) 197 | *tSkeletion-<+EMAIL+>* 198 | <+EMAIL+> 199 | The author's e-mail (g:tskelUserEmail) 200 | *tSkeletion-<+COMPANY+>* 201 | <+COMPANY+> 202 | The author's company (g:tskelUserCompany) 203 | *tSkeletion-<+WEBSITE+>* 204 | <+WEBSITE+> 205 | The author's homepage (g:tskelUserWWW) 206 | *tSkeletion-<+LICENSE+>* 207 | <+LICENSE+> 208 | The name of the license this file is released under 209 | (g:tskelLicense) 210 | 211 | In order to define your own tag, you have to define a function called 212 | TSkeleton_TAGNAME() that returns the text to be filled in. 213 | 214 | *tskeleton-tags* 215 | tskeleton also supports the following pseudo-tags: 216 | 217 | <+CURSOR+> *tSkeletion-<+CURSOR+>* 218 | Where to place the cursor after insertion 219 | 220 | <+&NAME+> *tSkeletion-<+&+>* 221 | A vim option 222 | 223 | <+g:NAME+> *tSkeletion-<+g:+>* 224 | A global variable 225 | 226 | <+b:NAME+> *tSkeletion-<+b:+>* 227 | A buffer local variable 228 | 229 | <+?QUERY?+> *tSkeletion-<+?+>* 230 | Query[1] the user 231 | 232 | <+?VAR|QUERY?+> 233 | Query[1] the user and propose some choices from the variable VAR 234 | 235 | *tSkeletion-<+bit+>* 236 | <+bit:BIT+>, <+bit:BIT|"DEFAULT"+>, <+bit:BIT|COMMANDS+> 237 | Insert a bit; if the bit isn't defined for the current filetype, 238 | use DEFAULT; if DEFAULT matches ".*" insert it as a string; 239 | otherwise interpret it as a command sequence to be fed to normal 240 | 241 | <+tskel:TSKELETON+> *tSkeletion-<+tskel+>* 242 | Same as the above 243 | 244 | <+call:FUNCTION(ARGS)+> *tSkeletion-<+call+>* 245 | Insert the result value of some function 246 | 247 | <+include(TSKELETON)+> *tSkeletion-<+include+>* 248 | Another synonym for the above. 249 | 250 | <+execute(EX COMMAND)+> *tSkeletion-<+execute+>* 251 | Run a vim command. 252 | 253 | [1] If the query ends with a colon, the second question mark will be 254 | removed. Up to verson 2.4 VAR is a string, separating the items by an 255 | "\n". From 3.0 on, VAR is a list. 256 | 257 | NOTE: Flow control and loop tags are experimental and it's more than 258 | just likely that the output doesn't meet your expectations. 259 | 260 | Flow control: *tSkeletion-<+if+>* 261 | <+if(CONDITION)+> 262 | <+elseif(CONDITION)+> 263 | <+else+> 264 | <+endif+> 265 | 266 | Loops: *tSkeletion-<+for+>* 267 | <+for(VAR in LIST)+> 268 | <+endfor+>, <+endfor(VAR)+> 269 | If you nest for loops, you have to add the variable name to the 270 | endfor tag. And no, this isn't the most clever way to do this. 271 | 272 | Variables: *tSkeletion-<+let+>* 273 | <+let(VAR=VALUE)+> 274 | The variable will be unset or restored to its original value 275 | after processing the current template. 276 | VAR may have some modifiers attached: 277 | VAR? ... Set only if undefined 278 | VAR& ... Don't restore original variable 279 | 280 | Interaction: *tSkeletion-<+input+>* 281 | <+input(VAR, QUERY, [DEFAULT], [COMPLETION])+> 282 | This will insert the user input and set the variable VAR (unless 283 | empty), which can be used throughout the template. The variable 284 | will be removed after finishing the current template. If the 285 | variable was previously defined, the original value will be 286 | restored. 287 | If VAR ends with '!', no text will be inserted in the buffer. In 288 | this case any whitespace (including one newline) after the tag 289 | will be removed. See also the notes on |tSkeletion-<+input+>|. 290 | 291 | *tSkeletion-<+select+>* 292 | <+select(VAR, LIST, [TYPE='s'], [SEPARATOR=', '])+> 293 | Let the user select an item from a list. 294 | VAR is a string. 295 | TYPE is either 's' (single selection) or 'm' (multiple selection) -- 296 | see also |tlib#input#List()|. 297 | If TYPE is 'm', the results are joined with SEPARATOR. 298 | Example: > 299 | before(<+select("s:type", [":all", ":each"])+>) 300 | before(<+select("s:type", ["A", "B", "C", "D"], "m", "-")+>) 301 | < 302 | 303 | Other: *tSkeletion-<+nl+>* 304 | <+nl+> 305 | Insert a newline 306 | 307 | <+joinline+> *tSkeletion-<+joinline+>* 308 | Join with next line. Delete any whitespace. 309 | 310 | <+nop+> *tSkeletion-<+nop+>* 311 | Insert nothing (could be necessary in conjunction with the "for" 312 | tag) 313 | 314 | A wiki like table could then be constructed using a skeleton like this: > 315 | 316 | 317 | let s:my_rows = input('Rows: ') 318 | let s:my_cols = input('Columns: ') 319 | 320 | 321 | unlet! s:my_rows s:my_cols 322 | 323 | <+CURSOR+><+for(i in range(s:my_rows))+> 324 | |<+for(j in range(s:my_cols))+> <+CELL+> |<+endfor(j)+><+nop+> 325 | <+endfor(i)+> 326 | 327 | or: > 328 | 329 | <+input('s:my_rows?!', 'Rows: ')+> 330 | <+input('s:my_cols?!', 'Cols: ')+> 331 | <+for(i in range(s:my_rows))+> 332 | |<+for(j in range(s:my_cols))+> <+CURSOR+> |<+endfor(j)+><+nop+> 333 | <+endfor(i)+> 334 | 335 | NOTE: The <+nop+> is necessary in order to prevent the <+endfor+> tag to 336 | "eat" the newline. If we include this bit from another bit that already 337 | sets s:my_rows and/or s:my_cols, the user won't be queried again (because of 338 | the "?" in the input statement). E.g. > 339 | 340 | <+let(s:my_rows = 3)+> 341 | <+let(s:my_cols = 3)+> 342 | <+include(table)+> 343 | 344 | *tSkeletion-backslash* 345 | Any special tag can be preceded with a backslash in order to prevent 346 | expansion. Examples: > 347 | 348 | <+\if(foo=1)+> 349 | 350 | surprisingly expands to > 351 | 352 | <+if(foo=1)+> 353 | 354 | It's best to use global variables with "if" and "for" tags as the body 355 | is most likely evaluated in a different buffer in a hypothetically 356 | unknown context. 357 | 358 | 359 | *tskeleton-jump-positions* 360 | Unknown tags are kept in the expanded skeleton. These tags can be used 361 | as cursor jump marks. This syntax was originally used by imap (vimscript 362 | #244 or vimscript #475). If you don't want to install imap, you can also 363 | use |TSkeletonMapGoToNextTag()|. 364 | 365 | Nameless tags (<++>) will disappear when they are selected. 366 | 367 | Example:> 368 | 369 | case <+CURSOR+> in 370 | <+PATTERN+>) 371 | <+BODY+> 372 | ;; 373 | *) 374 | <+DEFAULT+> 375 | ;; 376 | esac 377 | <++> 378 | 379 | When you insert this skeleton, the cursor will be placed at 380 | "<+CURSOR+>". If you press , the cursor will jump to "<+PATTERN+>" 381 | (the tag will remain selected). If you press three times, the 382 | cursor will jump to "<++>" (the tag will be deleted). 383 | 384 | Check out the "test_tskeleton" skeleton for examples. 385 | 386 | 387 | *tskeleton-modifiers* 388 | Tags can be modified using modifiers, like in: > 389 | 390 | <+TAG NAME:MODIFIER+> 391 | 392 | Known modifiers: 393 | 394 | l :: lower case 395 | u :: upper case 396 | c :: capitalize 397 | C :: transform to CamelCase 398 | s/FROM/TO/ :: replace text (actually a s//g); this has to be the 399 | last modifier; the pattern separator can be selected 400 | arbitrarily 401 | 402 | Example for a ruby class template: > 403 | 404 | class <+FILE NAME ROOT:cs*\W*_*+> 405 | <+CURSOR+> 406 | end 407 | <++> 408 | 409 | ----------------------------------------------------------------------- 410 | *tskeleton-code-skeletons* 411 | *tskeleton-bits* 412 | Bits/Code Skeletons~ 413 | 414 | Smaller skeleton bits are stored in SKELETONS/bits/FILETYPE/ or 415 | SKELETONS/bits/general/. I.e., code skeletons can be filetype specific 416 | or generally available. 417 | 418 | The filenames of the bits may be grouped in submenus as in: 419 | 420 | ../tex/&Define.%5Cnew&command 421 | ../tex/&Define.%5Cnew&environment 422 | 423 | This will create skeletons for \newcommand and \newenvironment but will 424 | group the skeletons under the TSkel.Define. menu with the respective 425 | accelerators. 426 | 427 | *tskeleton-Types* *g:tskelTypes* 428 | *tskeleton#Initialize()* 429 | tskeleton supports several types of code templates: 430 | 431 | - skeleton (standard tskeleton functionality) 432 | - abbreviations (VIM abbreviations) 433 | - functions (VIM script functions extracted from :function) 434 | - mini ("mini" bits, one-liners etc.) 435 | - tags (tags-based code templates, requires ctags, I presume) 436 | 437 | Not all types are enabled by default. User have to select, which types 438 | they want to use, by setting the g:tskelTypes at start-up. When changing 439 | the variable, users might have to call tskeleton#Initialize(). 440 | 441 | *tskeleton-Skeleton* 442 | Smaller skeleton bits are stored in SKELETONS/bits/FILETYPE/ or 443 | SKELETONS/bits/general/. I.e., code skeletons can be filetype specific 444 | or generally available. 445 | 446 | Skeleton bits can be filled in by typing: > 447 | 448 | :TSkeletonBit NAME 449 | 450 | For this command, command line completion is implemented. Calling this 451 | command will insert the contents of the respective file below the 452 | current line. 453 | 454 | NOTE: Bit names should not contain ampersand (as these are interpreted 455 | as menu accelerators) and periods (which are used to construct 456 | submenus). Other special characters can be included by encoding them in 457 | hex form as %XX as it is done in URLs. Example: "%5Csection" becomes 458 | "\section". 459 | 460 | *tskeleton-key-bindings* 461 | The default key bindings for inserting code skeletons are: 462 | 463 | ... In insert mode, expand name before the cursor 464 | ## ... Expand name under cursor 465 | #t ... Insert code skeleton via command line 466 | ... In insert mode, expand the bit before the cursor (on 467 | a German keyboard this happens to be ) 468 | 469 | *g:tskelKeyword_{&filetype}* 470 | A bit name usually is the |word| under the cursor. If this doesn't fit 471 | your needs, you can define g:tskelKeyword_{&filetype} to define what 472 | makes up a skeleton name. Example: > 473 | 474 | let g:tskelKeyword_viki = '\(#\|{\)\?[^#{[:blank:]]\{-}' 475 | 476 | 477 | *tskeleton-embedded-code* 478 | Code skeletons may contain vim code that is evaluated before or after 479 | expanding the tags. The before/after blocks are fed to |:exec| and must 480 | not contain function definitions. 481 | 482 | NOTE: The "parser" is quite primitive. These tags have to start as 483 | single statement in a line at column 1, and they have to appear in the 484 | following order: 485 | 486 | ** 487 | Display an explanatory message after template expansion 488 | 489 | ** 490 | Execute code before template expansion in the target buffer 491 | 492 | ** 493 | Execute code after template expansion in the target buffer 494 | 495 | ** 496 | Execute code before template expansion in the template buffer 497 | 498 | ** 499 | Execute code after template expansion in the template buffer 500 | 501 | ** 502 | Make the bit available via |:abbreviate| under the enclosed name. 503 | 504 | ** 505 | Use this menu name instead of the default one. 506 | 507 | ** 508 | An expression that checks whether a bit is eligible in the 509 | current context. 510 | 511 | BibTeX example: > 512 | 513 | 514 | Insert a collection entry 515 | 516 | 517 | let b:tskelArticleID = input("ID of bibentry: ") 518 | if b:tskelArticleID == "" | let b:tskelArticleID = "<+CURSOR+>" | endif 519 | 520 | 521 | unlet b:tskelArticleID 522 | 523 | @INCOLLECTION{<+b:tskelArticleID+>, 524 | author = {<+CURSOR+>}, 525 | title = {<+ARTICLE TITLE+>}, 526 | crossref = {<+CROSSREF+>}, 527 | pages = {<+PAGES+>}, 528 | abstract = {[[~/Docs/Abstracts/<+b:tskelArticleID+>.txt]]}, 529 | } 530 | <++> 531 | 532 | In the above example, we query the user for an ID and insert this ID as 533 | entry key and as an abstract's file name. 534 | 535 | The before/after blocks are evaluated in the destination buffer. The 536 | variants here_before/here_after are evaluated in the scratch buffer for 537 | the current code skeleton. 538 | 539 | *tskeleton-groups* 540 | *g:tskelBitGroup_{&filetype}* 541 | Groups~ 542 | 543 | Some filetype's bits might be of use for other filetypes too. You can 544 | make them accessible by defining a g:tskelBitGroup_{&filetype} variable. 545 | E.g., in php mode all html bits are made accessible by setting this 546 | variable (the default): > 547 | 548 | let g:tskelBitGroup_php = ['php', 'html'] 549 | 550 | Bits of type "general" are always available. 551 | 552 | *tskeleton-context* 553 | *tskeleton-map* 554 | Maps -- Context-sensitive expansion~ 555 | 556 | To some extent, tskeleton is capable of offering the user only a small 557 | selection of eligible bits for a specific context if a map file 558 | ($VIMFILES/skeletons/map/{&filetype}) is provided. Such a map file is made up 559 | of regular expressions matching a specific context (before the cursor 560 | only) and a blank-separated list of eligible bits. The regexp and the 561 | list are separated by whitespace: > 562 | 563 | REGEXP BIT1 BIT2 ... BITn 564 | 565 | Example: > 566 | 567 | ]\\|\\n\\)* name= action= method= 568 | 569 | If an eligible bit is undefined, the name is inserted as is. I.e. you 570 | don't have to define skeletons for all these options and argument names. 571 | 572 | 573 | *tskeleton-minibits* 574 | Minibits~ 575 | 576 | Mini bits are kept in the files: 577 | 578 | - $CWD/.tskelmini 579 | - $VIMFILES/skeletons/bits/{&filetype}.txt 580 | 581 | These files contain whitespace-separated pairs of bit names and their 582 | expansions. These files are meant to keep expansions of accronyms and 583 | abbreviations and the like. Example: > 584 | 585 | IMHO In my humble opinion 586 | AFAIK As far as I know 587 | 588 | *tskeleton-menu* 589 | *g:tskelMenuPrefix* 590 | Menu~ 591 | 592 | If g:tskelMenuPrefix is non-empty, tskeleton will display a menu 593 | containing all eligible bits for a certain filetype. 594 | 595 | The menu can be hierarchical and certain entries may have shortcuts by 596 | properly naming the bits. Example: > 597 | 598 | &Environment.&Quote 599 | &Environment.Q&uotation 600 | 601 | This will create the submenu "Environment" that can be selected by 602 | typing "e" (on Windows) and two entries, the first of which can be 603 | selected by typing "q" and the second by typing "u". 604 | 605 | Be aware that the actual bit names are Quote and Quotation (i.e. the 606 | submenu and the ampersand are stripped off). 607 | 608 | 609 | ----------------------------------------------------------------------- 610 | *tskeleton-utilities* 611 | Utilities~ 612 | 613 | *tskeleton#IncreaseRevisionNumber()* 614 | The function tskeleton#IncreaseRevisionNumber() provides a way to 615 | automatically update a revision number in the form > 616 | 617 | @Revision: 1.0.393 618 | 619 | In order to use this function, add something like this to your |vimrc| 620 | file: > 621 | 622 | autocmd BufWritePre * call tskeleton#IncreaseRevisionNumber() 623 | 624 | *:TSkeletonCleanUpBibEntry* 625 | The TSkeletonCleanUpBibEntry command can be used to purge the current bibtex 626 | entry from expendable fields (i.e., lines matching <+.\{-}+>). 627 | 628 | For bibtex files, this command is bound to: tc 629 | 630 | *TSkeletonMapGoToNextTag()* 631 | *tskeleton#GoToNextTag()* 632 | If g:tskelMapGoToNextTag is true, the map will be enabled. (That 633 | is the key that was also used by the imaps.vim plugin.) Press to 634 | jump between tags. 635 | 636 | This function provides one or two extras over the version of imaps.vim. 637 | An explanation: 638 | 639 | - ###, +++, ???, !!! are used as markers too. 640 | - If a marker is empty (e.g. <++>), the marker will be removed (as 641 | imaps.vim does). 642 | - If a marker matches <+NAME/DEFAULT+>, the marker will be replaced 643 | with DEFAULT. 644 | - If a snippet contains numbered placeholders (e.g. <+1+>), these 645 | will be selected first in increasing number. 646 | 647 | 648 | ======================================================================== 649 | Contents~ 650 | 651 | g:tskelGlobalBitsPath ...................... |g:tskelGlobalBitsPath| 652 | g:tskelLocalBitsDirs ....................... |g:tskelLocalBitsDirs| 653 | g:tskelMapLeader ........................... |g:tskelMapLeader| 654 | g:tskelMapInsert ........................... |g:tskelMapInsert| 655 | g:tskelAddMapInsert ........................ |g:tskelAddMapInsert| 656 | g:tskelMenuCache ........................... |g:tskelMenuCache| 657 | g:tskelMapGoToNextTag ...................... |g:tskelMapGoToNextTag| 658 | g:tskelMapHyperComplete .................... |g:tskelMapHyperComplete| 659 | g:tskelHyperComplete ....................... |g:tskelHyperComplete| 660 | g:tskelHyperType ........................... |g:tskelHyperType| 661 | TSkeletonMapHyperComplete .................. |TSkeletonMapHyperComplete()| 662 | :TSkeletonSetup ............................ |:TSkeletonSetup| 663 | :TSkeletonEdit ............................. |:TSkeletonEdit| 664 | :TSkeletonEditBit .......................... |:TSkeletonEditBit| 665 | :TSkeletonNewFile .......................... |:TSkeletonNewFile| 666 | :TSkeletonBitReset ......................... |:TSkeletonBitReset| 667 | :TSkeletonBit .............................. |:TSkeletonBit| 668 | g:tskelBitsIgnore .......................... |g:tskelBitsIgnore| 669 | g:tskelNewBufferIsDirty .................... |g:tskelNewBufferIsDirty| 670 | g:tskeleton#enable_stakeholders ............ |g:tskeleton#enable_stakeholders| 671 | g:tskeleton#max_basename ................... |g:tskeleton#max_basename| 672 | g:tskeleton#conceal_cchar .................. |g:tskeleton#conceal_cchar| 673 | g:tskeleton#filetype_map ................... |g:tskeleton#filetype_map| 674 | TSkeleton_FILE_DIRNAME ..................... |TSkeleton_FILE_DIRNAME()| 675 | TSkeleton_FILE_SUFFIX ...................... |TSkeleton_FILE_SUFFIX()| 676 | TSkeleton_FILE_NAME_ROOT ................... |TSkeleton_FILE_NAME_ROOT()| 677 | TSkeleton_FILE_NAME ........................ |TSkeleton_FILE_NAME()| 678 | TSkeleton_NOTE ............................. |TSkeleton_NOTE()| 679 | TSkeleton_DATE ............................. |TSkeleton_DATE()| 680 | TSkeleton_TIME ............................. |TSkeleton_TIME()| 681 | TSkeleton_AUTHOR ........................... |TSkeleton_AUTHOR()| 682 | TSkeleton_EMAIL ............................ |TSkeleton_EMAIL()| 683 | TSkeleton_COMPANY .......................... |TSkeleton_COMPANY()| 684 | TSkeleton_WEBSITE .......................... |TSkeleton_WEBSITE()| 685 | TSkeleton_LICENSE .......................... |TSkeleton_LICENSE()| 686 | TSkeletonCB_FILENAME ....................... |TSkeletonCB_FILENAME()| 687 | TSkeletonCB_DIRNAME ........................ |TSkeletonCB_DIRNAME()| 688 | TSkelNewScratchHook_viki ................... |TSkelNewScratchHook_viki()| 689 | tskeleton#WrapMarker ....................... |tskeleton#WrapMarker()| 690 | tskeleton#CursorMarker ..................... |tskeleton#CursorMarker()| 691 | tskeleton#TagRx ............................ |tskeleton#TagRx()| 692 | tskeleton#ExpandedAbbreviationTemplate ..... |tskeleton#ExpandedAbbreviationTemplate()| 693 | tskeleton#FillIn ........................... |tskeleton#FillIn()| 694 | tskeleton#ExtractMeta ...................... |tskeleton#ExtractMeta()| 695 | tskeleton#SetCursor ........................ |tskeleton#SetCursor()| 696 | tskeleton#GetVar ........................... |tskeleton#GetVar()| 697 | tskeleton#GetDestBuffer .................... |tskeleton#GetDestBuffer()| 698 | tskeleton#EvalInDestBuffer ................. |tskeleton#EvalInDestBuffer()| 699 | tskeleton#ExecInDestBuffer ................. |tskeleton#ExecInDestBuffer()| 700 | tskeleton#FindTemplate ..................... |tskeleton#FindTemplate()| 701 | tskeleton#CollectTemplates ................. |tskeleton#CollectTemplates()| 702 | tskeleton#Setup ............................ |tskeleton#Setup()| 703 | tskeleton#SelectTemplate ................... |tskeleton#SelectTemplate()| 704 | tskeleton#EditBitCompletion ................ |tskeleton#EditBitCompletion()| 705 | tskeleton#Edit ............................. |tskeleton#Edit()| 706 | tskeleton#BitsPath ......................... |tskeleton#BitsPath()| 707 | tskeleton#EditBit .......................... |tskeleton#EditBit()| 708 | tskeleton#NewFile .......................... |tskeleton#NewFile()| 709 | tskeleton#NewBufferMenuItem ................ |tskeleton#NewBufferMenuItem()| 710 | tskeleton#FetchMiniBits .................... |tskeleton#FetchMiniBits()| 711 | tskeleton#MaybePathshorten ................. |tskeleton#MaybePathshorten()| 712 | tskeleton#FetchMiniBitsGenerator ........... |tskeleton#FetchMiniBitsGenerator()| 713 | tskeleton#ReplacePrototypeArgs ............. |tskeleton#ReplacePrototypeArgs()| 714 | tskeleton#PurifyBit ........................ |tskeleton#PurifyBit()| 715 | tskeleton#BitDef ........................... |tskeleton#BitDef()| 716 | tskeleton#BuildBufferMenu .................. |tskeleton#BuildBufferMenu()| 717 | tskeleton#PrepareBits ...................... |tskeleton#PrepareBits()| 718 | tskeleton#ResetBits ........................ |tskeleton#ResetBits()| 719 | tskeleton#SelectBit ........................ |tskeleton#SelectBit()| 720 | tskeleton#IsScratchBuffer .................. |tskeleton#IsScratchBuffer()| 721 | tskeleton#Retrieve ......................... |tskeleton#Retrieve()| 722 | tskeleton#Bit .............................. |tskeleton#Bit()| 723 | tskeleton#ExpandBitUnderCursor ............. |tskeleton#ExpandBitUnderCursor()| 724 | tskeleton#WithSelection .................... |tskeleton#WithSelection()| 725 | tskeleton#Complete_use_omnifunc ............ |tskeleton#Complete_use_omnifunc()| 726 | tskeleton#Complete_use_completefunc ........ |tskeleton#Complete_use_completefunc()| 727 | tskeleton#Complete_scan_words .............. |tskeleton#Complete_scan_words()| 728 | tskeleton#Complete_scan_tags ............... |tskeleton#Complete_scan_tags()| 729 | tskeleton#GetCompletions ................... |tskeleton#GetCompletions()| 730 | tskeleton#Complete ......................... |tskeleton#Complete()| 731 | tskeleton#Placeholders ..................... |tskeleton#Placeholders()| 732 | tskeleton#LateExpand ....................... |tskeleton#LateExpand()| 733 | tskeleton#Repeat ........................... |tskeleton#Repeat()| 734 | tskeleton#InsertTable ...................... |tskeleton#InsertTable()| 735 | tskeleton#HyperComplete_query .............. |tskeleton#HyperComplete_query()| 736 | tskeleton#HyperComplete_pum ................ |tskeleton#HyperComplete_pum()| 737 | tskeleton#functions#Initialize ............. |tskeleton#functions#Initialize()| 738 | tskeleton#functions#FiletypeBits_vim ....... |tskeleton#functions#FiletypeBits_vim()| 739 | g:tskeleton#snippets#force ................. |g:tskeleton#snippets#force| 740 | tskeleton#snippets#Initialize .............. |tskeleton#snippets#Initialize()| 741 | tskeleton#snippets#FiletypeBits ............ |tskeleton#snippets#FiletypeBits()| 742 | tskeleton#snippets#Generator ............... |tskeleton#snippets#Generator()| 743 | Filename ................................... |Filename()| 744 | tskeleton#snippets#Preprocess .............. |tskeleton#snippets#Preprocess()| 745 | tskeleton#tags#Initialize .................. |tskeleton#tags#Initialize()| 746 | tskeleton#tags#BufferBits .................. |tskeleton#tags#BufferBits()| 747 | tskeleton#tags#Process_vim ................. |tskeleton#tags#Process_vim()| 748 | tskeleton#tags#Process_ruby ................ |tskeleton#tags#Process_ruby()| 749 | tskeleton#tags#Process_c ................... |tskeleton#tags#Process_c()| 750 | tskeleton#tags#Process_java ................ |tskeleton#tags#Process_java()| 751 | tskeleton#mini#Initialize .................. |tskeleton#mini#Initialize()| 752 | tskeleton#mini#FiletypeBits ................ |tskeleton#mini#FiletypeBits()| 753 | tskeleton#abbreviations#Reset .............. |tskeleton#abbreviations#Reset()| 754 | tskeleton#abbreviations#Initialize ......... |tskeleton#abbreviations#Initialize()| 755 | tskeleton#abbreviations#GetAbbreviations ... |tskeleton#abbreviations#GetAbbreviations()| 756 | tskeleton#abbreviations#BufferBits ......... |tskeleton#abbreviations#BufferBits()| 757 | tskeleton#abbreviations#Retrieve ........... |tskeleton#abbreviations#Retrieve()| 758 | tskeleton#omnicomplete#Initialize .......... |tskeleton#omnicomplete#Initialize()| 759 | tskeleton#omnicomplete#FiletypeBits ........ |tskeleton#omnicomplete#FiletypeBits()| 760 | tskeleton#skeleton#Initialize .............. |tskeleton#skeleton#Initialize()| 761 | tskeleton#skeleton#FiletypeBits ............ |tskeleton#skeleton#FiletypeBits()| 762 | tskeleton#skeleton#BufferBits .............. |tskeleton#skeleton#BufferBits()| 763 | tskeleton#skeleton#Generator ............... |tskeleton#skeleton#Generator()| 764 | tskeleton#completefunc#Initialize .......... |tskeleton#completefunc#Initialize()| 765 | tskeleton#completefunc#FiletypeBits ........ |tskeleton#completefunc#FiletypeBits()| 766 | 767 | 768 | ======================================================================== 769 | plugin/tskeleton.vim~ 770 | 771 | *g:tskelGlobalBitsPath* 772 | g:tskelGlobalBitsPath (default: exists('g:tskelBitsDir') ? g:tskelBitsDir : '') 773 | A comma-separated list of directories (see |globpath()|) for 774 | globally available bits. If empty, use all "skeletons/bits/" 775 | subdirectories in 'runtimepath'. 776 | 777 | *g:tskelLocalBitsDirs* 778 | g:tskelLocalBitsDirs (default: ['.tskel', '_tskel']) 779 | A list of directories that contains buffer-local bits. 780 | 781 | *g:tskelMapLeader* 782 | g:tskelMapLeader (default: "#") 783 | Map leader for maps in normal mode. 784 | 785 | *g:tskelMapInsert* 786 | g:tskelMapInsert (default: '') 787 | Map leader for maps in insert mode. 788 | 789 | *g:tskelAddMapInsert* 790 | g:tskelAddMapInsert (default: 0) 791 | If true, insert |g:tskelMapInsert| after expanding a bit. This 792 | could be useful if you plan to map |g:tskelMapInsert| to something 793 | like . 794 | 795 | *g:tskelMenuCache* 796 | g:tskelMenuCache (default: '.tskelmenu') 797 | If non-empty, cache menu items. 798 | 799 | *g:tskelMapGoToNextTag* 800 | g:tskelMapGoToNextTag (default: '') 801 | If non-empty, create maps for "go to next place holder" feature. 802 | This map should work in normal, visual, selection, and insert 803 | mode. 804 | 805 | *g:tskelMapHyperComplete* 806 | g:tskelMapHyperComplete (default: '') 807 | Key to invoke hyper completion (see |g:tskelHyperComplete|). 808 | 809 | *g:tskelHyperComplete* 810 | g:tskelHyperComplete (default: {'use_completefunc': 1, 'scan_words': 1, 'scan_tags': 1}) 811 | A dictionary of items that should be offered on "hyper complete". 812 | 813 | *g:tskelHyperType* 814 | g:tskelHyperType (default: 'query') 815 | Either query or pum. 816 | If you set the variable to "pum", you have to accept completions 817 | with . 818 | This variable must be set in your |vimrc| file before loading the 819 | tskeleton plugin. 820 | 821 | *TSkeletonMapHyperComplete()* 822 | TSkeletonMapHyperComplete(key, ...) 823 | In the current buffer, map a:key so that 824 | - If the cursor is located at the beginning of the line or if the 825 | the cursor is over a whitespace character, indent the current 826 | line 827 | - otherwise expand the bit under the cursor or (if not suitable bit 828 | was found) use &omnifunc, &completefunc, tags, and (as fallback 829 | strategy) the words in the buffer as possible completions. 830 | 831 | *:TSkeletonSetup* 832 | :TSkeletonSetup 833 | Fill in a file template. 834 | 835 | *:TSkeletonEdit* 836 | :TSkeletonEdit 837 | Edit a file template. 838 | 839 | *:TSkeletonEditBit* 840 | :TSkeletonEditBit 841 | Edit a bit. 842 | 843 | *:TSkeletonNewFile* 844 | :TSkeletonNewFile 845 | Create a new file template. 846 | 847 | *:TSkeletonBitReset* 848 | :TSkeletonBitReset 849 | Reset a buffer's bits. Use this command if the list of bits known in a 850 | buffer is outdated. 851 | 852 | *:TSkeletonBit* 853 | :TSkeletonBit 854 | Insert a bit/snippet. 855 | 856 | 857 | ======================================================================== 858 | autoload/tskeleton.vim~ 859 | 860 | *g:tskelBitsIgnore* 861 | g:tskelBitsIgnore (default: tlib#rx#Suffixes()) 862 | 863 | *g:tskelNewBufferIsDirty* 864 | g:tskelNewBufferIsDirty (default: ! &hidden) 865 | If true, a new file that was filled with a template is marked as 866 | 'modified'. 867 | 868 | *g:tskeleton#enable_stakeholders* 869 | g:tskeleton#enable_stakeholders (default: exists('g:loaded_stakeholders') && g:loaded_stakeholders) 870 | 871 | *g:tskeleton#max_basename* 872 | g:tskeleton#max_basename (default: 255 - len(tlib#cache#Filename('tskeleton', '.'))) 873 | 874 | *g:tskeleton#conceal_cchar* 875 | g:tskeleton#conceal_cchar (default: has('conceal') ? {'utf-8': '⬚', '_': '#'} : {}) 876 | With |+conceal|, show this character for placeholders. 877 | If empty, don't use |:syn-conceal|. 878 | 879 | *g:tskeleton#filetype_map* 880 | g:tskeleton#filetype_map (default: {'mkd.markdown': 'markdown'}) 881 | 882 | *TSkeleton_FILE_DIRNAME()* 883 | TSkeleton_FILE_DIRNAME() 884 | 885 | *TSkeleton_FILE_SUFFIX()* 886 | TSkeleton_FILE_SUFFIX() 887 | 888 | *TSkeleton_FILE_NAME_ROOT()* 889 | TSkeleton_FILE_NAME_ROOT() 890 | 891 | *TSkeleton_FILE_NAME()* 892 | TSkeleton_FILE_NAME() 893 | 894 | *TSkeleton_NOTE()* 895 | TSkeleton_NOTE() 896 | 897 | *TSkeleton_DATE()* 898 | TSkeleton_DATE() 899 | 900 | *TSkeleton_TIME()* 901 | TSkeleton_TIME() 902 | 903 | *TSkeleton_AUTHOR()* 904 | TSkeleton_AUTHOR() 905 | 906 | *TSkeleton_EMAIL()* 907 | TSkeleton_EMAIL() 908 | 909 | *TSkeleton_COMPANY()* 910 | TSkeleton_COMPANY() 911 | 912 | *TSkeleton_WEBSITE()* 913 | TSkeleton_WEBSITE() 914 | 915 | *TSkeleton_LICENSE()* 916 | TSkeleton_LICENSE() 917 | 918 | *TSkeletonCB_FILENAME()* 919 | TSkeletonCB_FILENAME() 920 | 921 | *TSkeletonCB_DIRNAME()* 922 | TSkeletonCB_DIRNAME() 923 | 924 | *TSkelNewScratchHook_viki()* 925 | TSkelNewScratchHook_viki() 926 | 927 | *tskeleton#WrapMarker()* 928 | tskeleton#WrapMarker(text, ...) 929 | 930 | *tskeleton#CursorMarker()* 931 | tskeleton#CursorMarker(...) 932 | 933 | *tskeleton#TagRx()* 934 | tskeleton#TagRx() 935 | 936 | *tskeleton#ExpandedAbbreviationTemplate()* 937 | tskeleton#ExpandedAbbreviationTemplate() 938 | 939 | *tskeleton#FillIn()* 940 | tskeleton#FillIn(bit, ?filetype='', ?meta={}) 941 | Expand special tags. 942 | 943 | *tskeleton#ExtractMeta()* 944 | tskeleton#ExtractMeta(text) 945 | 946 | *tskeleton#SetCursor()* 947 | tskeleton#SetCursor(from, to, ...) 948 | tskeleton#SetCursor(from, to, ?findAny=0, ?findOnly) 949 | 950 | *tskeleton#GetVar()* 951 | tskeleton#GetVar(name, ?default=g:name) 952 | Get the value of variable name from the destination buffer. 953 | 954 | *tskeleton#GetDestBuffer()* 955 | tskeleton#GetDestBuffer() 956 | 957 | *tskeleton#EvalInDestBuffer()* 958 | tskeleton#EvalInDestBuffer(code) 959 | Evaluate code in the destination buffer. 960 | 961 | *tskeleton#ExecInDestBuffer()* 962 | tskeleton#ExecInDestBuffer(code) 963 | Execute code in the destination buffer. 964 | 965 | *tskeleton#FindTemplate()* 966 | tskeleton#FindTemplate(template) 967 | 968 | *tskeleton#CollectTemplates()* 969 | tskeleton#CollectTemplates() 970 | 971 | *tskeleton#Setup()* 972 | tskeleton#Setup(template, ?unconditionally=0) 973 | Fill in a file template. 974 | 975 | *tskeleton#SelectTemplate()* 976 | tskeleton#SelectTemplate(ArgLead, CmdLine, CursorPos) 977 | Command line completion. 978 | 979 | *tskeleton#EditBitCompletion()* 980 | tskeleton#EditBitCompletion(ArgLead, CmdLine, CursorPos) 981 | Command line completion. 982 | 983 | *tskeleton#Edit()* 984 | tskeleton#Edit(?dir) 985 | Edit a file template. 986 | 987 | *tskeleton#BitsPath()* 988 | tskeleton#BitsPath(...) 989 | 990 | *tskeleton#EditBit()* 991 | tskeleton#EditBit(bit) 992 | Edit a skeleton bit. 993 | 994 | *tskeleton#NewFile()* 995 | tskeleton#NewFile(?template, ?dir, ?fileName) 996 | Create a new file template. 997 | 998 | *tskeleton#NewBufferMenuItem()* 999 | tskeleton#NewBufferMenuItem(menu, bit, ...) 1000 | 1001 | *tskeleton#FetchMiniBits()* 1002 | tskeleton#FetchMiniBits(dict, path, pattern, buildmenu) 1003 | 1004 | *tskeleton#MaybePathshorten()* 1005 | tskeleton#MaybePathshorten(filename) 1006 | 1007 | *tskeleton#FetchMiniBitsGenerator()* 1008 | tskeleton#FetchMiniBitsGenerator(filename, buildmenu) 1009 | 1010 | *tskeleton#ReplacePrototypeArgs()* 1011 | tskeleton#ReplacePrototypeArgs(text, rest) 1012 | 1013 | *tskeleton#PurifyBit()* 1014 | tskeleton#PurifyBit(bit) 1015 | 1016 | *tskeleton#BitDef()* 1017 | tskeleton#BitDef(name, ...) 1018 | 1019 | *tskeleton#BuildBufferMenu()* 1020 | tskeleton#BuildBufferMenu(prepareBits) 1021 | 1022 | *tskeleton#PrepareBits()* 1023 | tskeleton#PrepareBits(?filetype=&filetype, ?reset=0) 1024 | Prepare the buffer for use with tskeleton. 1025 | 1026 | *tskeleton#ResetBits()* 1027 | tskeleton#ResetBits(filetype) 1028 | 1029 | *tskeleton#SelectBit()* 1030 | tskeleton#SelectBit(ArgLead, CmdLine, CursorPos) 1031 | 1032 | *tskeleton#IsScratchBuffer()* 1033 | tskeleton#IsScratchBuffer() 1034 | 1035 | *tskeleton#Retrieve()* 1036 | tskeleton#Retrieve(name) 1037 | 1038 | *tskeleton#Bit()* 1039 | tskeleton#Bit(bit, ...) 1040 | tskeleton#Bit(bit, ?mode='n') 1041 | 1042 | *tskeleton#ExpandBitUnderCursor()* 1043 | tskeleton#ExpandBitUnderCursor(mode, ...) 1044 | tskeleton#ExpandBitUnderCursor(mode, ?bit="", ?default={}) 1045 | See also |g:tskelHyperComplete|. 1046 | 1047 | *tskeleton#WithSelection()* 1048 | tskeleton#WithSelection(pre) 1049 | 1050 | *tskeleton#Complete_use_omnifunc()* 1051 | tskeleton#Complete_use_omnifunc(bit, completions) 1052 | 1053 | *tskeleton#Complete_use_completefunc()* 1054 | tskeleton#Complete_use_completefunc(bit, completions) 1055 | 1056 | *tskeleton#Complete_scan_words()* 1057 | tskeleton#Complete_scan_words(bit, completions) 1058 | 1059 | *tskeleton#Complete_scan_tags()* 1060 | tskeleton#Complete_scan_tags(bit, completions) 1061 | 1062 | *tskeleton#GetCompletions()* 1063 | tskeleton#GetCompletions(func, bit) 1064 | 1065 | *tskeleton#Complete()* 1066 | tskeleton#Complete(findstart, base, ?default={}) 1067 | A function suitable for use as 'completefunc' or 'omnifunc'. 1068 | You have to accept a match with in order to trigger skeleton 1069 | expansion. See |popupmenu-keys|. 1070 | 1071 | *tskeleton#Placeholders()* 1072 | tskeleton#Placeholders(line1, line2) 1073 | 1074 | *tskeleton#LateExpand()* 1075 | tskeleton#LateExpand() 1076 | 1077 | *tskeleton#Repeat()* 1078 | tskeleton#Repeat(n, string, ?sep="\n") 1079 | 1080 | *tskeleton#InsertTable()* 1081 | tskeleton#InsertTable(rows, cols, rowbeg, rowend, celljoin) 1082 | 1083 | *tskeleton#HyperComplete_query()* 1084 | tskeleton#HyperComplete_query(mode, default) 1085 | 1086 | *tskeleton#HyperComplete_pum()* 1087 | tskeleton#HyperComplete_pum(mode, default) 1088 | 1089 | 1090 | ======================================================================== 1091 | autoload/tskeleton/functions.vim~ 1092 | 1093 | *tskeleton#functions#Initialize()* 1094 | tskeleton#functions#Initialize() 1095 | 1096 | *tskeleton#functions#FiletypeBits_vim()* 1097 | tskeleton#functions#FiletypeBits_vim(dict, filetype) 1098 | 1099 | 1100 | ======================================================================== 1101 | autoload/tskeleton/snippets.vim~ 1102 | 1103 | *g:tskeleton#snippets#force* 1104 | g:tskeleton#snippets#force (default: 0) 1105 | If true, allow snippets to overwrite other skeletons. 1106 | 1107 | *tskeleton#snippets#Initialize()* 1108 | tskeleton#snippets#Initialize() 1109 | 1110 | *tskeleton#snippets#FiletypeBits()* 1111 | tskeleton#snippets#FiletypeBits(dict, type) 1112 | 1113 | *tskeleton#snippets#Generator()* 1114 | tskeleton#snippets#Generator(filename) 1115 | 1116 | *Filename()* 1117 | Filename(...) 1118 | 1119 | *tskeleton#snippets#Preprocess()* 1120 | tskeleton#snippets#Preprocess(text) 1121 | 1122 | 1123 | ======================================================================== 1124 | autoload/tskeleton/tags.vim~ 1125 | 1126 | *tskeleton#tags#Initialize()* 1127 | tskeleton#tags#Initialize() 1128 | 1129 | *tskeleton#tags#BufferBits()* 1130 | tskeleton#tags#BufferBits(dict, filetype) 1131 | 1132 | *tskeleton#tags#Process_vim()* 1133 | tskeleton#tags#Process_vim(dict, tag) 1134 | 1135 | *tskeleton#tags#Process_ruby()* 1136 | tskeleton#tags#Process_ruby(dict, tag) 1137 | 1138 | *tskeleton#tags#Process_c()* 1139 | tskeleton#tags#Process_c(dict, tag) 1140 | 1141 | *tskeleton#tags#Process_java()* 1142 | tskeleton#tags#Process_java(dict, tag) 1143 | 1144 | 1145 | ======================================================================== 1146 | autoload/tskeleton/mini.vim~ 1147 | 1148 | *tskeleton#mini#Initialize()* 1149 | tskeleton#mini#Initialize() 1150 | 1151 | *tskeleton#mini#FiletypeBits()* 1152 | tskeleton#mini#FiletypeBits(dict, type) 1153 | 1154 | 1155 | ======================================================================== 1156 | autoload/tskeleton/abbreviations.vim~ 1157 | 1158 | *tskeleton#abbreviations#Reset()* 1159 | tskeleton#abbreviations#Reset() 1160 | 1161 | *tskeleton#abbreviations#Initialize()* 1162 | tskeleton#abbreviations#Initialize() 1163 | 1164 | *tskeleton#abbreviations#GetAbbreviations()* 1165 | tskeleton#abbreviations#GetAbbreviations() 1166 | 1167 | *tskeleton#abbreviations#BufferBits()* 1168 | tskeleton#abbreviations#BufferBits(dict, filetype) 1169 | 1170 | *tskeleton#abbreviations#Retrieve()* 1171 | tskeleton#abbreviations#Retrieve(bit, indent, ft) 1172 | 1173 | 1174 | ======================================================================== 1175 | autoload/tskeleton/omnicomplete.vim~ 1176 | 1177 | *tskeleton#omnicomplete#Initialize()* 1178 | tskeleton#omnicomplete#Initialize() 1179 | 1180 | *tskeleton#omnicomplete#FiletypeBits()* 1181 | tskeleton#omnicomplete#FiletypeBits(dict, type) 1182 | 1183 | 1184 | ======================================================================== 1185 | autoload/tskeleton/skeleton.vim~ 1186 | 1187 | *tskeleton#skeleton#Initialize()* 1188 | tskeleton#skeleton#Initialize() 1189 | 1190 | *tskeleton#skeleton#FiletypeBits()* 1191 | tskeleton#skeleton#FiletypeBits(dict, type) 1192 | 1193 | *tskeleton#skeleton#BufferBits()* 1194 | tskeleton#skeleton#BufferBits(dict, type) 1195 | 1196 | *tskeleton#skeleton#Generator()* 1197 | tskeleton#skeleton#Generator(filename) 1198 | 1199 | 1200 | ======================================================================== 1201 | autoload/tskeleton/completefunc.vim~ 1202 | 1203 | *tskeleton#completefunc#Initialize()* 1204 | tskeleton#completefunc#Initialize() 1205 | 1206 | *tskeleton#completefunc#FiletypeBits()* 1207 | tskeleton#completefunc#FiletypeBits(dict, type) 1208 | 1209 | 1210 | 1211 | vim:tw=78:fo=w2croql:isk=!-~,^*,^|,^":ts=8:ft=help:norl: 1212 | -------------------------------------------------------------------------------- /etc/tpl_tskeleton.txt: -------------------------------------------------------------------------------- 1 | *tskeleton.txt* tskeleton -- File Templates and Code Skeletons 2 | 3 | Author: Tom Link, micathom AT gmail com?subject=vim 4 | 5 | 6 | tskeleton provides file templates and code skeletons ("snippets" or "bits"). 7 | These templates may contain special tags that are replaced with some computed 8 | value (e.g., variables, user input ...), vimscript code, or place holders/jump 9 | positions (see |tskeleton-jump-positions|). 10 | 11 | Basic usage: 12 | Type `:new filename.ext`. If a skeleton for the respective filetype is 13 | defined (see |tskeleton-skeletons|), it will be read into the buffer. 14 | 15 | Type a partial name of a snippet (at least the first letter) and press 16 | (in insert mode) (see |tskeleton-key-bindings| for alternative 17 | key maps). If the name identifies a snippet/bit, it will be replaced with 18 | its expansion text. If there are several snippets beginning with that 19 | "name", you will be asked to select one from a list of matching 20 | snippets. 21 | 22 | can be configured to expand snippets but also (albeit disabled 23 | by default) abbreviations, functions (VIM script only), tags, word, 24 | 'completefunc' and 'omnifunc' items (see |g:tskelTypes| and 25 | |g:tskelHyperComplete| for details.) 26 | 27 | Press to jump to the next place holder (see 28 | |tskeleton#GoToNextTag()|). 29 | 30 | 31 | Demo -- tskeleton and the stakeholders (vimscript #3326) plugin: 32 | http://vimsomnia.blogspot.com/2010/11/tskeleton-and-stakeholders-vim-plugins.html 33 | 34 | 35 | Git: 36 | https://github.com/tomtom/tskeleton_vim 37 | 38 | 39 | For similar plugins see: http://vim.wikia.com/wiki/Snippet_Plugin_Comparison 40 | 41 | Limitations of tskeleton: 42 | - Place holders cannot be nested. 43 | - tskeleton was originally written for vim 6.0. I'd expect it to be 44 | less snappy than more modern and simpler plugins, although it 45 | tries to provide acceptable performance on slower computers by 46 | caching frequently reused data. 47 | 48 | Advantages of tskeleton with respect to some other plugins: 49 | - tskeleton provides for more complex templates (see 50 | |tskeleton-place-holder|) including conditional expansion, loops, 51 | inclusion of other templates, user queries etc. 52 | - Easy creation of camel case, all upper/lower case letter names etc. (see 53 | |tskeleton-modifiers|). 54 | 55 | It depends: 56 | - A place holder is some text in the buffer, i.e. tskeleton uses less magic 57 | when handling jump positions. As long as users don't replace all place 58 | holders, the buffer's contents most likely isn't valid code and an 59 | interpreter/compiler will most likely refuse to load it even if the 60 | code is never executed. 61 | 62 | 63 | ----------------------------------------------------------------------- 64 | *tskeleton-install* 65 | Install~ 66 | 67 | Edit the vba file and type: 68 | 69 | :so %% 70 | 71 | See :help vimball for details. 72 | 73 | It is recommended to use tskeleton in conjunction with the stakeholders plugin 74 | (vimscript #3326): 75 | 76 | http://www.vim.org/scripts/script.php?script_id=3326 77 | https://github.com/tomtom/stakeholders_vim 78 | 79 | If you don't already have some skeletons, you may want to download 80 | tskeleton-Samples.zip from: 81 | 82 | http://www.vim.org/scripts/script.php?script_id=1160 83 | 84 | or from 85 | 86 | https://github.com/tomtom/tskeletons 87 | 88 | Copy the files to your local vimfiles directory (see also |add-global-plugin|). 89 | The directory structure should look like this: 90 | 91 | ~/.vim/skeletons/ 92 | FILE TEMPLATES ... 93 | map/ 94 | MAP FILES FOR CONDITIONAL EXPANSION 95 | bits/ 96 | &filetype.txt (single line templates) 97 | general/ 98 | GENERAL CODE SKELETONS ... 99 | &filetype/ 100 | FILETYPE SPECIFIC CODE SKELETONS: ONE SKELETON PER FILE ... 101 | 102 | 103 | *tskeleton-snippets* 104 | tskeleton also provides partial support for snipMate snippets (see 105 | https://github.com/honza/snipmate-snippets). The following limitations apply: 106 | - tskeleton cannot handle nested tags/place holders 107 | 108 | 109 | *tskeleton-cache* 110 | In order to speed up things, tskeleton caches intermediate results. 111 | Those files are created in |g:tlib_cache|. By default, the old files 112 | will be removed from the cache every |g:tlib#cache#purge_every_days| 113 | days. In order to disable purging (e.g. if you purge the cache directory 114 | by means of a cron script), set |g:tlib#cache#purge_every_days| to -1. 115 | 116 | 117 | ----------------------------------------------------------------------- 118 | *tskeleton-usage* 119 | *tskeleton-skeletons* 120 | File templates~ 121 | 122 | The file skeletons are stored in the skeletons subdirectory. Which 123 | template is used for which new file is controlled by |:autocmd|s. This 124 | provides greater flexibility than a &filetype based approach as you can 125 | select templates on the basis of a filename pattern or a specific 126 | directory. 127 | 128 | Currently, the following file types are supported by default: 129 | 130 | - batch.bat 131 | - deplate.txt 132 | - latex.tex 133 | - php.inc.php 134 | - php.php 135 | - plugin.vim 136 | - ruby.rb 137 | - shell.sh 138 | - text.txt 139 | 140 | In order to add support for a new filetype, save a skeleton file to 141 | ~/.vim/skeletons/file.suffix and add something like this to your .vimrc 142 | file: > 143 | 144 | autocmd BufNewFile *.suffix TSkeletonSetup template.suffix 145 | autocmd BufNewFile /here/*.suffix TSkeletonSetup othertemplate.suffix 146 | 147 | 148 | Alternatively, you can store templates as: > 149 | 150 | ~/.vim/skeletons/templates/GROUP/FILETYPE PATTERN 151 | 152 | where GROUP is an arbitrary name for a collection of auto templates, 153 | FILETYPE is a know vim filetype, and the pattern is an encoded pattern (# == 154 | *, %%XX=Char XXh) for auto-generated autocmds. 155 | 156 | Example: Templates file names for some vim-related files: > 157 | 158 | ~/.vim/skeletons/templates/vim/help #%%2fvimfiles%%2fdoc%%2f#.txt 159 | ~/.vim/skeletons/templates/vim/vim #%%2fvimfiles#%%2fftplugin%%2f#.vim 160 | ~/.vim/skeletons/templates/vim/vim #%%2fvimfiles#%%2fsyntax%%2f#.vim 161 | 162 | < 163 | *tskeleton-place-holder* 164 | 165 | Tags (which look like <+...+>) serve two purposes: 166 | 167 | - marker for jump positions (see |tskeleton#GoToNextTag()|) 168 | - dynamic content expansion 169 | 170 | You can use tags to define cursor jump positions. tskeleton also 171 | supports some special tags that are expanded when inserting the 172 | skeleton. 173 | 174 | A list of special tags: 175 | *tSkeletion-<+FILE NAME ROOT+>* 176 | <+FILE NAME ROOT+> 177 | The file name root 178 | *tSkeletion-<+FILE NAME+>* 179 | <+FILE NAME+> 180 | The file name 181 | *tSkeletion-<+FILE SUFFIX+>* 182 | <+FILE SUFFIX+> 183 | The file suffix 184 | *tSkeletion-<+FILE DIRNAME+>* 185 | <+FILE DIRNAME+> 186 | The file's directory 187 | *tSkeletion-<+NOTE+>* 188 | <+NOTE+> 189 | A note 190 | *tSkeletion-<+DATE+>* 191 | <+DATE+> 192 | The current date (the format is controlled via 193 | g:tskelDateFormat) 194 | *tSkeletion-<+AUTHOR+>* 195 | <+AUTHOR+> 196 | The author's name (g:tskelUserName) 197 | *tSkeletion-<+EMAIL+>* 198 | <+EMAIL+> 199 | The author's e-mail (g:tskelUserEmail) 200 | *tSkeletion-<+COMPANY+>* 201 | <+COMPANY+> 202 | The author's company (g:tskelUserCompany) 203 | *tSkeletion-<+WEBSITE+>* 204 | <+WEBSITE+> 205 | The author's homepage (g:tskelUserWWW) 206 | *tSkeletion-<+LICENSE+>* 207 | <+LICENSE+> 208 | The name of the license this file is released under 209 | (g:tskelLicense) 210 | 211 | In order to define your own tag, you have to define a function called 212 | TSkeleton_TAGNAME() that returns the text to be filled in. 213 | 214 | *tskeleton-tags* 215 | tskeleton also supports the following pseudo-tags: 216 | 217 | <+CURSOR+> *tSkeletion-<+CURSOR+>* 218 | Where to place the cursor after insertion 219 | 220 | <+&NAME+> *tSkeletion-<+&+>* 221 | A vim option 222 | 223 | <+g:NAME+> *tSkeletion-<+g:+>* 224 | A global variable 225 | 226 | <+b:NAME+> *tSkeletion-<+b:+>* 227 | A buffer local variable 228 | 229 | <+?QUERY?+> *tSkeletion-<+?+>* 230 | Query[1] the user 231 | 232 | <+?VAR|QUERY?+> 233 | Query[1] the user and propose some choices from the variable VAR 234 | 235 | *tSkeletion-<+bit+>* 236 | <+bit:BIT+>, <+bit:BIT|"DEFAULT"+>, <+bit:BIT|COMMANDS+> 237 | Insert a bit; if the bit isn't defined for the current filetype, 238 | use DEFAULT; if DEFAULT matches ".*" insert it as a string; 239 | otherwise interpret it as a command sequence to be fed to normal 240 | 241 | <+tskel:TSKELETON+> *tSkeletion-<+tskel+>* 242 | Same as the above 243 | 244 | <+call:FUNCTION(ARGS)+> *tSkeletion-<+call+>* 245 | Insert the result value of some function 246 | 247 | <+include(TSKELETON)+> *tSkeletion-<+include+>* 248 | Another synonym for the above. 249 | 250 | <+execute(EX COMMAND)+> *tSkeletion-<+execute+>* 251 | Run a vim command. 252 | 253 | [1] If the query ends with a colon, the second question mark will be 254 | removed. Up to verson 2.4 VAR is a string, separating the items by an 255 | "\n". From 3.0 on, VAR is a list. 256 | 257 | NOTE: Flow control and loop tags are experimental and it's more than 258 | just likely that the output doesn't meet your expectations. 259 | 260 | Flow control: *tSkeletion-<+if+>* 261 | <+if(CONDITION)+> 262 | <+elseif(CONDITION)+> 263 | <+else+> 264 | <+endif+> 265 | 266 | Loops: *tSkeletion-<+for+>* 267 | <+for(VAR in LIST)+> 268 | <+endfor+>, <+endfor(VAR)+> 269 | If you nest for loops, you have to add the variable name to the 270 | endfor tag. And no, this isn't the most clever way to do this. 271 | 272 | Variables: *tSkeletion-<+let+>* 273 | <+let(VAR=VALUE)+> 274 | The variable will be unset or restored to its original value 275 | after processing the current template. 276 | VAR may have some modifiers attached: 277 | VAR? ... Set only if undefined 278 | VAR& ... Don't restore original variable 279 | 280 | Interaction: *tSkeletion-<+input+>* 281 | <+input(VAR, QUERY, [DEFAULT], [COMPLETION])+> 282 | This will insert the user input and set the variable VAR (unless 283 | empty), which can be used throughout the template. The variable 284 | will be removed after finishing the current template. If the 285 | variable was previously defined, the original value will be 286 | restored. 287 | If VAR ends with '!', no text will be inserted in the buffer. In 288 | this case any whitespace (including one newline) after the tag 289 | will be removed. See also the notes on |tSkeletion-<+input+>|. 290 | 291 | *tSkeletion-<+select+>* 292 | <+select(VAR, LIST, [TYPE='s'], [SEPARATOR=', '])+> 293 | Let the user select an item from a list. 294 | VAR is a string. 295 | TYPE is either 's' (single selection) or 'm' (multiple selection) -- 296 | see also |tlib#input#List()|. 297 | If TYPE is 'm', the results are joined with SEPARATOR. 298 | Example: > 299 | before(<+select("s:type", [":all", ":each"])+>) 300 | before(<+select("s:type", ["A", "B", "C", "D"], "m", "-")+>) 301 | < 302 | 303 | Other: *tSkeletion-<+nl+>* 304 | <+nl+> 305 | Insert a newline 306 | 307 | <+joinline+> *tSkeletion-<+joinline+>* 308 | Join with next line. Delete any whitespace. 309 | 310 | <+nop+> *tSkeletion-<+nop+>* 311 | Insert nothing (could be necessary in conjunction with the "for" 312 | tag) 313 | 314 | A wiki like table could then be constructed using a skeleton like this: > 315 | 316 | 317 | let s:my_rows = input('Rows: ') 318 | let s:my_cols = input('Columns: ') 319 | 320 | 321 | unlet! s:my_rows s:my_cols 322 | 323 | <+CURSOR+><+for(i in range(s:my_rows))+> 324 | |<+for(j in range(s:my_cols))+> <+CELL+> |<+endfor(j)+><+nop+> 325 | <+endfor(i)+> 326 | 327 | or: > 328 | 329 | <+input('s:my_rows?!', 'Rows: ')+> 330 | <+input('s:my_cols?!', 'Cols: ')+> 331 | <+for(i in range(s:my_rows))+> 332 | |<+for(j in range(s:my_cols))+> <+CURSOR+> |<+endfor(j)+><+nop+> 333 | <+endfor(i)+> 334 | 335 | NOTE: The <+nop+> is necessary in order to prevent the <+endfor+> tag to 336 | "eat" the newline. If we include this bit from another bit that already 337 | sets s:my_rows and/or s:my_cols, the user won't be queried again (because of 338 | the "?" in the input statement). E.g. > 339 | 340 | <+let(s:my_rows = 3)+> 341 | <+let(s:my_cols = 3)+> 342 | <+include(table)+> 343 | 344 | *tSkeletion-backslash* 345 | Any special tag can be preceded with a backslash in order to prevent 346 | expansion. Examples: > 347 | 348 | <+\if(foo=1)+> 349 | 350 | surprisingly expands to > 351 | 352 | <+if(foo=1)+> 353 | 354 | It's best to use global variables with "if" and "for" tags as the body 355 | is most likely evaluated in a different buffer in a hypothetically 356 | unknown context. 357 | 358 | 359 | *tskeleton-jump-positions* 360 | Unknown tags are kept in the expanded skeleton. These tags can be used 361 | as cursor jump marks. This syntax was originally used by imap (vimscript 362 | #244 or vimscript #475). If you don't want to install imap, you can also 363 | use |TSkeletonMapGoToNextTag()|. 364 | 365 | Nameless tags (<++>) will disappear when they are selected. 366 | 367 | Example:> 368 | 369 | case <+CURSOR+> in 370 | <+PATTERN+>) 371 | <+BODY+> 372 | ;; 373 | *) 374 | <+DEFAULT+> 375 | ;; 376 | esac 377 | <++> 378 | 379 | When you insert this skeleton, the cursor will be placed at 380 | "<+CURSOR+>". If you press , the cursor will jump to "<+PATTERN+>" 381 | (the tag will remain selected). If you press three times, the 382 | cursor will jump to "<++>" (the tag will be deleted). 383 | 384 | Check out the "test_tskeleton" skeleton for examples. 385 | 386 | 387 | *tskeleton-modifiers* 388 | Tags can be modified using modifiers, like in: > 389 | 390 | <+TAG NAME:MODIFIER+> 391 | 392 | Known modifiers: 393 | 394 | l :: lower case 395 | u :: upper case 396 | c :: capitalize 397 | C :: transform to CamelCase 398 | s/FROM/TO/ :: replace text (actually a s//g); this has to be the 399 | last modifier; the pattern separator can be selected 400 | arbitrarily 401 | 402 | Example for a ruby class template: > 403 | 404 | class <+FILE NAME ROOT:cs*\W*_*+> 405 | <+CURSOR+> 406 | end 407 | <++> 408 | 409 | ----------------------------------------------------------------------- 410 | *tskeleton-code-skeletons* 411 | *tskeleton-bits* 412 | Bits/Code Skeletons~ 413 | 414 | Smaller skeleton bits are stored in SKELETONS/bits/FILETYPE/ or 415 | SKELETONS/bits/general/. I.e., code skeletons can be filetype specific 416 | or generally available. 417 | 418 | The filenames of the bits may be grouped in submenus as in: 419 | 420 | ../tex/&Define.%%5Cnew&command 421 | ../tex/&Define.%%5Cnew&environment 422 | 423 | This will create skeletons for \newcommand and \newenvironment but will 424 | group the skeletons under the TSkel.Define. menu with the respective 425 | accelerators. 426 | 427 | *tskeleton-Types* *g:tskelTypes* 428 | *tskeleton#Initialize()* 429 | tskeleton supports several types of code templates: 430 | 431 | - skeleton (standard tskeleton functionality) 432 | - abbreviations (VIM abbreviations) 433 | - functions (VIM script functions extracted from :function) 434 | - mini ("mini" bits, one-liners etc.) 435 | - tags (tags-based code templates, requires ctags, I presume) 436 | 437 | Not all types are enabled by default. User have to select, which types 438 | they want to use, by setting the g:tskelTypes at start-up. When changing 439 | the variable, users might have to call tskeleton#Initialize(). 440 | 441 | *tskeleton-Skeleton* 442 | Smaller skeleton bits are stored in SKELETONS/bits/FILETYPE/ or 443 | SKELETONS/bits/general/. I.e., code skeletons can be filetype specific 444 | or generally available. 445 | 446 | Skeleton bits can be filled in by typing: > 447 | 448 | :TSkeletonBit NAME 449 | 450 | For this command, command line completion is implemented. Calling this 451 | command will insert the contents of the respective file below the 452 | current line. 453 | 454 | NOTE: Bit names should not contain ampersand (as these are interpreted 455 | as menu accelerators) and periods (which are used to construct 456 | submenus). Other special characters can be included by encoding them in 457 | hex form as %%XX as it is done in URLs. Example: "%%5Csection" becomes 458 | "\section". 459 | 460 | *tskeleton-key-bindings* 461 | The default key bindings for inserting code skeletons are: 462 | 463 | ... In insert mode, expand name before the cursor 464 | ## ... Expand name under cursor 465 | #t ... Insert code skeleton via command line 466 | ... In insert mode, expand the bit before the cursor (on 467 | a German keyboard this happens to be ) 468 | 469 | *g:tskelKeyword_{&filetype}* 470 | A bit name usually is the |word| under the cursor. If this doesn't fit 471 | your needs, you can define g:tskelKeyword_{&filetype} to define what 472 | makes up a skeleton name. Example: > 473 | 474 | let g:tskelKeyword_viki = '\(#\|{\)\?[^#{[:blank:]]\{-}' 475 | 476 | 477 | *tskeleton-embedded-code* 478 | Code skeletons may contain vim code that is evaluated before or after 479 | expanding the tags. The before/after blocks are fed to |:exec| and must 480 | not contain function definitions. 481 | 482 | NOTE: The "parser" is quite primitive. These tags have to start as 483 | single statement in a line at column 1, and they have to appear in the 484 | following order: 485 | 486 | ** 487 | Display an explanatory message after template expansion 488 | 489 | ** 490 | Execute code before template expansion in the target buffer 491 | 492 | ** 493 | Execute code after template expansion in the target buffer 494 | 495 | ** 496 | Execute code before template expansion in the template buffer 497 | 498 | ** 499 | Execute code after template expansion in the template buffer 500 | 501 | ** 502 | Make the bit available via |:abbreviate| under the enclosed name. 503 | 504 | ** 505 | Use this menu name instead of the default one. 506 | 507 | ** 508 | An expression that checks whether a bit is eligible in the 509 | current context. 510 | 511 | BibTeX example: > 512 | 513 | 514 | Insert a collection entry 515 | 516 | 517 | let b:tskelArticleID = input("ID of bibentry: ") 518 | if b:tskelArticleID == "" | let b:tskelArticleID = "<+CURSOR+>" | endif 519 | 520 | 521 | unlet b:tskelArticleID 522 | 523 | @INCOLLECTION{<+b:tskelArticleID+>, 524 | author = {<+CURSOR+>}, 525 | title = {<+ARTICLE TITLE+>}, 526 | crossref = {<+CROSSREF+>}, 527 | pages = {<+PAGES+>}, 528 | abstract = {[[~/Docs/Abstracts/<+b:tskelArticleID+>.txt]]}, 529 | } 530 | <++> 531 | 532 | In the above example, we query the user for an ID and insert this ID as 533 | entry key and as an abstract's file name. 534 | 535 | The before/after blocks are evaluated in the destination buffer. The 536 | variants here_before/here_after are evaluated in the scratch buffer for 537 | the current code skeleton. 538 | 539 | *tskeleton-groups* 540 | *g:tskelBitGroup_{&filetype}* 541 | Groups~ 542 | 543 | Some filetype's bits might be of use for other filetypes too. You can 544 | make them accessible by defining a g:tskelBitGroup_{&filetype} variable. 545 | E.g., in php mode all html bits are made accessible by setting this 546 | variable (the default): > 547 | 548 | let g:tskelBitGroup_php = ['php', 'html'] 549 | 550 | Bits of type "general" are always available. 551 | 552 | *tskeleton-context* 553 | *tskeleton-map* 554 | Maps -- Context-sensitive expansion~ 555 | 556 | To some extent, tskeleton is capable of offering the user only a small 557 | selection of eligible bits for a specific context if a map file 558 | ($VIMFILES/skeletons/map/{&filetype}) is provided. Such a map file is made up 559 | of regular expressions matching a specific context (before the cursor 560 | only) and a blank-separated list of eligible bits. The regexp and the 561 | list are separated by whitespace: > 562 | 563 | REGEXP BIT1 BIT2 ... BITn 564 | 565 | Example: > 566 | 567 | ]\\|\\n\\)* name= action= method= 568 | 569 | If an eligible bit is undefined, the name is inserted as is. I.e. you 570 | don't have to define skeletons for all these options and argument names. 571 | 572 | 573 | *tskeleton-minibits* 574 | Minibits~ 575 | 576 | Mini bits are kept in the files: 577 | 578 | - $CWD/.tskelmini 579 | - $VIMFILES/skeletons/bits/{&filetype}.txt 580 | 581 | These files contain whitespace-separated pairs of bit names and their 582 | expansions. These files are meant to keep expansions of accronyms and 583 | abbreviations and the like. Example: > 584 | 585 | IMHO In my humble opinion 586 | AFAIK As far as I know 587 | 588 | *tskeleton-menu* 589 | *g:tskelMenuPrefix* 590 | Menu~ 591 | 592 | If g:tskelMenuPrefix is non-empty, tskeleton will display a menu 593 | containing all eligible bits for a certain filetype. 594 | 595 | The menu can be hierarchical and certain entries may have shortcuts by 596 | properly naming the bits. Example: > 597 | 598 | &Environment.&Quote 599 | &Environment.Q&uotation 600 | 601 | This will create the submenu "Environment" that can be selected by 602 | typing "e" (on Windows) and two entries, the first of which can be 603 | selected by typing "q" and the second by typing "u". 604 | 605 | Be aware that the actual bit names are Quote and Quotation (i.e. the 606 | submenu and the ampersand are stripped off). 607 | 608 | 609 | ----------------------------------------------------------------------- 610 | *tskeleton-utilities* 611 | Utilities~ 612 | 613 | *tskeleton#IncreaseRevisionNumber()* 614 | The function tskeleton#IncreaseRevisionNumber() provides a way to 615 | automatically update a revision number in the form > 616 | 617 | @Revision: 1.0.393 618 | 619 | In order to use this function, add something like this to your |vimrc| 620 | file: > 621 | 622 | autocmd BufWritePre * call tskeleton#IncreaseRevisionNumber() 623 | 624 | *:TSkeletonCleanUpBibEntry* 625 | The TSkeletonCleanUpBibEntry command can be used to purge the current bibtex 626 | entry from expendable fields (i.e., lines matching <+.\{-}+>). 627 | 628 | For bibtex files, this command is bound to: tc 629 | 630 | *TSkeletonMapGoToNextTag()* 631 | *tskeleton#GoToNextTag()* 632 | If g:tskelMapGoToNextTag is true, the map will be enabled. (That 633 | is the key that was also used by the imaps.vim plugin.) Press to 634 | jump between tags. 635 | 636 | This function provides one or two extras over the version of imaps.vim. 637 | An explanation: 638 | 639 | - ###, +++, ???, !!! are used as markers too. 640 | - If a marker is empty (e.g. <++>), the marker will be removed (as 641 | imaps.vim does). 642 | - If a marker matches <+NAME/DEFAULT+>, the marker will be replaced 643 | with DEFAULT. 644 | - If a snippet contains numbered placeholders (e.g. <+1+>), these 645 | will be selected first in increasing number. 646 | 647 | 648 | %s 649 | -------------------------------------------------------------------------------- /plugin/tskeleton.vim: -------------------------------------------------------------------------------- 1 | " tSkeleton.vim 2 | " @Author: Tom Link (micathom AT gmail com?subject=vim) 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Created: 21-Sep-2004. 5 | " @Last Change: 2012-10-25. 6 | " @Revision: 3958 7 | " 8 | " GetLatestVimScripts: 1160 1 tskeleton.vim 9 | " http://www.vim.org/scripts/script.php?script_id=1160 10 | 11 | if &cp || exists("loaded_tskeleton") "{{{2 12 | finish 13 | endif 14 | if !exists('loaded_tlib') || loaded_tlib < 110 15 | runtime plugin/02tlib.vim 16 | if !exists('loaded_tlib') || loaded_tlib < 110 17 | echoerr "tSkeleton requires tlib >= 1.10" 18 | finish 19 | endif 20 | endif 21 | let loaded_tskeleton = 502 22 | 23 | 24 | if !exists("g:tskelDir") "{{{2 25 | let g:tskelDir = get(split(globpath(&rtp, 'skeletons/'), '\n'), 0, '') 26 | endif 27 | if !isdirectory(g:tskelDir) "{{{2 28 | echoerr 'tSkeleton: g:tskelDir ('. g:tskelDir .') isn''t readable. See :help tSkeleton-install for details!' 29 | finish 30 | endif 31 | let g:tskelDir = tlib#dir#CanonicName(g:tskelDir) 32 | 33 | if !exists('g:tskelGlobalBitsPath') "{{{2 34 | " A comma-separated list of directories (see |globpath()|) for 35 | " globally available bits. If empty, use all "skeletons/bits/" 36 | " subdirectories in 'runtimepath'. 37 | let g:tskelGlobalBitsPath = exists('g:tskelBitsDir') ? g:tskelBitsDir : '' "{{{2 38 | endif 39 | 40 | if !exists('g:tskelLocalBitsDirs') "{{{2 41 | " A list of directories that contains buffer-local bits. 42 | let g:tskelLocalBitsDirs = ['.tskel', '_tskel'] "{{{2 43 | endif 44 | 45 | let g:tskeleton_SetFiletype = 1 46 | 47 | if !exists("g:tskelMapLeader") 48 | " Map leader for maps in normal mode. 49 | let g:tskelMapLeader = "#" "{{{2 50 | endif 51 | 52 | if !exists("g:tskelMapInsert") 53 | " Map leader for maps in insert mode. 54 | let g:tskelMapInsert = '' "{{{2 55 | endif 56 | 57 | if !exists("g:tskelAddMapInsert") 58 | " If true, insert |g:tskelMapInsert| after expanding a bit. This 59 | " could be useful if you plan to map |g:tskelMapInsert| to something 60 | " like . 61 | let g:tskelAddMapInsert = 0 "{{{2 62 | endif 63 | 64 | if !exists("g:tskelMenuCache") 65 | " If non-empty, cache menu items. 66 | let g:tskelMenuCache = '.tskelmenu' "{{{2 67 | endif 68 | 69 | if !exists("g:tskelMenuPrefix") 70 | " :nodoc: 71 | " Prefix for menu items. 72 | let g:tskelMenuPrefix = 'TSke&l' "{{{2 73 | endif 74 | 75 | if !exists("g:tskelMapGoToNextTag") 76 | " If non-empty, create maps for "go to next place holder" feature. 77 | " This map should work in normal, visual, selection, and insert 78 | " mode. 79 | let g:tskelMapGoToNextTag = '' "{{{2 80 | endif 81 | 82 | if !exists("g:tskelMapHyperComplete") "{{{2 83 | if empty(maparg('') . maparg('', 'i')) 84 | " Key to invoke hyper completion (see |g:tskelHyperComplete|). 85 | let g:tskelMapHyperComplete = '' "{{{2 86 | else 87 | let g:tskelMapHyperComplete = '' 88 | endif 89 | endif 90 | 91 | if !exists("g:tskelHyperComplete") "{{{2 92 | " A dictionary of items that should be offered on "hyper complete". 93 | let g:tskelHyperComplete = {'use_completefunc': 1, 'scan_words': 1, 'scan_tags': 1} "{{{2 94 | endif 95 | 96 | if !exists('g:tskelHyperType') 97 | " Either query or pum. 98 | " If you set the variable to "pum", you have to accept completions 99 | " with . 100 | " This variable must be set in your |vimrc| file before loading the 101 | " tskeleton plugin. 102 | let g:tskelHyperType = 'query' "{{{2 103 | endif 104 | 105 | 106 | " :nodoc: 107 | " Create maps for the "go to next placeholder" functionality (see g:tskelMapGoToNextTag|). 108 | function! TSkeletonMapGoToNextTag() "{{{3 109 | let map = type(g:tskelMapGoToNextTag) == 0 ? '' : g:tskelMapGoToNextTag 110 | exec 'nnoremap ' map ':call tskeleton#GoToNextTag()' 111 | exec 'vnoremap ' map ':call tskeleton#GoToNextTag()' 112 | exec 'inoremap ' map ':call tskeleton#GoToNextTag()' 113 | endf 114 | if !empty(g:tskelMapGoToNextTag) 115 | call TSkeletonMapGoToNextTag() 116 | endif 117 | 118 | 119 | " In the current buffer, map a:key so that 120 | " - If the cursor is located at the beginning of the line or if the 121 | " the cursor is over a whitespace character, indent the current 122 | " line 123 | " - otherwise expand the bit under the cursor or (if not suitable bit 124 | " was found) use &omnifunc, &completefunc, tags, and (as fallback 125 | " strategy) the words in the buffer as possible completions. 126 | function! TSkeletonMapHyperComplete(key, ...) "{{{3 127 | let default = a:0 >= 1 ? a:1 : '==' 128 | if g:tskelHyperType == 'pum' 129 | exec 'inoremap '. a:key .' =tskeleton#HyperComplete_'. g:tskelHyperType .'("i", '. string(default) .')' 130 | elseif g:tskelHyperType == 'query' 131 | exec 'inoremap '. a:key .' :call tskeleton#HyperComplete_'. g:tskelHyperType .'("i", '. string(default) .')' 132 | else 133 | echoerr "tSkeleton: Unknown type for g:tskelHyperType: "+ g:tskelHyperType 134 | endif 135 | exec 'noremap '. a:key .' :call tskeleton#HyperComplete_query("n", '. string(default) .')' 136 | endf 137 | if !empty(g:tskelMapHyperComplete) 138 | call TSkeletonMapHyperComplete(g:tskelMapHyperComplete) 139 | endif 140 | 141 | 142 | " Fill in a file template. 143 | command! -bang -nargs=* -complete=custom,tskeleton#SelectTemplate TSkeletonSetup 144 | \ call tskeleton#Setup(, !empty("")) 145 | 146 | 147 | " Edit a file template. 148 | command! -nargs=? -complete=custom,tskeleton#SelectTemplate TSkeletonEdit 149 | \ call tskeleton#Edit() 150 | 151 | 152 | " Edit a bit. 153 | command! -nargs=? -complete=customlist,tskeleton#EditBitCompletion TSkeletonEditBit 154 | \ call tskeleton#EditBit() 155 | 156 | 157 | " Create a new file template. 158 | command! -nargs=* -complete=custom,tskeleton#SelectTemplate TSkeletonNewFile 159 | \ call tskeleton#NewFile() 160 | 161 | 162 | " Reset a buffer's bits. Use this command if the list of bits known in a 163 | " buffer is outdated. 164 | command! -bar -nargs=? TSkeletonBitReset call tskeleton#ResetBits() 165 | 166 | 167 | " Insert a bit/snippet. 168 | command! -nargs=? -complete=custom,tskeleton#SelectBit TSkeletonBit 169 | \ call tskeleton#Bit() 170 | 171 | 172 | " :nodoc: 173 | " Remove lines containing placeholders from a bibtex entry. 174 | command! TSkeletonCleanUpBibEntry call tskeleton#CleanUpBibEntry() 175 | 176 | if !empty(g:tskelMapLeader) 177 | " noremap tt ""diw:TSkeletonBit " 178 | exec "noremap ". g:tskelMapLeader ."t :TSkeletonBit " 179 | 180 | exec "nnoremap ". g:tskelMapLeader ."# :call tskeleton#ExpandBitUnderCursor('n')" 181 | if g:tskelAddMapInsert 182 | exec "inoremap ". g:tskelMapInsert ." :call tskeleton#ExpandBitUnderCursor('i','', {'string':". string(g:tskelMapInsert) ."})" 183 | else 184 | exec "inoremap ". g:tskelMapInsert ." :call tskeleton#ExpandBitUnderCursor('i')" 185 | endif 186 | 187 | exec "vnoremap ". g:tskelMapLeader ."# d:call tskeleton#WithSelection('')" 188 | exec "vnoremap ". g:tskelMapLeader ." d:call tskeleton#WithSelection(' ')" 189 | 190 | exec "nnoremap ". g:tskelMapLeader ."x :call tskeleton#LateExpand()" 191 | exec "vnoremap ". g:tskelMapLeader ."x `<:call tskeleton#LateExpand()" 192 | endif 193 | 194 | 195 | augroup tSkeleton 196 | autocmd! 197 | if !exists("g:tskelDontSetup") "{{{2 198 | function! s:DefineAutoCmd(template) "{{{3 199 | " TLogVAR a:template 200 | " let sfx = fnamemodify(a:template, ':e') 201 | let tpl = fnamemodify(a:template, ':t') 202 | " TLogVAR tpl 203 | let filetype = tlib#url#Decode(matchstr(tpl, '^\S\+')) 204 | let pattern = matchstr(tpl, '^\S\+ \+\zs.*$') 205 | if !empty(filetype) && !empty(pattern) 206 | " TLogVAR pattern 207 | let pattern = substitute(pattern, '#', '*', 'g') 208 | " TLogVAR pattern 209 | let pattern = tlib#url#Decode(pattern) 210 | " TLogVAR pattern 211 | exec 'autocmd BufNewFile' escape(pattern, ' ') 'set ft='. escape(filetype, ' ') '| TSkeletonSetup' a:template 212 | endif 213 | endf 214 | 215 | call map(split(glob(tlib#file#Join([g:tskelDir, 'templates', '**'], 1)), '\n'), 'isdirectory(v:val) || s:DefineAutoCmd(v:val)') 216 | delfunction s:DefineAutoCmd 217 | 218 | for [s:pat, s:tpl] in [ 219 | \ ["*.bat", "batch.bat"], 220 | \ ["*.tex", "latex.tex"], 221 | \ ["tc-*.rb", "tc-ruby.rb"], 222 | \ ["*.rb", "ruby.rb"], 223 | \ ["*.rbx", "ruby.rb"], 224 | \ ["*.sh", "shell.sh"], 225 | \ ["*.txt", "text.txt"], 226 | \ ["*.vim", "plugin.vim"], 227 | \ ["*.inc.php", "php.inc.php"], 228 | \ ["*.class.php", "php.class.php"], 229 | \ ["*.php", "php.php"], 230 | \ ["*.tpl", "smarty.tpl"], 231 | \ ["*.html", "html.html"] 232 | \ ] 233 | if filereadable(tlib#file#Join([g:tskelDir, s:tpl])) 234 | exec 'autocmd BufNewFile' s:pat 'TSkeletonSetup' s:tpl 235 | endif 236 | endfor 237 | 238 | endif 239 | 240 | exec 'autocmd BufNewFile,BufRead '. escape(g:tskelDir, ' ') .'* if g:tskeleton_SetFiletype | set ft=tskeleton | endif' 241 | autocmd FileType * call tskeleton#PrepareBits(&filetype) 242 | autocmd SessionLoadPost,BufEnter * if (g:tskelMenuPrefix != '' && g:tskelMenuCache != '' && !tskeleton#IsScratchBuffer()) | call tskeleton#BuildBufferMenu(1) | endif 243 | 244 | autocmd FileType bib if !hasmapto(":TSkeletonCleanUpBibEntry") | exec "noremap ". g:tskelMapLeader ."c :TSkeletonCleanUpBibEntry" | endif 245 | augroup END 246 | 247 | 248 | " call tskeleton#PrepareBits('general') 249 | 250 | -------------------------------------------------------------------------------- /skeletons/README_tskeleton.txt: -------------------------------------------------------------------------------- 1 | Skeletons for the tSkeleton vim plugin: 2 | http://www.vim.org/scripts/script.php?script_id=1160 3 | 4 | By default, this is the directory where tskeleton searches for skeletons. This directory may contain three types of files: 5 | 6 | 1. Manually configured skeletons, loaded from an autocommand. Example: This will load a file plain.txt from this directory when creating new files whose extension is "txt": 7 | 8 | autocmd BufNewFile *.txt TSkeletonSetup plain.txt 9 | 10 | 2. Automatically configured skeletons are kept in the "templates" subdirectory. tskeleton will automatically define suitable autocommands for you. The effect of the above example could also be achieved by saving the template as 11 | 12 | ".../templates/text/text #.vim" 13 | 14 | 3. "Bits" are skeletons for small portions of code. These are saved in the "bits" subdirectory. Example: The bits for, say, vimscript 15 | 16 | files are kept in ".../bits/vim/" 17 | 18 | -------------------------------------------------------------------------------- /syntax/tskeleton.vim: -------------------------------------------------------------------------------- 1 | " tskeleton.vim 2 | " @Author: Tom Link (micathom AT gmail com?subject=vim) 3 | " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) 4 | " @Created: 30-Dez-2003. 5 | " @Last Change: 2009-02-15. 6 | " @Revision: 0.493 7 | 8 | if version < 600 9 | syntax clear 10 | elseif exists("b:current_syntax") 11 | finish 12 | endif 13 | 14 | let s:tskel_filetype=expand("%:p:h:t") 15 | if s:tskel_filetype != 'tskeleton' 16 | try 17 | exec "runtime! syntax/". s:tskel_filetype .".vim" 18 | unlet b:current_syntax 19 | catch 20 | endtry 21 | endif 22 | 23 | if s:tskel_filetype == 'vim' 24 | syn region tskeletonProcess matchgroup=tskeletonProcessMarker 25 | \ start='^\s*<\z(tskel:[a-z_:]\+\)>\s*$' end='^\s*\s*$' 26 | else 27 | syntax include @Vim syntax/vim.vim 28 | syn region tskeletonProcess matchgroup=tskeletonProcessMarker 29 | \ start='^\s*<\z(tskel:[a-z_:]\+\)>\s*$' end='^\s*\s*$' 30 | \ contains=@Vim 31 | endif 32 | 33 | unlet s:tskel_filetype 34 | 35 | " Define the default highlighting. 36 | " For version 5.7 and earlier: only when not done already 37 | " For version 5.8 and later: only when an item doesn't have highlighting yet 38 | if version >= 508 || !exists("did_tskeleton_syntax_inits") 39 | if version < 508 40 | let did_tskeleton_syntax_inits = 1 41 | " :nodoc: 42 | command! -nargs=+ HiLink hi link 43 | else 44 | " :nodoc: 45 | command! -nargs=+ HiLink hi def link 46 | endif 47 | 48 | HiLink tskeletonProcessMarker Statement 49 | 50 | delcommand HiLink 51 | endif 52 | 53 | --------------------------------------------------------------------------------