summaryrefslogtreecommitdiff
path: root/usr.bin/more
diff options
context:
space:
mode:
authorTim Vanderhoek <hoek@FreeBSD.org>1999-05-30 18:06:58 +0000
committerTim Vanderhoek <hoek@FreeBSD.org>1999-05-30 18:06:58 +0000
commit0ac2ad320e516cdf6a752ea0a7c8a2fcf65a0c8e (patch)
treebbc8ac6fdaaf0c4ac68baa9235984cbb858ea9b7 /usr.bin/more
parent4e2f199e0c9ada1b226f685a848abb1420a1ff8f (diff)
downloadsrc-test2-0ac2ad320e516cdf6a752ea0a7c8a2fcf65a0c8e.tar.gz
src-test2-0ac2ad320e516cdf6a752ea0a7c8a2fcf65a0c8e.zip
Notes
Diffstat (limited to 'usr.bin/more')
-rw-r--r--usr.bin/more/command.c56
-rw-r--r--usr.bin/more/decode.c24
-rw-r--r--usr.bin/more/input.c51
-rw-r--r--usr.bin/more/less.h9
-rw-r--r--usr.bin/more/line.c41
-rw-r--r--usr.bin/more/main.c29
-rw-r--r--usr.bin/more/output.c128
-rw-r--r--usr.bin/more/position.c7
-rw-r--r--usr.bin/more/prim.c85
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);
}
-