📄 vi_mode.c
字号:
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^0bB", c) == 0) && (rl_mark < rl_end)) rl_mark++; /* The cursor never moves with c[wW]. */ if ((_rl_to_upper (c) == 'W') && rl_point < start_pos) rl_point = start_pos; if (vi_redoing) { if (vi_insert_buffer && *vi_insert_buffer) rl_begin_undo_group (); rl_delete_text (rl_point, rl_mark); if (vi_insert_buffer && *vi_insert_buffer) { rl_insert_text (vi_insert_buffer); rl_end_undo_group (); } } else { rl_begin_undo_group (); /* to make the `u' command work */ rl_kill_text (rl_point, rl_mark); /* `C' does not save the text inserted for undoing or redoing. */ if (_rl_uppercase_p (key) == 0) _rl_vi_doing_insert = 1; rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign); } return (0);}intrl_vi_yank_to (count, key) int count, key;{ int c, save = rl_point; if (_rl_uppercase_p (key)) rl_stuff_char ('$'); if (rl_vi_domove (key, &c)) { rl_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);}intrl_vi_delete (count, key) int count, key;{ int end; if (rl_end == 0) { rl_ding (); return -1; } if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); else 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_char (1, key); return (0);}intrl_vi_back_to_indent (count, key) int count, key;{ rl_beg_of_line (1, key); while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) rl_point++; return (0);}intrl_vi_first_print (count, key) int count, key;{ return (rl_vi_back_to_indent (1, key));}intrl_vi_char_search (count, key) int count, key;{#if defined (HANDLE_MULTIBYTE) static char *target; static int mb_len;#else static char target;#endif static int orig_dir, dir; if (key == ';' || key == ',') dir = key == ';' ? orig_dir : -orig_dir; else { if (vi_redoing)#if defined (HANDLE_MULTIBYTE) target = _rl_vi_last_search_mbchar;#else target = _rl_vi_last_search_char;#endif else {#if defined (HANDLE_MULTIBYTE) mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); target = _rl_vi_last_search_mbchar;#else RL_SETSTATE(RL_STATE_MOREINPUT); _rl_vi_last_search_char = target = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT);#endif } 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; } }#if defined (HANDLE_MULTIBYTE) return (_rl_char_search_internal (count, dir, target, mb_len));#else return (_rl_char_search_internal (count, dir, target));#endif}/* Match brackets */intrl_vi_match (ignore, key) int ignore, key;{ int count = 1, brack, pos, tmp, pre; pos = rl_point; if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) { if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) { pre = rl_point; rl_forward_char (1, key); if (pre == rl_point) break; } } else while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && rl_point < rl_end - 1) rl_forward_char (1, key); if (brack <= 0) { rl_point = pos; rl_ding (); return -1; } } pos = rl_point; if (brack < 0) { while (count) { tmp = pos; if (MB_CUR_MAX == 1 || rl_byte_oriented) pos--; else { pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); if (tmp == pos) pos--; } if (pos >= 0) { int b = rl_vi_bracktype (rl_line_buffer[pos]); if (b == -brack) count--; else if (b == brack) count++; } else { rl_ding (); return -1; } } } else { /* brack > 0 */ while (count) { if (MB_CUR_MAX == 1 || rl_byte_oriented) pos++; else pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY); if (pos < rl_end) { int b = rl_vi_bracktype (rl_line_buffer[pos]); if (b == -brack) count--; else if (b == brack) count++; } else { rl_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; }}/* XXX - think about reading an entire mbchar with _rl_read_mbchar and inserting it in one bunch instead of the loop below (like in rl_vi_char_search or _rl_vi_change_mbchar_case). Set c to mbchar[0] for test against 033 or ^C. Make sure that _rl_read_mbchar does this right. */intrl_vi_change_char (count, key) int count, key;{ int c, p; if (vi_redoing) c = _rl_vi_last_replacement; else { RL_SETSTATE(RL_STATE_MOREINPUT); _rl_vi_last_replacement = c = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT); } if (c == '\033' || c == CTRL ('C')) return -1; rl_begin_undo_group (); while (count-- && rl_point < rl_end) { p = rl_point; rl_vi_delete (1, c);#if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) while (_rl_insert_char (1, c)) { RL_SETSTATE (RL_STATE_MOREINPUT); c = rl_read_key (); RL_UNSETSTATE (RL_STATE_MOREINPUT); } else#endif { if (rl_point < p) /* Did we retreat at EOL? */ rl_point++; _rl_insert_char (1, c); } } rl_end_undo_group (); return (0);}intrl_vi_subst (count, key) int count, key;{ /* If we are redoing, rl_vi_change_to will stuff the last motion char */ if (vi_redoing == 0) rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */ return (rl_vi_change_to (count, 'c'));}intrl_vi_overstrike (count, key) int count, key;{ if (_rl_vi_doing_insert == 0) { _rl_vi_doing_insert = 1; rl_begin_undo_group (); } if (count > 0) { _rl_overwrite_char (count, key); vi_replace_count += count; } return (0);}intrl_vi_overstrike_delete (count, key) int count, key;{ int i, s; for (i = 0; i < count; i++) { if (vi_replace_count == 0) { rl_ding (); break; } s = rl_point; if (rl_do_undo ()) vi_replace_count--; if (rl_point == s) rl_backward_char (1, key); } if (vi_replace_count == 0 && _rl_vi_doing_insert) { rl_end_undo_group (); rl_do_undo (); _rl_vi_doing_insert = 0; } return (0);}intrl_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 < KEYMAP_SIZE; 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 ;. */intrl_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] == ';') { rl_ding (); return (0); } rl_possible_completions (); rl_point = save_pos; return (0);}#endif/* Functions to save and restore marks. */intrl_vi_set_mark (count, key) int count, key;{ int ch; RL_SETSTATE(RL_STATE_MOREINPUT); ch = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT); if (ch < 'a' || ch > 'z') { rl_ding (); return -1; } ch -= 'a'; vi_mark_chars[ch] = rl_point; return 0;}intrl_vi_goto_mark (count, key) int count, key;{ int ch; RL_SETSTATE(RL_STATE_MOREINPUT); ch = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT); if (ch == '`') { rl_point = rl_mark; return 0; } else if (ch < 'a' || ch > 'z') { rl_ding (); return -1; } ch -= 'a'; if (vi_mark_chars[ch] == -1) { rl_ding (); return -1; } rl_point = vi_mark_chars[ch]; return 0;}#endif /* VI_MODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -