=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/command.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- src/usr.bin/less/command.c 2003/04/14 15:09:57 1.8 +++ src/usr.bin/less/command.c 2011/09/16 18:12:09 1.9 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2002 Mark Nudelman + * Copyright (C) 1984-2011 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. @@ -21,19 +21,16 @@ #include "option.h" #include "cmd.h" -extern int erase_char, kill_char; +extern int erase_char, erase2_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; extern int swindow; extern int jump_sline; extern int quitting; extern int wscroll; -extern int nohelp; extern int top_scroll; extern int ignore_eoi; extern int secure; @@ -55,37 +52,49 @@ #endif extern int screen_trashed; /* The screen has been overwritten */ extern int shift_count; +extern int oldbot; +extern int forw_prompt; extern int be_helpful; -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 long fraction; /* The fractional part of the number */ +static struct loption *curropt; +static int opt_lower; static int optflag; static int optgetname; static POSITION bottompos; +static int save_hshift; static char *help_prompt; #if PIPEC static char pipec; #endif +struct ungot { + struct ungot *ug_next; + char ug_char; +}; +static struct ungot* ungot = NULL; +static int unget_end = 0; + static void multi_search(); /* - * Move the cursor to lower left before executing a command. + * Move the cursor to start of prompt line before executing a command. * This looks nicer if the command takes a long time before * updating the screen. */ static void cmd_exec() { +#if HILITE_SEARCH clear_attn(); - lower_left(); +#endif + clear_bot(); flush(); } @@ -100,6 +109,7 @@ int cmdflags; { mca = action; + clear_bot(); clear_cmd(); cmd_putstr(prompt); set_mlist(mlist, cmdflags); @@ -117,11 +127,17 @@ static void mca_search() { +#if HILITE_SEARCH + if (search_type & SRCH_FILTER) + mca = A_FILTER; + else +#endif if (search_type & SRCH_FORW) mca = A_F_SEARCH; else mca = A_B_SEARCH; + clear_bot(); clear_cmd(); if (search_type & SRCH_NO_MATCH) @@ -135,6 +151,11 @@ if (search_type & SRCH_NO_REGEX) cmd_putstr("Regex-off "); +#if HILITE_SEARCH + if (search_type & SRCH_FILTER) + cmd_putstr("&/"); + else +#endif if (search_type & SRCH_FORW) cmd_putstr("/"); else @@ -157,6 +178,7 @@ dash = (flag == OPT_NO_TOGGLE) ? "_" : "-"; mca = A_OPT_TOGGLE; + clear_bot(); clear_cmd(); cmd_putstr(dash); #if GNU_OPTIONS @@ -194,6 +216,12 @@ case A_B_SEARCH: multi_search(cbuf, (int) number); break; +#if HILITE_SEARCH + case A_FILTER: + search_type ^= SRCH_NO_MATCH; + set_filter_pattern(cbuf, search_type); + break; +#endif case A_FIRSTCMD: /* * Skip leading spaces or + signs in the string. @@ -208,8 +236,8 @@ every_first_cmd = save(cbuf); break; case A_OPT_TOGGLE: - toggle_option(optchar, cbuf, optflag); - optchar = '\0'; + toggle_option(curropt, opt_lower, cbuf, optflag); + curropt = NULL; break; case A_F_BRACKET: match_brac(cbuf[0], cbuf[1], 1, (int) number); @@ -262,22 +290,258 @@ } /* - * Add a character to a multi-character command. + * Is a character an erase or kill char? */ static int -mca_char(c) +is_erase_char(c) int c; { + return (c == erase_char || c == erase2_char || c == kill_char); +} + +/* + * Handle the first char of an option (after the initial dash). + */ + static int +mca_opt_first_char(c) + int c; +{ + int flag = (optflag & ~OPT_NO_PROMPT); +#if GNU_OPTIONS + if (flag == OPT_NO_TOGGLE) + { + switch (c) + { + case '_': + /* "__" = long option name. */ + optgetname = TRUE; + mca_opt_toggle(); + return (MCA_MORE); + } + } else +#endif + { + 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); +#if GNU_OPTIONS + case '-': + /* "--" = long option name. */ + optgetname = TRUE; + mca_opt_toggle(); + return (MCA_MORE); +#endif + } + } + /* Char was not handled here. */ + return (NO_MCA); +} + +#if GNU_OPTIONS +/* + * Add a char to a long option name. + * See if we've got a match for an option name yet. + * If so, display the complete name and stop + * accepting chars until user hits RETURN. + */ + static int +mca_opt_nonfirst_char(c) + int c; +{ char *p; - int flag; - char buf[3]; + char *oname; + + if (curropt != NULL) + { + /* + * Already have a match for the name. + * Don't accept anything but erase/kill. + */ + if (is_erase_char(c)) + 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(); + opt_lower = ASCII_IS_LOWER(p[0]); + curropt = findopt_name(&p, &oname, NULL); + if (curropt != NULL) + { + /* + * Got a match. + * Remember the option and + * display the full option name. + */ + cmd_reset(); + mca_opt_toggle(); + for (p = oname; *p != '\0'; p++) + { + c = *p; + if (!opt_lower && ASCII_IS_LOWER(c)) + c = ASCII_TO_UPPER(c); + if (cmd_char(c) != CC_OK) + return (MCA_DONE); + } + } + return (MCA_MORE); +} +#endif + +/* + * Handle a char of an option toggle command. + */ + static int +mca_opt_char(c) + int c; +{ PARG parg; + /* + * This may be a short option (single char), + * or one char of a long option name, + * or one char of the option parameter. + */ + if (curropt == NULL && len_cmdbuf() == 0) + { + int ret = mca_opt_first_char(c); + if (ret != NO_MCA) + return (ret); + } +#if GNU_OPTIONS + if (optgetname) + { + /* We're getting a long option name. */ + if (c != '\n' && c != '\r') + return (mca_opt_nonfirst_char(c)); + if (curropt == NULL) + { + parg.p_string = get_cmdbuf(); + error("There is no --%s option", &parg); + return (MCA_DONE); + } + optgetname = FALSE; + cmd_reset(); + } else +#endif + { + if (is_erase_char(c)) + return (NO_MCA); + if (curropt != NULL) + /* We're getting the option parameter. */ + return (NO_MCA); + curropt = findopt(c); + if (curropt == NULL) + { + parg.p_string = propt(c); + error("There is no %s option", &parg); + return (MCA_DONE); + } + } + /* + * If the option which was entered does not take a + * parameter, toggle the option immediately, + * so user doesn't have to hit RETURN. + */ + if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE || + !opt_has_param(curropt)) + { + toggle_option(curropt, ASCII_IS_LOWER(c), "", optflag); + return (MCA_DONE); + } + /* + * Display a prompt appropriate for the option parameter. + */ + start_mca(A_OPT_TOGGLE, opt_prompt(curropt), (void*)NULL, 0); + return (MCA_MORE); +} + +/* + * Handle a char of a search command. + */ + static int +mca_search_char(c) + int c; +{ + int flag = 0; + + /* + * 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 + */ + if (len_cmdbuf() > 0) + return (NO_MCA); + + switch (c) + { + case CONTROL('E'): /* ignore END of file */ + case '*': + if (mca != A_FILTER) + flag = SRCH_PAST_EOF; + break; + case CONTROL('F'): /* FIRST file */ + case '@': + if (mca != A_FILTER) + flag = SRCH_FIRST_FILE; + break; + case CONTROL('K'): /* KEEP position */ + if (mca != A_FILTER) + 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) + { + search_type ^= flag; + mca_search(); + return (MCA_MORE); + } + return (NO_MCA); +} + +/* + * Handle a character of a multi-character command. + */ + static int +mca_char(c) + int c; +{ + int ret; + switch (mca) { case 0: /* - * Not in a multicharacter command. + * We're not in a multicharacter command. */ return (NO_MCA); @@ -295,14 +559,15 @@ * Entering digits of a number. * Terminated by a non-digit. */ - if ((c < '0' || c > '9') && + if (!((c >= '0' && c <= '9') || c == '.') && editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID) { /* * Not part of the number. - * Treat as a normal command character. + * End the number and treat this char + * as a normal command character. */ - number = cmd_int(); + number = cmd_int(&fraction); mca = 0; cmd_accept(); return (NO_MCA); @@ -310,214 +575,26 @@ break; case A_OPT_TOGGLE: - /* - * Special case for the TOGGLE_OPTION command. - * If the option letter which was entered is a - * single-char option, execute the command immediately, - * 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 GNU_OPTIONS - if (flag == OPT_NO_TOGGLE) - { - switch (c) - { - case '_': - /* "__" = long option name. */ - optgetname = TRUE; - mca_opt_toggle(); - return (MCA_MORE); - } - } else -#endif - { - 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); -#if GNU_OPTIONS - case '-': - /* "--" = long option name. */ - optgetname = TRUE; - mca_opt_toggle(); - return (MCA_MORE); -#endif - } - } - } -#if GNU_OPTIONS - 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; + ret = mca_opt_char(c); + if (ret != NO_MCA) + return (ret); + break; - 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 -#endif - { - 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. - */ - if ((p = opt_prompt(c)) == NULL) - { - buf[0] = '-'; - buf[1] = c; - buf[2] = '\0'; - p = buf; - } - start_mca(A_OPT_TOGGLE, p, (void*)NULL, 0); - return (MCA_MORE); - case A_F_SEARCH: case A_B_SEARCH: - /* - * 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 - */ - if (len_cmdbuf() > 0) - /* - * Only works for the first char of the pattern. - */ - break; + case A_FILTER: + ret = mca_search_char(c); + if (ret != NO_MCA) + return (ret); + break; - 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) - { - search_type ^= flag; - mca_search(); - return (MCA_MORE); - } + default: + /* Other multicharacter command. */ break; } /* - * Any other multicharacter command - * is terminated by a newline. + * The multichar command is terminated by a newline. */ if (c == '\n' || c == '\r') { @@ -555,6 +632,21 @@ } /* + * Discard any buffered file data. + */ + static void +clear_buffers() +{ + if (!(ch_getflags() & CH_CANSEEK)) + return; + ch_flush(); + clr_linenum(); +#if HILITE_SEARCH + clr_hilite(); +#endif +} + +/* * Make sure the screen is displayed. */ static void @@ -577,11 +669,20 @@ jump_loc(initial_scrpos.pos, initial_scrpos.ln); } else if (screen_trashed) { - int save_top_scroll; - save_top_scroll = top_scroll; + int save_top_scroll = top_scroll; + int save_ignore_eoi = ignore_eoi; top_scroll = 1; + ignore_eoi = 0; + if (screen_trashed == 2) + { + /* Special case used by ignore_eoi: re-open the input file + * and jump to the end of the file. */ + reopen_curr_ifile(); + jump_forw(); + } repaint(); top_scroll = save_top_scroll; + ignore_eoi = save_ignore_eoi; } } @@ -593,7 +694,7 @@ { register char *p; - if (ungotp != NULL && ungotp > ungot) + if (ungot != NULL) { /* * No prompt necessary if commands are from @@ -609,38 +710,60 @@ bottompos = position(BOTTOM_PLUS_ONE); /* - * If the -E flag is set and we've hit EOF on the last file, quit. + * If we've hit EOF on the last file and the -E flag is set, quit. */ - if ((quit_at_eof == OPT_ONPLUS || quit_if_one_screen) && - hit_eof && next_ifile(curr_ifile) == NULL_IFILE) + if (get_quit_at_eof() == OPT_ONPLUS && + eof_displayed() && !(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 the entire file is displayed and the -F flag is set, quit. */ - if (quit_at_eof && squished && + if (quit_if_one_screen && + entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) && 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. */ + /* + * If the previous action was a forward movement, + * don't clear the bottom line of the display; + * just print the prompt since the forward movement guarantees + * that we're in the right position to display the prompt. + * Clearing the line could cause a problem: for example, if the last + * line displayed ended at the right screen edge without a newline, + * then clearing would clear the last displayed line rather than + * the prompt line. + */ + if (!forw_prompt) + clear_bot(); clear_cmd(); + forw_prompt = 0; p = help_prompt ? help_prompt : pr_string(); - if (p == NULL) + if (is_filtering()) + putstr("& "); + if (p == NULL || *p == '\0') putchr(':'); else { - so_enter(); + at_enter(AT_STANDOUT); putstr(p); if (be_helpful && !help_prompt && strlen(p) + 40 < sc_width) putstr(" [Press space to continue, 'q' to quit.]"); - so_exit(); + at_exit(); } help_prompt = NULL; + clear_eol(); } /* @@ -664,48 +787,59 @@ public int getcc() { - if (ungotp == NULL) + if (unget_end) + { /* - * Normal case: no ungotten chars, so get one from the user. + * We have just run out of ungotten chars. */ - return (getchr()); - - if (ungotp > ungot) + unget_end = 0; + if (len_cmdbuf() == 0 || !empty_screen()) + return (getchr()); /* - * Return the next ungotten char. + * Command is incomplete, so try to complete it. */ - return (*--ungotp); + switch (mca) + { + case A_DIGIT: + /* + * We have a number but no command. Treat as #g. + */ + return ('g'); - /* - * We have just run out of ungotten chars. - */ - ungotp = NULL; - if (len_cmdbuf() == 0 || !empty_screen()) - return (getchr()); - /* - * Command is incomplete, so try to complete it. - */ - switch (mca) - { - case A_DIGIT: - /* - * We have a number but no command. Treat as #g. - */ - return ('g'); + case A_F_SEARCH: + case A_B_SEARCH: + /* + * We have "/string" but no newline. Add the \n. + */ + return ('\n'); - case A_F_SEARCH: - case A_B_SEARCH: - /* - * We have "/string" but no newline. Add the \n. - */ - return ('\n'); + default: + /* + * Some other incomplete command. Let user complete it. + */ + return (getchr()); + } + } - default: + if (ungot == NULL) + { /* - * Some other incomplete command. Let user complete it. + * Normal case: no ungotten chars, so get one from the user. */ return (getchr()); } + + /* + * Return the next ungotten char. + */ + { + struct ungot *ug = ungot; + char c = ug->ug_char; + ungot = ug->ug_next; + free(ug); + unget_end = (ungot == NULL); + return (c); + } } /* @@ -716,14 +850,12 @@ ungetcc(c) int c; { - if (ungotp == NULL) - ungotp = ungot; - if (ungotp >= ungot + sizeof(ungot)) - { - error("ungetcc overflow", NULL_PARG); - quit(QUIT_ERROR); - } - *ungotp++ = c; + struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot)); + + ug->ug_char = c; + ug->ug_next = ungot; + ungot = ug; + unget_end = 0; } /* @@ -832,6 +964,9 @@ * Restore the file we were originally viewing. */ reedit_ifile(save_ifile); + } else + { + unsave_ifile(save_ifile); } } @@ -863,7 +998,7 @@ mca = 0; cmd_accept(); number = 0; - optchar = '\0'; + curropt = NULL; /* * See if any signals need processing. @@ -1080,12 +1215,16 @@ /* * Forward forever, ignoring EOF. */ + if (ch_getflags() & CH_HELPFILE) + break; cmd_exec(); jump_forw(); ignore_eoi = 1; - hit_eof = 0; while (!sigs) + { + make_display(); forward(1, 0, 0); + } ignore_eoi = 0; /* * This gets us back in "F mode" after processing @@ -1124,14 +1263,7 @@ * Flush buffers, then repaint screen. * Don't flush the buffers on a pipe! */ - if (ch_getflags() & CH_CANSEEK) - { - ch_flush(); - clr_linenum(); -#if HILITE_SEARCH - clr_hilite(); -#endif - } + clear_buffers(); /* FALLTHRU */ case A_REPAINT: /* @@ -1156,11 +1288,17 @@ * Go to a specified percentage into the file. */ if (number < 0) + { number = 0; + fraction = 0; + } if (number > 100) + { number = 100; + fraction = 0; + } cmd_exec(); - jump_percent((int) number); + jump_percent((int) number, fraction); break; case A_GOEND: @@ -1188,6 +1326,8 @@ /* * Print file name, etc. */ + if (ch_getflags() & CH_HELPFILE) + break; cmd_exec(); parg.p_string = eq_message(); error("%s", &parg); @@ -1205,6 +1345,20 @@ /* * Exit. */ +#if !SMALL + if (curr_ifile != NULL_IFILE && + ch_getflags() & CH_HELPFILE) + { + /* + * Quit while viewing the help file + * just means return to viewing the + * previous file. + */ + hshift = save_hshift; + if (edit_prev(1) == 0) + break; + } +#endif /* !SMALL */ if (extra != NULL) quit(*extra); quit(QUIT_OK); @@ -1213,7 +1367,8 @@ /* * Define abbreviation for a commonly used sequence below. */ -#define DO_SEARCH() if (number <= 0) number = 1; \ +#define DO_SEARCH() \ + if (number <= 0) number = 1; \ mca_search(); \ cmd_exec(); \ multi_search((char *)NULL, (int) number); @@ -1243,6 +1398,17 @@ c = getcc(); goto again; + case A_FILTER: +#if HILITE_SEARCH + search_type = SRCH_FORW | SRCH_FILTER; + mca_search(); + c = getcc(); + goto again; +#else + error("Command not available", NULL_PARG); + break; +#endif + case A_AGAIN_SEARCH: /* * Repeat previous search. @@ -1285,18 +1451,17 @@ break; case A_HELP: +#if !SMALL /* * Help. */ - if (nohelp) - { - bell(); + if (ch_getflags() & CH_HELPFILE) break; - } - clear_bot(); - putstr(" help"); cmd_exec(); - help(0); + save_hshift = hshift; + hshift = 0; + (void) edit(HELPFILE); +#endif /* !SMALL */ break; case A_EXAMINE: @@ -1327,6 +1492,8 @@ 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); @@ -1334,9 +1501,8 @@ } if (curr_altfilename != NULL) { - error("Cannot edit file processed with LESSOPEN", + error("WARNING: This file was viewed via LESSOPEN", NULL_PARG); - break; } start_mca(A_SHELL, "!", ml_shell, 0); /* @@ -1369,7 +1535,8 @@ number = 1; if (edit_next((int) number)) { - if (quit_at_eof && hit_eof) + if (get_quit_at_eof() && eof_displayed() && + !(ch_getflags() & CH_HELPFILE)) quit(QUIT_OK); parg.p_string = (number > 1) ? "(N-th) " : ""; error("No %snext file", &parg); @@ -1449,6 +1616,8 @@ 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) @@ -1511,10 +1680,12 @@ /* * 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') + if (c == erase_char || c == erase2_char || + c == kill_char || c == '\n' || c == '\r') break; setmark(c); break; @@ -1525,9 +1696,10 @@ */ start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0); c = getcc(); - if (c == erase_char || c == kill_char || - c == '\n' || c == '\r') + if (c == erase_char || c == erase2_char || + c == kill_char || c == '\n' || c == '\r') break; + cmd_exec(); gomark(c); break; @@ -1540,7 +1712,7 @@ } start_mca(A_PIPE, "|mark: ", (void*)NULL, 0); c = getcc(); - if (c == erase_char || c == kill_char) + if (c == erase_char || c == erase2_char || c == kill_char) break; if (c == '\n' || c == '\r') c = '.';