dan@rna.UUCP (Dan Ts'o) (07/15/85)
I liked the pager "less" recently posted to net.sources, of course, most importantly its ability to go backwards. However a number of "features" I didn't like and have changed. Most try to make it more compatible with more(1) - less supports the -s option to squeeze multiple empty lines. This feature is used by man(1) which has been changed to look for alternative pagers in $PAGER and $MANPAGER. - less understands ^F, ^B, ^U, ^D as VI/more commands for f, b, u, d. - less understands "v" to jump into $EDITOR or VI. - less will quit or go to the next file after hitting the EOF of a file twice in a row. The distributed less can only be exited by "q". - less will act like cat(1)/more(1) if its standard output is not a terminal. Otherwise commands like: less file > junk will just sit there as will (depending on man), man topic | lpr If people are interested in these mods, I will post them... Perhaps someone with System 5 could tell me how pg(1) handles these and similar issues... Cheers, Dan Ts'o Dept. Neurobiology Rockefeller Univ. 1230 York Ave. NY, NY 10021 212-570-7671 ...cmcl2!rna!dan
dan@rna.UUCP (Dan Ts'o) (07/18/85)
rn char *first_cmd; extern char version[]; static char cmdbuf[90]; /* Buffer for holding a multi-char command */ static char *cp; /* Pointer into cmdbuf */ static int cmd_col; /* Current column of the multi-char command */ --- 15,27 ----- extern char current_file[]; extern int intrquit; + #define DEFEDITOR "vi" /* Default $EDITOR */ + + #ifdef EOFQUIT + extern int eofquit; + extern int curr_ac, ac; + #endif + static char cmdbuf[90]; /* Buffer for holding a multi-char command */ static char *cp; /* Pointer into cmdbuf */ static int cmd_col; /* Current column of the multi-char command */ *************** *** 294,309 c = getcc(); goto again; } ! } else switch (c) ! { ! case '0': case '1': case '2': case '3': case '4': ! case '5': case '6': case '7': case '8': case '9': ! /* ! * First digit of a number. ! */ ! mcc = ':'; ! start_mcc(); ! goto again; case 'f': case ' ': --- 304,333 ----- c = getcc(); goto again; } ! } else { ! #ifdef EOFQUIT ! intrquit = 0; ! if (strchr(" fdj\006\026", c) == 0) ! eofquit = 0; ! else if (eofquit) { ! eofquit = 0; ! if (curr_ac+1 >= ac) ! quit(); ! else ! next_file(1); ! continue; ! } ! #endif ! switch (c) ! { ! case '0': case '1': case '2': case '3': case '4': ! case '5': case '6': case '7': case '8': case '9': ! /* ! * First digit of a number. ! */ ! mcc = ':'; ! start_mcc(); ! goto again; case ('V'-'@'): case ('F'-'@'): *************** *** 305,319 start_mcc(); goto again; ! case 'f': ! case ' ': ! /* ! * Forward one screen. ! */ ! lower_left(); ! clear_eol(); ! forward(sc_height - 1); ! break; case 'b': /* --- 329,345 ----- start_mcc(); goto again; ! case ('V'-'@'): ! case ('F'-'@'): ! case 'f': ! case ' ': ! /* ! * Forward one screen. ! */ ! lower_left(); ! clear_eol(); ! forward(sc_height - 1); ! break; case ('B'-'@'): case 033: *************** *** 315,328 forward(sc_height - 1); break; ! case 'b': ! /* ! * Backward one screen. ! */ ! lower_left(); ! clear_eol(); ! backward(sc_height - 1); ! break; case 'e': case 'j': --- 341,356 ----- forward(sc_height - 1); break; ! case ('B'-'@'): ! case 033: ! case 'b': ! /* ! * Backward one screen. ! */ ! lower_left(); ! clear_eol(); ! backward(sc_height - 1); ! break; /* dyt */ #ifdef EDITORCMD *************** *** 324,343 backward(sc_height - 1); break; ! case 'e': ! case 'j': ! case '\r': ! case '\n': ! /* ! * Forward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! forward(n); ! break; case 'y': case 'k': --- 352,366 ----- backward(sc_height - 1); break; ! /* dyt */ ! #ifdef EDITORCMD ! case 'v': ! case 'e': ! if (!current_file[0] || !strcmp("-", current_file)) ! error("Cannot edit this input"); ! else { ! register char *cp; ! char *getenv(); cp = getenv("EDITOR"); if (cp == NULL || *cp == 0) *************** *** 339,356 forward(n); break; ! case 'y': ! case 'k': ! /* ! * Backward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! backward(n); ! break; case 'd': /* --- 362,392 ----- register char *cp; char *getenv(); ! cp = getenv("EDITOR"); ! if (cp == NULL || *cp == 0) ! cp = DEFEDITOR; ! raw_mode(0); ! execlp(cp, cp, current_file, 0); ! raw_mode(1); ! error("Cannot exec editor"); ! } ! break; ! #else ! case 'e': ! #endif ! case 'j': ! case '\r': ! case '\n': ! /* ! * Forward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! forward(n); ! break; case 'y': case 'k': *************** *** 352,369 backward(n); break; ! case 'd': ! /* ! * Forward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! forward(scroll); ! break; case 'u': /* --- 388,405 ----- forward(n); break; ! case 'y': ! case 'k': ! /* ! * Backward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! backward(n); ! break; case ('D'-'@'): case 'd': *************** *** 365,382 forward(scroll); break; ! case 'u': ! /* ! * Forward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! backward(scroll); ! break; case 'R': /* --- 401,419 ----- backward(n); break; ! case ('D'-'@'): ! case 'd': ! /* ! * Forward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! forward(scroll); ! break; case ('U'-'@'): case 'u': *************** *** 378,395 backward(scroll); break; ! case 'R': ! /* ! * Flush buffers, then repaint screen. ! */ ! ch_init(0); ! /* Fall thru */ ! case 'r': ! /* ! * Repaint screen. ! */ ! repaint(); ! break; case 'g': /* --- 415,433 ----- forward(scroll); break; ! case ('U'-'@'): ! case 'u': ! /* ! * Backward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! backward(scroll); ! break; case 'R': /* *************** *** 391,406 repaint(); break; ! case 'g': ! /* ! * Go to line N, default beginning of file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! cmd_exec(); ! jump_back(n); ! break; case 'p': /* --- 429,446 ----- backward(scroll); break; ! case 'R': ! /* ! * Flush buffers, then repaint screen. ! */ ! ch_init(0); ! /* Fall thru */ ! case 'r': ! /* ! * Repaint screen. ! */ ! repaint(); ! break; case 'g': /* *************** *** 402,429 jump_back(n); break; ! case 'p': ! /* ! * Go to a specified percentage into the file. ! */ ! n = cmd_int(); ! if (n < 0) ! n = 0; ! if (n > 100) ! n = 100; ! cmd_exec(); ! jump_percent(n); ! break; ! ! case 'G': ! /* ! * Go to line N, default end of file. ! */ ! n = cmd_int(); ! cmd_exec(); ! if (n <= 0) ! jump_forw(); ! else jump_back(n); break; --- 442,455 ----- repaint(); break; ! case 'g': ! /* ! * Go to line N, default beginning of file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! cmd_exec(); jump_back(n); break; *************** *** 425,431 jump_forw(); else jump_back(n); ! break; case '=': /* --- 451,457 ----- n = 1; cmd_exec(); jump_back(n); ! break; case 'p': /* *************** *** 427,445 jump_back(n); break; ! case '=': ! /* ! * Print file name, etc. ! */ ! error(eq_message(error_width(), MNAME|MOF|MBYTE|MPCT)); ! break; ! ! case 'v': ! /* ! * Print version number, without the "@(#)". ! */ ! error(version+4); ! break; case 'q': /* --- 453,470 ----- jump_back(n); break; ! case 'p': ! /* ! * Go to a specified percentage into the file. ! */ ! n = cmd_int(); ! if (n < 0) ! n = 0; ! if (n > 100) ! n = 100; ! cmd_exec(); ! jump_percent(n); ! break; case 'G': /* *************** *** 441,451 error(version+4); break; ! case 'q': ! /* ! * Exit. ! */ ! return; case '/': case '?': --- 466,482 ----- jump_percent(n); break; ! case 'G': ! /* ! * Go to line N, default end of file. ! */ ! n = cmd_int(); ! cmd_exec(); ! if (n <= 0) ! jump_forw(); ! else ! jump_back(n); ! break; case '=': /* *************** *** 447,465 */ return; ! case '/': ! case '?': ! /* ! * Search for a pattern. ! * Accept chars of the pattern until \n. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc = c; ! start_mcc(); ! c = getcc(); ! goto again; case 'n': /* --- 478,500 ----- jump_back(n); break; ! case '=': ! /* ! * Print file name, etc. ! */ ! error(eq_message(error_width(), MNAME|MOF|MBYTE|MPCT)); ! break; ! ! #ifdef EDITORCMD ! case 'V': ! #else ! case 'v': ! #endif ! /* ! * Print version number, without the "@(#)". ! */ ! error(version+4); ! break; case 'q': /* *************** *** 461,479 c = getcc(); goto again; ! case 'n': ! /* ! * Repeat previous search. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc; ! start_mcc(); ! cmd_exec(); ! search(mcc, (char *)NULL, n); ! mcc = 0; ! break; case 'h': /* --- 496,506 ----- error(version+4); break; ! case 'q': ! /* ! * Exit. ! */ ! return; case '/': case '?': *************** *** 475,487 mcc = 0; break; ! case 'h': ! /* ! * Help. ! */ ! help(); ! repaint(); ! break; case 'E': /* --- 502,520 ----- */ return; ! case '/': ! case '?': ! /* ! * Search for a pattern. ! * Accept chars of the pattern until \n. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc = c; ! start_mcc(); ! c = getcc(); ! goto again; case 'n': /* *************** *** 483,500 repaint(); break; ! case 'E': ! /* ! * Edit a new file. Get the filename. ! */ ! cmd_reset(); ! mcc = 'E'; ! start_mcc(); ! putc(' '); /* This looks nicer */ ! cmd_col++; ! c = getcc(); ! goto again; ! #if SHELL_ESCAPE case '!': /* --- 516,554 ----- c = getcc(); goto again; ! case 'n': ! /* ! * Repeat previous search. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc; ! start_mcc(); ! cmd_exec(); ! search(mcc, (char *)NULL, n); ! mcc = 0; ! break; ! ! case 'h': ! /* ! * Help. ! */ ! help(); ! repaint(); ! break; ! ! case 'E': ! /* ! * Edit a new file. Get the filename. ! */ ! cmd_reset(); ! mcc = 'E'; ! start_mcc(); ! putc(' '); /* This looks nicer */ ! cmd_col++; ! c = getcc(); ! goto again; #if SHELL_ESCAPE case '!': /* *************** *** 496,510 goto again; #if SHELL_ESCAPE ! case '!': ! /* ! * Shell escape. ! */ ! cmd_reset(); ! mcc = '!'; ! start_mcc(); ! c = getcc(); ! goto again; #endif case 'N': --- 550,564 ----- c = getcc(); goto again; #if SHELL_ESCAPE ! case '!': ! /* ! * Shell escape. ! */ ! cmd_reset(); ! mcc = '!'; ! start_mcc(); ! c = getcc(); ! goto again; #endif case 'N': *************** *** 507,521 goto again; #endif ! case 'N': ! /* ! * Examine next file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! next_file(n); ! break; case 'P': /* --- 561,575 ----- goto again; #endif ! case 'N': ! /* ! * Examine next file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! next_file(n); ! break; case 'P': /* *************** *** 517,531 next_file(n); break; ! case 'P': ! /* ! * Examine previous file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! prev_file(n); ! break; case '-': /* --- 571,585 ----- next_file(n); break; ! case 'P': ! /* ! * Examine previous file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! prev_file(n); ! break; case '-': /* *************** *** 527,540 prev_file(n); break; ! case '-': ! /* ! * Toggle a flag setting. ! */ ! mcc = '-'; ! start_mcc(); ! c = getcc(); ! mcc = 0; if (c == erase_char || c == kill_char) /* Abort the "-" command. */ break; --- 581,594 ----- prev_file(n); break; ! case '-': ! /* ! * Toggle a flag setting. ! */ ! mcc = '-'; ! start_mcc(); ! c = getcc(); ! mcc = 0; if (c == erase_char || c == kill_char) /* Abort the "-" command. */ break; *************** *** 544,549 default: bell(); break; } } } --- 598,604 ----- default: bell(); break; + } } } } *** less.l Wed Jul 17 23:26:15 1985 --- ../less/less.l Sun Jul 14 23:09:34 1985 *************** *** 39,44 .IP f Same as SPACE. .PP .IP b Scroll backward one screen. .PP --- 39,50 ----- .IP f Same as SPACE. .PP + .IP "^F" + Same as SPACE. + .PP + .IP "^V" + Same as SPACE. + .PP .IP b Scroll backward one screen. .PP *************** *** 42,47 .IP b Scroll backward one screen. .PP .IP RETURN Scroll forward N lines, default 1. .PP --- 48,56 ----- .IP b Scroll backward one screen. .PP + .IP "^B" + Same as b. + .PP .IP RETURN Scroll forward N lines, default 1. .PP *************** *** 45,51 .IP RETURN Scroll forward N lines, default 1. .PP ! .IP e Same as RETURN. .PP .IP j --- 54,60 ----- .IP RETURN Scroll forward N lines, default 1. .PP ! .IP j Same as RETURN. .PP .IP y *************** *** 48,56 .IP e Same as RETURN. .PP - .IP j - Also the same as RETURN. - .PP .IP y Scroll backward N lines, default 1. .IP k --- 57,62 ----- .IP j Same as RETURN. .PP .IP y Scroll backward N lines, default 1. .IP k *************** *** 60,65 Scroll forward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP .IP u Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. --- 66,74 ----- Scroll forward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP + .IP "^D" + Same as d. + .PP .IP u Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. *************** *** 64,69 Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP .IP r Repaint the screen. .PP --- 73,81 ----- Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP + .IP "^U" + Same as u. + .PP .IP r Repaint the screen. .PP *************** *** 101,106 .IP n Repeat previous search, for N-th occurence of the last pattern. .PP .IP E [filename] Examine a new file. If the filename is missing, the "current" file (see the N and P commands --- 113,126 ----- .IP n Repeat previous search, for N-th occurence of the last pattern. .PP + .IP v + Invoke $EDITOR or + .I vi + on the current file. Does not return. + .PP + .IP e + Same as v. + .PP .IP E [filename] Examine a new file. If the filename is missing, the "current" file (see the N and P commands *************** *** 126,132 this will toggle the setting of that option and print a message describing the new setting. .PP ! .IP v Prints the version number of .I less being run. --- 146,152 ----- this will toggle the setting of that option and print a message describing the new setting. .PP ! .IP V Prints the version number of .I less being run. *************** *** 233,239 the -c command line option will tell .I less to skip this checking. ! (However, if the data is not "clean", unpredicatable results may occur.) .PP If a command line option begins with \fB+\fR, the remainder of that option is taken to be an initial command to --- 253,263 ----- the -c command line option will tell .I less to skip this checking. ! (However, if the data is not "clean", unpredictable results may occur.) ! .PP ! The -s option directs ! .I less ! to squeeze multiple empty lines to one. .PP If a command line option begins with \fB+\fR, the remainder of that option is taken to be an initial command to *** main.c Wed Jul 17 23:26:51 1985 --- ../less/main.c Sun Jul 14 23:25:20 1985 *************** *** 25,30 public int pr_type; /* Type of prompt (short, medium, long) */ public int bs_mode; /* How to process backspaces */ public int know_dumb; /* Don't complain about dumb terminals */ /* * Defaults for command line options. --- 25,35 ----- public int pr_type; /* Type of prompt (short, medium, long) */ public int bs_mode; /* How to process backspaces */ public int know_dumb; /* Don't complain about dumb terminals */ + /* dyt */ + public int sflag; /* Squeeze empty lines */ + #ifdef EOFQUIT + public int eofquit; /* Quit at end of file */ + #endif /* * Defaults for command line options. *************** *** 41,47 extern int nbufs; extern int sigs; ! static char current_file[128]; static int ac; static char **av; --- 46,53 ----- extern int nbufs; extern int sigs; ! /* dyt - made public */ ! public char current_file[128]; public int ac; public int curr_ac; *************** *** 43,49 static char current_file[128]; ! static int ac; static char **av; static int curr_ac; --- 49,56 ----- /* dyt - made public */ public char current_file[128]; ! public int ac; ! public int curr_ac; static char **av; /* *************** *** 45,51 static int ac; static char **av; - static int curr_ac; /* * Edit a new file. --- 52,57 ----- public int ac; public int curr_ac; static char **av; /* * Edit a new file. *************** *** 85,91 * and the input file (for data) are the same, * we get weird results at best. */ ! error("Can't take input from a terminal"); if (f > 0) close(f); return; --- 91,101 ----- * and the input file (for data) are the same, * we get weird results at best. */ ! /* dyt */ ! if (curr_ac == 0) ! write(2, "Usage: less [-options] [files]\n", 31); ! else ! error("Can't take input from a terminal"); if (f > 0) close(f); return; *************** *** 396,401 case 'M': pr_type = PR_LONG; break; case 't': top_search = !TOP_SEARCH; break; --- 406,415 ----- case 'M': pr_type = PR_LONG; break; + /* dyt - squeeze empty lines */ + case 's': + sflag = 1; + break; case 't': top_search = !TOP_SEARCH; break; *************** *** 457,462 av = argv; curr_ac = 0; /* * Set up terminal, etc. */ --- 471,483 ----- av = argv; curr_ac = 0; + /* dyt */ + if (!isatty(1)) { + *--argv = "cat"; + execv("/bin/cat", argv); + write(2, "Cannot exec /bin/cat\n", 21); + exit(1); + } /* * Set up terminal, etc. */ *************** *** 461,467 * Set up terminal, etc. */ raw_mode(1); - get_term(); open_getc(); init(); --- 482,487 ----- * Set up terminal, etc. */ raw_mode(1); open_getc(); get_term(); init(); *************** *** 463,468 raw_mode(1); get_term(); open_getc(); init(); if (setjmp(main_loop) == 0) --- 483,489 ----- */ raw_mode(1); open_getc(); + get_term(); init(); if (setjmp(main_loop) == 0) *** prim.c Wed Jul 17 23:26:59 1985 --- ../less/prim.c Sun Jul 14 22:31:14 1985 *************** *** 11,16 extern int sigs; extern char *line; /* * Display n lines, scrolling forward, * starting at position pos in the input file. --- 11,20 ----- extern int sigs; extern char *line; + #ifdef EOFQUIT + extern int eofquit; + #endif + /* * Display n lines, scrolling forward, * starting at position pos in the input file. *************** *** 35,40 */ if (!force && position(TOP) != NULL_POSITION) { if (quiet == NOT_QUIET) bell(); else --- 39,47 ----- */ if (!force && position(TOP) != NULL_POSITION) { + #ifdef EOFQUIT + eofquit++; + #endif if (quiet == NOT_QUIET) bell(); else *** screen.c Wed Jul 17 23:27:04 1985 --- ../less/screen.c Sun Jul 14 23:48:31 1985 *************** *** 45,50 public int sc_width, sc_height; /* Height & width of screen */ public int ul_width, ue_width; /* Printing width of underline sequences */ /* * These two variables are sometimes defined in, * and needed by, the termcap library. --- 45,53 ----- public int sc_width, sc_height; /* Height & width of screen */ public int ul_width, ue_width; /* Printing width of underline sequences */ + /* dyt */ + extern int tty; /* Keyboard input */ + /* * These two variables are sometimes defined in, * and needed by, the termcap library. *************** *** 82,88 /* * Get terminal modes. */ ! ioctl(2, TCGETA, &s); /* * Save modes and set certain variables dependent on modes. --- 85,91 ----- /* * Get terminal modes. */ ! ioctl(tty, TCGETA, &s); /* * Save modes and set certain variables dependent on modes. *************** *** 107,113 */ s = save_term; } ! ioctl(2, TCSETAW, &s); #else struct sgttyb s; static struct sgttyb save_term; --- 110,116 ----- */ s = save_term; } ! ioctl(tty, TCSETAW, &s); #else struct sgttyb s; static struct sgttyb save_term; *************** *** 111,116 #else struct sgttyb s; static struct sgttyb save_term; if (on) { --- 114,120 ----- #else struct sgttyb s; static struct sgttyb save_term; + struct tchars tc; if (on) { *************** *** 117,123 /* * Get terminal modes. */ ! ioctl(2, TIOCGETP, &s); /* * Save modes and set certain variables dependent on modes. --- 121,127 ----- /* * Get terminal modes. */ ! ioctl(tty, TIOCGETP, &s); /* * Save modes and set certain variables dependent on modes. *************** *** 139,145 */ s = save_term; } ! ioctl(2, TIOCSETP, &s); #endif } --- 143,149 ----- */ s = save_term; } ! ioctl(tty, TIOCSETP, &s); #endif } *** signal.c Wed Jul 17 23:27:05 1985 --- ../less/signal.c Sun Jul 14 23:54:36 1985 *************** *** 34,39 extern char *first_cmd; extern jmp_buf main_loop; /* * Interrupt signal handler. */ --- 34,42 ----- extern char *first_cmd; extern jmp_buf main_loop; + /* dyt */ + int intrquit = 0; + /* * Interrupt signal handler. */ *************** *** 129,134 * {{ You may wish to replace the bell() with * error("Interrupt"); }} */ } longjmp(main_loop, 1); --- 132,139 ----- * {{ You may wish to replace the bell() with * error("Interrupt"); }} */ + if (intrquit++) + first_cmd = "q"; } longjmp(main_loop, 1); *** ttyin.c Wed Jul 17 23:27:06 1985 --- ../less/ttyin.c Sun Jul 14 23:24:48 1985 *************** *** 13,19 */ public int reading; ! static int tty; /* * Open keyboard for input. --- 13,20 ----- */ public int reading; ! /* dyt - made public */ ! int tty = 2; /* * Open keyboard for input. *************** *** 23,28 open_getc() { tty = 2; } /* --- 24,32 ----- open_getc() { tty = 2; + /* dyt */ + if (!isatty(tty)) + tty = open("/dev/tty", 2); } /* *** makefile.bsd42 Sat Jul 13 18:52:01 1985 --- Makefile Wed Jul 17 23:15:52 1985 *************** *** 57,63 # SHELL_ESCAPE is 1 if you wish to allow shell escapes. # (This is possible only if your system supplies the system() function.) ! SHELL_ESCAPE = 0 ########################################################################## --- 57,63 ----- # SHELL_ESCAPE is 1 if you wish to allow shell escapes. # (This is possible only if your system supplies the system() function.) ! SHELL_ESCAPE = 1 ########################################################################## *************** *** 69,75 # INSTALL_LESS is a list of the public versions of less. # INSTALL_MAN is a list of the public versions of the manual page. ! INSTALL_LESS = /usr/local/less INSTALL_MAN = /usr/man/manl/less.l # OPTIM is passed to the compiler and the loader. --- 69,75 ----- # INSTALL_LESS is a list of the public versions of less. # INSTALL_MAN is a list of the public versions of the manual page. ! INSTALL_LESS = /usr/local/bin/less INSTALL_MAN = /usr/man/manl/less.l # OPTIM is passed to the compiler and the loader. *************** *** 96,102 "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \ "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \ "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \ ! "-DXENIX=$(XENIX)" CFLAGS = $(OPTIM) $(DEFS) --- 96,105 ----- "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \ "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \ "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \ ! "-DXENIX=$(XENIX)" \ ! "-DEOFQUIT" \ ! "-Dstrchr=index" \ ! "-DEDITORCMD" CFLAGS = $(OPTIM) $(DEFS) *** man.c.org Sun Sep 25 21:05:27 1983 --- man.c Sun Jul 14 20:53:04 1985 *************** *** 276,281 char *cp; { char cmd[BUFSIZ]; if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); --- 273,280 ----- char *cp; { char cmd[BUFSIZ]; + /* dyt */ + char *pager, *getenv(); pager = getenv("MANPAGER"); if (pager == NULL || *pager == 0) { *************** *** 277,282 { char cmd[BUFSIZ]; if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); else --- 276,287 ----- /* dyt */ char *pager, *getenv(); + pager = getenv("MANPAGER"); + if (pager == NULL || *pager == 0) { + pager = getenv("PAGER"); + if (pager == NULL || *pager == 0) + pager = MORE; + } if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : pager, cp); else *************** *** 278,284 char cmd[BUFSIZ]; if (cp[0] == 'c') ! sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); else sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, MORE); system(cmd); --- 283,289 ----- pager = MORE; } if (cp[0] == 'c') ! sprintf(cmd, "%s %s", nomore? CAT : pager, cp); else sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, pager); system(cmd); *************** *** 280,286 if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); else ! sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, MORE); system(cmd); } --- 285,291 ----- if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : pager, cp); else ! sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, pager); system(cmd); }
dan@rna.UUCP (Dan Ts'o) (07/20/85)
x Here are the diffs again because apparently the line eater bug crunched the previous article for a number of sites (hasn't that bug been fixed everywhere yet?!?). And for those that didn't see the first article, here, again, is a synopsis of the mods: - less supports the -s option to squeeze multiple empty lines. This feature is used by man(1) which has been changed to look for alternative pagers in $PAGER and $MANPAGER. - less understands ^F, ^B, ^U, ^D as VI/more commands for f, b, u, d. - less understands "v" to jump into $EDITOR or VI. - less will quit or go to the next file after hitting the EOF of a file twice in a row. The distributed less can only be exited by "q". - less will act like cat(1)/more(1) if its standard output is not a terminal. Otherwise commands like: less file > junk will just sit there as will (depending on man), man topic | lpr Someone else mailed me saying that they changed less to start displaying from the top. I would love to have someone perhaps the original author keep track of all these mods. However I received no response from him after mailing him a note about these mods. (Are you out there ?) Cheers, Dan Ts'o Dept. Neurobiology Rockefeller Univ. 1230 York Ave. NY, NY 10021 212-570-7671 ...cmcl2!rna!dan *** ch.c Wed Jul 17 23:26:25 1985 --- ../less/ch.c Sun Jul 14 22:20:45 1985 *************** *** 8,13 public int file = -1; /* File descriptor of the input file */ /* * Pool of buffers holding the most recently used blocks of the input file. */ --- 8,16 ----- public int file = -1; /* File descriptor of the input file */ + /* dyt */ + public int sflag = 0; + /* * Pool of buffers holding the most recently used blocks of the input file. */ *************** *** 104,110 * is coming from standard input, due to the nature of pipes. */ end = 0; ! while ((n = read(file, &bp->data[end], BUFSIZ-end)) > 0) if ((end += n) >= BUFSIZ) break; --- 107,116 ----- * is coming from standard input, due to the nature of pipes. */ end = 0; ! /* dyt - added multi empty line squeeze */ ! while ((n = read(file, &bp->data[end], BUFSIZ-end)) > 0) { ! if (sflag) ! n = squeeze(bp->data, end, n); if ((end += n) >= BUFSIZ) break; } *************** *** 107,112 while ((n = read(file, &bp->data[end], BUFSIZ-end)) > 0) if ((end += n) >= BUFSIZ) break; if (n < 0) { --- 113,119 ----- n = squeeze(bp->data, end, n); if ((end += n) >= BUFSIZ) break; + } if (n < 0) { *************** *** 193,199 public int ch_end_seek() { ! if (pipe) { /* * Do it the slow way: read till end of data. --- 200,207 ----- public int ch_end_seek() { ! /* dyt */ ! if (pipe || sflag) { /* * Do it the slow way: read till end of data. *************** *** 331,334 buf_tail = &bufs[nbufs-1]; last_piped_block = -1; (void) ch_seek((POSITION)0); /* ? */ } --- 339,381 ----- buf_tail = &bufs[nbufs-1]; last_piped_block = -1; (void) ch_seek((POSITION)0); /* ? */ + } + + /* dyt */ + squeeze(bp, end, n) + register char *bp; + register unsigned end, n; + { + register int lastc, lastc1; + register char *s, *t, *u, *v; + + if (end == 0) + lastc1 = lastc = 0; + else { + lastc = bp[end - 1]; + if (end > 1) + lastc1 = bp[end - 2]; + else + lastc1 = 0; + } + bp = bp + end; + t = bp + n; + while (bp < t) { + if (lastc == '\n' && lastc1 == '\n' && *bp == '\n') { + s = bp; + u = t; + while (s < t && *s == '\n') { + n--; + u--; + s++; + } + v = bp; + while (s < t) + *v++ = *s++; + t = u; + } + lastc1 = lastc; + lastc = *bp++; + } + return n; } *** command.c Wed Jul 17 23:26:29 1985 --- ../less/command.c Wed Jul 17 23:21:22 1985 *************** *** 11,16 extern int sc_width, sc_height; extern char *first_cmd; extern char version[]; static char cmdbuf[90]; /* Buffer for holding a multi-char command */ static char *cp; /* Pointer into cmdbuf */ --- 11,19 ----- extern int sc_width, sc_height; extern char *first_cmd; extern char version[]; + /* dyt */ + extern char current_file[]; + extern int intrquit; #define DEFEDITOR "vi" /* Default $EDITOR */ *************** *** 12,17 extern char *first_cmd; extern char version[]; static char cmdbuf[90]; /* Buffer for holding a multi-char command */ static char *cp; /* Pointer into cmdbuf */ static int cmd_col; /* Current column of the multi-char command */ --- 15,27 ----- extern char current_file[]; extern int intrquit; + #define DEFEDITOR "vi" /* Default $EDITOR */ + + #ifdef EOFQUIT + extern int eofquit; + extern int curr_ac, ac; + #endif + static char cmdbuf[90]; /* Buffer for holding a multi-char command */ static char *cp; /* Pointer into cmdbuf */ static int cmd_col; /* Current column of the multi-char command */ *************** *** 294,309 c = getcc(); goto again; } ! } else switch (c) ! { ! case '0': case '1': case '2': case '3': case '4': ! case '5': case '6': case '7': case '8': case '9': ! /* ! * First digit of a number. ! */ ! mcc = ':'; ! start_mcc(); ! goto again; case 'f': case ' ': --- 304,333 ----- c = getcc(); goto again; } ! } else { ! #ifdef EOFQUIT ! intrquit = 0; ! if (strchr(" fdj\006\026", c) == 0) ! eofquit = 0; ! else if (eofquit) { ! eofquit = 0; ! if (curr_ac+1 >= ac) ! quit(); ! else ! next_file(1); ! continue; ! } ! #endif ! switch (c) ! { ! case '0': case '1': case '2': case '3': case '4': ! case '5': case '6': case '7': case '8': case '9': ! /* ! * First digit of a number. ! */ ! mcc = ':'; ! start_mcc(); ! goto again; case ('V'-'@'): case ('F'-'@'): *************** *** 305,319 start_mcc(); goto again; ! case 'f': ! case ' ': ! /* ! * Forward one screen. ! */ ! lower_left(); ! clear_eol(); ! forward(sc_height - 1); ! break; case 'b': /* --- 329,345 ----- start_mcc(); goto again; ! case ('V'-'@'): ! case ('F'-'@'): ! case 'f': ! case ' ': ! /* ! * Forward one screen. ! */ ! lower_left(); ! clear_eol(); ! forward(sc_height - 1); ! break; case ('B'-'@'): case 033: *************** *** 315,328 forward(sc_height - 1); break; ! case 'b': ! /* ! * Backward one screen. ! */ ! lower_left(); ! clear_eol(); ! backward(sc_height - 1); ! break; case 'e': case 'j': --- 341,356 ----- forward(sc_height - 1); break; ! case ('B'-'@'): ! case 033: ! case 'b': ! /* ! * Backward one screen. ! */ ! lower_left(); ! clear_eol(); ! backward(sc_height - 1); ! break; /* dyt */ #ifdef EDITORCMD *************** *** 324,343 backward(sc_height - 1); break; ! case 'e': ! case 'j': ! case '\r': ! case '\n': ! /* ! * Forward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! forward(n); ! break; case 'y': case 'k': --- 352,366 ----- backward(sc_height - 1); break; ! /* dyt */ ! #ifdef EDITORCMD ! case 'v': ! case 'e': ! if (!current_file[0] || !strcmp("-", current_file)) ! error("Cannot edit this input"); ! else { ! register char *cp; ! char *getenv(); cp = getenv("EDITOR"); if (cp == NULL || *cp == 0) *************** *** 339,356 forward(n); break; ! case 'y': ! case 'k': ! /* ! * Backward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! backward(n); ! break; case 'd': /* --- 362,392 ----- register char *cp; char *getenv(); ! cp = getenv("EDITOR"); ! if (cp == NULL || *cp == 0) ! cp = DEFEDITOR; ! raw_mode(0); ! execlp(cp, cp, current_file, 0); ! raw_mode(1); ! error("Cannot exec editor"); ! } ! break; ! #else ! case 'e': ! #endif ! case 'j': ! case '\r': ! case '\n': ! /* ! * Forward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! forward(n); ! break; case 'y': case 'k': *************** *** 352,369 backward(n); break; ! case 'd': ! /* ! * Forward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! forward(scroll); ! break; case 'u': /* --- 388,405 ----- forward(n); break; ! case 'y': ! case 'k': ! /* ! * Backward N (default 1) line. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! lower_left(); ! clear_eol(); ! backward(n); ! break; case ('D'-'@'): case 'd': *************** *** 365,382 forward(scroll); break; ! case 'u': ! /* ! * Forward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! backward(scroll); ! break; case 'R': /* --- 401,419 ----- backward(n); break; ! case ('D'-'@'): ! case 'd': ! /* ! * Forward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! forward(scroll); ! break; case ('U'-'@'): case 'u': *************** *** 378,395 backward(scroll); break; ! case 'R': ! /* ! * Flush buffers, then repaint screen. ! */ ! ch_init(0); ! /* Fall thru */ ! case 'r': ! /* ! * Repaint screen. ! */ ! repaint(); ! break; case 'g': /* --- 415,433 ----- forward(scroll); break; ! case ('U'-'@'): ! case 'u': ! /* ! * Backward N lines ! * (default same as last 'd' or 'u' command). ! */ ! n = cmd_int(); ! if (n > 0) ! scroll = n; ! lower_left(); ! clear_eol(); ! backward(scroll); ! break; case 'R': /* *************** *** 391,406 repaint(); break; ! case 'g': ! /* ! * Go to line N, default beginning of file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! cmd_exec(); ! jump_back(n); ! break; case 'p': /* --- 429,446 ----- backward(scroll); break; ! case 'R': ! /* ! * Flush buffers, then repaint screen. ! */ ! ch_init(0); ! /* Fall thru */ ! case 'r': ! /* ! * Repaint screen. ! */ ! repaint(); ! break; case 'g': /* *************** *** 402,429 jump_back(n); break; ! case 'p': ! /* ! * Go to a specified percentage into the file. ! */ ! n = cmd_int(); ! if (n < 0) ! n = 0; ! if (n > 100) ! n = 100; ! cmd_exec(); ! jump_percent(n); ! break; ! ! case 'G': ! /* ! * Go to line N, default end of file. ! */ ! n = cmd_int(); ! cmd_exec(); ! if (n <= 0) ! jump_forw(); ! else jump_back(n); break; --- 442,455 ----- repaint(); break; ! case 'g': ! /* ! * Go to line N, default beginning of file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! cmd_exec(); jump_back(n); break; *************** *** 425,431 jump_forw(); else jump_back(n); ! break; case '=': /* --- 451,457 ----- n = 1; cmd_exec(); jump_back(n); ! break; case 'p': /* *************** *** 427,445 jump_back(n); break; ! case '=': ! /* ! * Print file name, etc. ! */ ! error(eq_message(error_width(), MNAME|MOF|MBYTE|MPCT)); ! break; ! ! case 'v': ! /* ! * Print version number, without the "@(#)". ! */ ! error(version+4); ! break; case 'q': /* --- 453,470 ----- jump_back(n); break; ! case 'p': ! /* ! * Go to a specified percentage into the file. ! */ ! n = cmd_int(); ! if (n < 0) ! n = 0; ! if (n > 100) ! n = 100; ! cmd_exec(); ! jump_percent(n); ! break; case 'G': /* *************** *** 441,451 error(version+4); break; ! case 'q': ! /* ! * Exit. ! */ ! return; case '/': case '?': --- 466,482 ----- jump_percent(n); break; ! case 'G': ! /* ! * Go to line N, default end of file. ! */ ! n = cmd_int(); ! cmd_exec(); ! if (n <= 0) ! jump_forw(); ! else ! jump_back(n); ! break; case '=': /* *************** *** 447,465 */ return; ! case '/': ! case '?': ! /* ! * Search for a pattern. ! * Accept chars of the pattern until \n. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc = c; ! start_mcc(); ! c = getcc(); ! goto again; case 'n': /* --- 478,500 ----- jump_back(n); break; ! case '=': ! /* ! * Print file name, etc. ! */ ! error(eq_message(error_width(), MNAME|MOF|MBYTE|MPCT)); ! break; ! ! #ifdef EDITORCMD ! case 'V': ! #else ! case 'v': ! #endif ! /* ! * Print version number, without the "@(#)". ! */ ! error(version+4); ! break; case 'q': /* *************** *** 461,479 c = getcc(); goto again; ! case 'n': ! /* ! * Repeat previous search. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc; ! start_mcc(); ! cmd_exec(); ! search(mcc, (char *)NULL, n); ! mcc = 0; ! break; case 'h': /* --- 496,506 ----- error(version+4); break; ! case 'q': ! /* ! * Exit. ! */ ! return; case '/': case '?': *************** *** 475,487 mcc = 0; break; ! case 'h': ! /* ! * Help. ! */ ! help(); ! repaint(); ! break; case 'E': /* --- 502,520 ----- */ return; ! case '/': ! case '?': ! /* ! * Search for a pattern. ! * Accept chars of the pattern until \n. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc = c; ! start_mcc(); ! c = getcc(); ! goto again; case 'n': /* *************** *** 483,500 repaint(); break; ! case 'E': ! /* ! * Edit a new file. Get the filename. ! */ ! cmd_reset(); ! mcc = 'E'; ! start_mcc(); ! putc(' '); /* This looks nicer */ ! cmd_col++; ! c = getcc(); ! goto again; ! #if SHELL_ESCAPE case '!': /* --- 516,554 ----- c = getcc(); goto again; ! case 'n': ! /* ! * Repeat previous search. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! mcc = last_mcc; ! start_mcc(); ! cmd_exec(); ! search(mcc, (char *)NULL, n); ! mcc = 0; ! break; ! ! case 'h': ! /* ! * Help. ! */ ! help(); ! repaint(); ! break; ! ! case 'E': ! /* ! * Edit a new file. Get the filename. ! */ ! cmd_reset(); ! mcc = 'E'; ! start_mcc(); ! putc(' '); /* This looks nicer */ ! cmd_col++; ! c = getcc(); ! goto again; #if SHELL_ESCAPE case '!': /* *************** *** 496,510 goto again; #if SHELL_ESCAPE ! case '!': ! /* ! * Shell escape. ! */ ! cmd_reset(); ! mcc = '!'; ! start_mcc(); ! c = getcc(); ! goto again; #endif case 'N': --- 550,564 ----- c = getcc(); goto again; #if SHELL_ESCAPE ! case '!': ! /* ! * Shell escape. ! */ ! cmd_reset(); ! mcc = '!'; ! start_mcc(); ! c = getcc(); ! goto again; #endif case 'N': *************** *** 507,521 goto again; #endif ! case 'N': ! /* ! * Examine next file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! next_file(n); ! break; case 'P': /* --- 561,575 ----- goto again; #endif ! case 'N': ! /* ! * Examine next file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! next_file(n); ! break; case 'P': /* *************** *** 517,531 next_file(n); break; ! case 'P': ! /* ! * Examine previous file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! prev_file(n); ! break; case '-': /* --- 571,585 ----- next_file(n); break; ! case 'P': ! /* ! * Examine previous file. ! */ ! n = cmd_int(); ! if (n <= 0) ! n = 1; ! prev_file(n); ! break; case '-': /* *************** *** 527,540 prev_file(n); break; ! case '-': ! /* ! * Toggle a flag setting. ! */ ! mcc = '-'; ! start_mcc(); ! c = getcc(); ! mcc = 0; if (c == erase_char || c == kill_char) /* Abort the "-" command. */ break; --- 581,594 ----- prev_file(n); break; ! case '-': ! /* ! * Toggle a flag setting. ! */ ! mcc = '-'; ! start_mcc(); ! c = getcc(); ! mcc = 0; if (c == erase_char || c == kill_char) /* Abort the "-" command. */ break; *************** *** 544,549 default: bell(); break; } } } --- 598,604 ----- default: bell(); break; + } } } } *** less.l Wed Jul 17 23:26:15 1985 --- ../less/less.l Sun Jul 14 23:09:34 1985 *************** *** 39,44 .IP f Same as SPACE. .PP .IP b Scroll backward one screen. .PP --- 39,50 ----- .IP f Same as SPACE. .PP + .IP "^F" + Same as SPACE. + .PP + .IP "^V" + Same as SPACE. + .PP .IP b Scroll backward one screen. .PP *************** *** 42,47 .IP b Scroll backward one screen. .PP .IP RETURN Scroll forward N lines, default 1. .PP --- 48,56 ----- .IP b Scroll backward one screen. .PP + .IP "^B" + Same as b. + .PP .IP RETURN Scroll forward N lines, default 1. .PP *************** *** 45,51 .IP RETURN Scroll forward N lines, default 1. .PP ! .IP e Same as RETURN. .PP .IP j --- 54,60 ----- .IP RETURN Scroll forward N lines, default 1. .PP ! .IP j Same as RETURN. .PP .IP y *************** *** 48,56 .IP e Same as RETURN. .PP - .IP j - Also the same as RETURN. - .PP .IP y Scroll backward N lines, default 1. .IP k --- 57,62 ----- .IP j Same as RETURN. .PP .IP y Scroll backward N lines, default 1. .IP k *************** *** 60,65 Scroll forward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP .IP u Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. --- 66,74 ----- Scroll forward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP + .IP "^D" + Same as d. + .PP .IP u Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. *************** *** 64,69 Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP .IP r Repaint the screen. .PP --- 73,81 ----- Scroll backward N lines, default 10. If N is specified, it becomes the new default for all d and u commands. .PP + .IP "^U" + Same as u. + .PP .IP r Repaint the screen. .PP *************** *** 101,106 .IP n Repeat previous search, for N-th occurence of the last pattern. .PP .IP E [filename] Examine a new file. If the filename is missing, the "current" file (see the N and P commands --- 113,126 ----- .IP n Repeat previous search, for N-th occurence of the last pattern. .PP + .IP v + Invoke $EDITOR or + .I vi + on the current file. Does not return. + .PP + .IP e + Same as v. + .PP .IP E [filename] Examine a new file. If the filename is missing, the "current" file (see the N and P commands *************** *** 126,132 this will toggle the setting of that option and print a message describing the new setting. .PP ! .IP v Prints the version number of .I less being run. --- 146,152 ----- this will toggle the setting of that option and print a message describing the new setting. .PP ! .IP V Prints the version number of .I less being run. *************** *** 233,239 the -c command line option will tell .I less to skip this checking. ! (However, if the data is not "clean", unpredicatable results may occur.) .PP If a command line option begins with \fB+\fR, the remainder of that option is taken to be an initial command to --- 253,263 ----- the -c command line option will tell .I less to skip this checking. ! (However, if the data is not "clean", unpredictable results may occur.) ! .PP ! The -s option directs ! .I less ! to squeeze multiple empty lines to one. .PP If a command line option begins with \fB+\fR, the remainder of that option is taken to be an initial command to *** main.c Wed Jul 17 23:26:51 1985 --- ../less/main.c Sun Jul 14 23:25:20 1985 *************** *** 25,30 public int pr_type; /* Type of prompt (short, medium, long) */ public int bs_mode; /* How to process backspaces */ public int know_dumb; /* Don't complain about dumb terminals */ /* * Defaults for command line options. --- 25,35 ----- public int pr_type; /* Type of prompt (short, medium, long) */ public int bs_mode; /* How to process backspaces */ public int know_dumb; /* Don't complain about dumb terminals */ + /* dyt */ + public int sflag; /* Squeeze empty lines */ + #ifdef EOFQUIT + public int eofquit; /* Quit at end of file */ + #endif /* * Defaults for command line options. *************** *** 41,47 extern int nbufs; extern int sigs; ! static char current_file[128]; static int ac; static char **av; --- 46,53 ----- extern int nbufs; extern int sigs; ! /* dyt - made public */ ! public char current_file[128]; public int ac; public int curr_ac; *************** *** 43,49 static char current_file[128]; ! static int ac; static char **av; static int curr_ac; --- 49,56 ----- /* dyt - made public */ public char current_file[128]; ! public int ac; ! public int curr_ac; static char **av; /* *************** *** 45,51 static int ac; static char **av; - static int curr_ac; /* * Edit a new file. --- 52,57 ----- public int ac; public int curr_ac; static char **av; /* * Edit a new file. *************** *** 85,91 * and the input file (for data) are the same, * we get weird results at best. */ ! error("Can't take input from a terminal"); if (f > 0) close(f); return; --- 91,101 ----- * and the input file (for data) are the same, * we get weird results at best. */ ! /* dyt */ ! if (curr_ac == 0) ! write(2, "Usage: less [-options] [files]\n", 31); ! else ! error("Can't take input from a terminal"); if (f > 0) close(f); return; *************** *** 396,401 case 'M': pr_type = PR_LONG; break; case 't': top_search = !TOP_SEARCH; break; --- 406,415 ----- case 'M': pr_type = PR_LONG; break; + /* dyt - squeeze empty lines */ + case 's': + sflag = 1; + break; case 't': top_search = !TOP_SEARCH; break; *************** *** 457,462 av = argv; curr_ac = 0; /* * Set up terminal, etc. */ --- 471,483 ----- av = argv; curr_ac = 0; + /* dyt */ + if (!isatty(1)) { + *--argv = "cat"; + execv("/bin/cat", argv); + write(2, "Cannot exec /bin/cat\n", 21); + exit(1); + } /* * Set up terminal, etc. */ *************** *** 461,467 * Set up terminal, etc. */ raw_mode(1); - get_term(); open_getc(); init(); --- 482,487 ----- * Set up terminal, etc. */ raw_mode(1); open_getc(); get_term(); init(); *************** *** 463,468 raw_mode(1); get_term(); open_getc(); init(); if (setjmp(main_loop) == 0) --- 483,489 ----- */ raw_mode(1); open_getc(); + get_term(); init(); if (setjmp(main_loop) == 0) *** prim.c Wed Jul 17 23:26:59 1985 --- ../less/prim.c Sun Jul 14 22:31:14 1985 *************** *** 11,16 extern int sigs; extern char *line; /* * Display n lines, scrolling forward, * starting at position pos in the input file. --- 11,20 ----- extern int sigs; extern char *line; + #ifdef EOFQUIT + extern int eofquit; + #endif + /* * Display n lines, scrolling forward, * starting at position pos in the input file. *************** *** 35,40 */ if (!force && position(TOP) != NULL_POSITION) { if (quiet == NOT_QUIET) bell(); else --- 39,47 ----- */ if (!force && position(TOP) != NULL_POSITION) { + #ifdef EOFQUIT + eofquit++; + #endif if (quiet == NOT_QUIET) bell(); else *** screen.c Wed Jul 17 23:27:04 1985 --- ../less/screen.c Sun Jul 14 23:48:31 1985 *************** *** 45,50 public int sc_width, sc_height; /* Height & width of screen */ public int ul_width, ue_width; /* Printing width of underline sequences */ /* * These two variables are sometimes defined in, * and needed by, the termcap library. --- 45,53 ----- public int sc_width, sc_height; /* Height & width of screen */ public int ul_width, ue_width; /* Printing width of underline sequences */ + /* dyt */ + extern int tty; /* Keyboard input */ + /* * These two variables are sometimes defined in, * and needed by, the termcap library. *************** *** 82,88 /* * Get terminal modes. */ ! ioctl(2, TCGETA, &s); /* * Save modes and set certain variables dependent on modes. --- 85,91 ----- /* * Get terminal modes. */ ! ioctl(tty, TCGETA, &s); /* * Save modes and set certain variables dependent on modes. *************** *** 107,113 */ s = save_term; } ! ioctl(2, TCSETAW, &s); #else struct sgttyb s; static struct sgttyb save_term; --- 110,116 ----- */ s = save_term; } ! ioctl(tty, TCSETAW, &s); #else struct sgttyb s; static struct sgttyb save_term; *************** *** 111,116 #else struct sgttyb s; static struct sgttyb save_term; if (on) { --- 114,120 ----- #else struct sgttyb s; static struct sgttyb save_term; + struct tchars tc; if (on) { *************** *** 117,123 /* * Get terminal modes. */ ! ioctl(2, TIOCGETP, &s); /* * Save modes and set certain variables dependent on modes. --- 121,127 ----- /* * Get terminal modes. */ ! ioctl(tty, TIOCGETP, &s); /* * Save modes and set certain variables dependent on modes. *************** *** 139,145 */ s = save_term; } ! ioctl(2, TIOCSETP, &s); #endif } --- 143,149 ----- */ s = save_term; } ! ioctl(tty, TIOCSETP, &s); #endif } *** signal.c Wed Jul 17 23:27:05 1985 --- ../less/signal.c Sun Jul 14 23:54:36 1985 *************** *** 34,39 extern char *first_cmd; extern jmp_buf main_loop; /* * Interrupt signal handler. */ --- 34,42 ----- extern char *first_cmd; extern jmp_buf main_loop; + /* dyt */ + int intrquit = 0; + /* * Interrupt signal handler. */ *************** *** 129,134 * {{ You may wish to replace the bell() with * error("Interrupt"); }} */ } longjmp(main_loop, 1); --- 132,139 ----- * {{ You may wish to replace the bell() with * error("Interrupt"); }} */ + if (intrquit++) + first_cmd = "q"; } longjmp(main_loop, 1); *** ttyin.c Wed Jul 17 23:27:06 1985 --- ../less/ttyin.c Sun Jul 14 23:24:48 1985 *************** *** 13,19 */ public int reading; ! static int tty; /* * Open keyboard for input. --- 13,20 ----- */ public int reading; ! /* dyt - made public */ ! int tty = 2; /* * Open keyboard for input. *************** *** 23,28 open_getc() { tty = 2; } /* --- 24,32 ----- open_getc() { tty = 2; + /* dyt */ + if (!isatty(tty)) + tty = open("/dev/tty", 2); } /* *** makefile.bsd42 Sat Jul 13 18:52:01 1985 --- Makefile Wed Jul 17 23:15:52 1985 *************** *** 57,63 # SHELL_ESCAPE is 1 if you wish to allow shell escapes. # (This is possible only if your system supplies the system() function.) ! SHELL_ESCAPE = 0 ########################################################################## --- 57,63 ----- # SHELL_ESCAPE is 1 if you wish to allow shell escapes. # (This is possible only if your system supplies the system() function.) ! SHELL_ESCAPE = 1 ########################################################################## *************** *** 69,75 # INSTALL_LESS is a list of the public versions of less. # INSTALL_MAN is a list of the public versions of the manual page. ! INSTALL_LESS = /usr/local/less INSTALL_MAN = /usr/man/manl/less.l # OPTIM is passed to the compiler and the loader. --- 69,75 ----- # INSTALL_LESS is a list of the public versions of less. # INSTALL_MAN is a list of the public versions of the manual page. ! INSTALL_LESS = /usr/local/bin/less INSTALL_MAN = /usr/man/manl/less.l # OPTIM is passed to the compiler and the loader. *************** *** 96,102 "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \ "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \ "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \ ! "-DXENIX=$(XENIX)" CFLAGS = $(OPTIM) $(DEFS) --- 96,105 ----- "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \ "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \ "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \ ! "-DXENIX=$(XENIX)" \ ! "-DEOFQUIT" \ ! "-Dstrchr=index" \ ! "-DEDITORCMD" CFLAGS = $(OPTIM) $(DEFS) *** man.c.org Sun Sep 25 21:05:27 1983 --- man.c Sun Jul 14 20:53:04 1985 *************** *** 276,281 char *cp; { char cmd[BUFSIZ]; if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); --- 273,280 ----- char *cp; { char cmd[BUFSIZ]; + /* dyt */ + char *pager, *getenv(); pager = getenv("MANPAGER"); if (pager == NULL || *pager == 0) { *************** *** 277,282 { char cmd[BUFSIZ]; if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); else --- 276,287 ----- /* dyt */ char *pager, *getenv(); + pager = getenv("MANPAGER"); + if (pager == NULL || *pager == 0) { + pager = getenv("PAGER"); + if (pager == NULL || *pager == 0) + pager = MORE; + } if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : pager, cp); else *************** *** 278,284 char cmd[BUFSIZ]; if (cp[0] == 'c') ! sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); else sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, MORE); system(cmd); --- 283,289 ----- pager = MORE; } if (cp[0] == 'c') ! sprintf(cmd, "%s %s", nomore? CAT : pager, cp); else sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, pager); system(cmd); *************** *** 280,286 if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : MORE, cp); else ! sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, MORE); system(cmd); } --- 285,291 ----- if (cp[0] == 'c') sprintf(cmd, "%s %s", nomore? CAT : pager, cp); else ! sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, pager); system(cmd); }
dan@rna.UUCP (Dan Ts'o) (07/22/85)
x Here are diffs to help.c of less to make it conform to the mods just posted. *** help.c.org Mon Jul 22 14:19:20 1985 --- help.c Mon Jul 22 14:45:07 1985 *************** *** 7,14 static void help0() { ! puts("f, SPACE Forward one screen.\n"); ! puts("b Backward one screen.\n"); puts("e, j, CR * Forward N lines, default 1.\n"); puts("y, k * Backward N lines, default 1.\n"); puts("d * Forward N lines, default 10 or last N to d or u command.\n"); --- 7,17 ----- static void help0() { ! puts("f, SP, ^F, ^V Forward one screen.\n"); ! puts("b, ^B Backward one screen.\n"); ! #ifdef EDITORCMD ! puts("j, CR * Forward N lines, default 1.\n"); ! #else puts("e, j, CR * Forward N lines, default 1.\n"); #endif puts("y, k * Backward N lines, default 1.\n"); *************** *** 10,15 puts("f, SPACE Forward one screen.\n"); puts("b Backward one screen.\n"); puts("e, j, CR * Forward N lines, default 1.\n"); puts("y, k * Backward N lines, default 1.\n"); puts("d * Forward N lines, default 10 or last N to d or u command.\n"); puts("u * Backward N lines, default 10 or last N to d or u command.\n"); --- 13,19 ----- puts("j, CR * Forward N lines, default 1.\n"); #else puts("e, j, CR * Forward N lines, default 1.\n"); + #endif puts("y, k * Backward N lines, default 1.\n"); puts("d, ^U * Forward N lines, default 10 or last N to d or u command.\n"); puts("u, ^U * Backward N lines, default 10 or last N to d or u command.\n"); *************** *** 11,18 puts("b Backward one screen.\n"); puts("e, j, CR * Forward N lines, default 1.\n"); puts("y, k * Backward N lines, default 1.\n"); ! puts("d * Forward N lines, default 10 or last N to d or u command.\n"); ! puts("u * Backward N lines, default 10 or last N to d or u command.\n"); puts("r Repaint screen.\n"); puts("g * Go to line N, default 1.\n"); puts("G * Like g, but default is last line in file.\n"); --- 15,22 ----- puts("e, j, CR * Forward N lines, default 1.\n"); #endif puts("y, k * Backward N lines, default 1.\n"); ! puts("d, ^U * Forward N lines, default 10 or last N to d or u command.\n"); ! puts("u, ^U * Backward N lines, default 10 or last N to d or u command.\n"); puts("r Repaint screen.\n"); puts("g * Go to line N, default 1.\n"); puts("G * Like g, but default is last line in file.\n"); *************** *** 33,38 puts("E [file] Examine a new file.\n"); puts("N Examine the next file (from the command line).\n"); puts("P Examine the previous file (from the command line).\n"); puts("v Print version number.\n"); error(""); } --- 37,46 ----- puts("E [file] Examine a new file.\n"); puts("N Examine the next file (from the command line).\n"); puts("P Examine the previous file (from the command line).\n"); + #ifdef EDITORCMD + puts("V Print version number.\n"); + puts("e, v Invoke $EDITOR.\n"); + #else puts("v Print version number.\n"); #endif error(""); *************** *** 34,39 puts("N Examine the next file (from the command line).\n"); puts("P Examine the previous file (from the command line).\n"); puts("v Print version number.\n"); error(""); } --- 42,48 ----- puts("e, v Invoke $EDITOR.\n"); #else puts("v Print version number.\n"); + #endif error(""); }