📄 text.c
字号:
/* text.c -- text handling commands for readline. *//* Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. Readline is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Readline is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Readline. If not, see <http://www.gnu.org/licenses/>.*/#define READLINE_LIBRARY#if defined (HAVE_CONFIG_H)# include <config.h>#endif#if defined (HAVE_UNISTD_H)# include <unistd.h>#endif /* HAVE_UNISTD_H */#if defined (HAVE_STDLIB_H)# include <stdlib.h>#else# include "ansi_stdlib.h"#endif /* HAVE_STDLIB_H */#if defined (HAVE_LOCALE_H)# include <locale.h>#endif#include <stdio.h>/* System-specific feature definitions and include files. */#include "rldefs.h"#include "rlmbutil.h"#if defined (__EMX__)# define INCL_DOSPROCESS# include <os2.h>#endif /* __EMX__ *//* Some standard library routines. */#include "readline.h"#include "history.h"#include "rlprivate.h"#include "rlshell.h"#include "xmalloc.h"/* Forward declarations. */static int rl_change_case PARAMS((int, int));static int _rl_char_search PARAMS((int, int, int));#if defined (READLINE_CALLBACKS)static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));#endif/* The largest chunk of text that can be inserted in one call to rl_insert_text. Text blocks larger than this are divided. */#define TEXT_COUNT_MAX 1024/* **************************************************************** *//* *//* Insert and Delete *//* *//* **************************************************************** *//* Insert a string of text into the line at point. This is the only way that you should do insertion. _rl_insert_char () calls this function. Returns the number of characters inserted. */intrl_insert_text (string) const char *string;{ register int i, l; l = (string && *string) ? strlen (string) : 0; if (l == 0) return 0; if (rl_end + l >= rl_line_buffer_len) rl_extend_line_buffer (rl_end + l); for (i = rl_end; i >= rl_point; i--) rl_line_buffer[i + l] = rl_line_buffer[i]; strncpy (rl_line_buffer + rl_point, string, l); /* Remember how to undo this if we aren't undoing something. */ if (_rl_doing_an_undo == 0) { /* If possible and desirable, concatenate the undos. */ if ((l == 1) && rl_undo_list && (rl_undo_list->what == UNDO_INSERT) && (rl_undo_list->end == rl_point) && (rl_undo_list->end - rl_undo_list->start < 20)) rl_undo_list->end++; else rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL); } rl_point += l; rl_end += l; rl_line_buffer[rl_end] = '\0'; return l;}/* Delete the string between FROM and TO. FROM is inclusive, TO is not. Returns the number of characters deleted. */intrl_delete_text (from, to) int from, to;{ register char *text; register int diff, i; /* Fix it if the caller is confused. */ if (from > to) SWAP (from, to); /* fix boundaries */ if (to > rl_end) { to = rl_end; if (from > to) from = to; } if (from < 0) from = 0; 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++) rl_line_buffer[i] = rl_line_buffer[i + diff]; /* Remember how to undo this delete. */ if (_rl_doing_an_undo == 0) rl_add_undo (UNDO_DELETE, from, to, text); else xfree (text); rl_end -= diff; rl_line_buffer[rl_end] = '\0'; return (diff);}/* Fix up point so that it is within the line boundaries after killing text. If FIX_MARK_TOO is non-zero, the mark is forced within line boundaries also. */#define _RL_FIX_POINT(x) \ do { \ if (x > rl_end) \ x = rl_end; \ else if (x < 0) \ x = 0; \ } while (0)void_rl_fix_point (fix_mark_too) int fix_mark_too;{ _RL_FIX_POINT (rl_point); if (fix_mark_too) _RL_FIX_POINT (rl_mark);}#undef _RL_FIX_POINT/* Replace the contents of the line buffer between START and END with TEXT. The operation is undoable. To replace the entire line in an undoable mode, use _rl_replace_text(text, 0, rl_end); */int_rl_replace_text (text, start, end) const char *text; int start, end;{ int n; n = 0; rl_begin_undo_group (); if (start <= end) rl_delete_text (start, end + 1); rl_point = start; if (*text) n = rl_insert_text (text); rl_end_undo_group (); return n;}/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is non-zero, we free the current undo list. */voidrl_replace_line (text, clear_undo) const char *text; int clear_undo;{ int len; len = strlen (text); if (len >= rl_line_buffer_len) rl_extend_line_buffer (len); strcpy (rl_line_buffer, text); rl_end = len; if (clear_undo) rl_free_undo_list (); _rl_fix_point (1);}/* **************************************************************** *//* *//* 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 bytes. */intrl_forward_byte (count, key) int count, key;{ if (count < 0) return (rl_backward_byte (-count, key)); if (count > 0) { int end, lend; end = rl_point + count;#if defined (VI_MODE) lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;#else lend = rl_end;#endif if (end > lend) { rl_point = lend; rl_ding (); } else rl_point = end; } if (rl_end < 0) rl_end = 0; return 0;}int_rl_forward_char_internal (count) int count;{ int point;#if defined (HANDLE_MULTIBYTE) point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);#if defined (VI_MODE) if (point >= rl_end && VI_COMMAND_MODE()) point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);#endif if (rl_end < 0) rl_end = 0;#else point = rl_point + count; if (point > rl_end) point = rl_end;#endif return (point);}#if defined (HANDLE_MULTIBYTE)/* Move forward COUNT characters. */intrl_forward_char (count, key) int count, key;{ int point; if (MB_CUR_MAX == 1 || rl_byte_oriented) return (rl_forward_byte (count, key)); if (count < 0) return (rl_backward_char (-count, key)); if (count > 0) { if (rl_point == rl_end && EMACS_MODE()) { rl_ding (); return 0; } point = _rl_forward_char_internal (count); if (rl_point == point) rl_ding (); rl_point = point; } return 0;}#else /* !HANDLE_MULTIBYTE */intrl_forward_char (count, key) int count, key;{ return (rl_forward_byte (count, key));}#endif /* !HANDLE_MULTIBYTE */ /* Backwards compatibility. */intrl_forward (count, key) int count, key;{ return (rl_forward_char (count, key));}/* Move backward COUNT bytes. */intrl_backward_byte (count, key) int count, key;{ if (count < 0) return (rl_forward_byte (-count, key)); if (count > 0) { if (rl_point < count) { rl_point = 0; rl_ding (); } else rl_point -= count; } if (rl_point < 0) rl_point = 0; return 0;}#if defined (HANDLE_MULTIBYTE)/* Move backward COUNT characters. */intrl_backward_char (count, key) int count, key;{ int point; if (MB_CUR_MAX == 1 || rl_byte_oriented) return (rl_backward_byte (count, key)); if (count < 0) return (rl_forward_char (-count, key)); if (count > 0) { point = rl_point; while (count > 0 && point > 0) { point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); count--; } if (count > 0) { rl_point = 0; rl_ding (); } else rl_point = point; } return 0;}#elseintrl_backward_char (count, key) int count, key;{ return (rl_backward_byte (count, key));}#endif/* Backwards compatibility. */intrl_backward (count, key) int count, key;{ return (rl_backward_char (count, key));}/* Move to the beginning of the line. */intrl_beg_of_line (count, key) int count, key;{ rl_point = 0; return 0;}/* Move to the end of the line. */intrl_end_of_line (count, key) int count, key;{ rl_point = rl_end; return 0;}/* Move forward a word. We do what Emacs does. Handles multibyte chars. */intrl_forward_word (count, key) int count, key;{ int c; if (count < 0) return (rl_backward_word (-count, key)); 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 = _rl_char_value (rl_line_buffer, rl_point); if (_rl_walphabetic (c) == 0) { rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); while (rl_point < rl_end) { c = _rl_char_value (rl_line_buffer, rl_point); if (_rl_walphabetic (c)) break; rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); } } if (rl_point == rl_end) return 0; rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); while (rl_point < rl_end) { c = _rl_char_value (rl_line_buffer, rl_point); if (_rl_walphabetic (c) == 0) break; rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); } --count; } return 0;}/* Move backward a word. We do what Emacs does. Handles multibyte chars. */intrl_backward_word (count, key) int count, key;{ int c, p; if (count < 0) return (rl_forward_word (-count, key)); while (count) { if (rl_point == 0) return 0; /* Like rl_forward_word (), except that we look at the characters just before point. */ p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); c = _rl_char_value (rl_line_buffer, p); if (_rl_walphabetic (c) == 0) { rl_point = p; while (rl_point > 0) { p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); c = _rl_char_value (rl_line_buffer, p); if (_rl_walphabetic (c)) break; rl_point = p; } } while (rl_point) { p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); c = _rl_char_value (rl_line_buffer, p); if (_rl_walphabetic (c) == 0) break; else rl_point = p; } --count; } return 0;}/* Clear the current line. Numeric argument to C-l does this. */intrl_refresh_line (ignore1, ignore2) int ignore1, ignore2;{ int curr_line; curr_line = _rl_current_display_line (); _rl_move_vert (curr_line);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -