1a8f92a7cSPaul Saab /* $FreeBSD$ */ 2a5f0fb15SPaul Saab /* 3*f6b74a7dSXin LI * Copyright (C) 1984-2017 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 * 896e55cc7SXin LI * For more information, 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" 178fd4165cSPaul Saab #if MSDOS_COMPILER==WIN32C 188fd4165cSPaul Saab #include <windows.h> 198fd4165cSPaul Saab #endif 20a5f0fb15SPaul Saab #include "position.h" 21a5f0fb15SPaul Saab #include "option.h" 22a5f0fb15SPaul Saab #include "cmd.h" 23a5f0fb15SPaul Saab 2489dd99dcSXin LI extern int erase_char, erase2_char, kill_char; 25a5f0fb15SPaul Saab extern int sigs; 26a5f0fb15SPaul Saab extern int quit_if_one_screen; 27a5f0fb15SPaul Saab extern int squished; 28a5f0fb15SPaul Saab extern int sc_width; 29a5f0fb15SPaul Saab extern int sc_height; 30a5f0fb15SPaul Saab extern int swindow; 31a5f0fb15SPaul Saab extern int jump_sline; 32a5f0fb15SPaul Saab extern int quitting; 33a5f0fb15SPaul Saab extern int wscroll; 34a5f0fb15SPaul Saab extern int top_scroll; 35a5f0fb15SPaul Saab extern int ignore_eoi; 36a5f0fb15SPaul Saab extern int secure; 37a5f0fb15SPaul Saab extern int hshift; 38a15691bfSXin LI extern int bs_mode; 39a5f0fb15SPaul Saab extern int show_attn; 40720c436cSXin LI extern int less_is_more; 4196e55cc7SXin LI extern POSITION highest_hilite; 42a5f0fb15SPaul Saab extern char *every_first_cmd; 43a5f0fb15SPaul Saab extern char *curr_altfilename; 44a5f0fb15SPaul Saab extern char version[]; 45a5f0fb15SPaul Saab extern struct scrpos initial_scrpos; 46a5f0fb15SPaul Saab extern IFILE curr_ifile; 47*f6b74a7dSXin LI extern void *ml_search; 48*f6b74a7dSXin LI extern void *ml_examine; 49a5f0fb15SPaul Saab #if SHELL_ESCAPE || PIPEC 50*f6b74a7dSXin LI extern void *ml_shell; 51a5f0fb15SPaul Saab #endif 52a5f0fb15SPaul Saab #if EDITOR 53a5f0fb15SPaul Saab extern char *editor; 54a5f0fb15SPaul Saab extern char *editproto; 55a5f0fb15SPaul Saab #endif 56a5f0fb15SPaul Saab extern int screen_trashed; /* The screen has been overwritten */ 5715596da4SPaul Saab extern int shift_count; 58720c436cSXin LI extern int oldbot; 59720c436cSXin LI extern int forw_prompt; 60a15691bfSXin LI extern int same_pos_bell; 61a5f0fb15SPaul Saab 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 */ 6933096f16SXin LI static struct loption *curropt; 7033096f16SXin LI static int opt_lower; 71a5f0fb15SPaul Saab static int optflag; 72a5f0fb15SPaul Saab static int optgetname; 73a5f0fb15SPaul Saab static POSITION bottompos; 7489dd99dcSXin LI static int save_hshift; 75a15691bfSXin LI static int save_bs_mode; 76a5f0fb15SPaul Saab #if PIPEC 77a5f0fb15SPaul Saab static char pipec; 78a5f0fb15SPaul Saab #endif 79a5f0fb15SPaul Saab 8033096f16SXin LI struct ungot { 8133096f16SXin LI struct ungot *ug_next; 8233096f16SXin LI char ug_char; 83a15691bfSXin LI char ug_end_command; 8433096f16SXin LI }; 8533096f16SXin LI static struct ungot* ungot = NULL; 8633096f16SXin LI 87*f6b74a7dSXin LI static void multi_search(); 88a5f0fb15SPaul Saab 89a5f0fb15SPaul Saab /* 90720c436cSXin LI * Move the cursor to start of prompt line before executing a command. 91a5f0fb15SPaul Saab * This looks nicer if the command takes a long time before 92a5f0fb15SPaul Saab * updating the screen. 93a5f0fb15SPaul Saab */ 94a5f0fb15SPaul Saab static void 95*f6b74a7dSXin LI cmd_exec() 96a5f0fb15SPaul Saab { 977374caaaSXin LI #if HILITE_SEARCH 98a5f0fb15SPaul Saab clear_attn(); 997374caaaSXin LI #endif 100aa22b8b6SXin LI clear_bot(); 101a5f0fb15SPaul Saab flush(); 102a5f0fb15SPaul Saab } 103a5f0fb15SPaul Saab 104a5f0fb15SPaul Saab /* 105a5f0fb15SPaul Saab * Set up the display to start a new multi-character command. 106a5f0fb15SPaul Saab */ 107a5f0fb15SPaul Saab static void 108*f6b74a7dSXin LI start_mca(action, prompt, mlist, cmdflags) 109*f6b74a7dSXin LI int action; 110*f6b74a7dSXin LI constant char *prompt; 111*f6b74a7dSXin LI void *mlist; 112*f6b74a7dSXin LI int cmdflags; 113a5f0fb15SPaul Saab { 114a5f0fb15SPaul Saab mca = action; 115720c436cSXin LI clear_bot(); 116a5f0fb15SPaul Saab clear_cmd(); 117a5f0fb15SPaul Saab cmd_putstr(prompt); 118a5f0fb15SPaul Saab set_mlist(mlist, cmdflags); 119a5f0fb15SPaul Saab } 120a5f0fb15SPaul Saab 121a5f0fb15SPaul Saab public int 122*f6b74a7dSXin LI in_mca() 123a5f0fb15SPaul Saab { 124a5f0fb15SPaul Saab return (mca != 0 && mca != A_PREFIX); 125a5f0fb15SPaul Saab } 126a5f0fb15SPaul Saab 127a5f0fb15SPaul Saab /* 128a5f0fb15SPaul Saab * Set up the display to start a new search command. 129a5f0fb15SPaul Saab */ 130a5f0fb15SPaul Saab static void 131*f6b74a7dSXin LI mca_search() 132a5f0fb15SPaul Saab { 1337374caaaSXin LI #if HILITE_SEARCH 1347374caaaSXin LI if (search_type & SRCH_FILTER) 1357374caaaSXin LI mca = A_FILTER; 1367374caaaSXin LI else 1377374caaaSXin LI #endif 138a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 139a5f0fb15SPaul Saab mca = A_F_SEARCH; 140a5f0fb15SPaul Saab else 141a5f0fb15SPaul Saab mca = A_B_SEARCH; 142a5f0fb15SPaul Saab 143720c436cSXin LI clear_bot(); 144a5f0fb15SPaul Saab clear_cmd(); 145a5f0fb15SPaul Saab 146a5f0fb15SPaul Saab if (search_type & SRCH_NO_MATCH) 147a5f0fb15SPaul Saab cmd_putstr("Non-match "); 148a5f0fb15SPaul Saab if (search_type & SRCH_FIRST_FILE) 149a5f0fb15SPaul Saab cmd_putstr("First-file "); 150a5f0fb15SPaul Saab if (search_type & SRCH_PAST_EOF) 151a5f0fb15SPaul Saab cmd_putstr("EOF-ignore "); 152a5f0fb15SPaul Saab if (search_type & SRCH_NO_MOVE) 153a5f0fb15SPaul Saab cmd_putstr("Keep-pos "); 154a5f0fb15SPaul Saab if (search_type & SRCH_NO_REGEX) 155a5f0fb15SPaul Saab cmd_putstr("Regex-off "); 156a5f0fb15SPaul Saab 1577374caaaSXin LI #if HILITE_SEARCH 1587374caaaSXin LI if (search_type & SRCH_FILTER) 1597374caaaSXin LI cmd_putstr("&/"); 1607374caaaSXin LI else 1617374caaaSXin LI #endif 162a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 163a5f0fb15SPaul Saab cmd_putstr("/"); 164a5f0fb15SPaul Saab else 165a5f0fb15SPaul Saab cmd_putstr("?"); 166a15691bfSXin LI forw_prompt = 0; 167a5f0fb15SPaul Saab set_mlist(ml_search, 0); 168a5f0fb15SPaul Saab } 169a5f0fb15SPaul Saab 170a5f0fb15SPaul Saab /* 171a5f0fb15SPaul Saab * Set up the display to start a new toggle-option command. 172a5f0fb15SPaul Saab */ 173a5f0fb15SPaul Saab static void 174*f6b74a7dSXin LI mca_opt_toggle() 175a5f0fb15SPaul Saab { 176a5f0fb15SPaul Saab int no_prompt; 177a5f0fb15SPaul Saab int flag; 178a5f0fb15SPaul Saab char *dash; 179a5f0fb15SPaul Saab 180a5f0fb15SPaul Saab no_prompt = (optflag & OPT_NO_PROMPT); 181a5f0fb15SPaul Saab flag = (optflag & ~OPT_NO_PROMPT); 182a5f0fb15SPaul Saab dash = (flag == OPT_NO_TOGGLE) ? "_" : "-"; 183a5f0fb15SPaul Saab 184a5f0fb15SPaul Saab mca = A_OPT_TOGGLE; 185720c436cSXin LI clear_bot(); 186a5f0fb15SPaul Saab clear_cmd(); 187a5f0fb15SPaul Saab cmd_putstr(dash); 188a5f0fb15SPaul Saab if (optgetname) 189a5f0fb15SPaul Saab cmd_putstr(dash); 190a5f0fb15SPaul Saab if (no_prompt) 191a5f0fb15SPaul Saab cmd_putstr("(P)"); 192a5f0fb15SPaul Saab switch (flag) 193a5f0fb15SPaul Saab { 194a5f0fb15SPaul Saab case OPT_UNSET: 195a5f0fb15SPaul Saab cmd_putstr("+"); 196a5f0fb15SPaul Saab break; 197a5f0fb15SPaul Saab case OPT_SET: 198a5f0fb15SPaul Saab cmd_putstr("!"); 199a5f0fb15SPaul Saab break; 200a5f0fb15SPaul Saab } 201a15691bfSXin LI forw_prompt = 0; 202a5f0fb15SPaul Saab set_mlist(NULL, 0); 203a5f0fb15SPaul Saab } 204a5f0fb15SPaul Saab 205a5f0fb15SPaul Saab /* 206a5f0fb15SPaul Saab * Execute a multicharacter command. 207a5f0fb15SPaul Saab */ 208a5f0fb15SPaul Saab static void 209*f6b74a7dSXin LI exec_mca() 210a5f0fb15SPaul Saab { 2111ea31627SRobert Watson char *cbuf; 212a5f0fb15SPaul Saab 213a5f0fb15SPaul Saab cmd_exec(); 214a5f0fb15SPaul Saab cbuf = get_cmdbuf(); 215a5f0fb15SPaul Saab 216a5f0fb15SPaul Saab switch (mca) 217a5f0fb15SPaul Saab { 218a5f0fb15SPaul Saab case A_F_SEARCH: 219a5f0fb15SPaul Saab case A_B_SEARCH: 220a15691bfSXin LI multi_search(cbuf, (int) number, 0); 221a5f0fb15SPaul Saab break; 2227374caaaSXin LI #if HILITE_SEARCH 2237374caaaSXin LI case A_FILTER: 2247374caaaSXin LI search_type ^= SRCH_NO_MATCH; 2257374caaaSXin LI set_filter_pattern(cbuf, search_type); 2267374caaaSXin LI break; 2277374caaaSXin LI #endif 228a5f0fb15SPaul Saab case A_FIRSTCMD: 229a5f0fb15SPaul Saab /* 230a5f0fb15SPaul Saab * Skip leading spaces or + signs in the string. 231a5f0fb15SPaul Saab */ 232a5f0fb15SPaul Saab while (*cbuf == '+' || *cbuf == ' ') 233a5f0fb15SPaul Saab cbuf++; 234a5f0fb15SPaul Saab if (every_first_cmd != NULL) 235a5f0fb15SPaul Saab free(every_first_cmd); 236a5f0fb15SPaul Saab if (*cbuf == '\0') 237a5f0fb15SPaul Saab every_first_cmd = NULL; 238a5f0fb15SPaul Saab else 239a5f0fb15SPaul Saab every_first_cmd = save(cbuf); 240a5f0fb15SPaul Saab break; 241a5f0fb15SPaul Saab case A_OPT_TOGGLE: 24233096f16SXin LI toggle_option(curropt, opt_lower, cbuf, optflag); 24333096f16SXin LI curropt = NULL; 244a5f0fb15SPaul Saab break; 245a5f0fb15SPaul Saab case A_F_BRACKET: 2461ede1615STim J. Robbins match_brac(cbuf[0], cbuf[1], 1, (int) number); 247a5f0fb15SPaul Saab break; 248a5f0fb15SPaul Saab case A_B_BRACKET: 2491ede1615STim J. Robbins match_brac(cbuf[1], cbuf[0], 0, (int) number); 250a5f0fb15SPaul Saab break; 251a5f0fb15SPaul Saab #if EXAMINE 252a5f0fb15SPaul Saab case A_EXAMINE: 253a5f0fb15SPaul Saab if (secure) 254a5f0fb15SPaul Saab break; 255a5f0fb15SPaul Saab edit_list(cbuf); 2561ede1615STim J. Robbins #if TAGS 2578fd4165cSPaul Saab /* If tag structure is loaded then clean it up. */ 2588fd4165cSPaul Saab cleantags(); 2591ede1615STim J. Robbins #endif 260a5f0fb15SPaul Saab break; 261a5f0fb15SPaul Saab #endif 262a5f0fb15SPaul Saab #if SHELL_ESCAPE 263a5f0fb15SPaul Saab case A_SHELL: 264a5f0fb15SPaul Saab /* 265a5f0fb15SPaul Saab * !! just uses whatever is in shellcmd. 266a5f0fb15SPaul Saab * Otherwise, copy cmdbuf to shellcmd, 267a5f0fb15SPaul Saab * expanding any special characters ("%" or "#"). 268a5f0fb15SPaul Saab */ 269a5f0fb15SPaul Saab if (*cbuf != '!') 270a5f0fb15SPaul Saab { 271a5f0fb15SPaul Saab if (shellcmd != NULL) 272a5f0fb15SPaul Saab free(shellcmd); 273a5f0fb15SPaul Saab shellcmd = fexpand(cbuf); 274a5f0fb15SPaul Saab } 275a5f0fb15SPaul Saab 276a5f0fb15SPaul Saab if (secure) 277a5f0fb15SPaul Saab break; 278a5f0fb15SPaul Saab if (shellcmd == NULL) 279a5f0fb15SPaul Saab lsystem("", "!done"); 280a5f0fb15SPaul Saab else 281a5f0fb15SPaul Saab lsystem(shellcmd, "!done"); 282a5f0fb15SPaul Saab break; 283a5f0fb15SPaul Saab #endif 284a5f0fb15SPaul Saab #if PIPEC 285a5f0fb15SPaul Saab case A_PIPE: 286a5f0fb15SPaul Saab if (secure) 287a5f0fb15SPaul Saab break; 288a5f0fb15SPaul Saab (void) pipe_mark(pipec, cbuf); 289a5f0fb15SPaul Saab error("|done", NULL_PARG); 290a5f0fb15SPaul Saab break; 291a5f0fb15SPaul Saab #endif 292a5f0fb15SPaul Saab } 293a5f0fb15SPaul Saab } 294a5f0fb15SPaul Saab 295a5f0fb15SPaul Saab /* 29633096f16SXin LI * Is a character an erase or kill char? 297a5f0fb15SPaul Saab */ 298a5f0fb15SPaul Saab static int 299*f6b74a7dSXin LI is_erase_char(c) 300*f6b74a7dSXin LI int c; 301a5f0fb15SPaul Saab { 30233096f16SXin LI return (c == erase_char || c == erase2_char || c == kill_char); 303a5f0fb15SPaul Saab } 304a5f0fb15SPaul Saab 305a5f0fb15SPaul Saab /* 30633096f16SXin LI * Handle the first char of an option (after the initial dash). 307a5f0fb15SPaul Saab */ 30833096f16SXin LI static int 309*f6b74a7dSXin LI mca_opt_first_char(c) 310*f6b74a7dSXin LI int c; 311a5f0fb15SPaul Saab { 31233096f16SXin LI int flag = (optflag & ~OPT_NO_PROMPT); 313a5f0fb15SPaul Saab if (flag == OPT_NO_TOGGLE) 314a5f0fb15SPaul Saab { 315a5f0fb15SPaul Saab switch (c) 316a5f0fb15SPaul Saab { 317a5f0fb15SPaul Saab case '_': 318a5f0fb15SPaul Saab /* "__" = long option name. */ 319a5f0fb15SPaul Saab optgetname = TRUE; 320a5f0fb15SPaul Saab mca_opt_toggle(); 321a5f0fb15SPaul Saab return (MCA_MORE); 322a5f0fb15SPaul Saab } 323a5f0fb15SPaul Saab } else 324a5f0fb15SPaul Saab { 325a5f0fb15SPaul Saab switch (c) 326a5f0fb15SPaul Saab { 327a5f0fb15SPaul Saab case '+': 328a5f0fb15SPaul Saab /* "-+" = UNSET. */ 329a5f0fb15SPaul Saab optflag = (flag == OPT_UNSET) ? 330a5f0fb15SPaul Saab OPT_TOGGLE : OPT_UNSET; 331a5f0fb15SPaul Saab mca_opt_toggle(); 332a5f0fb15SPaul Saab return (MCA_MORE); 333a5f0fb15SPaul Saab case '!': 334a5f0fb15SPaul Saab /* "-!" = SET */ 335a5f0fb15SPaul Saab optflag = (flag == OPT_SET) ? 336a5f0fb15SPaul Saab OPT_TOGGLE : OPT_SET; 337a5f0fb15SPaul Saab mca_opt_toggle(); 338a5f0fb15SPaul Saab return (MCA_MORE); 339a5f0fb15SPaul Saab case CONTROL('P'): 340a5f0fb15SPaul Saab optflag ^= OPT_NO_PROMPT; 341a5f0fb15SPaul Saab mca_opt_toggle(); 342a5f0fb15SPaul Saab return (MCA_MORE); 343a5f0fb15SPaul Saab case '-': 344a5f0fb15SPaul Saab /* "--" = long option name. */ 345a5f0fb15SPaul Saab optgetname = TRUE; 346a5f0fb15SPaul Saab mca_opt_toggle(); 347a5f0fb15SPaul Saab return (MCA_MORE); 348a5f0fb15SPaul Saab } 349a5f0fb15SPaul Saab } 35033096f16SXin LI /* Char was not handled here. */ 35133096f16SXin LI return (NO_MCA); 352a5f0fb15SPaul Saab } 35333096f16SXin LI 354a5f0fb15SPaul Saab /* 35533096f16SXin LI * Add a char to a long option name. 35633096f16SXin LI * See if we've got a match for an option name yet. 357a5f0fb15SPaul Saab * If so, display the complete name and stop 358a5f0fb15SPaul Saab * accepting chars until user hits RETURN. 359a5f0fb15SPaul Saab */ 36033096f16SXin LI static int 361*f6b74a7dSXin LI mca_opt_nonfirst_char(c) 362*f6b74a7dSXin LI int c; 36333096f16SXin LI { 36433096f16SXin LI char *p; 365a5f0fb15SPaul Saab char *oname; 366a5f0fb15SPaul Saab 36733096f16SXin LI if (curropt != NULL) 368a5f0fb15SPaul Saab { 369a5f0fb15SPaul Saab /* 370a5f0fb15SPaul Saab * Already have a match for the name. 371a5f0fb15SPaul Saab * Don't accept anything but erase/kill. 372a5f0fb15SPaul Saab */ 37333096f16SXin LI if (is_erase_char(c)) 374a5f0fb15SPaul Saab return (MCA_DONE); 375a5f0fb15SPaul Saab return (MCA_MORE); 376a5f0fb15SPaul Saab } 377a5f0fb15SPaul Saab /* 378a5f0fb15SPaul Saab * Add char to cmd buffer and try to match 379a5f0fb15SPaul Saab * the option name. 380a5f0fb15SPaul Saab */ 381a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT) 382a5f0fb15SPaul Saab return (MCA_DONE); 383a5f0fb15SPaul Saab p = get_cmdbuf(); 38433096f16SXin LI opt_lower = ASCII_IS_LOWER(p[0]); 38533096f16SXin LI curropt = findopt_name(&p, &oname, NULL); 38633096f16SXin LI if (curropt != NULL) 387a5f0fb15SPaul Saab { 388a5f0fb15SPaul Saab /* 389a5f0fb15SPaul Saab * Got a match. 39033096f16SXin LI * Remember the option and 391a5f0fb15SPaul Saab * display the full option name. 392a5f0fb15SPaul Saab */ 393a5f0fb15SPaul Saab cmd_reset(); 394a5f0fb15SPaul Saab mca_opt_toggle(); 395a5f0fb15SPaul Saab for (p = oname; *p != '\0'; p++) 396a5f0fb15SPaul Saab { 397a5f0fb15SPaul Saab c = *p; 39833096f16SXin LI if (!opt_lower && ASCII_IS_LOWER(c)) 39989dd99dcSXin LI c = ASCII_TO_UPPER(c); 400a5f0fb15SPaul Saab if (cmd_char(c) != CC_OK) 401a5f0fb15SPaul Saab return (MCA_DONE); 402a5f0fb15SPaul Saab } 403a5f0fb15SPaul Saab } 404a5f0fb15SPaul Saab return (MCA_MORE); 405a5f0fb15SPaul Saab } 40633096f16SXin LI 40733096f16SXin LI /* 40833096f16SXin LI * Handle a char of an option toggle command. 40933096f16SXin LI */ 41033096f16SXin LI static int 411*f6b74a7dSXin LI mca_opt_char(c) 412*f6b74a7dSXin LI int c; 41333096f16SXin LI { 41433096f16SXin LI PARG parg; 41533096f16SXin LI 41633096f16SXin LI /* 41733096f16SXin LI * This may be a short option (single char), 41833096f16SXin LI * or one char of a long option name, 41933096f16SXin LI * or one char of the option parameter. 42033096f16SXin LI */ 42133096f16SXin LI if (curropt == NULL && len_cmdbuf() == 0) 42233096f16SXin LI { 42333096f16SXin LI int ret = mca_opt_first_char(c); 42433096f16SXin LI if (ret != NO_MCA) 42533096f16SXin LI return (ret); 42633096f16SXin LI } 42733096f16SXin LI if (optgetname) 42833096f16SXin LI { 42933096f16SXin LI /* We're getting a long option name. */ 43033096f16SXin LI if (c != '\n' && c != '\r') 43133096f16SXin LI return (mca_opt_nonfirst_char(c)); 43233096f16SXin LI if (curropt == NULL) 43333096f16SXin LI { 43433096f16SXin LI parg.p_string = get_cmdbuf(); 43533096f16SXin LI error("There is no --%s option", &parg); 43633096f16SXin LI return (MCA_DONE); 43733096f16SXin LI } 43833096f16SXin LI optgetname = FALSE; 43933096f16SXin LI cmd_reset(); 440a5f0fb15SPaul Saab } else 441a5f0fb15SPaul Saab { 44233096f16SXin LI if (is_erase_char(c)) 44333096f16SXin LI return (NO_MCA); 44433096f16SXin LI if (curropt != NULL) 44533096f16SXin LI /* We're getting the option parameter. */ 44633096f16SXin LI return (NO_MCA); 44733096f16SXin LI curropt = findopt(c); 44833096f16SXin LI if (curropt == NULL) 449a5f0fb15SPaul Saab { 45033096f16SXin LI parg.p_string = propt(c); 45133096f16SXin LI error("There is no %s option", &parg); 45233096f16SXin LI return (MCA_DONE); 45333096f16SXin LI } 45433096f16SXin LI } 45533096f16SXin LI /* 45633096f16SXin LI * If the option which was entered does not take a 45733096f16SXin LI * parameter, toggle the option immediately, 45833096f16SXin LI * so user doesn't have to hit RETURN. 45933096f16SXin LI */ 46033096f16SXin LI if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE || 46133096f16SXin LI !opt_has_param(curropt)) 46233096f16SXin LI { 46333096f16SXin LI toggle_option(curropt, ASCII_IS_LOWER(c), "", optflag); 464a5f0fb15SPaul Saab return (MCA_DONE); 465a5f0fb15SPaul Saab } 466a5f0fb15SPaul Saab /* 46733096f16SXin LI * Display a prompt appropriate for the option parameter. 468a5f0fb15SPaul Saab */ 46933096f16SXin LI start_mca(A_OPT_TOGGLE, opt_prompt(curropt), (void*)NULL, 0); 470a5f0fb15SPaul Saab return (MCA_MORE); 47133096f16SXin LI } 472a5f0fb15SPaul Saab 473a5f0fb15SPaul Saab /* 47433096f16SXin LI * Handle a char of a search command. 47533096f16SXin LI */ 47633096f16SXin LI static int 477*f6b74a7dSXin LI mca_search_char(c) 478*f6b74a7dSXin LI int c; 47933096f16SXin LI { 48033096f16SXin LI int flag = 0; 48133096f16SXin LI 48233096f16SXin LI /* 483a5f0fb15SPaul Saab * Certain characters as the first char of 484a5f0fb15SPaul Saab * the pattern have special meaning: 485a5f0fb15SPaul Saab * ! Toggle the NO_MATCH flag 486a5f0fb15SPaul Saab * * Toggle the PAST_EOF flag 487a5f0fb15SPaul Saab * @ Toggle the FIRST_FILE flag 488a5f0fb15SPaul Saab */ 489a5f0fb15SPaul Saab if (len_cmdbuf() > 0) 49033096f16SXin LI return (NO_MCA); 491a5f0fb15SPaul Saab 492a5f0fb15SPaul Saab switch (c) 493a5f0fb15SPaul Saab { 494a5f0fb15SPaul Saab case '*': 495720c436cSXin LI if (less_is_more) 496a8f92a7cSPaul Saab break; 497a8f92a7cSPaul Saab case CONTROL('E'): /* ignore END of file */ 4987374caaaSXin LI if (mca != A_FILTER) 499a5f0fb15SPaul Saab flag = SRCH_PAST_EOF; 500a5f0fb15SPaul Saab break; 501a5f0fb15SPaul Saab case '@': 502720c436cSXin LI if (less_is_more) 503a8f92a7cSPaul Saab break; 504a8f92a7cSPaul Saab case CONTROL('F'): /* FIRST file */ 5057374caaaSXin LI if (mca != A_FILTER) 506a5f0fb15SPaul Saab flag = SRCH_FIRST_FILE; 507a5f0fb15SPaul Saab break; 508a5f0fb15SPaul Saab case CONTROL('K'): /* KEEP position */ 5097374caaaSXin LI if (mca != A_FILTER) 510a5f0fb15SPaul Saab flag = SRCH_NO_MOVE; 511a5f0fb15SPaul Saab break; 512a5f0fb15SPaul Saab case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */ 513a5f0fb15SPaul Saab flag = SRCH_NO_REGEX; 514a5f0fb15SPaul Saab break; 515a5f0fb15SPaul Saab case CONTROL('N'): /* NOT match */ 516a5f0fb15SPaul Saab case '!': 517a5f0fb15SPaul Saab flag = SRCH_NO_MATCH; 518a5f0fb15SPaul Saab break; 519a5f0fb15SPaul Saab } 52033096f16SXin LI 521a5f0fb15SPaul Saab if (flag != 0) 522a5f0fb15SPaul Saab { 523a5f0fb15SPaul Saab search_type ^= flag; 524a5f0fb15SPaul Saab mca_search(); 525a5f0fb15SPaul Saab return (MCA_MORE); 526a5f0fb15SPaul Saab } 52733096f16SXin LI return (NO_MCA); 52833096f16SXin LI } 52933096f16SXin LI 53033096f16SXin LI /* 53133096f16SXin LI * Handle a character of a multi-character command. 53233096f16SXin LI */ 53333096f16SXin LI static int 534*f6b74a7dSXin LI mca_char(c) 535*f6b74a7dSXin LI int c; 53633096f16SXin LI { 53733096f16SXin LI int ret; 53833096f16SXin LI 53933096f16SXin LI switch (mca) 54033096f16SXin LI { 54133096f16SXin LI case 0: 54233096f16SXin LI /* 54333096f16SXin LI * We're not in a multicharacter command. 54433096f16SXin LI */ 54533096f16SXin LI return (NO_MCA); 54633096f16SXin LI 54733096f16SXin LI case A_PREFIX: 54833096f16SXin LI /* 54933096f16SXin LI * In the prefix of a command. 55033096f16SXin LI * This not considered a multichar command 55133096f16SXin LI * (even tho it uses cmdbuf, etc.). 55233096f16SXin LI * It is handled in the commands() switch. 55333096f16SXin LI */ 55433096f16SXin LI return (NO_MCA); 55533096f16SXin LI 55633096f16SXin LI case A_DIGIT: 55733096f16SXin LI /* 55833096f16SXin LI * Entering digits of a number. 55933096f16SXin LI * Terminated by a non-digit. 56033096f16SXin LI */ 56133096f16SXin LI if (!((c >= '0' && c <= '9') || c == '.') && 56233096f16SXin LI editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID) 56333096f16SXin LI { 56433096f16SXin LI /* 56533096f16SXin LI * Not part of the number. 56633096f16SXin LI * End the number and treat this char 56733096f16SXin LI * as a normal command character. 56833096f16SXin LI */ 56933096f16SXin LI number = cmd_int(&fraction); 57033096f16SXin LI mca = 0; 57133096f16SXin LI cmd_accept(); 57233096f16SXin LI return (NO_MCA); 57333096f16SXin LI } 57433096f16SXin LI break; 57533096f16SXin LI 57633096f16SXin LI case A_OPT_TOGGLE: 57733096f16SXin LI ret = mca_opt_char(c); 57833096f16SXin LI if (ret != NO_MCA) 57933096f16SXin LI return (ret); 58033096f16SXin LI break; 58133096f16SXin LI 58233096f16SXin LI case A_F_SEARCH: 58333096f16SXin LI case A_B_SEARCH: 58433096f16SXin LI case A_FILTER: 58533096f16SXin LI ret = mca_search_char(c); 58633096f16SXin LI if (ret != NO_MCA) 58733096f16SXin LI return (ret); 58833096f16SXin LI break; 58933096f16SXin LI 59033096f16SXin LI default: 59133096f16SXin LI /* Other multicharacter command. */ 592a5f0fb15SPaul Saab break; 593a5f0fb15SPaul Saab } 594a5f0fb15SPaul Saab 595a5f0fb15SPaul Saab /* 59633096f16SXin LI * The multichar command is terminated by a newline. 597a5f0fb15SPaul Saab */ 598a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 599a5f0fb15SPaul Saab { 600a5f0fb15SPaul Saab /* 601a5f0fb15SPaul Saab * Execute the command. 602a5f0fb15SPaul Saab */ 603a5f0fb15SPaul Saab exec_mca(); 604a5f0fb15SPaul Saab return (MCA_DONE); 605a5f0fb15SPaul Saab } 606a5f0fb15SPaul Saab 607a5f0fb15SPaul Saab /* 608a5f0fb15SPaul Saab * Append the char to the command buffer. 609a5f0fb15SPaul Saab */ 610a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT) 611a5f0fb15SPaul Saab /* 612a5f0fb15SPaul Saab * Abort the multi-char command. 613a5f0fb15SPaul Saab */ 614a5f0fb15SPaul Saab return (MCA_DONE); 615a5f0fb15SPaul Saab 616a5f0fb15SPaul Saab if ((mca == A_F_BRACKET || mca == A_B_BRACKET) && len_cmdbuf() >= 2) 617a5f0fb15SPaul Saab { 618a5f0fb15SPaul Saab /* 619a5f0fb15SPaul Saab * Special case for the bracket-matching commands. 620a5f0fb15SPaul Saab * Execute the command after getting exactly two 621a5f0fb15SPaul Saab * characters from the user. 622a5f0fb15SPaul Saab */ 623a5f0fb15SPaul Saab exec_mca(); 624a5f0fb15SPaul Saab return (MCA_DONE); 625a5f0fb15SPaul Saab } 626a5f0fb15SPaul Saab 627a5f0fb15SPaul Saab /* 628a5f0fb15SPaul Saab * Need another character. 629a5f0fb15SPaul Saab */ 630a5f0fb15SPaul Saab return (MCA_MORE); 631a5f0fb15SPaul Saab } 632a5f0fb15SPaul Saab 633a5f0fb15SPaul Saab /* 634423c5ce5SXin LI * Discard any buffered file data. 635423c5ce5SXin LI */ 636423c5ce5SXin LI static void 637*f6b74a7dSXin LI clear_buffers() 638423c5ce5SXin LI { 639423c5ce5SXin LI if (!(ch_getflags() & CH_CANSEEK)) 640423c5ce5SXin LI return; 641423c5ce5SXin LI ch_flush(); 642423c5ce5SXin LI clr_linenum(); 643423c5ce5SXin LI #if HILITE_SEARCH 644423c5ce5SXin LI clr_hilite(); 645423c5ce5SXin LI #endif 646423c5ce5SXin LI } 647423c5ce5SXin LI 648423c5ce5SXin LI /* 649a5f0fb15SPaul Saab * Make sure the screen is displayed. 650a5f0fb15SPaul Saab */ 651a5f0fb15SPaul Saab static void 652*f6b74a7dSXin LI make_display() 653a5f0fb15SPaul Saab { 654a5f0fb15SPaul Saab /* 655a5f0fb15SPaul Saab * If nothing is displayed yet, display starting from initial_scrpos. 656a5f0fb15SPaul Saab */ 657a5f0fb15SPaul Saab if (empty_screen()) 658a5f0fb15SPaul Saab { 659a5f0fb15SPaul Saab if (initial_scrpos.pos == NULL_POSITION) 660a5f0fb15SPaul Saab /* 661a5f0fb15SPaul Saab * {{ Maybe this should be: 662a5f0fb15SPaul Saab * jump_loc(ch_zero(), jump_sline); 663a5f0fb15SPaul Saab * but this behavior seems rather unexpected 664a5f0fb15SPaul Saab * on the first screen. }} 665a5f0fb15SPaul Saab */ 666a5f0fb15SPaul Saab jump_loc(ch_zero(), 1); 667a5f0fb15SPaul Saab else 668a5f0fb15SPaul Saab jump_loc(initial_scrpos.pos, initial_scrpos.ln); 669a5f0fb15SPaul Saab } else if (screen_trashed) 670a5f0fb15SPaul Saab { 671423c5ce5SXin LI int save_top_scroll = top_scroll; 672423c5ce5SXin LI int save_ignore_eoi = ignore_eoi; 673a5f0fb15SPaul Saab top_scroll = 1; 674423c5ce5SXin LI ignore_eoi = 0; 675423c5ce5SXin LI if (screen_trashed == 2) 676423c5ce5SXin LI { 677423c5ce5SXin LI /* Special case used by ignore_eoi: re-open the input file 678423c5ce5SXin LI * and jump to the end of the file. */ 679423c5ce5SXin LI reopen_curr_ifile(); 680423c5ce5SXin LI jump_forw(); 681423c5ce5SXin LI } 682a5f0fb15SPaul Saab repaint(); 683a5f0fb15SPaul Saab top_scroll = save_top_scroll; 684423c5ce5SXin LI ignore_eoi = save_ignore_eoi; 685a5f0fb15SPaul Saab } 686a5f0fb15SPaul Saab } 687a5f0fb15SPaul Saab 688a5f0fb15SPaul Saab /* 689a5f0fb15SPaul Saab * Display the appropriate prompt. 690a5f0fb15SPaul Saab */ 691a5f0fb15SPaul Saab static void 692*f6b74a7dSXin LI prompt() 693a5f0fb15SPaul Saab { 6941ea31627SRobert Watson constant char *p; 695a5f0fb15SPaul Saab 696a15691bfSXin LI if (ungot != NULL && !ungot->ug_end_command) 697a5f0fb15SPaul Saab { 698a5f0fb15SPaul Saab /* 699a5f0fb15SPaul Saab * No prompt necessary if commands are from 700a5f0fb15SPaul Saab * ungotten chars rather than from the user. 701a5f0fb15SPaul Saab */ 702a5f0fb15SPaul Saab return; 703a5f0fb15SPaul Saab } 704a5f0fb15SPaul Saab 705a5f0fb15SPaul Saab /* 706a5f0fb15SPaul Saab * Make sure the screen is displayed. 707a5f0fb15SPaul Saab */ 708a5f0fb15SPaul Saab make_display(); 709a5f0fb15SPaul Saab bottompos = position(BOTTOM_PLUS_ONE); 710a5f0fb15SPaul Saab 711a5f0fb15SPaul Saab /* 7127374caaaSXin LI * If we've hit EOF on the last file and the -E flag is set, quit. 713a5f0fb15SPaul Saab */ 7147374caaaSXin LI if (get_quit_at_eof() == OPT_ONPLUS && 7157374caaaSXin LI eof_displayed() && !(ch_getflags() & CH_HELPFILE) && 716a5f0fb15SPaul Saab next_ifile(curr_ifile) == NULL_IFILE) 717a5f0fb15SPaul Saab quit(QUIT_OK); 7187374caaaSXin LI 719a5f0fb15SPaul Saab /* 7207374caaaSXin LI * If the entire file is displayed and the -F flag is set, quit. 721a5f0fb15SPaul Saab */ 7227374caaaSXin LI if (quit_if_one_screen && 7237374caaaSXin LI entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) && 724a5f0fb15SPaul Saab next_ifile(curr_ifile) == NULL_IFILE) 725a5f0fb15SPaul Saab quit(QUIT_OK); 726a5f0fb15SPaul Saab 7278fd4165cSPaul Saab #if MSDOS_COMPILER==WIN32C 7288fd4165cSPaul Saab /* 7298fd4165cSPaul Saab * In Win32, display the file name in the window title. 7308fd4165cSPaul Saab */ 7318fd4165cSPaul Saab if (!(ch_getflags() & CH_HELPFILE)) 7328fd4165cSPaul Saab SetConsoleTitle(pr_expand("Less?f - %f.", 0)); 7338fd4165cSPaul Saab #endif 734a5f0fb15SPaul Saab /* 735a5f0fb15SPaul Saab * Select the proper prompt and display it. 736a5f0fb15SPaul Saab */ 737720c436cSXin LI /* 738720c436cSXin LI * If the previous action was a forward movement, 739720c436cSXin LI * don't clear the bottom line of the display; 740720c436cSXin LI * just print the prompt since the forward movement guarantees 741720c436cSXin LI * that we're in the right position to display the prompt. 742720c436cSXin LI * Clearing the line could cause a problem: for example, if the last 743720c436cSXin LI * line displayed ended at the right screen edge without a newline, 744720c436cSXin LI * then clearing would clear the last displayed line rather than 745720c436cSXin LI * the prompt line. 746720c436cSXin LI */ 747720c436cSXin LI if (!forw_prompt) 748720c436cSXin LI clear_bot(); 749a5f0fb15SPaul Saab clear_cmd(); 750720c436cSXin LI forw_prompt = 0; 751a5f0fb15SPaul Saab p = pr_string(); 7527374caaaSXin LI if (is_filtering()) 7537374caaaSXin LI putstr("& "); 75489dd99dcSXin LI if (p == NULL || *p == '\0') 755a5f0fb15SPaul Saab putchr(':'); 756a5f0fb15SPaul Saab else 757a5f0fb15SPaul Saab { 75889dd99dcSXin LI at_enter(AT_STANDOUT); 759a5f0fb15SPaul Saab putstr(p); 76089dd99dcSXin LI at_exit(); 761a5f0fb15SPaul Saab } 762720c436cSXin LI clear_eol(); 763a5f0fb15SPaul Saab } 764a5f0fb15SPaul Saab 765a5f0fb15SPaul Saab /* 766a5f0fb15SPaul Saab * Display the less version message. 767a5f0fb15SPaul Saab */ 768a5f0fb15SPaul Saab public void 769*f6b74a7dSXin LI dispversion() 770a5f0fb15SPaul Saab { 771a5f0fb15SPaul Saab PARG parg; 772a5f0fb15SPaul Saab 773a5f0fb15SPaul Saab parg.p_string = version; 774a5f0fb15SPaul Saab error("less %s", &parg); 775a5f0fb15SPaul Saab } 776a5f0fb15SPaul Saab 777a5f0fb15SPaul Saab /* 778a5f0fb15SPaul Saab * Get command character. 779a5f0fb15SPaul Saab * The character normally comes from the keyboard, 780a5f0fb15SPaul Saab * but may come from ungotten characters 781a5f0fb15SPaul Saab * (characters previously given to ungetcc or ungetsc). 782a5f0fb15SPaul Saab */ 783a5f0fb15SPaul Saab public int 784*f6b74a7dSXin LI getcc() 785a5f0fb15SPaul Saab { 786a15691bfSXin LI if (ungot == NULL) 78733096f16SXin LI { 788a5f0fb15SPaul Saab /* 789a15691bfSXin LI * Normal case: no ungotten chars, so get one from the user. 790a5f0fb15SPaul Saab */ 791a5f0fb15SPaul Saab return (getchr()); 792a15691bfSXin LI } 793a15691bfSXin LI 794a15691bfSXin LI /* 795a15691bfSXin LI * Return the next ungotten char. 796a15691bfSXin LI */ 797a15691bfSXin LI { 798a15691bfSXin LI struct ungot *ug = ungot; 799a15691bfSXin LI char c = ug->ug_char; 800a15691bfSXin LI int end_command = ug->ug_end_command; 801a15691bfSXin LI ungot = ug->ug_next; 802a15691bfSXin LI free(ug); 803a15691bfSXin LI if (end_command) 804a15691bfSXin LI { 805a5f0fb15SPaul Saab /* 806a5f0fb15SPaul Saab * Command is incomplete, so try to complete it. 807a5f0fb15SPaul Saab */ 808a5f0fb15SPaul Saab switch (mca) 809a5f0fb15SPaul Saab { 810a5f0fb15SPaul Saab case A_DIGIT: 811a5f0fb15SPaul Saab /* 812a5f0fb15SPaul Saab * We have a number but no command. Treat as #g. 813a5f0fb15SPaul Saab */ 814a5f0fb15SPaul Saab return ('g'); 815a5f0fb15SPaul Saab 816a5f0fb15SPaul Saab case A_F_SEARCH: 817a5f0fb15SPaul Saab case A_B_SEARCH: 818a5f0fb15SPaul Saab /* 819a5f0fb15SPaul Saab * We have "/string" but no newline. Add the \n. 820a5f0fb15SPaul Saab */ 821a5f0fb15SPaul Saab return ('\n'); 822a5f0fb15SPaul Saab 823a5f0fb15SPaul Saab default: 824a5f0fb15SPaul Saab /* 825a5f0fb15SPaul Saab * Some other incomplete command. Let user complete it. 826a5f0fb15SPaul Saab */ 827a5f0fb15SPaul Saab return (getchr()); 828a5f0fb15SPaul Saab } 829a5f0fb15SPaul Saab } 83033096f16SXin LI return (c); 83133096f16SXin LI } 83233096f16SXin LI } 83333096f16SXin LI 834a5f0fb15SPaul Saab /* 835a5f0fb15SPaul Saab * "Unget" a command character. 836a5f0fb15SPaul Saab * The next getcc() will return this character. 837a5f0fb15SPaul Saab */ 838a5f0fb15SPaul Saab public void 839*f6b74a7dSXin LI ungetcc(c) 840*f6b74a7dSXin LI int c; 841a5f0fb15SPaul Saab { 84233096f16SXin LI struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot)); 84333096f16SXin LI 844a15691bfSXin LI ug->ug_char = (char) c; 845a15691bfSXin LI ug->ug_end_command = (c == CHAR_END_COMMAND); 84633096f16SXin LI ug->ug_next = ungot; 84733096f16SXin LI ungot = ug; 848a5f0fb15SPaul Saab } 849a5f0fb15SPaul Saab 850a5f0fb15SPaul Saab /* 851a5f0fb15SPaul Saab * Unget a whole string of command characters. 852a5f0fb15SPaul Saab * The next sequence of getcc()'s will return this string. 853a5f0fb15SPaul Saab */ 854a5f0fb15SPaul Saab public void 855*f6b74a7dSXin LI ungetsc(s) 856*f6b74a7dSXin LI char *s; 857a5f0fb15SPaul Saab { 8581ea31627SRobert Watson char *p; 859a5f0fb15SPaul Saab 860a5f0fb15SPaul Saab for (p = s + strlen(s) - 1; p >= s; p--) 861a5f0fb15SPaul Saab ungetcc(*p); 862a5f0fb15SPaul Saab } 863a5f0fb15SPaul Saab 864a5f0fb15SPaul Saab /* 865a5f0fb15SPaul Saab * Search for a pattern, possibly in multiple files. 866a5f0fb15SPaul Saab * If SRCH_FIRST_FILE is set, begin searching at the first file. 867a5f0fb15SPaul Saab * If SRCH_PAST_EOF is set, continue the search thru multiple files. 868a5f0fb15SPaul Saab */ 869a5f0fb15SPaul Saab static void 870*f6b74a7dSXin LI multi_search(pattern, n, silent) 871*f6b74a7dSXin LI char *pattern; 872*f6b74a7dSXin LI int n; 873*f6b74a7dSXin LI int silent; 874a5f0fb15SPaul Saab { 8751ea31627SRobert Watson int nomore; 876a5f0fb15SPaul Saab IFILE save_ifile; 877a5f0fb15SPaul Saab int changed_file; 878a5f0fb15SPaul Saab 879a5f0fb15SPaul Saab changed_file = 0; 880a5f0fb15SPaul Saab save_ifile = save_curr_ifile(); 881a5f0fb15SPaul Saab 882a5f0fb15SPaul Saab if (search_type & SRCH_FIRST_FILE) 883a5f0fb15SPaul Saab { 884a5f0fb15SPaul Saab /* 885a5f0fb15SPaul Saab * Start at the first (or last) file 886a5f0fb15SPaul Saab * in the command line list. 887a5f0fb15SPaul Saab */ 888a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 889a5f0fb15SPaul Saab nomore = edit_first(); 890a5f0fb15SPaul Saab else 891a5f0fb15SPaul Saab nomore = edit_last(); 892a5f0fb15SPaul Saab if (nomore) 893a5f0fb15SPaul Saab { 894a5f0fb15SPaul Saab unsave_ifile(save_ifile); 895a5f0fb15SPaul Saab return; 896a5f0fb15SPaul Saab } 897a5f0fb15SPaul Saab changed_file = 1; 898a5f0fb15SPaul Saab search_type &= ~SRCH_FIRST_FILE; 899a5f0fb15SPaul Saab } 900a5f0fb15SPaul Saab 901a5f0fb15SPaul Saab for (;;) 902a5f0fb15SPaul Saab { 903a5f0fb15SPaul Saab n = search(search_type, pattern, n); 904a5f0fb15SPaul Saab /* 905a5f0fb15SPaul Saab * The SRCH_NO_MOVE flag doesn't "stick": it gets cleared 906a5f0fb15SPaul Saab * after being used once. This allows "n" to work after 907a5f0fb15SPaul Saab * using a /@@ search. 908a5f0fb15SPaul Saab */ 909a5f0fb15SPaul Saab search_type &= ~SRCH_NO_MOVE; 910a5f0fb15SPaul Saab if (n == 0) 911a5f0fb15SPaul Saab { 912a5f0fb15SPaul Saab /* 913a5f0fb15SPaul Saab * Found it. 914a5f0fb15SPaul Saab */ 915a5f0fb15SPaul Saab unsave_ifile(save_ifile); 916a5f0fb15SPaul Saab return; 917a5f0fb15SPaul Saab } 918a5f0fb15SPaul Saab 919a5f0fb15SPaul Saab if (n < 0) 920a5f0fb15SPaul Saab /* 921a5f0fb15SPaul Saab * Some kind of error in the search. 922a5f0fb15SPaul Saab * Error message has been printed by search(). 923a5f0fb15SPaul Saab */ 924a5f0fb15SPaul Saab break; 925a5f0fb15SPaul Saab 926a5f0fb15SPaul Saab if ((search_type & SRCH_PAST_EOF) == 0) 927a5f0fb15SPaul Saab /* 928a5f0fb15SPaul Saab * We didn't find a match, but we're 929a5f0fb15SPaul Saab * supposed to search only one file. 930a5f0fb15SPaul Saab */ 931a5f0fb15SPaul Saab break; 932a5f0fb15SPaul Saab /* 933a5f0fb15SPaul Saab * Move on to the next file. 934a5f0fb15SPaul Saab */ 935a5f0fb15SPaul Saab if (search_type & SRCH_FORW) 936a5f0fb15SPaul Saab nomore = edit_next(1); 937a5f0fb15SPaul Saab else 938a5f0fb15SPaul Saab nomore = edit_prev(1); 939a5f0fb15SPaul Saab if (nomore) 940a5f0fb15SPaul Saab break; 941a5f0fb15SPaul Saab changed_file = 1; 942a5f0fb15SPaul Saab } 943a5f0fb15SPaul Saab 944a5f0fb15SPaul Saab /* 945a5f0fb15SPaul Saab * Didn't find it. 946a5f0fb15SPaul Saab * Print an error message if we haven't already. 947a5f0fb15SPaul Saab */ 948a15691bfSXin LI if (n > 0 && !silent) 949a5f0fb15SPaul Saab error("Pattern not found", NULL_PARG); 950a5f0fb15SPaul Saab 951a5f0fb15SPaul Saab if (changed_file) 952a5f0fb15SPaul Saab { 953a5f0fb15SPaul Saab /* 954a5f0fb15SPaul Saab * Restore the file we were originally viewing. 955a5f0fb15SPaul Saab */ 956a5f0fb15SPaul Saab reedit_ifile(save_ifile); 95789dd99dcSXin LI } else 95889dd99dcSXin LI { 95989dd99dcSXin LI unsave_ifile(save_ifile); 960a5f0fb15SPaul Saab } 961a5f0fb15SPaul Saab } 962a5f0fb15SPaul Saab 963a5f0fb15SPaul Saab /* 96496e55cc7SXin LI * Forward forever, or until a highlighted line appears. 96596e55cc7SXin LI */ 96696e55cc7SXin LI static int 967*f6b74a7dSXin LI forw_loop(until_hilite) 968*f6b74a7dSXin LI int until_hilite; 96996e55cc7SXin LI { 97096e55cc7SXin LI POSITION curr_len; 97196e55cc7SXin LI 97296e55cc7SXin LI if (ch_getflags() & CH_HELPFILE) 97396e55cc7SXin LI return (A_NOACTION); 97496e55cc7SXin LI 97596e55cc7SXin LI cmd_exec(); 976a15691bfSXin LI jump_forw_buffered(); 97796e55cc7SXin LI curr_len = ch_length(); 97896e55cc7SXin LI highest_hilite = until_hilite ? curr_len : NULL_POSITION; 97996e55cc7SXin LI ignore_eoi = 1; 98096e55cc7SXin LI while (!sigs) 98196e55cc7SXin LI { 98296e55cc7SXin LI if (until_hilite && highest_hilite > curr_len) 98396e55cc7SXin LI { 98496e55cc7SXin LI bell(); 98596e55cc7SXin LI break; 98696e55cc7SXin LI } 98796e55cc7SXin LI make_display(); 98896e55cc7SXin LI forward(1, 0, 0); 98996e55cc7SXin LI } 99096e55cc7SXin LI ignore_eoi = 0; 991e2449719SXin LI ch_set_eof(); 99296e55cc7SXin LI 99396e55cc7SXin LI /* 99496e55cc7SXin LI * This gets us back in "F mode" after processing 99596e55cc7SXin LI * a non-abort signal (e.g. window-change). 99696e55cc7SXin LI */ 99796e55cc7SXin LI if (sigs && !ABORT_SIGS()) 998e2449719SXin LI return (until_hilite ? A_F_UNTIL_HILITE : A_F_FOREVER); 999e2449719SXin LI 100096e55cc7SXin LI return (A_NOACTION); 100196e55cc7SXin LI } 100296e55cc7SXin LI 100396e55cc7SXin LI /* 1004a5f0fb15SPaul Saab * Main command processor. 1005a5f0fb15SPaul Saab * Accept and execute commands until a quit command. 1006a5f0fb15SPaul Saab */ 1007a5f0fb15SPaul Saab public void 1008*f6b74a7dSXin LI commands() 1009a5f0fb15SPaul Saab { 10101ea31627SRobert Watson int c; 10111ea31627SRobert Watson int action; 10121ea31627SRobert Watson char *cbuf; 1013a5f0fb15SPaul Saab int newaction; 1014a5f0fb15SPaul Saab int save_search_type; 1015a5f0fb15SPaul Saab char *extra; 1016a5f0fb15SPaul Saab char tbuf[2]; 1017a5f0fb15SPaul Saab PARG parg; 1018a5f0fb15SPaul Saab IFILE old_ifile; 1019a5f0fb15SPaul Saab IFILE new_ifile; 10208fd4165cSPaul Saab char *tagfile; 1021a5f0fb15SPaul Saab 1022a5f0fb15SPaul Saab search_type = SRCH_FORW; 1023a5f0fb15SPaul Saab wscroll = (sc_height + 1) / 2; 1024a5f0fb15SPaul Saab newaction = A_NOACTION; 1025a5f0fb15SPaul Saab 1026a5f0fb15SPaul Saab for (;;) 1027a5f0fb15SPaul Saab { 1028a5f0fb15SPaul Saab mca = 0; 1029a5f0fb15SPaul Saab cmd_accept(); 1030a5f0fb15SPaul Saab number = 0; 103133096f16SXin LI curropt = NULL; 1032a5f0fb15SPaul Saab 1033a5f0fb15SPaul Saab /* 1034a5f0fb15SPaul Saab * See if any signals need processing. 1035a5f0fb15SPaul Saab */ 1036a5f0fb15SPaul Saab if (sigs) 1037a5f0fb15SPaul Saab { 1038a5f0fb15SPaul Saab psignals(); 1039a5f0fb15SPaul Saab if (quitting) 1040a5f0fb15SPaul Saab quit(QUIT_SAVED_STATUS); 1041a5f0fb15SPaul Saab } 1042a5f0fb15SPaul Saab 1043a5f0fb15SPaul Saab /* 1044a5f0fb15SPaul Saab * See if window size changed, for systems that don't 1045a5f0fb15SPaul Saab * generate SIGWINCH. 1046a5f0fb15SPaul Saab */ 1047a5f0fb15SPaul Saab check_winch(); 1048a5f0fb15SPaul Saab 1049a5f0fb15SPaul Saab /* 1050a5f0fb15SPaul Saab * Display prompt and accept a character. 1051a5f0fb15SPaul Saab */ 1052a5f0fb15SPaul Saab cmd_reset(); 1053a5f0fb15SPaul Saab prompt(); 1054a5f0fb15SPaul Saab if (sigs) 1055a5f0fb15SPaul Saab continue; 1056a5f0fb15SPaul Saab if (newaction == A_NOACTION) 1057a5f0fb15SPaul Saab c = getcc(); 1058a5f0fb15SPaul Saab 1059a5f0fb15SPaul Saab again: 1060a5f0fb15SPaul Saab if (sigs) 1061a5f0fb15SPaul Saab continue; 1062a5f0fb15SPaul Saab 1063a5f0fb15SPaul Saab if (newaction != A_NOACTION) 1064a5f0fb15SPaul Saab { 1065a5f0fb15SPaul Saab action = newaction; 1066a5f0fb15SPaul Saab newaction = A_NOACTION; 1067a5f0fb15SPaul Saab } else 1068a5f0fb15SPaul Saab { 1069a5f0fb15SPaul Saab /* 1070a5f0fb15SPaul Saab * If we are in a multicharacter command, call mca_char. 1071a5f0fb15SPaul Saab * Otherwise we call fcmd_decode to determine the 1072a5f0fb15SPaul Saab * action to be performed. 1073a5f0fb15SPaul Saab */ 1074a5f0fb15SPaul Saab if (mca) 1075a5f0fb15SPaul Saab switch (mca_char(c)) 1076a5f0fb15SPaul Saab { 1077a5f0fb15SPaul Saab case MCA_MORE: 1078a5f0fb15SPaul Saab /* 1079a5f0fb15SPaul Saab * Need another character. 1080a5f0fb15SPaul Saab */ 1081a5f0fb15SPaul Saab c = getcc(); 1082a5f0fb15SPaul Saab goto again; 1083a5f0fb15SPaul Saab case MCA_DONE: 1084a5f0fb15SPaul Saab /* 1085a5f0fb15SPaul Saab * Command has been handled by mca_char. 1086a5f0fb15SPaul Saab * Start clean with a prompt. 1087a5f0fb15SPaul Saab */ 1088a5f0fb15SPaul Saab continue; 1089a5f0fb15SPaul Saab case NO_MCA: 1090a5f0fb15SPaul Saab /* 1091a5f0fb15SPaul Saab * Not a multi-char command 1092a5f0fb15SPaul Saab * (at least, not anymore). 1093a5f0fb15SPaul Saab */ 1094a5f0fb15SPaul Saab break; 1095a5f0fb15SPaul Saab } 1096a5f0fb15SPaul Saab 1097a5f0fb15SPaul Saab /* 1098a5f0fb15SPaul Saab * Decode the command character and decide what to do. 1099a5f0fb15SPaul Saab */ 1100a5f0fb15SPaul Saab if (mca) 1101a5f0fb15SPaul Saab { 1102a5f0fb15SPaul Saab /* 1103a5f0fb15SPaul Saab * We're in a multichar command. 1104a5f0fb15SPaul Saab * Add the character to the command buffer 1105a5f0fb15SPaul Saab * and display it on the screen. 1106a5f0fb15SPaul Saab * If the user backspaces past the start 1107a5f0fb15SPaul Saab * of the line, abort the command. 1108a5f0fb15SPaul Saab */ 1109a5f0fb15SPaul Saab if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0) 1110a5f0fb15SPaul Saab continue; 1111a5f0fb15SPaul Saab cbuf = get_cmdbuf(); 1112a5f0fb15SPaul Saab } else 1113a5f0fb15SPaul Saab { 1114a5f0fb15SPaul Saab /* 1115a5f0fb15SPaul Saab * Don't use cmd_char if we're starting fresh 1116a5f0fb15SPaul Saab * at the beginning of a command, because we 1117a5f0fb15SPaul Saab * don't want to echo the command until we know 1118a5f0fb15SPaul Saab * it is a multichar command. We also don't 1119a5f0fb15SPaul Saab * want erase_char/kill_char to be treated 1120a5f0fb15SPaul Saab * as line editing characters. 1121a5f0fb15SPaul Saab */ 1122a5f0fb15SPaul Saab tbuf[0] = c; 1123a5f0fb15SPaul Saab tbuf[1] = '\0'; 1124a5f0fb15SPaul Saab cbuf = tbuf; 1125a5f0fb15SPaul Saab } 1126a5f0fb15SPaul Saab extra = NULL; 1127a5f0fb15SPaul Saab action = fcmd_decode(cbuf, &extra); 1128a5f0fb15SPaul Saab /* 1129a5f0fb15SPaul Saab * If an "extra" string was returned, 1130a5f0fb15SPaul Saab * process it as a string of command characters. 1131a5f0fb15SPaul Saab */ 1132a5f0fb15SPaul Saab if (extra != NULL) 1133a5f0fb15SPaul Saab ungetsc(extra); 1134a5f0fb15SPaul Saab } 1135a5f0fb15SPaul Saab /* 1136a5f0fb15SPaul Saab * Clear the cmdbuf string. 1137a5f0fb15SPaul Saab * (But not if we're in the prefix of a command, 1138a5f0fb15SPaul Saab * because the partial command string is kept there.) 1139a5f0fb15SPaul Saab */ 1140a5f0fb15SPaul Saab if (action != A_PREFIX) 1141a5f0fb15SPaul Saab cmd_reset(); 1142a5f0fb15SPaul Saab 1143a5f0fb15SPaul Saab switch (action) 1144a5f0fb15SPaul Saab { 1145a5f0fb15SPaul Saab case A_DIGIT: 1146a5f0fb15SPaul Saab /* 1147a5f0fb15SPaul Saab * First digit of a number. 1148a5f0fb15SPaul Saab */ 1149a5f0fb15SPaul Saab start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE); 1150a5f0fb15SPaul Saab goto again; 1151a5f0fb15SPaul Saab 1152a5f0fb15SPaul Saab case A_F_WINDOW: 1153a5f0fb15SPaul Saab /* 1154a5f0fb15SPaul Saab * Forward one window (and set the window size). 1155a5f0fb15SPaul Saab */ 1156a5f0fb15SPaul Saab if (number > 0) 11571ede1615STim J. Robbins swindow = (int) number; 1158a5f0fb15SPaul Saab /* FALLTHRU */ 1159a5f0fb15SPaul Saab case A_F_SCREEN: 1160a5f0fb15SPaul Saab /* 1161a5f0fb15SPaul Saab * Forward one screen. 1162a5f0fb15SPaul Saab */ 1163a5f0fb15SPaul Saab if (number <= 0) 1164a5f0fb15SPaul Saab number = get_swindow(); 1165a5f0fb15SPaul Saab cmd_exec(); 1166a5f0fb15SPaul Saab if (show_attn) 1167a5f0fb15SPaul Saab set_attnpos(bottompos); 11681ede1615STim J. Robbins forward((int) number, 0, 1); 1169a5f0fb15SPaul Saab break; 1170a5f0fb15SPaul Saab 1171a5f0fb15SPaul Saab case A_B_WINDOW: 1172a5f0fb15SPaul Saab /* 1173a5f0fb15SPaul Saab * Backward one window (and set the window size). 1174a5f0fb15SPaul Saab */ 1175a5f0fb15SPaul Saab if (number > 0) 11761ede1615STim J. Robbins swindow = (int) number; 1177a5f0fb15SPaul Saab /* FALLTHRU */ 1178a5f0fb15SPaul Saab case A_B_SCREEN: 1179a5f0fb15SPaul Saab /* 1180a5f0fb15SPaul Saab * Backward one screen. 1181a5f0fb15SPaul Saab */ 1182a5f0fb15SPaul Saab if (number <= 0) 1183a5f0fb15SPaul Saab number = get_swindow(); 1184a5f0fb15SPaul Saab cmd_exec(); 11851ede1615STim J. Robbins backward((int) number, 0, 1); 1186a5f0fb15SPaul Saab break; 1187a5f0fb15SPaul Saab 1188a5f0fb15SPaul Saab case A_F_LINE: 1189a5f0fb15SPaul Saab /* 1190a5f0fb15SPaul Saab * Forward N (default 1) line. 1191a5f0fb15SPaul Saab */ 1192a5f0fb15SPaul Saab if (number <= 0) 1193a5f0fb15SPaul Saab number = 1; 1194a5f0fb15SPaul Saab cmd_exec(); 1195a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS && number > 1) 1196a5f0fb15SPaul Saab set_attnpos(bottompos); 11971ede1615STim J. Robbins forward((int) number, 0, 0); 1198a5f0fb15SPaul Saab break; 1199a5f0fb15SPaul Saab 1200a5f0fb15SPaul Saab case A_B_LINE: 1201a5f0fb15SPaul Saab /* 1202a5f0fb15SPaul Saab * Backward N (default 1) line. 1203a5f0fb15SPaul Saab */ 1204a5f0fb15SPaul Saab if (number <= 0) 1205a5f0fb15SPaul Saab number = 1; 1206a5f0fb15SPaul Saab cmd_exec(); 12071ede1615STim J. Robbins backward((int) number, 0, 0); 1208a5f0fb15SPaul Saab break; 1209a5f0fb15SPaul Saab 1210a5f0fb15SPaul Saab case A_FF_LINE: 1211a5f0fb15SPaul Saab /* 1212a5f0fb15SPaul Saab * Force forward N (default 1) line. 1213a5f0fb15SPaul Saab */ 1214a5f0fb15SPaul Saab if (number <= 0) 1215a5f0fb15SPaul Saab number = 1; 1216a5f0fb15SPaul Saab cmd_exec(); 1217a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS && number > 1) 1218a5f0fb15SPaul Saab set_attnpos(bottompos); 12191ede1615STim J. Robbins forward((int) number, 1, 0); 1220a5f0fb15SPaul Saab break; 1221a5f0fb15SPaul Saab 1222a5f0fb15SPaul Saab case A_BF_LINE: 1223a5f0fb15SPaul Saab /* 1224a5f0fb15SPaul Saab * Force backward N (default 1) line. 1225a5f0fb15SPaul Saab */ 1226a5f0fb15SPaul Saab if (number <= 0) 1227a5f0fb15SPaul Saab number = 1; 1228a5f0fb15SPaul Saab cmd_exec(); 12291ede1615STim J. Robbins backward((int) number, 1, 0); 1230a5f0fb15SPaul Saab break; 1231a5f0fb15SPaul Saab 1232a5f0fb15SPaul Saab case A_FF_SCREEN: 1233a5f0fb15SPaul Saab /* 1234a5f0fb15SPaul Saab * Force forward one screen. 1235a5f0fb15SPaul Saab */ 1236a5f0fb15SPaul Saab if (number <= 0) 1237a5f0fb15SPaul Saab number = get_swindow(); 1238a5f0fb15SPaul Saab cmd_exec(); 1239a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS) 1240a5f0fb15SPaul Saab set_attnpos(bottompos); 12411ede1615STim J. Robbins forward((int) number, 1, 0); 1242a5f0fb15SPaul Saab break; 1243a5f0fb15SPaul Saab 1244a5f0fb15SPaul Saab case A_F_FOREVER: 1245a5f0fb15SPaul Saab /* 1246a5f0fb15SPaul Saab * Forward forever, ignoring EOF. 1247a5f0fb15SPaul Saab */ 1248a15691bfSXin LI if (show_attn) 1249a15691bfSXin LI set_attnpos(bottompos); 125096e55cc7SXin LI newaction = forw_loop(0); 1251a5f0fb15SPaul Saab break; 125296e55cc7SXin LI 125396e55cc7SXin LI case A_F_UNTIL_HILITE: 125496e55cc7SXin LI newaction = forw_loop(1); 1255a5f0fb15SPaul Saab break; 1256a5f0fb15SPaul Saab 1257a5f0fb15SPaul Saab case A_F_SCROLL: 1258a5f0fb15SPaul Saab /* 1259a5f0fb15SPaul Saab * Forward N lines 1260a5f0fb15SPaul Saab * (default same as last 'd' or 'u' command). 1261a5f0fb15SPaul Saab */ 1262a5f0fb15SPaul Saab if (number > 0) 12631ede1615STim J. Robbins wscroll = (int) number; 1264a5f0fb15SPaul Saab cmd_exec(); 1265a5f0fb15SPaul Saab if (show_attn == OPT_ONPLUS) 1266a5f0fb15SPaul Saab set_attnpos(bottompos); 1267a5f0fb15SPaul Saab forward(wscroll, 0, 0); 1268a5f0fb15SPaul Saab break; 1269a5f0fb15SPaul Saab 1270a5f0fb15SPaul Saab case A_B_SCROLL: 1271a5f0fb15SPaul Saab /* 1272a5f0fb15SPaul Saab * Forward N lines 1273a5f0fb15SPaul Saab * (default same as last 'd' or 'u' command). 1274a5f0fb15SPaul Saab */ 1275a5f0fb15SPaul Saab if (number > 0) 12761ede1615STim J. Robbins wscroll = (int) number; 1277a5f0fb15SPaul Saab cmd_exec(); 1278a5f0fb15SPaul Saab backward(wscroll, 0, 0); 1279a5f0fb15SPaul Saab break; 1280a5f0fb15SPaul Saab 1281a5f0fb15SPaul Saab case A_FREPAINT: 1282a5f0fb15SPaul Saab /* 1283a5f0fb15SPaul Saab * Flush buffers, then repaint screen. 1284a5f0fb15SPaul Saab * Don't flush the buffers on a pipe! 1285a5f0fb15SPaul Saab */ 1286423c5ce5SXin LI clear_buffers(); 1287a5f0fb15SPaul Saab /* FALLTHRU */ 1288a5f0fb15SPaul Saab case A_REPAINT: 1289a5f0fb15SPaul Saab /* 1290a5f0fb15SPaul Saab * Repaint screen. 1291a5f0fb15SPaul Saab */ 1292a5f0fb15SPaul Saab cmd_exec(); 1293a5f0fb15SPaul Saab repaint(); 1294a5f0fb15SPaul Saab break; 1295a5f0fb15SPaul Saab 1296a5f0fb15SPaul Saab case A_GOLINE: 1297a5f0fb15SPaul Saab /* 1298a5f0fb15SPaul Saab * Go to line N, default beginning of file. 1299a5f0fb15SPaul Saab */ 1300a5f0fb15SPaul Saab if (number <= 0) 1301a5f0fb15SPaul Saab number = 1; 1302a5f0fb15SPaul Saab cmd_exec(); 1303a5f0fb15SPaul Saab jump_back(number); 1304a5f0fb15SPaul Saab break; 1305a5f0fb15SPaul Saab 1306a5f0fb15SPaul Saab case A_PERCENT: 1307a5f0fb15SPaul Saab /* 1308a5f0fb15SPaul Saab * Go to a specified percentage into the file. 1309a5f0fb15SPaul Saab */ 1310a5f0fb15SPaul Saab if (number < 0) 1311720c436cSXin LI { 1312a5f0fb15SPaul Saab number = 0; 1313720c436cSXin LI fraction = 0; 1314720c436cSXin LI } 1315a5f0fb15SPaul Saab if (number > 100) 1316720c436cSXin LI { 1317a5f0fb15SPaul Saab number = 100; 1318720c436cSXin LI fraction = 0; 1319720c436cSXin LI } 1320a5f0fb15SPaul Saab cmd_exec(); 1321720c436cSXin LI jump_percent((int) number, fraction); 1322a5f0fb15SPaul Saab break; 1323a5f0fb15SPaul Saab 1324a5f0fb15SPaul Saab case A_GOEND: 1325a5f0fb15SPaul Saab /* 1326a5f0fb15SPaul Saab * Go to line N, default end of file. 1327a5f0fb15SPaul Saab */ 1328a5f0fb15SPaul Saab cmd_exec(); 1329a5f0fb15SPaul Saab if (number <= 0) 1330a5f0fb15SPaul Saab jump_forw(); 1331a5f0fb15SPaul Saab else 1332a5f0fb15SPaul Saab jump_back(number); 1333a5f0fb15SPaul Saab break; 1334a5f0fb15SPaul Saab 1335a15691bfSXin LI case A_GOEND_BUF: 1336a15691bfSXin LI /* 1337a15691bfSXin LI * Go to line N, default last buffered byte. 1338a15691bfSXin LI */ 1339a15691bfSXin LI cmd_exec(); 1340a15691bfSXin LI if (number <= 0) 1341a15691bfSXin LI jump_forw_buffered(); 1342a15691bfSXin LI else 1343a15691bfSXin LI jump_back(number); 1344a15691bfSXin LI break; 1345a15691bfSXin LI 1346a5f0fb15SPaul Saab case A_GOPOS: 1347a5f0fb15SPaul Saab /* 1348a5f0fb15SPaul Saab * Go to a specified byte position in the file. 1349a5f0fb15SPaul Saab */ 1350a5f0fb15SPaul Saab cmd_exec(); 1351a5f0fb15SPaul Saab if (number < 0) 1352a5f0fb15SPaul Saab number = 0; 1353a5f0fb15SPaul Saab jump_line_loc((POSITION) number, jump_sline); 1354a5f0fb15SPaul Saab break; 1355a5f0fb15SPaul Saab 1356a5f0fb15SPaul Saab case A_STAT: 1357a5f0fb15SPaul Saab /* 1358a5f0fb15SPaul Saab * Print file name, etc. 1359a5f0fb15SPaul Saab */ 1360a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1361a5f0fb15SPaul Saab break; 1362a5f0fb15SPaul Saab cmd_exec(); 1363a5f0fb15SPaul Saab parg.p_string = eq_message(); 1364a5f0fb15SPaul Saab error("%s", &parg); 1365a5f0fb15SPaul Saab break; 1366a5f0fb15SPaul Saab 1367a5f0fb15SPaul Saab case A_VERSION: 1368a5f0fb15SPaul Saab /* 1369a5f0fb15SPaul Saab * Print version number, without the "@(#)". 1370a5f0fb15SPaul Saab */ 1371a5f0fb15SPaul Saab cmd_exec(); 1372a5f0fb15SPaul Saab dispversion(); 1373a5f0fb15SPaul Saab break; 1374a5f0fb15SPaul Saab 1375a5f0fb15SPaul Saab case A_QUIT: 1376a5f0fb15SPaul Saab /* 1377a5f0fb15SPaul Saab * Exit. 1378a5f0fb15SPaul Saab */ 1379a5f0fb15SPaul Saab if (curr_ifile != NULL_IFILE && 1380a5f0fb15SPaul Saab ch_getflags() & CH_HELPFILE) 1381a5f0fb15SPaul Saab { 1382a5f0fb15SPaul Saab /* 1383a5f0fb15SPaul Saab * Quit while viewing the help file 1384a5f0fb15SPaul Saab * just means return to viewing the 1385a5f0fb15SPaul Saab * previous file. 1386a5f0fb15SPaul Saab */ 138789dd99dcSXin LI hshift = save_hshift; 1388a15691bfSXin LI bs_mode = save_bs_mode; 1389a5f0fb15SPaul Saab if (edit_prev(1) == 0) 1390a5f0fb15SPaul Saab break; 1391a5f0fb15SPaul Saab } 1392a5f0fb15SPaul Saab if (extra != NULL) 1393a5f0fb15SPaul Saab quit(*extra); 1394a5f0fb15SPaul Saab quit(QUIT_OK); 1395a5f0fb15SPaul Saab break; 1396a5f0fb15SPaul Saab 1397a5f0fb15SPaul Saab /* 1398a5f0fb15SPaul Saab * Define abbreviation for a commonly used sequence below. 1399a5f0fb15SPaul Saab */ 1400423c5ce5SXin LI #define DO_SEARCH() \ 1401423c5ce5SXin LI if (number <= 0) number = 1; \ 1402a5f0fb15SPaul Saab mca_search(); \ 1403a5f0fb15SPaul Saab cmd_exec(); \ 1404a15691bfSXin LI multi_search((char *)NULL, (int) number, 0); 1405a5f0fb15SPaul Saab 1406a5f0fb15SPaul Saab 1407a5f0fb15SPaul Saab case A_F_SEARCH: 1408a5f0fb15SPaul Saab /* 1409a5f0fb15SPaul Saab * Search forward for a pattern. 1410a5f0fb15SPaul Saab * Get the first char of the pattern. 1411a5f0fb15SPaul Saab */ 1412a5f0fb15SPaul Saab search_type = SRCH_FORW; 1413a5f0fb15SPaul Saab if (number <= 0) 1414a5f0fb15SPaul Saab number = 1; 1415a5f0fb15SPaul Saab mca_search(); 1416a5f0fb15SPaul Saab c = getcc(); 1417a5f0fb15SPaul Saab goto again; 1418a5f0fb15SPaul Saab 1419a5f0fb15SPaul Saab case A_B_SEARCH: 1420a5f0fb15SPaul Saab /* 1421a5f0fb15SPaul Saab * Search backward for a pattern. 1422a5f0fb15SPaul Saab * Get the first char of the pattern. 1423a5f0fb15SPaul Saab */ 1424a5f0fb15SPaul Saab search_type = SRCH_BACK; 1425a5f0fb15SPaul Saab if (number <= 0) 1426a5f0fb15SPaul Saab number = 1; 1427a5f0fb15SPaul Saab mca_search(); 1428a5f0fb15SPaul Saab c = getcc(); 1429a5f0fb15SPaul Saab goto again; 1430a5f0fb15SPaul Saab 14317374caaaSXin LI case A_FILTER: 14327374caaaSXin LI #if HILITE_SEARCH 14337374caaaSXin LI search_type = SRCH_FORW | SRCH_FILTER; 14347374caaaSXin LI mca_search(); 14357374caaaSXin LI c = getcc(); 14367374caaaSXin LI goto again; 14377374caaaSXin LI #else 14387374caaaSXin LI error("Command not available", NULL_PARG); 14397374caaaSXin LI break; 14407374caaaSXin LI #endif 14417374caaaSXin LI 1442a5f0fb15SPaul Saab case A_AGAIN_SEARCH: 1443a5f0fb15SPaul Saab /* 1444a5f0fb15SPaul Saab * Repeat previous search. 1445a5f0fb15SPaul Saab */ 1446a5f0fb15SPaul Saab DO_SEARCH(); 1447a5f0fb15SPaul Saab break; 1448a5f0fb15SPaul Saab 1449a5f0fb15SPaul Saab case A_T_AGAIN_SEARCH: 1450a5f0fb15SPaul Saab /* 1451a5f0fb15SPaul Saab * Repeat previous search, multiple files. 1452a5f0fb15SPaul Saab */ 1453a5f0fb15SPaul Saab search_type |= SRCH_PAST_EOF; 1454a5f0fb15SPaul Saab DO_SEARCH(); 1455a5f0fb15SPaul Saab break; 1456a5f0fb15SPaul Saab 1457a5f0fb15SPaul Saab case A_REVERSE_SEARCH: 1458a5f0fb15SPaul Saab /* 1459a5f0fb15SPaul Saab * Repeat previous search, in reverse direction. 1460a5f0fb15SPaul Saab */ 1461a5f0fb15SPaul Saab save_search_type = search_type; 1462a5f0fb15SPaul Saab search_type = SRCH_REVERSE(search_type); 1463a5f0fb15SPaul Saab DO_SEARCH(); 1464a5f0fb15SPaul Saab search_type = save_search_type; 1465a5f0fb15SPaul Saab break; 1466a5f0fb15SPaul Saab 1467a5f0fb15SPaul Saab case A_T_REVERSE_SEARCH: 1468a5f0fb15SPaul Saab /* 1469a5f0fb15SPaul Saab * Repeat previous search, 1470a5f0fb15SPaul Saab * multiple files in reverse direction. 1471a5f0fb15SPaul Saab */ 1472a5f0fb15SPaul Saab save_search_type = search_type; 1473a5f0fb15SPaul Saab search_type = SRCH_REVERSE(search_type); 1474a5f0fb15SPaul Saab search_type |= SRCH_PAST_EOF; 1475a5f0fb15SPaul Saab DO_SEARCH(); 1476a5f0fb15SPaul Saab search_type = save_search_type; 1477a5f0fb15SPaul Saab break; 1478a5f0fb15SPaul Saab 1479a5f0fb15SPaul Saab case A_UNDO_SEARCH: 1480a5f0fb15SPaul Saab undo_search(); 1481a5f0fb15SPaul Saab break; 1482a5f0fb15SPaul Saab 1483a5f0fb15SPaul Saab case A_HELP: 1484a5f0fb15SPaul Saab /* 1485a5f0fb15SPaul Saab * Help. 1486a5f0fb15SPaul Saab */ 1487a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1488a5f0fb15SPaul Saab break; 1489a5f0fb15SPaul Saab cmd_exec(); 149089dd99dcSXin LI save_hshift = hshift; 149189dd99dcSXin LI hshift = 0; 1492a15691bfSXin LI save_bs_mode = bs_mode; 1493a15691bfSXin LI bs_mode = BS_SPECIAL; 1494a5f0fb15SPaul Saab (void) edit(FAKE_HELPFILE); 1495a5f0fb15SPaul Saab break; 1496a5f0fb15SPaul Saab 1497a5f0fb15SPaul Saab case A_EXAMINE: 1498a5f0fb15SPaul Saab #if EXAMINE 1499a5f0fb15SPaul Saab /* 1500a5f0fb15SPaul Saab * Edit a new file. Get the filename. 1501a5f0fb15SPaul Saab */ 1502a5f0fb15SPaul Saab if (secure) 1503a5f0fb15SPaul Saab { 1504a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1505a5f0fb15SPaul Saab break; 1506a5f0fb15SPaul Saab } 1507dd3bd0edSDimitry Andric start_mca(A_EXAMINE, "Examine: ", ml_examine, 0); 1508a5f0fb15SPaul Saab c = getcc(); 1509a5f0fb15SPaul Saab goto again; 1510a5f0fb15SPaul Saab #else 1511a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1512a5f0fb15SPaul Saab break; 1513a5f0fb15SPaul Saab #endif 1514a5f0fb15SPaul Saab 1515a5f0fb15SPaul Saab case A_VISUAL: 1516a5f0fb15SPaul Saab /* 1517a5f0fb15SPaul Saab * Invoke an editor on the input file. 1518a5f0fb15SPaul Saab */ 1519a5f0fb15SPaul Saab #if EDITOR 1520a5f0fb15SPaul Saab if (secure) 1521a5f0fb15SPaul Saab { 1522a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1523a5f0fb15SPaul Saab break; 1524a5f0fb15SPaul Saab } 1525a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1526a5f0fb15SPaul Saab break; 1527a5f0fb15SPaul Saab if (strcmp(get_filename(curr_ifile), "-") == 0) 1528a5f0fb15SPaul Saab { 1529a5f0fb15SPaul Saab error("Cannot edit standard input", NULL_PARG); 1530a5f0fb15SPaul Saab break; 1531a5f0fb15SPaul Saab } 1532a5f0fb15SPaul Saab if (curr_altfilename != NULL) 1533a5f0fb15SPaul Saab { 153489dd99dcSXin LI error("WARNING: This file was viewed via LESSOPEN", 1535a5f0fb15SPaul Saab NULL_PARG); 1536a5f0fb15SPaul Saab } 1537dd3bd0edSDimitry Andric start_mca(A_SHELL, "!", ml_shell, 0); 1538a5f0fb15SPaul Saab /* 1539a5f0fb15SPaul Saab * Expand the editor prototype string 1540a5f0fb15SPaul Saab * and pass it to the system to execute. 1541a5f0fb15SPaul Saab * (Make sure the screen is displayed so the 1542a5f0fb15SPaul Saab * expansion of "+%lm" works.) 1543a5f0fb15SPaul Saab */ 1544a5f0fb15SPaul Saab make_display(); 1545a5f0fb15SPaul Saab cmd_exec(); 1546a5f0fb15SPaul Saab lsystem(pr_expand(editproto, 0), (char*)NULL); 1547a5f0fb15SPaul Saab break; 1548a5f0fb15SPaul Saab #else 1549a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1550a5f0fb15SPaul Saab break; 1551a5f0fb15SPaul Saab #endif 1552a5f0fb15SPaul Saab 1553a5f0fb15SPaul Saab case A_NEXT_FILE: 1554a5f0fb15SPaul Saab /* 1555a5f0fb15SPaul Saab * Examine next file. 1556a5f0fb15SPaul Saab */ 15571ede1615STim J. Robbins #if TAGS 15588fd4165cSPaul Saab if (ntags()) 15598fd4165cSPaul Saab { 15608fd4165cSPaul Saab error("No next file", NULL_PARG); 15618fd4165cSPaul Saab break; 15628fd4165cSPaul Saab } 15631ede1615STim J. Robbins #endif 1564a5f0fb15SPaul Saab if (number <= 0) 1565a5f0fb15SPaul Saab number = 1; 15661ede1615STim J. Robbins if (edit_next((int) number)) 1567a5f0fb15SPaul Saab { 15687374caaaSXin LI if (get_quit_at_eof() && eof_displayed() && 1569a5f0fb15SPaul Saab !(ch_getflags() & CH_HELPFILE)) 1570a5f0fb15SPaul Saab quit(QUIT_OK); 1571a5f0fb15SPaul Saab parg.p_string = (number > 1) ? "(N-th) " : ""; 1572a5f0fb15SPaul Saab error("No %snext file", &parg); 1573a5f0fb15SPaul Saab } 1574a5f0fb15SPaul Saab break; 1575a5f0fb15SPaul Saab 1576a5f0fb15SPaul Saab case A_PREV_FILE: 1577a5f0fb15SPaul Saab /* 1578a5f0fb15SPaul Saab * Examine previous file. 1579a5f0fb15SPaul Saab */ 15801ede1615STim J. Robbins #if TAGS 15818fd4165cSPaul Saab if (ntags()) 15828fd4165cSPaul Saab { 15838fd4165cSPaul Saab error("No previous file", NULL_PARG); 15848fd4165cSPaul Saab break; 15858fd4165cSPaul Saab } 15861ede1615STim J. Robbins #endif 1587a5f0fb15SPaul Saab if (number <= 0) 1588a5f0fb15SPaul Saab number = 1; 15891ede1615STim J. Robbins if (edit_prev((int) number)) 1590a5f0fb15SPaul Saab { 1591a5f0fb15SPaul Saab parg.p_string = (number > 1) ? "(N-th) " : ""; 1592a5f0fb15SPaul Saab error("No %sprevious file", &parg); 1593a5f0fb15SPaul Saab } 1594a5f0fb15SPaul Saab break; 1595a5f0fb15SPaul Saab 15968fd4165cSPaul Saab case A_NEXT_TAG: 15971ede1615STim J. Robbins #if TAGS 15988fd4165cSPaul Saab if (number <= 0) 15998fd4165cSPaul Saab number = 1; 16001ede1615STim J. Robbins tagfile = nexttag((int) number); 16018fd4165cSPaul Saab if (tagfile == NULL) 16028fd4165cSPaul Saab { 16038fd4165cSPaul Saab error("No next tag", NULL_PARG); 16048fd4165cSPaul Saab break; 16058fd4165cSPaul Saab } 16068fd4165cSPaul Saab if (edit(tagfile) == 0) 16078fd4165cSPaul Saab { 16088fd4165cSPaul Saab POSITION pos = tagsearch(); 16098fd4165cSPaul Saab if (pos != NULL_POSITION) 16108fd4165cSPaul Saab jump_loc(pos, jump_sline); 16118fd4165cSPaul Saab } 16121ede1615STim J. Robbins #else 16131ede1615STim J. Robbins error("Command not available", NULL_PARG); 16141ede1615STim J. Robbins #endif 16158fd4165cSPaul Saab break; 16168fd4165cSPaul Saab 16178fd4165cSPaul Saab case A_PREV_TAG: 16181ede1615STim J. Robbins #if TAGS 16198fd4165cSPaul Saab if (number <= 0) 16208fd4165cSPaul Saab number = 1; 16211ede1615STim J. Robbins tagfile = prevtag((int) number); 16228fd4165cSPaul Saab if (tagfile == NULL) 16238fd4165cSPaul Saab { 16248fd4165cSPaul Saab error("No previous tag", NULL_PARG); 16258fd4165cSPaul Saab break; 16268fd4165cSPaul Saab } 16278fd4165cSPaul Saab if (edit(tagfile) == 0) 16288fd4165cSPaul Saab { 16298fd4165cSPaul Saab POSITION pos = tagsearch(); 16308fd4165cSPaul Saab if (pos != NULL_POSITION) 16318fd4165cSPaul Saab jump_loc(pos, jump_sline); 16328fd4165cSPaul Saab } 16331ede1615STim J. Robbins #else 16341ede1615STim J. Robbins error("Command not available", NULL_PARG); 16351ede1615STim J. Robbins #endif 16368fd4165cSPaul Saab break; 16378fd4165cSPaul Saab 1638a5f0fb15SPaul Saab case A_INDEX_FILE: 1639a5f0fb15SPaul Saab /* 1640a5f0fb15SPaul Saab * Examine a particular file. 1641a5f0fb15SPaul Saab */ 1642a5f0fb15SPaul Saab if (number <= 0) 1643a5f0fb15SPaul Saab number = 1; 16441ede1615STim J. Robbins if (edit_index((int) number)) 1645a5f0fb15SPaul Saab error("No such file", NULL_PARG); 1646a5f0fb15SPaul Saab break; 1647a5f0fb15SPaul Saab 1648a5f0fb15SPaul Saab case A_REMOVE_FILE: 1649a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1650a5f0fb15SPaul Saab break; 1651a5f0fb15SPaul Saab old_ifile = curr_ifile; 1652a5f0fb15SPaul Saab new_ifile = getoff_ifile(curr_ifile); 1653a5f0fb15SPaul Saab if (new_ifile == NULL_IFILE) 1654a5f0fb15SPaul Saab { 1655a5f0fb15SPaul Saab bell(); 1656a5f0fb15SPaul Saab break; 1657a5f0fb15SPaul Saab } 1658a5f0fb15SPaul Saab if (edit_ifile(new_ifile) != 0) 1659a5f0fb15SPaul Saab { 1660a5f0fb15SPaul Saab reedit_ifile(old_ifile); 1661a5f0fb15SPaul Saab break; 1662a5f0fb15SPaul Saab } 1663a5f0fb15SPaul Saab del_ifile(old_ifile); 1664a5f0fb15SPaul Saab break; 1665a5f0fb15SPaul Saab 1666a5f0fb15SPaul Saab case A_OPT_TOGGLE: 1667a5f0fb15SPaul Saab optflag = OPT_TOGGLE; 1668a5f0fb15SPaul Saab optgetname = FALSE; 1669a5f0fb15SPaul Saab mca_opt_toggle(); 1670a5f0fb15SPaul Saab c = getcc(); 1671a5f0fb15SPaul Saab goto again; 1672a5f0fb15SPaul Saab 1673a5f0fb15SPaul Saab case A_DISP_OPTION: 1674a5f0fb15SPaul Saab /* 1675a5f0fb15SPaul Saab * Report a flag setting. 1676a5f0fb15SPaul Saab */ 1677a5f0fb15SPaul Saab optflag = OPT_NO_TOGGLE; 1678a5f0fb15SPaul Saab optgetname = FALSE; 1679a5f0fb15SPaul Saab mca_opt_toggle(); 1680a5f0fb15SPaul Saab c = getcc(); 1681a5f0fb15SPaul Saab goto again; 1682a5f0fb15SPaul Saab 1683a5f0fb15SPaul Saab case A_FIRSTCMD: 1684a5f0fb15SPaul Saab /* 1685a5f0fb15SPaul Saab * Set an initial command for new files. 1686a5f0fb15SPaul Saab */ 1687a5f0fb15SPaul Saab start_mca(A_FIRSTCMD, "+", (void*)NULL, 0); 1688a5f0fb15SPaul Saab c = getcc(); 1689a5f0fb15SPaul Saab goto again; 1690a5f0fb15SPaul Saab 1691a5f0fb15SPaul Saab case A_SHELL: 1692a5f0fb15SPaul Saab /* 1693a5f0fb15SPaul Saab * Shell escape. 1694a5f0fb15SPaul Saab */ 1695a5f0fb15SPaul Saab #if SHELL_ESCAPE 1696a5f0fb15SPaul Saab if (secure) 1697a5f0fb15SPaul Saab { 1698a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1699a5f0fb15SPaul Saab break; 1700a5f0fb15SPaul Saab } 1701dd3bd0edSDimitry Andric start_mca(A_SHELL, "!", ml_shell, 0); 1702a5f0fb15SPaul Saab c = getcc(); 1703a5f0fb15SPaul Saab goto again; 1704a5f0fb15SPaul Saab #else 1705a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1706a5f0fb15SPaul Saab break; 1707a5f0fb15SPaul Saab #endif 1708a5f0fb15SPaul Saab 1709a5f0fb15SPaul Saab case A_SETMARK: 1710a5f0fb15SPaul Saab /* 1711a5f0fb15SPaul Saab * Set a mark. 1712a5f0fb15SPaul Saab */ 1713a5f0fb15SPaul Saab if (ch_getflags() & CH_HELPFILE) 1714a5f0fb15SPaul Saab break; 1715a5f0fb15SPaul Saab start_mca(A_SETMARK, "mark: ", (void*)NULL, 0); 1716a5f0fb15SPaul Saab c = getcc(); 171789dd99dcSXin LI if (c == erase_char || c == erase2_char || 171889dd99dcSXin LI c == kill_char || c == '\n' || c == '\r') 1719a5f0fb15SPaul Saab break; 1720a5f0fb15SPaul Saab setmark(c); 1721a5f0fb15SPaul Saab break; 1722a5f0fb15SPaul Saab 1723a5f0fb15SPaul Saab case A_GOMARK: 1724a5f0fb15SPaul Saab /* 1725a5f0fb15SPaul Saab * Go to a mark. 1726a5f0fb15SPaul Saab */ 1727a5f0fb15SPaul Saab start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0); 1728a5f0fb15SPaul Saab c = getcc(); 172989dd99dcSXin LI if (c == erase_char || c == erase2_char || 173089dd99dcSXin LI c == kill_char || c == '\n' || c == '\r') 1731a5f0fb15SPaul Saab break; 17327374caaaSXin LI cmd_exec(); 1733a5f0fb15SPaul Saab gomark(c); 1734a5f0fb15SPaul Saab break; 1735a5f0fb15SPaul Saab 1736a5f0fb15SPaul Saab case A_PIPE: 1737a5f0fb15SPaul Saab #if PIPEC 1738a5f0fb15SPaul Saab if (secure) 1739a5f0fb15SPaul Saab { 1740a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1741a5f0fb15SPaul Saab break; 1742a5f0fb15SPaul Saab } 1743a5f0fb15SPaul Saab start_mca(A_PIPE, "|mark: ", (void*)NULL, 0); 1744a5f0fb15SPaul Saab c = getcc(); 174589dd99dcSXin LI if (c == erase_char || c == erase2_char || c == kill_char) 1746a5f0fb15SPaul Saab break; 1747a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 1748a5f0fb15SPaul Saab c = '.'; 1749a5f0fb15SPaul Saab if (badmark(c)) 1750a5f0fb15SPaul Saab break; 1751a5f0fb15SPaul Saab pipec = c; 1752dd3bd0edSDimitry Andric start_mca(A_PIPE, "!", ml_shell, 0); 1753a5f0fb15SPaul Saab c = getcc(); 1754a5f0fb15SPaul Saab goto again; 1755a5f0fb15SPaul Saab #else 1756a5f0fb15SPaul Saab error("Command not available", NULL_PARG); 1757a5f0fb15SPaul Saab break; 1758a5f0fb15SPaul Saab #endif 1759a5f0fb15SPaul Saab 1760a5f0fb15SPaul Saab case A_B_BRACKET: 1761a5f0fb15SPaul Saab case A_F_BRACKET: 1762a5f0fb15SPaul Saab start_mca(action, "Brackets: ", (void*)NULL, 0); 1763a5f0fb15SPaul Saab c = getcc(); 1764a5f0fb15SPaul Saab goto again; 1765a5f0fb15SPaul Saab 1766a5f0fb15SPaul Saab case A_LSHIFT: 17678fd4165cSPaul Saab if (number > 0) 17688fd4165cSPaul Saab shift_count = number; 17698fd4165cSPaul Saab else 177015596da4SPaul Saab number = (shift_count > 0) ? 177115596da4SPaul Saab shift_count : sc_width / 2; 1772a5f0fb15SPaul Saab if (number > hshift) 1773a5f0fb15SPaul Saab number = hshift; 1774a5f0fb15SPaul Saab hshift -= number; 1775a5f0fb15SPaul Saab screen_trashed = 1; 1776a5f0fb15SPaul Saab break; 1777a5f0fb15SPaul Saab 1778a5f0fb15SPaul Saab case A_RSHIFT: 17798fd4165cSPaul Saab if (number > 0) 17808fd4165cSPaul Saab shift_count = number; 17818fd4165cSPaul Saab else 178215596da4SPaul Saab number = (shift_count > 0) ? 178315596da4SPaul Saab shift_count : sc_width / 2; 1784a5f0fb15SPaul Saab hshift += number; 1785a5f0fb15SPaul Saab screen_trashed = 1; 1786a5f0fb15SPaul Saab break; 1787a5f0fb15SPaul Saab 1788*f6b74a7dSXin LI case A_LLSHIFT: 1789*f6b74a7dSXin LI hshift = 0; 1790*f6b74a7dSXin LI screen_trashed = 1; 1791*f6b74a7dSXin LI break; 1792*f6b74a7dSXin LI 1793*f6b74a7dSXin LI case A_RRSHIFT: 1794*f6b74a7dSXin LI hshift = rrshift(); 1795*f6b74a7dSXin LI screen_trashed = 1; 1796*f6b74a7dSXin LI break; 1797*f6b74a7dSXin LI 1798a5f0fb15SPaul Saab case A_PREFIX: 1799a5f0fb15SPaul Saab /* 1800a5f0fb15SPaul Saab * The command is incomplete (more chars are needed). 1801a5f0fb15SPaul Saab * Display the current char, so the user knows 1802a5f0fb15SPaul Saab * what's going on, and get another character. 1803a5f0fb15SPaul Saab */ 1804a5f0fb15SPaul Saab if (mca != A_PREFIX) 1805a5f0fb15SPaul Saab { 1806a5f0fb15SPaul Saab cmd_reset(); 1807a5f0fb15SPaul Saab start_mca(A_PREFIX, " ", (void*)NULL, 1808a5f0fb15SPaul Saab CF_QUIT_ON_ERASE); 1809a5f0fb15SPaul Saab (void) cmd_char(c); 1810a5f0fb15SPaul Saab } 1811a5f0fb15SPaul Saab c = getcc(); 1812a5f0fb15SPaul Saab goto again; 1813a5f0fb15SPaul Saab 1814a5f0fb15SPaul Saab case A_NOACTION: 1815a5f0fb15SPaul Saab break; 1816a5f0fb15SPaul Saab 1817a5f0fb15SPaul Saab default: 1818a5f0fb15SPaul Saab bell(); 1819a5f0fb15SPaul Saab break; 1820a5f0fb15SPaul Saab } 1821a5f0fb15SPaul Saab } 1822a5f0fb15SPaul Saab } 1823