📄 readline.c
字号:
rl_delete_text (from, to) int from, to;{ register char *text; register int diff, i; /* Fix it if the caller is confused. */ if (from > to) { int t = from; from = to; to = t; } if (to > rl_end) to = rl_end; text = rl_copy_text (from, to); /* Some versions of strncpy() can't handle overlapping arguments. */ diff = to - from; for (i = from; i < rl_end - diff; i++) the_line[i] = the_line[i + diff]; /* Remember how to undo this delete. */ if (!doing_an_undo) rl_add_undo (UNDO_DELETE, from, to, text); else free (text); rl_end -= diff; the_line[rl_end] = '\0'; return (diff);}/* **************************************************************** *//* *//* Readline character functions *//* *//* **************************************************************** *//* This is not a gap editor, just a stupid line input routine. No hair is involved in writing any of the functions, and none should be. *//* Note that: rl_end is the place in the string that we would place '\0'; i.e., it is always safe to place '\0' there. rl_point is the place in the string where the cursor is. Sometimes this is the same as rl_end. Any command that is called interactively receives two arguments. The first is a count: the numeric arg pased to this command. The second is the key which invoked this command.*//* **************************************************************** *//* *//* Movement Commands *//* *//* **************************************************************** *//* Note that if you `optimize' the display for these functions, you cannot use said functions in other functions which do not do optimizing display. I.e., you will have to update the data base for rl_redisplay, and you might as well let rl_redisplay do that job. *//* Move forward COUNT characters. */rl_forward (count, key) int count, key;{ if (count < 0) rl_backward (-count); else if (count > 0) { int end = rl_point + count;#if defined (VI_MODE) int lend = rl_end - (rl_editing_mode == vi_mode);#else int lend = rl_end;#endif if (end > lend) { rl_point = lend; ding (); } else rl_point = end; } return 0;}/* Move backward COUNT characters. */rl_backward (count, key) int count, key;{ if (count < 0) rl_forward (-count); else if (count > 0) { if (rl_point < count) { rl_point = 0; ding (); } else rl_point -= count; } return 0;}/* Move to the beginning of the line. */rl_beg_of_line (count, key) int count, key;{ rl_point = 0; return 0;}/* Move to the end of the line. */rl_end_of_line (count, key) int count, key;{ rl_point = rl_end; return 0;}/* Move forward a word. We do what Emacs does. */rl_forward_word (count, key) int count, key;{ int c; if (count < 0) { rl_backward_word (-count); return 0; } while (count) { if (rl_point == rl_end) return 0; /* If we are not in a word, move forward until we are in one. Then, move forward until we hit a non-alphabetic character. */ c = the_line[rl_point]; if (!alphabetic (c)) { while (++rl_point < rl_end) { c = the_line[rl_point]; if (alphabetic (c)) break; } } if (rl_point == rl_end) return 0; while (++rl_point < rl_end) { c = the_line[rl_point]; if (!alphabetic (c)) break; } --count; } return 0;}/* Move backward a word. We do what Emacs does. */rl_backward_word (count, key) int count, key;{ int c; if (count < 0) { rl_forward_word (-count); return 0; } while (count) { if (!rl_point) return 0; /* Like rl_forward_word (), except that we look at the characters just before point. */ c = the_line[rl_point - 1]; if (!alphabetic (c)) { while (--rl_point) { c = the_line[rl_point - 1]; if (alphabetic (c)) break; } } while (rl_point) { c = the_line[rl_point - 1]; if (!alphabetic (c)) break; else --rl_point; } --count; } return 0;}/* Clear the current line. Numeric argument to C-l does this. */rl_refresh_line (){ int curr_line, nleft; /* Find out whether or not there might be invisible characters in the editing buffer. */ if (rl_display_prompt == rl_prompt) nleft = _rl_last_c_pos - screenwidth - rl_visible_prompt_length; else nleft = _rl_last_c_pos - screenwidth; if (nleft > 0) curr_line = 1 + nleft / screenwidth; else curr_line = 0; _rl_move_vert (curr_line); _rl_move_cursor_relative (0, the_line); /* XXX is this right */#if defined (__GO32__) { int row, col, width, row_start; ScreenGetCursor (&row, &col); width = ScreenCols (); row_start = ScreenPrimary + (row * width); memset (row_start + col, 0, (width - col) * 2); }#else /* !__GO32__ */ if (term_clreol) tputs (term_clreol, 1, _rl_output_character_function);#endif /* !__GO32__ */ rl_forced_update_display (); rl_display_fixed = 1; return 0;}/* C-l typed to a line without quoting clears the screen, and then reprints the prompt and the current input line. Given a numeric arg, redraw only the current line. */rl_clear_screen (count, key) int count, key;{ if (rl_explicit_arg) { rl_refresh_line (); return 0; }#if !defined (__GO32__) if (term_clrpag) tputs (term_clrpag, 1, _rl_output_character_function); else#endif /* !__GO32__ */ crlf (); rl_forced_update_display (); rl_display_fixed = 1; return 0;}rl_arrow_keys (count, c) int count, c;{ int ch; ch = rl_read_key (); switch (to_upper (ch)) { case 'A': rl_get_previous_history (count); break; case 'B': rl_get_next_history (count); break; case 'C': rl_forward (count); break; case 'D': rl_backward (count); break; default: ding (); } return 0;}/* **************************************************************** *//* *//* Text commands *//* *//* **************************************************************** *//* Insert the character C at the current location, moving point forward. */rl_insert (count, c) int count, c;{ register int i; char *string; if (count <= 0) return 0; /* If we can optimize, then do it. But don't let people crash readline because of extra large arguments. */ if (count > 1 && count < 1024) { string = xmalloc (1 + count); for (i = 0; i < count; i++) string[i] = c; string[i] = '\0'; rl_insert_text (string); free (string); return 0; } if (count > 1024) { int decreaser; char str[1024+1]; for (i = 0; i < 1024; i++) str[i] = c; while (count) { decreaser = (count > 1024 ? 1024 : count); str[decreaser] = '\0'; rl_insert_text (str); count -= decreaser; } return 0; } /* We are inserting a single character. If there is pending input, then make a string of all of the pending characters that are bound to rl_insert, and insert them all. */ if (any_typein) { int key = 0, t; i = 0; string = xmalloc (ibuffer_len + 1); string[i++] = c; while ((t = rl_get_char (&key)) && (_rl_keymap[key].type == ISFUNC && _rl_keymap[key].function == rl_insert)) string[i++] = key; if (t) rl_unget_char (key); string[i] = '\0'; rl_insert_text (string); free (string); } else { /* Inserting a single character. */ char str[2]; str[1] = '\0'; str[0] = c; rl_insert_text (str); } return 0;}/* Insert the next typed character verbatim. */rl_quoted_insert (count, key) int count, key;{ int c; c = rl_read_key (); return (rl_insert (count, c)); }/* Insert a tab character. */rl_tab_insert (count, key) int count, key;{ return (rl_insert (count, '\t'));}/* What to do when a NEWLINE is pressed. We accept the whole line. KEY is the key that invoked this command. I guess it could have meaning in the future. */rl_newline (count, key) int count, key;{ rl_done = 1;#if defined (VI_MODE) _rl_vi_done_inserting (); _rl_vi_reset_last ();#endif /* VI_MODE */ if (readline_echoing_p) _rl_update_final (); return 0;}rl_clean_up_for_exit (){ if (readline_echoing_p) { _rl_move_vert (_rl_vis_botlin); _rl_vis_botlin = 0; fflush (out_stream); rl_restart_output (); } return 0;}/* What to do for some uppercase characters, like meta characters, and some characters appearing in emacs_ctlx_keymap. This function is just a stub, you bind keys to it and the code in _rl_dispatch () is special cased. */rl_do_lowercase_version (ignore1, ignore2) int ignore1, ignore2;{ return 0;}/* Rubout the character behind point. */rl_rubout (count, key) int count, key;{ if (count < 0) { rl_delete (-count); return 0; } if (!rl_point) { ding (); return -1; } if (count > 1 || rl_explicit_arg) { int orig_point = rl_point; rl_backward (count); rl_kill_text (orig_point, rl_point); } else { int c = the_line[--rl_point]; rl_delete_text (rl_point, rl_point + 1); if (rl_point == rl_end && isprint (c) && _rl_last_c_pos) { int l; l = rl_character_len (c, rl_point); _rl_erase_at_end_of_line (l); } } return 0;}/* Delete the character under the cursor. Given a numeric argument, kill that many characters instead. */rl_delete (count, invoking_key) int count, invoking_key;{ if (count < 0) { return (rl_rubout (-count)); } if (rl_point == rl_end) { ding (); return -1; } if (count > 1 || rl_explicit_arg) { int orig_point = rl_point; rl_forward (count); rl_kill_text (orig_point, rl_point); rl_point = orig_point; return 0; } else return (rl_delete_text (rl_point, rl_point + 1)); }/* Delete all spaces and tabs around point. */rl_delete_horizontal_space (count, ignore) int count, ignore;{ int start = rl_point; while (rl_point && whitespace (the_line[rl_point - 1])) rl_point--; start = rl_point; while (rl_point < rl_end && whitespace (the_line[rl_point])) rl_point++; if (start != rl_point) { rl_delete_text (start, rl_point); rl_point = start; } return 0;}/* **************************************************************** *//* *//* Kill commands *//* *//* **************************************************************** *//* The next two functions mimic unix line editing behaviour, except they save the deleted text on the kill ring. This is safer than not saving it, and since we have a ring, nobody should get screwed. *//* This does what C-w does in Unix. We can't prevent people from using behaviour that they expect. */rl_unix_word_rubout (count, key) int count, key;{ if (!rl_point) ding (); else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -