Xref: utzoo comp.sys.amiga:38271 comp.emacs:6641 Path: utzoo!attcan!uunet!cs.utexas.edu!rutgers!gatech!ncsuvx!mcnc!rti!xyzzy!batgirl.rtp.dg.com!cassirer From: cassirer@batgirl.rtp.dg.com (Fred Cassirer) Newsgroups: comp.sys.amiga,comp.emacs Subject: MicroEmacs 3.9 ctags package Message-ID: <93@xyzzy.UUCP> Date: 9 Aug 89 17:01:02 GMT Sender: usenet@xyzzy.UUCP Reply-To: cassirer@batgirl.rtp.dg.com (Fred Cassirer) Organization: Data General Corporation Lines: 468 I've recently completed a tags package using MicroEmacs 3.9e, it's not all that big so I figured I'd post it. It works with all the versions of emacs that I've tried, Amiga, Sun and DG/UX. I have a poor mans version of "dired", an enhanced version MicroSpell's "scan.cmd" that will spell check an emacs buffer within emacs, and a version of "list-buffers" that will allow you to delete the buffers in the list-buffers window by hitting a "d" on the line the buffer is on. If anyone is interested I'll send them via email, or if there is enough interest, I'll post. The "dired" procedures only run on the Amiga version because >key does not work under Unix, I'm not sure why ... yet. I' cross-posting this to comp.sys.amiga and comp.emacs. P.S. Does anyone know where I can get a copy of MicroEmacs 3.10?? ========================================================================= # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # tags.doc # tags.cmd # This archive created: Thu Aug 3 23:23:05 1989 cat << \SHAR_EOF > tags.doc -=-=-=-=-=-=-=-=- MicroEmacs 3.9e Ftags package =-=-=-=-=-=-=-=-=-= FTags provide a convenient method of browsing source code. Typically a file called "tags" is created by the Unix utility "ctags". "ctags" creates a list of symbols, the file they are defined in, and a line number or unique search string within the file. There is a public domain version of ctags in the unix mod.sources library vol_03 written by Ken Arnold. This version of ctags successfully compiles on the Amiga with the -u options commented out (uses unix system() call). With some small modifications (included) Ftags will also work with the Manx ctags output. These macros have successfully run on an Amiga 1000 under WorkBench 1.3, Data General MV and Aviion DG/UX Unix, and Sun/3 OS. How it works: *Update MicroEmacs source as specified in tags.cmd Place tags.cmd in a known directory. Modify your emacs startup file to call "tags.cmd" as per the following macros - set %home &env "HOME" 3 store-macro execute-file &cat %home "/tags.cmd" ; Unix execute-file "s:tags.cmd" ; Amiga execute-macro-21 !endm bind-to-key execute-macro-3 M-t 4 store-macro execute-file &cat %home "/tags.cmd" ; Unix (home directory) execute-file "s:tags.cmd" ; Amiga execute-macro-22 !endm bind-to-key execute-macro-4 ^] 26 store-macro execute-file "s:tags.cmd" execute-macro-27 !endm bind-to-key execute-macro-26 M-^t Macros 3&4 will allow you a much faster .emacsrc. The only time that emacs will parse the tags.cmd file is the first time you actually need to tag to a symbol. Macro 26 will allow you to redefine the default tag file by prompting you for a different tags file. *Note: You may not need these changes, they have to do with handling long %string variables in emacs's macro language. To start everything rolling, go to the source directory that contains the tags file. Bring up emacs and hit escape-t (M-t). You will be prompted for a tag. Enter the name of the tag and hit return. At this point emacs will load the tags file, escape any * meta-characters, and add magic mode. It will then search out the tag, load the corresponding file, and search for the symbol. Once you have a file, you can either use M-t to enter new tags, or you can position the cursor near a symbol and hit ^]. ^] will skip over white space and various non-identifier characters before starting to gather a symbol, for example status = ++(*(myfunc(arg))) ^ ^ if the cursor is anywhere between the 1st and 2nd ^, the ^] would lookup the routine "myfunc()" You can use ^] or M-t in any combination. As you tag thru a file, a stack is being kept of tagg'd buffer locations. You can back out from the current tag by hitting M-p (escape p). This should return to the previously tagged buffer/position. This package is PD all the way, if you have any improvements or problems let me know. -FredC /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ < Fred Cassirer ... rti!rtp48!cassirer > < Data General Corporation Research Triangle Park, NC > \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ SHAR_EOF cat << \SHAR_EOF > tags.cmd ; ; Use a standard tags file so that source browsing is easier within ; MicroEMACS 3.9e. ; ; file - "tags.cmd" ; ; Written July 5, 1989 - Fred Cassirer (rti!dg.rtp.com!cassirer) ; ; Parse a "tags" file to bounce around source easily. This set of macros ; runs on a slightly modified version of MicroEMACS3.9e. The modifications ; are some bug fixes I made in order for the &mid and &left functions to ; work correctly. Basically, in eval.c, UFLEFT and UFMID switch labels ; return an strncpy which did/does not properly terminate the result string. ; ; At line 78 in eval.c: ; ; case UFLEFT: strncpy(result, arg1, atoi(arg2)); ; result[atoi(arg2)] = '\0'; /* term string */ ; return(result); ; case UFRIGHT: return(strcpy(result, ; &arg1[(strlen(arg1) - atoi(arg2))])); ; case UFMID: strncpy(result, &arg1[atoi(arg2)-1], ; atoi(arg3)); ; result[atoi(arg3)] = '\0'; /* term string */ ; return(result); ; ; In .emacsrc bind M-t (or whatever you like) to: ;3 store-macro ; execute-file "tags.cmd" ; execute-macro-21 ;!endm ; ;4 store-macro ; execute-file "tags.cmd" ; execute-macro-22 ;!endm ; ; Macros 3&4 will allow you a much faster .emacsrc. The only time that emacs ; will parse the tags.cmd file is the first time you actually need to tag to ; a symbol. ; ;bind-to-key execute-macro-3 M-t ;bind-to-key execute-macro-4 ^] ; ; Now that everything is set, just hit M-t and you will be prompted for ; a tag. Enter a tag and the file will be located and displayed at the ; needed place. You can continue from here to tag further, using either ; ^] or M-t (^] will look up the symbol under the cursor). When you are ; done you can hit M-p to "pop" back to each previous tag buffer, deleting ; the pop'd buffer as you go. ; ; The format of the tag buffer is as follows: ; ; symbol-namefile-name/regular expression/ ; or ; symbol-namefile-name##### (where #### is a line number) ; ; There can only be one seperating the 1st two fields. ; ; This macro package also works on the Amiga version of MicroEmacs3.9e using ; the Manx ctags command. The one difference is that Manx ctags use's spaces ; to delimit the fields and doesn't place an ending slash on the regular-exp. ; To use this with Manx ctags command change the marked lines. ; set $discmd 0 set %ctags_sep "~t" ;The sepeartor character in the tags file (Unix) ;set %ctags_sep " " ;The sepeartor character in the tags file (Manx/Amiga) set %tagsfile "tags" 27 store-macro set %tagsfile @"tag file? " write-message "Append?(y/n)" run push-buffer !if &sequal &upper >k "N" set %load-tags 0 run load-tags !else run append-tags !endif run pop-buffer !endm bind-to-key execute-macro-27 M-^t set %load-tags 0 ; Load the tags file store-procedure load-tags set $discmd 0 !if &equal %load-tags 0 select-buffer "_tags" name-buffer "$$_killtags" find-file %tagsfile name-buffer "_tags" !force delete-buffer "$$_killtags" set $cmode 0 replace-string "*" "\*" unmark-buffer set $cmode 72 set %load-tags 1 !endif set $discmd 1 !return !endm ; Append a tags buffer to the current one, this is good for multiple ; directories each with it's own tags file store-procedure append-tags set $discmd 0 !if &equal %load-tags 1 select-buffer "_tags" end-of-file set-mark insert-file %tagsfile exchange-point-and-mark set $cmode 0 replace-string "*" "\*" set $cmode 72 unmark-buffer write-message &cat "[ " &cat %tagsfile " appended to tag buffer ]" !endif set $discmd 1 !return !endm ; Input a tag at the command line 21 store-macro set %savesearch $search set %search &cat "^" @"tag? " set $search %savesearch set %search &cat %search %ctags_sep run tag-to-buffer !endm ; Take the current word in the buffer and use it as a tag ; This command will skip over white space and any characters ; in "%tokenizer" before it starts to look for the symbol. set %tokenizer " ~t~n;!@#$%^&*()-+=~~|?/<>~":[]" 22 store-macro set %tmp &sindex %tokenizer &chr $curchar !if &greater %tmp 0 !while &greater %tmp 0 forward-character set %tmp &sindex %tokenizer &chr $curchar !endwhile !endif set %search "^" !while &equal %tmp 0 set %search &cat %search &chr $curchar forward-character set %tmp &sindex %tokenizer &chr $curchar !endwhile !if &sequal %search "^" write-message "[Couldn't find a symbol!]" !return !endif set %search &cat %search %ctags_sep run tag-to-buffer !endm ; Given %search, go track down the file and get to the spot ; This is the real guts of the work here, push the current location ; and locate the new %search string in the _tags buffer store-procedure tag-to-buffer run push-buffer set %savesearch $search run load-tags select-buffer "_tags" beginning-of-file !force search-forward %search !if ¬ $status run pop-buffer write-message "[Couldn't find tag in tags file, sorry.]" !return !endif beginning-of-line set %tagline #_tags set %l &sub &sindex %tagline %ctags_sep 1 set %func &left %tagline %l set %l &add %l 2 set %ln &len %tagline set %tagline &mid %tagline %l %ln set %l &sub &sindex %tagline %ctags_sep 1 set %file &left %tagline %l !force find-file %file !if ¬ $status if ¬ &sequal $cbufname %file run pop-buffer write-message "[Couldn't find file for tag, sorry.]" set $search %savesearch !return !endif beginning-of-file !endif set $cmode 74 set %l &add %l 2 set %search &mid %tagline %l 127 set %tmp &left %search 1 !if &sindex "0123456789" %tmp %search goto-line !else ; If using Manx ctags, comment this line out. It strips off the ending slash ; in the regular expression. set %ln &sub &len %search 2 ; Manx Ctags doesn't have a ; trailing slash set %search &mid %search 2 %ln !force search-forward %search !if ¬ $status ; Found the file, but not the tag run pop-buffer write-message "[Couldn't find tag. Tag file out of date? ]" set $search %savesearch !return !endif !endif beginning-of-line update-screen set $search %savesearch !return !endm set %stack "" set %stklvl 0 ; Push a buffer on the psuedo-stack. Actually variables of the form ; %# where # is 1-? get allocated for each new push. The buffer name ; and the $curline we are at is saved in the %# variable. store-procedure push-buffer set %arg &cat "%" %stklvl set %tmp &cat $cbufname " " set %tmp &cat %tmp $curline set &ind %arg %tmp set %stklvl &add %stklvl 1 !return !endm ; Pop back to the buffer/line on the top of the psuedo stack. store-procedure pop-buffer !if &equal %stklvl 0 write-message "[No more buffers on stack]" !return !endif set %stklvl &sub %stklvl 1 set %arg &cat "%" %stklvl set %stack &ind %arg set %tmp &sindex %stack " " set %tmp &sub %tmp 1 set %pop &left %stack %tmp set %tmp &add %tmp 1 set %tmp &sub &len %stack %tmp set %col &right %stack %tmp set %tmp $cbufname !if ¬ &sequal %pop $cbufname !force select-buffer %pop !endif %col goto-line !if ¬ &sequal %tmp "_tags" !if ¬ &sequal %tmp $cbufname delete-buffer %tmp !endif !endif !return !endm ; Debug stuff. Dump the psuedo stack to a window. store-procedure dump-stack select-buffer "_stack_dump" set %lvl %stklvl !while &greater %lvl 0 set %lvl &sub %lvl 1 set %arg &cat "%" %lvl set %stack &ind %arg set %tmp &sindex %stack " " set %tmp &sub %tmp 1 set %pop &left %stack %tmp set %tmp &add %tmp 1 set %tmp &sub &len %stack %tmp set %col &right %stack %tmp insert-string %arg insert-string " " insert-string %pop insert-string " " ; insert-string %tmp ; insert-string " " insert-string %col newline !endwhile !endm bind-to-key execute-macro-21 M-t bind-to-key execute-macro-22 ^] ; Pop previous tag buffer 25 store-macro run pop-buffer !endm bind-to-key execute-macro-25 M-p set $discmd 1 SHAR_EOF # End of shell archive exit 0 /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ < Fred Cassirer ...rti!dg.rtp.com!cassirer > < Data General Corporation Research Triangle Park, NC > \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/