📄 text.c
字号:
/* text.c -- text handling commands for readline. *//* Copyright (C) 1987-2004 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. The GNU Readline Library 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 2, or (at your option) any later version. The GNU Readline Library 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. The GNU General Public License is often shipped with GNU software, and is generally kept in a file called COPYING or LICENSE. If you do not have a copy of the license, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */#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));/* **************************************************************** *//* *//* 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 free (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; rl_begin_undo_group (); rl_delete_text (start, end + 1); rl_point = start; 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 = rl_point + count;#if defined (VI_MODE) int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;#else int 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;}#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) { point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);#if defined (VI_MODE) if (rl_end <= point && rl_editing_mode == vi_mode) point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);#endif if (rl_point == point) rl_ding (); rl_point = point; if (rl_end < 0) rl_end = 0; } 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;}/* XXX - these might need changes for multibyte characters *//* Move forward a word. We do what Emacs does. */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_line_buffer[rl_point]; if (rl_alphabetic (c) == 0) { while (++rl_point < rl_end) { c = rl_line_buffer[rl_point]; if (rl_alphabetic (c)) break; } } if (rl_point == rl_end) return 0; while (++rl_point < rl_end) { c = rl_line_buffer[rl_point]; if (rl_alphabetic (c) == 0) break; } --count; } return 0;}/* Move backward a word. We do what Emacs does. */intrl_backward_word (count, key) int count, key;{ int c; if (count < 0) return (rl_forward_word (-count, key)); while (count) { if (!rl_point) return 0; /* Like rl_forward_word (), except that we look at the characters just before point. */ c = rl_line_buffer[rl_point - 1]; if (rl_alphabetic (c) == 0) { while (--rl_point) { c = rl_line_buffer[rl_point - 1]; if (rl_alphabetic (c)) break; } } while (rl_point) { c = rl_line_buffer[rl_point - 1]; if (rl_alphabetic (c) == 0) break; else --rl_point; } --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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -