1a5f0fb15SPaul Saab /* 2a5f0fb15SPaul Saab * Copyright (C) 1984-2000 Mark Nudelman 3a5f0fb15SPaul Saab * 4a5f0fb15SPaul Saab * You may distribute under the terms of either the GNU General Public 5a5f0fb15SPaul Saab * License or the Less License, as specified in the README file. 6a5f0fb15SPaul Saab * 7a5f0fb15SPaul Saab * For more information about less, or for information on how to 8a5f0fb15SPaul Saab * contact the author, see the README file. 9a5f0fb15SPaul Saab */ 10a5f0fb15SPaul Saab 11a5f0fb15SPaul Saab 12a5f0fb15SPaul Saab /* 13a5f0fb15SPaul Saab * User-level command processor. 14a5f0fb15SPaul Saab */ 15a5f0fb15SPaul Saab 16a5f0fb15SPaul Saab #include "less.h" 17a5f0fb15SPaul Saab #include "position.h" 18a5f0fb15SPaul Saab #include "option.h" 19a5f0fb15SPaul Saab #include "cmd.h" 20a5f0fb15SPaul Saab 21a5f0fb15SPaul Saab extern int erase_char, kill_char; 22a5f0fb15SPaul Saab extern int sigs; 23a5f0fb15SPaul Saab extern int quit_at_eof; 24a5f0fb15SPaul Saab extern int quit_if_one_screen; 25a5f0fb15SPaul Saab extern int squished; 26a5f0fb15SPaul Saab extern int hit_eof; 27a5f0fb15SPaul Saab extern int sc_width; 28a5f0fb15SPaul Saab extern int sc_height; 29a5f0fb15SPaul Saab extern int swindow; 30a5f0fb15SPaul Saab extern int jump_sline; 31a5f0fb15SPaul Saab extern int quitting; 32a5f0fb15SPaul Saab extern int wscroll; 33a5f0fb15SPaul Saab extern int top_scroll; 34a5f0fb15SPaul Saab extern int ignore_eoi; 35a5f0fb15SPaul Saab extern int secure; 36a5f0fb15SPaul Saab extern int hshift; 37a5f0fb15SPaul Saab extern int show_attn; 38a5f0fb15SPaul Saab extern char *every_first_cmd; 39a5f0fb15SPaul Saab extern char *curr_altfilename; 40a5f0fb15SPaul Saab extern char version[]; 41a5f0fb15SPaul Saab extern struct scrpos initial_scrpos; 42a5f0fb15SPaul Saab extern IFILE curr_ifile; 43a5f0fb15SPaul Saab extern void constant *ml_search; 44a5f0fb15SPaul Saab extern void constant *ml_examine; 45a5f0fb15SPaul Saab #if SHELL_ESCAPE || PIPEC 46a5f0fb15SPaul Saab extern void constant *ml_shell; 47a5f0fb15SPaul Saab #endif 48a5f0fb15SPaul Saab #if EDITOR 49a5f0fb15SPaul Saab extern char *editor; 50a5f0fb15SPaul Saab extern char *editproto; 51a5f0fb15SPaul Saab #endif 52a5f0fb15SPaul Saab extern int screen_trashed; /* The screen has been overwritten */ 53a5f0fb15SPaul Saab 54a5f0fb15SPaul Saab static char ungot[UNGOT_SIZE]; 55a5f0fb15SPaul Saab static char *ungotp = NULL; 56a5f0fb15SPaul Saab #if SHELL_ESCAPE 57a5f0fb15SPaul Saab static char *shellcmd = NULL; /* For holding last shell command for "!!" */ 58a5f0fb15SPaul Saab #endif 59a5f0fb15SPaul Saab static int mca; /* The multicharacter command (action) */ 60a5f0fb15SPaul Saab static int search_type; /* The previous type of search */ 61a5f0fb15SPaul Saab static int number; /* The number typed by the user */ 62a5f0fb15SPaul Saab static char optchar; 63a5f0fb15SPaul Saab static int optflag; 64a5f0fb15SPaul Saab static int optgetname; 65a5f0fb15SPaul Saab static POSITION bottompos; 66a5f0fb15SPaul Saab #if PIPEC 67a5f0fb15SPaul Saab static char pipec; 68a5f0fb15SPaul Saab #endif 69a5f0fb15SPaul Saab 70a5f0fb15SPaul Saab static void multi_search(); 71a5f0fb15SPaul Saab 72a5f0fb15SPaul Saab /* 73a5f0fb15SPaul Saab * Move the cursor to lower left before executing a command. 74a5f0fb15SPaul Saab * This looks nicer if the command takes a long time before 75a5f0fb15SPaul Saab * updating the screen. 76a5f0fb15SPaul Saab */ 77a5f0fb15SPaul Saab static void 78a5f0fb15SPaul Saab cmd_exec() 79a5f0fb15SPaul Saab { 80a5f0fb15SPaul Saab clear_attn(); 81a5f0fb15SPaul Saab lower_left(); 82a5f0fb15SPaul Saab flush(); 83a5f0fb15SPaul Saab } 84a5f0fb15SPaul Saab 85a5f0fb15SPaul Saab /* 86a5f0fb15SPaul Saab * Set up the display to start a new multi-character command. 87a5f0fb15SPaul Saab */ 88a5f0fb15SPaul Saab static void 89a5f0fb15SPaul Saab start_mca(action, prompt, mlist, cmdflags) 90a5f0fb15SPaul Saab int action; 91a5f0fb15SPaul Saab char *prompt; 92a5f0fb15SPaul Saab void *mlist; 93a5f0fb15SPaul Saab int cmdflags; 94a5f0fb15SPaul Saab { 95a5f0fb15SPaul Saab mca = action; 96a5f0fb15SPaul Saab clear_cmd(); 97a5f0fb15SPaul Saab cmd_putstr(prompt); 98a5f0fb15SPaul Saab set_mlist(mlist, cmdflags); 99a5f0fb15SPaul Saab } 100a5f0fb15SPaul Saab 101a5f0fb15SPaul Saab public int 102a5f0fb15SPaul Saab in_mca() 103a5f0fb15SPaul Saab { 104a5f0fb15SPaul Saab return (mca != 0 && mca != A_PREFIX); 105a5f0fb15SPaul Saab } 106a5f0fb15SPaul Saab 107a5f0fb15SPaul Saab /* 108a5f0fb15SPaul Saab * Set up the display to start a new search command. 109a5f0fb15SPaul Saab */ 110a5f0fb15SPaul Saab static void 111a5f0fb15SPaul Saab mca_search() 112a5f0fb15SPaul Saab { 113a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 114a5f0fb15SPaul Saab mca = A_F_SEARCH; 115a5f0fb15SPaul Saab else 116a5f0fb15SPaul Saab mca = A_B_SEARCH; 117a5f0fb15SPaul Saab 118a5f0fb15SPaul Saab clear_cmd(); 119a5f0fb15SPaul Saab 120a5f0fb15SPaul Saab if (search_type & SRCH_NO_MATCH) 121a5f0fb15SPaul Saab cmd_putstr("Non-match "); 122a5f0fb15SPaul Saab if (search_type & SRCH_FIRST_FILE) 123a5f0fb15SPaul Saab cmd_putstr("First-file "); 124a5f0fb15SPaul Saab if (search_type & SRCH_PAST_EOF) 125a5f0fb15SPaul Saab cmd_putstr("EOF-ignore "); 126a5f0fb15SPaul Saab if (search_type & SRCH_NO_MOVE) 127a5f0fb15SPaul Saab cmd_putstr("Keep-pos "); 128a5f0fb15SPaul Saab if (search_type & SRCH_NO_REGEX) 129a5f0fb15SPaul Saab cmd_putstr("Regex-off "); 130a5f0fb15SPaul Saab 131a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 132a5f0fb15SPaul Saab cmd_putstr("/"); 133a5f0fb15SPaul Saab else 134a5f0fb15SPaul Saab cmd_putstr("?"); 135a5f0fb15SPaul Saab set_mlist(ml_search, 0); 136a5f0fb15SPaul Saab } 137a5f0fb15SPaul Saab 138a5f0fb15SPaul Saab /* 139a5f0fb15SPaul Saab * Set up the display to start a new toggle-option command. 140a5f0fb15SPaul Saab */ 141a5f0fb15SPaul Saab static void 142a5f0fb15SPaul Saab mca_opt_toggle() 143a5f0fb15SPaul Saab { 144a5f0fb15SPaul Saab int no_prompt; 145a5f0fb15SPaul Saab int flag; 146a5f0fb15SPaul Saab char *dash; 147a5f0fb15SPaul Saab 148a5f0fb15SPaul Saab no_prompt = (optflag & OPT_NO_PROMPT); 149a5f0fb15SPaul Saab flag = (optflag & ~OPT_NO_PROMPT); 150a5f0fb15SPaul Saab dash = (flag == OPT_NO_TOGGLE) ? "_" : "-"; 151a5f0fb15SPaul Saab 152a5f0fb15SPaul Saab mca = A_OPT_TOGGLE; 153a5f0fb15SPaul Saab clear_cmd(); 154a5f0fb15SPaul Saab cmd_putstr(dash); 155a5f0fb15SPaul Saab if (optgetname) 156a5f0fb15SPaul Saab cmd_putstr(dash); 157a5f0fb15SPaul Saab if (no_prompt) 158a5f0fb15SPaul Saab cmd_putstr("(P)"); 159a5f0fb15SPaul Saab switch (flag) 160a5f0fb15SPaul Saab { 161a5f0fb15SPaul Saab case OPT_UNSET: 162a5f0fb15SPaul Saab cmd_putstr("+"); 163a5f0fb15SPaul Saab break; 164a5f0fb15SPaul Saab case OPT_SET: 165a5f0fb15SPaul Saab cmd_putstr("!"); 166a5f0fb15SPaul Saab break; 167a5f0fb15SPaul Saab } 168a5f0fb15SPaul Saab set_mlist(NULL, 0); 169a5f0fb15SPaul Saab } 170a5f0fb15SPaul Saab 171a5f0fb15SPaul Saab /* 172a5f0fb15SPaul Saab * Execute a multicharacter command. 173a5f0fb15SPaul Saab */ 174a5f0fb15SPaul Saab static void 175a5f0fb15SPaul Saab exec_mca() 176a5f0fb15SPaul Saab { 177a5f0fb15SPaul Saab register char *cbuf; 178a5f0fb15SPaul Saab 179a5f0fb15SPaul Saab cmd_exec(); 180a5f0fb15SPaul Saab cbuf = get_cmdbuf(); 181a5f0fb15SPaul Saab 182a5f0fb15SPaul Saab switch (mca) 183a5f0fb15SPaul Saab { 184a5f0fb15SPaul Saab case A_F_SEARCH: 185a5f0fb15SPaul Saab case A_B_SEARCH: 186a5f0fb15SPaul Saab multi_search(cbuf, number); 187a5f0fb15SPaul Saab break; 188a5f0fb15SPaul Saab case A_FIRSTCMD: 189a5f0fb15SPaul Saab /* 190a5f0fb15SPaul Saab * Skip leading spaces or + signs in the string. 191a5f0fb15SPaul Saab */ 192a5f0fb15SPaul Saab while (*cbuf == '+' || *cbuf == ' ') 193a5f0fb15SPaul Saab cbuf++; 194a5f0fb15SPaul Saab if (every_first_cmd != NULL) 195a5f0fb15SPaul Saab free(every_first_cmd); 196a5f0fb15SPaul Saab if (*cbuf == '\0') 197a5f0fb15SPaul Saab every_first_cmd = NULL; 198a5f0fb15SPaul Saab else 199a5f0fb15SPaul Saab every_first_cmd = save(cbuf); 200a5f0fb15SPaul Saab break; 201a5f0fb15SPaul Saab case A_OPT_TOGGLE: 202a5f0fb15SPaul Saab toggle_option(optchar, cbuf, optflag); 203a5f0fb15SPaul Saab optchar = '\0'; 204a5f0fb15SPaul Saab break; 205a5f0fb15SPaul Saab case A_F_BRACKET: 206a5f0fb15SPaul Saab match_brac(cbuf[0], cbuf[1], 1, number); 207a5f0fb15SPaul Saab break; 208a5f0fb15SPaul Saab case A_B_BRACKET: 209a5f0fb15SPaul Saab match_brac(cbuf[1], cbuf[0], 0, number); 210a5f0fb15SPaul Saab break; 211a5f0fb15SPaul Saab #if EXAMINE 212a5f0fb15SPaul Saab case A_EXAMINE: 213a5f0fb15SPaul Saab if (secure) 214a5f0fb15SPaul Saab break; 215a5f0fb15SPaul Saab edit_list(cbuf); 216a5f0fb15SPaul Saab break; 217a5f0fb15SPaul Saab #endif 218a5f0fb15SPaul Saab #if SHELL_ESCAPE 219a5f0fb15SPaul Saab case A_SHELL: 220a5f0fb15SPaul Saab /* 221a5f0fb15SPaul Saab * !! just uses whatever is in shellcmd. 222a5f0fb15SPaul Saab * Otherwise, copy cmdbuf to shellcmd, 223a5f0fb15SPaul Saab * expanding any special characters ("%" or "#"). 224a5f0fb15SPaul Saab */ 225a5f0fb15SPaul Saab if (*cbuf != '!') 226a5f0fb15SPaul Saab { 227a5f0fb15SPaul Saab if (shellcmd != NULL) 228a5f0fb15SPaul Saab free(shellcmd); 229a5f0fb15SPaul Saab shellcmd = fexpand(cbuf); 230a5f0fb15SPaul Saab } 231a5f0fb15SPaul Saab 232a5f0fb15SPaul Saab if (secure) 233a5f0fb15SPaul Saab break; 234a5f0fb15SPaul Saab if (shellcmd == NULL) 235a5f0fb15SPaul Saab lsystem("", "!done"); 236a5f0fb15SPaul Saab else 237a5f0fb15SPaul Saab lsystem(shellcmd, "!done"); 238a5f0fb15SPaul Saab break; 239a5f0fb15SPaul Saab #endif 240a5f0fb15SPaul Saab #if PIPEC 241a5f0fb15SPaul Saab case A_PIPE: 242a5f0fb15SPaul Saab if (secure) 243a5f0fb15SPaul Saab break; 244a5f0fb15SPaul Saab (void) pipe_mark(pipec, cbuf); 245a5f0fb15SPaul Saab error("|done", NULL_PARG); 246a5f0fb15SPaul Saab break; 247a5f0fb15SPaul Saab #endif 248a5f0fb15SPaul Saab } 249a5f0fb15SPaul Saab } 250a5f0fb15SPaul Saab 251a5f0fb15SPaul Saab /* 252a5f0fb15SPaul Saab * Add a character to a multi-character command. 253a5f0fb15SPaul Saab */ 254a5f0fb15SPaul Saab static int 255a5f0fb15SPaul Saab mca_char(c) 256a5f0fb15SPaul Saab int c; 257a5f0fb15SPaul Saab { 258a5f0fb15SPaul Saab char *p; 259a5f0fb15SPaul Saab int flag; 260a5f0fb15SPaul Saab char buf[3]; 261a5f0fb15SPaul Saab PARG parg; 262a5f0fb15SPaul Saab 263a5f0fb15SPaul Saab switch (mca) 264a5f0fb15SPaul Saab { 265a5f0fb15SPaul Saab case 0: 266a5f0fb15SPaul Saab /* 267a5f0fb15SPaul Saab * Not in a multicharacter command. 268a5f0fb15SPaul Saab */ 269a5f0fb15SPaul Saab return (NO_MCA); 270a5f0fb15SPaul Saab 271a5f0fb15SPaul Saab case A_PREFIX: 272a5f0fb15SPaul Saab /* 273a5f0fb15SPaul Saab * In the prefix of a command. 274a5f0fb15SPaul Saab * This not considered a multichar command 275a5f0fb15SPaul Saab * (even tho it uses cmdbuf, etc.). 276a5f0fb15SPaul Saab * It is handled in the commands() switch. 277a5f0fb15SPaul Saab */ 278a5f0fb15SPaul Saab return (NO_MCA); 279a5f0fb15SPaul Saab 280a5f0fb15SPaul Saab case A_DIGIT: 281a5f0fb15SPaul Saab /* 282a5f0fb15SPaul Saab * Entering digits of a number. 283a5f0fb15SPaul Saab * Terminated by a non-digit. 284a5f0fb15SPaul Saab */ 285a5f0fb15SPaul Saab if ((c < '0' || c > '9') && 286a5f0fb15SPaul Saab editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE) == A_INVALID) 287a5f0fb15SPaul Saab { 288a5f0fb15SPaul Saab /* 289a5f0fb15SPaul Saab * Not part of the number. 290a5f0fb15SPaul Saab * Treat as a normal command character. 291a5f0fb15SPaul Saab */ 292a5f0fb15SPaul Saab number = cmd_int(); 293a5f0fb15SPaul Saab mca = 0; 294a5f0fb15SPaul Saab cmd_accept(); 295a5f0fb15SPaul Saab return (NO_MCA); 296a5f0fb15SPaul Saab } 297a5f0fb15SPaul Saab break; 298a5f0fb15SPaul Saab 299a5f0fb15SPaul Saab case A_OPT_TOGGLE: 300a5f0fb15SPaul Saab /* 301a5f0fb15SPaul Saab * Special case for the TOGGLE_OPTION command. 302a5f0fb15SPaul Saab * If the option letter which was entered is a 303a5f0fb15SPaul Saab * single-char option, execute the command immediately, 304a5f0fb15SPaul Saab * so user doesn't have to hit RETURN. 305a5f0fb15SPaul Saab * If the first char is + or -, this indicates 306a5f0fb15SPaul Saab * OPT_UNSET or OPT_SET respectively, instead of OPT_TOGGLE. 307a5f0fb15SPaul Saab * "--" begins inputting a long option name. 308a5f0fb15SPaul Saab */ 309a5f0fb15SPaul Saab if (optchar == '\0' && len_cmdbuf() == 0) 310a5f0fb15SPaul Saab { 311a5f0fb15SPaul Saab flag = (optflag & ~OPT_NO_PROMPT); 312a5f0fb15SPaul Saab if (flag == OPT_NO_TOGGLE) 313a5f0fb15SPaul Saab { 314a5f0fb15SPaul Saab switch (c) 315a5f0fb15SPaul Saab { 316a5f0fb15SPaul Saab case '_': 317a5f0fb15SPaul Saab /* "__" = long option name. */ 318a5f0fb15SPaul Saab optgetname = TRUE; 319a5f0fb15SPaul Saab mca_opt_toggle(); 320a5f0fb15SPaul Saab return (MCA_MORE); 321a5f0fb15SPaul Saab } 322a5f0fb15SPaul Saab } else 323a5f0fb15SPaul Saab { 324a5f0fb15SPaul Saab switch (c) 325a5f0fb15SPaul Saab { 326a5f0fb15SPaul Saab case '+': 327a5f0fb15SPaul Saab /* "-+" = UNSET. */ 328a5f0fb15SPaul Saab optflag = (flag == OPT_UNSET) ? 329a5f0fb15SPaul Saab OPT_TOGGLE : OPT_UNSET; 330a5f0fb15SPaul Saab mca_opt_toggle(); 331a5f0fb15SPaul Saab return (MCA_MORE); 332a5f0fb15SPaul Saab case '!': 333a5f0fb15SPaul Saab /* "-!" = SET */ 334a5f0fb15SPaul Saab optflag = (flag == OPT_SET) ? 335a5f0fb15SPaul Saab OPT_TOGGLE : OPT_SET; 336a5f0fb15SPaul Saab mca_opt_toggle(); 337a5f0fb15SPaul Saab return (MCA_MORE); 338a5f0fb15SPaul Saab case CONTROL('P'): 339a5f0fb15SPaul Saab optflag ^= OPT_NO_PROMPT; 340a5f0fb15SPaul Saab mca_opt_toggle(); 341a5f0fb15SPaul Saab return (MCA_MORE); 342a5f0fb15SPaul Saab case '-': 343a5f0fb15SPaul Saab /* "--" = long option name. */ 344a5f0fb15SPaul Saab optgetname = TRUE; 345a5f0fb15SPaul Saab mca_opt_toggle(); 346a5f0fb15SPaul Saab return (MCA_MORE); 347a5f0fb15SPaul Saab } 348a5f0fb15SPaul Saab } 349a5f0fb15SPaul Saab } 350a5f0fb15SPaul Saab if (optgetname) 351a5f0fb15SPaul Saab { 352a5f0fb15SPaul Saab /* 353a5f0fb15SPaul Saab * We're getting a long option name. 354a5f0fb15SPaul Saab * See if we've matched an option name yet. 355a5f0fb15SPaul Saab * If so, display the complete name and stop 356a5f0fb15SPaul Saab * accepting chars until user hits RETURN. 357a5f0fb15SPaul Saab */ 358a5f0fb15SPaul Saab struct option *o; 359a5f0fb15SPaul Saab char *oname; 360a5f0fb15SPaul Saab int lc; 361a5f0fb15SPaul Saab 362a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 363a5f0fb15SPaul Saab { 364a5f0fb15SPaul Saab /* 365a5f0fb15SPaul Saab * When the user hits RETURN, make sure 366a5f0fb15SPaul Saab * we've matched an option name, then 367a5f0fb15SPaul Saab * pretend he just entered the equivalent 368a5f0fb15SPaul Saab * option letter. 369a5f0fb15SPaul Saab */ 370a5f0fb15SPaul Saab if (optchar == '\0') 371a5f0fb15SPaul Saab { 372a5f0fb15SPaul Saab parg.p_string = get_cmdbuf(); 373a5f0fb15SPaul Saab error("There is no --%s option", &parg); 374a5f0fb15SPaul Saab return (MCA_DONE); 375a5f0fb15SPaul Saab } 376a5f0fb15SPaul Saab optgetname = FALSE; 377a5f0fb15SPaul Saab cmd_reset(); 378a5f0fb15SPaul Saab c = optchar; 379a5f0fb15SPaul Saab } else 380a5f0fb15SPaul Saab { 381a5f0fb15SPaul Saab if (optchar != '\0') 382a5f0fb15SPaul Saab { 383a5f0fb15SPaul Saab /* 384a5f0fb15SPaul Saab * Already have a match for the name. 385a5f0fb15SPaul Saab * Don't accept anything but erase/kill. 386a5f0fb15SPaul Saab */ 387a5f0fb15SPaul Saab if (c == erase_char || c == kill_char) 388a5f0fb15SPaul Saab return (MCA_DONE); 389a5f0fb15SPaul Saab return (MCA_MORE); 390a5f0fb15SPaul Saab } 391a5f0fb15SPaul Saab /* 392a5f0fb15SPaul Saab * Add char to cmd buffer and try to match 393a5f0fb15SPaul Saab * the option name. 394a5f0fb15SPaul Saab */ 395a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT) 396a5f0fb15SPaul Saab return (MCA_DONE); 397a5f0fb15SPaul Saab p = get_cmdbuf(); 398a5f0fb15SPaul Saab lc = islower(p[0]); 399a5f0fb15SPaul Saab o = findopt_name(&p, &oname, NULL); 400a5f0fb15SPaul Saab if (o != NULL) 401a5f0fb15SPaul Saab { 402a5f0fb15SPaul Saab /* 403a5f0fb15SPaul Saab * Got a match. 404a5f0fb15SPaul Saab * Remember the option letter and 405a5f0fb15SPaul Saab * display the full option name. 406a5f0fb15SPaul Saab */ 407a5f0fb15SPaul Saab optchar = o->oletter; 408a5f0fb15SPaul Saab if (!lc && islower(optchar)) 409a5f0fb15SPaul Saab optchar = toupper(optchar); 410a5f0fb15SPaul Saab cmd_reset(); 411a5f0fb15SPaul Saab mca_opt_toggle(); 412a5f0fb15SPaul Saab for (p = oname; *p != '\0'; p++) 413a5f0fb15SPaul Saab { 414a5f0fb15SPaul Saab c = *p; 415a5f0fb15SPaul Saab if (!lc && islower(c)) 416a5f0fb15SPaul Saab c = toupper(c); 417a5f0fb15SPaul Saab if (cmd_char(c) != CC_OK) 418a5f0fb15SPaul Saab return (MCA_DONE); 419a5f0fb15SPaul Saab } 420a5f0fb15SPaul Saab } 421a5f0fb15SPaul Saab return (MCA_MORE); 422a5f0fb15SPaul Saab } 423a5f0fb15SPaul Saab } else 424a5f0fb15SPaul Saab { 425a5f0fb15SPaul Saab if (c == erase_char || c == kill_char) 426a5f0fb15SPaul Saab break; 427a5f0fb15SPaul Saab if (optchar != '\0') 428a5f0fb15SPaul Saab /* We already have the option letter. */ 429a5f0fb15SPaul Saab break; 430a5f0fb15SPaul Saab } 431a5f0fb15SPaul Saab 432a5f0fb15SPaul Saab optchar = c; 433a5f0fb15SPaul Saab if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE || 434a5f0fb15SPaul Saab single_char_option(c)) 435a5f0fb15SPaul Saab { 436a5f0fb15SPaul Saab toggle_option(c, "", optflag); 437a5f0fb15SPaul Saab return (MCA_DONE); 438a5f0fb15SPaul Saab } 439a5f0fb15SPaul Saab /* 440a5f0fb15SPaul Saab * Display a prompt appropriate for the option letter. 441a5f0fb15SPaul Saab */ 442a5f0fb15SPaul Saab if ((p = opt_prompt(c)) == NULL) 443a5f0fb15SPaul Saab { 444a5f0fb15SPaul Saab buf[0] = '-'; 445a5f0fb15SPaul Saab buf[1] = c; 446a5f0fb15SPaul Saab buf[2] = '\0'; 447a5f0fb15SPaul Saab p = buf; 448a5f0fb15SPaul Saab } 449a5f0fb15SPaul Saab start_mca(A_OPT_TOGGLE, p, (void*)NULL, 0); 450a5f0fb15SPaul Saab return (MCA_MORE); 451a5f0fb15SPaul Saab 452a5f0fb15SPaul Saab case A_F_SEARCH: 453a5f0fb15SPaul Saab case A_B_SEARCH: 454a5f0fb15SPaul Saab /* 455a5f0fb15SPaul Saab * Special case for search commands. 456a5f0fb15SPaul Saab * Certain characters as the first char of 457a5f0fb15SPaul Saab * the pattern have special meaning: 458a5f0fb15SPaul Saab * ! Toggle the NO_MATCH flag 459a5f0fb15SPaul Saab * * Toggle the PAST_EOF flag 460a5f0fb15SPaul Saab * @ Toggle the FIRST_FILE flag 461a5f0fb15SPaul Saab */ 462a5f0fb15SPaul Saab if (len_cmdbuf() > 0) 463a5f0fb15SPaul Saab /* 464a5f0fb15SPaul Saab * Only works for the first char of the pattern. 465a5f0fb15SPaul Saab */ 466a5f0fb15SPaul Saab break; 467a5f0fb15SPaul Saab 468a5f0fb15SPaul Saab flag = 0; 469a5f0fb15SPaul Saab switch (c) 470a5f0fb15SPaul Saab { 471a5f0fb15SPaul Saab case CONTROL('E'): /* ignore END of file */ 472a5f0fb15SPaul Saab case '*': 473a5f0fb15SPaul Saab flag = SRCH_PAST_EOF; 474a5f0fb15SPaul Saab break; 475a5f0fb15SPaul Saab case CONTROL('F'): /* FIRST file */ 476a5f0fb15SPaul Saab case '@': 477a5f0fb15SPaul Saab flag = SRCH_FIRST_FILE; 478a5f0fb15SPaul Saab break; 479a5f0fb15SPaul Saab case CONTROL('K'): /* KEEP position */ 480a5f0fb15SPaul Saab flag = SRCH_NO_MOVE; 481a5f0fb15SPaul Saab break; 482a5f0fb15SPaul Saab case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */ 483a5f0fb15SPaul Saab flag = SRCH_NO_REGEX; 484a5f0fb15SPaul Saab break; 485a5f0fb15SPaul Saab case CONTROL('N'): /* NOT match */ 486a5f0fb15SPaul Saab case '!': 487a5f0fb15SPaul Saab flag = SRCH_NO_MATCH; 488a5f0fb15SPaul Saab break; 489a5f0fb15SPaul Saab } 490a5f0fb15SPaul Saab if (flag != 0) 491a5f0fb15SPaul Saab { 492a5f0fb15SPaul Saab search_type ^= flag; 493a5f0fb15SPaul Saab mca_search(); 494a5f0fb15SPaul Saab return (MCA_MORE); 495a5f0fb15SPaul Saab } 496a5f0fb15SPaul Saab break; 497a5f0fb15SPaul Saab } 498a5f0fb15SPaul Saab 499a5f0fb15SPaul Saab /* 500a5f0fb15SPaul Saab * Any other multicharacter command 501a5f0fb15SPaul Saab * is terminated by a newline. 502a5f0fb15SPaul Saab */ 503a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 504a5f0fb15SPaul Saab { 505a5f0fb15SPaul Saab /* 506a5f0fb15SPaul Saab * Execute the command. 507a5f0fb15SPaul Saab */ 508a5f0fb15SPaul Saab exec_mca(); 509a5f0fb15SPaul Saab return (MCA_DONE); 510a5f0fb15SPaul Saab } 511a5f0fb15SPaul Saab 512a5f0fb15SPaul Saab /* 513a5f0fb15SPaul Saab * Append the char to the command buffer. 514a5f0fb15SPaul Saab */ 515a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT) 516a5f0fb15SPaul Saab /* 517a5f0fb15SPaul Saab * Abort the multi-char command. 518a5f0fb15SPaul Saab */ 519a5f0fb15SPaul Saab return (MCA_DONE); 520a5f0fb15SPaul Saab 521a5f0fb15SPaul Saab if ((mca == A_F_BRACKET || mca == A_B_BRACKET) && len_cmdbuf() >= 2) 522a5f0fb15SPaul Saab { 523a5f0fb15SPaul Saab /* 524a5f0fb15SPaul Saab * Special case for the bracket-matching commands. 525a5f0fb15SPaul Saab * Execute the command after getting exactly two 526a5f0fb15SPaul Saab * characters from the user. 527a5f0fb15SPaul Saab */ 528a5f0fb15SPaul Saab exec_mca(); 529a5f0fb15SPaul Saab return (MCA_DONE); 530a5f0fb15SPaul Saab } 531a5f0fb15SPaul Saab 532a5f0fb15SPaul Saab /* 533a5f0fb15SPaul Saab * Need another character. 534a5f0fb15SPaul Saab */ 535a5f0fb15SPaul Saab return (MCA_MORE); 536a5f0fb15SPaul Saab } 537a5f0fb15SPaul Saab 538a5f0fb15SPaul Saab /* 539a5f0fb15SPaul Saab * Make sure the screen is displayed. 540a5f0fb15SPaul Saab */ 541a5f0fb15SPaul Saab static void 542a5f0fb15SPaul Saab make_display() 543a5f0fb15SPaul Saab { 544a5f0fb15SPaul Saab /* 545a5f0fb15SPaul Saab * If nothing is displayed yet, display starting from initial_scrpos. 546a5f0fb15SPaul Saab */ 547a5f0fb15SPaul Saab if (empty_screen()) 548a5f0fb15SPaul Saab { 549a5f0fb15SPaul Saab if (initial_scrpos.pos == NULL_POSITION) 550a5f0fb15SPaul Saab /* 551a5f0fb15SPaul Saab * {{ Maybe this should be: 552a5f0fb15SPaul Saab * jump_loc(ch_zero(), jump_sline); 553a5f0fb15SPaul Saab * but this behavior seems rather unexpected 554a5f0fb15SPaul Saab * on the first screen. }} 555a5f0fb15SPaul Saab */ 556a5f0fb15SPaul Saab jump_loc(ch_zero(), 1); 557a5f0fb15SPaul Saab else 558a5f0fb15SPaul Saab jump_loc(initial_scrpos.pos, initial_scrpos.ln); 559a5f0fb15SPaul Saab } else if (screen_trashed) 560a5f0fb15SPaul Saab { 561a5f0fb15SPaul Saab int save_top_scroll; 562a5f0fb15SPaul Saab save_top_scroll = top_scroll; 563a5f0fb15SPaul Saab top_scroll = 1; 564a5f0fb15SPaul Saab repaint(); 565a5f0fb15SPaul Saab top_scroll = save_top_scroll; 566a5f0fb15SPaul Saab } 567a5f0fb15SPaul Saab } 568a5f0fb15SPaul Saab 569a5f0fb15SPaul Saab /* 570a5f0fb15SPaul Saab * Display the appropriate prompt. 571a5f0fb15SPaul Saab */ 572a5f0fb15SPaul Saab static void 573a5f0fb15SPaul Saab prompt() 574a5f0fb15SPaul Saab { 575a5f0fb15SPaul Saab register char *p; 576a5f0fb15SPaul Saab 577a5f0fb15SPaul Saab if (ungotp != NULL && ungotp > ungot) 578a5f0fb15SPaul Saab { 579a5f0fb15SPaul Saab /* 580a5f0fb15SPaul Saab * No prompt necessary if commands are from 581a5f0fb15SPaul Saab * ungotten chars rather than from the user. 582a5f0fb15SPaul Saab */ 583a5f0fb15SPaul Saab return; 584a5f0fb15SPaul Saab } 585a5f0fb15SPaul Saab 586a5f0fb15SPaul Saab /* 587a5f0fb15SPaul Saab * Make sure the screen is displayed. 588a5f0fb15SPaul Saab */ 589a5f0fb15SPaul Saab make_display(); 590a5f0fb15SPaul Saab bottompos = position(BOTTOM_PLUS_ONE); 591a5f0fb15SPaul Saab 592a5f0fb15SPaul Saab /* 593a5f0fb15SPaul Saab * If the -E flag is set and we've hit EOF on the last file, quit. 594a5f0fb15SPaul Saab */ 595a5f0fb15SPaul Saab if ((quit_at_eof == OPT_ONPLUS || quit_if_one_screen) && 596a5f0fb15SPaul Saab hit_eof && !(ch_getflags() & CH_HELPFILE) && 597a5f0fb15SPaul Saab next_ifile(curr_ifile) == NULL_IFILE) 598a5f0fb15SPaul Saab quit(QUIT_OK); 599a5f0fb15SPaul Saab quit_if_one_screen = FALSE; 600a5f0fb15SPaul Saab #if 0 /* This doesn't work well because some "te"s clear the screen. */ 601a5f0fb15SPaul Saab /* 602a5f0fb15SPaul Saab * If the -e flag is set and we've hit EOF on the last file, 603a5f0fb15SPaul Saab * and the file is squished (shorter than the screen), quit. 604a5f0fb15SPaul Saab */ 605a5f0fb15SPaul Saab if (quit_at_eof && squished && 606a5f0fb15SPaul Saab next_ifile(curr_ifile) == NULL_IFILE) 607a5f0fb15SPaul Saab quit(QUIT_OK); 608a5f0fb15SPaul Saab #endif 609a5f0fb15SPaul Saab 610a5f0fb15SPaul Saab /* 611a5f0fb15SPaul Saab * Select the proper prompt and display it. 612a5f0fb15SPaul Saab */ 613a5f0fb15SPaul Saab clear_cmd(); 614a5f0fb15SPaul Saab p = pr_string(); 615a5f0fb15SPaul Saab if (p == NULL) 616a5f0fb15SPaul Saab putchr(':'); 617a5f0fb15SPaul Saab else 618a5f0fb15SPaul Saab { 619a5f0fb15SPaul Saab so_enter(); 620a5f0fb15SPaul Saab putstr(p); 621a5f0fb15SPaul Saab so_exit(); 622a5f0fb15SPaul Saab } 623a5f0fb15SPaul Saab } 624a5f0fb15SPaul Saab 625a5f0fb15SPaul Saab /* 626a5f0fb15SPaul Saab * Display the less version message. 627a5f0fb15SPaul Saab */ 628a5f0fb15SPaul Saab public void 629a5f0fb15SPaul Saab dispversion() 630a5f0fb15SPaul Saab { 631a5f0fb15SPaul Saab PARG parg; 632a5f0fb15SPaul Saab 633a5f0fb15SPaul Saab parg.p_string = version; 634a5f0fb15SPaul Saab error("less %s", &parg); 635a5f0fb15SPaul Saab } 636a5f0fb15SPaul Saab 637a5f0fb15SPaul Saab /* 638a5f0fb15SPaul Saab * Get command character. 639a5f0fb15SPaul Saab * The character normally comes from the keyboard, 640a5f0fb15SPaul Saab * but may come from ungotten characters 641a5f0fb15SPaul Saab * (characters previously given to ungetcc or ungetsc). 642a5f0fb15SPaul Saab */ 643a5f0fb15SPaul Saab public int 644a5f0fb15SPaul Saab getcc() 645a5f0fb15SPaul Saab { 646a5f0fb15SPaul Saab if (ungotp == NULL) 647a5f0fb15SPaul Saab /* 648a5f0fb15SPaul Saab * Normal case: no ungotten chars, so get one from the user. 649a5f0fb15SPaul Saab */ 650a5f0fb15SPaul Saab return (getchr()); 651a5f0fb15SPaul Saab 652a5f0fb15SPaul Saab if (ungotp > ungot) 653a5f0fb15SPaul Saab /* 654a5f0fb15SPaul Saab * Return the next ungotten char. 655a5f0fb15SPaul Saab */ 656a5f0fb15SPaul Saab return (*--ungotp); 657a5f0fb15SPaul Saab 658a5f0fb15SPaul Saab /* 659a5f0fb15SPaul Saab * We have just run out of ungotten chars. 660a5f0fb15SPaul Saab */ 661a5f0fb15SPaul Saab ungotp = NULL; 662a5f0fb15SPaul Saab if (len_cmdbuf() == 0 || !empty_screen()) 663a5f0fb15SPaul Saab return (getchr()); 664a5f0fb15SPaul Saab /* 665a5f0fb15SPaul Saab * Command is incomplete, so try to complete it. 666a5f0fb15SPaul Saab */ 667a5f0fb15SPaul Saab switch (mca) 668a5f0fb15SPaul Saab { 669a5f0fb15SPaul Saab case A_DIGIT: 670a5f0fb15SPaul Saab /* 671a5f0fb15SPaul Saab * We have a number but no command. Treat as #g. 672a5f0fb15SPaul Saab */ 673a5f0fb15SPaul Saab return ('g'); 674a5f0fb15SPaul Saab 675a5f0fb15SPaul Saab case A_F_SEARCH: 676a5f0fb15SPaul Saab case A_B_SEARCH: 677a5f0fb15SPaul Saab /* 678a5f0fb15SPaul Saab * We have "/string" but no newline. Add the \n. 679a5f0fb15SPaul Saab */ 680a5f0fb15SPaul Saab return ('\n'); 681a5f0fb15SPaul Saab 682a5f0fb15SPaul Saab default: 683a5f0fb15SPaul Saab /* 684a5f0fb15SPaul Saab * Some other incomplete command. Let user complete it. 685a5f0fb15SPaul Saab */ 686a5f0fb15SPaul Saab return (getchr()); 687a5f0fb15SPaul Saab } 688a5f0fb15SPaul Saab } 689a5f0fb15SPaul Saab 690a5f0fb15SPaul Saab /* 691a5f0fb15SPaul Saab * "Unget" a command character. 692a5f0fb15SPaul Saab * The next getcc() will return this character. 693a5f0fb15SPaul Saab */ 694a5f0fb15SPaul Saab public void 695a5f0fb15SPaul Saab ungetcc(c) 696a5f0fb15SPaul Saab int c; 697a5f0fb15SPaul Saab { 698a5f0fb15SPaul Saab if (ungotp == NULL) 699a5f0fb15SPaul Saab ungotp = ungot; 700a5f0fb15SPaul Saab if (ungotp >= ungot + sizeof(ungot)) 701a5f0fb15SPaul Saab { 702a5f0fb15SPaul Saab error("ungetcc overflow", NULL_PARG); 703a5f0fb15SPaul Saab quit(QUIT_ERROR); 704a5f0fb15SPaul Saab } 705a5f0fb15SPaul Saab *ungotp++ = c; 706a5f0fb15SPaul Saab } 707a5f0fb15SPaul Saab 708a5f0fb15SPaul Saab /* 709a5f0fb15SPaul Saab * Unget a whole string of command characters. 710a5f0fb15SPaul Saab * The next sequence of getcc()'s will return this string. 711a5f0fb15SPaul Saab */ 712a5f0fb15SPaul Saab public void 713a5f0fb15SPaul Saab ungetsc(s) 714a5f0fb15SPaul Saab char *s; 715a5f0fb15SPaul Saab { 716a5f0fb15SPaul Saab register char *p; 717a5f0fb15SPaul Saab 718a5f0fb15SPaul Saab for (p = s + strlen(s) - 1; p >= s; p--) 719a5f0fb15SPaul Saab ungetcc(*p); 720a5f0fb15SPaul Saab } 721a5f0fb15SPaul Saab 722a5f0fb15SPaul Saab /* 723a5f0fb15SPaul Saab * Search for a pattern, possibly in multiple files. 724a5f0fb15SPaul Saab * If SRCH_FIRST_FILE is set, begin searching at the first file. 725a5f0fb15SPaul Saab * If SRCH_PAST_EOF is set, continue the search thru multiple files. 726a5f0fb15SPaul Saab */ 727a5f0fb15SPaul Saab static void 728a5f0fb15SPaul Saab multi_search(pattern, n) 729a5f0fb15SPaul Saab char *pattern; 730a5f0fb15SPaul Saab int n; 731a5f0fb15SPaul Saab { 732a5f0fb15SPaul Saab register int nomore; 733a5f0fb15SPaul Saab IFILE save_ifile; 734a5f0fb15SPaul Saab int changed_file; 735a5f0fb15SPaul Saab 736a5f0fb15SPaul Saab changed_file = 0; 737a5f0fb15SPaul Saab save_ifile = save_curr_ifile(); 738a5f0fb15SPaul Saab 739a5f0fb15SPaul Saab if (search_type & SRCH_FIRST_FILE) 740a5f0fb15SPaul Saab { 741a5f0fb15SPaul Saab /* 742a5f0fb15SPaul Saab * Start at the first (or last) file 743a5f0fb15SPaul Saab * in the command line list. 744a5f0fb15SPaul Saab */ 745a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 746a5f0fb15SPaul Saab nomore = edit_first(); 747a5f0fb15SPaul Saab else 748a5f0fb15SPaul Saab nomore = edit_last(); 749a5f0fb15SPaul Saab if (nomore) 750a5f0fb15SPaul Saab { 751a5f0fb15SPaul Saab unsave_ifile(save_ifile); 752a5f0fb15SPaul Saab return; 753a5f0fb15SPaul Saab } 754a5f0fb15SPaul Saab changed_file = 1; 755a5f0fb15SPaul Saab search_type &= ~SRCH_FIRST_FILE; 756a5f0fb15SPaul Saab } 757a5f0fb15SPaul Saab 758a5f0fb15SPaul Saab for (;;) 759a5f0fb15SPaul Saab { 760a5f0fb15SPaul Saab n = search(search_type, pattern, n); 761a5f0fb15SPaul Saab /* 762a5f0fb15SPaul Saab * The SRCH_NO_MOVE flag doesn't "stick": it gets cleared 763a5f0fb15SPaul Saab * after being used once. This allows "n" to work after 764a5f0fb15SPaul Saab * using a /@@ search. 765a5f0fb15SPaul Saab */ 766a5f0fb15SPaul Saab search_type &= ~SRCH_NO_MOVE; 767a5f0fb15SPaul Saab if (n == 0) 768a5f0fb15SPaul Saab { 769a5f0fb15SPaul Saab /* 770a5f0fb15SPaul Saab * Found it. 771a5f0fb15SPaul Saab */ 772a5f0fb15SPaul Saab unsave_ifile(save_ifile); 773a5f0fb15SPaul Saab return; 774a5f0fb15SPaul Saab } 775a5f0fb15SPaul Saab 776a5f0fb15SPaul Saab if (n < 0) 777a5f0fb15SPaul Saab /* 778a5f0fb15SPaul Saab * Some kind of error in the search. 779a5f0fb15SPaul Saab * Error message has been printed by search(). 780a5f0fb15SPaul Saab */ 781a5f0fb15SPaul Saab break; 782a5f0fb15SPaul Saab 783a5f0fb15SPaul Saab if ((search_type & SRCH_PAST_EOF) == 0) 784a5f0fb15SPaul Saab /* 785a5f0fb15SPaul Saab * We didn't find a match, but we're 786a5f0fb15SPaul Saab * supposed to search only one file. 787a5f0fb15SPaul Saab */ 788a5f0fb15SPaul Saab break; 789a5f0fb15SPaul Saab /* 790a5f0fb15SPaul Saab * Move on to the next file. 791a5f0fb15SPaul Saab */ 792a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 793a5f0fb15SPaul Saab nomore = edit_next(1); 794a5f0fb15SPaul Saab else 795a5f0fb15SPaul Saab nomore = edit_prev(1); 796a5f0fb15SPaul Saab if (nomore) 797a5f0fb15SPaul Saab break; 798a5f0fb15SPaul Saab changed_file = 1; 799a5f0fb15SPaul Saab } 800a5f0fb15SPaul Saab 801a5f0fb15SPaul Saab /* 802a5f0fb15SPaul Saab * Didn't find it. 803a5f0fb15SPaul Saab * Print an error message if we haven't already. 804a5f0fb15SPaul Saab */ 805a5f0fb15SPaul Saab if (n > 0) 806a5f0fb15SPaul Saab error("Pattern not found", NULL_PARG); 807a5f0fb15SPaul Saab 808a5f0fb15SPaul Saab if (changed_file) 809a5f0fb15SPaul Saab { 810a5f0fb15SPaul Saab /* 811a5f0fb15SPaul Saab * Restore the file we were originally viewing. 812a5f0fb15SPaul Saab */ 813a5f0fb15SPaul Saab reedit_ifile(save_ifile); 814a5f0fb15SPaul Saab } 815a5f0fb15SPaul Saab } 816a5f0fb15SPaul Saab 817a5f0fb15SPaul Saab /* 818a5f0fb15SPaul Saab * Main command processor. 819a5f0fb15SPaul Saab * Accept and execute commands until a quit command. 820a5f0fb15SPaul Saab */ 821a5f0fb15SPaul Saab public void 822a5f0fb15SPaul Saab commands() 823a5f0fb15SPaul Saab { 824a5f0fb15SPaul Saab register int c; 825a5f0fb15SPaul Saab register int action; 826a5f0fb15SPaul Saab register char *cbuf; 827a5f0fb15SPaul Saab int newaction; 828a5f0fb15SPaul Saab int save_search_type; 829a5f0fb15SPaul Saab char *extra; 830a5f0fb15SPaul Saab char tbuf[2]; 831a5f0fb15SPaul Saab PARG parg; 832a5f0fb15SPaul Saab IFILE old_ifile; 833a5f0fb15SPaul Saab IFILE new_ifile; 834a5f0fb15SPaul Saab 835a5f0fb15SPaul Saab search_type = SRCH_FORW; 836a5f0fb15SPaul Saab wscroll = (sc_height + 1) / 2; 837a5f0fb15SPaul Saab newaction = A_NOACTION; 838a5f0fb15SPaul Saab 839a5f0fb15SPaul Saab for (;;) 840a5f0fb15SPaul Saab { 841a5f0fb15SPaul Saab mca = 0; 842a5f0fb15SPaul Saab cmd_accept(); 843a5f0fb15SPaul Saab number = 0; 844a5f0fb15SPaul Saab optchar = '\0'; 845a5f0fb15SPaul Saab 846a5f0fb15SPaul Saab /* 847a5f0fb15SPaul Saab * See if any signals need processing. 848a5f0fb15SPaul Saab */ 849a5f0fb15SPaul Saab if (sigs) 850a5f0fb15SPaul Saab { 851a5f0fb15SPaul Saab psignals(); 852a5f0fb15SPaul Saab if (quitting) 853a5f0fb15SPaul Saab quit(QUIT_SAVED_STATUS); 854a5f0fb15SPaul Saab } 855a5f0fb15SPaul Saab 856a5f0fb15SPaul Saab /* 857a5f0fb15SPaul Saab * See if window size changed, for systems that don't 858a5f0fb15SPaul Saab * generate SIGWINCH. 859a5f0fb15SPaul Saab */ 860a5f0fb15SPaul Saab check_winch(); 861a5f0fb15SPaul Saab 862a5f0fb15SPaul Saab /* 863a5f0fb15SPaul Saab * Display prompt and accept a character. 864a5f0fb15SPaul Saab */ 865a5f0fb15SPaul Saab cmd_reset(); 866a5f0fb15SPaul Saab prompt(); 867a5f0fb15SPaul Saab if (sigs) 868a5f0fb15SPaul Saab continue; 869a5f0fb15SPaul Saab if (newaction == A_NOACTION) 870a5f0fb15SPaul Saab c = getcc(); 871a5f0fb15SPaul Saab 872a5f0fb15SPaul Saab again: 873a5f0fb15SPaul Saab if (sigs) 874a5f0fb15SPaul Saab continue; 875a5f0fb15SPaul Saab 876a5f0fb15SPaul Saab if (newaction != A_NOACTION) 877a5f0fb15SPaul Saab { 878a5f0fb15SPaul Saab action = newaction; 879a5f0fb15SPaul Saab newaction = A_NOACTION; 880a5f0fb15SPaul Saab } else 881a5f0fb15SPaul Saab { 882a5f0fb15SPaul Saab /* 883a5f0fb15SPaul Saab * If we are in a multicharacter command, call mca_char. 884a5f0fb15SPaul Saab * Otherwise we call fcmd_decode to determine the 885a5f0fb15SPaul Saab * action to be performed. 886a5f0fb15SPaul Saab */ 887a5f0fb15SPaul Saab if (mca) 888a5f0fb15SPaul Saab switch (mca_char(c)) 889a5f0fb15SPaul Saab { 890a5f0fb15SPaul Saab case MCA_MORE: 891a5f0fb15SPaul Saab /* 892a5f0fb15SPaul Saab * Need another character. 893a5f0fb15SPaul Saab */ 894a5f0fb15SPaul Saab c = getcc(); 895a5f0fb15SPaul Saab goto again; 896a5f0fb15SPaul Saab case MCA_DONE: 897a5f0fb15SPaul Saab /* 898a5f0fb15SPaul Saab * Command has been handled by mca_char. 899a5f0fb15SPaul Saab * Start clean with a prompt. 900a5f0fb15SPaul Saab */ 901a5f0fb15SPaul Saab continue; 902a5f0fb15SPaul Saab case NO_MCA: 903a5f0fb15SPaul Saab /* 904a5f0fb15SPaul Saab * Not a multi-char command 905a5f0fb15SPaul Saab * (at least, not anymore). 906a5f0fb15SPaul Saab */ 907a5f0fb15SPaul Saab break; 908a5f0fb15SPaul Saab } 909a5f0fb15SPaul Saab 910a5f0fb15SPaul Saab /* 911a5f0fb15SPaul Saab * Decode the command character and decide what to do. 912a5f0fb15SPaul Saab */ 913a5f0fb15SPaul Saab if (mca) 914a5f0fb15SPaul Saab { 915a5f0fb15SPaul Saab /* 916a5f0fb15SPaul Saab * We're in a multichar command. 917a5f0fb15SPaul Saab * Add the character to the command buffer 918a5f0fb15SPaul Saab * and display it on the screen. 919a5f0fb15SPaul Saab * If the user backspaces past the start 920a5f0fb15SPaul Saab * of the line, abort the command. 921a5f0fb15SPaul Saab */ 922a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0) 923a5f0fb15SPaul Saab continue; 924a5f0fb15SPaul Saab cbuf = get_cmdbuf(); 925a5f0fb15SPaul Saab } else 926a5f0fb15SPaul Saab { 927a5f0fb15SPaul Saab /* 928a5f0fb15SPaul Saab * Don't use cmd_char if we're starting fresh 929a5f0fb15SPaul Saab * at the beginning of a command, because we 930a5f0fb15SPaul Saab * don't want to echo the command until we know 931a5f0fb15SPaul Saab * it is a multichar command. We also don't 932a5f0fb15SPaul Saab * want erase_char/kill_char to be treated 933a5f0fb15SPaul Saab * as line editing characters. 934a5f0fb15SPaul Saab */ 935a5f0fb15SPaul Saab tbuf[0] = c; 936a5f0fb15SPaul Saab tbuf[1] = '\0'; 937a5f0fb15SPaul Saab cbuf = tbuf; 938a5f0fb15SPaul Saab } 939a5f0fb15SPaul Saab extra = NULL; 940a5f0fb15SPaul Saab action = fcmd_decode(cbuf, &extra); 941a5f0fb15SPaul Saab /* 942a5f0fb15SPaul Saab * If an "extra" string was returned, 943a5f0fb15SPaul Saab * process it as a string of command characters. 944a5f0fb15SPaul Saab */ 945a5f0fb15SPaul Saab if (extra != NULL) 946a5f0fb15SPaul Saab ungetsc(extra); 947a5f0fb15SPaul Saab } 948a5f0fb15SPaul Saab /* 949a5f0fb15SPaul Saab * Clear the cmdbuf string. 950a5f0fb15SPaul Saab * (But not if we're in the prefix of a command, 951a5f0fb15SPaul Saab * because the partial command string is kept there.) 952a5f0fb15SPaul Saab */ 953a5f0fb15SPaul Saab if (action != A_PREFIX) 954a5f0fb15SPaul Saab cmd_reset(); 955a5f0fb15SPaul Saab 956a5f0fb15SPaul Saab switch (action) 957a5f0fb15SPaul Saab { 958a5f0fb15SPaul Saab case A_DIGIT: 959a5f0fb15SPaul Saab /* 960a5f0fb15SPaul Saab * First digit of a number. 961a5f0fb15SPaul Saab */ 962a5f0fb15SPaul Saab start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE); 963a5f0fb15SPaul Saab goto again; 964a5f0fb15SPaul Saab 965a5f0fb15SPaul Saab case A_F_WINDOW: 966a5f0fb15SPaul Saab /* 967a5f0fb15SPaul Saab * Forward one window (and set the window size). 968a5f0fb15SPaul Saab */ 969a5f0fb15SPaul Saab if (number > 0) 970a5f0fb15SPaul Saab swindow = number; 971a5f0fb15SPaul Saab /* FALLTHRU */ 972a5f0fb15SPaul Saab case A_F_SCREEN: 973a5f0fb15SPaul Saab /* 974a5f0fb15SPaul Saab * Forward one screen. 975a5f0fb15SPaul Saab */ 976a5f0fb15SPaul Saab if (number <= 0) 977a5f0fb15SPaul Saab number = get_swindow(); 978a5f0fb15SPaul Saab cmd_exec(); 979a5f0fb15SPaul Saab if (show_attn) 980a5f0fb15SPaul Saab set_attnpos(bottompos); 981a5f0fb15SPaul Saab forward(number, 0, 1); 982a5f0fb15SPaul Saab break; 983a5f0fb15SPaul Saab 984a5f0fb15SPaul Saab case A_B_WINDOW: 985a5f0fb15SPaul Saab /* 986a5f0fb15SPaul Saab * Backward one window (and set the window size). 987a5f0fb15SPaul Saab */ 988a5f0fb15SPaul Saab if (number > 0) 989a5f0fb15SPaul Saab swindow = number; 990a5f0fb15SPaul Saab /* FALLTHRU */ 991a5f0fb15SPaul Saab case A_B_SCREEN: 992a5f0fb15SPaul Saab /* 993a5f0fb15SPaul Saab * Backward one screen. 994a5f0fb15SPaul Saab */ 995a5f0fb15SPaul Saab if (number <= 0) 996a5f0fb15SPaul Saab number = get_swindow(); 997a5f0fb15SPaul Saab cmd_exec(); 998a5f0fb15SPaul Saab backward(number, 0, 1); 999a5f0fb15SPaul Saab break; 1000a5f0fb15SPaul Saab 1001a5f0fb15SPaul Saab case A_F_LINE: 1002a5f0fb15SPaul Saab /* 1003a5f0fb15SPaul Saab * Forward N (default 1) line. 1004a5f0fb15SPaul Saab */ 1005a5f0fb15SPaul Saab if (number <= 0) 1006a5f0fb15SPaul Saab number = 1; 1007a5f0fb15SPaul Saab cmd_exec(); 1008a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS && number > 1) 1009a5f0fb15SPaul Saab set_attnpos(bottompos); 1010a5f0fb15SPaul Saab forward(number, 0, 0); 1011a5f0fb15SPaul Saab break; 1012a5f0fb15SPaul Saab 1013a5f0fb15SPaul Saab case A_B_LINE: 1014a5f0fb15SPaul Saab /* 1015a5f0fb15SPaul Saab * Backward N (default 1) line. 1016a5f0fb15SPaul Saab */ 1017a5f0fb15SPaul Saab if (number <= 0) 1018a5f0fb15SPaul Saab number = 1; 1019a5f0fb15SPaul Saab cmd_exec(); 1020a5f0fb15SPaul Saab backward(number, 0, 0); 1021a5f0fb15SPaul Saab break; 1022a5f0fb15SPaul Saab 1023a5f0fb15SPaul Saab case A_FF_LINE: 1024a5f0fb15SPaul Saab /* 1025a5f0fb15SPaul Saab * Force forward N (default 1) line. 1026a5f0fb15SPaul Saab */ 1027a5f0fb15SPaul Saab if (number <= 0) 1028a5f0fb15SPaul Saab number = 1; 1029a5f0fb15SPaul Saab cmd_exec(); 1030a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS && number > 1) 1031a5f0fb15SPaul Saab set_attnpos(bottompos); 1032a5f0fb15SPaul Saab forward(number, 1, 0); 1033a5f0fb15SPaul Saab break; 1034a5f0fb15SPaul Saab 1035a5f0fb15SPaul Saab case A_BF_LINE: 1036a5f0fb15SPaul Saab /* 1037a5f0fb15SPaul Saab * Force backward N (default 1) line. 1038a5f0fb15SPaul Saab */ 1039a5f0fb15SPaul Saab if (number <= 0) 1040a5f0fb15SPaul Saab number = 1; 1041a5f0fb15SPaul Saab cmd_exec(); 1042a5f0fb15SPaul Saab backward(number, 1, 0); 1043a5f0fb15SPaul Saab break; 1044a5f0fb15SPaul Saab 1045a5f0fb15SPaul Saab case A_FF_SCREEN: 1046a5f0fb15SPaul Saab /* 1047a5f0fb15SPaul Saab * Force forward one screen. 1048a5f0fb15SPaul Saab */ 1049a5f0fb15SPaul Saab if (number <= 0) 1050a5f0fb15SPaul Saab number = get_swindow(); 1051a5f0fb15SPaul Saab cmd_exec(); 1052a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS) 1053a5f0fb15SPaul Saab set_attnpos(bottompos); 1054a5f0fb15SPaul Saab forward(number, 1, 0); 1055a5f0fb15SPaul Saab break; 1056a5f0fb15SPaul Saab 1057a5f0fb15SPaul Saab case A_F_FOREVER: 1058a5f0fb15SPaul Saab /* 1059a5f0fb15SPaul Saab * Forward forever, ignoring EOF. 1060a5f0fb15SPaul Saab */ 1061a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1062a5f0fb15SPaul Saab break; 1063a5f0fb15SPaul Saab cmd_exec(); 1064a5f0fb15SPaul Saab jump_forw(); 1065a5f0fb15SPaul Saab ignore_eoi = 1; 1066a5f0fb15SPaul Saab hit_eof = 0; 1067a5f0fb15SPaul Saab while (!sigs) 1068a5f0fb15SPaul Saab forward(1, 0, 0); 1069a5f0fb15SPaul Saab ignore_eoi = 0; 1070a5f0fb15SPaul Saab /* 1071a5f0fb15SPaul Saab * This gets us back in "F mode" after processing 1072a5f0fb15SPaul Saab * a non-abort signal (e.g. window-change). 1073a5f0fb15SPaul Saab */ 1074a5f0fb15SPaul Saab if (sigs && !ABORT_SIGS()) 1075a5f0fb15SPaul Saab newaction = A_F_FOREVER; 1076a5f0fb15SPaul Saab break; 1077a5f0fb15SPaul Saab 1078a5f0fb15SPaul Saab case A_F_SCROLL: 1079a5f0fb15SPaul Saab /* 1080a5f0fb15SPaul Saab * Forward N lines 1081a5f0fb15SPaul Saab * (default same as last 'd' or 'u' command). 1082a5f0fb15SPaul Saab */ 1083a5f0fb15SPaul Saab if (number > 0) 1084a5f0fb15SPaul Saab wscroll = number; 1085a5f0fb15SPaul Saab cmd_exec(); 1086a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS) 1087a5f0fb15SPaul Saab set_attnpos(bottompos); 1088a5f0fb15SPaul Saab forward(wscroll, 0, 0); 1089a5f0fb15SPaul Saab break; 1090a5f0fb15SPaul Saab 1091a5f0fb15SPaul Saab case A_B_SCROLL: 1092a5f0fb15SPaul Saab /* 1093a5f0fb15SPaul Saab * Forward N lines 1094a5f0fb15SPaul Saab * (default same as last 'd' or 'u' command). 1095a5f0fb15SPaul Saab */ 1096a5f0fb15SPaul Saab if (number > 0) 1097a5f0fb15SPaul Saab wscroll = number; 1098a5f0fb15SPaul Saab cmd_exec(); 1099a5f0fb15SPaul Saab backward(wscroll, 0, 0); 1100a5f0fb15SPaul Saab break; 1101a5f0fb15SPaul Saab 1102a5f0fb15SPaul Saab case A_FREPAINT: 1103a5f0fb15SPaul Saab /* 1104a5f0fb15SPaul Saab * Flush buffers, then repaint screen. 1105a5f0fb15SPaul Saab * Don't flush the buffers on a pipe! 1106a5f0fb15SPaul Saab */ 1107a5f0fb15SPaul Saab if (ch_getflags() & CH_CANSEEK) 1108a5f0fb15SPaul Saab { 1109a5f0fb15SPaul Saab ch_flush(); 1110a5f0fb15SPaul Saab clr_linenum(); 1111a5f0fb15SPaul Saab #if HILITE_SEARCH 1112a5f0fb15SPaul Saab clr_hilite(); 1113a5f0fb15SPaul Saab #endif 1114a5f0fb15SPaul Saab } 1115a5f0fb15SPaul Saab /* FALLTHRU */ 1116a5f0fb15SPaul Saab case A_REPAINT: 1117a5f0fb15SPaul Saab /* 1118a5f0fb15SPaul Saab * Repaint screen. 1119a5f0fb15SPaul Saab */ 1120a5f0fb15SPaul Saab cmd_exec(); 1121a5f0fb15SPaul Saab repaint(); 1122a5f0fb15SPaul Saab break; 1123a5f0fb15SPaul Saab 1124a5f0fb15SPaul Saab case A_GOLINE: 1125a5f0fb15SPaul Saab /* 1126a5f0fb15SPaul Saab * Go to line N, default beginning of file. 1127a5f0fb15SPaul Saab */ 1128a5f0fb15SPaul Saab if (number <= 0) 1129a5f0fb15SPaul Saab number = 1; 1130a5f0fb15SPaul Saab cmd_exec(); 1131a5f0fb15SPaul Saab jump_back(number); 1132a5f0fb15SPaul Saab break; 1133a5f0fb15SPaul Saab 1134a5f0fb15SPaul Saab case A_PERCENT: 1135a5f0fb15SPaul Saab /* 1136a5f0fb15SPaul Saab * Go to a specified percentage into the file. 1137a5f0fb15SPaul Saab */ 1138a5f0fb15SPaul Saab if (number < 0) 1139a5f0fb15SPaul Saab number = 0; 1140a5f0fb15SPaul Saab if (number > 100) 1141a5f0fb15SPaul Saab number = 100; 1142a5f0fb15SPaul Saab cmd_exec(); 1143a5f0fb15SPaul Saab jump_percent(number); 1144a5f0fb15SPaul Saab break; 1145a5f0fb15SPaul Saab 1146a5f0fb15SPaul Saab case A_GOEND: 1147a5f0fb15SPaul Saab /* 1148a5f0fb15SPaul Saab * Go to line N, default end of file. 1149a5f0fb15SPaul Saab */ 1150a5f0fb15SPaul Saab cmd_exec(); 1151a5f0fb15SPaul Saab if (number <= 0) 1152a5f0fb15SPaul Saab jump_forw(); 1153a5f0fb15SPaul Saab else 1154a5f0fb15SPaul Saab jump_back(number); 1155a5f0fb15SPaul Saab break; 1156a5f0fb15SPaul Saab 1157a5f0fb15SPaul Saab case A_GOPOS: 1158a5f0fb15SPaul Saab /* 1159a5f0fb15SPaul Saab * Go to a specified byte position in the file. 1160a5f0fb15SPaul Saab */ 1161a5f0fb15SPaul Saab cmd_exec(); 1162a5f0fb15SPaul Saab if (number < 0) 1163a5f0fb15SPaul Saab number = 0; 1164a5f0fb15SPaul Saab jump_line_loc((POSITION)number, jump_sline); 1165a5f0fb15SPaul Saab break; 1166a5f0fb15SPaul Saab 1167a5f0fb15SPaul Saab case A_STAT: 1168a5f0fb15SPaul Saab /* 1169a5f0fb15SPaul Saab * Print file name, etc. 1170a5f0fb15SPaul Saab */ 1171a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1172a5f0fb15SPaul Saab break; 1173a5f0fb15SPaul Saab cmd_exec(); 1174a5f0fb15SPaul Saab parg.p_string = eq_message(); 1175a5f0fb15SPaul Saab error("%s", &parg); 1176a5f0fb15SPaul Saab break; 1177a5f0fb15SPaul Saab 1178a5f0fb15SPaul Saab case A_VERSION: 1179a5f0fb15SPaul Saab /* 1180a5f0fb15SPaul Saab * Print version number, without the "@(#)". 1181a5f0fb15SPaul Saab */ 1182a5f0fb15SPaul Saab cmd_exec(); 1183a5f0fb15SPaul Saab dispversion(); 1184a5f0fb15SPaul Saab break; 1185a5f0fb15SPaul Saab 1186a5f0fb15SPaul Saab case A_QUIT: 1187a5f0fb15SPaul Saab /* 1188a5f0fb15SPaul Saab * Exit. 1189a5f0fb15SPaul Saab */ 1190a5f0fb15SPaul Saab if (curr_ifile != NULL_IFILE && 1191a5f0fb15SPaul Saab ch_getflags() & CH_HELPFILE) 1192a5f0fb15SPaul Saab { 1193a5f0fb15SPaul Saab /* 1194a5f0fb15SPaul Saab * Quit while viewing the help file 1195a5f0fb15SPaul Saab * just means return to viewing the 1196a5f0fb15SPaul Saab * previous file. 1197a5f0fb15SPaul Saab */ 1198a5f0fb15SPaul Saab if (edit_prev(1) == 0) 1199a5f0fb15SPaul Saab break; 1200a5f0fb15SPaul Saab } 1201a5f0fb15SPaul Saab if (extra != NULL) 1202a5f0fb15SPaul Saab quit(*extra); 1203a5f0fb15SPaul Saab quit(QUIT_OK); 1204a5f0fb15SPaul Saab break; 1205a5f0fb15SPaul Saab 1206a5f0fb15SPaul Saab /* 1207a5f0fb15SPaul Saab * Define abbreviation for a commonly used sequence below. 1208a5f0fb15SPaul Saab */ 1209a5f0fb15SPaul Saab #define DO_SEARCH() if (number <= 0) number = 1; \ 1210a5f0fb15SPaul Saab mca_search(); \ 1211a5f0fb15SPaul Saab cmd_exec(); \ 1212a5f0fb15SPaul Saab multi_search((char *)NULL, number); 1213a5f0fb15SPaul Saab 1214a5f0fb15SPaul Saab 1215a5f0fb15SPaul Saab case A_F_SEARCH: 1216a5f0fb15SPaul Saab /* 1217a5f0fb15SPaul Saab * Search forward for a pattern. 1218a5f0fb15SPaul Saab * Get the first char of the pattern. 1219a5f0fb15SPaul Saab */ 1220a5f0fb15SPaul Saab search_type = SRCH_FORW; 1221a5f0fb15SPaul Saab if (number <= 0) 1222a5f0fb15SPaul Saab number = 1; 1223a5f0fb15SPaul Saab mca_search(); 1224a5f0fb15SPaul Saab c = getcc(); 1225a5f0fb15SPaul Saab goto again; 1226a5f0fb15SPaul Saab 1227a5f0fb15SPaul Saab case A_B_SEARCH: 1228a5f0fb15SPaul Saab /* 1229a5f0fb15SPaul Saab * Search backward for a pattern. 1230a5f0fb15SPaul Saab * Get the first char of the pattern. 1231a5f0fb15SPaul Saab */ 1232a5f0fb15SPaul Saab search_type = SRCH_BACK; 1233a5f0fb15SPaul Saab if (number <= 0) 1234a5f0fb15SPaul Saab number = 1; 1235a5f0fb15SPaul Saab mca_search(); 1236a5f0fb15SPaul Saab c = getcc(); 1237a5f0fb15SPaul Saab goto again; 1238a5f0fb15SPaul Saab 1239a5f0fb15SPaul Saab case A_AGAIN_SEARCH: 1240a5f0fb15SPaul Saab /* 1241a5f0fb15SPaul Saab * Repeat previous search. 1242a5f0fb15SPaul Saab */ 1243a5f0fb15SPaul Saab DO_SEARCH(); 1244a5f0fb15SPaul Saab break; 1245a5f0fb15SPaul Saab 1246a5f0fb15SPaul Saab case A_T_AGAIN_SEARCH: 1247a5f0fb15SPaul Saab /* 1248a5f0fb15SPaul Saab * Repeat previous search, multiple files. 1249a5f0fb15SPaul Saab */ 1250a5f0fb15SPaul Saab search_type |= SRCH_PAST_EOF; 1251a5f0fb15SPaul Saab DO_SEARCH(); 1252a5f0fb15SPaul Saab break; 1253a5f0fb15SPaul Saab 1254a5f0fb15SPaul Saab case A_REVERSE_SEARCH: 1255a5f0fb15SPaul Saab /* 1256a5f0fb15SPaul Saab * Repeat previous search, in reverse direction. 1257a5f0fb15SPaul Saab */ 1258a5f0fb15SPaul Saab save_search_type = search_type; 1259a5f0fb15SPaul Saab search_type = SRCH_REVERSE(search_type); 1260a5f0fb15SPaul Saab DO_SEARCH(); 1261a5f0fb15SPaul Saab search_type = save_search_type; 1262a5f0fb15SPaul Saab break; 1263a5f0fb15SPaul Saab 1264a5f0fb15SPaul Saab case A_T_REVERSE_SEARCH: 1265a5f0fb15SPaul Saab /* 1266a5f0fb15SPaul Saab * Repeat previous search, 1267a5f0fb15SPaul Saab * multiple files in reverse direction. 1268a5f0fb15SPaul Saab */ 1269a5f0fb15SPaul Saab save_search_type = search_type; 1270a5f0fb15SPaul Saab search_type = SRCH_REVERSE(search_type); 1271a5f0fb15SPaul Saab search_type |= SRCH_PAST_EOF; 1272a5f0fb15SPaul Saab DO_SEARCH(); 1273a5f0fb15SPaul Saab search_type = save_search_type; 1274a5f0fb15SPaul Saab break; 1275a5f0fb15SPaul Saab 1276a5f0fb15SPaul Saab case A_UNDO_SEARCH: 1277a5f0fb15SPaul Saab undo_search(); 1278a5f0fb15SPaul Saab break; 1279a5f0fb15SPaul Saab 1280a5f0fb15SPaul Saab case A_HELP: 1281a5f0fb15SPaul Saab /* 1282a5f0fb15SPaul Saab * Help. 1283a5f0fb15SPaul Saab */ 1284a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1285a5f0fb15SPaul Saab break; 1286a5f0fb15SPaul Saab cmd_exec(); 1287a5f0fb15SPaul Saab (void) edit(FAKE_HELPFILE); 1288a5f0fb15SPaul Saab break; 1289a5f0fb15SPaul Saab 1290a5f0fb15SPaul Saab case A_EXAMINE: 1291a5f0fb15SPaul Saab #if EXAMINE 1292a5f0fb15SPaul Saab /* 1293a5f0fb15SPaul Saab * Edit a new file. Get the filename. 1294a5f0fb15SPaul Saab */ 1295a5f0fb15SPaul Saab if (secure) 1296a5f0fb15SPaul Saab { 1297a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1298a5f0fb15SPaul Saab break; 1299a5f0fb15SPaul Saab } 1300a5f0fb15SPaul Saab start_mca(A_EXAMINE, "Examine: ", ml_examine, 0); 1301a5f0fb15SPaul Saab c = getcc(); 1302a5f0fb15SPaul Saab goto again; 1303a5f0fb15SPaul Saab #else 1304a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1305a5f0fb15SPaul Saab break; 1306a5f0fb15SPaul Saab #endif 1307a5f0fb15SPaul Saab 1308a5f0fb15SPaul Saab case A_VISUAL: 1309a5f0fb15SPaul Saab /* 1310a5f0fb15SPaul Saab * Invoke an editor on the input file. 1311a5f0fb15SPaul Saab */ 1312a5f0fb15SPaul Saab #if EDITOR 1313a5f0fb15SPaul Saab if (secure) 1314a5f0fb15SPaul Saab { 1315a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1316a5f0fb15SPaul Saab break; 1317a5f0fb15SPaul Saab } 1318a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1319a5f0fb15SPaul Saab break; 1320a5f0fb15SPaul Saab if (strcmp(get_filename(curr_ifile), "-") == 0) 1321a5f0fb15SPaul Saab { 1322a5f0fb15SPaul Saab error("Cannot edit standard input", NULL_PARG); 1323a5f0fb15SPaul Saab break; 1324a5f0fb15SPaul Saab } 1325a5f0fb15SPaul Saab if (curr_altfilename != NULL) 1326a5f0fb15SPaul Saab { 1327a5f0fb15SPaul Saab error("Cannot edit file processed with LESSOPEN", 1328a5f0fb15SPaul Saab NULL_PARG); 1329a5f0fb15SPaul Saab break; 1330a5f0fb15SPaul Saab } 1331a5f0fb15SPaul Saab start_mca(A_SHELL, "!", ml_shell, 0); 1332a5f0fb15SPaul Saab /* 1333a5f0fb15SPaul Saab * Expand the editor prototype string 1334a5f0fb15SPaul Saab * and pass it to the system to execute. 1335a5f0fb15SPaul Saab * (Make sure the screen is displayed so the 1336a5f0fb15SPaul Saab * expansion of "+%lm" works.) 1337a5f0fb15SPaul Saab */ 1338a5f0fb15SPaul Saab make_display(); 1339a5f0fb15SPaul Saab cmd_exec(); 1340a5f0fb15SPaul Saab lsystem(pr_expand(editproto, 0), (char*)NULL); 1341a5f0fb15SPaul Saab break; 1342a5f0fb15SPaul Saab #else 1343a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1344a5f0fb15SPaul Saab break; 1345a5f0fb15SPaul Saab #endif 1346a5f0fb15SPaul Saab 1347a5f0fb15SPaul Saab case A_NEXT_FILE: 1348a5f0fb15SPaul Saab /* 1349a5f0fb15SPaul Saab * Examine next file. 1350a5f0fb15SPaul Saab */ 1351a5f0fb15SPaul Saab if (number <= 0) 1352a5f0fb15SPaul Saab number = 1; 1353a5f0fb15SPaul Saab if (edit_next(number)) 1354a5f0fb15SPaul Saab { 1355a5f0fb15SPaul Saab if (quit_at_eof && hit_eof && 1356a5f0fb15SPaul Saab !(ch_getflags() & CH_HELPFILE)) 1357a5f0fb15SPaul Saab quit(QUIT_OK); 1358a5f0fb15SPaul Saab parg.p_string = (number > 1) ? "(N-th) " : ""; 1359a5f0fb15SPaul Saab error("No %snext file", &parg); 1360a5f0fb15SPaul Saab } 1361a5f0fb15SPaul Saab break; 1362a5f0fb15SPaul Saab 1363a5f0fb15SPaul Saab case A_PREV_FILE: 1364a5f0fb15SPaul Saab /* 1365a5f0fb15SPaul Saab * Examine previous file. 1366a5f0fb15SPaul Saab */ 1367a5f0fb15SPaul Saab if (number <= 0) 1368a5f0fb15SPaul Saab number = 1; 1369a5f0fb15SPaul Saab if (edit_prev(number)) 1370a5f0fb15SPaul Saab { 1371a5f0fb15SPaul Saab parg.p_string = (number > 1) ? "(N-th) " : ""; 1372a5f0fb15SPaul Saab error("No %sprevious file", &parg); 1373a5f0fb15SPaul Saab } 1374a5f0fb15SPaul Saab break; 1375a5f0fb15SPaul Saab 1376a5f0fb15SPaul Saab case A_INDEX_FILE: 1377a5f0fb15SPaul Saab /* 1378a5f0fb15SPaul Saab * Examine a particular file. 1379a5f0fb15SPaul Saab */ 1380a5f0fb15SPaul Saab if (number <= 0) 1381a5f0fb15SPaul Saab number = 1; 1382a5f0fb15SPaul Saab if (edit_index(number)) 1383a5f0fb15SPaul Saab error("No such file", NULL_PARG); 1384a5f0fb15SPaul Saab break; 1385a5f0fb15SPaul Saab 1386a5f0fb15SPaul Saab case A_REMOVE_FILE: 1387a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1388a5f0fb15SPaul Saab break; 1389a5f0fb15SPaul Saab old_ifile = curr_ifile; 1390a5f0fb15SPaul Saab new_ifile = getoff_ifile(curr_ifile); 1391a5f0fb15SPaul Saab if (new_ifile == NULL_IFILE) 1392a5f0fb15SPaul Saab { 1393a5f0fb15SPaul Saab bell(); 1394a5f0fb15SPaul Saab break; 1395a5f0fb15SPaul Saab } 1396a5f0fb15SPaul Saab if (edit_ifile(new_ifile) != 0) 1397a5f0fb15SPaul Saab { 1398a5f0fb15SPaul Saab reedit_ifile(old_ifile); 1399a5f0fb15SPaul Saab break; 1400a5f0fb15SPaul Saab } 1401a5f0fb15SPaul Saab del_ifile(old_ifile); 1402a5f0fb15SPaul Saab break; 1403a5f0fb15SPaul Saab 1404a5f0fb15SPaul Saab case A_OPT_TOGGLE: 1405a5f0fb15SPaul Saab optflag = OPT_TOGGLE; 1406a5f0fb15SPaul Saab optgetname = FALSE; 1407a5f0fb15SPaul Saab mca_opt_toggle(); 1408a5f0fb15SPaul Saab c = getcc(); 1409a5f0fb15SPaul Saab goto again; 1410a5f0fb15SPaul Saab 1411a5f0fb15SPaul Saab case A_DISP_OPTION: 1412a5f0fb15SPaul Saab /* 1413a5f0fb15SPaul Saab * Report a flag setting. 1414a5f0fb15SPaul Saab */ 1415a5f0fb15SPaul Saab optflag = OPT_NO_TOGGLE; 1416a5f0fb15SPaul Saab optgetname = FALSE; 1417a5f0fb15SPaul Saab mca_opt_toggle(); 1418a5f0fb15SPaul Saab c = getcc(); 1419a5f0fb15SPaul Saab goto again; 1420a5f0fb15SPaul Saab 1421a5f0fb15SPaul Saab case A_FIRSTCMD: 1422a5f0fb15SPaul Saab /* 1423a5f0fb15SPaul Saab * Set an initial command for new files. 1424a5f0fb15SPaul Saab */ 1425a5f0fb15SPaul Saab start_mca(A_FIRSTCMD, "+", (void*)NULL, 0); 1426a5f0fb15SPaul Saab c = getcc(); 1427a5f0fb15SPaul Saab goto again; 1428a5f0fb15SPaul Saab 1429a5f0fb15SPaul Saab case A_SHELL: 1430a5f0fb15SPaul Saab /* 1431a5f0fb15SPaul Saab * Shell escape. 1432a5f0fb15SPaul Saab */ 1433a5f0fb15SPaul Saab #if SHELL_ESCAPE 1434a5f0fb15SPaul Saab if (secure) 1435a5f0fb15SPaul Saab { 1436a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1437a5f0fb15SPaul Saab break; 1438a5f0fb15SPaul Saab } 1439a5f0fb15SPaul Saab start_mca(A_SHELL, "!", ml_shell, 0); 1440a5f0fb15SPaul Saab c = getcc(); 1441a5f0fb15SPaul Saab goto again; 1442a5f0fb15SPaul Saab #else 1443a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1444a5f0fb15SPaul Saab break; 1445a5f0fb15SPaul Saab #endif 1446a5f0fb15SPaul Saab 1447a5f0fb15SPaul Saab case A_SETMARK: 1448a5f0fb15SPaul Saab /* 1449a5f0fb15SPaul Saab * Set a mark. 1450a5f0fb15SPaul Saab */ 1451a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1452a5f0fb15SPaul Saab break; 1453a5f0fb15SPaul Saab start_mca(A_SETMARK, "mark: ", (void*)NULL, 0); 1454a5f0fb15SPaul Saab c = getcc(); 1455a5f0fb15SPaul Saab if (c == erase_char || c == kill_char || 1456a5f0fb15SPaul Saab c == '\n' || c == '\r') 1457a5f0fb15SPaul Saab break; 1458a5f0fb15SPaul Saab setmark(c); 1459a5f0fb15SPaul Saab break; 1460a5f0fb15SPaul Saab 1461a5f0fb15SPaul Saab case A_GOMARK: 1462a5f0fb15SPaul Saab /* 1463a5f0fb15SPaul Saab * Go to a mark. 1464a5f0fb15SPaul Saab */ 1465a5f0fb15SPaul Saab start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0); 1466a5f0fb15SPaul Saab c = getcc(); 1467a5f0fb15SPaul Saab if (c == erase_char || c == kill_char || 1468a5f0fb15SPaul Saab c == '\n' || c == '\r') 1469a5f0fb15SPaul Saab break; 1470a5f0fb15SPaul Saab gomark(c); 1471a5f0fb15SPaul Saab break; 1472a5f0fb15SPaul Saab 1473a5f0fb15SPaul Saab case A_PIPE: 1474a5f0fb15SPaul Saab #if PIPEC 1475a5f0fb15SPaul Saab if (secure) 1476a5f0fb15SPaul Saab { 1477a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1478a5f0fb15SPaul Saab break; 1479a5f0fb15SPaul Saab } 1480a5f0fb15SPaul Saab start_mca(A_PIPE, "|mark: ", (void*)NULL, 0); 1481a5f0fb15SPaul Saab c = getcc(); 1482a5f0fb15SPaul Saab if (c == erase_char || c == kill_char) 1483a5f0fb15SPaul Saab break; 1484a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 1485a5f0fb15SPaul Saab c = '.'; 1486a5f0fb15SPaul Saab if (badmark(c)) 1487a5f0fb15SPaul Saab break; 1488a5f0fb15SPaul Saab pipec = c; 1489a5f0fb15SPaul Saab start_mca(A_PIPE, "!", ml_shell, 0); 1490a5f0fb15SPaul Saab c = getcc(); 1491a5f0fb15SPaul Saab goto again; 1492a5f0fb15SPaul Saab #else 1493a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1494a5f0fb15SPaul Saab break; 1495a5f0fb15SPaul Saab #endif 1496a5f0fb15SPaul Saab 1497a5f0fb15SPaul Saab case A_B_BRACKET: 1498a5f0fb15SPaul Saab case A_F_BRACKET: 1499a5f0fb15SPaul Saab start_mca(action, "Brackets: ", (void*)NULL, 0); 1500a5f0fb15SPaul Saab c = getcc(); 1501a5f0fb15SPaul Saab goto again; 1502a5f0fb15SPaul Saab 1503a5f0fb15SPaul Saab case A_LSHIFT: 1504a5f0fb15SPaul Saab if (number <= 0) 1505a5f0fb15SPaul Saab number = 8; 1506a5f0fb15SPaul Saab if (number > hshift) 1507a5f0fb15SPaul Saab number = hshift; 1508a5f0fb15SPaul Saab hshift -= number; 1509a5f0fb15SPaul Saab screen_trashed = 1; 1510a5f0fb15SPaul Saab break; 1511a5f0fb15SPaul Saab 1512a5f0fb15SPaul Saab case A_RSHIFT: 1513a5f0fb15SPaul Saab if (number <= 0) 1514a5f0fb15SPaul Saab number = 8; 1515a5f0fb15SPaul Saab hshift += number; 1516a5f0fb15SPaul Saab screen_trashed = 1; 1517a5f0fb15SPaul Saab break; 1518a5f0fb15SPaul Saab 1519a5f0fb15SPaul Saab case A_PREFIX: 1520a5f0fb15SPaul Saab /* 1521a5f0fb15SPaul Saab * The command is incomplete (more chars are needed). 1522a5f0fb15SPaul Saab * Display the current char, so the user knows 1523a5f0fb15SPaul Saab * what's going on, and get another character. 1524a5f0fb15SPaul Saab */ 1525a5f0fb15SPaul Saab if (mca != A_PREFIX) 1526a5f0fb15SPaul Saab { 1527a5f0fb15SPaul Saab cmd_reset(); 1528a5f0fb15SPaul Saab start_mca(A_PREFIX, " ", (void*)NULL, 1529a5f0fb15SPaul Saab CF_QUIT_ON_ERASE); 1530a5f0fb15SPaul Saab (void) cmd_char(c); 1531a5f0fb15SPaul Saab } 1532a5f0fb15SPaul Saab c = getcc(); 1533a5f0fb15SPaul Saab goto again; 1534a5f0fb15SPaul Saab 1535a5f0fb15SPaul Saab case A_NOACTION: 1536a5f0fb15SPaul Saab break; 1537a5f0fb15SPaul Saab 1538a5f0fb15SPaul Saab default: 1539a5f0fb15SPaul Saab bell(); 1540a5f0fb15SPaul Saab break; 1541a5f0fb15SPaul Saab } 1542a5f0fb15SPaul Saab } 1543a5f0fb15SPaul Saab } 1544