]>
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 | ||
a0c0a00f | 4 | Copyright (C) 1987-2015 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. | |
a0c0a00f | 57 | -X List key sequences bound with -x and associated commands |
ac50fbac | 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; |
a0c0a00f | 118 | char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq, *t; |
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; |
a0c0a00f | 132 | initfile = map_name = fun_name = unbind_name = remove_seq = cmd_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 (); | |
a0c0a00f | 144 | while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != -1) |
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; | |
a0c0a00f | 196 | CASE_HELPOPT; |
726f6388 | 197 | default: |
ccc6cda3 | 198 | builtin_usage (); |
726f6388 JA |
199 | BIND_RETURN (EX_USAGE); |
200 | } | |
201 | } | |
202 | ||
203 | list = loptend; | |
204 | ||
205 | /* First, see if we need to install a special keymap for this | |
206 | command. Then start on the arguments. */ | |
207 | ||
ccc6cda3 | 208 | if ((flags & MFLAG) && map_name) |
726f6388 JA |
209 | { |
210 | kmap = rl_get_keymap_by_name (map_name); | |
ac50fbac | 211 | if (kmap == 0) |
28ef6c31 | 212 | { |
b80f6443 | 213 | builtin_error (_("`%s': invalid keymap name"), map_name); |
726f6388 | 214 | BIND_RETURN (EXECUTION_FAILURE); |
28ef6c31 | 215 | } |
726f6388 JA |
216 | } |
217 | ||
218 | if (kmap) | |
219 | { | |
220 | saved_keymap = rl_get_keymap (); | |
221 | rl_set_keymap (kmap); | |
222 | } | |
223 | ||
224 | /* XXX - we need to add exclusive use tests here. It doesn't make sense | |
225 | to use some of these options together. */ | |
226 | /* Now hack the option arguments */ | |
ccc6cda3 JA |
227 | if (flags & LFLAG) |
228 | rl_list_funmap_names (); | |
726f6388 | 229 | |
ccc6cda3 JA |
230 | if (flags & PFLAG) |
231 | rl_function_dumper (1); | |
232 | ||
233 | if (flags & PPFLAG) | |
726f6388 JA |
234 | rl_function_dumper (0); |
235 | ||
ccc6cda3 JA |
236 | if (flags & SFLAG) |
237 | rl_macro_dumper (1); | |
238 | ||
239 | if (flags & SSFLAG) | |
240 | rl_macro_dumper (0); | |
726f6388 | 241 | |
ccc6cda3 JA |
242 | if (flags & VFLAG) |
243 | rl_variable_dumper (1); | |
244 | ||
245 | if (flags & VVFLAG) | |
246 | rl_variable_dumper (0); | |
247 | ||
248 | if ((flags & FFLAG) && initfile) | |
726f6388 JA |
249 | { |
250 | if (rl_read_init_file (initfile) != 0) | |
251 | { | |
a0c0a00f CR |
252 | t = printable_filename (initfile, 0); |
253 | builtin_error (_("%s: cannot read: %s"), t, strerror (errno)); | |
254 | if (t != initfile) | |
255 | free (t); | |
726f6388 JA |
256 | BIND_RETURN (EXECUTION_FAILURE); |
257 | } | |
258 | } | |
259 | ||
ccc6cda3 | 260 | if ((flags & QFLAG) && fun_name) |
726f6388 JA |
261 | return_code = query_bindings (fun_name); |
262 | ||
cce855bc JA |
263 | if ((flags & UFLAG) && unbind_name) |
264 | return_code = unbind_command (unbind_name); | |
265 | ||
ccc6cda3 JA |
266 | if ((flags & RFLAG) && remove_seq) |
267 | { | |
0001803f | 268 | if (rl_bind_keyseq (remove_seq, (rl_command_func_t *)NULL) != 0) |
ccc6cda3 | 269 | { |
b80f6443 | 270 | builtin_error (_("`%s': cannot unbind"), remove_seq); |
ccc6cda3 JA |
271 | BIND_RETURN (EXECUTION_FAILURE); |
272 | } | |
273 | } | |
274 | ||
bb70624e JA |
275 | if (flags & XFLAG) |
276 | return_code = bind_keyseq_to_unix_command (cmd_seq); | |
277 | ||
ac50fbac CR |
278 | if (flags & XXFLAG) |
279 | return_code = print_unix_command_map (); | |
280 | ||
726f6388 JA |
281 | /* Process the rest of the arguments as binding specifications. */ |
282 | while (list) | |
283 | { | |
284 | rl_parse_and_bind (list->word->word); | |
285 | list = list->next; | |
286 | } | |
287 | ||
288 | bind_exit: | |
289 | if (saved_keymap) | |
290 | rl_set_keymap (saved_keymap); | |
291 | ||
f73dda09 JA |
292 | run_unwind_frame ("bind_builtin"); |
293 | ||
3185942a | 294 | return (sh_chkwrite (return_code)); |
726f6388 JA |
295 | } |
296 | ||
297 | static int | |
298 | query_bindings (name) | |
299 | char *name; | |
300 | { | |
f73dda09 | 301 | rl_command_func_t *function; |
726f6388 JA |
302 | char **keyseqs; |
303 | int j; | |
304 | ||
305 | function = rl_named_function (name); | |
cce855bc | 306 | if (function == 0) |
726f6388 | 307 | { |
b80f6443 | 308 | builtin_error (_("`%s': unknown function name"), name); |
726f6388 JA |
309 | return EXECUTION_FAILURE; |
310 | } | |
311 | ||
312 | keyseqs = rl_invoking_keyseqs (function); | |
313 | ||
314 | if (!keyseqs) | |
315 | { | |
b80f6443 | 316 | printf (_("%s is not bound to any keys.\n"), name); |
726f6388 JA |
317 | return EXECUTION_FAILURE; |
318 | } | |
319 | ||
b80f6443 | 320 | printf (_("%s can be invoked via "), name); |
726f6388 JA |
321 | for (j = 0; j < 5 && keyseqs[j]; j++) |
322 | printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n"); | |
323 | if (keyseqs[j]) | |
324 | printf ("...\n"); | |
7117c2d2 | 325 | strvec_dispose (keyseqs); |
726f6388 JA |
326 | return EXECUTION_SUCCESS; |
327 | } | |
cce855bc JA |
328 | |
329 | static int | |
330 | unbind_command (name) | |
331 | char *name; | |
332 | { | |
f73dda09 | 333 | rl_command_func_t *function; |
cce855bc JA |
334 | |
335 | function = rl_named_function (name); | |
336 | if (function == 0) | |
337 | { | |
3185942a | 338 | builtin_error (_("`%s': unknown function name"), name); |
cce855bc JA |
339 | return EXECUTION_FAILURE; |
340 | } | |
341 | ||
342 | rl_unbind_function_in_map (function, rl_get_keymap ()); | |
343 | return EXECUTION_SUCCESS; | |
344 | } | |
726f6388 | 345 | #endif /* READLINE */ |