bowles@is.s.u-tokyo.ac.jp (Eric E. Bowles) (05/02/91)
In article <DANJ1.91Apr28061619@cbnewse.ATT.COM> might as well reply to netnews, it's the usual editor war writes: >In article <1991Apr24.155049.21710@njitgw.njit.edu> ken@hertz.njit.edu >(Ken Ng CCCC) writes: >> Instead of scrolling through the actual function source code each and every >> time, if you could hide or close off certain sections of code from being >> presently displayable, you could find the functions easier. If you were >> not sure how function 'foo' works, you could open up/display the text that >> was hidden. > > GNU Emacs got things like that: Now so does vi... well, sort of. My previous "word completion" macros were well received, so I decided to put together a couple of macros to fold and unfold lines of text in vi, more or less. That is, it's possible to hide selected lines of text and then expose them. Text can be recursively folded (as long as it's more than one line you're folding). If you're careful, it's even possible to save the folded file, quit, edit that file again, and unfold it. It's also quite easy to lose that text unless you know what you're doing. :-( Here is the basic command: <1> !<address> vfold <CR> To fold (hide) text, position the cursor on the first line that you want to hide, then hit "!" followed by a motion command that indicates the last line to be hidden, then type "vfold" and return. (This filters the range of text to the shell command "vfold", which perhaps you should install in ~/bin). This command replaces the range of lines with the following ugly marker: $$FOLDED:-- 15 /usr/tmp/vifold.8137 --$$ The number after the two dashes (e.g., "15") indicates the number of hidden lines. The filename after that (e.g., "/usr/tmp/vifold.8137") tells where the hidden text was stored. To unfold (expose) the hidden text, just pass the line containing the "folded" marker to "vfold", like this: "!!vfold", and hit return. The `[u' macro below does precisely this. Now here are some macros to make things easier: <2> [f - This macro folds all lines between the opening and closing braces of a C function. Specifically, it will find the previous occurrence of ?^{? and fold lines until /^}/ is encountered. (Try it on a copy of a C source file and you'll understand what I'm trying to say...) <3> [u - This unfolds the folded text that the cursor currently lies on. <4> [n - This finds the next "folded text" marker (that ugly thingy). WARNING: Do not use 'u' (undo) with these macros. The "vfold" script currently deletes the temporary file when text is unfolded. By using "undo", it is possible to return to the "folded" state within vi, but the shell script will not know this. The upshot is, if you unfold something, undo it, then unfold the same line, you will lose the original text! One solution would be to comment out the code in "vfold" that deletes the file. However, you could be left with a bunch of temporary files that you'd have to remove yourself. Here is the stuff you need to add to your .exrc (passed through "cat -v"): | " vi macros to fold and unfold text. | " by Eric Bowles <bowles@is.s.u-tokyo.ac.jp> | " (Let me know of improvements & bug fixes). | " | " Commands: | " !<address> vfold - fold specified range of lines. | " [f - fold current C function. | " [u - unfold current line. | " [n - go to next folded line. | " | :map [f j[[j!/^}/-1^M~/bin/vfold^M | :map [u !!~/bin/vfold^M | :map [n /^$$FOLDED:-- /^M I've attached at the end of this posting a shar file containing a uuencoded version of the above macros (just append it to your .exrc -- how convenient), and the "vfold" shell script, which should be in your ~/bin directory. Experiment with these, and be sure to let me know of any comments, improvements, and bug fixes. =============================================================================== Eric Edward Bowles Dept of Information Science, Faculty of Science University of Tokyo, 7-3-1 Hongo, Bunkyo-ku bowles@is.s.u-tokyo.ac.jp Tokyo, JAPAN 113. +81-3-3812-2111 x4096 -----------------------------CUT HERE------------------------------------------ #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: exrc.fold.uu vfold # Wrapped by bowles@adara on Thu May 2 15:57:56 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'exrc.fold.uu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'exrc.fold.uu'\" else echo shar: Extracting \"'exrc.fold.uu'\" \(614 characters\) sed "s/^X//" >'exrc.fold.uu' <<'END_OF_FILE' Xbegin 644 exrc.fold XM(B!V:2!M86-R;W,@=&\@9F]L9"!A;F0@=6YF;VQD('1E>'0N"B(@8GD@17)I XM8R!";W=L97,@/&)O=VQE<T!I<RYS+G4M=&]K>6\N86,N:G ^"B(@*$QE="!M XM92!K;F]W(&]F(&EM<')O=F5M96YT<R F(&)U9R!F:7AE<RDN"B(*(B!#;VUM XM86YD<SH*(B @(#H\861D<F5S<SX@=F9O;&0@(" M(&9O;&0@<W!E8VEF:65D XM(')A;F=E(&]F(&QI;F5S+@HB(" @6V8@(" @(" @(" @(" @(" @("T@9F]L XM9"!C=7)R96YT($,@9G5N8W1I;VXN"B(@("!;=2 @(" @(" @(" @(" @(" @ XM+2!U;F9O;&0@8W5R<F5N="!L:6YE+@HB(" @6VX@(" @(" @(" @(" @(" @ XM("T@9V\@=&\@;F5X="!F;VQD960@;&EN92X*(@HZ;6%P(%MF(&I;6VHA+UY] XM+RTQ#7XO8FEN+W9F;VQD#0HZ;6%P(%MU("$A?B]B:6XO=F9O;&0-( HZ;6%P X5(%MN("]>)"1&3TQ$140Z+2T@+PT* X Xend END_OF_FILE if test 614 -ne `wc -c <'exrc.fold.uu'`; then echo shar: \"'exrc.fold.uu'\" unpacked with wrong size! fi # end of 'exrc.fold.uu' fi if test -f 'vfold' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'vfold'\" else echo shar: Extracting \"'vfold'\" \(1610 characters\) sed "s/^X//" >'vfold' <<'END_OF_FILE' X#!/bin/csh -f X# X# Shell script to fold and unfold lines in vi. X# X# By Eric Bowles <bowles@is.s.u-tokyo.ac.jp> X# Public domain, of course. X# Let me know of improvements and bug fixes! X# X# This script does two things. First, if it receives from standard X# input a bunch of text whose first line doesn't match the special X# "folded line" pattern (see below), it will save the text in a temporary X# file and return a new "folded line" pattern containing the name of that X# temporary file. X# Second, if this script receives a line that matches the "folded line" X# pattern, it will return the contents of the file encoded in the pattern. X# NOTE: It will also delete that temporary file. Comment out that line if X# you wish to stay on the safe side. X# X# The "folded line" pattern looks like: X# $$FOLDED:-- <# of lines> <filename> --$$ X# X Xset taghead = '$$FOLDED:-- ' Xset tagtail = ' --$$' Xset filename_template = /usr/tmp/vifold X X# Decide what to do based on the contents of the first input line. Xset first_line = $< X Xif ("$first_line" =~ "$taghead"*"$tagtail") then # Unfold text. X set line = ($first_line) X set filename = $line[3] X X if (! -e $filename) then X echo '*** ACK! Cannot find '$filename' -- folded text may be lost.' X exit 1 X endif X cat $filename X rm -f $filename # not really safe... could comment this line out. Xelse # Fold text. X set filename = $filename_template.$$ X echo "$first_line" >! $filename X cat >> $filename X set output = `wc -l $filename` X echo "$taghead$output$tagtail" # Return "folded" marker. Xendif Xexit 0 END_OF_FILE if test 1610 -ne `wc -c <'vfold'`; then echo shar: \"'vfold'\" unpacked with wrong size! fi chmod +x 'vfold' # end of 'vfold' fi echo shar: End of shell archive. exit 0 =============================================================================== Eric Edward Bowles Dept of Information Science, Faculty of Science University of Tokyo, 7-3-1 Hongo, Bunkyo-ku bowles@is.s.u-tokyo.ac.jp Tokyo, JAPAN 113. +81-3-3812-2111 x4096