📄 bind.c
字号:
/* bind.c -- key binding and startup file support for the readline library. *//* Copyright (C) 1987, 1989, 1992 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#include <stdio.h>#include <sys/types.h>#include <fcntl.h>#if defined (HAVE_SYS_FILE_H)# include <sys/file.h>#endif /* HAVE_SYS_FILE_H */#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 */#include <errno.h>#if !defined (errno)extern int errno;#endif /* !errno */#include "posixstat.h"/* System-specific feature definitions and include files. */#include "rldefs.h"/* Some standard library routines. */#include "readline.h"#include "history.h"#include "rlprivate.h"#include "rlshell.h"#include "xmalloc.h"#if !defined (strchr) && !defined (__STDC__)extern char *strchr (), *strrchr ();#endif /* !strchr && !__STDC__ *//* Variables exported by this file. */Keymap rl_binding_keymap;static int _rl_read_init_file __P((char *, int));static int glean_key_from_name __P((char *));static int substring_member_of_array __P((char *, char **));static int currently_reading_init_file;/* used only in this file */static int _rl_prefer_visible_bell = 1;/* **************************************************************** *//* *//* Binding keys *//* *//* **************************************************************** *//* rl_add_defun (char *name, Function *function, int key) Add NAME to the list of named functions. Make FUNCTION be the function that gets called. If KEY is not -1, then bind it. */intrl_add_defun (name, function, key) char *name; Function *function; int key;{ if (key != -1) rl_bind_key (key, function); rl_add_funmap_entry (name, function); return 0;}/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */intrl_bind_key (key, function) int key; Function *function;{ if (key < 0) return (key); if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) { if (_rl_keymap[ESC].type == ISKMAP) { Keymap escmap; escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC); key = UNMETA (key); escmap[key].type = ISFUNC; escmap[key].function = function; return (0); } return (key); } _rl_keymap[key].type = ISFUNC; _rl_keymap[key].function = function; rl_binding_keymap = _rl_keymap; return (0);}/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid KEY. */intrl_bind_key_in_map (key, function, map) int key; Function *function; Keymap map;{ int result; Keymap oldmap; oldmap = _rl_keymap; _rl_keymap = map; result = rl_bind_key (key, function); _rl_keymap = oldmap; return (result);}/* Make KEY do nothing in the currently selected keymap. Returns non-zero in case of error. */intrl_unbind_key (key) int key;{ return (rl_bind_key (key, (Function *)NULL));}/* Make KEY do nothing in MAP. Returns non-zero in case of error. */intrl_unbind_key_in_map (key, map) int key; Keymap map;{ return (rl_bind_key_in_map (key, (Function *)NULL, map));}/* Unbind all keys bound to FUNCTION in MAP. */intrl_unbind_function_in_map (func, map) Function *func; Keymap map;{ register int i, rval; for (i = rval = 0; i < KEYMAP_SIZE; i++) { if (map[i].type == ISFUNC && map[i].function == func) { map[i].function = (Function *)NULL; rval = 1; } } return rval;}intrl_unbind_command_in_map (command, map) char *command; Keymap map;{ Function *func; func = rl_named_function (command); if (func == 0) return 0; return (rl_unbind_function_in_map (func, map));}/* Bind the key sequence represented by the string KEYSEQ to FUNCTION. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */intrl_set_key (keyseq, function, map) char *keyseq; Function *function; Keymap map;{ return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));}/* Bind the key sequence represented by the string KEYSEQ to the string of characters MACRO. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */intrl_macro_bind (keyseq, macro, map) char *keyseq, *macro; Keymap map;{ char *macro_keys; int macro_keys_len; macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1); if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len)) { free (macro_keys); return -1; } rl_generic_bind (ISMACR, keyseq, macro_keys, map); return 0;}/* Bind the key sequence represented by the string KEYSEQ to the arbitrary pointer DATA. TYPE says what kind of data is pointed to by DATA, right now this can be a function (ISFUNC), a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps as necessary. The initial place to do bindings is in MAP. */intrl_generic_bind (type, keyseq, data, map) int type; char *keyseq, *data; Keymap map;{ char *keys; int keys_len; register int i; /* If no keys to bind to, exit right away. */ if (!keyseq || !*keyseq) { if (type == ISMACR) free (data); return -1; } keys = xmalloc (1 + (2 * strlen (keyseq))); /* Translate the ASCII representation of KEYSEQ into an array of characters. Stuff the characters into KEYS, and the length of KEYS into KEYS_LEN. */ if (rl_translate_keyseq (keyseq, keys, &keys_len)) { free (keys); return -1; } /* Bind keys, making new keymaps as necessary. */ for (i = 0; i < keys_len; i++) { int ic = (int) ((unsigned char)keys[i]); if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic)) { ic = UNMETA (ic); if (map[ESC].type == ISKMAP) map = FUNCTION_TO_KEYMAP (map, ESC); } if ((i + 1) < keys_len) { if (map[ic].type != ISKMAP) { if (map[ic].type == ISMACR) free ((char *)map[ic].function); map[ic].type = ISKMAP; map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap()); } map = FUNCTION_TO_KEYMAP (map, ic); } else { if (map[ic].type == ISMACR) free ((char *)map[ic].function); map[ic].function = KEYMAP_TO_FUNCTION (data); map[ic].type = type; } rl_binding_keymap = map; } free (keys); return 0;}/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, an array of characters. LEN gets the final length of ARRAY. Return non-zero if there was an error parsing SEQ. */intrl_translate_keyseq (seq, array, len) char *seq, *array; int *len;{ register int i, c, l, temp; for (i = l = 0; c = seq[i]; i++) { if (c == '\\') { c = seq[++i]; if (c == 0) break; /* Handle \C- and \M- prefixes. */ if ((c == 'C' || c == 'M') && seq[i + 1] == '-') { /* Handle special case of backwards define. */ if (strncmp (&seq[i], "C-\\M-", 5) == 0) { array[l++] = ESC; i += 5; array[l++] = CTRL (_rl_to_upper (seq[i])); if (seq[i] == '\0') i--; } else if (c == 'M') { i++; array[l++] = ESC; /* XXX */ } else if (c == 'C') { i += 2; /* Special hack for C-?... */ array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); } continue; } /* Translate other backslash-escaped characters. These are the same escape sequences that bash's `echo' and `printf' builtins handle, with the addition of \d -> RUBOUT. A backslash preceding a character that is not special is stripped. */ switch (c) { case 'a': array[l++] = '\007'; break; case 'b': array[l++] = '\b'; break; case 'd': array[l++] = RUBOUT; /* readline-specific */ break; case 'e': array[l++] = ESC; break; case 'f': array[l++] = '\f'; break; case 'n': array[l++] = NEWLINE; break; case 'r': array[l++] = RETURN; break; case 't': array[l++] = TAB; break; case 'v': array[l++] = 0x0B; break; case '\\': array[l++] = '\\'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': i++; for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++) c = (c * 8) + OCTVALUE (seq[i]); i--; /* auto-increment in for loop */ array[l++] = c % (largest_char + 1); break; case 'x': i++; for (temp = 3, c = 0; isxdigit (seq[i]) && temp--; i++) c = (c * 16) + HEXVALUE (seq[i]); if (temp == 3) c = 'x'; i--; /* auto-increment in for loop */ array[l++] = c % (largest_char + 1); break; default: /* backslashes before non-special chars just add the char */ array[l++] = c; break; /* the backslash is stripped */ } continue; } array[l++] = c; } *len = l; array[l] = '\0'; return (0);}char *rl_untranslate_keyseq (seq) int seq;{ static char kseq[16]; int i, c; i = 0; c = seq; if (META_CHAR (c)) { kseq[i++] = '\\'; kseq[i++] = 'M'; kseq[i++] = '-'; c = UNMETA (c); } else if (CTRL_CHAR (c)) { kseq[i++] = '\\'; kseq[i++] = 'C'; kseq[i++] = '-'; c = _rl_to_lower (UNCTRL (c)); } else if (c == RUBOUT) { kseq[i++] = '\\'; kseq[i++] = 'C'; kseq[i++] = '-'; c = '?'; } if (c == ESC) { kseq[i++] = '\\'; c = 'e'; } else if (c == '\\' || c == '"') { kseq[i++] = '\\'; } kseq[i++] = (unsigned char) c; kseq[i] = '\0'; return kseq;}static char *_rl_untranslate_macro_value (seq) char *seq;{ char *ret, *r, *s; int c; r = ret = xmalloc (7 * strlen (seq) + 1); for (s = seq; *s; s++) { c = *s; if (META_CHAR (c)) { *r++ = '\\'; *r++ = 'M'; *r++ = '-'; c = UNMETA (c); } else if (CTRL_CHAR (c) && c != ESC) { *r++ = '\\'; *r++ = 'C'; *r++ = '-'; c = _rl_to_lower (UNCTRL (c)); } else if (c == RUBOUT) { *r++ = '\\'; *r++ = 'C'; *r++ = '-'; c = '?'; } if (c == ESC) { *r++ = '\\'; c = 'e'; } else if (c == '\\' || c == '"') *r++ = '\\'; *r++ = (unsigned char)c; } *r = '\0'; return ret;}/* Return a pointer to the function that STRING represents. If STRING doesn't have a matching function, then a NULL pointer is returned. */Function *rl_named_function (string) char *string;{ register int i; rl_initialize_funmap (); for (i = 0; funmap[i]; i++) if (_rl_stricmp (funmap[i]->name, string) == 0) return (funmap[i]->function);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -