=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/command.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.2 diff -c -r1.1.1.1 -r1.1.1.2 *** src/usr.bin/less/command.c 1996/09/21 05:39:42 1.1.1.1 --- src/usr.bin/less/command.c 2003/04/13 18:21:21 1.1.1.2 *************** *** 1,27 **** /* ! * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman ! * All rights reserved. * ! * Redistribution and use in source and binary forms, with or without ! * modification, are permitted provided that the following conditions ! * are met: ! * 1. Redistributions of source code must retain the above copyright ! * notice, this list of conditions and the following disclaimer. ! * 2. Redistributions in binary form must reproduce the above copyright ! * notice in the documentation and/or other materials provided with ! * the distribution. * ! * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY ! * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ! * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE ! * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ! * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT ! * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ! * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ! * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE ! * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN ! * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ --- 1,11 ---- /* ! * Copyright (C) 1984-2002 Mark Nudelman * ! * You may distribute under the terms of either the GNU General Public ! * License or the Less License, as specified in the README file. * ! * For more information about less, or for information on how to ! * contact the author, see the README file. */ *************** *** 30,35 **** --- 14,22 ---- */ #include "less.h" + #if MSDOS_COMPILER==WIN32C + #include + #endif #include "position.h" #include "option.h" #include "cmd.h" *************** *** 37,42 **** --- 24,31 ---- extern int erase_char, kill_char; extern int sigs; extern int quit_at_eof; + extern int quit_if_one_screen; + extern int squished; extern int hit_eof; extern int sc_width; extern int sc_height; *************** *** 44,85 **** extern int jump_sline; extern int quitting; extern int wscroll; - extern int nohelp; extern int top_scroll; extern int ignore_eoi; extern char *every_first_cmd; extern char *curr_altfilename; extern char version[]; extern struct scrpos initial_scrpos; extern IFILE curr_ifile; ! #if CMD_HISTORY ! extern void *ml_search; ! extern void *ml_examine; #if SHELL_ESCAPE || PIPEC ! extern void *ml_shell; #endif - #else - /* No CMD_HISTORY */ - #define ml_search NULL - #define ml_examine NULL - #define ml_shell NULL - #endif #if EDITOR extern char *editor; extern char *editproto; #endif extern int screen_trashed; /* The screen has been overwritten */ ! static char ungot[100]; static char *ungotp = NULL; #if SHELL_ESCAPE static char *shellcmd = NULL; /* For holding last shell command for "!!" */ #endif static int mca; /* The multicharacter command (action) */ static int search_type; /* The previous type of search */ ! static int number; /* The number typed by the user */ static char optchar; static int optflag; #if PIPEC static char pipec; #endif --- 33,72 ---- extern int jump_sline; extern int quitting; extern int wscroll; extern int top_scroll; extern int ignore_eoi; + extern int secure; + extern int hshift; + extern int show_attn; extern char *every_first_cmd; extern char *curr_altfilename; extern char version[]; extern struct scrpos initial_scrpos; extern IFILE curr_ifile; ! extern void constant *ml_search; ! extern void constant *ml_examine; #if SHELL_ESCAPE || PIPEC ! extern void constant *ml_shell; #endif #if EDITOR extern char *editor; extern char *editproto; #endif extern int screen_trashed; /* The screen has been overwritten */ + extern int shift_count; ! static char ungot[UNGOT_SIZE]; static char *ungotp = NULL; #if SHELL_ESCAPE static char *shellcmd = NULL; /* For holding last shell command for "!!" */ #endif static int mca; /* The multicharacter command (action) */ static int search_type; /* The previous type of search */ ! static LINENUM number; /* The number typed by the user */ static char optchar; static int optflag; + static int optgetname; + static POSITION bottompos; #if PIPEC static char pipec; #endif *************** *** 94,99 **** --- 81,87 ---- static void cmd_exec() { + clear_attn(); lower_left(); flush(); } *************** *** 102,118 **** * Set up the display to start a new multi-character command. */ static void ! start_mca(action, prompt, mlist) int action; char *prompt; void *mlist; { mca = action; ! clear_bot(); cmd_putstr(prompt); ! #if CMD_HISTORY ! set_mlist(mlist); ! #endif } public int --- 90,105 ---- * Set up the display to start a new multi-character command. */ static void ! start_mca(action, prompt, mlist, cmdflags) int action; char *prompt; void *mlist; + int cmdflags; { mca = action; ! clear_cmd(); cmd_putstr(prompt); ! set_mlist(mlist, cmdflags); } public int *************** *** 132,158 **** else mca = A_B_SEARCH; ! clear_bot(); if (search_type & SRCH_FIRST_FILE) ! cmd_putstr("@"); ! if (search_type & SRCH_PAST_EOF) ! cmd_putstr("*"); - if (search_type & SRCH_NOMATCH) - cmd_putstr("!"); - if (search_type & SRCH_FORW) cmd_putstr("/"); else cmd_putstr("?"); ! #if CMD_HISTORY ! set_mlist(ml_search); ! #endif } /* * Execute a multicharacter command. */ static void --- 119,178 ---- else mca = A_B_SEARCH; ! clear_cmd(); + if (search_type & SRCH_NO_MATCH) + cmd_putstr("Non-match "); if (search_type & SRCH_FIRST_FILE) ! cmd_putstr("First-file "); if (search_type & SRCH_PAST_EOF) ! cmd_putstr("EOF-ignore "); ! if (search_type & SRCH_NO_MOVE) ! cmd_putstr("Keep-pos "); ! if (search_type & SRCH_NO_REGEX) ! cmd_putstr("Regex-off "); if (search_type & SRCH_FORW) cmd_putstr("/"); else cmd_putstr("?"); ! set_mlist(ml_search, 0); } /* + * Set up the display to start a new toggle-option command. + */ + static void + mca_opt_toggle() + { + int no_prompt; + int flag; + char *dash; + + no_prompt = (optflag & OPT_NO_PROMPT); + flag = (optflag & ~OPT_NO_PROMPT); + dash = (flag == OPT_NO_TOGGLE) ? "_" : "-"; + + mca = A_OPT_TOGGLE; + clear_cmd(); + cmd_putstr(dash); + if (optgetname) + cmd_putstr(dash); + if (no_prompt) + cmd_putstr("(P)"); + switch (flag) + { + case OPT_UNSET: + cmd_putstr("+"); + break; + case OPT_SET: + cmd_putstr("!"); + break; + } + set_mlist(NULL, 0); + } + + /* * Execute a multicharacter command. */ static void *************** *** 167,173 **** { case A_F_SEARCH: case A_B_SEARCH: ! multi_search(cbuf, number); break; case A_FIRSTCMD: /* --- 187,193 ---- { case A_F_SEARCH: case A_B_SEARCH: ! multi_search(cbuf, (int) number); break; case A_FIRSTCMD: /* *************** *** 187,200 **** optchar = '\0'; break; case A_F_BRACKET: ! match_brac(cbuf[0], cbuf[1], 1, number); break; case A_B_BRACKET: ! match_brac(cbuf[1], cbuf[0], 0, number); break; #if EXAMINE case A_EXAMINE: edit_list(cbuf); break; #endif #if SHELL_ESCAPE --- 207,226 ---- optchar = '\0'; break; case A_F_BRACKET: ! match_brac(cbuf[0], cbuf[1], 1, (int) number); break; case A_B_BRACKET: ! match_brac(cbuf[1], cbuf[0], 0, (int) number); break; #if EXAMINE case A_EXAMINE: + if (secure) + break; edit_list(cbuf); + #if TAGS + /* If tag structure is loaded then clean it up. */ + cleantags(); + #endif break; #endif #if SHELL_ESCAPE *************** *** 211,225 **** shellcmd = fexpand(cbuf); } if (shellcmd == NULL) ! lsystem(""); else ! lsystem(shellcmd); ! error("!done", NULL_PARG); break; #endif #if PIPEC case A_PIPE: (void) pipe_mark(pipec, cbuf); error("|done", NULL_PARG); break; --- 237,254 ---- shellcmd = fexpand(cbuf); } + if (secure) + break; if (shellcmd == NULL) ! lsystem("", "!done"); else ! lsystem(shellcmd, "!done"); break; #endif #if PIPEC case A_PIPE: + if (secure) + break; (void) pipe_mark(pipec, cbuf); error("|done", NULL_PARG); break; *************** *** 237,242 **** --- 266,272 ---- char *p; int flag; char buf[3]; + PARG parg; switch (mca) { *************** *** 261,267 **** * Terminated by a non-digit. */ if ((c < '0' || c > '9') && ! editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE) == A_INVALID) { /* * Not part of the number. --- 291,297 ---- * Terminated by a non-digit. */ if ((c < '0' || c > '9') && ! editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID) { /* * Not part of the number. *************** *** 282,316 **** * so user doesn't have to hit RETURN. * If the first char is + or -, this indicates * OPT_UNSET or OPT_SET respectively, instead of OPT_TOGGLE. */ ! if (c == erase_char || c == kill_char) ! break; ! if (optchar != '\0' && optchar != '+' && optchar != '-') /* ! * We already have the option letter. */ ! break; ! switch (c) ! { ! case '+': ! optflag = OPT_UNSET; ! break; ! case '-': ! optflag = OPT_SET; ! break; ! default: ! optchar = c; ! if (optflag != OPT_TOGGLE || single_char_option(c)) { ! toggle_option(c, "", optflag); ! return (MCA_DONE); } ! break; } ! if (optchar == '+' || optchar == '-') { ! optchar = c; ! break; } /* * Display a prompt appropriate for the option letter. --- 312,448 ---- * so user doesn't have to hit RETURN. * If the first char is + or -, this indicates * OPT_UNSET or OPT_SET respectively, instead of OPT_TOGGLE. + * "--" begins inputting a long option name. */ ! if (optchar == '\0' && len_cmdbuf() == 0) ! { ! flag = (optflag & ~OPT_NO_PROMPT); ! if (flag == OPT_NO_TOGGLE) ! { ! switch (c) ! { ! case '_': ! /* "__" = long option name. */ ! optgetname = TRUE; ! mca_opt_toggle(); ! return (MCA_MORE); ! } ! } else ! { ! switch (c) ! { ! case '+': ! /* "-+" = UNSET. */ ! optflag = (flag == OPT_UNSET) ? ! OPT_TOGGLE : OPT_UNSET; ! mca_opt_toggle(); ! return (MCA_MORE); ! case '!': ! /* "-!" = SET */ ! optflag = (flag == OPT_SET) ? ! OPT_TOGGLE : OPT_SET; ! mca_opt_toggle(); ! return (MCA_MORE); ! case CONTROL('P'): ! optflag ^= OPT_NO_PROMPT; ! mca_opt_toggle(); ! return (MCA_MORE); ! case '-': ! /* "--" = long option name. */ ! optgetname = TRUE; ! mca_opt_toggle(); ! return (MCA_MORE); ! } ! } ! } ! if (optgetname) ! { /* ! * We're getting a long option name. ! * See if we've matched an option name yet. ! * If so, display the complete name and stop ! * accepting chars until user hits RETURN. */ ! struct loption *o; ! char *oname; ! int lc; ! ! if (c == '\n' || c == '\r') { ! /* ! * When the user hits RETURN, make sure ! * we've matched an option name, then ! * pretend he just entered the equivalent ! * option letter. ! */ ! if (optchar == '\0') ! { ! parg.p_string = get_cmdbuf(); ! error("There is no --%s option", &parg); ! return (MCA_DONE); ! } ! optgetname = FALSE; ! cmd_reset(); ! c = optchar; ! } else ! { ! if (optchar != '\0') ! { ! /* ! * Already have a match for the name. ! * Don't accept anything but erase/kill. ! */ ! if (c == erase_char || c == kill_char) ! return (MCA_DONE); ! return (MCA_MORE); ! } ! /* ! * Add char to cmd buffer and try to match ! * the option name. ! */ ! if (cmd_char(c) == CC_QUIT) ! return (MCA_DONE); ! p = get_cmdbuf(); ! lc = islower(p[0]); ! o = findopt_name(&p, &oname, NULL); ! if (o != NULL) ! { ! /* ! * Got a match. ! * Remember the option letter and ! * display the full option name. ! */ ! optchar = o->oletter; ! if (!lc && islower(optchar)) ! optchar = toupper(optchar); ! cmd_reset(); ! mca_opt_toggle(); ! for (p = oname; *p != '\0'; p++) ! { ! c = *p; ! if (!lc && islower(c)) ! c = toupper(c); ! if (cmd_char(c) != CC_OK) ! return (MCA_DONE); ! } ! } ! return (MCA_MORE); } ! } else ! { ! if (c == erase_char || c == kill_char) ! break; ! if (optchar != '\0') ! /* We already have the option letter. */ ! break; } ! ! optchar = c; ! if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE || ! single_char_option(c)) { ! toggle_option(c, "", optflag); ! return (MCA_DONE); } /* * Display a prompt appropriate for the option letter. *************** *** 322,328 **** buf[2] = '\0'; p = buf; } ! start_mca(A_OPT_TOGGLE, p, (void*)NULL); return (MCA_MORE); case A_F_SEARCH: --- 454,460 ---- buf[2] = '\0'; p = buf; } ! start_mca(A_OPT_TOGGLE, p, (void*)NULL, 0); return (MCA_MORE); case A_F_SEARCH: *************** *** 331,337 **** * Special case for search commands. * Certain characters as the first char of * the pattern have special meaning: ! * ! Toggle the NOMATCH flag * * Toggle the PAST_EOF flag * @ Toggle the FIRST_FILE flag */ --- 463,469 ---- * Special case for search commands. * Certain characters as the first char of * the pattern have special meaning: ! * ! Toggle the NO_MATCH flag * * Toggle the PAST_EOF flag * @ Toggle the FIRST_FILE flag */ *************** *** 344,358 **** flag = 0; switch (c) { ! case '!': ! flag = SRCH_NOMATCH; break; case '@': flag = SRCH_FIRST_FILE; break; ! case '*': ! flag = SRCH_PAST_EOF; break; } if (flag != 0) { --- 476,499 ---- flag = 0; switch (c) { ! case CONTROL('E'): /* ignore END of file */ ! case '*': ! flag = SRCH_PAST_EOF; break; + case CONTROL('F'): /* FIRST file */ case '@': flag = SRCH_FIRST_FILE; break; ! case CONTROL('K'): /* KEEP position */ ! flag = SRCH_NO_MOVE; break; + case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */ + flag = SRCH_NO_REGEX; + break; + case CONTROL('N'): /* NOT match */ + case '!': + flag = SRCH_NO_MATCH; + break; } if (flag != 0) { *************** *** 375,380 **** --- 516,522 ---- exec_mca(); return (MCA_DONE); } + /* * Append the char to the command buffer. */ *************** *** 402,423 **** } /* ! * Display the appropriate prompt. */ static void ! prompt() { - register char *p; - - if (ungotp != NULL && ungotp > ungot) - { - /* - * No prompt necessary if commands are from - * ungotten chars rather than from the user. - */ - return; - } - /* * If nothing is displayed yet, display starting from initial_scrpos. */ --- 544,554 ---- } /* ! * Make sure the screen is displayed. */ static void ! make_display() { /* * If nothing is displayed yet, display starting from initial_scrpos. */ *************** *** 441,458 **** repaint(); top_scroll = save_top_scroll; } /* * If the -E flag is set and we've hit EOF on the last file, quit. */ ! if (quit_at_eof == OPT_ONPLUS && hit_eof && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); /* * Select the proper prompt and display it. */ ! clear_bot(); p = pr_string(); if (p == NULL) putchr(':'); --- 572,631 ---- repaint(); top_scroll = save_top_scroll; } + } + /* + * Display the appropriate prompt. + */ + static void + prompt() + { + register char *p; + + if (ungotp != NULL && ungotp > ungot) + { + /* + * No prompt necessary if commands are from + * ungotten chars rather than from the user. + */ + return; + } + /* + * Make sure the screen is displayed. + */ + make_display(); + bottompos = position(BOTTOM_PLUS_ONE); + + /* * If the -E flag is set and we've hit EOF on the last file, quit. */ ! if ((quit_at_eof == OPT_ONPLUS || quit_if_one_screen) && ! hit_eof && !(ch_getflags() & CH_HELPFILE) && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); + quit_if_one_screen = FALSE; + #if 0 /* This doesn't work well because some "te"s clear the screen. */ + /* + * If the -e flag is set and we've hit EOF on the last file, + * and the file is squished (shorter than the screen), quit. + */ + if (quit_at_eof && squished && + next_ifile(curr_ifile) == NULL_IFILE) + quit(QUIT_OK); + #endif + #if MSDOS_COMPILER==WIN32C + /* + * In Win32, display the file name in the window title. + */ + if (!(ch_getflags() & CH_HELPFILE)) + SetConsoleTitle(pr_expand("Less?f - %f.", 0)); + #endif /* * Select the proper prompt and display it. */ ! clear_cmd(); p = pr_string(); if (p == NULL) putchr(':'); *************** *** 464,476 **** } } public void dispversion() { PARG parg; parg.p_string = version; ! error("less version %s", &parg); } /* --- 637,652 ---- } } + /* + * Display the less version message. + */ public void dispversion() { PARG parg; parg.p_string = version; ! error("less %s", &parg); } /* *************** *** 573,579 **** int changed_file; changed_file = 0; ! save_ifile = curr_ifile; if (search_type & SRCH_FIRST_FILE) { --- 749,755 ---- int changed_file; changed_file = 0; ! save_ifile = save_curr_ifile(); if (search_type & SRCH_FIRST_FILE) { *************** *** 586,603 **** else nomore = edit_last(); if (nomore) return; changed_file = 1; search_type &= ~SRCH_FIRST_FILE; } for (;;) { ! if ((n = search(search_type, pattern, n)) == 0) /* * Found it. */ return; if (n < 0) /* --- 762,792 ---- else nomore = edit_last(); if (nomore) + { + unsave_ifile(save_ifile); return; + } changed_file = 1; search_type &= ~SRCH_FIRST_FILE; } for (;;) { ! n = search(search_type, pattern, n); ! /* ! * The SRCH_NO_MOVE flag doesn't "stick": it gets cleared ! * after being used once. This allows "n" to work after ! * using a /@@ search. ! */ ! search_type &= ~SRCH_NO_MOVE; ! if (n == 0) ! { /* * Found it. */ + unsave_ifile(save_ifile); return; + } if (n < 0) /* *************** *** 636,643 **** /* * Restore the file we were originally viewing. */ ! if (edit_ifile(save_ifile)) ! quit(QUIT_ERROR); } } --- 825,831 ---- /* * Restore the file we were originally viewing. */ ! reedit_ifile(save_ifile); } } *************** *** 651,663 **** register int c; register int action; register char *cbuf; int save_search_type; ! char *s; char tbuf[2]; PARG parg; search_type = SRCH_FORW; wscroll = (sc_height + 1) / 2; for (;;) { --- 839,856 ---- register int c; register int action; register char *cbuf; + int newaction; int save_search_type; ! char *extra; char tbuf[2]; PARG parg; + IFILE old_ifile; + IFILE new_ifile; + char *tagfile; search_type = SRCH_FORW; wscroll = (sc_height + 1) / 2; + newaction = A_NOACTION; for (;;) { *************** *** 675,760 **** if (quitting) quit(QUIT_SAVED_STATUS); } ! /* * Display prompt and accept a character. */ cmd_reset(); prompt(); if (sigs) continue; ! c = getcc(); again: if (sigs) continue; ! /* ! * If we are in a multicharacter command, call mca_char. ! * Otherwise we call fcmd_decode to determine the ! * action to be performed. ! */ ! if (mca) ! switch (mca_char(c)) { - case MCA_MORE: /* ! * Need another character. */ ! c = getcc(); ! goto again; ! case MCA_DONE: /* ! * Command has been handled by mca_char. ! * Start clean with a prompt. */ ! continue; ! case NO_MCA: ! /* ! * Not a multi-char command ! * (at least, not anymore). ! */ ! break; } ! ! /* ! * Decode the command character and decide what to do. ! */ ! if (mca) ! { /* ! * We're in a multichar command. ! * Add the character to the command buffer ! * and display it on the screen. ! * If the user backspaces past the start ! * of the line, abort the command. */ ! if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0) ! continue; ! cbuf = get_cmdbuf(); ! } else ! { ! /* ! * Don't use cmd_char if we're starting fresh ! * at the beginning of a command, because we ! * don't want to echo the command until we know ! * it is a multichar command. We also don't ! * want erase_char/kill_char to be treated ! * as line editing characters. ! */ ! tbuf[0] = c; ! tbuf[1] = '\0'; ! cbuf = tbuf; } - s = NULL; - action = fcmd_decode(cbuf, &s); /* - * If an "extra" string was returned, - * process it as a string of command characters. - */ - if (s != NULL) - ungetsc(s); - /* * Clear the cmdbuf string. * (But not if we're in the prefix of a command, * because the partial command string is kept there.) --- 868,967 ---- if (quitting) quit(QUIT_SAVED_STATUS); } ! /* + * See if window size changed, for systems that don't + * generate SIGWINCH. + */ + check_winch(); + + /* * Display prompt and accept a character. */ cmd_reset(); prompt(); if (sigs) continue; ! if (newaction == A_NOACTION) ! c = getcc(); again: if (sigs) continue; ! if (newaction != A_NOACTION) ! { ! action = newaction; ! newaction = A_NOACTION; ! } else ! { ! /* ! * If we are in a multicharacter command, call mca_char. ! * Otherwise we call fcmd_decode to determine the ! * action to be performed. ! */ ! if (mca) ! switch (mca_char(c)) ! { ! case MCA_MORE: ! /* ! * Need another character. ! */ ! c = getcc(); ! goto again; ! case MCA_DONE: ! /* ! * Command has been handled by mca_char. ! * Start clean with a prompt. ! */ ! continue; ! case NO_MCA: ! /* ! * Not a multi-char command ! * (at least, not anymore). ! */ ! break; ! } ! ! /* ! * Decode the command character and decide what to do. ! */ ! if (mca) { /* ! * We're in a multichar command. ! * Add the character to the command buffer ! * and display it on the screen. ! * If the user backspaces past the start ! * of the line, abort the command. */ ! if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0) ! continue; ! cbuf = get_cmdbuf(); ! } else ! { /* ! * Don't use cmd_char if we're starting fresh ! * at the beginning of a command, because we ! * don't want to echo the command until we know ! * it is a multichar command. We also don't ! * want erase_char/kill_char to be treated ! * as line editing characters. */ ! tbuf[0] = c; ! tbuf[1] = '\0'; ! cbuf = tbuf; } ! extra = NULL; ! action = fcmd_decode(cbuf, &extra); /* ! * If an "extra" string was returned, ! * process it as a string of command characters. */ ! if (extra != NULL) ! ungetsc(extra); } /* * Clear the cmdbuf string. * (But not if we're in the prefix of a command, * because the partial command string is kept there.) *************** *** 768,774 **** /* * First digit of a number. */ ! start_mca(A_DIGIT, ":", (void*)NULL); goto again; case A_F_WINDOW: --- 975,981 ---- /* * First digit of a number. */ ! start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE); goto again; case A_F_WINDOW: *************** *** 776,782 **** * Forward one window (and set the window size). */ if (number > 0) ! swindow = number; /* FALLTHRU */ case A_F_SCREEN: /* --- 983,989 ---- * Forward one window (and set the window size). */ if (number > 0) ! swindow = (int) number; /* FALLTHRU */ case A_F_SCREEN: /* *************** *** 785,791 **** if (number <= 0) number = get_swindow(); cmd_exec(); ! forward(number, 0, 1); break; case A_B_WINDOW: --- 992,1000 ---- if (number <= 0) number = get_swindow(); cmd_exec(); ! if (show_attn) ! set_attnpos(bottompos); ! forward((int) number, 0, 1); break; case A_B_WINDOW: *************** *** 793,799 **** * Backward one window (and set the window size). */ if (number > 0) ! swindow = number; /* FALLTHRU */ case A_B_SCREEN: /* --- 1002,1008 ---- * Backward one window (and set the window size). */ if (number > 0) ! swindow = (int) number; /* FALLTHRU */ case A_B_SCREEN: /* *************** *** 802,808 **** if (number <= 0) number = get_swindow(); cmd_exec(); ! backward(number, 0, 1); break; case A_F_LINE: --- 1011,1017 ---- if (number <= 0) number = get_swindow(); cmd_exec(); ! backward((int) number, 0, 1); break; case A_F_LINE: *************** *** 812,818 **** if (number <= 0) number = 1; cmd_exec(); ! forward(number, 0, 0); break; case A_B_LINE: --- 1021,1029 ---- if (number <= 0) number = 1; cmd_exec(); ! if (show_attn == OPT_ONPLUS && number > 1) ! set_attnpos(bottompos); ! forward((int) number, 0, 0); break; case A_B_LINE: *************** *** 822,828 **** if (number <= 0) number = 1; cmd_exec(); ! backward(number, 0, 0); break; case A_FF_LINE: --- 1033,1039 ---- if (number <= 0) number = 1; cmd_exec(); ! backward((int) number, 0, 0); break; case A_FF_LINE: *************** *** 832,838 **** if (number <= 0) number = 1; cmd_exec(); ! forward(number, 1, 0); break; case A_BF_LINE: --- 1043,1051 ---- if (number <= 0) number = 1; cmd_exec(); ! if (show_attn == OPT_ONPLUS && number > 1) ! set_attnpos(bottompos); ! forward((int) number, 1, 0); break; case A_BF_LINE: *************** *** 842,861 **** if (number <= 0) number = 1; cmd_exec(); ! backward(number, 1, 0); break; case A_F_FOREVER: /* * Forward forever, ignoring EOF. */ cmd_exec(); jump_forw(); ignore_eoi = 1; hit_eof = 0; ! while (!ABORT_SIGS()) forward(1, 0, 0); ignore_eoi = 0; break; case A_F_SCROLL: --- 1055,1094 ---- if (number <= 0) number = 1; cmd_exec(); ! backward((int) number, 1, 0); break; + case A_FF_SCREEN: + /* + * Force forward one screen. + */ + if (number <= 0) + number = get_swindow(); + cmd_exec(); + if (show_attn == OPT_ONPLUS) + set_attnpos(bottompos); + forward((int) number, 1, 0); + break; + case A_F_FOREVER: /* * Forward forever, ignoring EOF. */ + if (ch_getflags() & CH_HELPFILE) + break; cmd_exec(); jump_forw(); ignore_eoi = 1; hit_eof = 0; ! while (!sigs) forward(1, 0, 0); ignore_eoi = 0; + /* + * This gets us back in "F mode" after processing + * a non-abort signal (e.g. window-change). + */ + if (sigs && !ABORT_SIGS()) + newaction = A_F_FOREVER; break; case A_F_SCROLL: *************** *** 864,871 **** * (default same as last 'd' or 'u' command). */ if (number > 0) ! wscroll = number; cmd_exec(); forward(wscroll, 0, 0); break; --- 1097,1106 ---- * (default same as last 'd' or 'u' command). */ if (number > 0) ! wscroll = (int) number; cmd_exec(); + if (show_attn == OPT_ONPLUS) + set_attnpos(bottompos); forward(wscroll, 0, 0); break; *************** *** 875,881 **** * (default same as last 'd' or 'u' command). */ if (number > 0) ! wscroll = number; cmd_exec(); backward(wscroll, 0, 0); break; --- 1110,1116 ---- * (default same as last 'd' or 'u' command). */ if (number > 0) ! wscroll = (int) number; cmd_exec(); backward(wscroll, 0, 0); break; *************** *** 889,894 **** --- 1124,1132 ---- { ch_flush(); clr_linenum(); + #if HILITE_SEARCH + clr_hilite(); + #endif } /* FALLTHRU */ case A_REPAINT: *************** *** 918,924 **** if (number > 100) number = 100; cmd_exec(); ! jump_percent(number); break; case A_GOEND: --- 1156,1162 ---- if (number > 100) number = 100; cmd_exec(); ! jump_percent((int) number); break; case A_GOEND: *************** *** 939,956 **** cmd_exec(); if (number < 0) number = 0; ! jump_line_loc((POSITION)number, jump_sline); break; case A_STAT: /* * Print file name, etc. */ cmd_exec(); parg.p_string = eq_message(); error("%s", &parg); break; ! case A_VERSION: /* * Print version number, without the "@(#)". --- 1177,1196 ---- cmd_exec(); if (number < 0) number = 0; ! jump_line_loc((POSITION) number, jump_sline); break; case A_STAT: /* * Print file name, etc. */ + if (ch_getflags() & CH_HELPFILE) + break; cmd_exec(); parg.p_string = eq_message(); error("%s", &parg); break; ! case A_VERSION: /* * Print version number, without the "@(#)". *************** *** 963,969 **** --- 1203,1223 ---- /* * Exit. */ + if (curr_ifile != NULL_IFILE && + ch_getflags() & CH_HELPFILE) + { + /* + * Quit while viewing the help file + * just means return to viewing the + * previous file. + */ + if (edit_prev(1) == 0) + break; + } + if (extra != NULL) + quit(*extra); quit(QUIT_OK); + break; /* * Define abbreviation for a commonly used sequence below. *************** *** 971,977 **** #define DO_SEARCH() if (number <= 0) number = 1; \ mca_search(); \ cmd_exec(); \ ! multi_search((char *)NULL, number); case A_F_SEARCH: --- 1225,1231 ---- #define DO_SEARCH() if (number <= 0) number = 1; \ mca_search(); \ cmd_exec(); \ ! multi_search((char *)NULL, (int) number); case A_F_SEARCH: *************** *** 1043,1057 **** /* * Help. */ ! if (nohelp) ! { ! bell(); break; - } - clear_bot(); - putstr(" help"); cmd_exec(); ! help(0); break; case A_EXAMINE: --- 1297,1306 ---- /* * Help. */ ! if (ch_getflags() & CH_HELPFILE) break; cmd_exec(); ! (void) edit(FAKE_HELPFILE); break; case A_EXAMINE: *************** *** 1059,1065 **** /* * Edit a new file. Get the filename. */ ! start_mca(A_EXAMINE, "Examine: ", ml_examine); c = getcc(); goto again; #else --- 1308,1319 ---- /* * Edit a new file. Get the filename. */ ! if (secure) ! { ! error("Command not available", NULL_PARG); ! break; ! } ! start_mca(A_EXAMINE, "Examine: ", ml_examine, 0); c = getcc(); goto again; #else *************** *** 1072,1077 **** --- 1326,1338 ---- * Invoke an editor on the input file. */ #if EDITOR + if (secure) + { + error("Command not available", NULL_PARG); + break; + } + if (ch_getflags() & CH_HELPFILE) + break; if (strcmp(get_filename(curr_ifile), "-") == 0) { error("Cannot edit standard input", NULL_PARG); *************** *** 1083,1101 **** NULL_PARG); break; } /* * Expand the editor prototype string * and pass it to the system to execute. */ cmd_exec(); ! lsystem(pr_expand(editproto, 0)); ! /* ! * Re-edit the file, since data may have changed. ! * Some editors even recreate the file, so flushing ! * buffers is not sufficient. ! */ ! if (edit_ifile(curr_ifile)) ! quit(QUIT_ERROR); break; #else error("Command not available", NULL_PARG); --- 1344,1359 ---- NULL_PARG); break; } + start_mca(A_SHELL, "!", ml_shell, 0); /* * Expand the editor prototype string * and pass it to the system to execute. + * (Make sure the screen is displayed so the + * expansion of "+%lm" works.) */ + make_display(); cmd_exec(); ! lsystem(pr_expand(editproto, 0), (char*)NULL); break; #else error("Command not available", NULL_PARG); *************** *** 1106,1116 **** /* * Examine next file. */ if (number <= 0) number = 1; ! if (edit_next(number)) { ! if (quit_at_eof && hit_eof) quit(QUIT_OK); parg.p_string = (number > 1) ? "(N-th) " : ""; error("No %snext file", &parg); --- 1364,1382 ---- /* * Examine next file. */ + #if TAGS + if (ntags()) + { + error("No next file", NULL_PARG); + break; + } + #endif if (number <= 0) number = 1; ! if (edit_next((int) number)) { ! if (quit_at_eof && hit_eof && ! !(ch_getflags() & CH_HELPFILE)) quit(QUIT_OK); parg.p_string = (number > 1) ? "(N-th) " : ""; error("No %snext file", &parg); *************** *** 1121,1148 **** /* * Examine previous file. */ if (number <= 0) number = 1; ! if (edit_prev(number)) { parg.p_string = (number > 1) ? "(N-th) " : ""; error("No %sprevious file", &parg); } break; case A_INDEX_FILE: /* * Examine a particular file. */ if (number <= 0) number = 1; ! if (edit_index(number)) error("No such file", NULL_PARG); break; case A_OPT_TOGGLE: - start_mca(A_OPT_TOGGLE, "-", (void*)NULL); optflag = OPT_TOGGLE; c = getcc(); goto again; --- 1387,1482 ---- /* * Examine previous file. */ + #if TAGS + if (ntags()) + { + error("No previous file", NULL_PARG); + break; + } + #endif if (number <= 0) number = 1; ! if (edit_prev((int) number)) { parg.p_string = (number > 1) ? "(N-th) " : ""; error("No %sprevious file", &parg); } break; + case A_NEXT_TAG: + #if TAGS + if (number <= 0) + number = 1; + tagfile = nexttag((int) number); + if (tagfile == NULL) + { + error("No next tag", NULL_PARG); + break; + } + if (edit(tagfile) == 0) + { + POSITION pos = tagsearch(); + if (pos != NULL_POSITION) + jump_loc(pos, jump_sline); + } + #else + error("Command not available", NULL_PARG); + #endif + break; + + case A_PREV_TAG: + #if TAGS + if (number <= 0) + number = 1; + tagfile = prevtag((int) number); + if (tagfile == NULL) + { + error("No previous tag", NULL_PARG); + break; + } + if (edit(tagfile) == 0) + { + POSITION pos = tagsearch(); + if (pos != NULL_POSITION) + jump_loc(pos, jump_sline); + } + #else + error("Command not available", NULL_PARG); + #endif + break; + case A_INDEX_FILE: /* * Examine a particular file. */ if (number <= 0) number = 1; ! if (edit_index((int) number)) error("No such file", NULL_PARG); break; + case A_REMOVE_FILE: + if (ch_getflags() & CH_HELPFILE) + break; + old_ifile = curr_ifile; + new_ifile = getoff_ifile(curr_ifile); + if (new_ifile == NULL_IFILE) + { + bell(); + break; + } + if (edit_ifile(new_ifile) != 0) + { + reedit_ifile(old_ifile); + break; + } + del_ifile(old_ifile); + break; + case A_OPT_TOGGLE: optflag = OPT_TOGGLE; + optgetname = FALSE; + mca_opt_toggle(); c = getcc(); goto again; *************** *** 1150,1167 **** /* * Report a flag setting. */ ! start_mca(A_DISP_OPTION, "_", (void*)NULL); c = getcc(); ! if (c == erase_char || c == kill_char) ! break; ! toggle_option(c, "", OPT_NO_TOGGLE); ! break; case A_FIRSTCMD: /* * Set an initial command for new files. */ ! start_mca(A_FIRSTCMD, "+", (void*)NULL); c = getcc(); goto again; --- 1484,1500 ---- /* * Report a flag setting. */ ! optflag = OPT_NO_TOGGLE; ! optgetname = FALSE; ! mca_opt_toggle(); c = getcc(); ! goto again; case A_FIRSTCMD: /* * Set an initial command for new files. */ ! start_mca(A_FIRSTCMD, "+", (void*)NULL, 0); c = getcc(); goto again; *************** *** 1170,1176 **** * Shell escape. */ #if SHELL_ESCAPE ! start_mca(A_SHELL, "!", ml_shell); c = getcc(); goto again; #else --- 1503,1514 ---- * Shell escape. */ #if SHELL_ESCAPE ! if (secure) ! { ! error("Command not available", NULL_PARG); ! break; ! } ! start_mca(A_SHELL, "!", ml_shell, 0); c = getcc(); goto again; #else *************** *** 1182,1188 **** /* * Set a mark. */ ! start_mca(A_SETMARK, "mark: ", (void*)NULL); c = getcc(); if (c == erase_char || c == kill_char || c == '\n' || c == '\r') --- 1520,1528 ---- /* * Set a mark. */ ! if (ch_getflags() & CH_HELPFILE) ! break; ! start_mca(A_SETMARK, "mark: ", (void*)NULL, 0); c = getcc(); if (c == erase_char || c == kill_char || c == '\n' || c == '\r') *************** *** 1194,1200 **** /* * Go to a mark. */ ! start_mca(A_GOMARK, "goto mark: ", (void*)NULL); c = getcc(); if (c == erase_char || c == kill_char || c == '\n' || c == '\r') --- 1534,1540 ---- /* * Go to a mark. */ ! start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0); c = getcc(); if (c == erase_char || c == kill_char || c == '\n' || c == '\r') *************** *** 1204,1210 **** case A_PIPE: #if PIPEC ! start_mca(A_PIPE, "|mark: ", (void*)NULL); c = getcc(); if (c == erase_char || c == kill_char) break; --- 1544,1555 ---- case A_PIPE: #if PIPEC ! if (secure) ! { ! error("Command not available", NULL_PARG); ! break; ! } ! start_mca(A_PIPE, "|mark: ", (void*)NULL, 0); c = getcc(); if (c == erase_char || c == kill_char) break; *************** *** 1213,1219 **** if (badmark(c)) break; pipec = c; ! start_mca(A_PIPE, "!", ml_shell); c = getcc(); goto again; #else --- 1558,1564 ---- if (badmark(c)) break; pipec = c; ! start_mca(A_PIPE, "!", ml_shell, 0); c = getcc(); goto again; #else *************** *** 1223,1232 **** case A_B_BRACKET: case A_F_BRACKET: ! start_mca(action, "Brackets: ", (void*)NULL); c = getcc(); goto again; case A_PREFIX: /* * The command is incomplete (more chars are needed). --- 1568,1599 ---- case A_B_BRACKET: case A_F_BRACKET: ! start_mca(action, "Brackets: ", (void*)NULL, 0); c = getcc(); goto again; + case A_LSHIFT: + if (number > 0) + shift_count = number; + else + number = (shift_count > 0) ? + shift_count : sc_width / 2; + if (number > hshift) + number = hshift; + hshift -= number; + screen_trashed = 1; + break; + + case A_RSHIFT: + if (number > 0) + shift_count = number; + else + number = (shift_count > 0) ? + shift_count : sc_width / 2; + hshift += number; + screen_trashed = 1; + break; + case A_PREFIX: /* * The command is incomplete (more chars are needed). *************** *** 1235,1242 **** */ if (mca != A_PREFIX) { - start_mca(A_PREFIX, " ", (void*)NULL); cmd_reset(); (void) cmd_char(c); } c = getcc(); --- 1602,1610 ---- */ if (mca != A_PREFIX) { cmd_reset(); + start_mca(A_PREFIX, " ", (void*)NULL, + CF_QUIT_ON_ERASE); (void) cmd_char(c); } c = getcc();