From 294ccae3beaf78e01f5b268b9ebd8fd094f67879 Mon Sep 17 00:00:00 2001 From: Brian Callahan Date: Thu, 10 Jul 2014 18:11:43 -0400 Subject: [PATCH] emg 1.7 --- src/cmd/emg/ChangeLog | 7 ++ src/cmd/emg/Makefile | 6 +- src/cmd/emg/basic.c | 1 - src/cmd/emg/display.c | 2 +- src/cmd/emg/ebind.h | 10 --- src/cmd/emg/efunc.h | 7 -- src/cmd/emg/emg.keys | 23 +---- src/cmd/emg/estruct.h | 33 ++++++- src/cmd/emg/search.c | 180 +++----------------------------------- src/cmd/emg/tcap.c | 27 ------ src/cmd/emg/word.c | 198 +----------------------------------------- 11 files changed, 61 insertions(+), 433 deletions(-) diff --git a/src/cmd/emg/ChangeLog b/src/cmd/emg/ChangeLog index c5d10c8..8c09437 100644 --- a/src/cmd/emg/ChangeLog +++ b/src/cmd/emg/ChangeLog @@ -1,6 +1,13 @@ ChangeLog ========= +July 10, 2014 : emg 1.7 +----------------------- +Searching now correctly updates line number display. +Remove lots of rarely-used word functions. +Remove search+replace: sed(1) is quicker. +Reduce size of some static buffers. + May 29, 2014 : emg 1.6 ---------------------- emg is now part of the RetroBSD tree. diff --git a/src/cmd/emg/Makefile b/src/cmd/emg/Makefile index ff0b3cc..87b5495 100644 --- a/src/cmd/emg/Makefile +++ b/src/cmd/emg/Makefile @@ -10,15 +10,15 @@ CFLAGS = -Os -Wall -Werror # With the extra LDFLAGS, save some bytes. CFLAGS += -ffunction-sections -fdata-sections -# This reduces code size to 46K. +# This reduces code size significantly. CFLAGS += -mips16 # Set the screen size. # Will default to FORCE_COLS=80 and FORCE_ROWS=24 # if not set here. -CFLAGS += -DFORCE_COLS=80 -DFORCE_ROWS=24 +#CFLAGS += -DFORCE_COLS=80 -DFORCE_ROWS=24 -# with CFLAGS+= -ffunction-sections -fdatasections +# with CFLAGS+= -ffunction-sections -fdata-sections LDFLAGS += -Wl,--gc-sections LIBS = -ltermcap -lc diff --git a/src/cmd/emg/basic.c b/src/cmd/emg/basic.c index 75290ea..c3e86f7 100644 --- a/src/cmd/emg/basic.c +++ b/src/cmd/emg/basic.c @@ -13,7 +13,6 @@ #include "edef.h" extern int getccol(int bflg); -extern int inword(); extern void mlwrite(); extern int mlreplyt(); diff --git a/src/cmd/emg/display.c b/src/cmd/emg/display.c index ffc9979..adb36c9 100644 --- a/src/cmd/emg/display.c +++ b/src/cmd/emg/display.c @@ -647,7 +647,7 @@ void modeline(WINDOW *wp) n = 2; /* This is the version string. Do not forget to * increment when releasing a new version. */ - n += vtputs(" emg 1.6 "); + n += vtputs(" emg 1.7 "); vtputc(lchar); vtputc(lchar); diff --git a/src/cmd/emg/ebind.h b/src/cmd/emg/ebind.h index 35836dd..2356969 100644 --- a/src/cmd/emg/ebind.h +++ b/src/cmd/emg/ebind.h @@ -7,7 +7,6 @@ */ KEYTAB keytab[] = { - {CTRL | '@', setmark}, {CTRL | 'A', gotobol}, {CTRL | 'B', backchar}, {CTRL | 'D', forwdel}, @@ -50,25 +49,16 @@ KEYTAB keytab[] = { {CTLX | CTRL | 'R', fileread}, {CTLX | CTRL | 'S', filesave}, {CTLX | CTRL | 'W', filewrite}, - {META | ' ', setmark}, - {META | '%', qreplace}, {META | '.', setmark}, {META | '<', gotobob}, {META | '>', gotoeob}, {META | 'B', backword}, - {META | 'C', capword}, - {META | 'D', delfword}, {META | 'F', forwword}, {META | 'G', setline}, /* non-standard */ - {META | 'L', lowerword}, - {META | 'R', sreplace}, {META | 'S', forwsearch}, /* non-standard */ - {META | 'U', upperword}, {META | 'V', pageup}, {META | 'W', copyregion}, {META | 'Z', quickexit}, - {META | 0x7F, delbword}, - {META | CTRL | 'H', delbword}, {META | CTRL | 'N', namebuffer}, {0x7F, backdel}, {META | '[', extendedcmd}, diff --git a/src/cmd/emg/efunc.h b/src/cmd/emg/efunc.h index 00bf3ff..dd5ae85 100644 --- a/src/cmd/emg/efunc.h +++ b/src/cmd/emg/efunc.h @@ -31,8 +31,6 @@ extern int setfillcol(); /* Set fill column */ extern int setmark(); /* Set mark */ extern int forwsearch(); /* Search forward */ extern int backsearch(); /* Search backwards */ -extern int sreplace(); /* search and replace */ -extern int qreplace(); /* search and replace w/query */ extern int nextwind(); /* Move to the next window */ extern int prevwind(); /* Move to the previous window */ extern int onlywind(); /* Make current window only one */ @@ -54,11 +52,6 @@ extern int forwdel(); /* Forward delete */ extern int backdel(); /* Backward delete */ extern int killtext(); /* Kill forward */ extern int yank(); /* Yank back from killbuffer */ -extern int upperword(); /* Upper case word */ -extern int lowerword(); /* Lower case word */ -extern int capword(); /* Initial capitalize word */ -extern int delfword(); /* Delete forward word */ -extern int delbword(); /* Delete backward word */ extern int killregion(); /* Kill region */ extern int copyregion(); /* Copy region to kill buffer */ extern int quickexit(); /* low keystroke style exit */ diff --git a/src/cmd/emg/emg.keys b/src/cmd/emg/emg.keys index 9ab44fd..3f66e93 100644 --- a/src/cmd/emg/emg.keys +++ b/src/cmd/emg/emg.keys @@ -1,4 +1,4 @@ - emg keybindings (May 29, 2014) + emg keybindings (July 7, 2014) Based on Ersatz Emacs (2000/09/14) M- means to use the key prior to using another key @@ -26,12 +26,7 @@ M-G Go to line Arrow keys are active ------------------------------------------------------------------------------ FORMATTING & TRANSPOSING -M-U UPPERCASE word M-C Capitalize word -M-L lowercase word ^T Transpose characters ^Q Quote next key, so that control codes may be entered into text. (or ^X Q) -M-Q Format paragraph so that text is left-justified between margins. -^X F Set the right margin for paragraph formatting to the current position of - the cursor. ------------------------------------------------------------------------------ SEARCHING @@ -40,21 +35,10 @@ M-Q Format paragraph so that text is left-justified between margins. ENTER. Either case matches. (or M-S) ^R As above, but reverse search from cursor position. ------------------------------------------------------------------------------- - REPLACING - -M-R Replace all instances of first typed-in string with second typed-in - string. -M-% Replace with query. Answer with: - Y replace & continue N no replacement & continue - ! replace the rest ? Get a list of options - . exit and return to entry point - ^G,'q' or exit and remain at current location - ------------------------------------------------------------------------------ COPYING AND MOVING -^@ or M- Set mark at current position. +M-. Set mark at current position. ^W Delete region. M-W Copy region to kill buffer. ^Y Yank back kill buffer at cursor. @@ -64,7 +48,7 @@ position. The kill buffer is the text which has been most recently deleted or copied. Generally, the procedure for copying or moving text is: -1) Mark out region using M- at the beginning and move the cursor to +1) Mark out region using M-. at the beginning and move the cursor to the end. 2) Delete it (with ^W) or copy it (with M-W) into the kill buffer. 3) Move the cursor to the desired location and yank it back (with ^Y). @@ -113,7 +97,6 @@ M-^V Scroll other window down M-^Z Scroll other window up EXITING ^X^C Exit. Any unsaved files will require confirmation. -M-Z Write out all changed buffers automatically and exit. ------------------------------------------------------------------------------ MACROS diff --git a/src/cmd/emg/estruct.h b/src/cmd/emg/estruct.h index a5a84ef..9b2bf59 100644 --- a/src/cmd/emg/estruct.h +++ b/src/cmd/emg/estruct.h @@ -3,10 +3,10 @@ /* ESTRUCT: Structure and preprocessor */ /* internal constants */ -#define NFILEN 80 /* maximum # of bytes, file name */ +#define NFILEN 32 /* maximum # of bytes, file name */ #define NBUFN 16 /* maximum # of bytes, buffer name */ #define NLINE 512 /* maximum # of bytes, line */ -#define NKBDM 256 /* maximum # of strokes, keyboard macro */ +#define NKBDM 128 /* maximum # of strokes, keyboard macro */ #define NPAT 80 /* maximum # of bytes, pattern */ #define HUGE 32700 /* Huge number for "impossible" row&col */ @@ -31,6 +31,35 @@ #define CFCPCN 0x0001 /* Last command was C-P, C-N */ #define CFKILL 0x0002 /* Last command was a kill */ +/* + * screen constants + * override with + * CFLAGS += -DFORCE_COLS=XXX -DFORCE_ROWS=XXX + */ +#ifndef FORCE_COLS +#define FORCE_COLS 80 +#endif + +#ifndef FORCE_ROWS +#define FORCE_ROWS 24 +#endif + +/* + * XXX: + * Default/sane(?) maximum column and row sizes. + * Taken from mg1a. + * + * Let the user override these with + * CFLAGS += -DMAXCOL=XXX -DMAXROW=XXX + */ +#ifndef MAXCOL +#define MAXCOL 132 +#endif + +#ifndef MAXROW +#define MAXROW 66 +#endif + /* * There is a window structure allocated for every active display window. The * windows are kept in a big list, in top to bottom screen order, with the diff --git a/src/cmd/emg/search.c b/src/cmd/emg/search.c index 8eafae8..e9649a8 100644 --- a/src/cmd/emg/search.c +++ b/src/cmd/emg/search.c @@ -25,9 +25,6 @@ int backhunt(int f, int n); int bsearch(int f, int n); int eq(int bc, int pc); int readpattern(char *prompt); -int sreplace(int f, int n); -int qreplace(int f, int n); -int replaces(int kind, int f, int n); int forscan(char *patrn, int leavep); void expandp(char *srcstr, char *deststr, int maxlength); @@ -42,6 +39,7 @@ void expandp(char *srcstr, char *deststr, int maxlength); int forwsearch(int f, int n) { int status; + int curline = curwp->w_dotline; if (n == 0) /* resolve the repeat count */ n = 1; @@ -60,14 +58,17 @@ int forwsearch(int f, int n) } /* and complain if not there */ - if (status == FALSE) + if (status == FALSE) { mlwrite("Not found"); + curwp->w_dotline = curline; + } return (status); } int forwhunt(int f, int n) { int status = 0; + int curline = curwp->w_dotline; /* resolve the repeat count */ if (n == 0) @@ -89,8 +90,10 @@ int forwhunt(int f, int n) } /* and complain if not there */ - if (status == FALSE) + if (status == FALSE) { mlwrite("Not found"); + curwp->w_dotline = curline; + } return (status); } @@ -137,6 +140,7 @@ int bsearch(int f, int n) LINE *clp, *tlp; char *epp, *pp; int cbo, tbo, c; + int curline = curwp->w_dotline; /* find a pointer to the end of the pattern */ for (epp = &pat[0]; epp[1] != 0; ++epp) @@ -154,10 +158,12 @@ int bsearch(int f, int n) if (cbo == 0) { clp = lback(clp); + curwp->w_dotline--; if (clp == curbp->b_linep) { mlwrite("Not found"); + curwp->w_dotline = curline; return (FALSE); } cbo = llength(clp) + 1; @@ -182,6 +188,7 @@ int bsearch(int f, int n) if (tbo == 0) { tlp = lback(tlp); + curwp->w_dotline--; if (tlp == curbp->b_linep) goto fail; @@ -252,167 +259,6 @@ int readpattern(char *prompt) return (s); } -/* - * Search and replace (ESC-R) - */ -int sreplace(int f, int n) -{ - return (replaces(FALSE, f, n)); -} - -/* - * search and replace with query (ESC-CTRL-R) - */ -int qreplace(int f, int n) -{ - return (replaces(TRUE, f, n)); -} - -/* - * replaces: search for a string and replace it with another string. query - * might be enabled (according to kind) - */ -int replaces(int kind, int f, int n) -{ - LINE *origline; /* original "." position */ - char tmpc; /* temporary character */ - char c; /* input char for query */ - char tpat[NPAT]; /* temporary to hold search pattern */ - int i; /* loop index */ - int s; /* success flag on pattern inputs */ - int slength, rlength; /* length of search and replace strings */ - int numsub; /* number of substitutions */ - int nummatch; /* number of found matches */ - int nlflag; /* last char of search string a ? */ - int nlrepl; /* was a replace done on the last line? */ - int origoff; /* and offset (for . query option) */ - - /* check for negative repititions */ - if (f && n < 0) - return (FALSE); - - /* ask the user for the text of a pattern */ - if ((s = readpattern((kind == FALSE ? "Replace" : "Query replace"))) != TRUE) - return (s); - strncpy(&tpat[0], &pat[0], NPAT); /* salt it away */ - - /* ask for the replacement string */ - strncpy(&pat[0], &rpat[0], NPAT); /* set up default string */ - if ((s = readpattern("with")) == ABORT) - return (s); - - /* move everything to the right place and length them */ - strncpy(&rpat[0], &pat[0], NPAT); - strncpy(&pat[0], &tpat[0], NPAT); - slength = strlen(&pat[0]); - rlength = strlen(&rpat[0]); - - /* set up flags so we can make sure not to do a recursive replace on the - * last line */ - nlflag = (pat[slength - 1] == '\n'); - nlrepl = FALSE; - - /* build query replace question string */ - strncpy(tpat, "Replace '", 10); - expandp(&pat[0], &tpat[strlen (tpat)], NPAT / 3); - strncat(tpat, "' with '", 9); - - expandp(&rpat[0], &tpat[strlen (tpat)], NPAT / 3); - strncat(tpat, "'? ", 4); - - /* save original . position */ - origline = curwp->w_dotp; - origoff = curwp->w_doto; - - /* scan through the file */ - numsub = 0; - nummatch = 0; - while ((f == FALSE || n > nummatch) && - (nlflag == FALSE || nlrepl == FALSE)) - { - /* search for the pattern */ - if (forscan(&pat[0], PTBEG) != TRUE) - break; /* all done */ - ++nummatch; /* increment # of matches */ - - /* check if we are on the last line */ - nlrepl = (lforw (curwp->w_dotp) == curwp->w_bufp->b_linep); - - /* check for query */ - if (kind) - { - /* get the query */ - mlwrite(&tpat[0], &pat[0], &rpat[0]); - qprompt: - update(); /* show the proposed place to change */ - c = (*term.t_getchar) (); /* and input */ - mlwrite(""); /* and clear it */ - - /* and respond appropriately */ - switch (c) - { - case 'y': /* yes, substitute */ - case ' ': - break; - - case 'n': /* no, onword */ - forwchar(FALSE, 1); - continue; - - case '!': /* yes/stop asking */ - kind = FALSE; - break; - - case '.': /* abort! and return */ - /* restore old position */ - curwp->w_dotp = origline; - curwp->w_doto = origoff; - curwp->w_flag |= WFMOVE; - - case BELL: /* abort! and stay */ - mlwrite("Aborted!"); - return (FALSE); - - case 0x0d: /* controlled exit */ - case 'q': - return (TRUE); - - default: /* bitch and beep */ - (*term.t_beep) (); - - case '?': /* help me */ - mlwrite("(Y)es, (N)o, (!)Do the rest, (^G,RET,q)Abort, (.)Abort back, (?)Help: "); - goto qprompt; - } - } - /* delete the sucker */ - if (ldelete(slength, FALSE) != TRUE) - { - /* error while deleting */ - mlwrite("ERROR while deleting"); - return (FALSE); - } - /* and insert its replacement */ - for (i = 0; i < rlength; i++) - { - tmpc = rpat[i]; - s = (tmpc == '\n' ? lnewline() : linsert(1, tmpc)); - if (s != TRUE) - { - /* error while inserting */ - mlwrite("Out of memory while inserting"); - return (FALSE); - } - } - - numsub++; /* increment # of substitutions */ - } - - /* and report the results */ - mlwrite("%d substitutions", numsub); - return (TRUE); -} - /* search forward for a */ int forscan(char *patrn, int leavep) @@ -441,6 +287,7 @@ int forscan(char *patrn, int leavep) if (curoff == llength(curline)) { /* if at EOL */ curline = lforw(curline); /* skip to next line */ + curwp->w_dotline++; curoff = 0; c = '\n'; /* and return a */ } @@ -463,6 +310,7 @@ int forscan(char *patrn, int leavep) { /* advance past EOL */ matchline = lforw(matchline); + curwp->w_dotline++; matchoff = 0; c = '\n'; } diff --git a/src/cmd/emg/tcap.c b/src/cmd/emg/tcap.c index 3bf4ef6..522833d 100644 --- a/src/cmd/emg/tcap.c +++ b/src/cmd/emg/tcap.c @@ -4,33 +4,6 @@ #define termdef 1 /* don't define "term" externally */ -/* Did you remember to set FORCE_COLS? */ -#ifndef FORCE_COLS -#define FORCE_COLS 80 -#endif - -/* Did you remember to set FORCE_ROWS? */ -#ifndef FORCE_ROWS -#define FORCE_ROWS 24 -#endif - -/* - * XXX: - * Default/sane(?) maximum column and row sizes. - * Taken from mg1a. - * - * Let the user override this with a - * CFLAGS += -DMAXCOL=XXX -DMAXROW=XXX - * line in the Makefile. - */ -#ifndef MAXCOL -#define MAXCOL 132 -#endif - -#ifndef MAXROW -#define MAXROW 66 -#endif - #include /* puts(3), snprintf(3) */ #include "estruct.h" #include "edef.h" diff --git a/src/cmd/emg/word.c b/src/cmd/emg/word.c index abdc058..4943920 100644 --- a/src/cmd/emg/word.c +++ b/src/cmd/emg/word.c @@ -11,20 +11,10 @@ extern int backchar(int f, int n); extern int forwchar(int f, int n); -extern void lchange(int flag); -extern int ldelete(int n, int kflag); -extern void mlwrite(); -extern int linsert(int n, int c); -extern int lnewline(); int backword(int f, int n); int forwword(int f, int n); -int upperword(int f, int n); -int lowerword(int f, int n); -int capword(int f, int n); -int delfword(int f, int n); -int delbword(int f, int n); -int inword(); +int inword(void); /* * Move the cursor backward by "n" words. All of the details of motion are @@ -77,195 +67,11 @@ int forwword(int f, int n) return (TRUE); } -/* - * Move the cursor forward by the specified number of words. As you move, - * convert any characters to upper case. Error if you try and move beyond the - * end of the buffer. Bound to "M-U" - */ -int upperword(int f, int n) -{ - int c; - - if (n < 0) - return (FALSE); - while (n--) - { - while (inword() == FALSE) - { - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - } - while (inword() != FALSE) - { - c = lgetc(curwp->w_dotp, curwp->w_doto); - if (c >= 'a' && c <= 'z') - { - c -= 'a' - 'A'; - lputc(curwp->w_dotp, curwp->w_doto, c); - lchange(WFHARD); - } - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - } - } - return (TRUE); -} - -/* - * Move the cursor forward by the specified number of words. As you move - * convert characters to lower case. Error if you try and move over the end of - * the buffer. Bound to "M-L" - */ -int lowerword(int f, int n) -{ - int c; - - if (n < 0) - return (FALSE); - while (n--) - { - while (inword() == FALSE) - { - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - } - while (inword() != FALSE) - { - c = lgetc(curwp->w_dotp, curwp->w_doto); - if (c >= 'A' && c <= 'Z') - { - c += 'a' - 'A'; - lputc(curwp->w_dotp, curwp->w_doto, c); - lchange(WFHARD); - } - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - } - } - return (TRUE); -} - -/* - * Move the cursor forward by the specified number of words. As you move - * convert the first character of the word to upper case, and subsequent - * characters to lower case. Error if you try and move past the end of the - * buffer. Bound to "M-C" - */ -int capword(int f, int n) -{ - int c; - - if (n < 0) - return(FALSE); - while (n--) - { - while (inword() == FALSE) - { - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - } - if (inword() != FALSE) - { - c = lgetc(curwp->w_dotp, curwp->w_doto); - if (c >= 'a' && c <= 'z') - { - c -= 'a' - 'A'; - lputc(curwp->w_dotp, curwp->w_doto, c); - lchange(WFHARD); - } - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - while (inword() != FALSE) - { - c = lgetc(curwp->w_dotp, curwp->w_doto); - if (c >= 'A' && c <= 'Z') - { - c += 'a' - 'A'; - lputc(curwp->w_dotp, curwp->w_doto, c); - lchange(WFHARD); - } - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - } - } - } - return (TRUE); -} - -/* - * Kill forward by "n" words. Remember the location of dot. Move forward by - * the right number of words. Put dot back where it was and issue the kill - * command for the right number of characters. Bound to "M-D" - */ -int delfword(int f, int n) -{ - LINE *dotp; - int size, doto; - - if (n < 0) - return (FALSE); - dotp = curwp->w_dotp; - doto = curwp->w_doto; - size = 0; - while (n--) - { - while (inword() != FALSE) - { - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - ++size; - } - while (inword() == FALSE) - { - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - ++size; - } - } - curwp->w_dotp = dotp; - curwp->w_doto = doto; - return (ldelete(size, TRUE)); -} - -/* - * Kill backwards by "n" words. Move backwards by the desired number of words, - * counting the characters. When dot is finally moved to its resting place, - * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace" - */ -int delbword(int f, int n) -{ - int size; - - if (n < 0) - return (FALSE); - if (backchar(FALSE, 1) == FALSE) - return (FALSE); - size = 0; - while (n--) - { - while (inword() == FALSE) - { - if (backchar(FALSE, 1) == FALSE) - return (FALSE); - ++size; - } - while (inword() != FALSE) - { - if (backchar(FALSE, 1) == FALSE) - return (FALSE); - ++size; - } - } - if (forwchar(FALSE, 1) == FALSE) - return (FALSE); - return (ldelete(size, TRUE)); -} - /* * Return TRUE if the character at dot is a character that is considered to be * part of a word. The word character list is hard coded. Should be setable */ -int inword() +int inword(void) { int c;