]>
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 | ||
3185942a | 4 | Copyright (C) 1987-2009 Free Software Foundation, Inc. |
726f6388 JA |
5 | |
6 | This file is part of GNU Bash, the Bourne Again SHell. | |
7 | ||
3185942a JA |
8 | Bash is free software: you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation, either version 3 of the License, or | |
11 | (at your option) any later version. | |
726f6388 | 12 | |
3185942a JA |
13 | Bash is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
726f6388 | 17 | |
3185942a JA |
18 | You should have received a copy of the GNU General Public License |
19 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | |
726f6388 JA |
20 | |
21 | $PRODUCES bind.c | |
22 | ||
ccc6cda3 JA |
23 | #include <config.h> |
24 | ||
726f6388 JA |
25 | $BUILTIN bind |
26 | $DEPENDS_ON READLINE | |
27 | $FUNCTION bind_builtin | |
ac50fbac | 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] |
3185942a JA |
29 | Set Readline key bindings and variables. |
30 | ||
31 | Bind a key sequence to a Readline function or a macro, or set a | |
32 | Readline variable. The non-option argument syntax is equivalent to | |
33 | that found in ~/.inputrc, but must be passed as a single argument: | |
34 | e.g., bind '"\C-x\C-r": re-read-init-file'. | |
35 | ||
36 | Options: | |
37 | -m keymap Use KEYMAP as the keymap for the duration of this | |
726f6388 JA |
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. | |
ccc6cda3 JA |
42 | -P List function names and bindings. |
43 | -p List functions and bindings in a form that can be | |
44 | reused as input. | |
ccc6cda3 | 45 | -S List key sequences that invoke macros and their values |
7117c2d2 JA |
46 | -s List key sequences that invoke macros and their values |
47 | in a form that can be reused as input. | |
3185942a 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 | -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. | |
ac50fbac CR |
57 | -X List key sequences bound with -x and associated commands |
58 | in a form that can be reused as input. | |
3185942a JA |
59 | |
60 | Exit Status: | |
61 | bind returns 0 unless an unrecognized option is given or an error occurs. | |
726f6388 JA |
62 | $END |
63 | ||
726f6388 | 64 | #if defined (READLINE) |
ccc6cda3 JA |
65 | |
66 | #if defined (HAVE_UNISTD_H) | |
cce855bc JA |
67 | # ifdef _MINIX |
68 | # include <sys/types.h> | |
69 | # endif | |
ccc6cda3 JA |
70 | # include <unistd.h> |
71 | #endif | |
72 | ||
73 | #include <stdio.h> | |
726f6388 JA |
74 | #include <errno.h> |
75 | #if !defined (errno) | |
76 | extern int errno; | |
77 | #endif /* !errno */ | |
ccc6cda3 | 78 | |
726f6388 JA |
79 | #include <readline/readline.h> |
80 | #include <readline/history.h> | |
ccc6cda3 | 81 | |
b80f6443 JA |
82 | #include "../bashintl.h" |
83 | ||
ccc6cda3 JA |
84 | #include "../shell.h" |
85 | #include "../bashline.h" | |
726f6388 | 86 | #include "bashgetopt.h" |
ccc6cda3 | 87 | #include "common.h" |
726f6388 | 88 | |
f73dda09 JA |
89 | static int query_bindings __P((char *)); |
90 | static int unbind_command __P((char *)); | |
726f6388 | 91 | |
726f6388 JA |
92 | extern int no_line_editing; |
93 | ||
94 | #define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0) | |
95 | ||
cce855bc JA |
96 | #define LFLAG 0x0001 |
97 | #define PFLAG 0x0002 | |
98 | #define FFLAG 0x0004 | |
99 | #define VFLAG 0x0008 | |
100 | #define QFLAG 0x0010 | |
101 | #define MFLAG 0x0020 | |
102 | #define RFLAG 0x0040 | |
103 | #define PPFLAG 0x0080 | |
104 | #define VVFLAG 0x0100 | |
105 | #define SFLAG 0x0200 | |
106 | #define SSFLAG 0x0400 | |
107 | #define UFLAG 0x0800 | |
bb70624e | 108 | #define XFLAG 0x1000 |
ac50fbac | 109 | #define XXFLAG 0x2000 |
726f6388 JA |
110 | |
111 | int | |
112 | bind_builtin (list) | |
113 | WORD_LIST *list; | |
114 | { | |
ccc6cda3 | 115 | int return_code; |
726f6388 | 116 | Keymap kmap, saved_keymap; |
ccc6cda3 | 117 | int flags, opt; |
bb70624e | 118 | char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq; |
726f6388 JA |
119 | |
120 | if (no_line_editing) | |
3185942a JA |
121 | { |
122 | #if 0 | |
123 | builtin_error (_("line editing not enabled")); | |
124 | return (EXECUTION_FAILURE); | |
125 | #else | |
126 | builtin_warning (_("line editing not enabled")); | |
127 | #endif | |
128 | } | |
726f6388 JA |
129 | |
130 | kmap = saved_keymap = (Keymap) NULL; | |
ccc6cda3 | 131 | flags = 0; |
cce855bc | 132 | initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL; |
ccc6cda3 | 133 | return_code = EXECUTION_SUCCESS; |
726f6388 | 134 | |
3185942a | 135 | if (bash_readline_initialized == 0) |
726f6388 JA |
136 | initialize_readline (); |
137 | ||
f73dda09 JA |
138 | begin_unwind_frame ("bind_builtin"); |
139 | unwind_protect_var (rl_outstream); | |
140 | ||
726f6388 JA |
141 | rl_outstream = stdout; |
142 | ||
143 | reset_internal_getopt (); | |
ac50fbac | 144 | while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != EOF) |
726f6388 JA |
145 | { |
146 | switch (opt) | |
147 | { | |
148 | case 'l': | |
ccc6cda3 | 149 | flags |= LFLAG; |
726f6388 | 150 | break; |
726f6388 | 151 | case 'v': |
ccc6cda3 | 152 | flags |= VFLAG; |
726f6388 | 153 | break; |
ccc6cda3 JA |
154 | case 'p': |
155 | flags |= PFLAG; | |
726f6388 | 156 | break; |
726f6388 | 157 | case 'f': |
ccc6cda3 | 158 | flags |= FFLAG; |
726f6388 JA |
159 | initfile = list_optarg; |
160 | break; | |
726f6388 | 161 | case 'm': |
ccc6cda3 | 162 | flags |= MFLAG; |
726f6388 JA |
163 | map_name = list_optarg; |
164 | break; | |
726f6388 | 165 | case 'q': |
ccc6cda3 | 166 | flags |= QFLAG; |
726f6388 JA |
167 | fun_name = list_optarg; |
168 | break; | |
cce855bc JA |
169 | case 'u': |
170 | flags |= UFLAG; | |
171 | unbind_name = list_optarg; | |
172 | break; | |
ccc6cda3 JA |
173 | case 'r': |
174 | flags |= RFLAG; | |
175 | remove_seq = list_optarg; | |
176 | break; | |
177 | case 'V': | |
178 | flags |= VVFLAG; | |
179 | break; | |
180 | case 'P': | |
181 | flags |= PPFLAG; | |
182 | break; | |
183 | case 's': | |
184 | flags |= SFLAG; | |
185 | break; | |
186 | case 'S': | |
187 | flags |= SSFLAG; | |
188 | break; | |
bb70624e JA |
189 | case 'x': |
190 | flags |= XFLAG; | |
191 | cmd_seq = list_optarg; | |
192 | break; | |
ac50fbac CR |
193 | case 'X': |
194 | flags |= XXFLAG; | |
195 | break; | |
726f6388 | 196 | default: |
ccc6cda3 | 197 | builtin_usage (); |
726f6388 JA |
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 | ||
ccc6cda3 | 207 | if ((flags & MFLAG) && map_name) |
726f6388 JA |
208 | { |
209 | kmap = rl_get_keymap_by_name (map_name); | |
ac50fbac | 210 | if (kmap == 0) |
28ef6c31 | 211 | { |
b80f6443 | 212 | builtin_error (_("`%s': invalid keymap name"), map_name); |
726f6388 | 213 | BIND_RETURN (EXECUTION_FAILURE); |
28ef6c31 | 214 | } |
726f6388 JA |
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 */ | |
ccc6cda3 JA |
226 | if (flags & LFLAG) |
227 | rl_list_funmap_names (); | |
726f6388 | 228 | |
ccc6cda3 JA |
229 | if (flags & PFLAG) |
230 | rl_function_dumper (1); | |
231 | ||
232 | if (flags & PPFLAG) | |
726f6388 JA |
233 | rl_function_dumper (0); |
234 | ||
ccc6cda3 JA |
235 | if (flags & SFLAG) |
236 | rl_macro_dumper (1); | |
237 | ||
238 | if (flags & SSFLAG) | |
239 | rl_macro_dumper (0); | |
726f6388 | 240 | |
ccc6cda3 JA |
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) | |
726f6388 JA |
248 | { |
249 | if (rl_read_init_file (initfile) != 0) | |
250 | { | |
b80f6443 | 251 | builtin_error (_("%s: cannot read: %s"), initfile, strerror (errno)); |
726f6388 JA |
252 | BIND_RETURN (EXECUTION_FAILURE); |
253 | } | |
254 | } | |
255 | ||
ccc6cda3 | 256 | if ((flags & QFLAG) && fun_name) |
726f6388 JA |
257 | return_code = query_bindings (fun_name); |
258 | ||
cce855bc JA |
259 | if ((flags & UFLAG) && unbind_name) |
260 | return_code = unbind_command (unbind_name); | |
261 | ||
ccc6cda3 JA |
262 | if ((flags & RFLAG) && remove_seq) |
263 | { | |
0001803f | 264 | if (rl_bind_keyseq (remove_seq, (rl_command_func_t *)NULL) != 0) |
ccc6cda3 | 265 | { |
b80f6443 | 266 | builtin_error (_("`%s': cannot unbind"), remove_seq); |
ccc6cda3 JA |
267 | BIND_RETURN (EXECUTION_FAILURE); |
268 | } | |
269 | } | |
270 | ||
bb70624e JA |
271 | if (flags & XFLAG) |
272 | return_code = bind_keyseq_to_unix_command (cmd_seq); | |
273 | ||
ac50fbac CR |
274 | if (flags & XXFLAG) |
275 | return_code = print_unix_command_map (); | |
276 | ||
726f6388 JA |
277 | /* Process the rest of the arguments as binding specifications. */ |
278 | while (list) | |
279 | { | |
280 | rl_parse_and_bind (list->word->word); | |
281 | list = list->next; | |
282 | } | |
283 | ||
284 | bind_exit: | |
285 | if (saved_keymap) | |
286 | rl_set_keymap (saved_keymap); | |
287 | ||
f73dda09 JA |
288 | run_unwind_frame ("bind_builtin"); |
289 | ||
3185942a | 290 | return (sh_chkwrite (return_code)); |
726f6388 JA |
291 | } |
292 | ||
293 | static int | |
294 | query_bindings (name) | |
295 | char *name; | |
296 | { | |
f73dda09 | 297 | rl_command_func_t *function; |
726f6388 JA |
298 | char **keyseqs; |
299 | int j; | |
300 | ||
301 | function = rl_named_function (name); | |
cce855bc | 302 | if (function == 0) |
726f6388 | 303 | { |
b80f6443 | 304 | builtin_error (_("`%s': unknown function name"), name); |
726f6388 JA |
305 | return EXECUTION_FAILURE; |
306 | } | |
307 | ||
308 | keyseqs = rl_invoking_keyseqs (function); | |
309 | ||
310 | if (!keyseqs) | |
311 | { | |
b80f6443 | 312 | printf (_("%s is not bound to any keys.\n"), name); |
726f6388 JA |
313 | return EXECUTION_FAILURE; |
314 | } | |
315 | ||
b80f6443 | 316 | printf (_("%s can be invoked via "), name); |
726f6388 JA |
317 | for (j = 0; j < 5 && keyseqs[j]; j++) |
318 | printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n"); | |
319 | if (keyseqs[j]) | |
320 | printf ("...\n"); | |
7117c2d2 | 321 | strvec_dispose (keyseqs); |
726f6388 JA |
322 | return EXECUTION_SUCCESS; |
323 | } | |
cce855bc JA |
324 | |
325 | static int | |
326 | unbind_command (name) | |
327 | char *name; | |
328 | { | |
f73dda09 | 329 | rl_command_func_t *function; |
cce855bc JA |
330 | |
331 | function = rl_named_function (name); | |
332 | if (function == 0) | |
333 | { | |
3185942a | 334 | builtin_error (_("`%s': unknown function name"), name); |
cce855bc JA |
335 | return EXECUTION_FAILURE; |
336 | } | |
337 | ||
338 | rl_unbind_function_in_map (function, rl_get_keymap ()); | |
339 | return EXECUTION_SUCCESS; | |
340 | } | |
726f6388 | 341 | #endif /* READLINE */ |