├── Support └── bin │ ├── ctags-objc │ └── tmctags ├── info.plist ├── README.mdown └── Commands ├── Find Tags.tmCommand ├── Update Tags.tmCommand └── Help.tmCommand /Support/bin/ctags-objc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textmate/ctags.tmbundle/master/Support/bin/ctags-objc -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | contactEmailRot13 6 | tregv-grkgzngr@ovgneg.pbz 7 | contactName 8 | Gerd Knops 9 | deleted 10 | 11 | E0B23ED0-7602-494B-8C81-6C5929AAF98C 12 | 13 | description 14 | The <a href="http://ctags.sourceforge.net/">ctags</a> system allows you to jump to the definition of a symbol. This bundle adds such support to TextMate. 15 | name 16 | CTags 17 | ordering 18 | 19 | F82D2DF8-6914-4EEC-BA46-F1E4B1716108 20 | 4E4A0404-8560-483A-B975-E53F6A6B7E25 21 | 6A99FDF6-5DB4-4CBE-91F8-4B82D637F8AD 22 | CF06E855-A45F-4AC0-A5F3-D9A99B2D7059 23 | 24 | uuid 25 | 0D39D7BD-CD02-48EF-BB9C-2210BFFC5AD7 26 | 27 | 28 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | You can install this bundle in TextMate by opening the preferences and going to the bundles tab. After installation it will be automatically updated for you. 4 | 5 | # General 6 | 7 | * [Bundle Styleguide](http://kb.textmate.org/bundle_styleguide) — _before you make changes_ 8 | * [Commit Styleguide](http://kb.textmate.org/commit_styleguide) — _before you send a pull request_ 9 | * [Writing Bug Reports](http://kb.textmate.org/writing_bug_reports) — _before you report an issue_ 10 | 11 | # License 12 | 13 | If not otherwise specified (see below), files in this repository fall under the following license: 14 | 15 | Permission to copy, use, modify, sell and distribute this 16 | software is granted. This software is provided "as is" without 17 | express or implied warranty, and with no claim as to its 18 | suitability for any purpose. 19 | 20 | An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a “-license” suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example “tidy” is accompanied by “tidy-license.txt”. -------------------------------------------------------------------------------- /Commands/Find Tags.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env bash 9 | [[ -f "${TM_SUPPORT_PATH}/lib/bash_init.sh" ]] && . "${TM_SUPPORT_PATH}/lib/bash_init.sh" 10 | 11 | exec "$TM_BUNDLE_SUPPORT/bin/tmctags" 12 | 13 | fallbackInput 14 | document 15 | input 16 | selection 17 | inputFormat 18 | text 19 | name 20 | Find Tags 21 | outputCaret 22 | afterOutput 23 | outputFormat 24 | html 25 | outputLocation 26 | newWindow 27 | scope 28 | source dyn.modifier.command & dyn.modifier.shift 29 | semanticClass 30 | callback.single-click 31 | uuid 32 | 4E4A0404-8560-483A-B975-E53F6A6B7E25 33 | version 34 | 2 35 | 36 | 37 | -------------------------------------------------------------------------------- /Commands/Update Tags.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env bash 9 | [[ -f "${TM_SUPPORT_PATH}/lib/bash_init.sh" ]] && . "${TM_SUPPORT_PATH}/lib/bash_init.sh" 10 | 11 | # just to remind you of some useful environment variables 12 | # see Help / Environment Variables for the full list 13 | #echo File: "$TM_FILEPATH" 14 | #echo Word: "$TM_CURRENT_WORD" 15 | #echo Selection: "$TM_SELECTED_TEXT" 16 | 17 | exec "$TM_BUNDLE_SUPPORT/bin/tmctags" update 18 | 19 | input 20 | none 21 | inputFormat 22 | text 23 | keyEquivalent 24 | ^~@t 25 | name 26 | Update Tags 27 | outputCaret 28 | afterOutput 29 | outputFormat 30 | text 31 | outputLocation 32 | toolTip 33 | scope 34 | source 35 | uuid 36 | F82D2DF8-6914-4EEC-BA46-F1E4B1716108 37 | version 38 | 2 39 | 40 | 41 | -------------------------------------------------------------------------------- /Commands/Help.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | bundleUUID 8 | 0D39D7BD-CD02-48EF-BB9C-2210BFFC5AD7 9 | command 10 | #!/usr/bin/env bash 11 | [[ -f "${TM_SUPPORT_PATH}/lib/bash_init.sh" ]] && . "${TM_SUPPORT_PATH}/lib/bash_init.sh" 12 | 13 | . "$TM_SUPPORT_PATH/lib/webpreview.sh" 14 | html_header "CTags Help" "CTags" 15 | 16 | Markdown.pl <<'EOF'|SmartyPants.pl 17 | 18 | CTags.tmbundle 19 | --------------- 20 | 21 | The CTags bundle allows you to quickly look up function definitions, variables etc. It uses the [Universal Ctags][1] program freely available under the terms of the [GNU General Public License][2] to generate a list of definitions, and presents any match for the current word when invoked. 22 | 23 | Usage 24 | ----- 25 | 26 | With the cursor over a word for which you want to see the definition, select *CTags/Find Tags*. Alternatively you can Shift-Command-click a word to look it up. A window will show up listing all locations where the term was defined, as well as your current location so you can easily find your way back. If only one location is found, TextMate will jump there (this behavior can be changed with the *TmCtagsAutoJump* environment variable, see below). 27 | 28 | If you modify the source code, the definition list will become out of sync with your code. Invoke *CTags/Update Tags* to update it. 29 | 30 | **Note:** The definitions are stored in a file named *tmtags* in your project root directory. It is safe to delete this file when no longer needed. The bundle will recreate it on the fly whenever needed. 31 | 32 | To exclude certain files or directories (eg source control files), add the appropiate options in an [option file][3]. 33 | 34 | --exclude=*~ 35 | --exclude=\._* 36 | --exclude=*\.bak 37 | --exclude=\.svn 38 | --exclude=_darcs 39 | 40 | Please see the ctags man page or the [Universal Ctags][1] documentation for more information. 41 | 42 | 43 | Configuration 44 | ------------- 45 | 46 | The CTags bundle can be configured by adding environment variables, either to a project to only change the behavior within a project, or globally (TextMate/Preferences/Advanced/Shell Variables). The following variables are honored: 47 | 48 | * TmCtagsAutoJump 49 | 50 | Set this variable to 0 to avoid TextMate jumping when a unique definition is found. Default value: *1*. 51 | 52 | * TmCtagsTagFileName 53 | 54 | The file name used to store tags in. Default is *tmtags*. 55 | 56 | * TmCtagsHistoryFileName 57 | 58 | The file name used to store the history in. Default is *tmtagsHistory*. 59 | 60 | * TmCtagsHistorySize 61 | 62 | How many previous locations to show in the *You where here* section. Use 0 to disable creation of history file. Default value: *10*. 63 | 64 | * TM\_TAGS\_FILE 65 | 66 | For backward-compatibility with the *Lookup Definition (ctags)* command from the Source bundle. Only makes sense inside a project. If set must contain the full path and filename for the tags file ctags will use. The path also is the root from which ctags does its work (although additional directories can be added). 67 | 68 | * TmCtagsFlags 69 | 70 | Any additional flags or options the ctags program should honor. 71 | 72 | * TmCtagsTimeout 73 | 74 | The timeout in seconds after which ctags is considered hanging (there are some bugs in ctags) and it is killed. Default is 30 seconds. For really large projects that may need to be increased. 75 | 76 | * TmCtagsSoundDir 77 | 78 | Directory in which sound files are expected. Default is *'/System/Library/Sounds'*. 79 | 80 | * TmCtagsOkSingleSound 81 | 82 | The name for the sound file played when a unique definition is found. If the extension is *.aiff* it can be omitted. Set to empty string for no sound. Default is an empty string. 83 | 84 | * TmCtagsOkMultiSound 85 | 86 | The name for the sound file played when multiple definitions are found. If the extension is *.aiff* it can be omitted. Set to empty string for no sound. Default is *Frog*. 87 | 88 | * TmCtagsErrorSound 89 | 90 | The name for the sound file played when no definitions are found. If the extension is *.aiff* it can be omitted. Set to empty string for no sound. Default is *Sosumi*. 91 | 92 | * TM\_CTAGS\_ADDITIONAL\_DIRECTORIES 93 | 94 | Additional directories for CTags to process for tags. Directories should be separated by the colon character (":"). 95 | 96 | * TmCtagsAlternatePgm 97 | 98 | The path to an alternate ctags executable. Any program can be specified as long as it produces the proper ctags output. 99 | 100 | * TmCtagsAlternateFlags 101 | 102 | Provides alternate flags (or no flags) to the configured ctags program. 103 | 104 | Credits 105 | ------- 106 | 107 | This bundle is maintained by [Gerd Knops][4]. 108 | 109 | Feedback is welcome: gerti-ctagstmb@bitart.com 110 | 111 | [1]: https://ctags.io 112 | [2]: http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html 113 | [3]: https://docs.ctags.io/en/latest/option-file.html 114 | [4]: http://gerd.knops.com/ 115 | 116 | EOF 117 | html_footer 118 | 119 | input 120 | none 121 | inputFormat 122 | text 123 | name 124 | CTags Help 125 | outputCaret 126 | afterOutput 127 | outputFormat 128 | html 129 | outputLocation 130 | newWindow 131 | scope 132 | source 133 | uuid 134 | CF06E855-A45F-4AC0-A5F3-D9A99B2D7059 135 | version 136 | 2 137 | 138 | 139 | -------------------------------------------------------------------------------- /Support/bin/tmctags: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | ############################################################################### 3 | # Copyright 2005, 2005 BITart Gerd Knops, All rights reserved. 4 | # 5 | # Project : BITart 6 | # File : tmctags 7 | # Author : Gerd Knops gerti@BITart.com 8 | # 9 | ############################################################################### 10 | # 11 | # History: 12 | # 051101 Creation of file 13 | # 060628 Modified for use inside CTags.tmbundle 14 | # 140912 Support alternate ctags program 15 | # 16 | ############################################################################### 17 | # 18 | # Description: 19 | # ctags support for TextMate 20 | # 21 | # $Id:$ 22 | # 23 | ############################################################################### 24 | # 25 | # DISCLAIMER 26 | # 27 | # BITart and Gerd Knops make no warranties, representations or commitments 28 | # with regard to the contents of this software. BITart and Gerd Knops 29 | # specifically disclaim any and all warranties, whether express, implied or 30 | # statutory, including, but not limited to, any warranty of merchantability 31 | # or fitness for a particular purpose, and non-infringement. Under no 32 | # circumstances will BITart or Gerd Knops be liable for loss of data, 33 | # special, incidental or consequential damages out of the use of this 34 | # software, even if those damages were foreseeable, or BITart or Gerd Knops 35 | # was informed of their potential. 36 | # 37 | ############################################################################### 38 | # Configuration 39 | ############################################################################### 40 | 41 | use strict; 42 | 43 | our $DEBUG=0; 44 | 45 | our $TagFileName=&setFromEnv('TmCtagsTagFileName','tmtags'); 46 | our $CtagsFlags=&setFromEnv('TmCtagsAlternateFlags','-f tm_ctags --fields=Kn --excmd=pattern -R'); 47 | our $CtagsOptFlags=&setFromEnv('TmCtagsFlags',''); 48 | our $AutoJump=&setFromEnv('TmCtagsAutoJump',1); 49 | our $CtagsPGM=&setFromEnv('TmCtagsAlternatePgm', "$ENV{'TM_BUNDLE_SUPPORT'}/bin/ctags-objc"); 50 | our $CtagsPGMtmplugin="$ENV{'HOME'}/Library/Application Support/TextMate/PlugIns/TmCodeBrowser.tmplugin/Contents/Resources/ctags"; 51 | our $CtagsTimeout=&setFromEnv('TmCtagsTimeout',30); # timeout if ctags does not finish within x seconds 52 | 53 | our $CtagsHistoryFileName=&setFromEnv('TmCtagsHistoryFileName','tmtagsHistory'); 54 | our $CtagsHistorySize=&setFromEnv('TmCtagsHistorySize',10); # number of history lines 55 | 56 | #our $OkSingleSound=&setFromEnv('TmCtagsOkSingleSound','Ping'); 57 | our $OkSingleSound=&setFromEnv('TmCtagsOkSingleSound','Tink'); 58 | our $OkMultiSound=&setFromEnv('TmCtagsOkMultiSound','Frog'); 59 | our $ErrorSound=&setFromEnv('TmCtagsErrorSound','Sosumi'); 60 | our $SoundDir=&setFromEnv('TmCtagsSoundDir','/System/Library/Sounds'); 61 | 62 | our $ExitDiscard=200; 63 | our $ExitReplaceText=201; 64 | our $ExitReplaceDopcument=202; 65 | our $ExitInsertText=203; 66 | our $ExitInsertSnippet=204; 67 | our $ExitShowHtml=205; 68 | our $ExitShowToolTip=206; 69 | our $ExitCreateNewDocument=207; 70 | 71 | 72 | ############################################################################### 73 | # Main 74 | ############################################################################### 75 | 76 | my $cmd=''; 77 | $cmd=shift if(scalar(@ARGV>0)); 78 | 79 | if($cmd eq 'update') 80 | { 81 | print &updateTags(); 82 | } 83 | elsif($cmd eq 'last') 84 | { 85 | &lastTag(); 86 | } 87 | elsif($cmd eq '') 88 | { 89 | &findTags(); 90 | } 91 | else 92 | { 93 | die("Unknown command '$cmd'\n"); 94 | } 95 | 96 | ############################################################################### 97 | # Subroutines 98 | ############################################################################### 99 | sub setFromEnv { 100 | my $name=shift; 101 | my $default=shift; 102 | 103 | return $ENV{$name} if(exists($ENV{$name})); 104 | 105 | return $default; 106 | } 107 | 108 | sub findCtagsPGM { 109 | return $CtagsPGM if($CtagsPGM ne '' && -x $CtagsPGM); 110 | 111 | #return $CtagsPGMtmplugin if(-x($CtagsPGMtmplugin)); 112 | 113 | die("Can't find exuberant ctags!\n"); 114 | } 115 | 116 | sub findTagsDirStartingAt { 117 | 118 | my $dir=shift // ''; 119 | 120 | while($dir ne '') 121 | { 122 | #print "Checking dir $dir\n"; 123 | return $dir if(-f "$dir/$TagFileName"); 124 | 125 | $dir=~s/\/[^\/]*$//; 126 | } 127 | 128 | return undef; 129 | } 130 | 131 | sub tagsDir { 132 | # 133 | # If there is a TM_TAGS_FILE environment variable use that 134 | # to set both the directory and name of the tags file 135 | # 136 | if(exists($ENV{'TM_TAGS_FILE'}) && $ENV{'TM_TAGS_FILE'}=~/^(.+)\/(.+)$/) 137 | { 138 | $TagFileName=$2; 139 | return $1; 140 | } 141 | 142 | # 143 | # From the files directory, search upwards to 144 | # see if we have an existing tags file. 145 | # 146 | my $d=$ENV{'TM_DIRECTORY'}; 147 | 148 | my $d2=&findTagsDirStartingAt($d); 149 | 150 | return $d2 if(defined($d2)); 151 | 152 | # 153 | # If there is a TM_PROJECT_DIRECTORY environment variable use that 154 | # as the directory for the tags file 155 | # 156 | if(exists($ENV{'TM_PROJECT_DIRECTORY'})) 157 | { 158 | my $d=$ENV{'TM_PROJECT_DIRECTORY'}; 159 | return $d if($d ne '/' && $d ne '/'); 160 | } 161 | 162 | die("No TM_PROJECT_DIRECTORY or TM_DIRECTORY environment!") unless(exists($ENV{'TM_DIRECTORY'})); 163 | 164 | # 165 | # If we still did not find the tags file, use the current files dir. 166 | # 167 | return $d; 168 | } 169 | 170 | sub getQuotedDirs { 171 | # get and quote the directory names so odd characters (spaces etc) don't mess up our script 172 | 173 | my $dir = shift; 174 | my $dirString = "$dir:"; 175 | 176 | if ( exists( $ENV{'TM_CTAGS_ADDITIONAL_DIRECTORIES'} ) ) 177 | { 178 | $dirString = $dirString . $ENV{'TM_CTAGS_ADDITIONAL_DIRECTORIES'}; 179 | } 180 | my @dirs = split(":", $dirString); 181 | 182 | my @quotedDirs = (); 183 | for (my $i = 0; $i < @dirs; $i++) 184 | { 185 | $quotedDirs[$i] = "'$dirs[$i]'"; 186 | } 187 | 188 | return @quotedDirs; 189 | } 190 | sub updateTags { 191 | 192 | my $dir=&tagsDir(); 193 | 194 | my $ctags=&findCtagsPGM(); 195 | 196 | &playSoundNamed('Frog'); 197 | 198 | 199 | # 200 | # The old way with system is problematic because occasionally 201 | # ctags just hangs (various scanner bugs) and eats up CPU cycles 202 | # 203 | #system("cd '$dir';'$ctags' $CtagsFlags '$dir'"); 204 | 205 | # 206 | # New way: If ctags takes longer than $CtagsTimeout kill it 207 | # 208 | 209 | #my @directories = ($tdir, ""); 210 | 211 | my @quotedDirs = &getQuotedDirs($dir); #first quote (all) our directories. 212 | 213 | #now run it 214 | { 215 | my $cmd = ""; 216 | my $dirs = join( " ", @quotedDirs ); 217 | 218 | #print("tagfileName: ". $TagFileName); 219 | $cmd = "'$ctags' $CtagsFlags -f $TagFileName $CtagsOptFlags $dirs |"; 220 | 221 | $::_ctagsPID=undef; 222 | #print($dir . "\n"); 223 | #print($cmd . "\n"); 224 | chdir($dir) or die("chdir to '$dir' failed: $!\n"); 225 | 226 | $::_ctagsPID=open(CTAGS,$cmd); 227 | local $SIG{ALRM}=sub{kill(9,$::_ctagsPID);die("ctags timed out!\n")}; 228 | alarm($CtagsTimeout); 229 | while() 230 | { 231 | # Discard output 232 | } 233 | close(CTAGS); 234 | alarm(0); 235 | } 236 | 237 | my $count = @quotedDirs; 238 | my $directory; 239 | 240 | if ($count != 1) 241 | { 242 | $directory = "directories"; 243 | } 244 | else 245 | { 246 | $directory = "directory"; 247 | } 248 | return "Created/updated $TagFileName for $count $directory\n"; 249 | } 250 | 251 | sub byCtagsHeadersLast { 252 | 253 | my $fa=(split("\t",$a))[1]; 254 | my $fb=(split("\t",$b))[1]; 255 | 256 | $fa=~s/.*\.//; 257 | $fb=~s/.*\.//; 258 | 259 | return -1 if($fa ne 'h' && $fb eq 'h'); 260 | return 1 if($fb ne 'h' && $fa eq 'h'); 261 | 262 | return $a cmp $b; 263 | } 264 | 265 | sub extractMSig { 266 | 267 | my $word=shift; 268 | 269 | my @lines=split("\n",$word); 270 | 271 | my $lineNo=0+$ENV{'TM_LINE_NUMBER'}; 272 | my $before=join("\n",@lines[0..$lineNo-2]); 273 | my $after=join("\n",@lines[$ENV{'TM_LINE_NUMBER'}..scalar(@lines)-1]); 274 | 275 | my $line=$lines[$lineNo-1]; 276 | 277 | $before.=substr($line,0,$ENV{'TM_LINE_INDEX'}); 278 | $after=substr($line,$ENV{'TM_LINE_INDEX'}).$after; 279 | 280 | # print "
WORD-START: '$word'
\n"; 281 | # print "
LINE: '$line'
\n"; 282 | # print "
BEFORE: '$before'
\n"; 283 | # print "
AFTER: '$after'
\n"; 284 | 285 | 286 | my $pre=''; 287 | 288 | while(($pre=~tr/\[//)<=($pre=~tr/\]//)) 289 | { 290 | $before=~s/(\[[^\[]*)$// or return undef; 291 | $pre=$1.$pre; 292 | } 293 | 294 | # print "
PRE : '$pre'
\n"; 295 | 296 | 297 | my $post=''; 298 | 299 | while(($post=~tr/\]//)<=($post=~tr/\[//)) 300 | { 301 | $after=~s/^([^\]]*\])// or return undef; 302 | $post.=$1; 303 | } 304 | 305 | # print "
POST: '$post'
\n"; 306 | 307 | $word=substr($pre,1).substr($post,0,-1); 308 | 309 | # print "
LINE : '$word'
\n"; 310 | 311 | 312 | while($word=~s/\{[^\{\}]*\}//mg) {} 313 | while($word=~s/\[[^\[\]]*\]//mg) {} 314 | while($word=~s/\([^\(\)]*\)//mg) {} 315 | 316 | $word=~s/\:\s*\S+\s*/:/mg; 317 | 318 | $word=~s/.*\s+//; 319 | 320 | # print "
WORD : '$word'
\n"; 321 | $word; 322 | } 323 | sub findTags { 324 | 325 | my $originalFH=undef; 326 | 327 | if($DEBUG) 328 | { 329 | open(OUT,">/tmp/tmctags.html") or die("Can't open '/tmp/tmctags.html' for write: $!\n"); 330 | 331 | $originalFH=select(OUT); 332 | } 333 | 334 | &_findTags; 335 | 336 | if($DEBUG) 337 | { 338 | close(OUT); 339 | select($originalFH); 340 | 341 | exec('cat /tmp/tmctags.html'); 342 | } 343 | } 344 | 345 | sub _findTags { 346 | 347 | my $word=$ENV{'TM_CURRENT_WORD'} // $ENV{'TM_SELECTED_TEXT'} or die("Missing 'TM_CURRENT_WORD' environment!\n"); 348 | my $srchStrt=0; 349 | 350 | if($ENV{'TM_FILENAME'}=~/\.(m|mm|h|mh)$/) 351 | { 352 | # 353 | # For ObjC we need to extract the method signature if any 354 | # 355 | # $ENV{'TM_CURRENT_LINE'} 356 | # $ENV{'TM_COLUMN_NUMBER'} 357 | # 358 | # OLD 359 | # local $/; 360 | # $word=<>; 361 | # $word=~s/\[[^\]]*\]/X/mg; 362 | # $word=~s/\([^\]]*\)/X/mg; 363 | # $word=~s/\:\s*\S+\s*/:/mg; 364 | # 365 | # $srchStrt=1; 366 | # 367 | # new 368 | # 369 | local $/; 370 | $word=<>; 371 | 372 | if(exists($ENV{'TM_SELECTED_TEXT'})) 373 | { 374 | # print "
Path A
\n"; 375 | 376 | $word=~s/\[[^\]]*\]/X/mg; 377 | $word=~s/\([^\]]*\)/X/mg; 378 | $word=~s/\:\s*\S+\s*/:/mg; 379 | 380 | $srchStrt=1; 381 | } 382 | else 383 | { 384 | my $cl="$ENV{'TM_CURRENT_LINE'}"; 385 | 386 | my $ts=' ' x $ENV{'TM_TAB_SIZE'}; 387 | $cl=~s/\t/$ts/g; 388 | 389 | my $before=substr($cl,0,$ENV{'TM_COLUMN_NUMBER'}-1); 390 | my $behind=substr($cl,$ENV{'TM_COLUMN_NUMBER'}-1); 391 | 392 | # print "
before: '$before'
\n"; 393 | # print "
behind: '$behind'
\n"; 394 | 395 | 396 | $before=($before=~/([a-zA-Z0-9_]+)$/)?$1:''; 397 | $behind=($behind=~/^([a-zA-Z0-9_]+)/)?$1:''; 398 | 399 | # print "
before: '$before'
\n"; 400 | # print "
behind: '$behind'
\n"; 401 | 402 | my $currentWord=$before.$behind; 403 | 404 | my $result=extractMSig($word); 405 | 406 | # print "
\$result: '$result'
\n" if(defined($result)); 407 | 408 | if(defined($result) && index($result,$currentWord)>=0) 409 | { 410 | # print "
Path B
\n"; 411 | # 412 | $word=$result; 413 | $srchStrt=1; 414 | } 415 | else 416 | { 417 | # print "
Path C
\n"; 418 | $word=$currentWord; 419 | 420 | # Hack for single-line method signatures, 421 | # should be expanded for multi-line signatures 422 | 423 | if($cl=~s/^\s*(\-|\+)\s*\([^\)]+\)\s*//) 424 | { 425 | $cl=~s/\s*(\{|\;).*//; 426 | $cl=~s/\([^\)]+\)\s*\S+\s*//g; 427 | $cl=~s/\s+//g; 428 | 429 | if(index($cl,$word)>=0) 430 | { 431 | # print "
Path C.1
\n"; 432 | 433 | $word=$cl; 434 | $srchStrt=1; 435 | } 436 | } 437 | 438 | 439 | } 440 | } 441 | } 442 | else 443 | { 444 | # Strip certain characters from words 445 | $word =~ s/://; 446 | } 447 | 448 | my $sound=''; 449 | 450 | my $tagPrefix=($srchStrt==1)?'±':''; 451 | 452 | &pHeader($word,$tagPrefix); 453 | 454 | my $srch="$word\t"; 455 | my @lines=(); 456 | 457 | my $tagsDir=&tagsDir(); 458 | unless(-f "$tagsDir/$TagFileName") 459 | { 460 | print &updateTags(),"
\n"; 461 | } 462 | open(IN,"$tagsDir/$TagFileName") or die("Can't open '$tagsDir/$TagFileName' for read: $!\n"); 463 | while() 464 | { 465 | # next unless(index($_,$srch)==$srchStrt); 466 | next unless(index($_,$srch)==0); 467 | push(@lines,$_); 468 | while() 469 | { 470 | # last unless(index($_,$srch)==$srchStrt); 471 | last unless(index($_,$srch)==0); 472 | push(@lines,$_); 473 | } 474 | last; 475 | } 476 | close(IN); 477 | 478 | #print STDERR "Found:
",join("
\n",@lines),"
\n"; 479 | 480 | if(scalar(@lines)==0) 481 | { 482 | print "No tags found for '$tagPrefix$word'.\n"; 483 | $sound=$ErrorSound; 484 | #exit($ExitShowToolTip); 485 | } 486 | else 487 | { 488 | $sound=$OkMultiSound; 489 | my $outLineNo=0; 490 | my $hadHeader=0; 491 | my $countNonHeader=0; 492 | my $lastFile=undef; 493 | my $lastLine=undef; 494 | foreach my $line (sort byCtagsHeadersLast @lines) 495 | { 496 | #print "line: $line
\n"; 497 | 498 | my $idx1=index($line,"\t/^"); 499 | my $idx2=rindex($line,"/;\""); 500 | 501 | next unless($idx1>0 && $idx2>$idx1+3); 502 | 503 | my $code=substr($line,$idx1+3,$idx2-$idx1-3); 504 | $line=substr($line,0,$idx1).substr($line,$idx2+3); 505 | $code=~s/\$$//; 506 | 507 | my($w,$file,$type,$lno)=split("\t",$line); 508 | 509 | my $isHeader=0; 510 | if($file=~/\.h$/) 511 | { 512 | $isHeader=1; 513 | } 514 | else 515 | { 516 | $countNonHeader++; 517 | } 518 | # print "code: $code
\n"; 519 | # print "w: $w
\n"; 520 | # print "file: $file
\n"; 521 | # print "type: $type
\n"; 522 | # print "lno: $lno
\n"; 523 | 524 | if($lno=~/line\:(\d+)/) 525 | { 526 | $lno=$1; 527 | } 528 | else 529 | { 530 | $lno=1; 531 | } 532 | 533 | $file=~/(.*)\/(.+)/; 534 | my $path=$1; 535 | my $filename=$2; 536 | 537 | if($isHeader && !$hadHeader && $outLineNo>0) 538 | { 539 | print "

