bind.c revision 26497
197883Sgibbs/* bind.c -- key binding and startup file support for the readline library. */ 297883Sgibbs 397883Sgibbs/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. 497883Sgibbs 5102681Sgibbs This file is part of the GNU Readline Library, a library for 697883Sgibbs reading lines of text with interactive input and history editing. 797883Sgibbs 897883Sgibbs The GNU Readline Library is free software; you can redistribute it 997883Sgibbs and/or modify it under the terms of the GNU General Public License 1097883Sgibbs as published by the Free Software Foundation; either version 1, or 1197883Sgibbs (at your option) any later version. 1297883Sgibbs 1397883Sgibbs The GNU Readline Library is distributed in the hope that it will be 1497883Sgibbs useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1597883Sgibbs of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1697883Sgibbs GNU General Public License for more details. 1797883Sgibbs 1897883Sgibbs The GNU General Public License is often shipped with GNU software, and 1997883Sgibbs is generally kept in a file called COPYING or LICENSE. If you do not 2097883Sgibbs have a copy of the license, write to the Free Software Foundation, 2197883Sgibbs 675 Mass Ave, Cambridge, MA 02139, USA. */ 2297883Sgibbs#define READLINE_LIBRARY 2397883Sgibbs 2497883Sgibbs#if defined (HAVE_CONFIG_H) 2597883Sgibbs# include <config.h> 2697883Sgibbs#endif 2797883Sgibbs 2897883Sgibbs#include <stdio.h> 2997883Sgibbs#include <sys/types.h> 3097883Sgibbs#include <fcntl.h> 3197883Sgibbs#if defined (HAVE_SYS_FILE_H) 3297883Sgibbs# include <sys/file.h> 3397883Sgibbs#endif /* HAVE_SYS_FILE_H */ 3497883Sgibbs 3597883Sgibbs#if defined (HAVE_UNISTD_H) 3697883Sgibbs# include <unistd.h> 3797883Sgibbs#endif /* HAVE_UNISTD_H */ 3897883Sgibbs 3997883Sgibbs#if defined (HAVE_STDLIB_H) 4097883Sgibbs# include <stdlib.h> 4197883Sgibbs#else 42107623Sscottl# include "ansi_stdlib.h" 4397883Sgibbs#endif /* HAVE_STDLIB_H */ 4497883Sgibbs 4597883Sgibbs#include <signal.h> 4697883Sgibbs#include <errno.h> 4797883Sgibbs 4897883Sgibbs#if !defined (errno) 4997883Sgibbsextern int errno; 5097883Sgibbs#endif /* !errno */ 5197883Sgibbs 5297883Sgibbs#include "posixstat.h" 5397883Sgibbs 5497883Sgibbs/* System-specific feature definitions and include files. */ 5597883Sgibbs#include "rldefs.h" 5697883Sgibbs 5797883Sgibbs/* Some standard library routines. */ 5897883Sgibbs#include "readline.h" 59104023Sgibbs#include "history.h" 60104023Sgibbs 61104023Sgibbs#if !defined (strchr) && !defined (__STDC__) 62104023Sgibbsextern char *strchr (), *strrchr (); 63104023Sgibbs#endif /* !strchr && !__STDC__ */ 64104023Sgibbs 65104023Sgibbsextern int _rl_horizontal_scroll_mode; 66104023Sgibbsextern int _rl_mark_modified_lines; 6797883Sgibbsextern int _rl_bell_preference; 68104023Sgibbsextern int _rl_meta_flag; 69104023Sgibbsextern int _rl_convert_meta_chars_to_ascii; 70104023Sgibbsextern int _rl_output_meta_chars; 71104023Sgibbsextern int _rl_complete_show_all; 72104023Sgibbsextern int _rl_complete_mark_directories; 73104023Sgibbsextern int _rl_enable_keypad; 74104023Sgibbs#if defined (PAREN_MATCHING) 75107441Sscottlextern int rl_blink_matching_paren; 76107441Sscottl#endif /* PAREN_MATCHING */ 77107441Sscottl#if defined (VISIBLE_STATS) 78107441Sscottlextern int rl_visible_stats; 79107441Sscottl#endif /* VISIBLE_STATS */ 80107441Sscottlextern int rl_complete_with_tilde_expansion; 81104023Sgibbsextern int rl_completion_query_items; 82107441Sscottlextern int rl_inhibit_completion; 83107441Sscottlextern char *_rl_comment_begin; 84107441Sscottl 85107441Sscottlextern int rl_explicit_arg; 86107441Sscottlextern int rl_editing_mode; 87107441Sscottlextern unsigned char _rl_parsing_conditionalized_out; 88107441Sscottlextern Keymap _rl_keymap; 8997883Sgibbs 9097883Sgibbsextern char *possible_control_prefixes[], *possible_meta_prefixes[]; 9197883Sgibbs 9297883Sgibbs/* Functions imported from funmap.c */ 9397883Sgibbsextern char **rl_funmap_names (); 9497883Sgibbsextern int rl_add_funmap_entry (); 9597883Sgibbs 9697883Sgibbs/* Functions imported from util.c */ 9797883Sgibbsextern char *_rl_strindex (); 98102681Sgibbs 99102681Sgibbs/* Functions imported from shell.c */ 10097883Sgibbsextern char *get_env_value (); 10197883Sgibbs 10297883Sgibbs/* Variables exported by this file. */ 10397883SgibbsKeymap rl_binding_keymap; 10497883Sgibbs 10597883Sgibbs/* Forward declarations */ 10697883Sgibbsvoid rl_set_keymap_from_edit_mode (); 10797883Sgibbs 10897883Sgibbsstatic int glean_key_from_name (); 10997883Sgibbsstatic int substring_member_of_array (); 11097883Sgibbs 11197883Sgibbsextern char *xmalloc (), *xrealloc (); 112102681Sgibbs 113102681Sgibbs/* **************************************************************** */ 114102681Sgibbs/* */ 115102681Sgibbs/* Binding keys */ 116102681Sgibbs/* */ 117102681Sgibbs/* **************************************************************** */ 118102681Sgibbs 119102681Sgibbs/* rl_add_defun (char *name, Function *function, int key) 12097883Sgibbs Add NAME to the list of named functions. Make FUNCTION be the function 12197883Sgibbs that gets called. If KEY is not -1, then bind it. */ 12297883Sgibbsint 12397883Sgibbsrl_add_defun (name, function, key) 12497883Sgibbs char *name; 12597883Sgibbs Function *function; 12697883Sgibbs int key; 12797883Sgibbs{ 12897883Sgibbs if (key != -1) 129102681Sgibbs rl_bind_key (key, function); 130107441Sscottl rl_add_funmap_entry (name, function); 131107441Sscottl return 0; 132102681Sgibbs} 133102681Sgibbs 134102681Sgibbs/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */ 135102681Sgibbsint 136102681Sgibbsrl_bind_key (key, function) 13797883Sgibbs int key; 13897883Sgibbs Function *function; 13997883Sgibbs{ 14097883Sgibbs if (key < 0) 14197883Sgibbs return (key); 14297883Sgibbs 143102681Sgibbs if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) 14497883Sgibbs { 14597883Sgibbs if (_rl_keymap[ESC].type == ISKMAP) 14697883Sgibbs { 14797883Sgibbs Keymap escmap; 14897883Sgibbs 14997883Sgibbs escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC); 15097883Sgibbs key = UNMETA (key); 15197883Sgibbs escmap[key].type = ISFUNC; 152102681Sgibbs escmap[key].function = function; 153102681Sgibbs return (0); 15497883Sgibbs } 15597883Sgibbs return (key); 15697883Sgibbs } 15797883Sgibbs 158102681Sgibbs _rl_keymap[key].type = ISFUNC; 15997883Sgibbs _rl_keymap[key].function = function; 16097883Sgibbs rl_binding_keymap = _rl_keymap; 16197883Sgibbs return (0); 16297883Sgibbs} 163102681Sgibbs 16497883Sgibbs/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid 16597883Sgibbs KEY. */ 16697883Sgibbsint 16797883Sgibbsrl_bind_key_in_map (key, function, map) 16897883Sgibbs int key; 169102681Sgibbs Function *function; 170102681Sgibbs Keymap map; 171102681Sgibbs{ 172102681Sgibbs int result; 173102681Sgibbs Keymap oldmap; 174102681Sgibbs 175107441Sscottl oldmap = _rl_keymap; 176107441Sscottl _rl_keymap = map; 177107441Sscottl result = rl_bind_key (key, function); 178107441Sscottl _rl_keymap = oldmap; 179107441Sscottl return (result); 180107441Sscottl} 181102681Sgibbs 18297883Sgibbs/* Make KEY do nothing in the currently selected keymap. 18397883Sgibbs Returns non-zero in case of error. */ 18497883Sgibbsint 18597883Sgibbsrl_unbind_key (key) 18697883Sgibbs int key; 18797883Sgibbs{ 18897883Sgibbs return (rl_bind_key (key, (Function *)NULL)); 18997883Sgibbs} 190102681Sgibbs 191102681Sgibbs/* Make KEY do nothing in MAP. 192102681Sgibbs Returns non-zero in case of error. */ 193107623Sscottlint 194102681Sgibbsrl_unbind_key_in_map (key, map) 195102681Sgibbs int key; 196102681Sgibbs Keymap map; 197102681Sgibbs{ 19897883Sgibbs return (rl_bind_key_in_map (key, (Function *)NULL, map)); 19997883Sgibbs} 20097883Sgibbs 20197883Sgibbs/* Bind the key sequence represented by the string KEYSEQ to 20297883Sgibbs FUNCTION. This makes new keymaps as necessary. The initial 20397883Sgibbs place to do bindings is in MAP. */ 20497883Sgibbsint 20597883Sgibbsrl_set_key (keyseq, function, map) 206102681Sgibbs char *keyseq; 207102681Sgibbs Function *function; 208102681Sgibbs Keymap map; 209102681Sgibbs{ 210102681Sgibbs return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); 211102681Sgibbs} 212102681Sgibbs 21397883Sgibbs/* Bind the key sequence represented by the string KEYSEQ to 21497883Sgibbs the string of characters MACRO. This makes new keymaps as 21597883Sgibbs necessary. The initial place to do bindings is in MAP. */ 21697883Sgibbsint 21797883Sgibbsrl_macro_bind (keyseq, macro, map) 21897883Sgibbs char *keyseq, *macro; 21997883Sgibbs Keymap map; 22097883Sgibbs{ 221102681Sgibbs char *macro_keys; 222102681Sgibbs int macro_keys_len; 223102681Sgibbs 224102681Sgibbs macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1); 225102681Sgibbs 226102681Sgibbs if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len)) 227102681Sgibbs { 22897883Sgibbs free (macro_keys); 22997883Sgibbs return -1; 23097883Sgibbs } 23197883Sgibbs rl_generic_bind (ISMACR, keyseq, macro_keys, map); 23297883Sgibbs return 0; 23397883Sgibbs} 23497883Sgibbs 23597883Sgibbs/* Bind the key sequence represented by the string KEYSEQ to 23697883Sgibbs the arbitrary pointer DATA. TYPE says what kind of data is 237102681Sgibbs pointed to by DATA, right now this can be a function (ISFUNC), 238102681Sgibbs a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps 239102681Sgibbs as necessary. The initial place to do bindings is in MAP. */ 240102681Sgibbsint 241102681Sgibbsrl_generic_bind (type, keyseq, data, map) 242102681Sgibbs int type; 243102681Sgibbs char *keyseq, *data; 244102681Sgibbs Keymap map; 24597883Sgibbs{ 24697883Sgibbs char *keys; 24797883Sgibbs int keys_len; 24897883Sgibbs register int i; 24997883Sgibbs 25097883Sgibbs /* If no keys to bind to, exit right away. */ 25197883Sgibbs if (!keyseq || !*keyseq) 25297883Sgibbs { 25397883Sgibbs if (type == ISMACR) 25497883Sgibbs free (data); 25597883Sgibbs return -1; 25697883Sgibbs } 25797883Sgibbs 25897883Sgibbs keys = xmalloc (1 + (2 * strlen (keyseq))); 25997883Sgibbs 26097883Sgibbs /* Translate the ASCII representation of KEYSEQ into an array of 26197883Sgibbs characters. Stuff the characters into KEYS, and the length of 26297883Sgibbs KEYS into KEYS_LEN. */ 26397883Sgibbs if (rl_translate_keyseq (keyseq, keys, &keys_len)) 26497883Sgibbs { 26597883Sgibbs free (keys); 26697883Sgibbs return -1; 26797883Sgibbs } 26897883Sgibbs 26997883Sgibbs /* Bind keys, making new keymaps as necessary. */ 27097883Sgibbs for (i = 0; i < keys_len; i++) 27197883Sgibbs { 27297883Sgibbs int ic = (int) ((unsigned char)keys[i]); 27397883Sgibbs 27497883Sgibbs if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic)) 27597883Sgibbs { 27697883Sgibbs ic = UNMETA (ic); 27797883Sgibbs if (map[ESC].type == ISKMAP) 27897883Sgibbs map = FUNCTION_TO_KEYMAP (map, ESC); 279102681Sgibbs } 280102681Sgibbs 281102681Sgibbs if ((i + 1) < keys_len) 282102681Sgibbs { 283102681Sgibbs if (map[ic].type != ISKMAP) 28497883Sgibbs { 28597883Sgibbs if (map[ic].type == ISMACR) 28697883Sgibbs free ((char *)map[ic].function); 28797883Sgibbs 28897883Sgibbs map[ic].type = ISKMAP; 28997883Sgibbs map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap()); 29097883Sgibbs } 29197883Sgibbs map = FUNCTION_TO_KEYMAP (map, ic); 292102681Sgibbs } 293102681Sgibbs else 294102681Sgibbs { 295102681Sgibbs if (map[ic].type == ISMACR) 296102681Sgibbs free ((char *)map[ic].function); 29797883Sgibbs 29897883Sgibbs map[ic].function = KEYMAP_TO_FUNCTION (data); 29997883Sgibbs map[ic].type = type; 30097883Sgibbs } 30197883Sgibbs 30297883Sgibbs rl_binding_keymap = map; 30397883Sgibbs } 30497883Sgibbs free (keys); 30597883Sgibbs return 0; 30697883Sgibbs} 30797883Sgibbs 30897883Sgibbs/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, 30997883Sgibbs an array of characters. LEN gets the final length of ARRAY. Return 31097883Sgibbs non-zero if there was an error parsing SEQ. */ 31197883Sgibbsint 31297883Sgibbsrl_translate_keyseq (seq, array, len) 31397883Sgibbs char *seq, *array; 31497883Sgibbs int *len; 31597883Sgibbs{ 31697883Sgibbs register int i, c, l; 31797883Sgibbs 31897883Sgibbs for (i = l = 0; c = seq[i]; i++) 31997883Sgibbs { 32097883Sgibbs if (c == '\\') 32197883Sgibbs { 32297883Sgibbs c = seq[++i]; 32397883Sgibbs 32497883Sgibbs if (c == 0) 32597883Sgibbs break; 32697883Sgibbs 32797883Sgibbs if (((c == 'C' || c == 'M') && seq[i + 1] == '-') || (c == 'e')) 32897883Sgibbs { 32997883Sgibbs /* Handle special case of backwards define. */ 33097883Sgibbs if (strncmp (&seq[i], "C-\\M-", 5) == 0) 33197883Sgibbs { 33297883Sgibbs array[l++] = ESC; 33397883Sgibbs i += 5; 33497883Sgibbs array[l++] = CTRL (_rl_to_upper (seq[i])); 33597883Sgibbs if (!seq[i]) 33697883Sgibbs i--; 33797883Sgibbs continue; 33897883Sgibbs } 33997883Sgibbs 34097883Sgibbs switch (c) 34197883Sgibbs { 34297883Sgibbs case 'M': 34397883Sgibbs i++; 344102681Sgibbs array[l++] = ESC; /* XXX */ 345102681Sgibbs break; 346102681Sgibbs 347102681Sgibbs case 'C': 348102681Sgibbs i += 2; 349102681Sgibbs /* Special hack for C-?... */ 350102681Sgibbs array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); 351102681Sgibbs break; 352102681Sgibbs 353102681Sgibbs case 'e': 354102681Sgibbs array[l++] = ESC; 355102681Sgibbs } 356102681Sgibbs 357102681Sgibbs continue; 358102681Sgibbs } 359102681Sgibbs } 360102681Sgibbs array[l++] = c; 361102681Sgibbs } 362102681Sgibbs 36397883Sgibbs *len = l; 36497883Sgibbs array[l] = '\0'; 36597883Sgibbs return (0); 36697883Sgibbs} 36797883Sgibbs 36897883Sgibbschar * 36997883Sgibbsrl_untranslate_keyseq (seq) 37097883Sgibbs int seq; 371102681Sgibbs{ 372102681Sgibbs static char kseq[16]; 373102681Sgibbs int i, c; 374102681Sgibbs 375102681Sgibbs i = 0; 376102681Sgibbs c = seq; 377102681Sgibbs if (META_CHAR (c)) 378102681Sgibbs { 37997883Sgibbs kseq[i++] = '\\'; 38097883Sgibbs kseq[i++] = 'M'; 38197883Sgibbs kseq[i++] = '-'; 38297883Sgibbs c = UNMETA (c); 38397883Sgibbs } 38497883Sgibbs else if (CTRL_CHAR (c)) 38597883Sgibbs { 38697883Sgibbs kseq[i++] = '\\'; 38797883Sgibbs kseq[i++] = 'C'; 388102681Sgibbs kseq[i++] = '-'; 389107441Sscottl c = _rl_to_lower (UNCTRL (c)); 390102681Sgibbs } 391102681Sgibbs else if (c == RUBOUT) 392102681Sgibbs { 393102681Sgibbs kseq[i++] = '\\'; 394102681Sgibbs kseq[i++] = 'C'; 395102681Sgibbs kseq[i++] = '-'; 396102681Sgibbs c = '?'; 397102681Sgibbs } 398102681Sgibbs 39997883Sgibbs if (c == ESC) 40097883Sgibbs { 40197883Sgibbs kseq[i++] = '\\'; 40297883Sgibbs c = 'e'; 40397883Sgibbs } 40497883Sgibbs else if (c == '\\' || c == '"') 40597883Sgibbs { 40697883Sgibbs kseq[i++] = '\\'; 40797883Sgibbs } 408102681Sgibbs 409102681Sgibbs kseq[i++] = (unsigned char) c; 410102681Sgibbs kseq[i] = '\0'; 411102681Sgibbs return kseq; 412102681Sgibbs} 413102681Sgibbs 41497883Sgibbsstatic char * 41597883Sgibbs_rl_untranslate_macro_value (seq) 41697883Sgibbs char *seq; 41797883Sgibbs{ 41897883Sgibbs char *ret, *r, *s; 41997883Sgibbs int c; 42097883Sgibbs 42197883Sgibbs r = ret = xmalloc (7 * strlen (seq) + 1); 42297883Sgibbs for (s = seq; *s; s++) 423102681Sgibbs { 424102681Sgibbs c = *s; 425102681Sgibbs if (META_CHAR (c)) 426102681Sgibbs { 427102681Sgibbs *r++ = '\\'; 428102681Sgibbs *r++ = 'M'; 429102681Sgibbs *r++ = '-'; 43097883Sgibbs c = UNMETA (c); 43197883Sgibbs } 43297883Sgibbs else if (CTRL_CHAR (c) && c != ESC) 43397883Sgibbs { 43497883Sgibbs *r++ = '\\'; 43597883Sgibbs *r++ = 'C'; 43697883Sgibbs *r++ = '-'; 43797883Sgibbs c = _rl_to_lower (UNCTRL (c)); 43897883Sgibbs } 439102681Sgibbs else if (c == RUBOUT) 440102681Sgibbs { 441102681Sgibbs *r++ = '\\'; 44297883Sgibbs *r++ = 'C'; 44397883Sgibbs *r++ = '-'; 44497883Sgibbs c = '?'; 44597883Sgibbs } 44697883Sgibbs 44797883Sgibbs if (c == ESC) 448102681Sgibbs { 449102681Sgibbs *r++ = '\\'; 450102681Sgibbs c = 'e'; 451102681Sgibbs } 45297883Sgibbs else if (c == '\\' || c == '"') 45397883Sgibbs *r++ = '\\'; 45497883Sgibbs 45597883Sgibbs *r++ = (unsigned char)c; 45697883Sgibbs } 45797883Sgibbs *r = '\0'; 45897883Sgibbs return ret; 45997883Sgibbs} 46097883Sgibbs 461102681Sgibbs/* Return a pointer to the function that STRING represents. 462102681Sgibbs If STRING doesn't have a matching function, then a NULL pointer 463102681Sgibbs is returned. */ 46497883SgibbsFunction * 46597883Sgibbsrl_named_function (string) 46697883Sgibbs char *string; 46797883Sgibbs{ 46897883Sgibbs register int i; 46997883Sgibbs 47097883Sgibbs rl_initialize_funmap (); 47197883Sgibbs 47297883Sgibbs for (i = 0; funmap[i]; i++) 47397883Sgibbs if (_rl_stricmp (funmap[i]->name, string) == 0) 47497883Sgibbs return (funmap[i]->function); 47597883Sgibbs return ((Function *)NULL); 47697883Sgibbs} 47797883Sgibbs 47897883Sgibbs/* Return the function (or macro) definition which would be invoked via 47997883Sgibbs KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is 48097883Sgibbs used. TYPE, if non-NULL, is a pointer to an int which will receive the 48197883Sgibbs type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap), 48297883Sgibbs or ISMACR (macro). */ 48397883SgibbsFunction * 48497883Sgibbsrl_function_of_keyseq (keyseq, map, type) 48597883Sgibbs char *keyseq; 48697883Sgibbs Keymap map; 487107441Sscottl int *type; 488107441Sscottl{ 489107441Sscottl register int i; 490107441Sscottl 491107441Sscottl if (!map) 492107441Sscottl map = _rl_keymap; 493107441Sscottl 494107441Sscottl for (i = 0; keyseq && keyseq[i]; i++) 495107441Sscottl { 496107441Sscottl int ic = keyseq[i]; 497107441Sscottl 49897883Sgibbs if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) 49997883Sgibbs { 50097883Sgibbs if (map[ESC].type != ISKMAP) 50197883Sgibbs { 50297883Sgibbs if (type) 50397883Sgibbs *type = map[ESC].type; 50497883Sgibbs 50597883Sgibbs return (map[ESC].function); 50697883Sgibbs } 50797883Sgibbs else 50897883Sgibbs { 50997883Sgibbs map = FUNCTION_TO_KEYMAP (map, ESC); 51097883Sgibbs ic = UNMETA (ic); 51197883Sgibbs } 51297883Sgibbs } 51397883Sgibbs 51497883Sgibbs if (map[ic].type == ISKMAP) 51597883Sgibbs { 51697883Sgibbs /* If this is the last key in the key sequence, return the 51797883Sgibbs map. */ 51897883Sgibbs if (!keyseq[i + 1]) 51997883Sgibbs { 52097883Sgibbs if (type) 52197883Sgibbs *type = ISKMAP; 52297883Sgibbs 52397883Sgibbs return (map[ic].function); 52497883Sgibbs } 52597883Sgibbs else 52697883Sgibbs map = FUNCTION_TO_KEYMAP (map, ic); 52797883Sgibbs } 52897883Sgibbs else 52997883Sgibbs { 53097883Sgibbs if (type) 53197883Sgibbs *type = map[ic].type; 53297883Sgibbs 53397883Sgibbs return (map[ic].function); 53497883Sgibbs } 53597883Sgibbs } 53697883Sgibbs return ((Function *) NULL); 53797883Sgibbs} 53897883Sgibbs 53997883Sgibbs/* The last key bindings file read. */ 54097883Sgibbsstatic char *last_readline_init_file = (char *)NULL; 54197883Sgibbs 54297883Sgibbs/* The file we're currently reading key bindings from. */ 54397883Sgibbsstatic char *current_readline_init_file; 54497883Sgibbsstatic int current_readline_init_lineno; 54597883Sgibbs 54697883Sgibbs/* Re-read the current keybindings file. */ 54797883Sgibbsint 54897883Sgibbsrl_re_read_init_file (count, ignore) 54997883Sgibbs int count, ignore; 55097883Sgibbs{ 55197883Sgibbs int r; 55297883Sgibbs r = rl_read_init_file ((char *)NULL); 55397883Sgibbs rl_set_keymap_from_edit_mode (); 55497883Sgibbs return r; 55597883Sgibbs} 55697883Sgibbs 55797883Sgibbs/* Do key bindings from a file. If FILENAME is NULL it defaults 55897883Sgibbs to the first non-null filename from this list: 55997883Sgibbs 1. the filename used for the previous call 56097883Sgibbs 2. the value of the shell variable `INPUTRC' 56197883Sgibbs 3. ~/.inputrc 56297883Sgibbs If the file existed and could be opened and read, 0 is returned, 56397883Sgibbs otherwise errno is returned. */ 56497883Sgibbsint 56597883Sgibbsrl_read_init_file (filename) 56697883Sgibbs char *filename; 56797883Sgibbs{ 56897883Sgibbs register int i; 56997883Sgibbs char *buffer, *openname, *line, *end; 57097883Sgibbs struct stat finfo; 571102681Sgibbs int file; 572102681Sgibbs 573102681Sgibbs /* Default the filename. */ 574102681Sgibbs if (filename == 0) 575102681Sgibbs { 576102681Sgibbs filename = last_readline_init_file; 577102681Sgibbs if (filename == 0) 578102681Sgibbs filename = get_env_value ("INPUTRC"); 579102681Sgibbs if (filename == 0) 580102681Sgibbs filename = DEFAULT_INPUTRC; 581102681Sgibbs } 582102681Sgibbs 583102681Sgibbs if (*filename == 0) 584102681Sgibbs filename = DEFAULT_INPUTRC; 585102681Sgibbs 586102681Sgibbs current_readline_init_file = filename; 587102681Sgibbs openname = tilde_expand (filename); 588102681Sgibbs 589102681Sgibbs if ((stat (openname, &finfo) < 0) || 590102681Sgibbs (file = open (openname, O_RDONLY, 0666)) < 0) 59197883Sgibbs { 59297883Sgibbs free (openname); 59397883Sgibbs return (errno); 59497883Sgibbs } 59597883Sgibbs else 59697883Sgibbs free (openname); 59797883Sgibbs 59897883Sgibbs if (filename != last_readline_init_file) 59997883Sgibbs { 60097883Sgibbs if (last_readline_init_file) 60197883Sgibbs free (last_readline_init_file); 60297883Sgibbs 60397883Sgibbs last_readline_init_file = savestring (filename); 60497883Sgibbs } 60597883Sgibbs 60697883Sgibbs /* Read the file into BUFFER. */ 60797883Sgibbs buffer = (char *)xmalloc ((int)finfo.st_size + 1); 608102681Sgibbs i = read (file, buffer, finfo.st_size); 609102681Sgibbs close (file); 610102681Sgibbs 611102681Sgibbs if (i != finfo.st_size) 61297883Sgibbs return (errno); 61397883Sgibbs 61497883Sgibbs /* Loop over the lines in the file. Lines that start with `#' are 61597883Sgibbs comments; all other lines are commands for readline initialization. */ 61697883Sgibbs current_readline_init_lineno = 1; 61797883Sgibbs line = buffer; 61897883Sgibbs end = buffer + finfo.st_size; 61997883Sgibbs while (line < end) 62097883Sgibbs { 62197883Sgibbs /* Find the end of this line. */ 62297883Sgibbs for (i = 0; line + i != end && line[i] != '\n'; i++); 62397883Sgibbs 62497883Sgibbs /* Mark end of line. */ 62597883Sgibbs line[i] = '\0'; 62697883Sgibbs 62797883Sgibbs /* Skip leading whitespace. */ 62897883Sgibbs while (*line && whitespace (*line)) 629102681Sgibbs { 630102681Sgibbs line++; 63197883Sgibbs i--; 63297883Sgibbs } 63397883Sgibbs 63497883Sgibbs /* If the line is not a comment, then parse it. */ 63597883Sgibbs if (*line && *line != '#') 63697883Sgibbs rl_parse_and_bind (line); 63797883Sgibbs 63897883Sgibbs /* Move to the next line. */ 63997883Sgibbs line += i + 1; 640102681Sgibbs current_readline_init_lineno++; 641102681Sgibbs } 64297883Sgibbs free (buffer); 64397883Sgibbs return (0); 64497883Sgibbs} 64597883Sgibbs 64697883Sgibbsstatic void 64797883Sgibbs_rl_init_file_error (msg) 64897883Sgibbs char *msg; 64997883Sgibbs{ 65097883Sgibbs fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file, 651102681Sgibbs current_readline_init_lineno, 652102681Sgibbs msg); 65397883Sgibbs} 65497883Sgibbs 65597883Sgibbs/* **************************************************************** */ 65697883Sgibbs/* */ 65797883Sgibbs/* Parser Directives */ 65897883Sgibbs/* */ 65997883Sgibbs/* **************************************************************** */ 66097883Sgibbs 66197883Sgibbs/* Conditionals. */ 662102681Sgibbs 663102681Sgibbs/* Calling programs set this to have their argv[0]. */ 664102681Sgibbschar *rl_readline_name = "other"; 665102681Sgibbs 666102681Sgibbs/* Stack of previous values of parsing_conditionalized_out. */ 667102681Sgibbsstatic unsigned char *if_stack = (unsigned char *)NULL; 66897883Sgibbsstatic int if_stack_depth; 66997883Sgibbsstatic int if_stack_size; 67097883Sgibbs 67197883Sgibbs/* Push _rl_parsing_conditionalized_out, and set parser state based 67297883Sgibbs on ARGS. */ 67397883Sgibbsstatic int 67497883Sgibbsparser_if (args) 67597883Sgibbs char *args; 67697883Sgibbs{ 677102681Sgibbs register int i; 67897883Sgibbs 67997883Sgibbs /* Push parser state. */ 68097883Sgibbs if (if_stack_depth + 1 >= if_stack_size) 68197883Sgibbs { 68297883Sgibbs if (!if_stack) 68397883Sgibbs if_stack = (unsigned char *)xmalloc (if_stack_size = 20); 68497883Sgibbs else 68597883Sgibbs if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20); 68697883Sgibbs } 687102681Sgibbs if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out; 68897883Sgibbs 68997883Sgibbs /* If parsing is turned off, then nothing can turn it back on except 69097883Sgibbs for finding the matching endif. In that case, return right now. */ 69197883Sgibbs if (_rl_parsing_conditionalized_out) 69297883Sgibbs return 0; 69397883Sgibbs 69497883Sgibbs /* Isolate first argument. */ 69597883Sgibbs for (i = 0; args[i] && !whitespace (args[i]); i++); 69697883Sgibbs 697102681Sgibbs if (args[i]) 69897883Sgibbs args[i++] = '\0'; 69997883Sgibbs 70097883Sgibbs /* Handle "if term=foo" and "if mode=emacs" constructs. If this 70197883Sgibbs isn't term=foo, or mode=emacs, then check to see if the first 70297883Sgibbs word in ARGS is the same as the value stored in rl_readline_name. */ 70397883Sgibbs if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0) 70497883Sgibbs { 70597883Sgibbs char *tem, *tname; 70697883Sgibbs 707102681Sgibbs /* Terminals like "aaa-60" are equivalent to "aaa". */ 708102681Sgibbs tname = savestring (rl_terminal_name); 709102681Sgibbs tem = strchr (tname, '-'); 710102681Sgibbs if (tem) 711102681Sgibbs *tem = '\0'; 712102681Sgibbs 71397883Sgibbs /* Test the `long' and `short' forms of the terminal name so that 71497883Sgibbs if someone has a `sun-cmd' and does not want to have bindings 71597883Sgibbs that will be executed if the terminal is a `sun', they can put 71697883Sgibbs `$if term=sun-cmd' into their .inputrc. */ 71797883Sgibbs _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) && 71897883Sgibbs _rl_stricmp (args + 5, rl_terminal_name); 71997883Sgibbs free (tname); 72097883Sgibbs } 72197883Sgibbs#if defined (VI_MODE) 722102681Sgibbs else if (_rl_strnicmp (args, "mode=", 5) == 0) 72397883Sgibbs { 72497883Sgibbs int mode; 72597883Sgibbs 72697883Sgibbs if (_rl_stricmp (args + 5, "emacs") == 0) 72797883Sgibbs mode = emacs_mode; 72897883Sgibbs else if (_rl_stricmp (args + 5, "vi") == 0) 72997883Sgibbs mode = vi_mode; 73097883Sgibbs else 73197883Sgibbs mode = no_mode; 732102681Sgibbs 73397883Sgibbs _rl_parsing_conditionalized_out = mode != rl_editing_mode; 73497883Sgibbs } 73597883Sgibbs#endif /* VI_MODE */ 73697883Sgibbs /* Check to see if the first word in ARGS is the same as the 73797883Sgibbs value stored in rl_readline_name. */ 73897883Sgibbs else if (_rl_stricmp (args, rl_readline_name) == 0) 73997883Sgibbs _rl_parsing_conditionalized_out = 0; 74097883Sgibbs else 74197883Sgibbs _rl_parsing_conditionalized_out = 1; 742102681Sgibbs return 0; 74397883Sgibbs} 74497883Sgibbs 74597883Sgibbs/* Invert the current parser state if there is anything on the stack. */ 74697883Sgibbsstatic int 74797883Sgibbsparser_else (args) 74897883Sgibbs char *args; 74997883Sgibbs{ 75097883Sgibbs register int i; 75197883Sgibbs 75297883Sgibbs if (!if_stack_depth) 75397883Sgibbs { 75497883Sgibbs /* Error message? */ 75597883Sgibbs return 0; 75697883Sgibbs } 75797883Sgibbs 75897883Sgibbs /* Check the previous (n - 1) levels of the stack to make sure that 75997883Sgibbs we haven't previously turned off parsing. */ 76097883Sgibbs for (i = 0; i < if_stack_depth - 1; i++) 761102681Sgibbs if (if_stack[i] == 1) 76297883Sgibbs return 0; 76397883Sgibbs 76497883Sgibbs /* Invert the state of parsing if at top level. */ 76597883Sgibbs _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out; 76697883Sgibbs return 0; 76797883Sgibbs} 76897883Sgibbs 76997883Sgibbs/* Terminate a conditional, popping the value of 77097883Sgibbs _rl_parsing_conditionalized_out from the stack. */ 771102681Sgibbsstatic int 77297883Sgibbsparser_endif (args) 77397883Sgibbs char *args; 77497883Sgibbs{ 77597883Sgibbs if (if_stack_depth) 77697883Sgibbs _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; 77797883Sgibbs else 77897883Sgibbs { 77997883Sgibbs /* *** What, no error message? *** */ 78097883Sgibbs } 781102681Sgibbs return 0; 78297883Sgibbs} 78397883Sgibbs 78497883Sgibbs/* Associate textual names with actual functions. */ 78597883Sgibbsstatic struct { 78697883Sgibbs char *name; 78797883Sgibbs Function *function; 78897883Sgibbs} parser_directives [] = { 78997883Sgibbs { "if", parser_if }, 79097883Sgibbs { "endif", parser_endif }, 791102681Sgibbs { "else", parser_else }, 792102681Sgibbs { (char *)0x0, (Function *)0x0 } 793102681Sgibbs}; 794102681Sgibbs 795102681Sgibbs/* Handle a parser directive. STATEMENT is the line of the directive 796102681Sgibbs without any leading `$'. */ 797102681Sgibbsstatic int 79897883Sgibbshandle_parser_directive (statement) 79997883Sgibbs char *statement; 80097883Sgibbs{ 80197883Sgibbs register int i; 80297883Sgibbs char *directive, *args; 80397883Sgibbs 80497883Sgibbs /* Isolate the actual directive. */ 80597883Sgibbs 80697883Sgibbs /* Skip whitespace. */ 80797883Sgibbs for (i = 0; whitespace (statement[i]); i++); 80897883Sgibbs 80997883Sgibbs directive = &statement[i]; 81097883Sgibbs 81197883Sgibbs for (; statement[i] && !whitespace (statement[i]); i++); 81297883Sgibbs 81397883Sgibbs if (statement[i]) 81497883Sgibbs statement[i++] = '\0'; 81597883Sgibbs 81697883Sgibbs for (; statement[i] && whitespace (statement[i]); i++); 81797883Sgibbs 81897883Sgibbs args = &statement[i]; 81997883Sgibbs 82097883Sgibbs /* Lookup the command, and act on it. */ 82197883Sgibbs for (i = 0; parser_directives[i].name; i++) 82297883Sgibbs if (_rl_stricmp (directive, parser_directives[i].name) == 0) 82397883Sgibbs { 82497883Sgibbs (*parser_directives[i].function) (args); 82597883Sgibbs return (0); 82697883Sgibbs } 82797883Sgibbs 82897883Sgibbs /* *** Should an error message be output? */ 82997883Sgibbs return (1); 83097883Sgibbs} 83197883Sgibbs 83297883Sgibbs/* Read the binding command from STRING and perform it. 83397883Sgibbs A key binding command looks like: Keyname: function-name\0, 83497883Sgibbs a variable binding command looks like: set variable value. 835102681Sgibbs A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ 836102681Sgibbsint 837102681Sgibbsrl_parse_and_bind (string) 838102681Sgibbs char *string; 839102681Sgibbs{ 840102681Sgibbs char *funname, *kname; 841102681Sgibbs register int c, i; 842102681Sgibbs int key, equivalency; 84397883Sgibbs 84497883Sgibbs while (string && whitespace (*string)) 84597883Sgibbs string++; 84697883Sgibbs 84797883Sgibbs if (!string || !*string || *string == '#') 84897883Sgibbs return 0; 84997883Sgibbs 85097883Sgibbs /* If this is a parser directive, act on it. */ 85197883Sgibbs if (*string == '$') 852102681Sgibbs { 853102681Sgibbs handle_parser_directive (&string[1]); 854102681Sgibbs return 0; 855102681Sgibbs } 856102681Sgibbs 857102681Sgibbs /* If we aren't supposed to be parsing right now, then we're done. */ 858102681Sgibbs if (_rl_parsing_conditionalized_out) 859102681Sgibbs return 0; 86097883Sgibbs 86197883Sgibbs i = 0; 86297883Sgibbs /* If this keyname is a complex key expression surrounded by quotes, 86397883Sgibbs advance to after the matching close quote. This code allows the 86497883Sgibbs backslash to quote characters in the key expression. */ 86597883Sgibbs if (*string == '"') 86697883Sgibbs { 86797883Sgibbs int passc = 0; 86897883Sgibbs 869102681Sgibbs for (i = 1; c = string[i]; i++) 870102681Sgibbs { 871102681Sgibbs if (passc) 872102681Sgibbs { 873102681Sgibbs passc = 0; 874102681Sgibbs continue; 875102681Sgibbs } 876102681Sgibbs 87797883Sgibbs if (c == '\\') 87897883Sgibbs { 87997883Sgibbs passc++; 88097883Sgibbs continue; 88197883Sgibbs } 88297883Sgibbs 88397883Sgibbs if (c == '"') 88497883Sgibbs break; 88597883Sgibbs } 886102681Sgibbs /* If we didn't find a closing quote, abort the line. */ 88797883Sgibbs if (string[i] == '\0') 88897883Sgibbs { 88997883Sgibbs _rl_init_file_error ("no closing `\"' in key binding"); 89097883Sgibbs return 1; 89197883Sgibbs } 89297883Sgibbs } 89397883Sgibbs 89497883Sgibbs /* Advance to the colon (:) or whitespace which separates the two objects. */ 89597883Sgibbs for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); 896102681Sgibbs 89797883Sgibbs equivalency = (c == ':' && string[i + 1] == '='); 89897883Sgibbs 89997883Sgibbs /* Mark the end of the command (or keyname). */ 90097883Sgibbs if (string[i]) 90197883Sgibbs string[i++] = '\0'; 90297883Sgibbs 90397883Sgibbs /* If doing assignment, skip the '=' sign as well. */ 90497883Sgibbs if (equivalency) 90597883Sgibbs string[i++] = '\0'; 906102681Sgibbs 90797883Sgibbs /* If this is a command to set a variable, then do that. */ 90897883Sgibbs if (_rl_stricmp (string, "set") == 0) 90997883Sgibbs { 91097883Sgibbs char *var = string + i; 91197883Sgibbs char *value; 91297883Sgibbs 91397883Sgibbs /* Make VAR point to start of variable name. */ 91497883Sgibbs while (*var && whitespace (*var)) var++; 91597883Sgibbs 916102681Sgibbs /* Make value point to start of value string. */ 917102681Sgibbs value = var; 91897883Sgibbs while (*value && !whitespace (*value)) value++; 91997883Sgibbs if (*value) 92097883Sgibbs *value++ = '\0'; 92197883Sgibbs while (*value && whitespace (*value)) value++; 92297883Sgibbs 92397883Sgibbs rl_variable_bind (var, value); 92497883Sgibbs return 0; 92597883Sgibbs } 92697883Sgibbs 927102681Sgibbs /* Skip any whitespace between keyname and funname. */ 92897883Sgibbs for (; string[i] && whitespace (string[i]); i++); 92997883Sgibbs funname = &string[i]; 93097883Sgibbs 93197883Sgibbs /* Now isolate funname. 93297883Sgibbs For straight function names just look for whitespace, since 93397883Sgibbs that will signify the end of the string. But this could be a 93497883Sgibbs macro definition. In that case, the string is quoted, so skip 93597883Sgibbs to the matching delimiter. We allow the backslash to quote the 93697883Sgibbs delimiter characters in the macro body. */ 937102681Sgibbs /* This code exists to allow whitespace in macro expansions, which 93897883Sgibbs would otherwise be gobbled up by the next `for' loop.*/ 93997883Sgibbs /* XXX - it may be desirable to allow backslash quoting only if " is 94097883Sgibbs the quoted string delimiter, like the shell. */ 94197883Sgibbs if (*funname == '\'' || *funname == '"') 94297883Sgibbs { 94397883Sgibbs int delimiter = string[i++]; 94497883Sgibbs int passc = 0; 94597883Sgibbs 94697883Sgibbs for (; c = string[i]; i++) 947102681Sgibbs { 94897883Sgibbs if (passc) 94997883Sgibbs { 95097883Sgibbs passc = 0; 95197883Sgibbs continue; 95297883Sgibbs } 95397883Sgibbs 95497883Sgibbs if (c == '\\') 95597883Sgibbs { 95697883Sgibbs passc = 1; 957102681Sgibbs continue; 95897883Sgibbs } 95997883Sgibbs 96097883Sgibbs if (c == delimiter) 96197883Sgibbs break; 96297883Sgibbs } 96397883Sgibbs if (c) 96497883Sgibbs i++; 96597883Sgibbs } 96697883Sgibbs 967102681Sgibbs /* Advance to the end of the string. */ 968102681Sgibbs for (; string[i] && !whitespace (string[i]); i++); 96997883Sgibbs 97097883Sgibbs /* No extra whitespace at the end of the string. */ 97197883Sgibbs string[i] = '\0'; 97297883Sgibbs 97397883Sgibbs /* Handle equivalency bindings here. Make the left-hand side be exactly 97497883Sgibbs whatever the right-hand evaluates to, including keymaps. */ 97597883Sgibbs if (equivalency) 97697883Sgibbs { 97797883Sgibbs return 0; 978102681Sgibbs } 97997883Sgibbs 98097883Sgibbs /* If this is a new-style key-binding, then do the binding with 98197883Sgibbs rl_set_key (). Otherwise, let the older code deal with it. */ 98297883Sgibbs if (*string == '"') 98397883Sgibbs { 98497883Sgibbs char *seq = xmalloc (1 + strlen (string)); 98597883Sgibbs register int j, k = 0; 98697883Sgibbs int passc = 0; 98797883Sgibbs 988102681Sgibbs for (j = 1; string[j]; j++) 989102681Sgibbs { 99097883Sgibbs /* Allow backslash to quote characters, but leave them in place. 99197883Sgibbs This allows a string to end with a backslash quoting another 99297883Sgibbs backslash, or with a backslash quoting a double quote. The 99397883Sgibbs backslashes are left in place for rl_translate_keyseq (). */ 99497883Sgibbs if (passc || (string[j] == '\\')) 99597883Sgibbs { 99697883Sgibbs seq[k++] = string[j]; 99797883Sgibbs passc = !passc; 99897883Sgibbs continue; 99997883Sgibbs } 100097883Sgibbs 100197883Sgibbs if (string[j] == '"') 100297883Sgibbs break; 100397883Sgibbs 100497883Sgibbs seq[k++] = string[j]; 100597883Sgibbs } 100697883Sgibbs seq[k] = '\0'; 100797883Sgibbs 1008102681Sgibbs /* Binding macro? */ 100997883Sgibbs if (*funname == '\'' || *funname == '"') 101097883Sgibbs { 101197883Sgibbs j = strlen (funname); 101297883Sgibbs 101397883Sgibbs /* Remove the delimiting quotes from each end of FUNNAME. */ 101497883Sgibbs if (j && funname[j - 1] == *funname) 101597883Sgibbs funname[j - 1] = '\0'; 101697883Sgibbs 101797883Sgibbs rl_macro_bind (seq, &funname[1], _rl_keymap); 1018102681Sgibbs } 1019102681Sgibbs else 102097883Sgibbs rl_set_key (seq, rl_named_function (funname), _rl_keymap); 102197883Sgibbs 102297883Sgibbs free (seq); 102397883Sgibbs return 0; 102497883Sgibbs } 102597883Sgibbs 102697883Sgibbs /* Get the actual character we want to deal with. */ 102797883Sgibbs kname = strrchr (string, '-'); 102897883Sgibbs if (!kname) 102997883Sgibbs kname = string; 1030102681Sgibbs else 103197883Sgibbs kname++; 103297883Sgibbs 103397883Sgibbs key = glean_key_from_name (kname); 103497883Sgibbs 103597883Sgibbs /* Add in control and meta bits. */ 103697883Sgibbs if (substring_member_of_array (string, possible_control_prefixes)) 103797883Sgibbs key = CTRL (_rl_to_upper (key)); 103897883Sgibbs 1039102681Sgibbs if (substring_member_of_array (string, possible_meta_prefixes)) 1040102681Sgibbs key = META (key); 1041102681Sgibbs 1042102681Sgibbs /* Temporary. Handle old-style keyname with macro-binding. */ 1043102681Sgibbs if (*funname == '\'' || *funname == '"') 1044102681Sgibbs { 1045102681Sgibbs unsigned char useq[2]; 1046102681Sgibbs int fl = strlen (funname); 104797883Sgibbs 104897883Sgibbs useq[0] = key; useq[1] = '\0'; 104997883Sgibbs if (fl && funname[fl - 1] == *funname) 105097883Sgibbs funname[fl - 1] = '\0'; 105197883Sgibbs 105297883Sgibbs rl_macro_bind (useq, &funname[1], _rl_keymap); 105397883Sgibbs } 105497883Sgibbs#if defined (PREFIX_META_HACK) 105597883Sgibbs /* Ugly, but working hack to keep prefix-meta around. */ 1056102681Sgibbs else if (_rl_stricmp (funname, "prefix-meta") == 0) 105797883Sgibbs { 105897883Sgibbs char seq[2]; 105997883Sgibbs 106097883Sgibbs seq[0] = key; 106197883Sgibbs seq[1] = '\0'; 106297883Sgibbs rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap); 106397883Sgibbs } 106497883Sgibbs#endif /* PREFIX_META_HACK */ 106597883Sgibbs else 1066102681Sgibbs rl_bind_key (key, rl_named_function (funname)); 1067102681Sgibbs return 0; 106897883Sgibbs} 106997883Sgibbs 107097883Sgibbs/* Simple structure for boolean readline variables (i.e., those that can 107197883Sgibbs have one of two values; either "On" or 1 for truth, or "Off" or 0 for 107297883Sgibbs false. */ 107397883Sgibbs 107497883Sgibbsstatic struct { 107597883Sgibbs char *name; 107697883Sgibbs int *value; 1077102681Sgibbs} boolean_varlist [] = { 1078102681Sgibbs#if defined (PAREN_MATCHING) 1079102681Sgibbs { "blink-matching-paren", &rl_blink_matching_paren }, 1080102681Sgibbs#endif 1081102681Sgibbs { "convert-meta", &_rl_convert_meta_chars_to_ascii }, 1082102681Sgibbs { "disable-completion", &rl_inhibit_completion }, 1083102681Sgibbs { "enable-keypad", &_rl_enable_keypad }, 1084102681Sgibbs { "expand-tilde", &rl_complete_with_tilde_expansion }, 108597883Sgibbs { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode }, 108697883Sgibbs { "input-meta", &_rl_meta_flag }, 108797883Sgibbs { "mark-directories", &_rl_complete_mark_directories }, 108897883Sgibbs { "mark-modified-lines", &_rl_mark_modified_lines }, 108997883Sgibbs { "meta-flag", &_rl_meta_flag }, 109097883Sgibbs { "output-meta", &_rl_output_meta_chars }, 109197883Sgibbs { "show-all-if-ambiguous", &_rl_complete_show_all }, 109297883Sgibbs#if defined (VISIBLE_STATS) 109397883Sgibbs { "visible-stats", &rl_visible_stats }, 1094102681Sgibbs#endif /* VISIBLE_STATS */ 1095102681Sgibbs { (char *)NULL, (int *)NULL } 1096102681Sgibbs}; 1097102681Sgibbs 1098102681Sgibbsint 1099102681Sgibbsrl_variable_bind (name, value) 1100102681Sgibbs char *name, *value; 1101102681Sgibbs{ 110297883Sgibbs register int i; 110397883Sgibbs 110497883Sgibbs /* Check for simple variables first. */ 110597883Sgibbs for (i = 0; boolean_varlist[i].name; i++) 110697883Sgibbs { 110797883Sgibbs if (_rl_stricmp (name, boolean_varlist[i].name) == 0) 110897883Sgibbs { 110997883Sgibbs /* A variable is TRUE if the "value" is "on", "1" or "". */ 111097883Sgibbs *boolean_varlist[i].value = *value == 0 || 1111102681Sgibbs _rl_stricmp (value, "on") == 0 || 1112102681Sgibbs (value[0] == '1' && value[1] == '\0'); 1113102681Sgibbs return 0; 1114102681Sgibbs } 1115102681Sgibbs } 1116102681Sgibbs 1117102681Sgibbs /* Not a boolean variable, so check for specials. */ 111897883Sgibbs 111997883Sgibbs /* Editing mode change? */ 112097883Sgibbs if (_rl_stricmp (name, "editing-mode") == 0) 112197883Sgibbs { 112297883Sgibbs if (_rl_strnicmp (value, "vi", 2) == 0) 112397883Sgibbs { 112497883Sgibbs#if defined (VI_MODE) 112597883Sgibbs _rl_keymap = vi_insertion_keymap; 112697883Sgibbs rl_editing_mode = vi_mode; 1127102681Sgibbs#endif /* VI_MODE */ 1128102681Sgibbs } 1129102681Sgibbs else if (_rl_strnicmp (value, "emacs", 5) == 0) 1130102681Sgibbs { 1131102681Sgibbs _rl_keymap = emacs_standard_keymap; 1132102681Sgibbs rl_editing_mode = emacs_mode; 1133102681Sgibbs } 1134102681Sgibbs } 113597883Sgibbs 113697883Sgibbs /* Comment string change? */ 113797883Sgibbs else if (_rl_stricmp (name, "comment-begin") == 0) 113897883Sgibbs { 113997883Sgibbs if (*value) 114097883Sgibbs { 114197883Sgibbs if (_rl_comment_begin) 114297883Sgibbs free (_rl_comment_begin); 114397883Sgibbs 1144102681Sgibbs _rl_comment_begin = savestring (value); 1145102681Sgibbs } 1146102681Sgibbs } 1147102681Sgibbs else if (_rl_stricmp (name, "completion-query-items") == 0) 1148102681Sgibbs { 1149102681Sgibbs int nval = 100; 1150102681Sgibbs if (*value) 115197883Sgibbs { 115297883Sgibbs nval = atoi (value); 115397883Sgibbs if (nval < 0) 115497883Sgibbs nval = 0; 115597883Sgibbs } 115697883Sgibbs rl_completion_query_items = nval; 115797883Sgibbs } 115897883Sgibbs else if (_rl_stricmp (name, "keymap") == 0) 115997883Sgibbs { 1160102681Sgibbs Keymap kmap; 1161102681Sgibbs kmap = rl_get_keymap_by_name (value); 1162102681Sgibbs if (kmap) 1163102681Sgibbs rl_set_keymap (kmap); 1164102681Sgibbs } 1165102681Sgibbs else if (_rl_stricmp (name, "bell-style") == 0) 116697883Sgibbs { 116797883Sgibbs if (!*value) 116897883Sgibbs _rl_bell_preference = AUDIBLE_BELL; 116997883Sgibbs else 117097883Sgibbs { 117197883Sgibbs if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0) 1172107623Sscottl _rl_bell_preference = NO_BELL; 117397883Sgibbs else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0) 117497883Sgibbs _rl_bell_preference = AUDIBLE_BELL; 1175102681Sgibbs else if (_rl_stricmp (value, "visible") == 0) 1176102681Sgibbs _rl_bell_preference = VISIBLE_BELL; 1177102681Sgibbs } 1178102681Sgibbs } 117997883Sgibbs else if (_rl_stricmp (name, "prefer-visible-bell") == 0) 118097883Sgibbs { 118197883Sgibbs /* Backwards compatibility. */ 118297883Sgibbs if (*value && (_rl_stricmp (value, "on") == 0 || 118397883Sgibbs (*value == '1' && !value[1]))) 118497883Sgibbs _rl_bell_preference = VISIBLE_BELL; 118597883Sgibbs else 118697883Sgibbs _rl_bell_preference = AUDIBLE_BELL; 118797883Sgibbs } 118897883Sgibbs 118997883Sgibbs return 0; 119097883Sgibbs} 119197883Sgibbs 119297883Sgibbs/* Return the character which matches NAME. 119397883Sgibbs For example, `Space' returns ' '. */ 119497883Sgibbs 119597883Sgibbstypedef struct { 119697883Sgibbs char *name; 119797883Sgibbs int value; 119897883Sgibbs} assoc_list; 119997883Sgibbs 120097883Sgibbsstatic assoc_list name_key_alist[] = { 120197883Sgibbs { "DEL", 0x7f }, 120297883Sgibbs { "ESC", '\033' }, 120397883Sgibbs { "Escape", '\033' }, 120497883Sgibbs { "LFD", '\n' }, 120597883Sgibbs { "Newline", '\n' }, 120697883Sgibbs { "RET", '\r' }, 120797883Sgibbs { "Return", '\r' }, 120897883Sgibbs { "Rubout", 0x7f }, 120997883Sgibbs { "SPC", ' ' }, 121097883Sgibbs { "Space", ' ' }, 121197883Sgibbs { "Tab", 0x09 }, 121297883Sgibbs { (char *)0x0, 0 } 121397883Sgibbs}; 121497883Sgibbs 121597883Sgibbsstatic int 121697883Sgibbsglean_key_from_name (name) 121797883Sgibbs char *name; 121897883Sgibbs{ 121997883Sgibbs register int i; 122097883Sgibbs 122197883Sgibbs for (i = 0; name_key_alist[i].name; i++) 122297883Sgibbs if (_rl_stricmp (name, name_key_alist[i].name) == 0) 122397883Sgibbs return (name_key_alist[i].value); 122497883Sgibbs 122597883Sgibbs return (*(unsigned char *)name); /* XXX was return (*name) */ 122697883Sgibbs} 122797883Sgibbs 122897883Sgibbs/* Auxiliary functions to manage keymaps. */ 122997883Sgibbsstatic struct { 123097883Sgibbs char *name; 123197883Sgibbs Keymap map; 123297883Sgibbs} keymap_names[] = { 123397883Sgibbs { "emacs", emacs_standard_keymap }, 123497883Sgibbs { "emacs-standard", emacs_standard_keymap }, 123597883Sgibbs { "emacs-meta", emacs_meta_keymap }, 123697883Sgibbs { "emacs-ctlx", emacs_ctlx_keymap }, 123797883Sgibbs#if defined (VI_MODE) 123897883Sgibbs { "vi", vi_movement_keymap }, 123997883Sgibbs { "vi-move", vi_movement_keymap }, 124097883Sgibbs { "vi-command", vi_movement_keymap }, 124197883Sgibbs { "vi-insert", vi_insertion_keymap }, 124297883Sgibbs#endif /* VI_MODE */ 124397883Sgibbs { (char *)0x0, (Keymap)0x0 } 124497883Sgibbs}; 124597883Sgibbs 124697883SgibbsKeymap 124797883Sgibbsrl_get_keymap_by_name (name) 124897883Sgibbs char *name; 124997883Sgibbs{ 125097883Sgibbs register int i; 125197883Sgibbs 125297883Sgibbs for (i = 0; keymap_names[i].name; i++) 125397883Sgibbs if (strcmp (name, keymap_names[i].name) == 0) 125497883Sgibbs return (keymap_names[i].map); 125597883Sgibbs return ((Keymap) NULL); 125697883Sgibbs} 125797883Sgibbs 125897883Sgibbschar * 125997883Sgibbsrl_get_keymap_name (map) 126097883Sgibbs Keymap map; 126197883Sgibbs{ 126297883Sgibbs register int i; 126397883Sgibbs for (i = 0; keymap_names[i].name; i++) 126497883Sgibbs if (map == keymap_names[i].map) 126597883Sgibbs return (keymap_names[i].name); 126697883Sgibbs return ((char *)NULL); 126797883Sgibbs} 126897883Sgibbs 126997883Sgibbsvoid 127097883Sgibbsrl_set_keymap (map) 127197883Sgibbs Keymap map; 127297883Sgibbs{ 127397883Sgibbs if (map) 127497883Sgibbs _rl_keymap = map; 127597883Sgibbs} 127697883Sgibbs 127797883SgibbsKeymap 127897883Sgibbsrl_get_keymap () 127997883Sgibbs{ 128097883Sgibbs return (_rl_keymap); 128197883Sgibbs} 128297883Sgibbs 128397883Sgibbsvoid 128497883Sgibbsrl_set_keymap_from_edit_mode () 128597883Sgibbs{ 128697883Sgibbs if (rl_editing_mode == emacs_mode) 128797883Sgibbs _rl_keymap = emacs_standard_keymap; 128897883Sgibbs#if defined (VI_MODE) 128997883Sgibbs else if (rl_editing_mode == vi_mode) 129097883Sgibbs _rl_keymap = vi_insertion_keymap; 129197883Sgibbs#endif /* VI_MODE */ 129297883Sgibbs} 129397883Sgibbs 129497883Sgibbschar * 129597883Sgibbsrl_get_keymap_name_from_edit_mode () 129697883Sgibbs{ 129797883Sgibbs if (rl_editing_mode == emacs_mode) 129897883Sgibbs return "emacs"; 129997883Sgibbs#if defined (VI_MODE) 130097883Sgibbs else if (rl_editing_mode == vi_mode) 130197883Sgibbs return "vi"; 130297883Sgibbs#endif /* VI_MODE */ 130397883Sgibbs else 130497883Sgibbs return "none"; 130597883Sgibbs} 130697883Sgibbs 130797883Sgibbs/* **************************************************************** */ 130897883Sgibbs/* */ 130997883Sgibbs/* Key Binding and Function Information */ 131097883Sgibbs/* */ 131197883Sgibbs/* **************************************************************** */ 131297883Sgibbs 131397883Sgibbs/* Each of the following functions produces information about the 131497883Sgibbs state of keybindings and functions known to Readline. The info 131597883Sgibbs is always printed to rl_outstream, and in such a way that it can 131697883Sgibbs be read back in (i.e., passed to rl_parse_and_bind (). */ 131797883Sgibbs 131897883Sgibbs/* Print the names of functions known to Readline. */ 131997883Sgibbsvoid 132097883Sgibbsrl_list_funmap_names () 132197883Sgibbs{ 132297883Sgibbs register int i; 132397883Sgibbs char **funmap_names; 132497883Sgibbs 132597883Sgibbs funmap_names = rl_funmap_names (); 132697883Sgibbs 1327102681Sgibbs if (!funmap_names) 1328102681Sgibbs return; 1329102681Sgibbs 1330102681Sgibbs for (i = 0; funmap_names[i]; i++) 1331102681Sgibbs fprintf (rl_outstream, "%s\n", funmap_names[i]); 1332102681Sgibbs 1333102681Sgibbs free (funmap_names); 1334102681Sgibbs} 1335102681Sgibbs 1336102681Sgibbsstatic char * 1337102681Sgibbs_rl_get_keyname (key) 1338102681Sgibbs int key; 1339102681Sgibbs{ 1340102681Sgibbs char *keyname; 1341102681Sgibbs int i, c; 1342102681Sgibbs 1343102681Sgibbs keyname = (char *)xmalloc (8); 1344102681Sgibbs 1345102681Sgibbs c = key; 1346102681Sgibbs /* Since this is going to be used to write out keysequence-function 1347102681Sgibbs pairs for possible inclusion in an inputrc file, we don't want to 1348102681Sgibbs do any special meta processing on KEY. */ 1349102681Sgibbs 1350102681Sgibbs#if 0 1351102681Sgibbs /* We might want to do this, but the old version of the code did not. */ 1352102681Sgibbs 1353102681Sgibbs /* If this is an escape character, we don't want to do any more processing. 135497883Sgibbs Just add the special ESC key sequence and return. */ 135597883Sgibbs if (c == ESC) 135697883Sgibbs { 135797883Sgibbs keyseq[0] = '\\'; 135897883Sgibbs keyseq[1] = 'e'; 135997883Sgibbs keyseq[2] = '\0'; 136097883Sgibbs return keyseq; 136197883Sgibbs } 136297883Sgibbs#endif 136397883Sgibbs 136497883Sgibbs /* RUBOUT is translated directly into \C-? */ 136597883Sgibbs if (key == RUBOUT) 136697883Sgibbs { 136797883Sgibbs keyname[0] = '\\'; 136897883Sgibbs keyname[1] = 'C'; 136997883Sgibbs keyname[2] = '-'; 137097883Sgibbs keyname[3] = '?'; 137197883Sgibbs keyname[4] = '\0'; 137297883Sgibbs return keyname; 137397883Sgibbs } 137497883Sgibbs 137597883Sgibbs i = 0; 137697883Sgibbs /* Now add special prefixes needed for control characters. This can 137797883Sgibbs potentially change C. */ 137897883Sgibbs if (CTRL_CHAR (c)) 137997883Sgibbs { 138097883Sgibbs keyname[i++] = '\\'; 138197883Sgibbs keyname[i++] = 'C'; 138297883Sgibbs keyname[i++] = '-'; 138397883Sgibbs c = _rl_to_lower (UNCTRL (c)); 138497883Sgibbs } 138597883Sgibbs 138697883Sgibbs /* Now, if the character needs to be quoted with a backslash, do that. */ 138797883Sgibbs if (c == '\\' || c == '"') 138897883Sgibbs keyname[i++] = '\\'; 138997883Sgibbs 139097883Sgibbs /* Now add the key, terminate the string, and return it. */ 139197883Sgibbs keyname[i++] = (char) c; 139297883Sgibbs keyname[i] = '\0'; 139397883Sgibbs 139497883Sgibbs return keyname; 139597883Sgibbs} 139697883Sgibbs 139797883Sgibbs/* Return a NULL terminated array of strings which represent the key 139897883Sgibbs sequences that are used to invoke FUNCTION in MAP. */ 139997883Sgibbschar ** 140097883Sgibbsrl_invoking_keyseqs_in_map (function, map) 140197883Sgibbs Function *function; 140297883Sgibbs Keymap map; 140397883Sgibbs{ 140497883Sgibbs register int key; 140597883Sgibbs char **result; 140697883Sgibbs int result_index, result_size; 140797883Sgibbs 140897883Sgibbs result = (char **)NULL; 140997883Sgibbs result_index = result_size = 0; 141097883Sgibbs 141197883Sgibbs for (key = 0; key < KEYMAP_SIZE; key++) 141297883Sgibbs { 141397883Sgibbs switch (map[key].type) 141497883Sgibbs { 141597883Sgibbs case ISMACR: 141697883Sgibbs /* Macros match, if, and only if, the pointers are identical. 141797883Sgibbs Thus, they are treated exactly like functions in here. */ 141897883Sgibbs case ISFUNC: 141997883Sgibbs /* If the function in the keymap is the one we are looking for, 142097883Sgibbs then add the current KEY to the list of invoking keys. */ 142197883Sgibbs if (map[key].function == function) 142297883Sgibbs { 142397883Sgibbs char *keyname; 142497883Sgibbs 142597883Sgibbs keyname = _rl_get_keyname (key); 142697883Sgibbs 142797883Sgibbs if (result_index + 2 > result_size) 142897883Sgibbs { 142997883Sgibbs result_size += 10; 143097883Sgibbs result = (char **) xrealloc (result, result_size * sizeof (char *)); 143197883Sgibbs } 143297883Sgibbs 1433102681Sgibbs result[result_index++] = keyname; 1434102681Sgibbs result[result_index] = (char *)NULL; 1435102681Sgibbs } 1436102681Sgibbs break; 143797883Sgibbs 143897883Sgibbs case ISKMAP: 143997883Sgibbs { 144097883Sgibbs char **seqs; 144197883Sgibbs register int i; 144297883Sgibbs 144397883Sgibbs /* Find the list of keyseqs in this map which have FUNCTION as 144497883Sgibbs their target. Add the key sequences found to RESULT. */ 144597883Sgibbs if (map[key].function) 1446102681Sgibbs seqs = 1447102681Sgibbs rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key)); 1448102681Sgibbs else 144997883Sgibbs break; 145097883Sgibbs 145197883Sgibbs if (seqs == 0) 145297883Sgibbs break; 145397883Sgibbs 145497883Sgibbs for (i = 0; seqs[i]; i++) 145597883Sgibbs { 145697883Sgibbs char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); 145797883Sgibbs 1458102681Sgibbs if (key == ESC) 1459102681Sgibbs sprintf (keyname, "\\e"); 1460102681Sgibbs else if (CTRL_CHAR (key)) 1461102681Sgibbs sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key))); 1462102681Sgibbs else if (key == RUBOUT) 1463102681Sgibbs sprintf (keyname, "\\C-?"); 1464102681Sgibbs else if (key == '\\' || key == '"') 1465102681Sgibbs { 146697883Sgibbs keyname[0] = '\\'; 146797883Sgibbs keyname[1] = (char) key; 146897883Sgibbs keyname[2] = '\0'; 146997883Sgibbs } 147097883Sgibbs else 147197883Sgibbs { 147297883Sgibbs keyname[0] = (char) key; 147397883Sgibbs keyname[1] = '\0'; 147497883Sgibbs } 1475102681Sgibbs 1476102681Sgibbs strcat (keyname, seqs[i]); 1477102681Sgibbs free (seqs[i]); 1478102681Sgibbs 1479102681Sgibbs if (result_index + 2 > result_size) 1480102681Sgibbs { 148197883Sgibbs result_size += 10; 148297883Sgibbs result = (char **) xrealloc (result, result_size * sizeof (char *)); 148397883Sgibbs } 148497883Sgibbs 148597883Sgibbs result[result_index++] = keyname; 148697883Sgibbs result[result_index] = (char *)NULL; 148797883Sgibbs } 148897883Sgibbs 148997883Sgibbs free (seqs); 1490102681Sgibbs } 1491102681Sgibbs break; 1492102681Sgibbs } 1493102681Sgibbs } 1494102681Sgibbs return (result); 149597883Sgibbs} 149697883Sgibbs 149797883Sgibbs/* Return a NULL terminated array of strings which represent the key 149897883Sgibbs sequences that can be used to invoke FUNCTION using the current keymap. */ 149997883Sgibbschar ** 150097883Sgibbsrl_invoking_keyseqs (function) 150197883Sgibbs Function *function; 150297883Sgibbs{ 150397883Sgibbs return (rl_invoking_keyseqs_in_map (function, _rl_keymap)); 1504102681Sgibbs} 1505102681Sgibbs 1506102681Sgibbs/* Print all of the functions and their bindings to rl_outstream. If 150797883Sgibbs PRINT_READABLY is non-zero, then print the output in such a way 150897883Sgibbs that it can be read back in. */ 150997883Sgibbsvoid 151097883Sgibbsrl_function_dumper (print_readably) 151197883Sgibbs int print_readably; 151297883Sgibbs{ 151397883Sgibbs register int i; 151497883Sgibbs char **names; 151597883Sgibbs char *name; 1516102681Sgibbs 1517102681Sgibbs names = rl_funmap_names (); 1518102681Sgibbs 1519102681Sgibbs fprintf (rl_outstream, "\n"); 1520102681Sgibbs 1521102681Sgibbs for (i = 0; name = names[i]; i++) 152297883Sgibbs { 152397883Sgibbs Function *function; 152497883Sgibbs char **invokers; 152597883Sgibbs 152697883Sgibbs function = rl_named_function (name); 152797883Sgibbs invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap); 152897883Sgibbs 152997883Sgibbs if (print_readably) 153097883Sgibbs { 1531102681Sgibbs if (!invokers) 1532102681Sgibbs fprintf (rl_outstream, "# %s (not bound)\n", name); 1533102681Sgibbs else 1534102681Sgibbs { 153597883Sgibbs register int j; 153697883Sgibbs 153797883Sgibbs for (j = 0; invokers[j]; j++) 153897883Sgibbs { 153997883Sgibbs fprintf (rl_outstream, "\"%s\": %s\n", 154097883Sgibbs invokers[j], name); 154197883Sgibbs free (invokers[j]); 154297883Sgibbs } 154397883Sgibbs 1544102681Sgibbs free (invokers); 1545102681Sgibbs } 1546102681Sgibbs } 1547102681Sgibbs else 1548102681Sgibbs { 1549102681Sgibbs if (!invokers) 1550102681Sgibbs fprintf (rl_outstream, "%s is not bound to any keys\n", 155197883Sgibbs name); 155297883Sgibbs else 155397883Sgibbs { 155497883Sgibbs register int j; 155597883Sgibbs 155697883Sgibbs fprintf (rl_outstream, "%s can be found on ", name); 155797883Sgibbs 155897883Sgibbs for (j = 0; invokers[j] && j < 5; j++) 155997883Sgibbs { 1560102681Sgibbs fprintf (rl_outstream, "\"%s\"%s", invokers[j], 1561102681Sgibbs invokers[j + 1] ? ", " : ".\n"); 1562102681Sgibbs } 156397883Sgibbs 156497883Sgibbs if (j == 5 && invokers[j]) 156597883Sgibbs fprintf (rl_outstream, "...\n"); 156697883Sgibbs 156797883Sgibbs for (j = 0; invokers[j]; j++) 156897883Sgibbs free (invokers[j]); 156997883Sgibbs 157097883Sgibbs free (invokers); 157197883Sgibbs } 157297883Sgibbs } 157397883Sgibbs } 157497883Sgibbs} 157597883Sgibbs 157697883Sgibbs/* Print all of the current functions and their bindings to 157797883Sgibbs rl_outstream. If an explicit argument is given, then print 157897883Sgibbs the output in such a way that it can be read back in. */ 157997883Sgibbsint 158097883Sgibbsrl_dump_functions (count, key) 158197883Sgibbs int count, key; 158297883Sgibbs{ 158397883Sgibbs if (rl_dispatching) 158497883Sgibbs fprintf (rl_outstream, "\r\n"); 158597883Sgibbs rl_function_dumper (rl_explicit_arg); 158697883Sgibbs rl_on_new_line (); 158797883Sgibbs return (0); 158897883Sgibbs} 158997883Sgibbs 159097883Sgibbsstatic void 159197883Sgibbs_rl_macro_dumper_internal (print_readably, map, prefix) 159297883Sgibbs int print_readably; 159397883Sgibbs Keymap map; 1594102681Sgibbs char *prefix; 1595102681Sgibbs{ 1596107441Sscottl register int key; 1597107441Sscottl char *keyname, *out; 1598107441Sscottl int prefix_len; 1599107441Sscottl 1600107441Sscottl for (key = 0; key < KEYMAP_SIZE; key++) 1601107441Sscottl { 1602107441Sscottl switch (map[key].type) 1603107441Sscottl { 1604107441Sscottl case ISMACR: 1605107441Sscottl keyname = _rl_get_keyname (key); 1606107441Sscottl#if 0 1607107441Sscottl out = (char *)map[key].function; 1608107441Sscottl#else 1609107441Sscottl out = _rl_untranslate_macro_value ((char *)map[key].function); 161097883Sgibbs#endif 161197883Sgibbs if (print_readably) 1612107441Sscottl fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "", 1613107441Sscottl keyname, 161497883Sgibbs out ? out : ""); 161597883Sgibbs else 161697883Sgibbs fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "", 161797883Sgibbs keyname, 161897883Sgibbs out ? out : ""); 161997883Sgibbs free (keyname); 162097883Sgibbs#if 1 162197883Sgibbs free (out); 162297883Sgibbs#endif 162397883Sgibbs break; 162497883Sgibbs case ISFUNC: 162597883Sgibbs break; 162697883Sgibbs case ISKMAP: 162797883Sgibbs prefix_len = prefix ? strlen (prefix) : 0; 162897883Sgibbs if (key == ESC) 162997883Sgibbs { 163097883Sgibbs keyname = xmalloc (3 + prefix_len); 163197883Sgibbs if (prefix) 1632102681Sgibbs strcpy (keyname, prefix); 1633102681Sgibbs keyname[prefix_len] = '\\'; 1634102681Sgibbs keyname[prefix_len + 1] = 'e'; 1635102681Sgibbs keyname[prefix_len + 2] = '\0'; 1636102681Sgibbs } 1637102681Sgibbs else 1638102681Sgibbs { 1639102681Sgibbs keyname = _rl_get_keyname (key); 164097883Sgibbs if (prefix) 164197883Sgibbs { 164297883Sgibbs out = xmalloc (strlen (keyname) + prefix_len + 1); 1643102681Sgibbs strcpy (out, prefix); 1644102681Sgibbs strcpy (out + prefix_len, keyname); 1645102681Sgibbs free (keyname); 1646102681Sgibbs keyname = out; 1647102681Sgibbs } 1648102681Sgibbs } 1649102681Sgibbs 1650102681Sgibbs _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname); 1651102681Sgibbs free (keyname); 1652102681Sgibbs break; 165397883Sgibbs } 165497883Sgibbs } 165597883Sgibbs} 165697883Sgibbs 165797883Sgibbsvoid 165897883Sgibbsrl_macro_dumper (print_readably) 1659102681Sgibbs int print_readably; 1660102681Sgibbs{ 1661102681Sgibbs _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL); 1662102681Sgibbs} 1663102681Sgibbs 1664102681Sgibbsint 1665102681Sgibbsrl_dump_macros (count, key) 1666102681Sgibbs int count, key; 166797883Sgibbs{ 166897883Sgibbs if (rl_dispatching) 166997883Sgibbs fprintf (rl_outstream, "\r\n"); 1670102681Sgibbs rl_macro_dumper (rl_explicit_arg); 1671102681Sgibbs rl_on_new_line (); 1672102681Sgibbs return (0); 1673102681Sgibbs} 1674102681Sgibbs 1675102681Sgibbsvoid 1676102681Sgibbsrl_variable_dumper (print_readably) 1677102681Sgibbs int print_readably; 1678102681Sgibbs{ 1679102681Sgibbs int i; 168097883Sgibbs char *kname; 168197883Sgibbs 168297883Sgibbs for (i = 0; boolean_varlist[i].name; i++) 168397883Sgibbs { 168497883Sgibbs if (print_readably) 168597883Sgibbs fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name, 168697883Sgibbs *boolean_varlist[i].value ? "on" : "off"); 168797883Sgibbs else 168897883Sgibbs fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name, 168997883Sgibbs *boolean_varlist[i].value ? "on" : "off"); 169097883Sgibbs } 169197883Sgibbs 169297883Sgibbs /* bell-style */ 169397883Sgibbs switch (_rl_bell_preference) 169497883Sgibbs { 169597883Sgibbs case NO_BELL: kname = "none"; break; 169697883Sgibbs case VISIBLE_BELL: kname = "visible"; break; 169797883Sgibbs case AUDIBLE_BELL: 169897883Sgibbs default: kname = "audible"; break; 169997883Sgibbs } 1700102681Sgibbs if (print_readably) 1701102681Sgibbs fprintf (rl_outstream, "set bell-style %s\n", kname); 1702102681Sgibbs else 1703102681Sgibbs fprintf (rl_outstream, "bell-style is set to `%s'\n", kname); 1704102681Sgibbs 1705102681Sgibbs /* comment-begin */ 1706102681Sgibbs if (print_readably) 1707102681Sgibbs fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); 170897883Sgibbs else 170997883Sgibbs fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : ""); 171097883Sgibbs 171197883Sgibbs /* completion-query-items */ 171297883Sgibbs if (print_readably) 171397883Sgibbs fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items); 171497883Sgibbs else 171597883Sgibbs fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items); 171697883Sgibbs 171797883Sgibbs /* editing-mode */ 171897883Sgibbs if (print_readably) 171997883Sgibbs fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi"); 172097883Sgibbs else 172197883Sgibbs fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi"); 172297883Sgibbs 172397883Sgibbs /* keymap */ 172497883Sgibbs kname = rl_get_keymap_name (_rl_keymap); 172597883Sgibbs if (kname == 0) 172697883Sgibbs kname = rl_get_keymap_name_from_edit_mode (); 172797883Sgibbs if (print_readably) 172897883Sgibbs fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none"); 172997883Sgibbs else 173097883Sgibbs fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none"); 173197883Sgibbs} 173297883Sgibbs 173397883Sgibbs/* Print all of the current variables and their values to 173497883Sgibbs rl_outstream. If an explicit argument is given, then print 173597883Sgibbs the output in such a way that it can be read back in. */ 173697883Sgibbsint 173797883Sgibbsrl_dump_variables (count, key) 173897883Sgibbs int count, key; 173997883Sgibbs{ 174097883Sgibbs if (rl_dispatching) 174197883Sgibbs fprintf (rl_outstream, "\r\n"); 174297883Sgibbs rl_variable_dumper (rl_explicit_arg); 174397883Sgibbs rl_on_new_line (); 174497883Sgibbs return (0); 174597883Sgibbs} 1746102681Sgibbs 1747102681Sgibbs/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. */ 174897883Sgibbsvoid 174997883Sgibbs_rl_bind_if_unbound (keyseq, default_func) 175097883Sgibbs char *keyseq; 175197883Sgibbs Function *default_func; 175297883Sgibbs{ 175397883Sgibbs Function *func; 175497883Sgibbs 175597883Sgibbs if (keyseq) 175697883Sgibbs { 175797883Sgibbs func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL); 175897883Sgibbs if (!func || func == rl_do_lowercase_version) 1759102681Sgibbs rl_set_key (keyseq, default_func, _rl_keymap); 1760102681Sgibbs } 176197883Sgibbs} 176297883Sgibbs 176397883Sgibbs/* Return non-zero if any members of ARRAY are a substring in STRING. */ 176497883Sgibbsstatic int 176597883Sgibbssubstring_member_of_array (string, array) 176697883Sgibbs char *string, **array; 176797883Sgibbs{ 176897883Sgibbs while (*array) 176997883Sgibbs { 177097883Sgibbs if (_rl_strindex (string, *array)) 177197883Sgibbs return (1); 1772102681Sgibbs array++; 1773102681Sgibbs } 1774102681Sgibbs return (0); 1775102681Sgibbs} 1776102681Sgibbs