Commit | Line | Data |
---|---|---|
c374ab69 MV |
1 | /* readline.c --- line editing support for Guile */ |
2 | ||
7dfcaf26 | 3 | /* Copyright (C) 1997,1999,2000,2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010, 2013 Free Software Foundation, Inc. |
c374ab69 MV |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
b82a8b48 | 7 | * the Free Software Foundation; either version 3, or (at your option) |
c374ab69 MV |
8 | * any later version. |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this software; see the file COPYING. If not, write to | |
92205699 MV |
17 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | * Boston, MA 02110-1301 USA | |
c374ab69 MV |
19 | * |
20 | */ | |
f48e47b9 | 21 | |
f48e47b9 | 22 | |
c374ab69 | 23 | \f |
7a5ab369 LC |
24 | #ifdef HAVE_CONFIG_H |
25 | # include <config.h> | |
26 | #endif | |
26aff4f9 | 27 | |
62947883 | 28 | #ifdef HAVE_RL_GETC_FUNCTION |
fbf68f8b | 29 | #include "libguile.h" |
739b3bf1 | 30 | |
ffdeebc3 | 31 | #include <stdio.h> |
48552b1d | 32 | #include <unistd.h> |
c374ab69 MV |
33 | #include <readline/readline.h> |
34 | #include <readline/history.h> | |
c374ab69 | 35 | #include <sys/time.h> |
7dfcaf26 | 36 | #include <sys/select.h> |
b71099ba | 37 | #include <signal.h> |
c374ab69 | 38 | |
1c537018 | 39 | #include "libguile/validate.h" |
a0599745 | 40 | #include "guile-readline/readline.h" |
c374ab69 | 41 | |
593be5d2 | 42 | scm_t_option scm_readline_opts[] = { |
c374ab69 MV |
43 | { SCM_OPTION_BOOLEAN, "history-file", 1, |
44 | "Use history file." }, | |
45 | { SCM_OPTION_INTEGER, "history-length", 200, | |
46 | "History length." }, | |
47 | { SCM_OPTION_INTEGER, "bounce-parens", 500, | |
62560650 HWN |
48 | "Time (ms) to show matching opening parenthesis (0 = off)."}, |
49 | { 0 } | |
c374ab69 MV |
50 | }; |
51 | ||
52 | extern void stifle_history (int max); | |
53 | ||
b916d813 | 54 | SCM_DEFINE (scm_readline_options, "readline-options-interface", 0, 1, 0, |
f48e47b9 GB |
55 | (SCM setting), |
56 | "") | |
57 | #define FUNC_NAME s_scm_readline_options | |
c374ab69 MV |
58 | { |
59 | SCM ans = scm_options (setting, | |
60 | scm_readline_opts, | |
f48e47b9 | 61 | FUNC_NAME); |
c374ab69 MV |
62 | stifle_history (SCM_HISTORY_LENGTH); |
63 | return ans; | |
64 | } | |
f48e47b9 | 65 | #undef FUNC_NAME |
c374ab69 MV |
66 | |
67 | #ifndef HAVE_STRDUP | |
68 | static char * | |
69 | strdup (char *s) | |
70 | { | |
1be6b49c | 71 | size_t len = strlen (s); |
c374ab69 MV |
72 | char *new = malloc (len + 1); |
73 | strcpy (new, s); | |
74 | return new; | |
75 | } | |
76 | #endif /* HAVE_STRDUP */ | |
77 | ||
78 | #ifndef HAVE_RL_CLEANUP_AFTER_SIGNAL | |
79 | ||
80 | /* These are readline functions added in release 2.3. They will work | |
81 | * together with readline-2.1 and 2.2. (The readline interface is | |
82 | * disabled for earlier releases.) | |
83 | * They are declared static; if we want to use them elsewhere, then | |
84 | * we need external declarations for them, but at the moment, I don't | |
85 | * think anything else in Guile ought to use these. | |
86 | */ | |
87 | ||
88 | extern void _rl_clean_up_for_exit (); | |
89 | extern void _rl_kill_kbd_macro (); | |
90 | extern int _rl_init_argument (); | |
91 | ||
2e3d5987 | 92 | void |
c374ab69 MV |
93 | rl_cleanup_after_signal () |
94 | { | |
95 | #ifdef HAVE_RL_CLEAR_SIGNALS | |
96 | _rl_clean_up_for_exit (); | |
97 | #endif | |
98 | (*rl_deprep_term_function) (); | |
99 | #ifdef HAVE_RL_CLEAR_SIGNALS | |
100 | rl_clear_signals (); | |
101 | #endif | |
102 | rl_pending_input = 0; | |
103 | } | |
104 | ||
2e3d5987 | 105 | void |
c374ab69 MV |
106 | rl_free_line_state () |
107 | { | |
108 | register HIST_ENTRY *entry; | |
109 | ||
110 | free_undo_list (); | |
111 | ||
112 | entry = current_history (); | |
113 | if (entry) | |
114 | entry->data = (char *)NULL; | |
115 | ||
116 | _rl_kill_kbd_macro (); | |
117 | rl_clear_message (); | |
118 | _rl_init_argument (); | |
119 | } | |
120 | ||
121 | #endif /* !HAVE_RL_CLEANUP_AFTER_SIGNAL */ | |
122 | ||
123 | static int promptp; | |
124 | static SCM input_port; | |
75192345 | 125 | static SCM output_port; |
c374ab69 MV |
126 | static SCM before_read; |
127 | ||
128 | static int | |
e81d98ec | 129 | current_input_getc (FILE *in SCM_UNUSED) |
c374ab69 | 130 | { |
be49d1df | 131 | if (promptp && scm_is_true (before_read)) |
c374ab69 MV |
132 | { |
133 | scm_apply (before_read, SCM_EOL, SCM_EOL); | |
134 | promptp = 0; | |
135 | } | |
75192345 | 136 | return scm_get_byte_or_eof (input_port); |
c374ab69 MV |
137 | } |
138 | ||
c374ab69 | 139 | static int in_readline = 0; |
bb0f37e7 | 140 | static SCM reentry_barrier_mutex; |
c374ab69 | 141 | |
f48e47b9 | 142 | static SCM internal_readline (SCM text); |
ddfb5e2b | 143 | static void unwind_readline (void *unused); |
48552b1d | 144 | static void reentry_barrier (void); |
f48e47b9 GB |
145 | |
146 | ||
b916d813 | 147 | SCM_DEFINE (scm_readline, "%readline", 0, 4, 0, |
f48e47b9 GB |
148 | (SCM text, SCM inp, SCM outp, SCM read_hook), |
149 | "") | |
150 | #define FUNC_NAME s_scm_readline | |
151 | { | |
152 | SCM ans; | |
153 | ||
154 | reentry_barrier (); | |
155 | ||
156 | before_read = SCM_BOOL_F; | |
157 | ||
158 | if (!SCM_UNBNDP (text)) | |
159 | { | |
ad6dec05 | 160 | if (!scm_is_string (text)) |
f48e47b9 GB |
161 | { |
162 | --in_readline; | |
163 | scm_wrong_type_arg (s_scm_readline, SCM_ARG1, text); | |
164 | } | |
f48e47b9 GB |
165 | } |
166 | ||
0ddf47fc | 167 | if (!((SCM_UNBNDP (inp) && SCM_OPINFPORTP (scm_current_input_port ())) |
379b35da | 168 | || SCM_OPINFPORTP (inp))) |
f48e47b9 GB |
169 | { |
170 | --in_readline; | |
171 | scm_misc_error (s_scm_readline, | |
172 | "Input port is not open or not a file port", | |
173 | SCM_EOL); | |
174 | } | |
175 | ||
0ddf47fc | 176 | if (!((SCM_UNBNDP (outp) && SCM_OPOUTFPORTP (scm_current_output_port ())) |
379b35da | 177 | || SCM_OPOUTFPORTP (outp))) |
f48e47b9 GB |
178 | { |
179 | --in_readline; | |
180 | scm_misc_error (s_scm_readline, | |
181 | "Output port is not open or not a file port", | |
182 | SCM_EOL); | |
183 | } | |
184 | ||
be49d1df | 185 | if (!(SCM_UNBNDP (read_hook) || scm_is_false (read_hook))) |
f48e47b9 | 186 | { |
be49d1df | 187 | if (scm_is_false (scm_thunk_p (read_hook))) |
f48e47b9 GB |
188 | { |
189 | --in_readline; | |
190 | scm_wrong_type_arg (s_scm_readline, SCM_ARG4, read_hook); | |
191 | } | |
192 | before_read = read_hook; | |
193 | } | |
194 | ||
195 | scm_readline_init_ports (inp, outp); | |
196 | ||
ddfb5e2b AW |
197 | scm_dynwind_begin (0); |
198 | scm_dynwind_unwind_handler (unwind_readline, NULL, 0); | |
199 | ||
200 | ans = internal_readline (text); | |
201 | ||
202 | scm_dynwind_end (); | |
f48e47b9 GB |
203 | |
204 | fclose (rl_instream); | |
205 | fclose (rl_outstream); | |
206 | ||
207 | --in_readline; | |
208 | return ans; | |
209 | } | |
210 | #undef FUNC_NAME | |
211 | ||
212 | ||
c374ab69 MV |
213 | static void |
214 | reentry_barrier () | |
215 | { | |
216 | int reentryp = 0; | |
246c563b | 217 | /* We should rather use scm_try_mutex when it becomes available */ |
bb0f37e7 | 218 | scm_lock_mutex (reentry_barrier_mutex); |
c374ab69 MV |
219 | if (in_readline) |
220 | reentryp = 1; | |
221 | else | |
222 | ++in_readline; | |
bb0f37e7 | 223 | scm_unlock_mutex (reentry_barrier_mutex); |
c374ab69 | 224 | if (reentryp) |
f48e47b9 | 225 | scm_misc_error (s_scm_readline, "readline is not reentrant", SCM_EOL); |
c374ab69 MV |
226 | } |
227 | ||
ddfb5e2b AW |
228 | /* This function is only called on nonlocal exit from readline(). */ |
229 | static void | |
230 | unwind_readline (void *unused) | |
c374ab69 MV |
231 | { |
232 | rl_free_line_state (); | |
233 | rl_cleanup_after_signal (); | |
739b3bf1 | 234 | fputc ('\n', rl_outstream); /* We don't want next output on this line */ |
c374ab69 MV |
235 | fclose (rl_instream); |
236 | fclose (rl_outstream); | |
237 | --in_readline; | |
c374ab69 MV |
238 | } |
239 | ||
240 | static SCM | |
241 | internal_readline (SCM text) | |
242 | { | |
243 | SCM ret; | |
244 | char *s; | |
ad6dec05 | 245 | char *prompt = SCM_UNBNDP (text) ? "" : scm_to_locale_string (text); |
c374ab69 MV |
246 | |
247 | promptp = 1; | |
248 | s = readline (prompt); | |
249 | if (s) | |
75192345 MG |
250 | { |
251 | scm_t_port *pt = SCM_PTAB_ENTRY (output_port); | |
252 | ||
f7f4d047 MG |
253 | ret = scm_from_stringn (s, strlen (s), pt->encoding, |
254 | SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE); | |
75192345 | 255 | } |
c374ab69 MV |
256 | else |
257 | ret = SCM_EOF_VAL; | |
258 | ||
ad6dec05 MV |
259 | if (!SCM_UNBNDP (text)) |
260 | free (prompt); | |
c374ab69 MV |
261 | free (s); |
262 | ||
263 | return ret; | |
264 | } | |
265 | ||
266 | static FILE * | |
267 | stream_from_fport (SCM port, char *mode, const char *subr) | |
268 | { | |
269 | int fd; | |
270 | FILE *f; | |
271 | ||
593be5d2 | 272 | fd = dup (((struct scm_t_fport *) SCM_STREAM (port))->fdes); |
c374ab69 MV |
273 | if (fd == -1) |
274 | { | |
275 | --in_readline; | |
276 | scm_syserror (subr); | |
277 | } | |
278 | ||
279 | f = fdopen (fd, mode); | |
280 | if (f == NULL) | |
281 | { | |
282 | --in_readline; | |
283 | scm_syserror (subr); | |
284 | } | |
285 | ||
286 | return f; | |
287 | } | |
288 | ||
2e3d5987 MD |
289 | void |
290 | scm_readline_init_ports (SCM inp, SCM outp) | |
291 | { | |
292 | if (SCM_UNBNDP (inp)) | |
0ddf47fc | 293 | inp = scm_current_input_port (); |
2e3d5987 MD |
294 | |
295 | if (SCM_UNBNDP (outp)) | |
0ddf47fc | 296 | outp = scm_current_output_port (); |
2e3d5987 | 297 | |
379b35da | 298 | if (!SCM_OPINFPORTP (inp)) { |
2e3d5987 MD |
299 | scm_misc_error (0, |
300 | "Input port is not open or not a file port", | |
301 | SCM_EOL); | |
302 | } | |
303 | ||
379b35da | 304 | if (!SCM_OPOUTFPORTP (outp)) { |
2e3d5987 MD |
305 | scm_misc_error (0, |
306 | "Output port is not open or not a file port", | |
307 | SCM_EOL); | |
308 | } | |
309 | ||
310 | input_port = inp; | |
75192345 | 311 | output_port = outp; |
f48e47b9 GB |
312 | rl_instream = stream_from_fport (inp, "r", s_scm_readline); |
313 | rl_outstream = stream_from_fport (outp, "w", s_scm_readline); | |
2e3d5987 MD |
314 | } |
315 | ||
c374ab69 | 316 | |
c374ab69 | 317 | |
b916d813 | 318 | SCM_DEFINE (scm_add_history, "add-history", 1, 0, 0, |
f48e47b9 GB |
319 | (SCM text), |
320 | "") | |
321 | #define FUNC_NAME s_scm_add_history | |
c374ab69 MV |
322 | { |
323 | char* s; | |
c374ab69 | 324 | |
ad6dec05 MV |
325 | s = scm_to_locale_string (text); |
326 | add_history (s); | |
d3075c52 | 327 | free (s); |
c374ab69 MV |
328 | |
329 | return SCM_UNSPECIFIED; | |
330 | } | |
f48e47b9 | 331 | #undef FUNC_NAME |
c374ab69 MV |
332 | |
333 | ||
b916d813 | 334 | SCM_DEFINE (scm_read_history, "read-history", 1, 0, 0, |
f48e47b9 GB |
335 | (SCM file), |
336 | "") | |
337 | #define FUNC_NAME s_scm_read_history | |
c374ab69 | 338 | { |
ad6dec05 MV |
339 | char *filename; |
340 | SCM ret; | |
341 | ||
342 | filename = scm_to_locale_string (file); | |
343 | ret = scm_from_bool (!read_history (filename)); | |
344 | free (filename); | |
345 | return ret; | |
c374ab69 | 346 | } |
f48e47b9 | 347 | #undef FUNC_NAME |
c374ab69 MV |
348 | |
349 | ||
b916d813 | 350 | SCM_DEFINE (scm_write_history, "write-history", 1, 0, 0, |
f48e47b9 GB |
351 | (SCM file), |
352 | "") | |
353 | #define FUNC_NAME s_scm_write_history | |
c374ab69 | 354 | { |
ad6dec05 MV |
355 | char *filename; |
356 | SCM ret; | |
357 | ||
358 | filename = scm_to_locale_string (file); | |
359 | ret = scm_from_bool (!write_history (filename)); | |
360 | free (filename); | |
361 | return ret; | |
c374ab69 | 362 | } |
f48e47b9 | 363 | #undef FUNC_NAME |
c374ab69 | 364 | |
8ed35a15 MV |
365 | SCM_DEFINE (scm_clear_history, "clear-history", 0, 0, 0, |
366 | (), | |
367 | "Clear the history buffer of the readline machinery.") | |
368 | #define FUNC_NAME s_scm_clear_history | |
369 | { | |
370 | clear_history(); | |
371 | return SCM_UNSPECIFIED; | |
372 | } | |
373 | #undef FUNC_NAME | |
374 | ||
c374ab69 | 375 | |
b916d813 | 376 | SCM_DEFINE (scm_filename_completion_function, "filename-completion-function", 2, 0, 0, |
f48e47b9 GB |
377 | (SCM text, SCM continuep), |
378 | "") | |
379 | #define FUNC_NAME s_scm_filename_completion_function | |
c374ab69 MV |
380 | { |
381 | char *s; | |
382 | SCM ans; | |
ad6dec05 | 383 | char *c_text = scm_to_locale_string (text); |
dcb17187 | 384 | #ifdef HAVE_RL_FILENAME_COMPLETION_FUNCTION |
ad6dec05 | 385 | s = rl_filename_completion_function (c_text, scm_is_true (continuep)); |
dcb17187 | 386 | #else |
ad6dec05 | 387 | s = filename_completion_function (c_text, scm_is_true (continuep)); |
dcb17187 | 388 | #endif |
ad6dec05 MV |
389 | ans = scm_take_locale_string (s); |
390 | free (c_text); | |
c374ab69 MV |
391 | return ans; |
392 | } | |
f48e47b9 | 393 | #undef FUNC_NAME |
c374ab69 MV |
394 | |
395 | /* | |
396 | * The following has been modified from code contributed by | |
397 | * Andrew Archibald <aarchiba@undergrad.math.uwaterloo.ca> | |
398 | */ | |
399 | ||
400 | SCM scm_readline_completion_function_var; | |
401 | ||
402 | static char * | |
403 | completion_function (char *text, int continuep) | |
404 | { | |
296ff5e7 | 405 | SCM compfunc = SCM_VARIABLE_REF (scm_readline_completion_function_var); |
c374ab69 MV |
406 | SCM res; |
407 | ||
be49d1df | 408 | if (scm_is_false (compfunc)) |
c374ab69 MV |
409 | return NULL; /* #f => completion disabled */ |
410 | else | |
411 | { | |
ad6dec05 | 412 | SCM t = scm_from_locale_string (text); |
be49d1df | 413 | SCM c = scm_from_bool (continuep); |
5b2a7b59 | 414 | res = scm_apply (compfunc, scm_list_2 (t, c), SCM_EOL); |
c374ab69 | 415 | |
be49d1df | 416 | if (scm_is_false (res)) |
c374ab69 MV |
417 | return NULL; |
418 | ||
ad6dec05 | 419 | return scm_to_locale_string (res); |
c374ab69 MV |
420 | } |
421 | } | |
422 | ||
6a945c34 | 423 | #if HAVE_RL_GET_KEYMAP |
c374ab69 MV |
424 | /*Bouncing parenthesis (reimplemented by GH, 11/23/98, since readline is strict gpl)*/ |
425 | ||
576cdec4 MD |
426 | static int match_paren (int x, int k); |
427 | static int find_matching_paren (int k); | |
428 | static void init_bouncing_parens (); | |
c374ab69 MV |
429 | |
430 | static void | |
576cdec4 | 431 | init_bouncing_parens () |
c374ab69 | 432 | { |
576cdec4 MD |
433 | if (strncmp (rl_get_keymap_name (rl_get_keymap ()), "vi", 2)) |
434 | { | |
435 | rl_bind_key (')', match_paren); | |
436 | rl_bind_key (']', match_paren); | |
437 | rl_bind_key ('}', match_paren); | |
438 | } | |
c374ab69 MV |
439 | } |
440 | ||
441 | static int | |
442 | find_matching_paren(int k) | |
443 | { | |
444 | register int i; | |
445 | register char c = 0; | |
446 | int end_parens_found = 0; | |
447 | ||
448 | /* Choose the corresponding opening bracket. */ | |
449 | if (k == ')') c = '('; | |
450 | else if (k == ']') c = '['; | |
451 | else if (k == '}') c = '{'; | |
452 | ||
453 | for (i=rl_point-2; i>=0; i--) | |
454 | { | |
455 | /* Is the current character part of a character literal? */ | |
456 | if (i - 2 >= 0 | |
457 | && rl_line_buffer[i - 1] == '\\' | |
458 | && rl_line_buffer[i - 2] == '#') | |
459 | ; | |
460 | else if (rl_line_buffer[i] == k) | |
461 | end_parens_found++; | |
462 | else if (rl_line_buffer[i] == '"') | |
463 | { | |
464 | /* Skip over a string literal. */ | |
465 | for (i--; i >= 0; i--) | |
466 | if (rl_line_buffer[i] == '"' | |
467 | && ! (i - 1 >= 0 | |
468 | && rl_line_buffer[i - 1] == '\\')) | |
469 | break; | |
470 | } | |
471 | else if (rl_line_buffer[i] == c) | |
472 | { | |
576cdec4 MD |
473 | if (end_parens_found==0) |
474 | return i; | |
c374ab69 MV |
475 | else --end_parens_found; |
476 | } | |
477 | } | |
478 | return -1; | |
479 | } | |
480 | ||
576cdec4 MD |
481 | static int |
482 | match_paren (int x, int k) | |
c374ab69 | 483 | { |
8f99e3f3 | 484 | int tmp; |
8f99e3f3 | 485 | int fno; |
7dfcaf26 | 486 | fd_set readset; |
c374ab69 | 487 | struct timeval timeout; |
8f99e3f3 | 488 | |
576cdec4 | 489 | rl_insert (x, k); |
c374ab69 | 490 | if (!SCM_READLINE_BOUNCE_PARENS) |
576cdec4 | 491 | return 0; |
c374ab69 MV |
492 | |
493 | /* Did we just insert a quoted paren? If so, then don't bounce. */ | |
494 | if (rl_point - 1 >= 1 | |
495 | && rl_line_buffer[rl_point - 2] == '\\') | |
576cdec4 | 496 | return 0; |
c374ab69 MV |
497 | |
498 | tmp = 1000 * SCM_READLINE_BOUNCE_PARENS; | |
499 | timeout.tv_sec = tmp / 1000000; | |
500 | timeout.tv_usec = tmp % 1000000; | |
576cdec4 | 501 | FD_ZERO (&readset); |
bc858b80 MD |
502 | fno = fileno (rl_instream); |
503 | FD_SET (fno, &readset); | |
8f99e3f3 | 504 | |
576cdec4 MD |
505 | if (rl_point > 1) |
506 | { | |
507 | tmp = rl_point; | |
508 | rl_point = find_matching_paren (k); | |
509 | if (rl_point > -1) | |
510 | { | |
511 | rl_redisplay (); | |
7dfcaf26 | 512 | select (fno + 1, &readset, NULL, NULL, &timeout); |
576cdec4 MD |
513 | } |
514 | rl_point = tmp; | |
c374ab69 | 515 | } |
576cdec4 | 516 | return 0; |
c374ab69 | 517 | } |
6a945c34 | 518 | #endif /* HAVE_RL_GET_KEYMAP */ |
c374ab69 | 519 | |
26047451 MD |
520 | #endif /* HAVE_RL_GETC_FUNCTION */ |
521 | ||
c374ab69 MV |
522 | void |
523 | scm_init_readline () | |
524 | { | |
62947883 | 525 | #ifdef HAVE_RL_GETC_FUNCTION |
a0599745 | 526 | #include "guile-readline/readline.x" |
c374ab69 | 527 | scm_readline_completion_function_var |
296ff5e7 | 528 | = scm_c_define ("*readline-completion-function*", SCM_BOOL_F); |
c374ab69 | 529 | rl_getc_function = current_input_getc; |
dcb17187 MV |
530 | #if defined (_RL_FUNCTION_TYPEDEF) |
531 | rl_completion_entry_function = (rl_compentry_func_t*) completion_function; | |
532 | #else | |
c374ab69 | 533 | rl_completion_entry_function = (Function*) completion_function; |
dcb17187 | 534 | #endif |
4255e79f | 535 | rl_basic_word_break_characters = " \t\n\"'`;()"; |
5c11cc9d GH |
536 | rl_readline_name = "Guile"; |
537 | ||
ddfb5e2b AW |
538 | /* Let Guile handle signals. */ |
539 | #if defined (HAVE_DECL_RL_CATCH_SIGNALS) && HAVE_DECL_RL_CATCH_SIGNALS | |
540 | rl_catch_signals = 0; | |
541 | #endif | |
542 | ||
543 | /* But let readline handle SIGWINCH. */ | |
544 | #if defined (HAVE_DECL_RL_CATCH_SIGWINCH) && HAVE_DECL_RL_CATCH_SIGWINCH | |
545 | rl_catch_sigwinch = 1; | |
546 | #endif | |
547 | ||
e7efe8e7 | 548 | reentry_barrier_mutex = scm_make_mutex (); |
c374ab69 | 549 | scm_init_opts (scm_readline_options, |
07109436 | 550 | scm_readline_opts); |
6a945c34 | 551 | #if HAVE_RL_GET_KEYMAP |
c374ab69 | 552 | init_bouncing_parens(); |
6a945c34 | 553 | #endif |
c374ab69 | 554 | scm_add_feature ("readline"); |
62947883 | 555 | #endif /* HAVE_RL_GETC_FUNCTION */ |
c374ab69 MV |
556 | } |
557 | ||
89e00824 ML |
558 | /* |
559 | Local Variables: | |
560 | c-file-style: "gnu" | |
561 | End: | |
562 | */ |