📄 vi_mode.c
字号:
function. */ last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]); if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) || (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident)) rl_point--; while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) rl_point--; if (rl_point > 0) { if (_rl_isident (rl_line_buffer[rl_point])) while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point])); else while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) && !whitespace (rl_line_buffer[rl_point])); rl_point++; } } return (0);}intrl_vi_eword (count, ignore) int count, ignore;{ while (count-- && rl_point < rl_end - 1) { if (!whitespace (rl_line_buffer[rl_point])) rl_point++; while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) rl_point++; if (rl_point < rl_end) { if (_rl_isident (rl_line_buffer[rl_point])) while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point])); else while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point]) && !whitespace (rl_line_buffer[rl_point])); } rl_point--; } return (0);}intrl_vi_insert_beg (count, key) int count, key;{ rl_beg_of_line (1, key); rl_vi_insertion_mode (1, key); return (0);}intrl_vi_append_mode (count, key) int count, key;{ if (rl_point < rl_end) { if (MB_CUR_MAX == 1 || rl_byte_oriented) rl_point++; else { int point = rl_point; rl_forward_char (1, key); if (point == rl_point) rl_point = rl_end; } } rl_vi_insertion_mode (1, key); return (0);}intrl_vi_append_eol (count, key) int count, key;{ rl_end_of_line (1, key); rl_vi_append_mode (1, key); return (0);}/* What to do in the case of C-d. */intrl_vi_eof_maybe (count, c) int count, c;{ return (rl_newline (1, '\n'));}/* Insertion mode stuff. *//* Switching from one mode to the other really just involves switching keymaps. */intrl_vi_insertion_mode (count, key) int count, key;{ _rl_keymap = vi_insertion_keymap; _rl_vi_last_key_before_insert = key; return (0);}static void_rl_vi_save_insert (up) UNDO_LIST *up;{ int len, start, end; if (up == 0) { if (vi_insert_buffer_size >= 1) vi_insert_buffer[0] = '\0'; return; } start = up->start; end = up->end; len = end - start + 1; if (len >= vi_insert_buffer_size) { vi_insert_buffer_size += (len + 32) - (len % 32); vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size); } strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); vi_insert_buffer[len-1] = '\0';} void_rl_vi_done_inserting (){ if (_rl_vi_doing_insert) { /* The `C', `s', and `S' commands set this. */ rl_end_undo_group (); /* Now, the text between rl_undo_list->next->start and rl_undo_list->next->end is what was inserted while in insert mode. It gets copied to VI_INSERT_BUFFER because it depends on absolute indices into the line which may change (though they probably will not). */ _rl_vi_doing_insert = 0; _rl_vi_save_insert (rl_undo_list->next); vi_continued_command = 1; } else { if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list) _rl_vi_save_insert (rl_undo_list); /* XXX - Other keys probably need to be checked. */ else if (_rl_vi_last_key_before_insert == 'C') rl_end_undo_group (); while (_rl_undo_group_level > 0) rl_end_undo_group (); vi_continued_command = 0; }}intrl_vi_movement_mode (count, key) int count, key;{ if (rl_point > 0) rl_backward_char (1, key); _rl_keymap = vi_movement_keymap; _rl_vi_done_inserting (); return (0);}intrl_vi_arg_digit (count, c) int count, c;{ if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) return (rl_beg_of_line (1, c)); else return (rl_digit_argument (count, c));}/* Change the case of the next COUNT characters. */#if defined (HANDLE_MULTIBYTE)static int_rl_vi_change_mbchar_case (count) int count;{ wchar_t wc; char mb[MB_LEN_MAX+1]; int mblen; mbstate_t ps; memset (&ps, 0, sizeof (mbstate_t)); if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0) count--; while (count-- && rl_point < rl_end) { mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps); if (iswupper (wc)) wc = towlower (wc); else if (iswlower (wc)) wc = towupper (wc); else { /* Just skip over chars neither upper nor lower case */ rl_forward_char (1, 0); continue; } /* Vi is kind of strange here. */ if (wc) { mblen = wcrtomb (mb, wc, &ps); if (mblen >= 0) mb[mblen] = '\0'; rl_begin_undo_group (); rl_delete (1, 0); rl_insert_text (mb); rl_end_undo_group (); rl_vi_check (); } else rl_forward_char (1, 0); } return 0;}#endifintrl_vi_change_case (count, ignore) int count, ignore;{ int c, p; /* Don't try this on an empty line. */ if (rl_point >= rl_end) return (0); c = 0;#if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) return (_rl_vi_change_mbchar_case (count));#endif while (count-- && rl_point < rl_end) { if (_rl_uppercase_p (rl_line_buffer[rl_point])) c = _rl_to_lower (rl_line_buffer[rl_point]); else if (_rl_lowercase_p (rl_line_buffer[rl_point])) c = _rl_to_upper (rl_line_buffer[rl_point]); else { /* Just skip over characters neither upper nor lower case. */ rl_forward_char (1, c); continue; } /* Vi is kind of strange here. */ if (c) { p = rl_point; rl_begin_undo_group (); rl_vi_delete (1, c); if (rl_point < p) /* Did we retreat at EOL? */ rl_point++; _rl_insert_char (1, c); rl_end_undo_group (); rl_vi_check (); } else rl_forward_char (1, c); } return (0);}intrl_vi_put (count, key) int count, key;{ if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end)) rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); while (count--) rl_yank (1, key); rl_backward_char (1, key); return (0);}intrl_vi_check (){ if (rl_point && rl_point == rl_end) { if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); else rl_point--; } return (0);}intrl_vi_column (count, key) int count, key;{ if (count > rl_end) rl_end_of_line (1, key); else rl_point = count - 1; return (0);}intrl_vi_domove (key, nextkey) int key, *nextkey;{ int c, save; int old_end; rl_mark = rl_point; RL_SETSTATE(RL_STATE_MOREINPUT); c = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT); *nextkey = c; if (!member (c, vi_motion)) { if (_rl_digit_p (c)) { save = rl_numeric_arg; rl_numeric_arg = _rl_digit_value (c); rl_explicit_arg = 1; rl_digit_loop1 (); rl_numeric_arg *= save; RL_SETSTATE(RL_STATE_MOREINPUT); c = rl_read_key (); /* real command */ RL_UNSETSTATE(RL_STATE_MOREINPUT); *nextkey = c; } else if (key == c && (key == 'd' || key == 'y' || key == 'c')) { rl_mark = rl_end; rl_beg_of_line (1, c); _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 ((_rl_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 && (_rl_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) SWAP (rl_point, rl_mark); return (0);}/* A simplified loop for vi. Don't dispatch key at end. Don't recognize minus sign? Should this do rl_save_prompt/rl_restore_prompt? */static intrl_digit_loop1 (){ int key, c; RL_SETSTATE(RL_STATE_NUMERICARG); while (1) { if (rl_numeric_arg > 1000000) { rl_explicit_arg = rl_numeric_arg = 0; rl_ding (); rl_clear_message (); RL_UNSETSTATE(RL_STATE_NUMERICARG); return 1; } rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); RL_SETSTATE(RL_STATE_MOREINPUT); key = c = rl_read_key (); RL_UNSETSTATE(RL_STATE_MOREINPUT); if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) { rl_numeric_arg *= 4; continue; } c = UNMETA (c); if (_rl_digit_p (c)) { if (rl_explicit_arg) rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c); else rl_numeric_arg = _rl_digit_value (c); rl_explicit_arg = 1; } else { rl_clear_message (); rl_stuff_char (key); break; } } RL_UNSETSTATE(RL_STATE_NUMERICARG); return (0);}intrl_vi_delete_to (count, key) int count, key;{ int c; if (_rl_uppercase_p (key)) rl_stuff_char ('$'); else if (vi_redoing) rl_stuff_char (_rl_vi_last_motion); 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^0bB", c) == 0) && (rl_mark < rl_end)) rl_mark++; rl_kill_text (rl_point, rl_mark); return (0);}intrl_vi_change_to (count, key) int count, key;{ int c, start_pos; if (_rl_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)) { rl_ding ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -