⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bind.c

📁 在非GUI环境下
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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 (__TANDEM)#  include <floss.h>#endif#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 char *_rl_read_file PARAMS((char *, size_t *));static void _rl_init_file_error PARAMS((const char *));static int _rl_read_init_file PARAMS((const char *, int));static int glean_key_from_name PARAMS((char *));static int substring_member_of_array PARAMS((char *, const 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, rl_command_func_t *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)     const char *name;     rl_command_func_t *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;     rl_command_func_t *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;     rl_command_func_t *function;     Keymap map;{  int result;  Keymap oldmap;  oldmap = _rl_keymap;  _rl_keymap = map;  result = rl_bind_key (key, function);  _rl_keymap = oldmap;  return (result);}/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right   now, this is always used to attempt to bind the arrow keys, hence the   check for rl_vi_movement_mode. */intrl_bind_key_if_unbound_in_map (key, default_func, kmap)     int key;     rl_command_func_t *default_func;     Keymap kmap;{  char keyseq[2];  keyseq[0] = (unsigned char)key;  keyseq[1] = '\0';  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));}intrl_bind_key_if_unbound (key, default_func)     int key;     rl_command_func_t *default_func;{  char keyseq[2];  keyseq[0] = (unsigned char)key;  keyseq[1] = '\0';  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));}/* 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, (rl_command_func_t *)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, (rl_command_func_t *)NULL, map));}/* Unbind all keys bound to FUNCTION in MAP. */intrl_unbind_function_in_map (func, map)     rl_command_func_t *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 = (rl_command_func_t *)NULL;	  rval = 1;	}    }  return rval;}intrl_unbind_command_in_map (command, map)     const char *command;     Keymap map;{  rl_command_func_t *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, starting in the current keymap.  This makes new   keymaps as necessary. */intrl_bind_keyseq (keyseq, function)     const char *keyseq;     rl_command_func_t *function;{  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));}/* 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_bind_keyseq_in_map (keyseq, function, map)     const char *keyseq;     rl_command_func_t *function;     Keymap map;{  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));}/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */intrl_set_key (keyseq, function, map)     const char *keyseq;     rl_command_func_t *function;     Keymap map;{  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));}/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right   now, this is always used to attempt to bind the arrow keys, hence the   check for rl_vi_movement_mode. */intrl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)     const char *keyseq;     rl_command_func_t *default_func;     Keymap kmap;{  rl_command_func_t *func;  if (keyseq)    {      func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);#if defined (VI_MODE)      if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)#else      if (!func || func == rl_do_lowercase_version)#endif	return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));      else	return 1;    }  return 0;}intrl_bind_keyseq_if_unbound (keyseq, default_func)     const char *keyseq;     rl_command_func_t *default_func;{  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));}/* 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)     const 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, &macro_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;     const char *keyseq;     char *data;     Keymap map;{  char *keys;  int keys_len;  register int i;  KEYMAP_ENTRY k;  k.function = 0;  /* If no keys to bind to, exit right away. */  if (!keyseq || !*keyseq)    {      if (type == ISMACR)	free (data);      return -1;    }  keys = (char *)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++)    {      unsigned char uc = keys[i];      int ic;      ic = uc;      if (ic < 0 || ic >= KEYMAP_SIZE)	return -1;      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)	    {	      /* We allow subsequences of keys.  If a keymap is being		 created that will `shadow' an existing function or macro		 key binding, we save that keybinding into the ANYOTHERKEY		 index in the new map.  The dispatch code will look there		 to find the function to execute if the subsequence is not		 matched.  ANYOTHERKEY was chosen to be greater than		 UCHAR_MAX. */	      k = map[ic];	      map[ic].type = ISKMAP;	      map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());	    }	  map = FUNCTION_TO_KEYMAP (map, ic);	  /* The dispatch code will return this function if no matching	     key sequence is found in the keymap.  This (with a little	     help from the dispatch code in readline.c) allows `a' to be	     mapped to something, `abc' to be mapped to something else,	     and the function bound  to `a' to be executed when the user	     types `abx', leaving `bx' in the input queue. */	  if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))	    {	      map[ANYOTHERKEY] = k;	      k.function = 0;	    }	}      else	{	  if (map[ic].type == ISMACR)	    free ((char *)map[ic].function);	  else if (map[ic].type == ISKMAP)	    {	      map = FUNCTION_TO_KEYMAP (map, ic);	      ic = ANYOTHERKEY;	    }	  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)     const char *seq;     char *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;	/* ESC is meta-prefix */		  i += 5;		  array[l++] = CTRL (_rl_to_upper (seq[i]));		  if (seq[i] == '\0')		    i--;		}	      else if (c == 'M')		{		  i++;		  array[l++] = ESC;	/* ESC is meta-prefix */		}	      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;	      break;	    case 'x':	      i++;	      for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)	        c = (c * 16) + HEXVALUE (seq[i]);	      if (temp == 2)	        c = 'x';	      i--;	/* auto-increment in for loop */	      array[l++] = c & largest_char;	      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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -