diff options
Diffstat (limited to 'contrib/less/command.c')
-rw-r--r-- | contrib/less/command.c | 189 |
1 files changed, 131 insertions, 58 deletions
diff --git a/contrib/less/command.c b/contrib/less/command.c index 8e0ae4b34d67..ae59181c2827 100644 --- a/contrib/less/command.c +++ b/contrib/less/command.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2020 Mark Nudelman + * Copyright (C) 1984-2021 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. @@ -57,21 +57,22 @@ extern void *ml_shell; extern char *editor; extern char *editproto; #endif -extern int screen_trashed; /* The screen has been overwritten */ +extern int screen_trashed; /* The screen has been overwritten */ extern int shift_count; extern int oldbot; extern int forw_prompt; +extern int incr_search; #if MSDOS_COMPILER==WIN32C extern int utf_mode; #endif #if SHELL_ESCAPE -static char *shellcmd = NULL; /* For holding last shell command for "!!" */ +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 long fraction; /* The fractional part of the number */ +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 long fraction; /* The fractional part of the number */ static struct loption *curropt; static int opt_lower; static int optflag; @@ -113,7 +114,6 @@ set_mca(action) int action; { mca = action; - deinit_mouse(); /* we don't want mouse events while entering a cmd */ clear_bot(); clear_cmd(); } @@ -127,7 +127,6 @@ clear_mca(VOID_PARAM) if (mca == 0) return; mca = 0; - init_mouse(); } /* @@ -177,6 +176,8 @@ mca_search(VOID_PARAM) cmd_putstr("Keep-pos "); if (search_type & SRCH_NO_REGEX) cmd_putstr("Regex-off "); + if (search_type & SRCH_WRAP) + cmd_putstr("Wrap "); #if HILITE_SEARCH if (search_type & SRCH_FILTER) @@ -520,9 +521,9 @@ mca_search_char(c) /* * 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 + * ! Toggle the NO_MATCH flag + * * Toggle the PAST_EOF flag + * @ Toggle the FIRST_FILE flag */ if (len_cmdbuf() > 0) return (NO_MCA); @@ -547,6 +548,10 @@ mca_search_char(c) if (mca != A_FILTER) flag = SRCH_NO_MOVE; break; + case CONTROL('W'): /* WRAP around */ + if (mca != A_FILTER) + flag = SRCH_WRAP; + break; case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */ flag = SRCH_NO_REGEX; break; @@ -558,7 +563,8 @@ mca_search_char(c) if (flag != 0) { - search_type ^= flag; + /* Toggle flag, but keep PAST_EOF and WRAP mutually exclusive. */ + search_type ^= flag | (search_type & (SRCH_PAST_EOF|SRCH_WRAP)); mca_search(); return (MCA_MORE); } @@ -596,9 +602,16 @@ mca_char(c) * Entering digits of a number. * Terminated by a non-digit. */ - if (!((c >= '0' && c <= '9') || c == '.') && - editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID) + if ((c >= '0' && c <= '9') || c == '.') + break; + switch (editchar(c, ECF_PEEK|ECF_NOHISTORY|ECF_NOCOMPLETE|ECF_NORIGHTLEFT)) { + case A_NOACTION: + /* + * Ignore this char and get another one. + */ + return (MCA_MORE); + case A_INVALID: /* * Not part of the number. * End the number and treat this char @@ -651,15 +664,44 @@ mca_char(c) */ return (MCA_DONE); - if ((mca == A_F_BRACKET || mca == A_B_BRACKET) && len_cmdbuf() >= 2) + switch (mca) { - /* - * Special case for the bracket-matching commands. - * Execute the command after getting exactly two - * characters from the user. - */ - exec_mca(); - return (MCA_DONE); + case A_F_BRACKET: + case A_B_BRACKET: + if (len_cmdbuf() >= 2) + { + /* + * Special case for the bracket-matching commands. + * Execute the command after getting exactly two + * characters from the user. + */ + exec_mca(); + return (MCA_DONE); + } + break; + case A_F_SEARCH: + case A_B_SEARCH: + if (incr_search) + { + /* Incremental search: do a search after every input char. */ + int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP)); + char *pattern = get_cmdbuf(); + cmd_exec(); + if (*pattern == '\0') + { + /* User has backspaced to an empty pattern. */ + undo_search(1); + } else + { + if (search(st | SRCH_INCR, pattern, 1) != 0) + /* No match, invalid pattern, etc. */ + undo_search(1); + } + /* Redraw the search prompt and search string. */ + mca_search(); + cmd_repaint(NULL); + } + break; } /* @@ -695,12 +737,6 @@ make_display(VOID_PARAM) if (empty_screen()) { if (initial_scrpos.pos == NULL_POSITION) - /* - * {{ Maybe this should be: - * jump_loc(ch_zero(), jump_sline); - * but this behavior seems rather unexpected - * on the first screen. }} - */ jump_loc(ch_zero(), 1); else jump_loc(initial_scrpos.pos, initial_scrpos.ln); @@ -793,11 +829,16 @@ prompt(VOID_PARAM) clear_cmd(); forw_prompt = 0; p = pr_string(); +#if HILITE_SEARCH if (is_filtering()) putstr("& "); +#endif if (p == NULL || *p == '\0') + { + at_enter(AT_NORMAL|AT_COLOR_PROMPT); putchr(':'); - else + at_exit(); + } else { #if MSDOS_COMPILER==WIN32C WCHAR w[MAX_PATH*2]; @@ -807,7 +848,7 @@ prompt(VOID_PARAM) 0, w, -1, a, sizeof(a), NULL, NULL); p = a; #endif - at_enter(AT_STANDOUT); + at_enter(AT_STANDOUT|AT_COLOR_PROMPT); putstr(p); at_exit(); } @@ -843,7 +884,7 @@ getcc_end_command(VOID_PARAM) return ('\n'); default: /* Some other incomplete command. Let user complete it. */ - return (getchr()); + return ((ungot == NULL) ? getchr() : 0); } } @@ -856,23 +897,26 @@ getcc_end_command(VOID_PARAM) static LWCHAR getccu(VOID_PARAM) { - LWCHAR c; - if (ungot == NULL) + LWCHAR c = 0; + while (c == 0) { - /* Normal case: no ungotten chars. - * Get char from the user. */ - c = getchr(); - } else - { - /* Ungotten chars available: - * Take the top of stack (most recent). */ - struct ungot *ug = ungot; - c = ug->ug_char; - ungot = ug->ug_next; - free(ug); - - if (c == CHAR_END_COMMAND) - c = getcc_end_command(); + if (ungot == NULL) + { + /* Normal case: no ungotten chars. + * Get char from the user. */ + c = getchr(); + } else + { + /* Ungotten chars available: + * Take the top of stack (most recent). */ + struct ungot *ug = ungot; + c = ug->ug_char; + ungot = ug->ug_next; + free(ug); + + if (c == CHAR_END_COMMAND) + c = getcc_end_command(); + } } return (c); } @@ -948,6 +992,28 @@ ungetcc(c) } /* + * "Unget" a command character. + * If any other chars are already ungotten, put this one after those. + */ + public void +ungetcc_back(c) + LWCHAR c; +{ + struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot)); + ug->ug_char = c; + ug->ug_next = NULL; + if (ungot == NULL) + ungot = ug; + else + { + struct ungot *pu; + for (pu = ungot; pu->ug_next != NULL; pu = pu->ug_next) + continue; + pu->ug_next = ug; + } +} + +/* * Unget a whole string of command characters. * The next sequence of getcc()'s will return this string. */ @@ -955,10 +1021,8 @@ ungetcc(c) ungetsc(s) char *s; { - char *p; - - for (p = s + strlen(s) - 1; p >= s; p--) - ungetcc(*p); + while (*s != '\0') + ungetcc_back(*s++); } /* @@ -1122,6 +1186,7 @@ commands(VOID_PARAM) int action; char *cbuf; int newaction; + int save_jump_sline; int save_search_type; char *extra; char tbuf[2]; @@ -1423,11 +1488,18 @@ commands(VOID_PARAM) case A_GOLINE: /* * Go to line N, default beginning of file. + * If N <= 0, ignore jump_sline in order to avoid + * empty lines before the beginning of the file. */ + save_jump_sline = jump_sline; if (number <= 0) + { number = 1; + jump_sline = 0; + } cmd_exec(); jump_back(number); + jump_sline = save_jump_sline; break; case A_PERCENT: @@ -1493,7 +1565,7 @@ commands(VOID_PARAM) case A_VERSION: /* - * Print version number, without the "@(#)". + * Print version number. */ cmd_exec(); dispversion(); @@ -1524,10 +1596,10 @@ commands(VOID_PARAM) /* * Define abbreviation for a commonly used sequence below. */ -#define DO_SEARCH() \ - if (number <= 0) number = 1; \ - mca_search(); \ - cmd_exec(); \ +#define DO_SEARCH() \ + if (number <= 0) number = 1; \ + mca_search(); \ + cmd_exec(); \ multi_search((char *)NULL, (int) number, 0); @@ -1604,10 +1676,11 @@ commands(VOID_PARAM) break; case A_UNDO_SEARCH: + case A_CLR_SEARCH: /* * Clear search string highlighting. */ - undo_search(); + undo_search(action == A_CLR_SEARCH); break; case A_HELP: |