📄 vi_mode.c
字号:
c = to_lower (rl_line_buffer[rl_point]); else if (lowercase_p (rl_line_buffer[rl_point])) c = to_upper (rl_line_buffer[rl_point]); /* Vi is kind of strange here. */ if (c) { rl_begin_undo_group (); rl_delete (1, c); rl_insert (1, c); rl_end_undo_group (); rl_vi_check (); } else rl_forward (1); }}rl_vi_put (count, key) int count, key;{ if (!uppercase_p (key) && (rl_point + 1 <= rl_end)) rl_point++; rl_yank (); rl_backward (1);}rl_vi_check (){ if (rl_point && rl_point == rl_end) rl_point--;}rl_vi_column (count){ if (count > rl_end) rl_end_of_line (); else rl_point = count - 1;}intrl_vi_domove (key, nextkey) int key, *nextkey;{ int c, save; int old_end, added_blank; added_blank = 0; rl_mark = rl_point; c = rl_read_key (); *nextkey = c; if (!member (c, vi_motion)) { if (digit (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 == 'd' && c == 'd') || (key == 'y' && c == 'y') || (key == 'c' && c == 'c')) { rl_mark = rl_end; rl_beg_of_line (); return (0); } else return (-1); } /* 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++] = ' '; /* This looks pretty bogus to me??? */ rl_line_buffer[rl_end] = '\0'; added_blank++; rl_dispatch (c, 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 - 1; /* 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 ((c == 'w' || c == 'W') && (rl_point < rl_end) && !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. Do the same thing for dw or dW. */ if (key == 'c' && (to_upper (c) == 'W')) { while (rl_point && 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? */rl_digit_loop1 (){ int key, c; while (1) { rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0); key = c = rl_read_key (); if (keymap[c].type == ISFUNC && keymap[c].function == rl_universal_argument) { rl_numeric_arg *= 4; continue; } c = UNMETA (c); if (numeric (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; } }}rl_vi_delete_to (count, key) int count, key;{ int c; if (uppercase_p (key)) rl_stuff_char ('$'); if (rl_vi_domove (key, &c)) { ding (); return; } if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end) rl_mark++; rl_kill_text (rl_point, rl_mark);}rl_vi_change_to (count, key) int count, key;{ int c; if (uppercase_p (key)) rl_stuff_char ('$'); if (rl_vi_domove (key, &c)) { ding (); return; } if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end) rl_mark++; rl_begin_undo_group (); vi_doing_insert = 1; rl_kill_text (rl_point, rl_mark); rl_vi_insertion_mode ();}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; } if ((c != 'l') && (c != '|') && (c != 'h') && 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;}rl_vi_delete (count){ int end; if (rl_end == 0) { ding (); return; } 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);}/* Turn the current line into a comment in shell history. A K*rn shell style function. */rl_vi_comment (){ rl_beg_of_line (); if (rl_vi_comment_begin != (char *)NULL) rl_insert_text (rl_vi_comment_begin); else rl_insert_text (": "); /* Default. */ rl_redisplay (); rl_newline (1, '\010');}rl_vi_first_print (){ rl_back_to_indent (0, 0);}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++;}/* 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 { 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; } 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; } } else { /* dir > 0 */ if (pos >= rl_end) { ding (); return; } 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; } } }}/* Match brackets */rl_vi_match (){ 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; } } 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; } } } 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; } } } rl_point = pos;}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; c = rl_getc (rl_instream); if (c == '\033' || c == CTRL ('C')) return; 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 (); }}rl_vi_subst (count, key) int count, key;{ rl_begin_undo_group (); vi_doing_insert = 1; if (uppercase_p (key)) { rl_beg_of_line (); rl_kill_line (1); } else rl_delete (count, key); rl_end_undo_group (); rl_vi_insertion_mode ();}rl_vi_overstrike (count, key) int count, key;{ int i; if (vi_doing_insert == 0) { 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 (); }}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 && vi_doing_insert) { rl_end_undo_group (); rl_do_undo (); vi_doing_insert = 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; } keymap = vi_replace_map;}/* * 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 (!index (" ;", rl_line_buffer[rl_point])) { while (!index(" ;", rl_line_buffer[++rl_point])) ; } else if (rl_line_buffer[rl_point-1] == ';') { ding (); return (0); } rl_possible_completions (); rl_point = save_pos; return (0);}#endif /* VI_MODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -