diff options
author | Tim Vanderhoek <hoek@FreeBSD.org> | 1999-05-30 18:06:58 +0000 |
---|---|---|
committer | Tim Vanderhoek <hoek@FreeBSD.org> | 1999-05-30 18:06:58 +0000 |
commit | 0ac2ad320e516cdf6a752ea0a7c8a2fcf65a0c8e (patch) | |
tree | bbc8ac6fdaaf0c4ac68baa9235984cbb858ea9b7 /usr.bin/more | |
parent | 4e2f199e0c9ada1b226f685a848abb1420a1ff8f (diff) | |
download | src-test2-0ac2ad320e516cdf6a752ea0a7c8a2fcf65a0c8e.tar.gz src-test2-0ac2ad320e516cdf6a752ea0a7c8a2fcf65a0c8e.zip |
Notes
Diffstat (limited to 'usr.bin/more')
-rw-r--r-- | usr.bin/more/command.c | 56 | ||||
-rw-r--r-- | usr.bin/more/decode.c | 24 | ||||
-rw-r--r-- | usr.bin/more/input.c | 51 | ||||
-rw-r--r-- | usr.bin/more/less.h | 9 | ||||
-rw-r--r-- | usr.bin/more/line.c | 41 | ||||
-rw-r--r-- | usr.bin/more/main.c | 29 | ||||
-rw-r--r-- | usr.bin/more/output.c | 128 | ||||
-rw-r--r-- | usr.bin/more/position.c | 7 | ||||
-rw-r--r-- | usr.bin/more/prim.c | 85 |
9 files changed, 339 insertions, 91 deletions
diff --git a/usr.bin/more/command.c b/usr.bin/more/command.c index a8785d22312a..62ed6e8934b7 100644 --- a/usr.bin/more/command.c +++ b/usr.bin/more/command.c @@ -36,11 +36,18 @@ static char sccsid[] = "@(#)command.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include <sys/param.h> -#include <stdio.h> + #include <ctype.h> +#include <stdio.h> #include <string.h> -#include <less.h> + +#include "less.h" #include "pathnames.h" #define NO_MCA 0 @@ -55,10 +62,10 @@ extern int hit_eof; extern int sc_width; extern int sc_height; extern int sc_window; +extern int horiz_off; extern int curr_ac; extern int ac; extern char **av; -extern int quitting; extern int scroll; extern int screen_trashed; /* The screen has been overwritten */ @@ -182,6 +189,13 @@ prompt() lower_left(); clear_eol(); if (longprompt) { + /* + * Get the current line/pos from the BOTTOM of the screen + * even though that's potentially confusing for the user + * when switching between NO_HORIZ_OFF and a valid horiz_off. + * In exchange, it is sometimes easier for the user to tell + * when a file is relatively short vs. long. + */ so_enter(); putstr(current_name); putstr(":"); @@ -348,6 +362,8 @@ commands() { register int c; register int action; + static int default_hscroll = 1; + static int saved_horiz_off = NO_HORIZ_OFF; last_mca = 0; scroll = (sc_height + 1) / 2; @@ -359,11 +375,9 @@ commands() /* * See if any signals need processing. */ - if (sigs) { + if (sigs) psignals(); - if (quitting) - quit(); - } + /* * Display prompt and accept a character. */ @@ -430,6 +444,34 @@ again: if (sigs) CMD_EXEC; backward(number <= 0 ? 1 : number, 0); break; + case A_R_COL: /* to the right N (default 1) cols */ + /* XXX Should beep here rather than silently truncating + * lines in line.c when we are about to exceed the + * line buffer. */ + if (number > 0) + default_hscroll = number; + horiz_off += default_hscroll; + repaint(); + break; + case A_L_COL: /* to the left N (default 1) cols */ + if (number > 0) + default_hscroll = number; + if (horiz_off != 0 && horiz_off != NO_HORIZ_OFF) { + horiz_off -= default_hscroll; + if (horiz_off < 0) + horiz_off = 0; + } else + horiz_off = NO_HORIZ_OFF; + repaint(); + break; + case A_HOME: + if (horiz_off != NO_HORIZ_OFF) { + saved_horiz_off = horiz_off; + horiz_off = NO_HORIZ_OFF; + } else + horiz_off = saved_horiz_off; + repaint(); + break; case A_F_SCROLL: /* forward N lines */ CMD_EXEC; if (number > 0) diff --git a/usr.bin/more/decode.c b/usr.bin/more/decode.c index 83fa624396b5..8edcdcf3cd4d 100644 --- a/usr.bin/more/decode.c +++ b/usr.bin/more/decode.c @@ -36,6 +36,11 @@ static char sccsid[] = "@(#)decode.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + /* * Routines to decode user commands. * @@ -52,10 +57,12 @@ static char sccsid[] = "@(#)decode.c 8.1 (Berkeley) 6/6/93"; * The default commands are described by cmdtable. */ -#include <sys/param.h> #include <sys/file.h> +#include <sys/param.h> + #include <stdio.h> -#include <less.h> + +#include "less.h" /* * Command table is ordered roughly according to expected @@ -63,7 +70,16 @@ static char sccsid[] = "@(#)decode.c 8.1 (Berkeley) 6/6/93"; */ #define CONTROL(c) ((c)&037) +/* + * Ideally the home and end keys would reset the horiz_scroll, too, + * but this whole thing needs to be made dynamic along with some type + * of macro commands. + */ static char cmdtable[] = { + '\e','[','B',0, A_F_LINE, + '\e','[','A',0, A_B_LINE, + '\e','[','C',0, A_R_COL, + '\e','[','D',0, A_L_COL, '\r',0, A_F_LINE, '\n',0, A_F_LINE, 'j',0, A_F_LINE, @@ -75,15 +91,19 @@ static char cmdtable[] = { ' ',0, A_F_SCREEN, 'f',0, A_F_SCREEN, CONTROL('F'),0, A_F_SCREEN, + '\e','[','G',0, A_F_SCREEN, 'b',0, A_B_SCREEN, CONTROL('B'),0, A_B_SCREEN, + '\e','[','I',0, A_B_SCREEN, 'R',0, A_FREPAINT, 'r',0, A_REPAINT, CONTROL('L'),0, A_REPAINT, 'g',0, A_GOLINE, + '\e','[','H',0, A_HOME, 'p',0, A_PERCENT, '%',0, A_PERCENT, 'G',0, A_GOEND, + '\e','[','F',0, A_GOEND, '0',0, A_DIGIT, '1',0, A_DIGIT, '2',0, A_DIGIT, diff --git a/usr.bin/more/input.c b/usr.bin/more/input.c index bdf65bb4925b..b22c3d9fd2a3 100644 --- a/usr.bin/more/input.c +++ b/usr.bin/more/input.c @@ -36,6 +36,11 @@ static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + /* * High level routines dealing with getting lines of input * from the file being viewed. @@ -47,7 +52,10 @@ static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/6/93"; */ #include <sys/types.h> -#include <less.h> + +#include "less.h" + +int horiz_off = NO_HORIZ_OFF; /* # characters scrolled off left of screen */ extern int squeeze; extern int sigs; @@ -56,11 +64,13 @@ extern char *line; off_t ch_tell(); /* - * Get the next line. + * Get the next printable line. + * * A "current" position is passed and a "new" position is returned. * The current position is the position of the first character of * a line. The new position is the position of the first character * of the NEXT line. The line obtained is the line starting at curr_pos. + * It is placed into the global line buffer ("line"). */ off_t forw_line(curr_pos) @@ -92,6 +102,10 @@ forw_line(curr_pos) /* * Append the char to the line and get the next char. + * The pappend() will throw away any unimportant chars + * (ie. not underlines or bolds) as per horiz_off. + * + * XXX line.c needs to be rewritten... */ if (pappend(c)) { @@ -100,7 +114,15 @@ forw_line(curr_pos) * is too long to print in the screen width. * End the line here. */ - new_pos = ch_tell() - 1; + if (horiz_off != NO_HORIZ_OFF) { + /* Throw away left-over characters on line */ + c = ch_forw_get(); + while (c != '\n' && c != EOI) + c = ch_forw_get(); + new_pos = ch_tell(); + } else { + new_pos = ch_tell() - 1; + } break; } c = ch_forw_get(); @@ -127,10 +149,12 @@ forw_line(curr_pos) /* * Get the previous line. + * * A "current" position is passed and a "new" position is returned. * The current position is the position of the first character of * a line. The new position is the position of the first character * of the PREVIOUS line. The line obtained is the one starting at new_pos. + * It is placed into the global line buffer ("line"). */ off_t back_line(curr_pos) @@ -223,15 +247,18 @@ back_line(curr_pos) break; if (pappend(c)) { - /* - * Got a full printable line, but we haven't - * reached our curr_pos yet. Discard the line - * and start a new one. - */ - (void) pappend('\0'); - (void) ch_back_get(); - new_pos--; - goto loop; + if (horiz_off == NO_HORIZ_OFF) { + /* + * Got a full printable line, but we haven't + * reached our curr_pos yet. Discard the line + * and start a new one. + */ + (void) pappend('\0'); + (void) ch_back_get(); + new_pos--; + goto loop; + } else + break; /* Got everything we need */ } } while (new_pos < curr_pos); diff --git a/usr.bin/more/less.h b/usr.bin/more/less.h index c4dd23f338df..805bee0cd026 100644 --- a/usr.bin/more/less.h +++ b/usr.bin/more/less.h @@ -32,15 +32,17 @@ * SUCH DAMAGE. * * @(#)less.h 8.1 (Berkeley) 6/6/93 + * + * $Id$ */ -#define RECOMP - #define NULL_POSITION ((off_t)(-1)) #define EOI (0) #define READ_INTR (-2) +#define NO_HORIZ_OFF (-1) /* Wrap lines like normal */ + /* Special chars used to tell put_line() to do something special */ #define UL_CHAR '\201' /* Enter underline mode */ #define UE_CHAR '\202' /* Exit underline mode */ @@ -85,3 +87,6 @@ #define A_VISUAL 25 #define A_TAGFILE 26 #define A_FILE_LIST 27 +#define A_L_COL 28 +#define A_R_COL 29 +#define A_HOME 30 diff --git a/usr.bin/more/line.c b/usr.bin/more/line.c index 0f2b6c64306d..88178bb76a2b 100644 --- a/usr.bin/more/line.c +++ b/usr.bin/more/line.c @@ -36,6 +36,11 @@ static char sccsid[] = "@(#)line.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + /* * Routines to manipulate the "line buffer". * The line buffer holds a line of output as it is being built @@ -44,10 +49,12 @@ static char sccsid[] = "@(#)line.c 8.1 (Berkeley) 6/6/93"; */ #include <sys/types.h> + #include <ctype.h> -#include <less.h> -static char linebuf[1024]; /* Buffer which holds the current output line */ +#include "less.h" + +static char linebuf[8192]; /* Buffer to hold the current output line */ static char *curr; /* Pointer into linebuf */ static int column; /* Printable length, accounting for backspaces, etc. */ @@ -78,8 +85,8 @@ static int column; /* Printable length, accounting for * we expect one more 'X' which will put us back * in LN_BOLDFACE). */ -static int ln_state; /* Currently in normal/underline/bold/etc mode? */ -#define LN_NORMAL 0 /* Not in underline, boldface or whatever mode */ +static int ln_state; /* Current normal/underline/bold/etc mode */ +#define LN_NORMAL 0 /* Not in underline/boldface/whatever mode */ #define LN_UNDERLINE 1 /* In underline, need next char */ #define LN_UL_X 2 /* In underline, got char, need \b */ #define LN_UL_XB 3 /* In underline, got char & \b, need one more */ @@ -95,6 +102,7 @@ extern int tabstop; extern int bo_width, be_width; extern int ul_width, ue_width; extern int sc_width, sc_height; +extern int horiz_off; /* * Rewind the line buffer. @@ -103,13 +111,16 @@ prewind() { line = curr = linebuf; ln_state = LN_NORMAL; - column = 0; + column = (horiz_off == NO_HORIZ_OFF) ? 0 : -horiz_off; } /* * Append a character to the line buffer. * Expand tabs into spaces, handle underlining, boldfacing, etc. - * Returns 0 if ok, 1 if couldn't fit in buffer. + * Returns 0 if ok, 1 if couldn't fit in buffer. Characters before horiz_off + * will be added to the buffer but will not count against the line size. + * + * XXX This function sucks. */ #define NEW_COLUMN(addon) \ if (column + addon + (ln_state ? ue_width : 0) > sc_width) \ @@ -156,7 +167,7 @@ pappend(c) * Don't take any chances. * {{ Linebuf is supposed to be big enough that this * will never happen, but may need to be made - * bigger for wide screens or lots of backspaces. }} + * bigger for really long lines. }} */ return(1); @@ -368,9 +379,14 @@ ln_bo_xb_case: /* * Expand a tab into spaces. */ - do { - NEW_COLUMN(1); - } while ((column % tabstop) != 0); + if (horiz_off != NO_HORIZ_OFF) + do { + NEW_COLUMN(1); + } while (((column + horiz_off) % tabstop) != 0); + else + do { + NEW_COLUMN(1); + } while ((column % tabstop) != 0); *curr++ = '\t'; return (0); } @@ -438,7 +454,10 @@ forw_raw_line(curr_pos) * Overflowed the input buffer. * Pretend the line ended here. * {{ The line buffer is supposed to be big - * enough that this never happens. }} + * enough that this never happens, but it's + * statically allocated, so that's really just + * a pipe dream. This causes no end of trouble. + * The line.c needs to be rewritten. }} */ new_pos = ch_tell() - 1; break; diff --git a/usr.bin/more/main.c b/usr.bin/more/main.c index 6df972849b5b..8441653b904a 100644 --- a/usr.bin/more/main.c +++ b/usr.bin/more/main.c @@ -43,30 +43,34 @@ char copyright[] = static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/7/93"; #endif /* not lint */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + /* * Entry point, initialization, miscellaneous routines. */ -#include <sys/types.h> -#include <sys/param.h> #include <sys/file.h> +#include <sys/param.h> +#include <sys/types.h> + +#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <locale.h> +#include <unistd.h> + #include "less.h" int ispipe; -int new_file; -int is_tty; char *current_file, *previous_file, *current_name, *next_name; -off_t prev_pos; int any_display; int scroll; int ac; char **av; int curr_ac; -int quitting; extern int file; extern int cbufs; @@ -86,7 +90,7 @@ edit(filename) extern int errno; register int f; register char *m; - off_t initial_pos, position(); + off_t initial_pos, prev_pos, position(); static int didpipe; char message[MAXPATHLEN + 50], *p; char *rindex(), *strerror(), *save(), *bad_file(); @@ -112,7 +116,7 @@ edit(filename) /* use standard input. */ if (!strcmp(filename, "-")) { if (didpipe) { - error("Can view standard input only once"); + error("can view standard input only once"); return(0); } f = 0; @@ -150,7 +154,6 @@ edit(filename) */ if (file > 0) (void)close(file); - new_file = 1; if (previous_file != NULL) free(previous_file); previous_file = current_file; @@ -171,7 +174,7 @@ edit(filename) ch_init(cbufs, 0); init_mark(); - if (is_tty) { + if (isatty(STDOUT_FILENO)) { int no_display = !any_display; any_display = 1; if (no_display && errmsgs > 0) { @@ -283,8 +286,7 @@ main(argc, argv) /* * Set up terminal, etc. */ - is_tty = isatty(1); - if (!is_tty) { + if (!isatty(STDOUT_FILENO)) { /* * Output is not a tty. * Just copy the input file(s) to output. @@ -365,7 +367,6 @@ quit() * Put cursor at bottom left corner, clear the line, * reset the terminal modes, and exit. */ - quitting = 1; lower_left(); clear_eol(); deinit(); diff --git a/usr.bin/more/output.c b/usr.bin/more/output.c index 80884c90f2a1..ab8367d02a86 100644 --- a/usr.bin/more/output.c +++ b/usr.bin/more/output.c @@ -36,6 +36,11 @@ static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + /* * High level routines dealing with the output to the screen. */ @@ -43,6 +48,7 @@ static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/6/93"; #include <ctype.h> #include <stdio.h> #include <string.h> + #include "less.h" int errmsgs; /* Count of messages displayed by error() */ @@ -57,16 +63,77 @@ extern int tabstop; extern int screen_trashed; extern int any_display; extern char *line; +extern int horiz_off; extern int mode_flags; + static int last_pos_highlighted = 0; -/* display the line which is in the line buffer. */ +/* static markup() + * + * Output correct markup char; return number of columns eaten-up. + * Called by put_line() just before doing any actual output. + */ +#define ENTER 1 +#define ACQUIESCE 0 /* XXX Check actual def'n... */ +#define EXIT -1 + +static +markup(ent_ul, ent_bo) + int *ent_ul, *ent_bo; +{ + int retr; + + retr = 0; + switch (*ent_ul) { + case ENTER: + ul_enter(); + retr += ul_width; + break; + case EXIT: + ul_exit(); + retr += ue_width; + break; + } + switch (*ent_bo) { + case ENTER: + bo_enter(); + retr += bo_width; + break; + case EXIT: + bo_exit(); + retr += be_width; + break; + } + *ent_ul = *ent_bo = ACQUIESCE; + return retr; +} + +/* put_line() + * + * Display the line which is in the line buffer. The number of output + * characters in the line buffer cannot exceed screen columns available. + * Output characters in the line buffer that precede horiz_off are skipped. + * The caller may depend on this behaviour to ensure that the number of output + * characters in the line buffer does not exceed the screen columns + * available. + * + * This routine will get confused if the line buffer has non-sensical + * UL_CHAR, UE_CHAR, BO_CHAR, BE_CHAR markups. + */ +#define MAYPUTCHR(char) \ + if (column >= eff_horiz_off) { \ + column += markup(&ent_ul, &ent_bo); \ + putchr(char); \ + } + put_line() { register char *p; register int c; register int column; extern int auto_wrap, ignaw; + int ent_ul, ent_bo; /* enter or exit ul|bo mode for next char */ + int eff_horiz_off; if (sigs) { @@ -77,6 +144,11 @@ put_line() return; } + if (horiz_off == NO_HORIZ_OFF) + eff_horiz_off = 0; + else + eff_horiz_off = horiz_off; + if (line == NULL) line = ""; @@ -86,34 +158,46 @@ put_line() last_pos_highlighted = 0; } column = 0; + ent_ul = ent_bo = ACQUIESCE; for (p = line; *p != '\0'; p++) { + /* + * XXX line.c needs to be rewritten to store markup + * information as metadata associated with each character. + * This will make several things much nicer, fixing problems, + * etc. Until then, this kludge will hold the fort well + * enough. + */ switch ((char)(c = (unsigned char)*p)) { case UL_CHAR: - ul_enter(); - column += ul_width; + ent_ul = ENTER; break; case UE_CHAR: - ul_exit(); - column += ue_width; + if (ent_ul != ENTER) + ent_ul = EXIT; + else + ent_ul = ACQUIESCE; break; case BO_CHAR: - bo_enter(); - column += bo_width; + ent_bo = ENTER; break; case BE_CHAR: - bo_exit(); - column += be_width; + if (ent_bo != ENTER) + ent_bo = EXIT; + else + ent_bo = ACQUIESCE; break; case '\t': do { - putchr(' '); + MAYPUTCHR(' '); column++; } while ((column % tabstop) != 0); break; case '\b': + /* markup() before putbs() ? */ + column += markup(&ent_ul, &ent_bo); putbs(); column--; break; @@ -123,32 +207,35 @@ put_line() { /* -u was set, or this CR is not a CRLF, so * treat this CR like any other control_char */ - putchr('^');; - putchr(CARAT_CHAR(c)); - column += 2; + MAYPUTCHR('^'); + column++; + MAYPUTCHR(CARAT_CHAR(c)); + column++; } break; default: if (c == 0200 || CONTROL_CHAR(c)) { c &= ~0200; - putchr('^'); - putchr(CARAT_CHAR(c)); - column += 2; + MAYPUTCHR('^'); + column++; + MAYPUTCHR(CARAT_CHAR(c)); + column++; } else { - putchr(c); + MAYPUTCHR(c); column++; } } - if (column == sc_width && mode_flags) + if (column == sc_width + eff_horiz_off && mode_flags) last_pos_highlighted = 1; } - if (column < sc_width || !auto_wrap || ignaw) + column += markup(&ent_ul, &ent_bo); + if (column < sc_width + eff_horiz_off || !auto_wrap || ignaw) putchr('\n'); } -static char obuf[1024]; +static char obuf[2048]; /* just large enough for a full 25*80 screen */ static char *ob = obuf; /* @@ -239,6 +326,7 @@ error(s) so_exit(); if ((ch = getchr()) != '\n') { + /* XXX hardcoded */ if (ch == 'q') quit(); cmdstack = ch; diff --git a/usr.bin/more/position.c b/usr.bin/more/position.c index 57ffb32985be..d9d818302192 100644 --- a/usr.bin/more/position.c +++ b/usr.bin/more/position.c @@ -113,6 +113,10 @@ add_back_pos(pos) table[0] = pos; } +/* + * Remove any NULL_POSITION markers from the top of the table, moving + * the bottom part up, if necessary. + */ copytable() { register int a, b; @@ -148,6 +152,9 @@ pos_clear() * See if the byte at a specified position is currently on the screen. * Check the position table to see if the position falls within its range. * Return the position table entry if found, -1 if not. + * + * This function doesn't really work when horizontal scrolling is enabled. + * I suspect it may not work in a few other cases, too. */ onscreen(pos) off_t pos; diff --git a/usr.bin/more/prim.c b/usr.bin/more/prim.c index 1a571e657044..bb815672e51f 100644 --- a/usr.bin/more/prim.c +++ b/usr.bin/more/prim.c @@ -36,19 +36,26 @@ static char sccsid[] = "@(#)prim.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + /* * Primitives for displaying the file on the screen. */ #include <sys/types.h> -#include <stdio.h> + #include <ctype.h> -#include <regex.h> #include <limits.h> -#include <less.h> +#include <regex.h> +#include <stdio.h> + +#include "less.h" int back_scroll = -1; -int hit_eof; /* keeps track of how many times we hit end of file */ +int hit_eof; /* true if we're displaying the end of the input */ int screen_trashed; static int squished; @@ -56,6 +63,7 @@ static int squished; extern int sigs; extern int top_scroll; extern int sc_width, sc_height; +extern int horiz_off; extern int caseless; extern int linenums; extern int tagoption; @@ -68,6 +76,7 @@ off_t ch_length(), ch_tell(); /* * Check to see if the end of file is currently "displayed". */ +static eof_check() { off_t pos; @@ -90,6 +99,7 @@ eof_check() * of the screen; this can happen when we display a short file * for the first time. */ +static squish_check() { if (squished) { @@ -103,6 +113,7 @@ squish_check() * input file. "only_last" means display only the last screenful if * n > screen size. */ +static forw(n, pos, only_last) register int n; off_t pos; @@ -204,6 +215,7 @@ forw(n, pos, only_last) /* * Display n lines, scrolling backward. */ +static back(n, pos, only_last) register int n; off_t pos; @@ -494,7 +506,10 @@ jump_loc(pos) */ #define NMARKS (27) /* 26 for a-z plus one for quote */ #define LASTMARK (NMARKS-1) /* For quote */ -static off_t marks[NMARKS]; +static struct mark { + int horiz_off; + off_t pos; +} marks[NMARKS]; /* * Initialize the mark table to show no marks are set. @@ -504,13 +519,13 @@ init_mark() int i; for (i = 0; i < NMARKS; i++) - marks[i] = NULL_POSITION; + marks[i].pos = NULL_POSITION; } /* * See if a mark letter is valid (between a and z). */ - static int +static int badmark(c) int c; { @@ -530,12 +545,14 @@ setmark(c) { if (badmark(c)) return; - marks[c-'a'] = position(TOP); + marks[c-'a'].pos = position(TOP); + marks[c-'a'].horiz_off = horiz_off; } lastmark() { - marks[LASTMARK] = position(TOP); + marks[LASTMARK].pos = position(TOP); + marks[LASTMARK].horiz_off = horiz_off; } /* @@ -545,22 +562,48 @@ gomark(c) int c; { off_t pos; + int new_horiz_off; if (c == '\'') { - pos = marks[LASTMARK]; + pos = marks[LASTMARK].pos; if (pos == NULL_POSITION) pos = 0; + new_horiz_off = marks[LASTMARK].horiz_off; } else { if (badmark(c)) return; - pos = marks[c-'a']; + pos = marks[c-'a'].pos; if (pos == NULL_POSITION) { error("mark not set"); return; } + new_horiz_off = marks[c-'a'].horiz_off; + } + + /* Try to be nice about changing the horizontal scroll */ + if (!(horiz_off == NO_HORIZ_OFF && new_horiz_off <= sc_width)) { + /* + * We're going to have to change the horiz_off, even if + * it's currently set to NO_HORIZ_OFF: if we don't change + * horiz_off the bookmarked location won't show on the screen. + */ + if (horiz_off != new_horiz_off) { + /* We'll need to repaint(), too... */ + horiz_off = new_horiz_off; + prepaint(pos); + } else { + /* No need to repaint. */ + jump_loc(pos); + } + } else { + /* + * The user doesn't want horizontal scrolling, and we can + * fortunately honour the bookmark request without doing + * any horizontal scrolling. + */ + jump_loc(pos); } - jump_loc(pos); } /* @@ -611,16 +654,21 @@ search(search_forward, pattern, n, wantmatch) error(errbuf); oncethru = 0; regfree(&rx); - return 0; + return (0); } oncethru = 1; } else if (!oncethru) { error("No previous regular expression"); - return 0; + return (0); } /* * Figure out where to start the search. + * + * XXX This should probably be adapted to handle horizontal + * scrolling. Consider a long line at the top of the screen + * that might be hiding more matches to its right (when doing + * successive searches). */ if (position(TOP) == NULL_POSITION) { @@ -706,14 +754,6 @@ search(search_forward, pattern, n, wantmatch) add_lnum(linenum, pos); /* - * If this is a caseless search, convert uppercase in the - * input line to lowercase. - */ - if (caseless) - for (p = q = line; *p; p++, q++) - *q = isupper(*p) ? tolower(*p) : *p; - - /* * Remove any backspaces along with the preceeding char. * This allows us to match text which is underlined or * overstruck. @@ -746,4 +786,3 @@ search(search_forward, pattern, n, wantmatch) jump_loc(linepos); return(1); } - |