]>
Commit | Line | Data |
---|---|---|
726f6388 JA |
1 | This file is bind.def, from which is created bind.c. |
2 | It implements the builtin "bind" in Bash. | |
3 | ||
4 | Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. | |
5 | ||
6 | This file is part of GNU Bash, the Bourne Again SHell. | |
7 | ||
8 | Bash is free software; you can redistribute it and/or modify it under | |
9 | the terms of the GNU General Public License as published by the Free | |
bb70624e | 10 | Software Foundation; either version 2, or (at your option) any later |
726f6388 JA |
11 | version. |
12 | ||
13 | Bash is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License along | |
19 | with Bash; see the file COPYING. If not, write to the Free Software | |
bb70624e | 20 | Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. |
726f6388 JA |
21 | |
22 | $PRODUCES bind.c | |
23 | ||
ccc6cda3 JA |
24 | #include <config.h> |
25 | ||
726f6388 JA |
26 | $BUILTIN bind |
27 | $DEPENDS_ON READLINE | |
28 | $FUNCTION bind_builtin | |
bb70624e | 29 | $SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function] |
726f6388 JA |
30 | Bind a key sequence to a Readline function, or to a macro. The |
31 | syntax is equivalent to that found in ~/.inputrc, but must be | |
32 | passed as a single argument: bind '"\C-x\C-r": re-read-init-file'. | |
33 | Arguments we accept: | |
34 | -m keymap Use `keymap' as the keymap for the duration of this | |
35 | command. Acceptable keymap names are emacs, | |
36 | emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, | |
37 | vi-command, and vi-insert. | |
38 | -l List names of functions. | |
ccc6cda3 JA |
39 | -P List function names and bindings. |
40 | -p List functions and bindings in a form that can be | |
41 | reused as input. | |
42 | -r keyseq Remove the binding for KEYSEQ. | |
bb70624e JA |
43 | -x keyseq:shell-command Cause SHELL-COMMAND to be executed when KEYSEQ |
44 | is entered. | |
726f6388 JA |
45 | -f filename Read key bindings from FILENAME. |
46 | -q function-name Query about which keys invoke the named function. | |
cce855bc | 47 | -u function-name Unbind all keys which are bound to the named function. |
ccc6cda3 JA |
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 | -S List key sequences that invoke macros and their values | |
52 | -s List key sequences that invoke macros and their values in | |
53 | a form that can be reused as input. | |
726f6388 JA |
54 | $END |
55 | ||
726f6388 | 56 | #if defined (READLINE) |
ccc6cda3 JA |
57 | |
58 | #if defined (HAVE_UNISTD_H) | |
cce855bc JA |
59 | # ifdef _MINIX |
60 | # include <sys/types.h> | |
61 | # endif | |
ccc6cda3 JA |
62 | # include <unistd.h> |
63 | #endif | |
64 | ||
65 | #include <stdio.h> | |
726f6388 JA |
66 | #include <errno.h> |
67 | #if !defined (errno) | |
68 | extern int errno; | |
69 | #endif /* !errno */ | |
ccc6cda3 | 70 | |
726f6388 JA |
71 | #include <readline/readline.h> |
72 | #include <readline/history.h> | |
ccc6cda3 JA |
73 | |
74 | #include "../shell.h" | |
75 | #include "../bashline.h" | |
726f6388 | 76 | #include "bashgetopt.h" |
ccc6cda3 | 77 | #include "common.h" |
726f6388 JA |
78 | |
79 | static int query_bindings (); | |
cce855bc | 80 | static int unbind_command (); |
726f6388 | 81 | |
726f6388 JA |
82 | extern int no_line_editing; |
83 | ||
84 | #define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0) | |
85 | ||
cce855bc JA |
86 | #define LFLAG 0x0001 |
87 | #define PFLAG 0x0002 | |
88 | #define FFLAG 0x0004 | |
89 | #define VFLAG 0x0008 | |
90 | #define QFLAG 0x0010 | |
91 | #define MFLAG 0x0020 | |
92 | #define RFLAG 0x0040 | |
93 | #define PPFLAG 0x0080 | |
94 | #define VVFLAG 0x0100 | |
95 | #define SFLAG 0x0200 | |
96 | #define SSFLAG 0x0400 | |
97 | #define UFLAG 0x0800 | |
bb70624e | 98 | #define XFLAG 0x1000 |
726f6388 JA |
99 | |
100 | int | |
101 | bind_builtin (list) | |
102 | WORD_LIST *list; | |
103 | { | |
ccc6cda3 | 104 | int return_code; |
726f6388 JA |
105 | FILE *old_rl_outstream; |
106 | Keymap kmap, saved_keymap; | |
ccc6cda3 | 107 | int flags, opt; |
bb70624e | 108 | char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq; |
726f6388 JA |
109 | |
110 | if (no_line_editing) | |
111 | return (EXECUTION_FAILURE); | |
112 | ||
113 | kmap = saved_keymap = (Keymap) NULL; | |
ccc6cda3 | 114 | flags = 0; |
cce855bc | 115 | initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL; |
ccc6cda3 | 116 | return_code = EXECUTION_SUCCESS; |
726f6388 JA |
117 | |
118 | if (!bash_readline_initialized) | |
119 | initialize_readline (); | |
120 | ||
121 | /* Cannot use unwind_protect_pointer () on "FILE *", it is only | |
122 | guaranteed to work for strings. */ | |
123 | /* XXX -- see if we can use unwind_protect here */ | |
124 | old_rl_outstream = rl_outstream; | |
125 | rl_outstream = stdout; | |
126 | ||
127 | reset_internal_getopt (); | |
bb70624e | 128 | while ((opt = internal_getopt (list, "lvpVPsSf:q:u:m:r:x:")) != EOF) |
726f6388 JA |
129 | { |
130 | switch (opt) | |
131 | { | |
132 | case 'l': | |
ccc6cda3 | 133 | flags |= LFLAG; |
726f6388 | 134 | break; |
726f6388 | 135 | case 'v': |
ccc6cda3 | 136 | flags |= VFLAG; |
726f6388 | 137 | break; |
ccc6cda3 JA |
138 | case 'p': |
139 | flags |= PFLAG; | |
726f6388 | 140 | break; |
726f6388 | 141 | case 'f': |
ccc6cda3 | 142 | flags |= FFLAG; |
726f6388 JA |
143 | initfile = list_optarg; |
144 | break; | |
726f6388 | 145 | case 'm': |
ccc6cda3 | 146 | flags |= MFLAG; |
726f6388 JA |
147 | map_name = list_optarg; |
148 | break; | |
726f6388 | 149 | case 'q': |
ccc6cda3 | 150 | flags |= QFLAG; |
726f6388 JA |
151 | fun_name = list_optarg; |
152 | break; | |
cce855bc JA |
153 | case 'u': |
154 | flags |= UFLAG; | |
155 | unbind_name = list_optarg; | |
156 | break; | |
ccc6cda3 JA |
157 | case 'r': |
158 | flags |= RFLAG; | |
159 | remove_seq = list_optarg; | |
160 | break; | |
161 | case 'V': | |
162 | flags |= VVFLAG; | |
163 | break; | |
164 | case 'P': | |
165 | flags |= PPFLAG; | |
166 | break; | |
167 | case 's': | |
168 | flags |= SFLAG; | |
169 | break; | |
170 | case 'S': | |
171 | flags |= SSFLAG; | |
172 | break; | |
bb70624e JA |
173 | case 'x': |
174 | flags |= XFLAG; | |
175 | cmd_seq = list_optarg; | |
176 | break; | |
726f6388 | 177 | default: |
ccc6cda3 | 178 | builtin_usage (); |
726f6388 JA |
179 | BIND_RETURN (EX_USAGE); |
180 | } | |
181 | } | |
182 | ||
183 | list = loptend; | |
184 | ||
185 | /* First, see if we need to install a special keymap for this | |
186 | command. Then start on the arguments. */ | |
187 | ||
ccc6cda3 | 188 | if ((flags & MFLAG) && map_name) |
726f6388 JA |
189 | { |
190 | kmap = rl_get_keymap_by_name (map_name); | |
191 | if (!kmap) | |
28ef6c31 | 192 | { |
ccc6cda3 | 193 | builtin_error ("`%s': invalid keymap name", map_name); |
726f6388 | 194 | BIND_RETURN (EXECUTION_FAILURE); |
28ef6c31 | 195 | } |
726f6388 JA |
196 | } |
197 | ||
198 | if (kmap) | |
199 | { | |
200 | saved_keymap = rl_get_keymap (); | |
201 | rl_set_keymap (kmap); | |
202 | } | |
203 | ||
204 | /* XXX - we need to add exclusive use tests here. It doesn't make sense | |
205 | to use some of these options together. */ | |
206 | /* Now hack the option arguments */ | |
ccc6cda3 JA |
207 | if (flags & LFLAG) |
208 | rl_list_funmap_names (); | |
726f6388 | 209 | |
ccc6cda3 JA |
210 | if (flags & PFLAG) |
211 | rl_function_dumper (1); | |
212 | ||
213 | if (flags & PPFLAG) | |
726f6388 JA |
214 | rl_function_dumper (0); |
215 | ||
ccc6cda3 JA |
216 | if (flags & SFLAG) |
217 | rl_macro_dumper (1); | |
218 | ||
219 | if (flags & SSFLAG) | |
220 | rl_macro_dumper (0); | |
726f6388 | 221 | |
ccc6cda3 JA |
222 | if (flags & VFLAG) |
223 | rl_variable_dumper (1); | |
224 | ||
225 | if (flags & VVFLAG) | |
226 | rl_variable_dumper (0); | |
227 | ||
228 | if ((flags & FFLAG) && initfile) | |
726f6388 JA |
229 | { |
230 | if (rl_read_init_file (initfile) != 0) | |
231 | { | |
232 | builtin_error ("cannot read %s: %s", initfile, strerror (errno)); | |
233 | BIND_RETURN (EXECUTION_FAILURE); | |
234 | } | |
235 | } | |
236 | ||
ccc6cda3 | 237 | if ((flags & QFLAG) && fun_name) |
726f6388 JA |
238 | return_code = query_bindings (fun_name); |
239 | ||
cce855bc JA |
240 | if ((flags & UFLAG) && unbind_name) |
241 | return_code = unbind_command (unbind_name); | |
242 | ||
ccc6cda3 JA |
243 | if ((flags & RFLAG) && remove_seq) |
244 | { | |
245 | if (rl_set_key (remove_seq, (Function *)NULL, rl_get_keymap ()) != 0) | |
246 | { | |
247 | builtin_error ("cannot unbind %s", remove_seq); | |
248 | BIND_RETURN (EXECUTION_FAILURE); | |
249 | } | |
250 | } | |
251 | ||
bb70624e JA |
252 | if (flags & XFLAG) |
253 | return_code = bind_keyseq_to_unix_command (cmd_seq); | |
254 | ||
726f6388 JA |
255 | /* Process the rest of the arguments as binding specifications. */ |
256 | while (list) | |
257 | { | |
258 | rl_parse_and_bind (list->word->word); | |
259 | list = list->next; | |
260 | } | |
261 | ||
262 | bind_exit: | |
263 | if (saved_keymap) | |
264 | rl_set_keymap (saved_keymap); | |
265 | ||
266 | rl_outstream = old_rl_outstream; | |
267 | return (return_code); | |
268 | } | |
269 | ||
270 | static int | |
271 | query_bindings (name) | |
272 | char *name; | |
273 | { | |
274 | Function *function; | |
275 | char **keyseqs; | |
276 | int j; | |
277 | ||
278 | function = rl_named_function (name); | |
cce855bc | 279 | if (function == 0) |
726f6388 JA |
280 | { |
281 | builtin_error ("unknown function name `%s'", name); | |
282 | return EXECUTION_FAILURE; | |
283 | } | |
284 | ||
285 | keyseqs = rl_invoking_keyseqs (function); | |
286 | ||
287 | if (!keyseqs) | |
288 | { | |
289 | printf ("%s is not bound to any keys.\n", name); | |
290 | return EXECUTION_FAILURE; | |
291 | } | |
292 | ||
293 | printf ("%s can be invoked via ", name); | |
294 | for (j = 0; j < 5 && keyseqs[j]; j++) | |
295 | printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n"); | |
296 | if (keyseqs[j]) | |
297 | printf ("...\n"); | |
298 | free_array (keyseqs); | |
299 | return EXECUTION_SUCCESS; | |
300 | } | |
cce855bc JA |
301 | |
302 | static int | |
303 | unbind_command (name) | |
304 | char *name; | |
305 | { | |
306 | Function *function; | |
307 | ||
308 | function = rl_named_function (name); | |
309 | if (function == 0) | |
310 | { | |
311 | builtin_error ("unknown function name `%s'", name); | |
312 | return EXECUTION_FAILURE; | |
313 | } | |
314 | ||
315 | rl_unbind_function_in_map (function, rl_get_keymap ()); | |
316 | return EXECUTION_SUCCESS; | |
317 | } | |
726f6388 | 318 | #endif /* READLINE */ |