📄 vi_mode.c
字号:
if (!member (c, vi_motion)) { if (digit_p (c)) { save = rl_numeric_arg; rl_numeric_arg = digit_value (c); rl_digit_loop1 (); rl_numeric_arg *= save; c = rl_read_key (); /* real command */ *nextkey = c; } else if (key == c && (key == 'd' || key == 'y' || key == 'c')) { rl_mark = rl_end; rl_beg_of_line (); _rl_vi_last_motion = c; return (0); } else return (-1); } _rl_vi_last_motion = c; /* Append a blank character temporarily so that the motion routines work right at the end of the line. */ old_end = rl_end; rl_line_buffer[rl_end++] = ' '; rl_line_buffer[rl_end] = '\0'; _rl_dispatch (c, _rl_keymap); /* Remove the blank that we added. */ rl_end = old_end; rl_line_buffer[rl_end] = '\0'; if (rl_point > rl_end) rl_point = rl_end; /* No change in position means the command failed. */ if (rl_mark == rl_point) return (-1); /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next word. If we are not at the end of the line, and we are on a non-whitespace character, move back one (presumably to whitespace). */ if ((to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark && !whitespace (rl_line_buffer[rl_point])) rl_point--; /* If cw or cW, back up to the end of a word, so the behaviour of ce or cE is the actual result. Brute-force, no subtlety. */ if (key == 'c' && rl_point >= rl_mark && (to_upper (c) == 'W')) { /* Don't move farther back than where we started. */ while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point])) rl_point--; /* Posix.2 says that if cw or cW moves the cursor towards the end of the line, the character under the cursor should be deleted. */ if (rl_point == rl_mark) rl_point++; else { /* Move past the end of the word so that the kill doesn't remove the last letter of the previous word. Only do this if we are not at the end of the line. */ if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point])) rl_point++; } } if (rl_mark < rl_point) exchange (rl_point, rl_mark); return (0);}/* A simplified loop for vi. Don't dispatch key at end. Don't recognize minus sign? */static intrl_digit_loop1 (){ int key, c; while (1) { rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0); key = c = rl_read_key (); if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) { rl_numeric_arg *= 4; continue; } c = UNMETA (c); if (digit_p (c)) { if (rl_explicit_arg) rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c); else rl_numeric_arg = digit_value (c); rl_explicit_arg = 1; } else { rl_clear_message (); rl_stuff_char (key); break; } } return (0);}rl_vi_delete_to (count, key) int count, key;{ int c; if (uppercase_p (key)) rl_stuff_char ('$'); else if (vi_redoing) rl_stuff_char (_rl_vi_last_motion); if (rl_vi_domove (key, &c)) { ding (); return -1; } /* These are the motion commands that do not require adjusting the mark. */ if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end)) rl_mark++; rl_kill_text (rl_point, rl_mark); return (0);}rl_vi_change_to (count, key) int count, key;{ int c, start_pos; if (uppercase_p (key)) rl_stuff_char ('$'); else if (vi_redoing) rl_stuff_char (_rl_vi_last_motion); start_pos = rl_point; if (rl_vi_domove (key, &c)) { ding (); return -1; } /* These are the motion commands that do not require adjusting the mark. c[wW] are handled by special-case code in rl_vi_domove(), and already leave the mark at the correct location. */ if ((strchr (" l|hwW^0%bB", c) == 0) && (rl_mark < rl_end)) rl_mark++; /* The cursor never moves with c[wW]. */ if ((to_upper (c) == 'W') && rl_point < start_pos) rl_point = start_pos; rl_kill_text (rl_point, rl_mark); rl_begin_undo_group (); _rl_vi_doing_insert = 1; _rl_vi_set_last (key, count, rl_arg_sign); rl_vi_insertion_mode (); return (0);}rl_vi_yank_to (count, key) int count, key;{ int c, save = rl_point; if (uppercase_p (key)) rl_stuff_char ('$'); if (rl_vi_domove (key, &c)) { ding (); return -1; } /* These are the motion commands that do not require adjusting the mark. */ if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end)) rl_mark++; rl_begin_undo_group (); rl_kill_text (rl_point, rl_mark); rl_end_undo_group (); rl_do_undo (); rl_point = save; return (0);}rl_vi_delete (count, key) int count, key;{ int end; if (rl_end == 0) { ding (); return -1; } end = rl_point + count; if (end >= rl_end) end = rl_end; rl_kill_text (rl_point, end); if (rl_point > 0 && rl_point == rl_end) rl_backward (1); return (0);}/* Turn the current line into a comment in shell history. A K*rn shell style function. */rl_vi_comment (count, key) int count, key;{ rl_beg_of_line (); if (rl_vi_comment_begin != (char *)NULL) rl_insert_text (rl_vi_comment_begin); else rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */ rl_redisplay (); rl_newline (1, '\010'); return (0);}rl_vi_first_print (count, key) int count, key;{ return (rl_back_to_indent ());}rl_back_to_indent (ignore1, ignore2) int ignore1, ignore2;{ rl_beg_of_line (); while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) rl_point++; return (0);}/* NOTE: it is necessary that opposite directions are inverses */#define FTO 1 /* forward to */#define BTO -1 /* backward to */#define FFIND 2 /* forward find */#define BFIND -2 /* backward find */rl_vi_char_search (count, key) int count, key;{ static char target; static int orig_dir, dir; int pos; if (key == ';' || key == ',') dir = (key == ';' ? orig_dir : -orig_dir); else { if (vi_redoing) target = _rl_vi_last_search_char; else _rl_vi_last_search_char = target = rl_getc (rl_instream); switch (key) { case 't': orig_dir = dir = FTO; break; case 'T': orig_dir = dir = BTO; break; case 'f': orig_dir = dir = FFIND; break; case 'F': orig_dir = dir = BFIND; break; } } pos = rl_point; while (count--) { if (dir < 0) { if (pos == 0) { ding (); return -1; } pos--; do { if (rl_line_buffer[pos] == target) { if (dir == BTO) rl_point = pos + 1; else rl_point = pos; break; } } while (pos--); if (pos < 0) { ding (); return -1; } } else { /* dir > 0 */ if (pos >= rl_end) { ding (); return -1; } pos++; do { if (rl_line_buffer[pos] == target) { if (dir == FTO) rl_point = pos - 1; else rl_point = pos; break; } } while (++pos < rl_end); if (pos >= (rl_end - 1)) { ding (); return -1; } } } return (0);}/* Match brackets */rl_vi_match (ignore, key) int ignore, key;{ int count = 1, brack, pos; pos = rl_point; if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) { while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && rl_point < rl_end - 1) rl_forward (1); if (brack <= 0) { rl_point = pos; ding (); return -1; } } pos = rl_point; if (brack < 0) { while (count) { if (--pos >= 0) { int b = rl_vi_bracktype (rl_line_buffer[pos]); if (b == -brack) count--; else if (b == brack) count++; } else { ding (); return -1; } } } else { /* brack > 0 */ while (count) { if (++pos < rl_end) { int b = rl_vi_bracktype (rl_line_buffer[pos]); if (b == -brack) count--; else if (b == brack) count++; } else { ding (); return -1; } } } rl_point = pos; return (0);}intrl_vi_bracktype (c) int c;{ switch (c) { case '(': return 1; case ')': return -1; case '[': return 2; case ']': return -2; case '{': return 3; case '}': return -3; default: return 0; }}rl_vi_change_char (count, key) int count, key;{ int c; if (vi_redoing) c = _rl_vi_last_replacement; else _rl_vi_last_replacement = c = rl_getc (rl_instream); if (c == '\033' || c == CTRL ('C')) return -1; while (count-- && rl_point < rl_end) { rl_begin_undo_group (); rl_delete (1, c); rl_insert (1, c); if (count == 0) rl_backward (1); rl_end_undo_group (); } return (0);}rl_vi_subst (count, key) int count, key;{ rl_begin_undo_group (); if (uppercase_p (key)) { rl_beg_of_line (); rl_kill_line (1); } else rl_delete (count, key); rl_end_undo_group (); _rl_vi_set_last (key, count, rl_arg_sign); rl_begin_undo_group (); _rl_vi_doing_insert = 1; rl_vi_insertion_mode (); return (0);}rl_vi_overstrike (count, key) int count, key;{ int i; if (_rl_vi_doing_insert == 0) { _rl_vi_doing_insert = 1; rl_begin_undo_group (); } for (i = 0; i < count; i++) { vi_replace_count++; rl_begin_undo_group (); if (rl_point < rl_end) { rl_delete (1, key); rl_insert (1, key); } else rl_insert (1, key); rl_end_undo_group (); } return (0);}rl_vi_overstrike_delete (count) int count;{ int i, s; for (i = 0; i < count; i++) { if (vi_replace_count == 0) { ding (); break; } s = rl_point; if (rl_do_undo ()) vi_replace_count--; if (rl_point == s) rl_backward (1); } if (vi_replace_count == 0 && _rl_vi_doing_insert) { rl_end_undo_group (); rl_do_undo (); _rl_vi_doing_insert = 0; } return (0);}rl_vi_replace (count, key) int count, key;{ int i; vi_replace_count = 0; if (!vi_replace_map) { vi_replace_map = rl_make_bare_keymap (); for (i = ' '; i < 127; i++) vi_replace_map[i].function = rl_vi_overstrike; vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; vi_replace_map[ESC].function = rl_vi_movement_mode; vi_replace_map[RETURN].function = rl_newline; vi_replace_map[NEWLINE].function = rl_newline; /* If the normal vi insertion keymap has ^H bound to erase, do the same here. Probably should remove the assignment to RUBOUT up there, but I don't think it will make a difference in real life. */ if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC && vi_insertion_keymap[CTRL ('H')].function == rl_rubout) vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; } _rl_keymap = vi_replace_map; return (0);}#if 0/* Try to complete the word we are standing on or the word that ends with the previous character. A space matches everything. Word delimiters are space and ;. */rl_vi_possible_completions(){ int save_pos = rl_point; if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';') { while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';') rl_point++; } else if (rl_line_buffer[rl_point - 1] == ';') { ding (); return (0); } rl_possible_completions (); rl_point = save_pos; return (0);}#endif#if defined (STATIC_MALLOC)/* **************************************************************** *//* *//* xmalloc and xrealloc () *//* *//* **************************************************************** */static void memory_error_and_abort ();static char *xmalloc (bytes) int bytes;{ char *temp = (char *)malloc (bytes); if (!temp) memory_error_and_abort (); return (temp);}static char *xrealloc (pointer, bytes) char *pointer; int bytes;{ char *temp; if (!pointer) temp = (char *)xmalloc (bytes); else temp = (char *)realloc (pointer, bytes); if (!temp) memory_error_and_abort (); return (temp);}static voidmemory_error_and_abort (){ fprintf (stderr, "readline: Out of virtual memory!\n"); abort ();}#endif /* STATIC_MALLOC */#endif /* VI_MODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -