1This file is bind.def, from which is created bind.c. 2It implements the builtin "bind" in Bash. 3 4Copyright (C) 1987-2020 Free Software Foundation, Inc. 5 6This file is part of GNU Bash, the Bourne Again SHell. 7 8Bash is free software: you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation, either version 3 of the License, or 11(at your option) any later version. 12 13Bash is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with Bash. If not, see <http://www.gnu.org/licenses/>. 20 21$PRODUCES bind.c 22 23#include <config.h> 24 25$BUILTIN bind 26$DEPENDS_ON READLINE 27$FUNCTION bind_builtin 28$SHORT_DOC bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command] 29Set Readline key bindings and variables. 30 31Bind a key sequence to a Readline function or a macro, or set a 32Readline variable. The non-option argument syntax is equivalent to 33that found in ~/.inputrc, but must be passed as a single argument: 34e.g., bind '"\C-x\C-r": re-read-init-file'. 35 36Options: 37 -m keymap Use KEYMAP as the keymap for the duration of this 38 command. Acceptable keymap names are emacs, 39 emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, 40 vi-command, and vi-insert. 41 -l List names of functions. 42 -P List function names and bindings. 43 -p List functions and bindings in a form that can be 44 reused as input. 45 -S List key sequences that invoke macros and their values 46 -s List key sequences that invoke macros and their values 47 in a form that can be reused as input. 48 -V List variable names and values 49 -v List variable names and values in a form that can 50 be reused as input. 51 -q function-name Query about which keys invoke the named function. 52 -u function-name Unbind all keys which are bound to the named function. 53 -r keyseq Remove the binding for KEYSEQ. 54 -f filename Read key bindings from FILENAME. 55 -x keyseq:shell-command Cause SHELL-COMMAND to be executed when 56 KEYSEQ is entered. 57 -X List key sequences bound with -x and associated commands 58 in a form that can be reused as input. 59 60Exit Status: 61bind returns 0 unless an unrecognized option is given or an error occurs. 62$END 63 64#if defined (READLINE) 65 66#if defined (HAVE_UNISTD_H) 67# ifdef _MINIX 68# include <sys/types.h> 69# endif 70# include <unistd.h> 71#endif 72 73#include <stdio.h> 74#include <errno.h> 75#if !defined (errno) 76extern int errno; 77#endif /* !errno */ 78 79#include <readline/readline.h> 80#include <readline/history.h> 81 82#include "../bashintl.h" 83 84#include "../shell.h" 85#include "../bashline.h" 86#include "bashgetopt.h" 87#include "common.h" 88 89static int query_bindings PARAMS((char *)); 90static int unbind_command PARAMS((char *)); 91static int unbind_keyseq PARAMS((char *)); 92 93#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0) 94 95#define LFLAG 0x0001 96#define PFLAG 0x0002 97#define FFLAG 0x0004 98#define VFLAG 0x0008 99#define QFLAG 0x0010 100#define MFLAG 0x0020 101#define RFLAG 0x0040 102#define PPFLAG 0x0080 103#define VVFLAG 0x0100 104#define SFLAG 0x0200 105#define SSFLAG 0x0400 106#define UFLAG 0x0800 107#define XFLAG 0x1000 108#define XXFLAG 0x2000 109 110int 111bind_builtin (list) 112 WORD_LIST *list; 113{ 114 int return_code; 115 Keymap kmap, saved_keymap; 116 int flags, opt; 117 char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq, *t; 118 119 if (no_line_editing) 120 { 121#if 0 122 builtin_error (_("line editing not enabled")); 123 return (EXECUTION_FAILURE); 124#else 125 builtin_warning (_("line editing not enabled")); 126#endif 127 } 128 129 kmap = saved_keymap = (Keymap) NULL; 130 flags = 0; 131 initfile = map_name = fun_name = unbind_name = remove_seq = cmd_seq = (char *)NULL; 132 return_code = EXECUTION_SUCCESS; 133 134 if (bash_readline_initialized == 0) 135 initialize_readline (); 136 137 begin_unwind_frame ("bind_builtin"); 138 unwind_protect_var (rl_outstream); 139 140 rl_outstream = stdout; 141 142 reset_internal_getopt (); 143 while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != -1) 144 { 145 switch (opt) 146 { 147 case 'l': 148 flags |= LFLAG; 149 break; 150 case 'v': 151 flags |= VFLAG; 152 break; 153 case 'p': 154 flags |= PFLAG; 155 break; 156 case 'f': 157 flags |= FFLAG; 158 initfile = list_optarg; 159 break; 160 case 'm': 161 flags |= MFLAG; 162 map_name = list_optarg; 163 break; 164 case 'q': 165 flags |= QFLAG; 166 fun_name = list_optarg; 167 break; 168 case 'u': 169 flags |= UFLAG; 170 unbind_name = list_optarg; 171 break; 172 case 'r': 173 flags |= RFLAG; 174 remove_seq = list_optarg; 175 break; 176 case 'V': 177 flags |= VVFLAG; 178 break; 179 case 'P': 180 flags |= PPFLAG; 181 break; 182 case 's': 183 flags |= SFLAG; 184 break; 185 case 'S': 186 flags |= SSFLAG; 187 break; 188 case 'x': 189 flags |= XFLAG; 190 cmd_seq = list_optarg; 191 break; 192 case 'X': 193 flags |= XXFLAG; 194 break; 195 case GETOPT_HELP: 196 default: 197 builtin_usage (); 198 BIND_RETURN (EX_USAGE); 199 } 200 } 201 202 list = loptend; 203 204 /* First, see if we need to install a special keymap for this 205 command. Then start on the arguments. */ 206 207 if ((flags & MFLAG) && map_name) 208 { 209 kmap = rl_get_keymap_by_name (map_name); 210 if (kmap == 0) 211 { 212 builtin_error (_("`%s': invalid keymap name"), map_name); 213 BIND_RETURN (EXECUTION_FAILURE); 214 } 215 } 216 217 if (kmap) 218 { 219 saved_keymap = rl_get_keymap (); 220 rl_set_keymap (kmap); 221 } 222 223 /* XXX - we need to add exclusive use tests here. It doesn't make sense 224 to use some of these options together. */ 225 /* Now hack the option arguments */ 226 if (flags & LFLAG) 227 rl_list_funmap_names (); 228 229 if (flags & PFLAG) 230 rl_function_dumper (1); 231 232 if (flags & PPFLAG) 233 rl_function_dumper (0); 234 235 if (flags & SFLAG) 236 rl_macro_dumper (1); 237 238 if (flags & SSFLAG) 239 rl_macro_dumper (0); 240 241 if (flags & VFLAG) 242 rl_variable_dumper (1); 243 244 if (flags & VVFLAG) 245 rl_variable_dumper (0); 246 247 if ((flags & FFLAG) && initfile) 248 { 249 if (rl_read_init_file (initfile) != 0) 250 { 251 t = printable_filename (initfile, 0); 252 builtin_error (_("%s: cannot read: %s"), t, strerror (errno)); 253 if (t != initfile) 254 free (t); 255 BIND_RETURN (EXECUTION_FAILURE); 256 } 257 } 258 259 if ((flags & QFLAG) && fun_name) 260 return_code = query_bindings (fun_name); 261 262 if ((flags & UFLAG) && unbind_name) 263 return_code = unbind_command (unbind_name); 264 265 if ((flags & RFLAG) && remove_seq) 266 { 267 opt = unbind_keyseq (remove_seq); 268 BIND_RETURN (opt); 269 } 270 271 if (flags & XFLAG) 272 return_code = bind_keyseq_to_unix_command (cmd_seq); 273 274 if (flags & XXFLAG) 275 return_code = print_unix_command_map (); 276 277 /* Process the rest of the arguments as binding specifications. */ 278 while (list) 279 { 280 int olen, nlen, d, i; 281 char **obindings, **nbindings; 282 283 obindings = rl_invoking_keyseqs (bash_execute_unix_command); 284 olen = obindings ? strvec_len (obindings) : 0; 285 286 rl_parse_and_bind (list->word->word); 287 288 nbindings = rl_invoking_keyseqs (bash_execute_unix_command); 289 nlen = nbindings ? strvec_len (nbindings) : 0; 290 291 if (nlen < olen) /* fewer bind -x bindings */ 292 for (d = olen - nlen, i = 0; i < olen && d > 0; i++) 293 if (nlen == 0 || strvec_search (nbindings, obindings[i]) >= 0) 294 { 295 unbind_unix_command (obindings[i]); 296 d--; 297 } 298 299 strvec_dispose (obindings); 300 strvec_dispose (nbindings); 301 302 list = list->next; 303 } 304 305 bind_exit: 306 if (saved_keymap) 307 rl_set_keymap (saved_keymap); 308 309 run_unwind_frame ("bind_builtin"); 310 311 if (return_code < 0) 312 return_code = EXECUTION_FAILURE; 313 314 return (sh_chkwrite (return_code)); 315} 316 317static int 318query_bindings (name) 319 char *name; 320{ 321 rl_command_func_t *function; 322 char **keyseqs; 323 int j; 324 325 function = rl_named_function (name); 326 if (function == 0) 327 { 328 builtin_error (_("`%s': unknown function name"), name); 329 return EXECUTION_FAILURE; 330 } 331 332 keyseqs = rl_invoking_keyseqs (function); 333 334 if (!keyseqs) 335 { 336 printf (_("%s is not bound to any keys.\n"), name); 337 return EXECUTION_FAILURE; 338 } 339 340 printf (_("%s can be invoked via "), name); 341 for (j = 0; j < 5 && keyseqs[j]; j++) 342 printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n"); 343 if (keyseqs[j]) 344 printf ("...\n"); 345 strvec_dispose (keyseqs); 346 return EXECUTION_SUCCESS; 347} 348 349static int 350unbind_command (name) 351 char *name; 352{ 353 rl_command_func_t *function; 354 355 function = rl_named_function (name); 356 if (function == 0) 357 { 358 builtin_error (_("`%s': unknown function name"), name); 359 return EXECUTION_FAILURE; 360 } 361 362 rl_unbind_function_in_map (function, rl_get_keymap ()); 363 return EXECUTION_SUCCESS; 364} 365 366static int 367unbind_keyseq (seq) 368 char *seq; 369{ 370 char *kseq; 371 int kslen, type; 372 rl_command_func_t *f; 373 374 kseq = (char *)xmalloc ((2 * strlen (seq)) + 1); 375 if (rl_translate_keyseq (seq, kseq, &kslen)) 376 { 377 free (kseq); 378 builtin_error (_("`%s': cannot unbind"), seq); 379 return EXECUTION_FAILURE; 380 } 381 if ((f = rl_function_of_keyseq_len (kseq, kslen, (Keymap)0, &type)) == 0) 382 { 383 free (kseq); 384 return (EXECUTION_SUCCESS); 385 } 386 if (type == ISKMAP) 387 f = ((Keymap) f)[ANYOTHERKEY].function; 388 389 /* I wish this didn't have to translate the key sequence again, but readline 390 doesn't have a binding function that takes a translated key sequence as 391 an argument. */ 392 if (rl_bind_keyseq (seq, (rl_command_func_t *)NULL) != 0) 393 { 394 free (kseq); 395 builtin_error (_("`%s': cannot unbind"), seq); 396 return (EXECUTION_FAILURE); 397 } 398 399 if (f == bash_execute_unix_command) 400 unbind_unix_command (seq); 401 402 free (kseq); 403 return (EXECUTION_SUCCESS); 404} 405#endif /* READLINE */ 406