📄 command.c
字号:
* Restore the file we were originally viewing. */ (void) edit(curr_filename, 0);}/* * Main command processor. * Accept and execute commands until a quit command. */ public voidcommands(){ register int c; register int action; register char *cbuf; int save_search_type; char *s; char tbuf[2]; PARG parg; search_type = SRCH_FORW; scroll = (sc_height + 1) / 2; for (;;) { mca = 0; number = 0; optchar = '\0'; /* * See if any signals need processing. */ if (sigs) { psignals(); if (quitting) quit(-1); } /* * Display prompt and accept a character. */ cmd_reset(); prompt(); if (sigs) continue; c = getcc(); again: if (sigs) continue; /* * If we are in a multicharacter command, call mca_char. * Otherwise we call cmd_decode to determine the * action to be performed. */ if (mca) switch (mca_char(c)) { case MCA_MORE: /* * Need another character. */ c = getcc(); goto again; case MCA_DONE: /* * Command has been handled by mca_char. * Start clean with a prompt. */ continue; case NO_MCA: /* * Not a multi-char command * (at least, not anymore). */ break; } /* * Decode the command character and decide what to do. */ if (mca) { /* * We're in a multichar command. * Add the character to the command buffer * and display it on the screen. * If the user backspaces past the start * of the line, abort the command. */ if (cmd_char(c) || len_cmdbuf() == 0) continue; cbuf = get_cmdbuf(); } else { /* * Don't use cmd_char if we're starting fresh * at the beginning of a command, because we * don't want to echo the command until we know * it is a multichar command. We also don't * want erase_char/kill_char to be treated * as line editing characters. */ tbuf[0] = c; tbuf[1] = '\0'; cbuf = tbuf; } s = NULL; action = cmd_decode(cbuf, &s); /* * If an "extra" string was returned, * process it as a string of command characters. */ if (s != NULL) ungetsc(s); /* * Clear the cmdbuf string. * (But not if we're in the prefix of a command, * because the partial command string is kept there.) */ if (action != A_PREFIX) cmd_reset(); switch (action) { case A_DIGIT: /* * First digit of a number. */ start_mca(A_DIGIT, ":"); goto again; case A_F_WINDOW: /* * Forward one window (and set the window size). */ if (number > 0) swindow = number; /* FALLTHRU */ case A_F_SCREEN: /* * Forward one screen. */ if (number <= 0) number = swindow; cmd_exec(); forward(number, 0, 1); break; case A_B_WINDOW: /* * Backward one window (and set the window size). */ if (number > 0) swindow = number; /* FALLTHRU */ case A_B_SCREEN: /* * Backward one screen. */ if (number <= 0) number = swindow; cmd_exec(); backward(number, 0, 1); break; case A_F_LINE: /* * Forward N (default 1) line. */ if (number <= 0) number = 1; cmd_exec(); forward(number, 0, 0); break; case A_B_LINE: /* * Backward N (default 1) line. */ if (number <= 0) number = 1; cmd_exec(); backward(number, 0, 0); break; case A_FF_LINE: /* * Force forward N (default 1) line. */ if (number <= 0) number = 1; cmd_exec(); forward(number, 1, 0); break; case A_BF_LINE: /* * Force backward N (default 1) line. */ if (number <= 0) number = 1; cmd_exec(); backward(number, 1, 0); break; case A_F_FOREVER: /* * Forward forever, ignoring EOF. */ cmd_exec(); jump_forw(); ignore_eoi = 1; hit_eof = 0; while (sigs == 0) forward(1, 0, 0); ignore_eoi = 0; break; case A_F_SCROLL: /* * Forward N lines * (default same as last 'd' or 'u' command). */ if (number > 0) scroll = number; cmd_exec(); forward(scroll, 0, 0); break; case A_B_SCROLL: /* * Forward N lines * (default same as last 'd' or 'u' command). */ if (number > 0) scroll = number; cmd_exec(); backward(scroll, 0, 0); break; case A_FREPAINT: /* * Flush buffers, then repaint screen. * Don't flush the buffers on a pipe! */ ch_flush(); if (!ispipe) clr_linenum(); /* FALLTHRU */ case A_REPAINT: /* * Repaint screen. */ cmd_exec(); repaint(); break; case A_GOLINE: /* * Go to line N, default beginning of file. */ if (number <= 0) number = 1; cmd_exec(); jump_back(number); break; case A_PERCENT: /* * Go to a specified percentage into the file. */ if (number < 0) number = 0; if (number > 100) number = 100; cmd_exec(); jump_percent(number); break; case A_GOEND: /* * Go to line N, default end of file. */ cmd_exec(); if (number <= 0) jump_forw(); else jump_back(number); break; case A_GOPOS: /* * Go to a specified byte position in the file. */ cmd_exec(); if (number < 0) number = 0; jump_line_loc((POSITION)number, jump_sline); break; case A_STAT: /* * Print file name, etc. */ cmd_exec(); parg.p_string = eq_message(); error("%s", &parg); break; case A_VERSION: /* * Print version number, without the "@(#)". */ cmd_exec(); parg.p_string = version+4; error("%s", &parg); break; case A_QUIT: /* * Exit. */ quit(0);/* * Define abbreviation for a commonly used sequence below. */#define DO_SEARCH() if (number <= 0) number = 1; \ mca_search(); \ cmd_exec(); \ multi_search((char *)NULL, number); case A_F_SEARCH: /* * Search forward for a pattern. * Get the first char of the pattern. */ search_type = SRCH_FORW; if (number <= 0) number = 1; mca_search(); c = getcc(); goto again; case A_B_SEARCH: /* * Search backward for a pattern. * Get the first char of the pattern. */ search_type = SRCH_BACK; if (number <= 0) number = 1; mca_search(); c = getcc(); goto again; case A_AGAIN_SEARCH: /* * Repeat previous search. */ DO_SEARCH(); break; case A_T_AGAIN_SEARCH: /* * Repeat previous search, multiple files. */ search_type |= SRCH_PAST_EOF; DO_SEARCH(); break; case A_REVERSE_SEARCH: /* * Repeat previous search, in reverse direction. */ save_search_type = search_type; search_type = SRCH_REVERSE(search_type); DO_SEARCH(); search_type = save_search_type; break; case A_T_REVERSE_SEARCH: /* * Repeat previous search, * multiple files in reverse direction. */ save_search_type = search_type; search_type = SRCH_REVERSE(search_type); search_type |= SRCH_PAST_EOF; DO_SEARCH(); search_type = save_search_type; break; case A_HELP: /* * Help. */ if (nohelp) { bell(); break; } lower_left(); clear_eol(); putstr("help"); cmd_exec(); help(); break; case A_EXAMINE: /* * Edit a new file. Get the filename. */ start_mca(A_EXAMINE, "Examine: "); c = getcc(); goto again; case A_VISUAL: /* * Invoke an editor on the input file. */#if EDITOR if (strcmp(get_filename(curr_ifile), "-") == 0) { error("Cannot edit standard input", NULL_PARG); break; } /* * Expand the editor prototype string * and pass it to the system to execute. */ cmd_exec(); lsystem(pr_expand(editproto, 0)); /* * Re-edit the file, since data may have changed. * Some editors even recreate the file, so flushing * buffers is not sufficient. */ (void) edit(get_filename(curr_ifile), 0); break;#else error("Command not available", NULL_PARG); break;#endif case A_NEXT_FILE: /* * Examine next file. */ if (number <= 0) number = 1; if (edit_next(number)) { if (quit_at_eof && hit_eof) quit(0); parg.p_string = (number > 1) ? "(N-th) " : ""; error("No %snext file", &parg); } break; case A_PREV_FILE: /* * Examine previous file. */ if (number <= 0) number = 1; if (edit_prev(number)) { parg.p_string = (number > 1) ? "(N-th) " : ""; error("No %sprevious file", &parg); } break; case A_INDEX_FILE: /* * Examine a particular file. */ if (number <= 0) number = 1; if (edit_index(number)) error("No such file", NULL_PARG); break; case A_OPT_TOGGLE: start_mca(A_OPT_TOGGLE, "-"); optflag = OPT_TOGGLE; c = getcc(); goto again; case A_DISP_OPTION: /* * Report a flag setting. */ start_mca(A_DISP_OPTION, "_"); c = getcc(); if (c == erase_char || c == kill_char) break; toggle_option(c, "", OPT_NO_TOGGLE); break; case A_FIRSTCMD: /* * Set an initial command for new files. */ start_mca(A_FIRSTCMD, "+"); c = getcc(); goto again; case A_SHELL: /* * Shell escape. */#if SHELL_ESCAPE start_mca(A_SHELL, "!"); c = getcc(); goto again;#else error("Command not available", NULL_PARG); break;#endif case A_SETMARK: /* * Set a mark. */ start_mca(A_SETMARK, "mark: "); c = getcc(); if (c == erase_char || c == kill_char || c == '\n' || c == '\r') break; setmark(c); break; case A_GOMARK: /* * Go to a mark. */ start_mca(A_GOMARK, "goto mark: "); c = getcc(); if (c == erase_char || c == kill_char || c == '\n' || c == '\r') break; gomark(c); break;#if PIPEC case A_PIPE: start_mca(A_PIPE, "|mark: "); c = getcc(); if (c == erase_char || c == kill_char) break; if (c == '\n' || c == '\r') c = '.'; if (badmark(c)) break; pipec = c; start_mca(A_PIPE, "!"); c = getcc(); goto again;#endif case A_B_BRACKET: case A_F_BRACKET: start_mca(action, "Brackets: "); c = getcc(); goto again; case A_PREFIX: /* * The command is incomplete (more chars are needed). * Display the current char, so the user knows * what's going on, and get another character. */ if (mca != A_PREFIX) { start_mca(A_PREFIX, " "); cmd_reset(); (void) cmd_char(c); } c = getcc(); goto again; case A_NOACTION: break; default: bell(); break; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -