1a8f92a7cSPaul Saab /* $FreeBSD$ */ 2a5f0fb15SPaul Saab /* 37374caaaSXin LI * Copyright (C) 1984-2008 Mark Nudelman 4a5f0fb15SPaul Saab * 5a5f0fb15SPaul Saab * You may distribute under the terms of either the GNU General Public 6a5f0fb15SPaul Saab * License or the Less License, as specified in the README file. 7a5f0fb15SPaul Saab * 8a5f0fb15SPaul Saab * For more information about less, or for information on how to 9a5f0fb15SPaul Saab * contact the author, see the README file. 10a5f0fb15SPaul Saab */ 11a5f0fb15SPaul Saab 12a5f0fb15SPaul Saab 13a5f0fb15SPaul Saab /* 14a5f0fb15SPaul Saab * User-level command processor. 15a5f0fb15SPaul Saab */ 16a5f0fb15SPaul Saab 17a5f0fb15SPaul Saab #include "less.h" 188fd4165cSPaul Saab #if MSDOS_COMPILER==WIN32C 198fd4165cSPaul Saab #include <windows.h> 208fd4165cSPaul Saab #endif 21a5f0fb15SPaul Saab #include "position.h" 22a5f0fb15SPaul Saab #include "option.h" 23a5f0fb15SPaul Saab #include "cmd.h" 24a5f0fb15SPaul Saab 2589dd99dcSXin LI extern int erase_char, erase2_char, kill_char; 26a5f0fb15SPaul Saab extern int sigs; 27a5f0fb15SPaul Saab extern int quit_if_one_screen; 28a5f0fb15SPaul Saab extern int squished; 29a5f0fb15SPaul Saab extern int sc_width; 30a5f0fb15SPaul Saab extern int sc_height; 31a5f0fb15SPaul Saab extern int swindow; 32a5f0fb15SPaul Saab extern int jump_sline; 33a5f0fb15SPaul Saab extern int quitting; 34a5f0fb15SPaul Saab extern int wscroll; 35a5f0fb15SPaul Saab extern int top_scroll; 36a5f0fb15SPaul Saab extern int ignore_eoi; 37a5f0fb15SPaul Saab extern int secure; 38a5f0fb15SPaul Saab extern int hshift; 39a5f0fb15SPaul Saab extern int show_attn; 40720c436cSXin LI extern int less_is_more; 41a5f0fb15SPaul Saab extern char *every_first_cmd; 42a5f0fb15SPaul Saab extern char *curr_altfilename; 43a5f0fb15SPaul Saab extern char version[]; 44a5f0fb15SPaul Saab extern struct scrpos initial_scrpos; 45a5f0fb15SPaul Saab extern IFILE curr_ifile; 46a5f0fb15SPaul Saab extern void constant *ml_search; 47a5f0fb15SPaul Saab extern void constant *ml_examine; 48a5f0fb15SPaul Saab #if SHELL_ESCAPE || PIPEC 49a5f0fb15SPaul Saab extern void constant *ml_shell; 50a5f0fb15SPaul Saab #endif 51a5f0fb15SPaul Saab #if EDITOR 52a5f0fb15SPaul Saab extern char *editor; 53a5f0fb15SPaul Saab extern char *editproto; 54a5f0fb15SPaul Saab #endif 55a5f0fb15SPaul Saab extern int screen_trashed; /* The screen has been overwritten */ 5615596da4SPaul Saab extern int shift_count; 57720c436cSXin LI extern int oldbot; 58720c436cSXin LI extern int forw_prompt; 59a5f0fb15SPaul Saab 60a5f0fb15SPaul Saab static char ungot[UNGOT_SIZE]; 61a5f0fb15SPaul Saab static char *ungotp = NULL; 62a5f0fb15SPaul Saab #if SHELL_ESCAPE 63a5f0fb15SPaul Saab static char *shellcmd = NULL; /* For holding last shell command for "!!" */ 64a5f0fb15SPaul Saab #endif 65a5f0fb15SPaul Saab static int mca; /* The multicharacter command (action) */ 66a5f0fb15SPaul Saab static int search_type; /* The previous type of search */ 671ede1615STim J. Robbins static LINENUM number; /* The number typed by the user */ 68720c436cSXin LI static long fraction; /* The fractional part of the number */ 69a5f0fb15SPaul Saab static char optchar; 70a5f0fb15SPaul Saab static int optflag; 71a5f0fb15SPaul Saab static int optgetname; 72a5f0fb15SPaul Saab static POSITION bottompos; 7389dd99dcSXin LI static int save_hshift; 74a5f0fb15SPaul Saab #if PIPEC 75a5f0fb15SPaul Saab static char pipec; 76a5f0fb15SPaul Saab #endif 77a5f0fb15SPaul Saab 78a5f0fb15SPaul Saab static void multi_search(); 79a5f0fb15SPaul Saab 80a5f0fb15SPaul Saab /* 81720c436cSXin LI * Move the cursor to start of prompt line before executing a command. 82a5f0fb15SPaul Saab * This looks nicer if the command takes a long time before 83a5f0fb15SPaul Saab * updating the screen. 84a5f0fb15SPaul Saab */ 85a5f0fb15SPaul Saab static void 86a5f0fb15SPaul Saab cmd_exec() 87a5f0fb15SPaul Saab { 887374caaaSXin LI #if HILITE_SEARCH 89a5f0fb15SPaul Saab clear_attn(); 907374caaaSXin LI #endif 91aa22b8b6SXin LI clear_bot(); 92a5f0fb15SPaul Saab flush(); 93a5f0fb15SPaul Saab } 94a5f0fb15SPaul Saab 95a5f0fb15SPaul Saab /* 96a5f0fb15SPaul Saab * Set up the display to start a new multi-character command. 97a5f0fb15SPaul Saab */ 98a5f0fb15SPaul Saab static void 99a5f0fb15SPaul Saab start_mca(action, prompt, mlist, cmdflags) 100a5f0fb15SPaul Saab int action; 101a5f0fb15SPaul Saab char *prompt; 102a5f0fb15SPaul Saab void *mlist; 103a5f0fb15SPaul Saab int cmdflags; 104a5f0fb15SPaul Saab { 105a5f0fb15SPaul Saab mca = action; 106720c436cSXin LI clear_bot(); 107a5f0fb15SPaul Saab clear_cmd(); 108a5f0fb15SPaul Saab cmd_putstr(prompt); 109a5f0fb15SPaul Saab set_mlist(mlist, cmdflags); 110a5f0fb15SPaul Saab } 111a5f0fb15SPaul Saab 112a5f0fb15SPaul Saab public int 113a5f0fb15SPaul Saab in_mca() 114a5f0fb15SPaul Saab { 115a5f0fb15SPaul Saab return (mca != 0 && mca != A_PREFIX); 116a5f0fb15SPaul Saab } 117a5f0fb15SPaul Saab 118a5f0fb15SPaul Saab /* 119a5f0fb15SPaul Saab * Set up the display to start a new search command. 120a5f0fb15SPaul Saab */ 121a5f0fb15SPaul Saab static void 122a5f0fb15SPaul Saab mca_search() 123a5f0fb15SPaul Saab { 1247374caaaSXin LI #if HILITE_SEARCH 1257374caaaSXin LI if (search_type & SRCH_FILTER) 1267374caaaSXin LI mca = A_FILTER; 1277374caaaSXin LI else 1287374caaaSXin LI #endif 129a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 130a5f0fb15SPaul Saab mca = A_F_SEARCH; 131a5f0fb15SPaul Saab else 132a5f0fb15SPaul Saab mca = A_B_SEARCH; 133a5f0fb15SPaul Saab 134720c436cSXin LI clear_bot(); 135a5f0fb15SPaul Saab clear_cmd(); 136a5f0fb15SPaul Saab 137a5f0fb15SPaul Saab if (search_type & SRCH_NO_MATCH) 138a5f0fb15SPaul Saab cmd_putstr("Non-match "); 139a5f0fb15SPaul Saab if (search_type & SRCH_FIRST_FILE) 140a5f0fb15SPaul Saab cmd_putstr("First-file "); 141a5f0fb15SPaul Saab if (search_type & SRCH_PAST_EOF) 142a5f0fb15SPaul Saab cmd_putstr("EOF-ignore "); 143a5f0fb15SPaul Saab if (search_type & SRCH_NO_MOVE) 144a5f0fb15SPaul Saab cmd_putstr("Keep-pos "); 145a5f0fb15SPaul Saab if (search_type & SRCH_NO_REGEX) 146a5f0fb15SPaul Saab cmd_putstr("Regex-off "); 147a5f0fb15SPaul Saab 1487374caaaSXin LI #if HILITE_SEARCH 1497374caaaSXin LI if (search_type & SRCH_FILTER) 1507374caaaSXin LI cmd_putstr("&/"); 1517374caaaSXin LI else 1527374caaaSXin LI #endif 153a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 154a5f0fb15SPaul Saab cmd_putstr("/"); 155a5f0fb15SPaul Saab else 156a5f0fb15SPaul Saab cmd_putstr("?"); 157a5f0fb15SPaul Saab set_mlist(ml_search, 0); 158a5f0fb15SPaul Saab } 159a5f0fb15SPaul Saab 160a5f0fb15SPaul Saab /* 161a5f0fb15SPaul Saab * Set up the display to start a new toggle-option command. 162a5f0fb15SPaul Saab */ 163a5f0fb15SPaul Saab static void 164a5f0fb15SPaul Saab mca_opt_toggle() 165a5f0fb15SPaul Saab { 166a5f0fb15SPaul Saab int no_prompt; 167a5f0fb15SPaul Saab int flag; 168a5f0fb15SPaul Saab char *dash; 169a5f0fb15SPaul Saab 170a5f0fb15SPaul Saab no_prompt = (optflag & OPT_NO_PROMPT); 171a5f0fb15SPaul Saab flag = (optflag & ~OPT_NO_PROMPT); 172a5f0fb15SPaul Saab dash = (flag == OPT_NO_TOGGLE) ? "_" : "-"; 173a5f0fb15SPaul Saab 174a5f0fb15SPaul Saab mca = A_OPT_TOGGLE; 175720c436cSXin LI clear_bot(); 176a5f0fb15SPaul Saab clear_cmd(); 177a5f0fb15SPaul Saab cmd_putstr(dash); 178a5f0fb15SPaul Saab if (optgetname) 179a5f0fb15SPaul Saab cmd_putstr(dash); 180a5f0fb15SPaul Saab if (no_prompt) 181a5f0fb15SPaul Saab cmd_putstr("(P)"); 182a5f0fb15SPaul Saab switch (flag) 183a5f0fb15SPaul Saab { 184a5f0fb15SPaul Saab case OPT_UNSET: 185a5f0fb15SPaul Saab cmd_putstr("+"); 186a5f0fb15SPaul Saab break; 187a5f0fb15SPaul Saab case OPT_SET: 188a5f0fb15SPaul Saab cmd_putstr("!"); 189a5f0fb15SPaul Saab break; 190a5f0fb15SPaul Saab } 191a5f0fb15SPaul Saab set_mlist(NULL, 0); 192a5f0fb15SPaul Saab } 193a5f0fb15SPaul Saab 194a5f0fb15SPaul Saab /* 195a5f0fb15SPaul Saab * Execute a multicharacter command. 196a5f0fb15SPaul Saab */ 197a5f0fb15SPaul Saab static void 198a5f0fb15SPaul Saab exec_mca() 199a5f0fb15SPaul Saab { 200a5f0fb15SPaul Saab register char *cbuf; 201a5f0fb15SPaul Saab 202a5f0fb15SPaul Saab cmd_exec(); 203a5f0fb15SPaul Saab cbuf = get_cmdbuf(); 204a5f0fb15SPaul Saab 205a5f0fb15SPaul Saab switch (mca) 206a5f0fb15SPaul Saab { 207a5f0fb15SPaul Saab case A_F_SEARCH: 208a5f0fb15SPaul Saab case A_B_SEARCH: 2091ede1615STim J. Robbins multi_search(cbuf, (int) number); 210a5f0fb15SPaul Saab break; 2117374caaaSXin LI #if HILITE_SEARCH 2127374caaaSXin LI case A_FILTER: 2137374caaaSXin LI search_type ^= SRCH_NO_MATCH; 2147374caaaSXin LI set_filter_pattern(cbuf, search_type); 2157374caaaSXin LI break; 2167374caaaSXin LI #endif 217a5f0fb15SPaul Saab case A_FIRSTCMD: 218a5f0fb15SPaul Saab /* 219a5f0fb15SPaul Saab * Skip leading spaces or + signs in the string. 220a5f0fb15SPaul Saab */ 221a5f0fb15SPaul Saab while (*cbuf == '+' || *cbuf == ' ') 222a5f0fb15SPaul Saab cbuf++; 223a5f0fb15SPaul Saab if (every_first_cmd != NULL) 224a5f0fb15SPaul Saab free(every_first_cmd); 225a5f0fb15SPaul Saab if (*cbuf == '\0') 226a5f0fb15SPaul Saab every_first_cmd = NULL; 227a5f0fb15SPaul Saab else 228a5f0fb15SPaul Saab every_first_cmd = save(cbuf); 229a5f0fb15SPaul Saab break; 230a5f0fb15SPaul Saab case A_OPT_TOGGLE: 231a5f0fb15SPaul Saab toggle_option(optchar, cbuf, optflag); 232a5f0fb15SPaul Saab optchar = '\0'; 233a5f0fb15SPaul Saab break; 234a5f0fb15SPaul Saab case A_F_BRACKET: 2351ede1615STim J. Robbins match_brac(cbuf[0], cbuf[1], 1, (int) number); 236a5f0fb15SPaul Saab break; 237a5f0fb15SPaul Saab case A_B_BRACKET: 2381ede1615STim J. Robbins match_brac(cbuf[1], cbuf[0], 0, (int) number); 239a5f0fb15SPaul Saab break; 240a5f0fb15SPaul Saab #if EXAMINE 241a5f0fb15SPaul Saab case A_EXAMINE: 242a5f0fb15SPaul Saab if (secure) 243a5f0fb15SPaul Saab break; 244a5f0fb15SPaul Saab edit_list(cbuf); 2451ede1615STim J. Robbins #if TAGS 2468fd4165cSPaul Saab /* If tag structure is loaded then clean it up. */ 2478fd4165cSPaul Saab cleantags(); 2481ede1615STim J. Robbins #endif 249a5f0fb15SPaul Saab break; 250a5f0fb15SPaul Saab #endif 251a5f0fb15SPaul Saab #if SHELL_ESCAPE 252a5f0fb15SPaul Saab case A_SHELL: 253a5f0fb15SPaul Saab /* 254a5f0fb15SPaul Saab * !! just uses whatever is in shellcmd. 255a5f0fb15SPaul Saab * Otherwise, copy cmdbuf to shellcmd, 256a5f0fb15SPaul Saab * expanding any special characters ("%" or "#"). 257a5f0fb15SPaul Saab */ 258a5f0fb15SPaul Saab if (*cbuf != '!') 259a5f0fb15SPaul Saab { 260a5f0fb15SPaul Saab if (shellcmd != NULL) 261a5f0fb15SPaul Saab free(shellcmd); 262a5f0fb15SPaul Saab shellcmd = fexpand(cbuf); 263a5f0fb15SPaul Saab } 264a5f0fb15SPaul Saab 265a5f0fb15SPaul Saab if (secure) 266a5f0fb15SPaul Saab break; 267a5f0fb15SPaul Saab if (shellcmd == NULL) 268a5f0fb15SPaul Saab lsystem("", "!done"); 269a5f0fb15SPaul Saab else 270a5f0fb15SPaul Saab lsystem(shellcmd, "!done"); 271a5f0fb15SPaul Saab break; 272a5f0fb15SPaul Saab #endif 273a5f0fb15SPaul Saab #if PIPEC 274a5f0fb15SPaul Saab case A_PIPE: 275a5f0fb15SPaul Saab if (secure) 276a5f0fb15SPaul Saab break; 277a5f0fb15SPaul Saab (void) pipe_mark(pipec, cbuf); 278a5f0fb15SPaul Saab error("|done", NULL_PARG); 279a5f0fb15SPaul Saab break; 280a5f0fb15SPaul Saab #endif 281a5f0fb15SPaul Saab } 282a5f0fb15SPaul Saab } 283a5f0fb15SPaul Saab 284a5f0fb15SPaul Saab /* 285a5f0fb15SPaul Saab * Add a character to a multi-character command. 286a5f0fb15SPaul Saab */ 287a5f0fb15SPaul Saab static int 288a5f0fb15SPaul Saab mca_char(c) 289a5f0fb15SPaul Saab int c; 290a5f0fb15SPaul Saab { 291a5f0fb15SPaul Saab char *p; 292a5f0fb15SPaul Saab int flag; 293a5f0fb15SPaul Saab char buf[3]; 294a5f0fb15SPaul Saab PARG parg; 295a5f0fb15SPaul Saab 296a5f0fb15SPaul Saab switch (mca) 297a5f0fb15SPaul Saab { 298a5f0fb15SPaul Saab case 0: 299a5f0fb15SPaul Saab /* 300a5f0fb15SPaul Saab * Not in a multicharacter command. 301a5f0fb15SPaul Saab */ 302a5f0fb15SPaul Saab return (NO_MCA); 303a5f0fb15SPaul Saab 304a5f0fb15SPaul Saab case A_PREFIX: 305a5f0fb15SPaul Saab /* 306a5f0fb15SPaul Saab * In the prefix of a command. 307a5f0fb15SPaul Saab * This not considered a multichar command 308a5f0fb15SPaul Saab * (even tho it uses cmdbuf, etc.). 309a5f0fb15SPaul Saab * It is handled in the commands() switch. 310a5f0fb15SPaul Saab */ 311a5f0fb15SPaul Saab return (NO_MCA); 312a5f0fb15SPaul Saab 313a5f0fb15SPaul Saab case A_DIGIT: 314a5f0fb15SPaul Saab /* 315a5f0fb15SPaul Saab * Entering digits of a number. 316a5f0fb15SPaul Saab * Terminated by a non-digit. 317a5f0fb15SPaul Saab */ 318720c436cSXin LI if (!((c >= '0' && c <= '9') || c == '.') && 3198fd4165cSPaul Saab editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID) 320a5f0fb15SPaul Saab { 321a5f0fb15SPaul Saab /* 322a5f0fb15SPaul Saab * Not part of the number. 323a5f0fb15SPaul Saab * Treat as a normal command character. 324a5f0fb15SPaul Saab */ 325720c436cSXin LI number = cmd_int(&fraction); 326a5f0fb15SPaul Saab mca = 0; 327a5f0fb15SPaul Saab cmd_accept(); 328a5f0fb15SPaul Saab return (NO_MCA); 329a5f0fb15SPaul Saab } 330a5f0fb15SPaul Saab break; 331a5f0fb15SPaul Saab 332a5f0fb15SPaul Saab case A_OPT_TOGGLE: 333a5f0fb15SPaul Saab /* 334a5f0fb15SPaul Saab * Special case for the TOGGLE_OPTION command. 335a5f0fb15SPaul Saab * If the option letter which was entered is a 336a5f0fb15SPaul Saab * single-char option, execute the command immediately, 337a5f0fb15SPaul Saab * so user doesn't have to hit RETURN. 338a5f0fb15SPaul Saab * If the first char is + or -, this indicates 339a5f0fb15SPaul Saab * OPT_UNSET or OPT_SET respectively, instead of OPT_TOGGLE. 340a5f0fb15SPaul Saab * "--" begins inputting a long option name. 341a5f0fb15SPaul Saab */ 342a5f0fb15SPaul Saab if (optchar == '\0' && len_cmdbuf() == 0) 343a5f0fb15SPaul Saab { 344a5f0fb15SPaul Saab flag = (optflag & ~OPT_NO_PROMPT); 345a5f0fb15SPaul Saab if (flag == OPT_NO_TOGGLE) 346a5f0fb15SPaul Saab { 347a5f0fb15SPaul Saab switch (c) 348a5f0fb15SPaul Saab { 349a5f0fb15SPaul Saab case '_': 350a5f0fb15SPaul Saab /* "__" = long option name. */ 351a5f0fb15SPaul Saab optgetname = TRUE; 352a5f0fb15SPaul Saab mca_opt_toggle(); 353a5f0fb15SPaul Saab return (MCA_MORE); 354a5f0fb15SPaul Saab } 355a5f0fb15SPaul Saab } else 356a5f0fb15SPaul Saab { 357a5f0fb15SPaul Saab switch (c) 358a5f0fb15SPaul Saab { 359a5f0fb15SPaul Saab case '+': 360a5f0fb15SPaul Saab /* "-+" = UNSET. */ 361a5f0fb15SPaul Saab optflag = (flag == OPT_UNSET) ? 362a5f0fb15SPaul Saab OPT_TOGGLE : OPT_UNSET; 363a5f0fb15SPaul Saab mca_opt_toggle(); 364a5f0fb15SPaul Saab return (MCA_MORE); 365a5f0fb15SPaul Saab case '!': 366a5f0fb15SPaul Saab /* "-!" = SET */ 367a5f0fb15SPaul Saab optflag = (flag == OPT_SET) ? 368a5f0fb15SPaul Saab OPT_TOGGLE : OPT_SET; 369a5f0fb15SPaul Saab mca_opt_toggle(); 370a5f0fb15SPaul Saab return (MCA_MORE); 371a5f0fb15SPaul Saab case CONTROL('P'): 372a5f0fb15SPaul Saab optflag ^= OPT_NO_PROMPT; 373a5f0fb15SPaul Saab mca_opt_toggle(); 374a5f0fb15SPaul Saab return (MCA_MORE); 375a5f0fb15SPaul Saab case '-': 376a5f0fb15SPaul Saab /* "--" = long option name. */ 377a5f0fb15SPaul Saab optgetname = TRUE; 378a5f0fb15SPaul Saab mca_opt_toggle(); 379a5f0fb15SPaul Saab return (MCA_MORE); 380a5f0fb15SPaul Saab } 381a5f0fb15SPaul Saab } 382a5f0fb15SPaul Saab } 383a5f0fb15SPaul Saab if (optgetname) 384a5f0fb15SPaul Saab { 385a5f0fb15SPaul Saab /* 386a5f0fb15SPaul Saab * We're getting a long option name. 387a5f0fb15SPaul Saab * See if we've matched an option name yet. 388a5f0fb15SPaul Saab * If so, display the complete name and stop 389a5f0fb15SPaul Saab * accepting chars until user hits RETURN. 390a5f0fb15SPaul Saab */ 3911ede1615STim J. Robbins struct loption *o; 392a5f0fb15SPaul Saab char *oname; 393a5f0fb15SPaul Saab int lc; 394a5f0fb15SPaul Saab 395a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 396a5f0fb15SPaul Saab { 397a5f0fb15SPaul Saab /* 398a5f0fb15SPaul Saab * When the user hits RETURN, make sure 399a5f0fb15SPaul Saab * we've matched an option name, then 400a5f0fb15SPaul Saab * pretend he just entered the equivalent 401a5f0fb15SPaul Saab * option letter. 402a5f0fb15SPaul Saab */ 403a5f0fb15SPaul Saab if (optchar == '\0') 404a5f0fb15SPaul Saab { 405a5f0fb15SPaul Saab parg.p_string = get_cmdbuf(); 406a5f0fb15SPaul Saab error("There is no --%s option", &parg); 407a5f0fb15SPaul Saab return (MCA_DONE); 408a5f0fb15SPaul Saab } 409a5f0fb15SPaul Saab optgetname = FALSE; 410a5f0fb15SPaul Saab cmd_reset(); 411a5f0fb15SPaul Saab c = optchar; 412a5f0fb15SPaul Saab } else 413a5f0fb15SPaul Saab { 414a5f0fb15SPaul Saab if (optchar != '\0') 415a5f0fb15SPaul Saab { 416a5f0fb15SPaul Saab /* 417a5f0fb15SPaul Saab * Already have a match for the name. 418a5f0fb15SPaul Saab * Don't accept anything but erase/kill. 419a5f0fb15SPaul Saab */ 42089dd99dcSXin LI if (c == erase_char || 42189dd99dcSXin LI c == erase2_char || 42289dd99dcSXin LI c == kill_char) 423a5f0fb15SPaul Saab return (MCA_DONE); 424a5f0fb15SPaul Saab return (MCA_MORE); 425a5f0fb15SPaul Saab } 426a5f0fb15SPaul Saab /* 427a5f0fb15SPaul Saab * Add char to cmd buffer and try to match 428a5f0fb15SPaul Saab * the option name. 429a5f0fb15SPaul Saab */ 430a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT) 431a5f0fb15SPaul Saab return (MCA_DONE); 432a5f0fb15SPaul Saab p = get_cmdbuf(); 43389dd99dcSXin LI lc = ASCII_IS_LOWER(p[0]); 434a5f0fb15SPaul Saab o = findopt_name(&p, &oname, NULL); 435a5f0fb15SPaul Saab if (o != NULL) 436a5f0fb15SPaul Saab { 437a5f0fb15SPaul Saab /* 438a5f0fb15SPaul Saab * Got a match. 439a5f0fb15SPaul Saab * Remember the option letter and 440a5f0fb15SPaul Saab * display the full option name. 441a5f0fb15SPaul Saab */ 442a5f0fb15SPaul Saab optchar = o->oletter; 44389dd99dcSXin LI if (!lc && ASCII_IS_LOWER(optchar)) 44489dd99dcSXin LI optchar = ASCII_TO_UPPER(optchar); 445a5f0fb15SPaul Saab cmd_reset(); 446a5f0fb15SPaul Saab mca_opt_toggle(); 447a5f0fb15SPaul Saab for (p = oname; *p != '\0'; p++) 448a5f0fb15SPaul Saab { 449a5f0fb15SPaul Saab c = *p; 45089dd99dcSXin LI if (!lc && ASCII_IS_LOWER(c)) 45189dd99dcSXin LI c = ASCII_TO_UPPER(c); 452a5f0fb15SPaul Saab if (cmd_char(c) != CC_OK) 453a5f0fb15SPaul Saab return (MCA_DONE); 454a5f0fb15SPaul Saab } 455a5f0fb15SPaul Saab } 456a5f0fb15SPaul Saab return (MCA_MORE); 457a5f0fb15SPaul Saab } 458a5f0fb15SPaul Saab } else 459a5f0fb15SPaul Saab { 46089dd99dcSXin LI if (c == erase_char || c == erase2_char || c == kill_char) 461a5f0fb15SPaul Saab break; 462a5f0fb15SPaul Saab if (optchar != '\0') 463a5f0fb15SPaul Saab /* We already have the option letter. */ 464a5f0fb15SPaul Saab break; 465a5f0fb15SPaul Saab } 466a5f0fb15SPaul Saab 467a5f0fb15SPaul Saab optchar = c; 468a5f0fb15SPaul Saab if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE || 469a5f0fb15SPaul Saab single_char_option(c)) 470a5f0fb15SPaul Saab { 471a5f0fb15SPaul Saab toggle_option(c, "", optflag); 472a5f0fb15SPaul Saab return (MCA_DONE); 473a5f0fb15SPaul Saab } 474a5f0fb15SPaul Saab /* 475a5f0fb15SPaul Saab * Display a prompt appropriate for the option letter. 476a5f0fb15SPaul Saab */ 477a5f0fb15SPaul Saab if ((p = opt_prompt(c)) == NULL) 478a5f0fb15SPaul Saab { 479a5f0fb15SPaul Saab buf[0] = '-'; 480a5f0fb15SPaul Saab buf[1] = c; 481a5f0fb15SPaul Saab buf[2] = '\0'; 482a5f0fb15SPaul Saab p = buf; 483a5f0fb15SPaul Saab } 484a5f0fb15SPaul Saab start_mca(A_OPT_TOGGLE, p, (void*)NULL, 0); 485a5f0fb15SPaul Saab return (MCA_MORE); 486a5f0fb15SPaul Saab 487a5f0fb15SPaul Saab case A_F_SEARCH: 488a5f0fb15SPaul Saab case A_B_SEARCH: 4897374caaaSXin LI case A_FILTER: 490a5f0fb15SPaul Saab /* 491a5f0fb15SPaul Saab * Special case for search commands. 492a5f0fb15SPaul Saab * Certain characters as the first char of 493a5f0fb15SPaul Saab * the pattern have special meaning: 494a5f0fb15SPaul Saab * ! Toggle the NO_MATCH flag 495a5f0fb15SPaul Saab * * Toggle the PAST_EOF flag 496a5f0fb15SPaul Saab * @ Toggle the FIRST_FILE flag 497a5f0fb15SPaul Saab */ 498a5f0fb15SPaul Saab if (len_cmdbuf() > 0) 499a5f0fb15SPaul Saab /* 500a5f0fb15SPaul Saab * Only works for the first char of the pattern. 501a5f0fb15SPaul Saab */ 502a5f0fb15SPaul Saab break; 503a5f0fb15SPaul Saab 504a5f0fb15SPaul Saab flag = 0; 505a5f0fb15SPaul Saab switch (c) 506a5f0fb15SPaul Saab { 507a5f0fb15SPaul Saab case '*': 508720c436cSXin LI if (less_is_more) 509a8f92a7cSPaul Saab break; 510a8f92a7cSPaul Saab case CONTROL('E'): /* ignore END of file */ 5117374caaaSXin LI if (mca != A_FILTER) 512a5f0fb15SPaul Saab flag = SRCH_PAST_EOF; 513a5f0fb15SPaul Saab break; 514a5f0fb15SPaul Saab case '@': 515720c436cSXin LI if (less_is_more) 516a8f92a7cSPaul Saab break; 517a8f92a7cSPaul Saab case CONTROL('F'): /* FIRST file */ 5187374caaaSXin LI if (mca != A_FILTER) 519a5f0fb15SPaul Saab flag = SRCH_FIRST_FILE; 520a5f0fb15SPaul Saab break; 521a5f0fb15SPaul Saab case CONTROL('K'): /* KEEP position */ 5227374caaaSXin LI if (mca != A_FILTER) 523a5f0fb15SPaul Saab flag = SRCH_NO_MOVE; 524a5f0fb15SPaul Saab break; 525a5f0fb15SPaul Saab case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */ 526a5f0fb15SPaul Saab flag = SRCH_NO_REGEX; 527a5f0fb15SPaul Saab break; 528a5f0fb15SPaul Saab case CONTROL('N'): /* NOT match */ 529a5f0fb15SPaul Saab case '!': 530a5f0fb15SPaul Saab flag = SRCH_NO_MATCH; 531a5f0fb15SPaul Saab break; 532a5f0fb15SPaul Saab } 533a5f0fb15SPaul Saab if (flag != 0) 534a5f0fb15SPaul Saab { 535a5f0fb15SPaul Saab search_type ^= flag; 536a5f0fb15SPaul Saab mca_search(); 537a5f0fb15SPaul Saab return (MCA_MORE); 538a5f0fb15SPaul Saab } 539a5f0fb15SPaul Saab break; 540a5f0fb15SPaul Saab } 541a5f0fb15SPaul Saab 542a5f0fb15SPaul Saab /* 543a5f0fb15SPaul Saab * Any other multicharacter command 544a5f0fb15SPaul Saab * is terminated by a newline. 545a5f0fb15SPaul Saab */ 546a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 547a5f0fb15SPaul Saab { 548a5f0fb15SPaul Saab /* 549a5f0fb15SPaul Saab * Execute the command. 550a5f0fb15SPaul Saab */ 551a5f0fb15SPaul Saab exec_mca(); 552a5f0fb15SPaul Saab return (MCA_DONE); 553a5f0fb15SPaul Saab } 554a5f0fb15SPaul Saab 555a5f0fb15SPaul Saab /* 556a5f0fb15SPaul Saab * Append the char to the command buffer. 557a5f0fb15SPaul Saab */ 558a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT) 559a5f0fb15SPaul Saab /* 560a5f0fb15SPaul Saab * Abort the multi-char command. 561a5f0fb15SPaul Saab */ 562a5f0fb15SPaul Saab return (MCA_DONE); 563a5f0fb15SPaul Saab 564a5f0fb15SPaul Saab if ((mca == A_F_BRACKET || mca == A_B_BRACKET) && len_cmdbuf() >= 2) 565a5f0fb15SPaul Saab { 566a5f0fb15SPaul Saab /* 567a5f0fb15SPaul Saab * Special case for the bracket-matching commands. 568a5f0fb15SPaul Saab * Execute the command after getting exactly two 569a5f0fb15SPaul Saab * characters from the user. 570a5f0fb15SPaul Saab */ 571a5f0fb15SPaul Saab exec_mca(); 572a5f0fb15SPaul Saab return (MCA_DONE); 573a5f0fb15SPaul Saab } 574a5f0fb15SPaul Saab 575a5f0fb15SPaul Saab /* 576a5f0fb15SPaul Saab * Need another character. 577a5f0fb15SPaul Saab */ 578a5f0fb15SPaul Saab return (MCA_MORE); 579a5f0fb15SPaul Saab } 580a5f0fb15SPaul Saab 581a5f0fb15SPaul Saab /* 582423c5ce5SXin LI * Discard any buffered file data. 583423c5ce5SXin LI */ 584423c5ce5SXin LI static void 585423c5ce5SXin LI clear_buffers() 586423c5ce5SXin LI { 587423c5ce5SXin LI if (!(ch_getflags() & CH_CANSEEK)) 588423c5ce5SXin LI return; 589423c5ce5SXin LI ch_flush(); 590423c5ce5SXin LI clr_linenum(); 591423c5ce5SXin LI #if HILITE_SEARCH 592423c5ce5SXin LI clr_hilite(); 593423c5ce5SXin LI #endif 594423c5ce5SXin LI } 595423c5ce5SXin LI 596423c5ce5SXin LI /* 597a5f0fb15SPaul Saab * Make sure the screen is displayed. 598a5f0fb15SPaul Saab */ 599a5f0fb15SPaul Saab static void 600a5f0fb15SPaul Saab make_display() 601a5f0fb15SPaul Saab { 602a5f0fb15SPaul Saab /* 603a5f0fb15SPaul Saab * If nothing is displayed yet, display starting from initial_scrpos. 604a5f0fb15SPaul Saab */ 605a5f0fb15SPaul Saab if (empty_screen()) 606a5f0fb15SPaul Saab { 607a5f0fb15SPaul Saab if (initial_scrpos.pos == NULL_POSITION) 608a5f0fb15SPaul Saab /* 609a5f0fb15SPaul Saab * {{ Maybe this should be: 610a5f0fb15SPaul Saab * jump_loc(ch_zero(), jump_sline); 611a5f0fb15SPaul Saab * but this behavior seems rather unexpected 612a5f0fb15SPaul Saab * on the first screen. }} 613a5f0fb15SPaul Saab */ 614a5f0fb15SPaul Saab jump_loc(ch_zero(), 1); 615a5f0fb15SPaul Saab else 616a5f0fb15SPaul Saab jump_loc(initial_scrpos.pos, initial_scrpos.ln); 617a5f0fb15SPaul Saab } else if (screen_trashed) 618a5f0fb15SPaul Saab { 619423c5ce5SXin LI int save_top_scroll = top_scroll; 620423c5ce5SXin LI int save_ignore_eoi = ignore_eoi; 621a5f0fb15SPaul Saab top_scroll = 1; 622423c5ce5SXin LI ignore_eoi = 0; 623423c5ce5SXin LI if (screen_trashed == 2) 624423c5ce5SXin LI { 625423c5ce5SXin LI /* Special case used by ignore_eoi: re-open the input file 626423c5ce5SXin LI * and jump to the end of the file. */ 627423c5ce5SXin LI reopen_curr_ifile(); 628423c5ce5SXin LI jump_forw(); 629423c5ce5SXin LI } 630a5f0fb15SPaul Saab repaint(); 631a5f0fb15SPaul Saab top_scroll = save_top_scroll; 632423c5ce5SXin LI ignore_eoi = save_ignore_eoi; 633a5f0fb15SPaul Saab } 634a5f0fb15SPaul Saab } 635a5f0fb15SPaul Saab 636a5f0fb15SPaul Saab /* 637a5f0fb15SPaul Saab * Display the appropriate prompt. 638a5f0fb15SPaul Saab */ 639a5f0fb15SPaul Saab static void 640a5f0fb15SPaul Saab prompt() 641a5f0fb15SPaul Saab { 642a5f0fb15SPaul Saab register char *p; 643a5f0fb15SPaul Saab 644a5f0fb15SPaul Saab if (ungotp != NULL && ungotp > ungot) 645a5f0fb15SPaul Saab { 646a5f0fb15SPaul Saab /* 647a5f0fb15SPaul Saab * No prompt necessary if commands are from 648a5f0fb15SPaul Saab * ungotten chars rather than from the user. 649a5f0fb15SPaul Saab */ 650a5f0fb15SPaul Saab return; 651a5f0fb15SPaul Saab } 652a5f0fb15SPaul Saab 653a5f0fb15SPaul Saab /* 654a5f0fb15SPaul Saab * Make sure the screen is displayed. 655a5f0fb15SPaul Saab */ 656a5f0fb15SPaul Saab make_display(); 657a5f0fb15SPaul Saab bottompos = position(BOTTOM_PLUS_ONE); 658a5f0fb15SPaul Saab 659a5f0fb15SPaul Saab /* 6607374caaaSXin LI * If we've hit EOF on the last file and the -E flag is set, quit. 661a5f0fb15SPaul Saab */ 6627374caaaSXin LI if (get_quit_at_eof() == OPT_ONPLUS && 6637374caaaSXin LI eof_displayed() && !(ch_getflags() & CH_HELPFILE) && 664a5f0fb15SPaul Saab next_ifile(curr_ifile) == NULL_IFILE) 665a5f0fb15SPaul Saab quit(QUIT_OK); 6667374caaaSXin LI 667a5f0fb15SPaul Saab /* 6687374caaaSXin LI * If the entire file is displayed and the -F flag is set, quit. 669a5f0fb15SPaul Saab */ 6707374caaaSXin LI if (quit_if_one_screen && 6717374caaaSXin LI entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) && 672a5f0fb15SPaul Saab next_ifile(curr_ifile) == NULL_IFILE) 673a5f0fb15SPaul Saab quit(QUIT_OK); 674a5f0fb15SPaul Saab 6758fd4165cSPaul Saab #if MSDOS_COMPILER==WIN32C 6768fd4165cSPaul Saab /* 6778fd4165cSPaul Saab * In Win32, display the file name in the window title. 6788fd4165cSPaul Saab */ 6798fd4165cSPaul Saab if (!(ch_getflags() & CH_HELPFILE)) 6808fd4165cSPaul Saab SetConsoleTitle(pr_expand("Less?f - %f.", 0)); 6818fd4165cSPaul Saab #endif 682a5f0fb15SPaul Saab /* 683a5f0fb15SPaul Saab * Select the proper prompt and display it. 684a5f0fb15SPaul Saab */ 685720c436cSXin LI /* 686720c436cSXin LI * If the previous action was a forward movement, 687720c436cSXin LI * don't clear the bottom line of the display; 688720c436cSXin LI * just print the prompt since the forward movement guarantees 689720c436cSXin LI * that we're in the right position to display the prompt. 690720c436cSXin LI * Clearing the line could cause a problem: for example, if the last 691720c436cSXin LI * line displayed ended at the right screen edge without a newline, 692720c436cSXin LI * then clearing would clear the last displayed line rather than 693720c436cSXin LI * the prompt line. 694720c436cSXin LI */ 695720c436cSXin LI if (!forw_prompt) 696720c436cSXin LI clear_bot(); 697a5f0fb15SPaul Saab clear_cmd(); 698720c436cSXin LI forw_prompt = 0; 699a5f0fb15SPaul Saab p = pr_string(); 7007374caaaSXin LI if (is_filtering()) 7017374caaaSXin LI putstr("& "); 70289dd99dcSXin LI if (p == NULL || *p == '\0') 703a5f0fb15SPaul Saab putchr(':'); 704a5f0fb15SPaul Saab else 705a5f0fb15SPaul Saab { 70689dd99dcSXin LI at_enter(AT_STANDOUT); 707a5f0fb15SPaul Saab putstr(p); 70889dd99dcSXin LI at_exit(); 709a5f0fb15SPaul Saab } 710720c436cSXin LI clear_eol(); 711a5f0fb15SPaul Saab } 712a5f0fb15SPaul Saab 713a5f0fb15SPaul Saab /* 714a5f0fb15SPaul Saab * Display the less version message. 715a5f0fb15SPaul Saab */ 716a5f0fb15SPaul Saab public void 717a5f0fb15SPaul Saab dispversion() 718a5f0fb15SPaul Saab { 719a5f0fb15SPaul Saab PARG parg; 720a5f0fb15SPaul Saab 721a5f0fb15SPaul Saab parg.p_string = version; 722a5f0fb15SPaul Saab error("less %s", &parg); 723a5f0fb15SPaul Saab } 724a5f0fb15SPaul Saab 725a5f0fb15SPaul Saab /* 726a5f0fb15SPaul Saab * Get command character. 727a5f0fb15SPaul Saab * The character normally comes from the keyboard, 728a5f0fb15SPaul Saab * but may come from ungotten characters 729a5f0fb15SPaul Saab * (characters previously given to ungetcc or ungetsc). 730a5f0fb15SPaul Saab */ 731a5f0fb15SPaul Saab public int 732a5f0fb15SPaul Saab getcc() 733a5f0fb15SPaul Saab { 734a5f0fb15SPaul Saab if (ungotp == NULL) 735a5f0fb15SPaul Saab /* 736a5f0fb15SPaul Saab * Normal case: no ungotten chars, so get one from the user. 737a5f0fb15SPaul Saab */ 738a5f0fb15SPaul Saab return (getchr()); 739a5f0fb15SPaul Saab 740a5f0fb15SPaul Saab if (ungotp > ungot) 741a5f0fb15SPaul Saab /* 742a5f0fb15SPaul Saab * Return the next ungotten char. 743a5f0fb15SPaul Saab */ 744a5f0fb15SPaul Saab return (*--ungotp); 745a5f0fb15SPaul Saab 746a5f0fb15SPaul Saab /* 747a5f0fb15SPaul Saab * We have just run out of ungotten chars. 748a5f0fb15SPaul Saab */ 749a5f0fb15SPaul Saab ungotp = NULL; 750a5f0fb15SPaul Saab if (len_cmdbuf() == 0 || !empty_screen()) 751a5f0fb15SPaul Saab return (getchr()); 752a5f0fb15SPaul Saab /* 753a5f0fb15SPaul Saab * Command is incomplete, so try to complete it. 754a5f0fb15SPaul Saab */ 755a5f0fb15SPaul Saab switch (mca) 756a5f0fb15SPaul Saab { 757a5f0fb15SPaul Saab case A_DIGIT: 758a5f0fb15SPaul Saab /* 759a5f0fb15SPaul Saab * We have a number but no command. Treat as #g. 760a5f0fb15SPaul Saab */ 761a5f0fb15SPaul Saab return ('g'); 762a5f0fb15SPaul Saab 763a5f0fb15SPaul Saab case A_F_SEARCH: 764a5f0fb15SPaul Saab case A_B_SEARCH: 765a5f0fb15SPaul Saab /* 766a5f0fb15SPaul Saab * We have "/string" but no newline. Add the \n. 767a5f0fb15SPaul Saab */ 768a5f0fb15SPaul Saab return ('\n'); 769a5f0fb15SPaul Saab 770a5f0fb15SPaul Saab default: 771a5f0fb15SPaul Saab /* 772a5f0fb15SPaul Saab * Some other incomplete command. Let user complete it. 773a5f0fb15SPaul Saab */ 774a5f0fb15SPaul Saab return (getchr()); 775a5f0fb15SPaul Saab } 776a5f0fb15SPaul Saab } 777a5f0fb15SPaul Saab 778a5f0fb15SPaul Saab /* 779a5f0fb15SPaul Saab * "Unget" a command character. 780a5f0fb15SPaul Saab * The next getcc() will return this character. 781a5f0fb15SPaul Saab */ 782a5f0fb15SPaul Saab public void 783a5f0fb15SPaul Saab ungetcc(c) 784a5f0fb15SPaul Saab int c; 785a5f0fb15SPaul Saab { 786a5f0fb15SPaul Saab if (ungotp == NULL) 787a5f0fb15SPaul Saab ungotp = ungot; 788a5f0fb15SPaul Saab if (ungotp >= ungot + sizeof(ungot)) 789a5f0fb15SPaul Saab { 790a5f0fb15SPaul Saab error("ungetcc overflow", NULL_PARG); 791a5f0fb15SPaul Saab quit(QUIT_ERROR); 792a5f0fb15SPaul Saab } 793a5f0fb15SPaul Saab *ungotp++ = c; 794a5f0fb15SPaul Saab } 795a5f0fb15SPaul Saab 796a5f0fb15SPaul Saab /* 797a5f0fb15SPaul Saab * Unget a whole string of command characters. 798a5f0fb15SPaul Saab * The next sequence of getcc()'s will return this string. 799a5f0fb15SPaul Saab */ 800a5f0fb15SPaul Saab public void 801a5f0fb15SPaul Saab ungetsc(s) 802a5f0fb15SPaul Saab char *s; 803a5f0fb15SPaul Saab { 804a5f0fb15SPaul Saab register char *p; 805a5f0fb15SPaul Saab 806a5f0fb15SPaul Saab for (p = s + strlen(s) - 1; p >= s; p--) 807a5f0fb15SPaul Saab ungetcc(*p); 808a5f0fb15SPaul Saab } 809a5f0fb15SPaul Saab 810a5f0fb15SPaul Saab /* 811a5f0fb15SPaul Saab * Search for a pattern, possibly in multiple files. 812a5f0fb15SPaul Saab * If SRCH_FIRST_FILE is set, begin searching at the first file. 813a5f0fb15SPaul Saab * If SRCH_PAST_EOF is set, continue the search thru multiple files. 814a5f0fb15SPaul Saab */ 815a5f0fb15SPaul Saab static void 816a5f0fb15SPaul Saab multi_search(pattern, n) 817a5f0fb15SPaul Saab char *pattern; 818a5f0fb15SPaul Saab int n; 819a5f0fb15SPaul Saab { 820a5f0fb15SPaul Saab register int nomore; 821a5f0fb15SPaul Saab IFILE save_ifile; 822a5f0fb15SPaul Saab int changed_file; 823a5f0fb15SPaul Saab 824a5f0fb15SPaul Saab changed_file = 0; 825a5f0fb15SPaul Saab save_ifile = save_curr_ifile(); 826a5f0fb15SPaul Saab 827a5f0fb15SPaul Saab if (search_type & SRCH_FIRST_FILE) 828a5f0fb15SPaul Saab { 829a5f0fb15SPaul Saab /* 830a5f0fb15SPaul Saab * Start at the first (or last) file 831a5f0fb15SPaul Saab * in the command line list. 832a5f0fb15SPaul Saab */ 833a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 834a5f0fb15SPaul Saab nomore = edit_first(); 835a5f0fb15SPaul Saab else 836a5f0fb15SPaul Saab nomore = edit_last(); 837a5f0fb15SPaul Saab if (nomore) 838a5f0fb15SPaul Saab { 839a5f0fb15SPaul Saab unsave_ifile(save_ifile); 840a5f0fb15SPaul Saab return; 841a5f0fb15SPaul Saab } 842a5f0fb15SPaul Saab changed_file = 1; 843a5f0fb15SPaul Saab search_type &= ~SRCH_FIRST_FILE; 844a5f0fb15SPaul Saab } 845a5f0fb15SPaul Saab 846a5f0fb15SPaul Saab for (;;) 847a5f0fb15SPaul Saab { 848a5f0fb15SPaul Saab n = search(search_type, pattern, n); 849a5f0fb15SPaul Saab /* 850a5f0fb15SPaul Saab * The SRCH_NO_MOVE flag doesn't "stick": it gets cleared 851a5f0fb15SPaul Saab * after being used once. This allows "n" to work after 852a5f0fb15SPaul Saab * using a /@@ search. 853a5f0fb15SPaul Saab */ 854a5f0fb15SPaul Saab search_type &= ~SRCH_NO_MOVE; 855a5f0fb15SPaul Saab if (n == 0) 856a5f0fb15SPaul Saab { 857a5f0fb15SPaul Saab /* 858a5f0fb15SPaul Saab * Found it. 859a5f0fb15SPaul Saab */ 860a5f0fb15SPaul Saab unsave_ifile(save_ifile); 861a5f0fb15SPaul Saab return; 862a5f0fb15SPaul Saab } 863a5f0fb15SPaul Saab 864a5f0fb15SPaul Saab if (n < 0) 865a5f0fb15SPaul Saab /* 866a5f0fb15SPaul Saab * Some kind of error in the search. 867a5f0fb15SPaul Saab * Error message has been printed by search(). 868a5f0fb15SPaul Saab */ 869a5f0fb15SPaul Saab break; 870a5f0fb15SPaul Saab 871a5f0fb15SPaul Saab if ((search_type & SRCH_PAST_EOF) == 0) 872a5f0fb15SPaul Saab /* 873a5f0fb15SPaul Saab * We didn't find a match, but we're 874a5f0fb15SPaul Saab * supposed to search only one file. 875a5f0fb15SPaul Saab */ 876a5f0fb15SPaul Saab break; 877a5f0fb15SPaul Saab /* 878a5f0fb15SPaul Saab * Move on to the next file. 879a5f0fb15SPaul Saab */ 880a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 881a5f0fb15SPaul Saab nomore = edit_next(1); 882a5f0fb15SPaul Saab else 883a5f0fb15SPaul Saab nomore = edit_prev(1); 884a5f0fb15SPaul Saab if (nomore) 885a5f0fb15SPaul Saab break; 886a5f0fb15SPaul Saab changed_file = 1; 887a5f0fb15SPaul Saab } 888a5f0fb15SPaul Saab 889a5f0fb15SPaul Saab /* 890a5f0fb15SPaul Saab * Didn't find it. 891a5f0fb15SPaul Saab * Print an error message if we haven't already. 892a5f0fb15SPaul Saab */ 893a5f0fb15SPaul Saab if (n > 0) 894a5f0fb15SPaul Saab error("Pattern not found", NULL_PARG); 895a5f0fb15SPaul Saab 896a5f0fb15SPaul Saab if (changed_file) 897a5f0fb15SPaul Saab { 898a5f0fb15SPaul Saab /* 899a5f0fb15SPaul Saab * Restore the file we were originally viewing. 900a5f0fb15SPaul Saab */ 901a5f0fb15SPaul Saab reedit_ifile(save_ifile); 90289dd99dcSXin LI } else 90389dd99dcSXin LI { 90489dd99dcSXin LI unsave_ifile(save_ifile); 905a5f0fb15SPaul Saab } 906a5f0fb15SPaul Saab } 907a5f0fb15SPaul Saab 908a5f0fb15SPaul Saab /* 909a5f0fb15SPaul Saab * Main command processor. 910a5f0fb15SPaul Saab * Accept and execute commands until a quit command. 911a5f0fb15SPaul Saab */ 912a5f0fb15SPaul Saab public void 913a5f0fb15SPaul Saab commands() 914a5f0fb15SPaul Saab { 915a5f0fb15SPaul Saab register int c; 916a5f0fb15SPaul Saab register int action; 917a5f0fb15SPaul Saab register char *cbuf; 918a5f0fb15SPaul Saab int newaction; 919a5f0fb15SPaul Saab int save_search_type; 920a5f0fb15SPaul Saab char *extra; 921a5f0fb15SPaul Saab char tbuf[2]; 922a5f0fb15SPaul Saab PARG parg; 923a5f0fb15SPaul Saab IFILE old_ifile; 924a5f0fb15SPaul Saab IFILE new_ifile; 9258fd4165cSPaul Saab char *tagfile; 926a5f0fb15SPaul Saab 927a5f0fb15SPaul Saab search_type = SRCH_FORW; 928a5f0fb15SPaul Saab wscroll = (sc_height + 1) / 2; 929a5f0fb15SPaul Saab newaction = A_NOACTION; 930a5f0fb15SPaul Saab 931a5f0fb15SPaul Saab for (;;) 932a5f0fb15SPaul Saab { 933a5f0fb15SPaul Saab mca = 0; 934a5f0fb15SPaul Saab cmd_accept(); 935a5f0fb15SPaul Saab number = 0; 936a5f0fb15SPaul Saab optchar = '\0'; 937a5f0fb15SPaul Saab 938a5f0fb15SPaul Saab /* 939a5f0fb15SPaul Saab * See if any signals need processing. 940a5f0fb15SPaul Saab */ 941a5f0fb15SPaul Saab if (sigs) 942a5f0fb15SPaul Saab { 943a5f0fb15SPaul Saab psignals(); 944a5f0fb15SPaul Saab if (quitting) 945a5f0fb15SPaul Saab quit(QUIT_SAVED_STATUS); 946a5f0fb15SPaul Saab } 947a5f0fb15SPaul Saab 948a5f0fb15SPaul Saab /* 949a5f0fb15SPaul Saab * See if window size changed, for systems that don't 950a5f0fb15SPaul Saab * generate SIGWINCH. 951a5f0fb15SPaul Saab */ 952a5f0fb15SPaul Saab check_winch(); 953a5f0fb15SPaul Saab 954a5f0fb15SPaul Saab /* 955a5f0fb15SPaul Saab * Display prompt and accept a character. 956a5f0fb15SPaul Saab */ 957a5f0fb15SPaul Saab cmd_reset(); 958a5f0fb15SPaul Saab prompt(); 959a5f0fb15SPaul Saab if (sigs) 960a5f0fb15SPaul Saab continue; 961a5f0fb15SPaul Saab if (newaction == A_NOACTION) 962a5f0fb15SPaul Saab c = getcc(); 963a5f0fb15SPaul Saab 964a5f0fb15SPaul Saab again: 965a5f0fb15SPaul Saab if (sigs) 966a5f0fb15SPaul Saab continue; 967a5f0fb15SPaul Saab 968a5f0fb15SPaul Saab if (newaction != A_NOACTION) 969a5f0fb15SPaul Saab { 970a5f0fb15SPaul Saab action = newaction; 971a5f0fb15SPaul Saab newaction = A_NOACTION; 972a5f0fb15SPaul Saab } else 973a5f0fb15SPaul Saab { 974a5f0fb15SPaul Saab /* 975a5f0fb15SPaul Saab * If we are in a multicharacter command, call mca_char. 976a5f0fb15SPaul Saab * Otherwise we call fcmd_decode to determine the 977a5f0fb15SPaul Saab * action to be performed. 978a5f0fb15SPaul Saab */ 979a5f0fb15SPaul Saab if (mca) 980a5f0fb15SPaul Saab switch (mca_char(c)) 981a5f0fb15SPaul Saab { 982a5f0fb15SPaul Saab case MCA_MORE: 983a5f0fb15SPaul Saab /* 984a5f0fb15SPaul Saab * Need another character. 985a5f0fb15SPaul Saab */ 986a5f0fb15SPaul Saab c = getcc(); 987a5f0fb15SPaul Saab goto again; 988a5f0fb15SPaul Saab case MCA_DONE: 989a5f0fb15SPaul Saab /* 990a5f0fb15SPaul Saab * Command has been handled by mca_char. 991a5f0fb15SPaul Saab * Start clean with a prompt. 992a5f0fb15SPaul Saab */ 993a5f0fb15SPaul Saab continue; 994a5f0fb15SPaul Saab case NO_MCA: 995a5f0fb15SPaul Saab /* 996a5f0fb15SPaul Saab * Not a multi-char command 997a5f0fb15SPaul Saab * (at least, not anymore). 998a5f0fb15SPaul Saab */ 999a5f0fb15SPaul Saab break; 1000a5f0fb15SPaul Saab } 1001a5f0fb15SPaul Saab 1002a5f0fb15SPaul Saab /* 1003a5f0fb15SPaul Saab * Decode the command character and decide what to do. 1004a5f0fb15SPaul Saab */ 1005a5f0fb15SPaul Saab if (mca) 1006a5f0fb15SPaul Saab { 1007a5f0fb15SPaul Saab /* 1008a5f0fb15SPaul Saab * We're in a multichar command. 1009a5f0fb15SPaul Saab * Add the character to the command buffer 1010a5f0fb15SPaul Saab * and display it on the screen. 1011a5f0fb15SPaul Saab * If the user backspaces past the start 1012a5f0fb15SPaul Saab * of the line, abort the command. 1013a5f0fb15SPaul Saab */ 1014a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0) 1015a5f0fb15SPaul Saab continue; 1016a5f0fb15SPaul Saab cbuf = get_cmdbuf(); 1017a5f0fb15SPaul Saab } else 1018a5f0fb15SPaul Saab { 1019a5f0fb15SPaul Saab /* 1020a5f0fb15SPaul Saab * Don't use cmd_char if we're starting fresh 1021a5f0fb15SPaul Saab * at the beginning of a command, because we 1022a5f0fb15SPaul Saab * don't want to echo the command until we know 1023a5f0fb15SPaul Saab * it is a multichar command. We also don't 1024a5f0fb15SPaul Saab * want erase_char/kill_char to be treated 1025a5f0fb15SPaul Saab * as line editing characters. 1026a5f0fb15SPaul Saab */ 1027a5f0fb15SPaul Saab tbuf[0] = c; 1028a5f0fb15SPaul Saab tbuf[1] = '\0'; 1029a5f0fb15SPaul Saab cbuf = tbuf; 1030a5f0fb15SPaul Saab } 1031a5f0fb15SPaul Saab extra = NULL; 1032a5f0fb15SPaul Saab action = fcmd_decode(cbuf, &extra); 1033a5f0fb15SPaul Saab /* 1034a5f0fb15SPaul Saab * If an "extra" string was returned, 1035a5f0fb15SPaul Saab * process it as a string of command characters. 1036a5f0fb15SPaul Saab */ 1037a5f0fb15SPaul Saab if (extra != NULL) 1038a5f0fb15SPaul Saab ungetsc(extra); 1039a5f0fb15SPaul Saab } 1040a5f0fb15SPaul Saab /* 1041a5f0fb15SPaul Saab * Clear the cmdbuf string. 1042a5f0fb15SPaul Saab * (But not if we're in the prefix of a command, 1043a5f0fb15SPaul Saab * because the partial command string is kept there.) 1044a5f0fb15SPaul Saab */ 1045a5f0fb15SPaul Saab if (action != A_PREFIX) 1046a5f0fb15SPaul Saab cmd_reset(); 1047a5f0fb15SPaul Saab 1048a5f0fb15SPaul Saab switch (action) 1049a5f0fb15SPaul Saab { 1050a5f0fb15SPaul Saab case A_DIGIT: 1051a5f0fb15SPaul Saab /* 1052a5f0fb15SPaul Saab * First digit of a number. 1053a5f0fb15SPaul Saab */ 1054a5f0fb15SPaul Saab start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE); 1055a5f0fb15SPaul Saab goto again; 1056a5f0fb15SPaul Saab 1057a5f0fb15SPaul Saab case A_F_WINDOW: 1058a5f0fb15SPaul Saab /* 1059a5f0fb15SPaul Saab * Forward one window (and set the window size). 1060a5f0fb15SPaul Saab */ 1061a5f0fb15SPaul Saab if (number > 0) 10621ede1615STim J. Robbins swindow = (int) number; 1063a5f0fb15SPaul Saab /* FALLTHRU */ 1064a5f0fb15SPaul Saab case A_F_SCREEN: 1065a5f0fb15SPaul Saab /* 1066a5f0fb15SPaul Saab * Forward one screen. 1067a5f0fb15SPaul Saab */ 1068a5f0fb15SPaul Saab if (number <= 0) 1069a5f0fb15SPaul Saab number = get_swindow(); 1070a5f0fb15SPaul Saab cmd_exec(); 1071a5f0fb15SPaul Saab if (show_attn) 1072a5f0fb15SPaul Saab set_attnpos(bottompos); 10731ede1615STim J. Robbins forward((int) number, 0, 1); 1074a5f0fb15SPaul Saab break; 1075a5f0fb15SPaul Saab 1076a5f0fb15SPaul Saab case A_B_WINDOW: 1077a5f0fb15SPaul Saab /* 1078a5f0fb15SPaul Saab * Backward one window (and set the window size). 1079a5f0fb15SPaul Saab */ 1080a5f0fb15SPaul Saab if (number > 0) 10811ede1615STim J. Robbins swindow = (int) number; 1082a5f0fb15SPaul Saab /* FALLTHRU */ 1083a5f0fb15SPaul Saab case A_B_SCREEN: 1084a5f0fb15SPaul Saab /* 1085a5f0fb15SPaul Saab * Backward one screen. 1086a5f0fb15SPaul Saab */ 1087a5f0fb15SPaul Saab if (number <= 0) 1088a5f0fb15SPaul Saab number = get_swindow(); 1089a5f0fb15SPaul Saab cmd_exec(); 10901ede1615STim J. Robbins backward((int) number, 0, 1); 1091a5f0fb15SPaul Saab break; 1092a5f0fb15SPaul Saab 1093a5f0fb15SPaul Saab case A_F_LINE: 1094a5f0fb15SPaul Saab /* 1095a5f0fb15SPaul Saab * Forward N (default 1) line. 1096a5f0fb15SPaul Saab */ 1097a5f0fb15SPaul Saab if (number <= 0) 1098a5f0fb15SPaul Saab number = 1; 1099a5f0fb15SPaul Saab cmd_exec(); 1100a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS && number > 1) 1101a5f0fb15SPaul Saab set_attnpos(bottompos); 11021ede1615STim J. Robbins forward((int) number, 0, 0); 1103a5f0fb15SPaul Saab break; 1104a5f0fb15SPaul Saab 1105a5f0fb15SPaul Saab case A_B_LINE: 1106a5f0fb15SPaul Saab /* 1107a5f0fb15SPaul Saab * Backward N (default 1) line. 1108a5f0fb15SPaul Saab */ 1109a5f0fb15SPaul Saab if (number <= 0) 1110a5f0fb15SPaul Saab number = 1; 1111a5f0fb15SPaul Saab cmd_exec(); 11121ede1615STim J. Robbins backward((int) number, 0, 0); 1113a5f0fb15SPaul Saab break; 1114a5f0fb15SPaul Saab 1115a5f0fb15SPaul Saab case A_FF_LINE: 1116a5f0fb15SPaul Saab /* 1117a5f0fb15SPaul Saab * Force forward N (default 1) line. 1118a5f0fb15SPaul Saab */ 1119a5f0fb15SPaul Saab if (number <= 0) 1120a5f0fb15SPaul Saab number = 1; 1121a5f0fb15SPaul Saab cmd_exec(); 1122a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS && number > 1) 1123a5f0fb15SPaul Saab set_attnpos(bottompos); 11241ede1615STim J. Robbins forward((int) number, 1, 0); 1125a5f0fb15SPaul Saab break; 1126a5f0fb15SPaul Saab 1127a5f0fb15SPaul Saab case A_BF_LINE: 1128a5f0fb15SPaul Saab /* 1129a5f0fb15SPaul Saab * Force backward N (default 1) line. 1130a5f0fb15SPaul Saab */ 1131a5f0fb15SPaul Saab if (number <= 0) 1132a5f0fb15SPaul Saab number = 1; 1133a5f0fb15SPaul Saab cmd_exec(); 11341ede1615STim J. Robbins backward((int) number, 1, 0); 1135a5f0fb15SPaul Saab break; 1136a5f0fb15SPaul Saab 1137a5f0fb15SPaul Saab case A_FF_SCREEN: 1138a5f0fb15SPaul Saab /* 1139a5f0fb15SPaul Saab * Force forward one screen. 1140a5f0fb15SPaul Saab */ 1141a5f0fb15SPaul Saab if (number <= 0) 1142a5f0fb15SPaul Saab number = get_swindow(); 1143a5f0fb15SPaul Saab cmd_exec(); 1144a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS) 1145a5f0fb15SPaul Saab set_attnpos(bottompos); 11461ede1615STim J. Robbins forward((int) number, 1, 0); 1147a5f0fb15SPaul Saab break; 1148a5f0fb15SPaul Saab 1149a5f0fb15SPaul Saab case A_F_FOREVER: 1150a5f0fb15SPaul Saab /* 1151a5f0fb15SPaul Saab * Forward forever, ignoring EOF. 1152a5f0fb15SPaul Saab */ 1153a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1154a5f0fb15SPaul Saab break; 1155a5f0fb15SPaul Saab cmd_exec(); 1156a5f0fb15SPaul Saab jump_forw(); 1157a5f0fb15SPaul Saab ignore_eoi = 1; 1158a5f0fb15SPaul Saab while (!sigs) 1159423c5ce5SXin LI { 1160423c5ce5SXin LI make_display(); 1161a5f0fb15SPaul Saab forward(1, 0, 0); 1162423c5ce5SXin LI } 1163a5f0fb15SPaul Saab ignore_eoi = 0; 1164a5f0fb15SPaul Saab /* 1165a5f0fb15SPaul Saab * This gets us back in "F mode" after processing 1166a5f0fb15SPaul Saab * a non-abort signal (e.g. window-change). 1167a5f0fb15SPaul Saab */ 1168a5f0fb15SPaul Saab if (sigs && !ABORT_SIGS()) 1169a5f0fb15SPaul Saab newaction = A_F_FOREVER; 1170a5f0fb15SPaul Saab break; 1171a5f0fb15SPaul Saab 1172a5f0fb15SPaul Saab case A_F_SCROLL: 1173a5f0fb15SPaul Saab /* 1174a5f0fb15SPaul Saab * Forward N lines 1175a5f0fb15SPaul Saab * (default same as last 'd' or 'u' command). 1176a5f0fb15SPaul Saab */ 1177a5f0fb15SPaul Saab if (number > 0) 11781ede1615STim J. Robbins wscroll = (int) number; 1179a5f0fb15SPaul Saab cmd_exec(); 1180a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS) 1181a5f0fb15SPaul Saab set_attnpos(bottompos); 1182a5f0fb15SPaul Saab forward(wscroll, 0, 0); 1183a5f0fb15SPaul Saab break; 1184a5f0fb15SPaul Saab 1185a5f0fb15SPaul Saab case A_B_SCROLL: 1186a5f0fb15SPaul Saab /* 1187a5f0fb15SPaul Saab * Forward N lines 1188a5f0fb15SPaul Saab * (default same as last 'd' or 'u' command). 1189a5f0fb15SPaul Saab */ 1190a5f0fb15SPaul Saab if (number > 0) 11911ede1615STim J. Robbins wscroll = (int) number; 1192a5f0fb15SPaul Saab cmd_exec(); 1193a5f0fb15SPaul Saab backward(wscroll, 0, 0); 1194a5f0fb15SPaul Saab break; 1195a5f0fb15SPaul Saab 1196a5f0fb15SPaul Saab case A_FREPAINT: 1197a5f0fb15SPaul Saab /* 1198a5f0fb15SPaul Saab * Flush buffers, then repaint screen. 1199a5f0fb15SPaul Saab * Don't flush the buffers on a pipe! 1200a5f0fb15SPaul Saab */ 1201423c5ce5SXin LI clear_buffers(); 1202a5f0fb15SPaul Saab /* FALLTHRU */ 1203a5f0fb15SPaul Saab case A_REPAINT: 1204a5f0fb15SPaul Saab /* 1205a5f0fb15SPaul Saab * Repaint screen. 1206a5f0fb15SPaul Saab */ 1207a5f0fb15SPaul Saab cmd_exec(); 1208a5f0fb15SPaul Saab repaint(); 1209a5f0fb15SPaul Saab break; 1210a5f0fb15SPaul Saab 1211a5f0fb15SPaul Saab case A_GOLINE: 1212a5f0fb15SPaul Saab /* 1213a5f0fb15SPaul Saab * Go to line N, default beginning of file. 1214a5f0fb15SPaul Saab */ 1215a5f0fb15SPaul Saab if (number <= 0) 1216a5f0fb15SPaul Saab number = 1; 1217a5f0fb15SPaul Saab cmd_exec(); 1218a5f0fb15SPaul Saab jump_back(number); 1219a5f0fb15SPaul Saab break; 1220a5f0fb15SPaul Saab 1221a5f0fb15SPaul Saab case A_PERCENT: 1222a5f0fb15SPaul Saab /* 1223a5f0fb15SPaul Saab * Go to a specified percentage into the file. 1224a5f0fb15SPaul Saab */ 1225a5f0fb15SPaul Saab if (number < 0) 1226720c436cSXin LI { 1227a5f0fb15SPaul Saab number = 0; 1228720c436cSXin LI fraction = 0; 1229720c436cSXin LI } 1230a5f0fb15SPaul Saab if (number > 100) 1231720c436cSXin LI { 1232a5f0fb15SPaul Saab number = 100; 1233720c436cSXin LI fraction = 0; 1234720c436cSXin LI } 1235a5f0fb15SPaul Saab cmd_exec(); 1236720c436cSXin LI jump_percent((int) number, fraction); 1237a5f0fb15SPaul Saab break; 1238a5f0fb15SPaul Saab 1239a5f0fb15SPaul Saab case A_GOEND: 1240a5f0fb15SPaul Saab /* 1241a5f0fb15SPaul Saab * Go to line N, default end of file. 1242a5f0fb15SPaul Saab */ 1243a5f0fb15SPaul Saab cmd_exec(); 1244a5f0fb15SPaul Saab if (number <= 0) 1245a5f0fb15SPaul Saab jump_forw(); 1246a5f0fb15SPaul Saab else 1247a5f0fb15SPaul Saab jump_back(number); 1248a5f0fb15SPaul Saab break; 1249a5f0fb15SPaul Saab 1250a5f0fb15SPaul Saab case A_GOPOS: 1251a5f0fb15SPaul Saab /* 1252a5f0fb15SPaul Saab * Go to a specified byte position in the file. 1253a5f0fb15SPaul Saab */ 1254a5f0fb15SPaul Saab cmd_exec(); 1255a5f0fb15SPaul Saab if (number < 0) 1256a5f0fb15SPaul Saab number = 0; 1257a5f0fb15SPaul Saab jump_line_loc((POSITION) number, jump_sline); 1258a5f0fb15SPaul Saab break; 1259a5f0fb15SPaul Saab 1260a5f0fb15SPaul Saab case A_STAT: 1261a5f0fb15SPaul Saab /* 1262a5f0fb15SPaul Saab * Print file name, etc. 1263a5f0fb15SPaul Saab */ 1264a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1265a5f0fb15SPaul Saab break; 1266a5f0fb15SPaul Saab cmd_exec(); 1267a5f0fb15SPaul Saab parg.p_string = eq_message(); 1268a5f0fb15SPaul Saab error("%s", &parg); 1269a5f0fb15SPaul Saab break; 1270a5f0fb15SPaul Saab 1271a5f0fb15SPaul Saab case A_VERSION: 1272a5f0fb15SPaul Saab /* 1273a5f0fb15SPaul Saab * Print version number, without the "@(#)". 1274a5f0fb15SPaul Saab */ 1275a5f0fb15SPaul Saab cmd_exec(); 1276a5f0fb15SPaul Saab dispversion(); 1277a5f0fb15SPaul Saab break; 1278a5f0fb15SPaul Saab 1279a5f0fb15SPaul Saab case A_QUIT: 1280a5f0fb15SPaul Saab /* 1281a5f0fb15SPaul Saab * Exit. 1282a5f0fb15SPaul Saab */ 1283a5f0fb15SPaul Saab if (curr_ifile != NULL_IFILE && 1284a5f0fb15SPaul Saab ch_getflags() & CH_HELPFILE) 1285a5f0fb15SPaul Saab { 1286a5f0fb15SPaul Saab /* 1287a5f0fb15SPaul Saab * Quit while viewing the help file 1288a5f0fb15SPaul Saab * just means return to viewing the 1289a5f0fb15SPaul Saab * previous file. 1290a5f0fb15SPaul Saab */ 129189dd99dcSXin LI hshift = save_hshift; 1292a5f0fb15SPaul Saab if (edit_prev(1) == 0) 1293a5f0fb15SPaul Saab break; 1294a5f0fb15SPaul Saab } 1295a5f0fb15SPaul Saab if (extra != NULL) 1296a5f0fb15SPaul Saab quit(*extra); 1297a5f0fb15SPaul Saab quit(QUIT_OK); 1298a5f0fb15SPaul Saab break; 1299a5f0fb15SPaul Saab 1300a5f0fb15SPaul Saab /* 1301a5f0fb15SPaul Saab * Define abbreviation for a commonly used sequence below. 1302a5f0fb15SPaul Saab */ 1303423c5ce5SXin LI #define DO_SEARCH() \ 1304423c5ce5SXin LI if (number <= 0) number = 1; \ 1305a5f0fb15SPaul Saab mca_search(); \ 1306a5f0fb15SPaul Saab cmd_exec(); \ 13071ede1615STim J. Robbins multi_search((char *)NULL, (int) number); 1308a5f0fb15SPaul Saab 1309a5f0fb15SPaul Saab 1310a5f0fb15SPaul Saab case A_F_SEARCH: 1311a5f0fb15SPaul Saab /* 1312a5f0fb15SPaul Saab * Search forward for a pattern. 1313a5f0fb15SPaul Saab * Get the first char of the pattern. 1314a5f0fb15SPaul Saab */ 1315a5f0fb15SPaul Saab search_type = SRCH_FORW; 1316a5f0fb15SPaul Saab if (number <= 0) 1317a5f0fb15SPaul Saab number = 1; 1318a5f0fb15SPaul Saab mca_search(); 1319a5f0fb15SPaul Saab c = getcc(); 1320a5f0fb15SPaul Saab goto again; 1321a5f0fb15SPaul Saab 1322a5f0fb15SPaul Saab case A_B_SEARCH: 1323a5f0fb15SPaul Saab /* 1324a5f0fb15SPaul Saab * Search backward for a pattern. 1325a5f0fb15SPaul Saab * Get the first char of the pattern. 1326a5f0fb15SPaul Saab */ 1327a5f0fb15SPaul Saab search_type = SRCH_BACK; 1328a5f0fb15SPaul Saab if (number <= 0) 1329a5f0fb15SPaul Saab number = 1; 1330a5f0fb15SPaul Saab mca_search(); 1331a5f0fb15SPaul Saab c = getcc(); 1332a5f0fb15SPaul Saab goto again; 1333a5f0fb15SPaul Saab 13347374caaaSXin LI case A_FILTER: 13357374caaaSXin LI #if HILITE_SEARCH 13367374caaaSXin LI search_type = SRCH_FORW | SRCH_FILTER; 13377374caaaSXin LI mca_search(); 13387374caaaSXin LI c = getcc(); 13397374caaaSXin LI goto again; 13407374caaaSXin LI #else 13417374caaaSXin LI error("Command not available", NULL_PARG); 13427374caaaSXin LI break; 13437374caaaSXin LI #endif 13447374caaaSXin LI 1345a5f0fb15SPaul Saab case A_AGAIN_SEARCH: 1346a5f0fb15SPaul Saab /* 1347a5f0fb15SPaul Saab * Repeat previous search. 1348a5f0fb15SPaul Saab */ 1349a5f0fb15SPaul Saab DO_SEARCH(); 1350a5f0fb15SPaul Saab break; 1351a5f0fb15SPaul Saab 1352a5f0fb15SPaul Saab case A_T_AGAIN_SEARCH: 1353a5f0fb15SPaul Saab /* 1354a5f0fb15SPaul Saab * Repeat previous search, multiple files. 1355a5f0fb15SPaul Saab */ 1356a5f0fb15SPaul Saab search_type |= SRCH_PAST_EOF; 1357a5f0fb15SPaul Saab DO_SEARCH(); 1358a5f0fb15SPaul Saab break; 1359a5f0fb15SPaul Saab 1360a5f0fb15SPaul Saab case A_REVERSE_SEARCH: 1361a5f0fb15SPaul Saab /* 1362a5f0fb15SPaul Saab * Repeat previous search, in reverse direction. 1363a5f0fb15SPaul Saab */ 1364a5f0fb15SPaul Saab save_search_type = search_type; 1365a5f0fb15SPaul Saab search_type = SRCH_REVERSE(search_type); 1366a5f0fb15SPaul Saab DO_SEARCH(); 1367a5f0fb15SPaul Saab search_type = save_search_type; 1368a5f0fb15SPaul Saab break; 1369a5f0fb15SPaul Saab 1370a5f0fb15SPaul Saab case A_T_REVERSE_SEARCH: 1371a5f0fb15SPaul Saab /* 1372a5f0fb15SPaul Saab * Repeat previous search, 1373a5f0fb15SPaul Saab * multiple files in reverse direction. 1374a5f0fb15SPaul Saab */ 1375a5f0fb15SPaul Saab save_search_type = search_type; 1376a5f0fb15SPaul Saab search_type = SRCH_REVERSE(search_type); 1377a5f0fb15SPaul Saab search_type |= SRCH_PAST_EOF; 1378a5f0fb15SPaul Saab DO_SEARCH(); 1379a5f0fb15SPaul Saab search_type = save_search_type; 1380a5f0fb15SPaul Saab break; 1381a5f0fb15SPaul Saab 1382a5f0fb15SPaul Saab case A_UNDO_SEARCH: 1383a5f0fb15SPaul Saab undo_search(); 1384a5f0fb15SPaul Saab break; 1385a5f0fb15SPaul Saab 1386a5f0fb15SPaul Saab case A_HELP: 1387a5f0fb15SPaul Saab /* 1388a5f0fb15SPaul Saab * Help. 1389a5f0fb15SPaul Saab */ 1390a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1391a5f0fb15SPaul Saab break; 1392a5f0fb15SPaul Saab cmd_exec(); 139389dd99dcSXin LI save_hshift = hshift; 139489dd99dcSXin LI hshift = 0; 1395a5f0fb15SPaul Saab (void) edit(FAKE_HELPFILE); 1396a5f0fb15SPaul Saab break; 1397a5f0fb15SPaul Saab 1398a5f0fb15SPaul Saab case A_EXAMINE: 1399a5f0fb15SPaul Saab #if EXAMINE 1400a5f0fb15SPaul Saab /* 1401a5f0fb15SPaul Saab * Edit a new file. Get the filename. 1402a5f0fb15SPaul Saab */ 1403a5f0fb15SPaul Saab if (secure) 1404a5f0fb15SPaul Saab { 1405a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1406a5f0fb15SPaul Saab break; 1407a5f0fb15SPaul Saab } 1408a5f0fb15SPaul Saab start_mca(A_EXAMINE, "Examine: ", ml_examine, 0); 1409a5f0fb15SPaul Saab c = getcc(); 1410a5f0fb15SPaul Saab goto again; 1411a5f0fb15SPaul Saab #else 1412a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1413a5f0fb15SPaul Saab break; 1414a5f0fb15SPaul Saab #endif 1415a5f0fb15SPaul Saab 1416a5f0fb15SPaul Saab case A_VISUAL: 1417a5f0fb15SPaul Saab /* 1418a5f0fb15SPaul Saab * Invoke an editor on the input file. 1419a5f0fb15SPaul Saab */ 1420a5f0fb15SPaul Saab #if EDITOR 1421a5f0fb15SPaul Saab if (secure) 1422a5f0fb15SPaul Saab { 1423a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1424a5f0fb15SPaul Saab break; 1425a5f0fb15SPaul Saab } 1426a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1427a5f0fb15SPaul Saab break; 1428a5f0fb15SPaul Saab if (strcmp(get_filename(curr_ifile), "-") == 0) 1429a5f0fb15SPaul Saab { 1430a5f0fb15SPaul Saab error("Cannot edit standard input", NULL_PARG); 1431a5f0fb15SPaul Saab break; 1432a5f0fb15SPaul Saab } 1433a5f0fb15SPaul Saab if (curr_altfilename != NULL) 1434a5f0fb15SPaul Saab { 143589dd99dcSXin LI error("WARNING: This file was viewed via LESSOPEN", 1436a5f0fb15SPaul Saab NULL_PARG); 1437a5f0fb15SPaul Saab } 1438a5f0fb15SPaul Saab start_mca(A_SHELL, "!", ml_shell, 0); 1439a5f0fb15SPaul Saab /* 1440a5f0fb15SPaul Saab * Expand the editor prototype string 1441a5f0fb15SPaul Saab * and pass it to the system to execute. 1442a5f0fb15SPaul Saab * (Make sure the screen is displayed so the 1443a5f0fb15SPaul Saab * expansion of "+%lm" works.) 1444a5f0fb15SPaul Saab */ 1445a5f0fb15SPaul Saab make_display(); 1446a5f0fb15SPaul Saab cmd_exec(); 1447a5f0fb15SPaul Saab lsystem(pr_expand(editproto, 0), (char*)NULL); 1448a5f0fb15SPaul Saab break; 1449a5f0fb15SPaul Saab #else 1450a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1451a5f0fb15SPaul Saab break; 1452a5f0fb15SPaul Saab #endif 1453a5f0fb15SPaul Saab 1454a5f0fb15SPaul Saab case A_NEXT_FILE: 1455a5f0fb15SPaul Saab /* 1456a5f0fb15SPaul Saab * Examine next file. 1457a5f0fb15SPaul Saab */ 14581ede1615STim J. Robbins #if TAGS 14598fd4165cSPaul Saab if (ntags()) 14608fd4165cSPaul Saab { 14618fd4165cSPaul Saab error("No next file", NULL_PARG); 14628fd4165cSPaul Saab break; 14638fd4165cSPaul Saab } 14641ede1615STim J. Robbins #endif 1465a5f0fb15SPaul Saab if (number <= 0) 1466a5f0fb15SPaul Saab number = 1; 14671ede1615STim J. Robbins if (edit_next((int) number)) 1468a5f0fb15SPaul Saab { 14697374caaaSXin LI if (get_quit_at_eof() && eof_displayed() && 1470a5f0fb15SPaul Saab !(ch_getflags() & CH_HELPFILE)) 1471a5f0fb15SPaul Saab quit(QUIT_OK); 1472a5f0fb15SPaul Saab parg.p_string = (number > 1) ? "(N-th) " : ""; 1473a5f0fb15SPaul Saab error("No %snext file", &parg); 1474a5f0fb15SPaul Saab } 1475a5f0fb15SPaul Saab break; 1476a5f0fb15SPaul Saab 1477a5f0fb15SPaul Saab case A_PREV_FILE: 1478a5f0fb15SPaul Saab /* 1479a5f0fb15SPaul Saab * Examine previous file. 1480a5f0fb15SPaul Saab */ 14811ede1615STim J. Robbins #if TAGS 14828fd4165cSPaul Saab if (ntags()) 14838fd4165cSPaul Saab { 14848fd4165cSPaul Saab error("No previous file", NULL_PARG); 14858fd4165cSPaul Saab break; 14868fd4165cSPaul Saab } 14871ede1615STim J. Robbins #endif 1488a5f0fb15SPaul Saab if (number <= 0) 1489a5f0fb15SPaul Saab number = 1; 14901ede1615STim J. Robbins if (edit_prev((int) number)) 1491a5f0fb15SPaul Saab { 1492a5f0fb15SPaul Saab parg.p_string = (number > 1) ? "(N-th) " : ""; 1493a5f0fb15SPaul Saab error("No %sprevious file", &parg); 1494a5f0fb15SPaul Saab } 1495a5f0fb15SPaul Saab break; 1496a5f0fb15SPaul Saab 14978fd4165cSPaul Saab case A_NEXT_TAG: 14981ede1615STim J. Robbins #if TAGS 14998fd4165cSPaul Saab if (number <= 0) 15008fd4165cSPaul Saab number = 1; 15011ede1615STim J. Robbins tagfile = nexttag((int) number); 15028fd4165cSPaul Saab if (tagfile == NULL) 15038fd4165cSPaul Saab { 15048fd4165cSPaul Saab error("No next tag", NULL_PARG); 15058fd4165cSPaul Saab break; 15068fd4165cSPaul Saab } 15078fd4165cSPaul Saab if (edit(tagfile) == 0) 15088fd4165cSPaul Saab { 15098fd4165cSPaul Saab POSITION pos = tagsearch(); 15108fd4165cSPaul Saab if (pos != NULL_POSITION) 15118fd4165cSPaul Saab jump_loc(pos, jump_sline); 15128fd4165cSPaul Saab } 15131ede1615STim J. Robbins #else 15141ede1615STim J. Robbins error("Command not available", NULL_PARG); 15151ede1615STim J. Robbins #endif 15168fd4165cSPaul Saab break; 15178fd4165cSPaul Saab 15188fd4165cSPaul Saab case A_PREV_TAG: 15191ede1615STim J. Robbins #if TAGS 15208fd4165cSPaul Saab if (number <= 0) 15218fd4165cSPaul Saab number = 1; 15221ede1615STim J. Robbins tagfile = prevtag((int) number); 15238fd4165cSPaul Saab if (tagfile == NULL) 15248fd4165cSPaul Saab { 15258fd4165cSPaul Saab error("No previous tag", NULL_PARG); 15268fd4165cSPaul Saab break; 15278fd4165cSPaul Saab } 15288fd4165cSPaul Saab if (edit(tagfile) == 0) 15298fd4165cSPaul Saab { 15308fd4165cSPaul Saab POSITION pos = tagsearch(); 15318fd4165cSPaul Saab if (pos != NULL_POSITION) 15328fd4165cSPaul Saab jump_loc(pos, jump_sline); 15338fd4165cSPaul Saab } 15341ede1615STim J. Robbins #else 15351ede1615STim J. Robbins error("Command not available", NULL_PARG); 15361ede1615STim J. Robbins #endif 15378fd4165cSPaul Saab break; 15388fd4165cSPaul Saab 1539a5f0fb15SPaul Saab case A_INDEX_FILE: 1540a5f0fb15SPaul Saab /* 1541a5f0fb15SPaul Saab * Examine a particular file. 1542a5f0fb15SPaul Saab */ 1543a5f0fb15SPaul Saab if (number <= 0) 1544a5f0fb15SPaul Saab number = 1; 15451ede1615STim J. Robbins if (edit_index((int) number)) 1546a5f0fb15SPaul Saab error("No such file", NULL_PARG); 1547a5f0fb15SPaul Saab break; 1548a5f0fb15SPaul Saab 1549a5f0fb15SPaul Saab case A_REMOVE_FILE: 1550a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1551a5f0fb15SPaul Saab break; 1552a5f0fb15SPaul Saab old_ifile = curr_ifile; 1553a5f0fb15SPaul Saab new_ifile = getoff_ifile(curr_ifile); 1554a5f0fb15SPaul Saab if (new_ifile == NULL_IFILE) 1555a5f0fb15SPaul Saab { 1556a5f0fb15SPaul Saab bell(); 1557a5f0fb15SPaul Saab break; 1558a5f0fb15SPaul Saab } 1559a5f0fb15SPaul Saab if (edit_ifile(new_ifile) != 0) 1560a5f0fb15SPaul Saab { 1561a5f0fb15SPaul Saab reedit_ifile(old_ifile); 1562a5f0fb15SPaul Saab break; 1563a5f0fb15SPaul Saab } 1564a5f0fb15SPaul Saab del_ifile(old_ifile); 1565a5f0fb15SPaul Saab break; 1566a5f0fb15SPaul Saab 1567a5f0fb15SPaul Saab case A_OPT_TOGGLE: 1568a5f0fb15SPaul Saab optflag = OPT_TOGGLE; 1569a5f0fb15SPaul Saab optgetname = FALSE; 1570a5f0fb15SPaul Saab mca_opt_toggle(); 1571a5f0fb15SPaul Saab c = getcc(); 1572a5f0fb15SPaul Saab goto again; 1573a5f0fb15SPaul Saab 1574a5f0fb15SPaul Saab case A_DISP_OPTION: 1575a5f0fb15SPaul Saab /* 1576a5f0fb15SPaul Saab * Report a flag setting. 1577a5f0fb15SPaul Saab */ 1578a5f0fb15SPaul Saab optflag = OPT_NO_TOGGLE; 1579a5f0fb15SPaul Saab optgetname = FALSE; 1580a5f0fb15SPaul Saab mca_opt_toggle(); 1581a5f0fb15SPaul Saab c = getcc(); 1582a5f0fb15SPaul Saab goto again; 1583a5f0fb15SPaul Saab 1584a5f0fb15SPaul Saab case A_FIRSTCMD: 1585a5f0fb15SPaul Saab /* 1586a5f0fb15SPaul Saab * Set an initial command for new files. 1587a5f0fb15SPaul Saab */ 1588a5f0fb15SPaul Saab start_mca(A_FIRSTCMD, "+", (void*)NULL, 0); 1589a5f0fb15SPaul Saab c = getcc(); 1590a5f0fb15SPaul Saab goto again; 1591a5f0fb15SPaul Saab 1592a5f0fb15SPaul Saab case A_SHELL: 1593a5f0fb15SPaul Saab /* 1594a5f0fb15SPaul Saab * Shell escape. 1595a5f0fb15SPaul Saab */ 1596a5f0fb15SPaul Saab #if SHELL_ESCAPE 1597a5f0fb15SPaul Saab if (secure) 1598a5f0fb15SPaul Saab { 1599a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1600a5f0fb15SPaul Saab break; 1601a5f0fb15SPaul Saab } 1602a5f0fb15SPaul Saab start_mca(A_SHELL, "!", ml_shell, 0); 1603a5f0fb15SPaul Saab c = getcc(); 1604a5f0fb15SPaul Saab goto again; 1605a5f0fb15SPaul Saab #else 1606a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1607a5f0fb15SPaul Saab break; 1608a5f0fb15SPaul Saab #endif 1609a5f0fb15SPaul Saab 1610a5f0fb15SPaul Saab case A_SETMARK: 1611a5f0fb15SPaul Saab /* 1612a5f0fb15SPaul Saab * Set a mark. 1613a5f0fb15SPaul Saab */ 1614a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1615a5f0fb15SPaul Saab break; 1616a5f0fb15SPaul Saab start_mca(A_SETMARK, "mark: ", (void*)NULL, 0); 1617a5f0fb15SPaul Saab c = getcc(); 161889dd99dcSXin LI if (c == erase_char || c == erase2_char || 161989dd99dcSXin LI c == kill_char || c == '\n' || c == '\r') 1620a5f0fb15SPaul Saab break; 1621a5f0fb15SPaul Saab setmark(c); 1622a5f0fb15SPaul Saab break; 1623a5f0fb15SPaul Saab 1624a5f0fb15SPaul Saab case A_GOMARK: 1625a5f0fb15SPaul Saab /* 1626a5f0fb15SPaul Saab * Go to a mark. 1627a5f0fb15SPaul Saab */ 1628a5f0fb15SPaul Saab start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0); 1629a5f0fb15SPaul Saab c = getcc(); 163089dd99dcSXin LI if (c == erase_char || c == erase2_char || 163189dd99dcSXin LI c == kill_char || c == '\n' || c == '\r') 1632a5f0fb15SPaul Saab break; 16337374caaaSXin LI cmd_exec(); 1634a5f0fb15SPaul Saab gomark(c); 1635a5f0fb15SPaul Saab break; 1636a5f0fb15SPaul Saab 1637a5f0fb15SPaul Saab case A_PIPE: 1638a5f0fb15SPaul Saab #if PIPEC 1639a5f0fb15SPaul Saab if (secure) 1640a5f0fb15SPaul Saab { 1641a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1642a5f0fb15SPaul Saab break; 1643a5f0fb15SPaul Saab } 1644a5f0fb15SPaul Saab start_mca(A_PIPE, "|mark: ", (void*)NULL, 0); 1645a5f0fb15SPaul Saab c = getcc(); 164689dd99dcSXin LI if (c == erase_char || c == erase2_char || c == kill_char) 1647a5f0fb15SPaul Saab break; 1648a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 1649a5f0fb15SPaul Saab c = '.'; 1650a5f0fb15SPaul Saab if (badmark(c)) 1651a5f0fb15SPaul Saab break; 1652a5f0fb15SPaul Saab pipec = c; 1653a5f0fb15SPaul Saab start_mca(A_PIPE, "!", ml_shell, 0); 1654a5f0fb15SPaul Saab c = getcc(); 1655a5f0fb15SPaul Saab goto again; 1656a5f0fb15SPaul Saab #else 1657a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1658a5f0fb15SPaul Saab break; 1659a5f0fb15SPaul Saab #endif 1660a5f0fb15SPaul Saab 1661a5f0fb15SPaul Saab case A_B_BRACKET: 1662a5f0fb15SPaul Saab case A_F_BRACKET: 1663a5f0fb15SPaul Saab start_mca(action, "Brackets: ", (void*)NULL, 0); 1664a5f0fb15SPaul Saab c = getcc(); 1665a5f0fb15SPaul Saab goto again; 1666a5f0fb15SPaul Saab 1667a5f0fb15SPaul Saab case A_LSHIFT: 16688fd4165cSPaul Saab if (number > 0) 16698fd4165cSPaul Saab shift_count = number; 16708fd4165cSPaul Saab else 167115596da4SPaul Saab number = (shift_count > 0) ? 167215596da4SPaul Saab shift_count : sc_width / 2; 1673a5f0fb15SPaul Saab if (number > hshift) 1674a5f0fb15SPaul Saab number = hshift; 1675a5f0fb15SPaul Saab hshift -= number; 1676a5f0fb15SPaul Saab screen_trashed = 1; 1677a5f0fb15SPaul Saab break; 1678a5f0fb15SPaul Saab 1679a5f0fb15SPaul Saab case A_RSHIFT: 16808fd4165cSPaul Saab if (number > 0) 16818fd4165cSPaul Saab shift_count = number; 16828fd4165cSPaul Saab else 168315596da4SPaul Saab number = (shift_count > 0) ? 168415596da4SPaul Saab shift_count : sc_width / 2; 1685a5f0fb15SPaul Saab hshift += number; 1686a5f0fb15SPaul Saab screen_trashed = 1; 1687a5f0fb15SPaul Saab break; 1688a5f0fb15SPaul Saab 1689a5f0fb15SPaul Saab case A_PREFIX: 1690a5f0fb15SPaul Saab /* 1691a5f0fb15SPaul Saab * The command is incomplete (more chars are needed). 1692a5f0fb15SPaul Saab * Display the current char, so the user knows 1693a5f0fb15SPaul Saab * what's going on, and get another character. 1694a5f0fb15SPaul Saab */ 1695a5f0fb15SPaul Saab if (mca != A_PREFIX) 1696a5f0fb15SPaul Saab { 1697a5f0fb15SPaul Saab cmd_reset(); 1698a5f0fb15SPaul Saab start_mca(A_PREFIX, " ", (void*)NULL, 1699a5f0fb15SPaul Saab CF_QUIT_ON_ERASE); 1700a5f0fb15SPaul Saab (void) cmd_char(c); 1701a5f0fb15SPaul Saab } 1702a5f0fb15SPaul Saab c = getcc(); 1703a5f0fb15SPaul Saab goto again; 1704a5f0fb15SPaul Saab 1705a5f0fb15SPaul Saab case A_NOACTION: 1706a5f0fb15SPaul Saab break; 1707a5f0fb15SPaul Saab 1708a5f0fb15SPaul Saab default: 1709a5f0fb15SPaul Saab bell(); 1710a5f0fb15SPaul Saab break; 1711a5f0fb15SPaul Saab } 1712a5f0fb15SPaul Saab } 1713a5f0fb15SPaul Saab } 1714