trb@stag.UUCP ( Todd Burkey ) (04/14/89)
This is a request for comments on an editor which will soon be released for public abuse. I hope to release the sources to comp.sources.unix in the near future, but what with taxes and real work (the kind that pays the bills and causes the taxes) I can't commit to when that will be. The code is pretty complete (i.e. all the version 1.0 features that I want are currently in it) and reliable. I use the editor now for most of my daily editing activies both at home and work and have gotten over the habit of saving my files every minute or so :-). I don't want to start an editor war or arguments over which type of editor is best. I am simply interested in hearing 1) which FOLDED features people like and 2) what they would like to see added. Also, if anyone sees any obvious shortfall that I may have missed, now would be a good time to let me know. To this end, I am including part of the documentation that I am putting together for FOLDED. Sorry, but this is kind of long. -Todd Burkey trb@stag.UUCP or tburkey@eta.com -------------Partial Draft of the FOLDED Documentation------------------ FOLDED A folding editor (c) 1989 By Todd Burkey FOLDED is a dual mode editor that provides several advanced features not currently found in text and programming editors. FOLDED is primarily intended to be used as a source code editor. As such, it incorporates a folding feature similar to that found in thought processor programs but with added support for the C language (and eventually Pascal). FOLDED also has some relational capabilities. These allow the user to associate lines in their source files with sections of their documentation files and vice-versa. And both folding and relations are incorporated in such a fashion that they don't impact the original text files in any way. FOLDED also has the standard set of editor features, with a few bells and whistles thrown in. It has dynamic 'as-you-type' searching, substition by block/global/direction of a string or exact word match (i.e. change variable i to i_var throughout your code), block copy/move/kill in normal or rectangular region modes, marks that allow intra-buffer movement, easy movement between buffers, a trash can, variable skipping (point to a variable, press ^n to skip to the next occurrance of it, ^p for previous), configuration save (you can leave a multi-buffer edit session and come back to the exact place you left off with all buffer positions restored), built in help, prompting for the beginning user, one-key buffer cloning, and more. So what doesn't FOLDED do? Well, the first release will not have an UNDO feature. The trash can will have to do. It also is dual mode, something which may alienate some of the Emacs users out there (I am bi-editable, since I use Emacs on some systems, graphic shell editors on others, vi on still others). With a little work, the editor could actually be made to work either as a dual mode editor or a single mode editor (hint to hackers out there). It also could use some better screen optimization, since I tended to develop it on high speed displays. It is usable at 2400 buad, but any slower than that and you are better off with ed. The first release also won't have any key binding capability. I still haven't decided upon the best approach to handle user-defined key maps. Finally, FOLDED isn't a layered editor. My goals during the development of FOLDED were to keep it relatively small (it is about 60K executable, <5000 lines of source) and fast, so layering as implemented in emacs-like editors was out. I wrote FOLDED simply to learn. Early on, I made a choice to 1) put basic 'must-have' functionality in the editor, 2) put advanced concepts into the editor that can't be handled by external programs (folding and relational features), 3) implement a simple to use and understand multi file editing capability so that moving between files and scratchpads was easy, 4) design the editor so that I could add enhanced 'wish-list' functionality as I determined I needed it, 5) ensure that the final version of the editor would function the same on my Atari ST at home as it does on the Sun workstations at work and even as it does on the mainframes, and 6) keep the program small (I hate long loading times). The latter requirement somewhat dictates the earlier ones...at least for the first release. I imagine that the editor will continue to grow unbounded in the future, since it is just too easy to add features as I feel a need to. One thing that I will eventually look into is a bindable user macro feature (not interpreted like in emacs, but really and truly bound into the executable.) The reason will be simply speed, speed, and more speed :-). FOLDED differs from both emacs and vi in several ways. First, it is an unconstrained editor. You can move your cursor anywhere on the screen and when you go into insert mode (or copy a rectangular block of text) the editor will take care of sticking in needed spaces. Another difference is that the editor does not 'wrap' lines. Instead, you can scroll/page the entire window sideways when necessary (the editor will do this for you if you are typing past the end of the right margin). I got too used to this feature on the Apollos, I guess. Also, FOLDED does not retain tab characters. Rather, they are replaced with white space on input and FOLDED will optionally 'optimize' your file when you write it out (i.e. inserting tabs wherever it can, removing trailing spaces on lines, etc). Actually, FOLDED doesn't even retain leading spaces in the way you might expect an editor to store them. All leading spaces in a line are compressed to an integer variable upon file read-in. The user still sees the spaces on the screen, but internally this sped up my folding logic (at the cost of almost going insane over the added code complexity... there is always a tradeoff). The first release of FOLDED has been tested on BSD4.2/3 (Suns, Symetric, and Apollo), SYSVR3 (ETA-10), and the ATARI ST. It is being ported by others to the Mac and the IBM PC. A preliminary port of the code to the BELLCORE MGR (window manager) environment took only two hours on a Sun workstation and provided individual windows for each buffer (with title bars). The following sections discuss the concepts of folding, relations, and a little about the primary commands and user environment of FOLDED. Although most of the examples will be source code related, I should mention that I find myself using folding and relations in my documentation and daily work plans and status reports even more than I do while coding. FOLDING: Obviously, a fundamental concept in using FOLDED is that of folding. Folding in a text editor is a mechanism that allows you to cause sections of code or text be replaced by a single line of text. This is useful for 'hiding' away clean and functional sections of code while you work on and only see the parts that you are currently debugging. It also proves useful for tucking away big comment blocks. Worried that folding will change your source code? Don't worry, the act of folding doesn't affect the edited file at all...even when saved. When you save a file that has folds in it, a seperate control file is also saved under your current directory. See the section in the documentation titled 'CONTROL FILES' for more info on this. In FOLDED, I implemented three types of folding. In each case, a segment of your file is reduced such that all you see is the first line of the segment in reverse image (or bold, depending on your standout terminal mode). First, is the simple 'fold a marked block'. This allows you to mark any arbitrary region of text and fold it away. For example, lets say we had started with the following text (the numbers are just for reference in this documentation): 1: main() 2: /* GID for main - Just a test case 3: Author: Todd Burkey 4: Date: 1/27/89 5: DESC: Methodology for a test case 6: */ 7: { 8: if(this==that) { 9: do_something_that_works(); 10: } 11: } By defining a region between lines 2 and 6 and then folding, what you would see on the screen would be: 1: main() 2: /* GID for main - Just a test case <-pretend this line is bold 7: { 8: if(this==that) { 9: do_something_that_works(); 10: } 11: } Another method of folding is that based on 'indent level'. The logic behind indent level folding is simply to start with the line the user is currently on, move down in the text until an indent occurs, and then continue down until an undent occurs that is less than or equal to the original lines 'indented' position. For example, if you had been on line 8 in the above 'folded' text when the 'f' key was pressed, you would see the following: 1: main() 2: /* GID for main - Just a test case <-pretend this line is bold 7: { 8: if(this==that) { <-pretend this line is bold 11: } Unfortunately, most source code contains lots of things that tend to break up the clean indentation levels, so I added a third folding mechanism. This one is a little smarter in that it does a 'logical fold'. A logical fold looks for logical block begin/end marks in the code (the braces in C) and skips around comments, strings, etc. For example, if you had pressed the 'F' key on line 1 in any of the above steps, you would end up with: 1: main() <-pretend this line is bold In all cases, unfolding the text is performed by simply moving to the folded line and pressing the 'f' or 'F' key. Folding isn't all that novel a concept. It has been used for years now in thought processor programs on the Mac, IBM PC, and even back in the CP/M days. Thought processors usually use the 'fold by indent level' technique. Take the following simple example: FOLDED Information * specifications <-pretend this line is bold * plans <-pretend this line is bold * problems <-pretend this line is bold This is all I see when I use FOLDED to call up my folded.info file. Now, if I move to line 3 and press the f key, I will see: FOLDED Information * specifications <-pretend this line is bold * plans - Documentation <-pretend this line is bold - Enhancements <-pretend this line is bold - Bullet-proofing <-pretend this line is bold * problems <-pretend this line is bold In summary, folding is fully heirarchical (i.e. a fold can contain any number of folds), it is smart (it can fold based on programming logic blocks and indentation level), and it is retained from one edit session to the next. The actual commands (and their associated key bindings) that involve folding are: indent fold (f) : fold based on indent level logic smart fold (F) : fold based on {} logic unfold (f or F) : unfold the fold under the cursor temp unfold (^f): temporarily unfold all folds (for searching/sub'ing) re-fold all (^f): yep, CTRL-f is just a toggle block fold (bf): fold current block region RELATING: The word 'relations' in the field of databases conjures up images of opening up a large database, finding a particular entry, moving to a particular field, and, with several keystrokes, calling up not only another database, but a specific record in that database. Now, I have never understood why we couldn't have similar capabilities in a text editor. We can envision having a document file, moving to a specific part of the document, calling up the source code file related to that part of the document, and then moving to the appropriate spot in the source file. We can even imagine moving through the source code and finding a structure (or variable) and wishing we could immediately view the definition of the structure. These scenarios are fundamentally the same as those handled by a relational database program. Relationships as pertains to editors (and, of course, in this context, FOLDED) primarily involve two concepts. First, there are word relationships. These are something like 'glossary' entries in that you define a word once in a file and then can immediately go to the exact place you defined it from anywhere in the file (or any other file you are currently editing.) From a programming viewpoint, this simply means that you can move your cursor over a structure name in a source file and with a few keystrokes be placed immediately in an include file at the place the structure is defined. A second relationship type is that of line relations. These are basically invisible links that relate a line in one buffer to a line in another buffer. This type of relationship allows you to easily move back and forth between source code and program outlines/documents. Folded will even open up a file if you try to go to a relation in a file that you aren't currently editing. FOLDED supports a number of commands that allow easy creation and use of these relationships. The following key sequences are used to perform the most common relation operations: Rsl (Relate Set Line): The current line becomes 1/2 of a line relationship. The next Rs command will complete the relationship. Rsw (Relate Set Word): The current word is indexed for reference. Rgl (Relate Goto Line):FOLDED looks at the first line with a relation on or above the current line and goes to its related line. If the related line is in a file not currently being edited it will be opened for viewing. Rgw (Relate Goto Word):Read the word under the cursor and move to the correct file that it was defined in. Rkl (Relate Kill Line):Kill the relationship for the current line. Rkw (Relate Kill Word):Kill the relationship for the current word. Rp (Relate Pop): Pop back to where you were before the last Relate Goto. The pop stack is currently 10 levels deep. As with folding, the relationship information does not affect the actual files you are editing. In fact, the information is simply saved out as part of the folding info files. It is also important to note that neither folding or relations affect the speed of loading, saving, or using the various editor features to a noticable extent. Since I added relations very late in the development of the editor, I have a feeling that this area will see the most improvement over the next year. I've already decided that I need a few more commands to do things like 'move' and 'view' relationships. EDITING COMMANDS: When you enter FOLDED the first time, press the ? key to see a cheat sheet that tells you what each key does. Sorry, haven't had time to document the commands in detail yet... The following is a roughly what you will see on the cheat sheet screen (less the standout boxes): Top level cheat sheet for FOLDED. Where appropriate, additional prompts will appear in the program. MOVEMENT: k-up, j-down, h-left, l-right, K/J/H/L for page movement ^/$-beginning/end of line, p-Toggle paging mode, g-goto a line READING : :r/:v/:i-read/view/insert file, ^r/^v-read/view under cursor WRITING : :w-write current buffer/block, :s-save changed buffers/config INFO : ?-this help, '='-local information, X-extended buffer info SEARCHES: ^n/^p-find next/prev word, /-forward, \-reverse, ^e-exactmode BUFFERS : t/T-toggle buffers/trash, ^g/' '-goto/Cycle through buffers c/C Create scratch/clone buf, ^b-tag buffer for moves/copies '-k'-kill current buffer, y-yank line from trash and insert BLOCKS : b-Go to block options (define start/end, moving, copying, etc) CHANGING: s-change one char, S-substitute a string/word (once or global) DELETING: d/D-delete a character/line, -v/-d: global delete/vdelete INSERTS : i/I-insert before char/line, a/A-append after char/line FOLDING : f-fold by indentation, F-fold by logic, bf-fold a defined block ^f-toggle unfoldall, NOTE: press f or F on a fold to unfold it RELATES : R-line, word, and error relation options (set, goto, kill, pop) MARKING : m-mark options (ms-set, mg-goto, md-delete, mc-clear all) EXTRAS : Q-quit, !-run program/shell, x-execute macro (unimplemented) --Hit any key to continue-- BACKUP PROTECTION: If FOLDED detects a local directory called febackup, then backup copies of anything you edit will be placed in that directory. A rename operation is performed on the original file, so this means that only local partition files will be backed up in this fashion. Backups only take place at the time you save a file the first time during an edit session, so no unneccessary backups are made. FOLDED CONTROL FILES: If folded detects a local directory called foldinfo, then FOLDED will store all its control files there rather than clutter your directory with them. A control file is created only when the file being edited is saved and has some folding or relations in it. The control file will be a file of the same name, but with an 'f' inserted immediately after the final '.' in the name...so 'test.c' has a control file called 'test.fc' and 'junk' would have 'junk.f'. ENVIRONMENT VARIABLES: Several Environment variables may be used if you wish to avoid some prompting by FOLDED. They are: FE_ASCII - Save control files in ASCII (easier to mail that way) FE_BINARY - Save control files in BINARY (a bit faster and more effecient). FE_NOTABS - Always write files without tabs (useful on the Apollos). FE_TABS - Always fully optimize the files when writing. MGR_FONT - Size of the font used under MGR for the windows. IMPLEMENTATION DETAILS: Folded uses a doubly linked list to store lines internally. It mallocs the exact amount of memory a line needs on read-in, but as you modify lines it will malloc additional memory in 4 byte chunks...so you can end up with some wastage if you edit a lot of lines in a file. FOLDED keeps track of a lot of information about lines in the buffers, so there is quite a bit of overhead in using FOLDED. I place it pretty close to emacs in the amount of overhead required for 'data' storage, but since the executable is only about 60K it wipes emacs away in raw loading time (program+files). I haven't had time to optimize the code for speed yet, but things like searching and substituting are significantly faster than emacs and slightly faster than vi. This is partly due to the design of the editor and also may be due to FOLDED's lack of regular expression parsing routines. The first version of FOLDED probably won't be heavily optimized in the sense that ints will probably still be used where chars may get by. Also, there may be tricks I don't know about that could compress the amount of overhead I incurr in the storage of lines, buffers, etc. -Todd Burkey
lee@uhccux.uhcc.hawaii.edu (Greg Lee) (04/15/89)
From article <786@stag.UUCP>, by trb@stag.UUCP ( Todd Burkey ): " This is a request for comments on an editor which will soon be released ... Sounds real nice. How about making some use of more than one special screen attribute? Like inverted *and* underlined *and* ... For instance, indexed words might appear underlined. Can you have null folds, in case you just want a line to stand out? Greg, lee@uhccux.uhcc.hawaii.edu
jeff1@garfield.mun.edu (Jeff Sparkes) (04/17/89)
Have you though about inverse folding? For highly indented code it would be good to just look at a single block, ignoring preceding levels of indentation. I.e. x() { while (1) { if (blah) { if (foo) { if (bar) { /* code */ } } .... becomes MARKER if (foo) { if (bar) { /* code */ } } MARKER -- Jeff Sparkes uunet!garfield!jeff1 || jeff1@garfield.mun.edu
klute%trillian.irb@unido.uucp (Rainer Klute) (04/18/89)
In article <786@stag.UUCP> trb@stag.UUCP ( Todd Burkey ) writes: >I am simply interested in hearing 1) which FOLDED features people >like and 2) what they would like to see added. I do like the idea of connecting parts of the source file to definition files and documentation files. That is something I have not seen anywhere else yet. Especially the latter type of connection opens the chance for up-to-date documentation :-). >A preliminary port of the code to the >BELLCORE MGR (window manager) environment took only two hours on a Sun >workstation and provided individual windows for each buffer (with >title bars). Does the FOLDED implementation on the Atari ST support GEM windows? I think it should! Rainer Klute ---- klute@trillian.irb.informatik.uni-dortmund.de Univ. Dortmund, IRB |)|/ klute@unido.uucp, klute@unido.bitnet Postfach 500500 |\|\ ...uunet!mcvax!unido!klute D-4600 Dortmund 50 ---- Tel.: +49 231 7554663
trb@stag.UUCP ( Todd Burkey ) (04/18/89)
In article <3769@uhccux.uhcc.hawaii.edu> lee@uhccux.uhcc.hawaii.edu (Greg Lee) writes: >Sounds real nice. How about making some use of more than one >special screen attribute? Like inverted *and* underlined *and* ... >For instance, indexed words might appear underlined. Folded actually has the routines in it to do so, since my prototype was on the Atari ST and used colors as well as reverse video. When I moved it to Unix, however, I found that some terminals (like my Wyse 50) don't handle underlining/standout very well. Some terminals use an extra character position on the screen just to show that you are entering or exiting reverse video or underlining, so it gets messy if you wanted a line to contain both...it is bad enough dealing with just reverse video. I do plan on looking into this problem, though. What are indexed words? Key words, maybe? >Can you have null folds, in case you just want a line to stand out? No, I decided that would be too confusing from a human interface point of view...you want to train your eyes to think that a highlighted line represents a hidden block of text. Always, not just sometimes. On the other hand, if you had colors... NOTE: Several people have asked about a ship date for folded...I should mention that up until yesterday morning I was planning to release the first version at the end of April. Unfortunately, CDC shut down ETA yesterday, so I am suddenly unemployed. What this means is that I won't be able to do any real-time testing on Suns, Apollos, or SysVR3. It also means I will be busy job-hunting, so either the release will slip or I will post it with some 'extra' checking built into the code. -Todd Burkey trb@stag.UUCP "note... eta.com no longer exists..."
wa8tzg@nucleus.UUCP (Bill Meahan) (04/19/89)
While horizontal scrolling is a very good idea for terminals used in writing code (especially when compilers allow long lines of 512 characters or more) it would seem less useful when writing documentation or other text primarily oriented toward human readability especially when the output will be sent to a printer of some sort that probably will not support horizontal scrolling. Could there not be a configurable/toggled wrap margin so that word wrap could be enabled when useful and disabled when horizontal scrolling is the best way to go? Being able to set what column is the wrap margin (ala' vi) would also be very helpful. I'm looking forward to seeing FOLDED soon and will port it to a couple of HP 9000's (300 & 800) ASAP! Bill Meahan wa8tzg%nucleus.UUCP@mailgw.cc.umich.edu
dav@eleazar.dartmouth.edu (William David Haas) (04/19/89)
>From article <786@stag.UUCP>, by trb@stag.UUCP ( Todd Burkey ): > >" This is a request for comments on an editor which will soon be released ... > Sounds REAL nice. Put in an environment var WORD_WRAP to allow wraping instead of side scrolling and the capacity to understand ctags and I am ready to use it. _ "Shadow, do something! Those flying Morpheous / \ birds are going to get us!" Psimon / _ \ shadow master / //\ \ "O.k., o.k., I'll cast Dav El II / // \\ \ Transmute Roc to mud." / /____\\ \ We are the /________\\ \ warrior spirit. \__________\/
wcs) (04/26/89)
In article <786@stag.UUCP> trb@stag.UUCP ( Todd Burkey ) writes:
:This is a request for comments on an editor which will soon be released
:for public abuse. I hope to release the sources to comp.sources.unix
Great! The overall description of capabilities looks like the
kind of stuff I'd love to have around.
:also has some relational capabilities. These allow the user to associate
:lines in their source files with sections of their documentation files
:and vice-versa. And both folding and relations are incorporated in such a
:fashion that they don't impact the original text files in any way.
Try to do this as generally as possible - users will always
try to use a system in ways the author never dreamed of,
and if things are straight-forward and general it helps a lot.
:So what doesn't FOLDED do? Well, the first release will not have an UNDO
:feature. The trash can will have to do. It also is dual mode, something
While I find modes easy to use, they seem to be hard for
people to learn (especially non-programmers, who you may not
care about, but who will use your editor if it's friendly.)
(On the other hand, UNDO is much easier in modes. In either
case, make the trash can big and easy to rummage around in,
and make sure *everything* goes in it (e.g. overwritten
characters, indents, ..)
If you do need modes, make sure to indicate the mode in
big letters somewhere on the screen so users know what's
happening. Similarly, Lotus/MSWord-like menus may be boring,
but they make it easy to just use. And try to make cursor
motion accessible from insert mode as well as command-mode.
There are two obvious approaches to modelessness - either
always be in command-like mode (the emacs approach where "a"
is merely a command to stick an "a" into the text), or
alternatively to always be in insert-like mode, with
commands recognizable because they start with "\" or come
from function keys (=> probably start with ESC.)
:The first release also won't have any key binding capability. I still
:haven't decided upon the best approach to handle user-defined key maps.
Key binding can be very useful for you, the developer, so
you can try things out without yet another round of compile-run.
If you don't provide it, and you do try to avoid having
separate insert and command modes, think really hard about
how this affects things like arrow-and-function keys on
commonly available terminals.
: [ boxes, rectangles, quarter-planes, horizontal scroll ]
Yay! These are nice to have.
:Also, FOLDED does not retain tab characters. ... replaced with white space
Booo! This is *EVIL*! If I put in a tab character, I want a
tab character, and I will refuse to use any program that
thinks I wanted spaces instead! Especially one that trashes
tabs on input. I realize this makes editing rectangles
tougher, but tabs are reality, especially for us troff/tbl users.
When I put in a tab character, *I mean TAB!*.
Similarly, make sure you can support characters with the 8th
bit on (i.e. non-ASCII) - for many people, these are real
characters! Even \0, if you can - then the editor can hack
binary files.
You may want to make some arbitrary definition about what
tabs mean, but leave the characters there. If you *must*
do something obscure with them, here's a suggestion:
Instead of using your trick of deleting initial white space
and keeping an indent-int, leave the characters there, use
the int to keep track of where it indented to, and also keep
a flag that says whether there are non-initial tabs on the line.
If there aren't any (except initials), you can do things
fast&easy, but if there are tabs, the user just waits while
you count over from the left. You get your speed, I get my
tabs, and you only write 25% more code :-)
If you really *must* trash tabs on input, here's an alternative:
fill it out with spaces, but use a tab instead of a space
as the last character, and treat tabs as width-1 internally.
At least then the tab characters are still there, and those
of use who want to move tbl-columns as rectangles can be only
confused instead of totally confused. It's still evil, but
it's compassionate evil:-).
: No line-wrap
Shouldn't be too hard to add, and it makes editing text much
easier - but be careful not to have it break things the way
vi's line-wrap does (try doing a "p" at the end of a line!)
If you do stick with modes, you may want to have wrap only
work in insert mode, and provide a command to explicitly
rewrap hunks of text in command mode.
:The first release of FOLDED has been tested on BSD4.2/3 (Suns, Symetric,
:and Apollo), SYSVR3 (ETA-10), and the ATARI ST. It is being ported by
^^^^^^^
Hey, if you've gotta use System V, might as well start out big!
: FOLDING
:Worried that folding will change your source code? Don't worry, the
:act of folding doesn't affect the edited file at all...even when saved.
Great! However, what happens if someone edits the program file
with emacs in between FOLDED runs? Do you try to recover
(unlikely), warn the user (asking whether to discard the
fold-control-file), or just assume it's right, causing
random folds to show up?
:In summary, folding is fully heirarchical (i.e. a fold can contain any number
:of folds), it is smart (it can fold based on programming logic blocks and
:indentation level), and it is retained from one edit session to the next.
:RELATING:
There are a lot of parallels to hypertext work here - you
should look into it if you haven't yet.
:A second relationship type is that of line relations. These are basically
:invisible links that relate a line in one buffer to a line in another buffer.
Try not to be too literally line-oriented - if you can put
marks at arbitrary points in the file, and maintain them
across formatting changes, it makes them a lot more useful.
Also, what happens if two buffers are different views of the
same file?
:Since I added relations very late in the development of the editor, I have a
:feeling that this area will see the most improvement over the next year. I've
:already decided that I need a few more commands to do things like 'move'
:and 'view' relationships.
:EDITING COMMANDS:
One of the things vi does right (mostly) is maintaining
orthogonality between actions and objects: aN object is
just a cursor-motion, and the way to do something is to
specify the verb (e.g. delete) and the motion. Unlike emacs,
this means you don't have totally different commands to
delete words, sentences, {}groups, ()groups, lines, ..., and
you have a lot more flexibility about creating new
object-types (such as FOLDS!).
--
# Bill Stewart, AT&T Bell Labs 2G218 Holmdel NJ 201-949-0705 ho95c.att.com!wcs
# also found at 201-271-4712 tarpon.att.com!wcs