v08i004: stevie 3.69 - part 2 of 8
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Sun Aug 20 10:47:08 AEST 1989
Posting-number: Volume 8, Issue 4
Submitted-by: tony at cs.utexas.edu@wldrdg.UUCP (Tony Andrews)
Archive-name: stevie3.68/part02
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# help.c
# hexchars.c
# keymap.h
# linefunc.c
# main.c
# mark.c
# misccmds.c
# This archive created: Sun Aug 13 11:45:56 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'help.c'" '(8540 characters)'
if test -f 'help.c'
then
echo shar: will not over-write existing file "'help.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'help.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/help.c,v 1.9 89/08/06 09:50:09 tony Exp $
X *
X * Routine to display a command summary.
X */
X
X#include "stevie.h"
X
Xextern char *Version;
X
Xstatic int helprow;
X
X#ifdef HELP
X
Xstatic void longline();
X
Xbool_t
Xhelp()
X{
X
X/***********************************************************************
X * First Screen: Positioning within file, Adjusting the Screen
X ***********************************************************************/
X
X outstr(T_ED);
X windgoto(helprow = 0, 0);
X
Xlongline("\
X Positioning within file\n\
X =======================\n\
X ^F Forward screenfull Developed by:\n\
X ^B Backward screenfull Tony Andrews\n");
Xlongline("\
X ^D scroll down half screen\n\
X ^U scroll up half screen Based on a program by:\n");
Xlongline("\
X G Goto line (end default) Tim Thompson\n\
X ]] next function\n\
X [[ previous function\n\
X /re next occurence of regular expression 're'\n");
Xlongline("\
X ?re prior occurence of regular expression 're'\n\
X n repeat last / or ?\n\
X N reverse last / or ?\n\
X % find matching (, ), {, }, [, or ]\n");
Xlongline("\
X\n\
X Adjusting the screen\n\
X ====================\n\
X ^L Redraw the screen\n\
X ^E scroll window down 1 line\n\
X ^Y scroll window up 1 line\n");
Xlongline("\
X z<RETURN> redraw, current line at top\n\
X z- ... at bottom\n\
X z. ... at center\n");
X
X windgoto(0, 52);
X longline(Version);
X
X windgoto(helprow = Rows-2, 47);
X longline("<Press space bar to continue>\n");
X windgoto(helprow = Rows-1, 47);
X longline("<Any other key will quit>");
X
X if ( vgetc() != ' ' )
X return TRUE;
X
X/***********************************************************************
X * Second Screen: Character positioning
X ***********************************************************************/
X
X outstr(T_ED);
X windgoto(helprow = 0, 0);
X
Xlongline("\
X Character Positioning\n\
X =====================\n\
X ^ first non-white\n\
X 0 beginning of line\n\
X $ end of line\n\
X h backward\n");
Xlongline("\
X l forward\n\
X ^H same as h\n\
X space same as l\n\
X fx find 'x' forward\n");
Xlongline("\
X Fx find 'x' backward\n\
X tx upto 'x' forward\n\
X Tx upto 'x' backward\n\
X ; Repeat last f, F, t, or T\n");
Xlongline("\
X , inverse of ;\n\
X | to specified column\n\
X % find matching (, ), {, }, [, or ]\n");
X
X windgoto(helprow = Rows-2, 47);
X longline("<Press space bar to continue>\n");
X windgoto(helprow = Rows-1, 47);
X longline("<Any other key will quit>");
X
X if ( vgetc() != ' ' )
X return TRUE;
X
X/***********************************************************************
X * Third Screen: Line Positioning, Marking and Returning
X ***********************************************************************/
X
X outstr(T_ED);
X windgoto(helprow = 0, 0);
X
Xlongline("\
X Line Positioning\n\
X ================\n\
X H home window line\n\
X L last window line\n\
X M middle window line\n");
Xlongline("\
X + next line, at first non-white\n\
X - previous line, at first non-white\n\
X CR return, same as +\n\
X j next line, same column\n\
X k previous line, same column\n");
X
Xlongline("\
X\n\
X Marking and Returning\n\
X =====================\n\
X `` previous context\n\
X '' ... at first non-white in line\n");
Xlongline("\
X mx mark position with letter 'x'\n\
X `x to mark 'x'\n\
X 'x ... at first non-white in line\n");
X
Xlongline("\n\
X Undo & Redo\n\
X =============\n\
X u undo last change\n\
X U restore current line\n\
X . repeat last change\n");
X
X windgoto(helprow = Rows-2, 47);
X longline("<Press space bar to continue>\n");
X windgoto(helprow = Rows-1, 47);
X longline("<Any other key will quit>");
X
X if ( vgetc() != ' ' )
X return TRUE;
X/***********************************************************************
X * Fourth Screen: Insert & Replace,
X ***********************************************************************/
X
X outstr(T_ED);
X windgoto(helprow = 0, 0);
X
Xlongline("\
X Insert and Replace\n\
X ==================\n\
X a append after cursor\n\
X i insert before cursor\n\
X A append at end of line\n\
X I insert before first non-blank\n");
Xlongline("\
X o open line below\n\
X O open line above\n\
X rx replace single char with 'x'\n\
X R replace characters\n");
X
Xlongline("\
X\n\
X Words, sentences, paragraphs\n\
X ============================\n\
X w word forward\n\
X b back word\n\
X e end of word\n\
X ) to next sentence (not yet)\n\
X } to next paragraph (not yet)\n");
Xlongline("\
X ( back sentence (not yet)\n\
X { back paragraph (not yet)\n\
X W blank delimited word\n\
X B back W\n\
X E to end of W\n");
X
X windgoto(helprow = Rows-2, 47);
X longline("<Press space bar to continue>\n");
X windgoto(helprow = Rows-1, 47);
X longline("<Any other key will quit>");
X
X if ( vgetc() != ' ' )
X return TRUE;
X
X/***********************************************************************
X * Fifth Screen: Misc. operations,
X ***********************************************************************/
X
X outstr(T_ED);
X windgoto(helprow = 0, 0);
X
Xlongline("\
X Miscellaneous Commands\n\
X ======================\n");
Xlongline("\
X :w write back changes\n\
X :wq write and quit\n\
X :x write if modified, and quit\n\
X :q quit\n\
X :q! quit, discard changes\n\
X :e name edit file 'name'\n");
Xlongline("\
X :e! reedit, discard changes\n\
X :e # edit alternate file\n\
X :w name write file 'name'\n");
Xlongline("\
X :n edit next file in arglist\n\
X :N edit prior file in arglist\n\
X :n args specify new arglist (not yet)\n\
X :rew rewind arglist\n\
X :f show current file and lines\n");
Xlongline("\
X :f file change current file name\n\
X :g/pat/p|d global command (print or delete only)\n\
X :s/p1/p2/ text substitution (trailing 'g' optional)\n\
X");
Xlongline("\
X :ta tag to tag file entry 'tag'\n\
X ^] :ta, current word is tag\n\
X :sh run an interactive shell\n\
X :!cmd execute a shell command\n\
X");
X
X windgoto(helprow = Rows-2, 47);
X longline("<Press space bar to continue>\n");
X windgoto(helprow = Rows-1, 47);
X longline("<Any other key will quit>");
X
X if ( vgetc() != ' ' )
X return TRUE;
X
X/***********************************************************************
X * Sixth Screen: Operators, Misc. operations, Yank & Put
X ***********************************************************************/
X
X outstr(T_ED);
X windgoto(helprow = 0, 0);
X
Xlongline("\
X Operators (double to affect lines)\n\
X ==================================\n\
X d delete\n\
X c change\n");
Xlongline("\
X < left shift\n\
X > right shift\n\
X y yank to buffer\n\
X ! filter lines\n");
X
Xlongline("\n\
X Miscellaneous operations\n\
X ========================\n\
X C change rest of line\n\
X D delete rest of line\n\
X s substitute chars\n");
Xlongline("\
X S substitute lines (not yet)\n\
X J join lines\n\
X x delete characters\n\
X X ... before cursor\n");
X
Xlongline("\n\
X Yank and Put\n\
X ============\n\
X p put back text\n\
X P put before\n\
X Y yank lines");
X
X windgoto(helprow = Rows-1, 47);
X longline("<Press any key>");
X
X (void) vgetc();
X
X return TRUE;
X}
X
Xstatic void
Xlongline(p)
Xchar *p;
X{
X register char *s;
X
X for ( s = p; *s ;s++ ) {
X if ( *s == '\n' )
X windgoto(++helprow, 0);
X else
X outchar(*s);
X }
X}
X#else
X
Xbool_t
Xhelp()
X{
X msg("Sorry, help not configured");
X return FALSE;
X}
X#endif
HE_HATES_THESE_CANS
if test 8540 -ne "`wc -c < 'help.c'`"
then
echo shar: error transmitting "'help.c'" '(should have been 8540 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'hexchars.c'" '(3109 characters)'
if test -f 'hexchars.c'
then
echo shar: will not over-write existing file "'hexchars.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'hexchars.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/hexchars.c,v 1.4 89/03/11 22:42:27 tony Exp $
X *
X * Contains information concerning the representation of characters for
X * visual output by the editor.
X */
X
X#include "stevie.h"
X
X/*
X * This file shows how to display characters on the screen. This is
X * approach is something of an overkill. It's a remnant from the
X * original code that isn't worth messing with for now. TABS are
X * special-cased depending on the value of the "list" parameter.
X */
X
Xstruct charinfo chars[] = {
X /* 000 */ 1, NULL,
X /* 001 */ 2, "^A",
X /* 002 */ 2, "^B",
X /* 003 */ 2, "^C",
X /* 004 */ 2, "^D",
X /* 005 */ 2, "^E",
X /* 006 */ 2, "^F",
X /* 007 */ 2, "^G",
X /* 010 */ 2, "^H",
X /* 011 */ 2, "^I",
X /* 012 */ 7, "[ERROR]", /* shouldn't occur */
X /* 013 */ 2, "^K",
X /* 014 */ 2, "^L",
X /* 015 */ 2, "^M",
X /* 016 */ 2, "^N",
X /* 017 */ 2, "^O",
X /* 020 */ 2, "^P",
X /* 021 */ 2, "^Q",
X /* 022 */ 2, "^R",
X /* 023 */ 2, "^S",
X /* 024 */ 2, "^T",
X /* 025 */ 2, "^U",
X /* 026 */ 2, "^V",
X /* 027 */ 2, "^W",
X /* 030 */ 2, "^X",
X /* 031 */ 2, "^Y",
X /* 032 */ 2, "^Z",
X /* 033 */ 2, "^[",
X /* 034 */ 2, "^\\",
X /* 035 */ 2, "^]",
X /* 036 */ 2, "^^",
X /* 037 */ 2, "^_",
X /* 040 */ 1, NULL,
X /* 041 */ 1, NULL,
X /* 042 */ 1, NULL,
X /* 043 */ 1, NULL,
X /* 044 */ 1, NULL,
X /* 045 */ 1, NULL,
X /* 046 */ 1, NULL,
X /* 047 */ 1, NULL,
X /* 050 */ 1, NULL,
X /* 051 */ 1, NULL,
X /* 052 */ 1, NULL,
X /* 053 */ 1, NULL,
X /* 054 */ 1, NULL,
X /* 055 */ 1, NULL,
X /* 056 */ 1, NULL,
X /* 057 */ 1, NULL,
X /* 060 */ 1, NULL,
X /* 061 */ 1, NULL,
X /* 062 */ 1, NULL,
X /* 063 */ 1, NULL,
X /* 064 */ 1, NULL,
X /* 065 */ 1, NULL,
X /* 066 */ 1, NULL,
X /* 067 */ 1, NULL,
X /* 070 */ 1, NULL,
X /* 071 */ 1, NULL,
X /* 072 */ 1, NULL,
X /* 073 */ 1, NULL,
X /* 074 */ 1, NULL,
X /* 075 */ 1, NULL,
X /* 076 */ 1, NULL,
X /* 077 */ 1, NULL,
X /* 100 */ 1, NULL,
X /* 101 */ 1, NULL,
X /* 102 */ 1, NULL,
X /* 103 */ 1, NULL,
X /* 104 */ 1, NULL,
X /* 105 */ 1, NULL,
X /* 106 */ 1, NULL,
X /* 107 */ 1, NULL,
X /* 110 */ 1, NULL,
X /* 111 */ 1, NULL,
X /* 112 */ 1, NULL,
X /* 113 */ 1, NULL,
X /* 114 */ 1, NULL,
X /* 115 */ 1, NULL,
X /* 116 */ 1, NULL,
X /* 117 */ 1, NULL,
X /* 120 */ 1, NULL,
X /* 121 */ 1, NULL,
X /* 122 */ 1, NULL,
X /* 123 */ 1, NULL,
X /* 124 */ 1, NULL,
X /* 125 */ 1, NULL,
X /* 126 */ 1, NULL,
X /* 127 */ 1, NULL,
X /* 130 */ 1, NULL,
X /* 131 */ 1, NULL,
X /* 132 */ 1, NULL,
X /* 133 */ 1, NULL,
X /* 134 */ 1, NULL,
X /* 135 */ 1, NULL,
X /* 136 */ 1, NULL,
X /* 137 */ 1, NULL,
X /* 140 */ 1, NULL,
X /* 141 */ 1, NULL,
X /* 142 */ 1, NULL,
X /* 143 */ 1, NULL,
X /* 144 */ 1, NULL,
X /* 145 */ 1, NULL,
X /* 146 */ 1, NULL,
X /* 147 */ 1, NULL,
X /* 150 */ 1, NULL,
X /* 151 */ 1, NULL,
X /* 152 */ 1, NULL,
X /* 153 */ 1, NULL,
X /* 154 */ 1, NULL,
X /* 155 */ 1, NULL,
X /* 156 */ 1, NULL,
X /* 157 */ 1, NULL,
X /* 160 */ 1, NULL,
X /* 161 */ 1, NULL,
X /* 162 */ 1, NULL,
X /* 163 */ 1, NULL,
X /* 164 */ 1, NULL,
X /* 165 */ 1, NULL,
X /* 166 */ 1, NULL,
X /* 167 */ 1, NULL,
X /* 170 */ 1, NULL,
X /* 171 */ 1, NULL,
X /* 172 */ 1, NULL,
X /* 173 */ 1, NULL,
X /* 174 */ 1, NULL,
X /* 175 */ 1, NULL,
X /* 176 */ 1, NULL,
X /* 177 */ 2, "^?",
X};
HE_HATES_THESE_CANS
if test 3109 -ne "`wc -c < 'hexchars.c'`"
then
echo shar: error transmitting "'hexchars.c'" '(should have been 3109 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'keymap.h'" '(936 characters)'
if test -f 'keymap.h'
then
echo shar: will not over-write existing file "'keymap.h'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'keymap.h'
X/*
X * $Header: /nw/tony/src/stevie/src/RCS/keymap.h,v 1.2 89/03/11 22:42:30 tony Exp $
X *
X * Keycode definitions for special keys
X *
X * On systems that have any of these keys, the routine 'inchar' in the
X * machine-dependent code should return one of the codes here.
X */
X
X#define K_HELP 0x80
X#define K_UNDO 0x81
X#define K_INSERT 0x82
X#define K_HOME 0x83
X#define K_UARROW 0x84
X#define K_DARROW 0x85
X#define K_LARROW 0x86
X#define K_RARROW 0x87
X#define K_CGRAVE 0x88 /* control grave accent */
X
X#define K_F1 0x91 /* function keys */
X#define K_F2 0x92
X#define K_F3 0x93
X#define K_F4 0x94
X#define K_F5 0x95
X#define K_F6 0x96
X#define K_F7 0x97
X#define K_F8 0x98
X#define K_F9 0x99
X#define K_F10 0x9a
X
X#define K_SF1 0xa1 /* shifted function keys */
X#define K_SF2 0xa2
X#define K_SF3 0xa3
X#define K_SF4 0xa4
X#define K_SF5 0xa5
X#define K_SF6 0xa6
X#define K_SF7 0xa7
X#define K_SF8 0xa8
X#define K_SF9 0xa9
X#define K_SF10 0xaa
HE_HATES_THESE_CANS
if test 936 -ne "`wc -c < 'keymap.h'`"
then
echo shar: error transmitting "'keymap.h'" '(should have been 936 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'linefunc.c'" '(1583 characters)'
if test -f 'linefunc.c'
then
echo shar: will not over-write existing file "'linefunc.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'linefunc.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/linefunc.c,v 1.2 89/03/11 22:42:32 tony Exp $
X *
X * Basic line-oriented motions.
X */
X
X#include "stevie.h"
X
X/*
X * nextline(curr)
X *
X * Return a pointer to the beginning of the next line after the one
X * referenced by 'curr'. Return NULL if there is no next line (at EOF).
X */
X
XLPTR *
Xnextline(curr)
XLPTR *curr;
X{
X static LPTR next;
X
X if (curr->linep->next != Fileend->linep) {
X next.index = 0;
X next.linep = curr->linep->next;
X return &next;
X }
X return (LPTR *) NULL;
X}
X
X/*
X * prevline(curr)
X *
X * Return a pointer to the beginning of the line before the one
X * referenced by 'curr'. Return NULL if there is no prior line.
X */
X
XLPTR *
Xprevline(curr)
XLPTR *curr;
X{
X static LPTR prev;
X
X if (curr->linep->prev != Filetop->linep) {
X prev.index = 0;
X prev.linep = curr->linep->prev;
X return &prev;
X }
X return (LPTR *) NULL;
X}
X
X/*
X * coladvance(p,col)
X *
X * Try to advance to the specified column, starting at p.
X */
X
XLPTR *
Xcoladvance(p, col)
XLPTR *p;
Xregister int col;
X{
X static LPTR lp;
X register int c, in;
X
X lp.linep = p->linep;
X lp.index = p->index;
X
X /* If we're on a blank ('\n' only) line, we can't do anything */
X if (lp.linep->s[lp.index] == '\0')
X return &lp;
X /* try to advance to the specified column */
X for ( c=0; col-- > 0; c++ ) {
X /* Count a tab for what it's worth (if list mode not on) */
X if ( gchar(&lp) == TAB && !P(P_LS) ) {
X in = ((P(P_TS)-1) - c%P(P_TS));
X col -= in;
X c += in;
X }
X /* Don't go past the end of */
X /* the file or the line. */
X if (inc(&lp)) {
X dec(&lp);
X break;
X }
X }
X return &lp;
X}
HE_HATES_THESE_CANS
if test 1583 -ne "`wc -c < 'linefunc.c'`"
then
echo shar: error transmitting "'linefunc.c'" '(should have been 1583 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'main.c'" '(7199 characters)'
if test -f 'main.c'
then
echo shar: will not over-write existing file "'main.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'main.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/main.c,v 1.12 89/08/02 19:53:27 tony Exp $
X *
X * The main routine and routines to deal with the input buffer.
X */
X
X#include "stevie.h"
X
Xint Rows; /* Number of Rows and Columns */
Xint Columns; /* in the current window. */
X
Xchar *Realscreen = NULL; /* What's currently on the screen, a single */
X /* array of size Rows*Columns. */
Xchar *Nextscreen = NULL; /* What's to be put on the screen. */
X
Xchar *Filename = NULL; /* Current file name */
X
XLPTR *Filemem; /* Pointer to the first line of the file */
X
XLPTR *Filetop; /* Line 'above' the start of the file */
X
XLPTR *Fileend; /* Pointer to the end of the file in Filemem. */
X /* (It points to the byte AFTER the last byte.) */
X
XLPTR *Topchar; /* Pointer to the byte in Filemem which is */
X /* in the upper left corner of the screen. */
X
XLPTR *Botchar; /* Pointer to the byte in Filemem which is */
X /* just off the bottom of the screen. */
X
XLPTR *Curschar; /* Pointer to byte in Filemem at which the */
X /* cursor is currently placed. */
X
Xint Cursrow, Curscol; /* Current position of cursor */
X
Xint Cursvcol; /* Current virtual column, the column number of */
X /* the file's actual line, as opposed to the */
X /* column number we're at on the screen. This */
X /* makes a difference on lines that span more */
X /* than one screen line. */
X
Xint Curswant = 0; /* The column we'd like to be at. This is used */
X /* try to stay in the same column through up/down */
X /* cursor motions. */
X
Xbool_t set_want_col; /* If set, then update Curswant the next time */
X /* through cursupdate() to the current virtual */
X /* column. */
X
Xint State = NORMAL; /* This is the current state of the command */
X /* interpreter. */
X
Xint Prenum = 0; /* The (optional) number before a command. */
X
XLPTR *Insstart; /* This is where the latest insert/append */
X /* mode started. */
X
Xbool_t Changed = 0; /* Set to 1 if something in the file has been */
X /* changed and not written out. */
X
Xchar Redobuff[1024]; /* Each command should stuff characters into this */
X /* buffer that will re-execute itself. */
X
Xchar Insbuff[1024]; /* Each insertion gets stuffed into this buffer. */
X
Xint Ninsert = 0; /* Number of characters in the current insertion. */
Xchar *Insptr = NULL;
X
Xbool_t got_int=FALSE; /* set to TRUE when an interrupt occurs (if possible) */
X
Xbool_t interactive = FALSE; /* set TRUE when main() is ready to roll */
X
Xchar **files; /* list of input files */
Xint numfiles; /* number of input files */
Xint curfile; /* number of the current file */
X
Xstatic void
Xusage()
X{
X fprintf(stderr, "usage: stevie [file ...]\n");
X fprintf(stderr, " stevie -t tag\n");
X fprintf(stderr, " stevie +[num] file\n");
X fprintf(stderr, " stevie +/pat file\n");
X exit(1);
X}
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X char *initstr, *getenv(); /* init string from the environment */
X char *tag = NULL; /* tag from command line */
X char *pat = NULL; /* pattern from command line */
X int line = -1; /* line number from command line */
X
X /*
X * Process the command line arguments.
X */
X if (argc > 1) {
X switch (argv[1][0]) {
X
X case '-': /* -t tag */
X if (argv[1][1] != 't')
X usage();
X
X if (argv[2] == NULL)
X usage();
X
X Filename = NULL;
X tag = argv[2];
X numfiles = 1;
X break;
X
X case '+': /* +n or +/pat */
X if (argv[1][1] == '/') {
X if (argv[2] == NULL)
X usage();
X Filename = strsave(argv[2]);
X pat = &(argv[1][1]);
X numfiles = 1;
X
X } else if (isdigit(argv[1][1]) || argv[1][1] == NUL) {
X if (argv[2] == NULL)
X usage();
X Filename = strsave(argv[2]);
X numfiles = 1;
X
X line = (isdigit(argv[1][1])) ?
X atoi(&(argv[1][1])) : 0;
X } else
X usage();
X
X break;
X
X default: /* must be a file name */
X Filename = strsave(argv[1]);
X files = &(argv[1]);
X numfiles = argc - 1;
X break;
X }
X } else {
X Filename = NULL;
X numfiles = 1;
X }
X curfile = 0;
X
X if (numfiles > 1)
X fprintf(stderr, "%d files to edit\n", numfiles);
X
X windinit();
X
X /*
X * Allocate LPTR structures for all the various position pointers
X */
X if ((Filemem = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X (Filetop = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X (Fileend = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X (Topchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X (Botchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X (Curschar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X (Insstart = (LPTR *) malloc(sizeof(LPTR))) == NULL ) {
X fprintf(stderr, "Can't allocate data structures\n");
X windexit(0);
X }
X
X screenalloc();
X filealloc(); /* Initialize Filemem, Filetop, and Fileend */
X
X screenclear();
X
X if ((initstr = getenv("EXINIT")) != NULL) {
X char *lp, buf[128];
X
X if ((lp = getenv("LINES")) != NULL) {
X sprintf(buf, "%s lines=%s", initstr, lp);
X docmdln(buf);
X } else
X docmdln(initstr);
X }
X
X if (Filename != NULL) {
X if (readfile(Filename, Filemem, FALSE))
X filemess("[New File]");
X } else if (tag == NULL)
X msg("Empty Buffer");
X
X setpcmark();
X
X if (tag) {
X stuffin(":ta ");
X stuffin(tag);
X stuffin("\n");
X
X } else if (pat) {
X stuffin(pat);
X stuffin("\n");
X
X } else if (line >= 0) {
X if (line > 0)
X stuffnum(line);
X stuffin("G");
X }
X
X interactive = TRUE;
X
X edit();
X
X windexit(0);
X
X return 1; /* shouldn't be reached */
X}
X
X#define RBSIZE 1024
Xstatic char getcbuff[RBSIZE];
Xstatic char *getcnext = NULL;
X
Xvoid
Xstuffin(s)
Xchar *s;
X{
X if (s == NULL) { /* clear the stuff buffer */
X getcnext = NULL;
X return;
X }
X
X if (getcnext == NULL) {
X strcpy(getcbuff,s);
X getcnext = getcbuff;
X } else
X strcat(getcbuff,s);
X}
X
Xvoid
Xstuffnum(n)
Xint n;
X{
X char buf[32];
X
X sprintf(buf, "%d", n);
X stuffin(buf);
X}
X
Xint
Xvgetc()
X{
X register int c;
X
X /*
X * inchar() may map special keys by using stuffin(). If it does
X * so, it returns -1 so we know to loop here to get a real char.
X */
X do {
X if ( getcnext != NULL ) {
X int nextc = *getcnext++;
X if ( *getcnext == NUL ) {
X *getcbuff = NUL;
X getcnext = NULL;
X }
X return(nextc);
X }
X c = inchar();
X } while (c == -1);
X
X return c;
X}
X
X/*
X * anyinput
X *
X * Return non-zero if input is pending.
X */
X
Xbool_t
Xanyinput()
X{
X return (getcnext != NULL);
X}
X
X/*
X * do_mlines() - process mode lines for the current file
X *
X * Returns immediately if the "ml" parameter isn't set.
X */
X#define NMLINES 5 /* no. of lines at start/end to check for modelines */
X
Xvoid
Xdo_mlines()
X{
X void chk_mline();
X int i;
X register LPTR *p;
X
X if (!P(P_ML))
X return;
X
X p = Filemem;
X for (i=0; i < NMLINES ;i++) {
X chk_mline(p->linep->s);
X if ((p = nextline(p)) == NULL)
X break;
X }
X
X if ((p = prevline(Fileend)) == NULL)
X return;
X
X for (i=0; i < NMLINES ;i++) {
X chk_mline(p->linep->s);
X if ((p = prevline(p)) == NULL)
X break;
X }
X}
X
X/*
X * chk_mline() - check a single line for a mode string
X */
Xstatic void
Xchk_mline(s)
Xregister char *s;
X{
X register char *cs; /* local copy of any modeline found */
X register char *e;
X
X for (; *s != NUL ;s++) {
X if (strncmp(s, "vi:", 3) == 0 || strncmp(s, "ex:", 3) == 0) {
X cs = strsave(s+3);
X if ((e = strchr(cs, ':')) != NULL) {
X *e = NUL;
X stuffin(mkstr(CTRL('o')));
X docmdln(cs);
X }
X free(cs);
X }
X }
X}
HE_HATES_THESE_CANS
if test 7199 -ne "`wc -c < 'main.c'`"
then
echo shar: error transmitting "'main.c'" '(should have been 7199 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mark.c'" '(2186 characters)'
if test -f 'mark.c'
then
echo shar: will not over-write existing file "'mark.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'mark.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/mark.c,v 1.3 89/03/11 22:42:39 tony Exp $
X *
X * Routines to save and retrieve marks.
X */
X
X#include "stevie.h"
X
X#define NMARKS 10 /* max. # of marks that can be saved */
X
Xstruct mark {
X char name;
X LPTR pos;
X};
X
Xstatic struct mark mlist[NMARKS];
Xstatic struct mark pcmark; /* previous context mark */
Xstatic bool_t pcvalid = FALSE; /* true if pcmark is valid */
X
X/*
X * setmark(c) - set mark 'c' at current cursor position
X *
X * Returns TRUE on success, FALSE if no room for mark or bad name given.
X */
Xbool_t
Xsetmark(c)
Xregister char c;
X{
X register int i;
X
X if (!isalpha(c))
X return FALSE;
X
X /*
X * If there is already a mark of this name, then just use the
X * existing mark entry.
X */
X for (i=0; i < NMARKS ;i++) {
X if (mlist[i].name == c) {
X mlist[i].pos = *Curschar;
X return TRUE;
X }
X }
X
X /*
X * There wasn't a mark of the given name, so find a free slot
X */
X for (i=0; i < NMARKS ;i++) {
X if (mlist[i].name == NUL) { /* got a free one */
X mlist[i].name = c;
X mlist[i].pos = *Curschar;
X return TRUE;
X }
X }
X return FALSE;
X}
X
X/*
X * setpcmark() - set the previous context mark to the current position
X */
Xvoid
Xsetpcmark()
X{
X pcmark.pos = *Curschar;
X pcvalid = TRUE;
X}
X
X/*
X * getmark(c) - find mark for char 'c'
X *
X * Return pointer to LPTR or NULL if no such mark.
X */
XLPTR *
Xgetmark(c)
Xregister char c;
X{
X register int i;
X
X if (c == '\'' || c == '`') /* previous context mark */
X return pcvalid ? &(pcmark.pos) : (LPTR *) NULL;
X
X for (i=0; i < NMARKS ;i++) {
X if (mlist[i].name == c)
X return &(mlist[i].pos);
X }
X return (LPTR *) NULL;
X}
X
X/*
X * clrall() - clear all marks
X *
X * Used mainly when trashing the entire buffer during ":e" type commands
X */
Xvoid
Xclrall()
X{
X register int i;
X
X for (i=0; i < NMARKS ;i++)
X mlist[i].name = NUL;
X pcvalid = FALSE;
X}
X
X/*
X * clrmark(line) - clear any marks for 'line'
X *
X * Used any time a line is deleted so we don't have marks pointing to
X * non-existent lines.
X */
Xvoid
Xclrmark(line)
Xregister LINE *line;
X{
X register int i;
X
X for (i=0; i < NMARKS ;i++) {
X if (mlist[i].pos.linep == line)
X mlist[i].name = NUL;
X }
X if (pcvalid && (pcmark.pos.linep == line))
X pcvalid = FALSE;
X}
HE_HATES_THESE_CANS
if test 2186 -ne "`wc -c < 'mark.c'`"
then
echo shar: error transmitting "'mark.c'" '(should have been 2186 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'misccmds.c'" '(9492 characters)'
if test -f 'misccmds.c'
then
echo shar: will not over-write existing file "'misccmds.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'misccmds.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/misccmds.c,v 1.14 89/08/06 09:50:17 tony Exp $
X *
X * Various routines to perform specific editing operations or return
X * useful information about the file.
X */
X
X#include "stevie.h"
X
Xstatic void openfwd(), openbwd();
X
Xextern bool_t did_ai;
X
X/*
X * opencmd
X *
X * Add a blank line above or below the current line.
X */
X
Xvoid
Xopencmd(dir, can_ai)
Xint dir;
Xint can_ai; /* if true, consider auto-indent */
X{
X if (dir == FORWARD)
X openfwd(can_ai);
X else
X openbwd(can_ai);
X}
X
Xstatic void
Xopenfwd(can_ai)
Xint can_ai;
X{
X register LINE *l;
X LPTR *next;
X register char *s; /* string to be moved to new line, if any */
X int newindex = 0; /* index of the cursor on the new line */
X
X /*
X * If we're in insert mode, we need to move the remainder of the
X * current line onto the new line. Otherwise the new line is left
X * blank.
X */
X if (State == INSERT || State == REPLACE)
X s = &Curschar->linep->s[Curschar->index];
X else
X s = "";
X
X if ((next = nextline(Curschar)) == NULL) /* open on last line */
X next = Fileend;
X
X /*
X * By asking for as much space as the prior line had we make sure
X * that we'll have enough space for any auto-indenting.
X */
X if ((l = newline(strlen(Curschar->linep->s) + SLOP)) == NULL)
X return;
X
X if (*s != NUL)
X strcpy(l->s, s); /* copy string to new line */
X
X else if (can_ai && P(P_AI) && !anyinput()) {
X char *p;
X
X /*
X * Copy prior line, and truncate after white space
X */
X strcpy(l->s, Curschar->linep->s);
X
X for (p = l->s; *p == ' ' || *p == TAB ;p++)
X ;
X *p = NUL;
X newindex = p - l->s;
X
X /*
X * If we just did an auto-indent, then we didn't type
X * anything on the prior line, and it should be truncated.
X */
X if (did_ai)
X Curschar->linep->s[0] = NUL;
X
X did_ai = TRUE;
X }
X
X /* truncate current line at cursor */
X if (State == INSERT || State == REPLACE)
X *s = NUL;
X
X
X Curschar->linep->next = l; /* link neighbors to new line */
X next->linep->prev = l;
X
X l->prev = Curschar->linep; /* link new line to neighbors */
X l->next = next->linep;
X
X if (next == Fileend) /* new line at end */
X l->num = Curschar->linep->num + LINEINC;
X
X else if ((l->prev->num) + 1 == l->next->num) /* no gap, renumber */
X renum();
X
X else { /* stick it in the middle */
X unsigned long lnum;
X lnum = ((long)l->prev->num + (long)l->next->num) / 2;
X l->num = lnum;
X }
X
X /*
X * Get the cursor to the start of the line, so that 'Cursrow'
X * gets set to the right physical line number for the stuff
X * that follows...
X */
X Curschar->index = 0;
X cursupdate();
X
X /*
X * If we're doing an open on the last logical line, then
X * go ahead and scroll the screen up. Otherwise, just insert
X * a blank line at the right place. We use calls to plines()
X * in case the cursor is resting on a long line.
X */
X if (Cursrow + plines(Curschar) == (Rows - 1))
X scrollup(1);
X else
X s_ins(Cursrow+plines(Curschar), 1);
X
X *Curschar = *nextline(Curschar); /* cursor moves down */
X Curschar->index = newindex;
X
X updatescreen(); /* because Botchar is now invalid... */
X
X cursupdate(); /* update Cursrow before insert */
X}
X
Xstatic void
Xopenbwd(can_ai)
Xint can_ai;
X{
X register LINE *l;
X LINE *prev;
X int newindex = 0;
X
X prev = Curschar->linep->prev;
X
X if ((l = newline(strlen(Curschar->linep->s) + SLOP)) == NULL)
X return;
X
X Curschar->linep->prev = l; /* link neighbors to new line */
X prev->next = l;
X
X l->next = Curschar->linep; /* link new line to neighbors */
X l->prev = prev;
X
X if (can_ai && P(P_AI) && !anyinput()) {
X char *p;
X
X /*
X * Copy current line, and truncate after white space
X */
X strcpy(l->s, Curschar->linep->s);
X
X for (p = l->s; *p == ' ' || *p == TAB ;p++)
X ;
X *p = NUL;
X newindex = p - l->s;
X
X did_ai = TRUE;
X }
X
X Curschar->linep = Curschar->linep->prev;
X Curschar->index = newindex;
X
X if (prev == Filetop->linep) /* new start of file */
X Filemem->linep = l;
X
X renum(); /* keep it simple - we don't do this often */
X
X cursupdate(); /* update Cursrow before insert */
X if (Cursrow != 0)
X s_ins(Cursrow, 1); /* insert a physical line */
X
X updatescreen();
X}
X
Xint
Xcntllines(pbegin,pend)
Xregister LPTR *pbegin, *pend;
X{
X register LINE *lp;
X int lnum = 1;
X
X for (lp = pbegin->linep; lp != pend->linep ;lp = lp->next)
X lnum++;
X
X return(lnum);
X}
X
X/*
X * plines(p) - return the number of physical screen lines taken by line 'p'
X */
Xint
Xplines(p)
XLPTR *p;
X{
X register int col = 0;
X register char *s;
X
X s = p->linep->s;
X
X if (*s == NUL) /* empty line */
X return 1;
X
X for (; *s != NUL ;s++) {
X if ( *s == TAB && !P(P_LS))
X col += P(P_TS) - (col % P(P_TS));
X else
X col += chars[(unsigned)(*s & 0xff)].ch_size;
X }
X
X /*
X * If list mode is on, then the '$' at the end of
X * the line takes up one extra column.
X */
X if (P(P_LS))
X col += 1;
X /*
X * If 'number' mode is on, add another 8.
X */
X if (P(P_NU))
X col += 8;
X
X return ((col + (Columns-1)) / Columns);
X}
X
Xvoid
Xfileinfo()
X{
X extern int numfiles, curfile;
X register long l1, l2;
X
X if (bufempty()) {
X l1 = 0;
X l2 = 1; /* don't div by zero */
X } else {
X l1 = cntllines(Filemem, Curschar);
X l2 = cntllines(Filemem, Fileend) - 1;
X }
X
X if (numfiles > 1)
X smsg("\"%s\"%s line %ld of %ld -- %ld %% -- (file %d of %d)",
X (Filename != NULL) ? Filename : "No File",
X Changed ? " [Modified]" : "",
X l1, l2, (l1 * 100)/l2,
X curfile+1, numfiles);
X else
X smsg("\"%s\"%s line %ld of %ld -- %ld %% --",
X (Filename != NULL) ? Filename : "No File",
X Changed ? " [Modified]" : "",
X l1, l2, (l1 * 100)/l2);
X}
X
X/*
X * gotoline(n) - return a pointer to line 'n'
X *
X * Returns a pointer to the last line of the file if n is zero, or
X * beyond the end of the file.
X */
XLPTR *
Xgotoline(n)
Xregister int n;
X{
X static LPTR l;
X
X l.index = 0;
X
X if ( n == 0 )
X l = *prevline(Fileend);
X else {
X LPTR *p;
X
X for (l = *Filemem; --n > 0 ;l = *p)
X if ((p = nextline(&l)) == NULL)
X break;
X }
X return &l;
X}
X
Xvoid
Xinschar(c)
Xint c;
X{
X register char *p, *pend;
X
X /* make room for the new char. */
X if ( ! canincrease(1) )
X return;
X
X if (State != REPLACE) {
X p = &Curschar->linep->s[strlen(Curschar->linep->s) + 1];
X pend = &Curschar->linep->s[Curschar->index];
X
X for (; p > pend ;p--)
X *p = *(p-1);
X
X *p = c;
X
X } else { /* replace mode */
X /*
X * Once we reach the end of the line, we are effectively
X * inserting new text, so make sure the string terminator
X * stays out there.
X */
X if (gchar(Curschar) == NUL)
X Curschar->linep->s[Curschar->index+1] = NUL;
X pchar(Curschar, c);
X }
X
X /*
X * If we're in insert mode and showmatch mode is set, then
X * check for right parens and braces. If there isn't a match,
X * then beep. If there is a match AND it's on the screen, then
X * flash to it briefly. If it isn't on the screen, don't do anything.
X */
X if (P(P_SM) && State == INSERT && (c == ')' || c == '}' || c == ']')) {
X LPTR *lpos, csave;
X
X if ((lpos = showmatch()) == NULL) /* no match, so beep */
X beep();
X else if (LINEOF(lpos) >= LINEOF(Topchar)) {
X updatescreen(); /* show the new char first */
X csave = *Curschar;
X *Curschar = *lpos; /* move to matching char */
X cursupdate();
X windgoto(Cursrow, Curscol);
X delay(); /* brief pause */
X *Curschar = csave; /* restore cursor position */
X cursupdate();
X }
X }
X
X inc(Curschar);
X CHANGED;
X}
X
Xbool_t
Xdelchar(fixpos)
Xbool_t fixpos; /* if TRUE, fix the cursor position when done */
X{
X register int i;
X
X /* Check for degenerate case; there's nothing in the file. */
X if (bufempty())
X return FALSE;
X
X if (lineempty()) /* can't do anything */
X return FALSE;
X
X /* Delete the char. at Curschar by shifting everything */
X /* in the line down. */
X for ( i=Curschar->index+1; i < Curschar->linep->size ;i++)
X Curschar->linep->s[i-1] = Curschar->linep->s[i];
X
X /* If we just took off the last character of a non-blank line, */
X /* we don't want to end up positioned at the newline. */
X if (fixpos) {
X if (gchar(Curschar)==NUL && Curschar->index>0 && State!=INSERT)
X Curschar->index--;
X }
X CHANGED;
X
X return TRUE;
X}
X
X
Xvoid
Xdelline(nlines, can_update)
Xint nlines;
Xbool_t can_update;
X{
X register LINE *p, *q;
X int doscreen; /* if true, update the screen */
X
X doscreen = can_update;
X /*
X * There's no point in keeping the screen updated if we're
X * deleting more than a screen's worth of lines.
X */
X if (nlines > (Rows - 1) && can_update) {
X doscreen = FALSE;
X s_del(Cursrow, Rows-1); /* flaky way to clear rest of screen */
X }
X
X while ( nlines-- > 0 ) {
X
X if (bufempty()) /* nothing to delete */
X break;
X
X if (buf1line()) { /* just clear the line */
X Curschar->linep->s[0] = NUL;
X Curschar->index = 0;
X break;
X }
X
X p = Curschar->linep->prev;
X q = Curschar->linep->next;
X
X if (p == Filetop->linep) { /* first line of file so... */
X Filemem->linep = q; /* adjust start of file */
X Topchar->linep = q; /* and screen */
X }
X p->next = q;
X q->prev = p;
X
X clrmark(Curschar->linep); /* clear marks for the line */
X
X /*
X * Delete the correct number of physical lines on the screen
X */
X if (doscreen)
X s_del(Cursrow, plines(Curschar));
X
X /*
X * If deleting the top line on the screen, adjust Topchar
X */
X if (Topchar->linep == Curschar->linep)
X Topchar->linep = q;
X
X free(Curschar->linep->s);
X free((char *) Curschar->linep);
X
X Curschar->linep = q;
X Curschar->index = 0; /* is this right? */
X CHANGED;
X
X /* If we delete the last line in the file, back up */
X if ( Curschar->linep == Fileend->linep) {
X Curschar->linep = Curschar->linep->prev;
X /* and don't try to delete any more lines */
X break;
X }
X }
X}
HE_HATES_THESE_CANS
if test 9492 -ne "`wc -c < 'misccmds.c'`"
then
echo shar: error transmitting "'misccmds.c'" '(should have been 9492 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--
More information about the Comp.sources.misc
mailing list