Header Files

\n"; 540 | } 541 | 542 | $outLineNo++; 543 | 544 | print <<"HTML"; 545 |
546 | $filename:$lno -- $path
547 |
$code
548 |
549 | HTML 550 | if(!$lastFile || !$isHeader) 551 | { 552 | $lastFile=$file; 553 | $lastLine=$lno; 554 | } 555 | 556 | $hadHeader=1 if($isHeader); 557 | } 558 | 559 | if($AutoJump && ($countNonHeader==1 || scalar(@lines)==1) && defined($lastFile) && defined($lastLine)) 560 | { 561 | print <<"HTML"; 562 | 565 | HTML 566 | $sound=$OkSingleSound; 567 | } 568 | 569 | } 570 | 571 | my $history.=qq{
$ENV{'TM_FILENAME'}:$ENV{'TM_LINE_NUMBER'} -- $ENV{'TM_DIRECTORY'}
$ENV{'TM_CURRENT_LINE'}
\n}; 572 | 573 | if($CtagsHistorySize>1) 574 | { 575 | my $h=$CtagsHistorySize-1; 576 | 577 | $history.=`head -$h '$tagsDir/$CtagsHistoryFileName'` if(-f "$tagsDir/$CtagsHistoryFileName"); 578 | 579 | open(HISTORY,">$tagsDir/$CtagsHistoryFileName") or die("Can't open '$tagsDir/$CtagsHistoryFileName' for write: $!\n"); 580 | print HISTORY $history; 581 | close(HISTORY); 582 | } 583 | 584 | print <<"HTML"; 585 | 586 |

You were here:

587 |
588 | $history 589 |
590 | HTML 591 | 592 | &pFooter(); 593 | 594 | &playSoundNamed($sound); 595 | } 596 | sub pHeader 597 | { 598 | my $word=shift; 599 | my $tagPrefix=shift // ''; 600 | 601 | print <<"HTML"; 602 | 603 | 604 | Tags for $tagPrefix$word 605 | 649 | 650 | 651 |

Tags for $tagPrefix$word

652 |
653 | HTML 654 | } 655 | 656 | sub pFooter 657 | { 658 | print <<"HTML"; 659 | 660 | 661 | HTML 662 | } 663 | 664 | sub playSoundNamed { 665 | 666 | my $sf=shift; 667 | 668 | return unless(defined($sf) && $sf ne ''); 669 | 670 | my $sp="$SoundDir/$sf"; 671 | 672 | $sp.='.aiff' unless(-r $sp); 673 | 674 | my $ps="$ENV{'TM_SUPPORT_PATH'}/bin/play"; 675 | 676 | if(-x $ps && -r $sp) 677 | { 678 | system("'$ps' '$sp' 2>/dev/null"); 679 | } 680 | } 681 | 682 | 1; 683 | ############################################################################EOF 684 | --------------------------------------------------------------------------------