OILS / pyext / line_input.c View on Github | oils.pub

1830 lines, 1085 significant
1/* line_input.c is an internal oils-for-unix fork of Python-2.7.13/Modules/readline.c.
2 * It is only used by pure-Python oils-ref. For C++ implementation, see cpp/frontend_pyreadline.cc.
3 */
4
5/* This module makes GNU readline available to Python. It has ideas
6 * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
7 * Center. The completer interface was inspired by Lele Gaifax. More
8 * recently, it was largely rewritten by Guido van Rossum.
9 */
10
11/* Standard definitions */
12#include "Python.h"
13#include <setjmp.h>
14#include <signal.h>
15#include <errno.h>
16#include <sys/time.h>
17
18/* ------------------------------------------------------------------------- */
19
20/* OVM_MAIN: This section copied from autotool-generated pyconfig.h.
21 * We're not detecting any of it in Oil's configure script. They are for
22 * ancient readline versions.
23 * */
24
25/* Define if you have readline 2.1 */
26#define HAVE_RL_CALLBACK 1
27
28/* Define if you can turn off readline's signal handling. */
29#define HAVE_RL_CATCH_SIGNAL 1
30
31/* Define if you have readline 2.2 */
32#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1
33
34/* Define if you have readline 4.0 */
35#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1
36
37/* Define if you have readline 4.2 */
38#define HAVE_RL_COMPLETION_MATCHES 1
39
40/* Define if you have rl_completion_suppress_append */
41#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1
42
43/* Define if you have readline 4.0 */
44#define HAVE_RL_PRE_INPUT_HOOK 1
45
46/* Define if you have readline 4.0 */
47#define HAVE_RL_RESIZE_TERMINAL 1
48
49/* ------------------------------------------------------------------------- */
50
51#if defined(HAVE_SETLOCALE)
52/* GNU readline() mistakenly sets the LC_CTYPE locale.
53 * This is evil. Only the user or the app's main() should do this!
54 * We must save and restore the locale around the rl_initialize() call.
55 */
56#define SAVE_LOCALE
57#include <locale.h>
58#endif
59
60#ifdef SAVE_LOCALE
61# define RESTORE_LOCALE(sl) { setlocale(LC_CTYPE, sl); free(sl); }
62#else
63# define RESTORE_LOCALE(sl)
64#endif
65
66/* GNU readline definitions */
67#undef HAVE_CONFIG_H /* Else readline/chardefs.h includes strings.h */
68#include <readline/readline.h>
69#include <readline/history.h>
70
71#ifdef HAVE_RL_COMPLETION_MATCHES
72#define completion_matches(x, y) \
73 rl_completion_matches((x), ((rl_compentry_func_t *)(y)))
74#else
75#if defined(_RL_FUNCTION_TYPEDEF)
76extern char **completion_matches(char *, rl_compentry_func_t *);
77#else
78
79#if !defined(__APPLE__)
80extern char **completion_matches(char *, CPFunction *);
81#endif
82#endif
83#endif
84
85#ifdef __APPLE__
86/*
87 * It is possible to link the readline module to the readline
88 * emulation library of editline/libedit.
89 *
90 * On OSX this emulation library is not 100% API compatible
91 * with the "real" readline and cannot be detected at compile-time,
92 * hence we use a runtime check to detect if we're using libedit
93 *
94 * Currently there is one known API incompatibility:
95 * - 'get_history' has a 1-based index with GNU readline, and a 0-based
96 * index with older versions of libedit's emulation.
97 * - Note that replace_history and remove_history use a 0-based index
98 * with both implementations.
99 */
100static int using_libedit_emulation = 0;
101static const char libedit_version_tag[] = "EditLine wrapper";
102
103static int libedit_history_start = 0;
104#endif /* __APPLE__ */
105
106#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
107static void
108on_completion_display_matches_hook(char **matches,
109 int num_matches, int max_length);
110#endif
111
112/* Memory allocated for rl_completer_word_break_characters
113 (see issue #17289 for the motivation). */
114static char *completer_word_break_characters;
115
116/* Exported function to send one line to readline's init file parser */
117
118static PyObject *
119parse_and_bind(PyObject *self, PyObject *args)
120{
121 char *s, *copy;
122 int binding_result;
123
124 if (!PyArg_ParseTuple(args, "s:parse_and_bind", &s))
125 return NULL;
126 /* Make a copy -- rl_parse_and_bind() modifies its argument */
127 /* Bernard Herzog */
128 copy = malloc(1 + strlen(s));
129 if (copy == NULL)
130 return PyErr_NoMemory();
131 strcpy(copy, s);
132
133 binding_result = rl_parse_and_bind(copy);
134 free(copy); /* Free the copy */
135
136 if (binding_result != 0) {
137 PyErr_Format(PyExc_ValueError, "'%s': invalid binding", s);
138 return NULL;
139 }
140
141 Py_RETURN_NONE;
142}
143
144PyDoc_STRVAR(doc_parse_and_bind,
145"parse_and_bind(string) -> None\n\
146Bind a key sequence to a readline function (or a variable to a value).");
147
148
149
150/* Exported function to parse a readline init file */
151
152static PyObject *
153read_init_file(PyObject *self, PyObject *args)
154{
155 char *s = NULL;
156 if (!PyArg_ParseTuple(args, "|z:read_init_file", &s))
157 return NULL;
158 errno = rl_read_init_file(s);
159 if (errno)
160 return PyErr_SetFromErrno(PyExc_IOError);
161 Py_RETURN_NONE;
162}
163
164PyDoc_STRVAR(doc_read_init_file,
165"read_init_file([filename]) -> None\n\
166Execute a readline initialization file.\n\
167The default filename is the last filename used.");
168
169
170/* Exported function to load a readline history file */
171
172static PyObject *
173read_history_file(PyObject *self, PyObject *args)
174{
175 char *s = NULL;
176 if (!PyArg_ParseTuple(args, "|z:read_history_file", &s))
177 return NULL;
178 errno = read_history(s);
179 if (errno)
180 return PyErr_SetFromErrno(PyExc_IOError);
181 Py_RETURN_NONE;
182}
183
184static int _history_length = -1; /* do not truncate history by default */
185PyDoc_STRVAR(doc_read_history_file,
186"read_history_file([filename]) -> None\n\
187Load a readline history file.\n\
188The default filename is ~/.history.");
189
190
191/* Exported function to save a readline history file */
192
193static PyObject *
194write_history_file(PyObject *self, PyObject *args)
195{
196 char *s = NULL;
197 if (!PyArg_ParseTuple(args, "|z:write_history_file", &s))
198 return NULL;
199 errno = write_history(s);
200 if (!errno && _history_length >= 0)
201 history_truncate_file(s, _history_length);
202 if (errno)
203 return PyErr_SetFromErrno(PyExc_IOError);
204 Py_RETURN_NONE;
205}
206
207PyDoc_STRVAR(doc_write_history_file,
208"write_history_file([filename]) -> None\n\
209Save a readline history file.\n\
210The default filename is ~/.history.");
211
212
213/* Set history length */
214
215static PyObject*
216set_history_length(PyObject *self, PyObject *args)
217{
218 int length = _history_length;
219 if (!PyArg_ParseTuple(args, "i:set_history_length", &length))
220 return NULL;
221 _history_length = length;
222 Py_RETURN_NONE;
223}
224
225PyDoc_STRVAR(set_history_length_doc,
226"set_history_length(length) -> None\n\
227set the maximal number of lines which will be written to\n\
228the history file. A negative length is used to inhibit\n\
229history truncation.");
230
231
232/* Get history length */
233
234static PyObject*
235get_history_length(PyObject *self, PyObject *noarg)
236{
237 return PyInt_FromLong(_history_length);
238}
239
240PyDoc_STRVAR(get_history_length_doc,
241"get_history_length() -> int\n\
242return the maximum number of lines that will be written to\n\
243the history file.");
244
245
246/* Generic hook function setter */
247
248static PyObject *
249set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
250{
251 PyObject *function = Py_None;
252 char buf[80];
253 PyOS_snprintf(buf, sizeof(buf), "|O:set_%.50s", funcname);
254 if (!PyArg_ParseTuple(args, buf, &function))
255 return NULL;
256 if (function == Py_None) {
257 Py_CLEAR(*hook_var);
258 }
259 else if (PyCallable_Check(function)) {
260 PyObject *tmp = *hook_var;
261 Py_INCREF(function);
262 *hook_var = function;
263 Py_XDECREF(tmp);
264 }
265 else {
266 PyOS_snprintf(buf, sizeof(buf),
267 "set_%.50s(func): argument not callable",
268 funcname);
269 PyErr_SetString(PyExc_TypeError, buf);
270 return NULL;
271 }
272 Py_RETURN_NONE;
273}
274
275
276/* Exported functions to specify hook functions in Python */
277
278static PyObject *completion_display_matches_hook = NULL;
279static PyObject *startup_hook = NULL;
280static PyObject *bind_shell_command_hook = NULL;
281
282#ifdef HAVE_RL_PRE_INPUT_HOOK
283static PyObject *pre_input_hook = NULL;
284#endif
285
286static PyObject *
287set_completion_display_matches_hook(PyObject *self, PyObject *args)
288{
289 PyObject *result = set_hook("completion_display_matches_hook",
290 &completion_display_matches_hook, args);
291#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
292 /* We cannot set this hook globally, since it replaces the
293 default completion display. */
294 rl_completion_display_matches_hook =
295 completion_display_matches_hook ?
296#if defined(_RL_FUNCTION_TYPEDEF)
297 (rl_compdisp_func_t *)on_completion_display_matches_hook : 0;
298#else
299 (VFunction *)on_completion_display_matches_hook : 0;
300#endif
301#endif
302 return result;
303
304}
305
306PyDoc_STRVAR(doc_set_completion_display_matches_hook,
307"set_completion_display_matches_hook([function]) -> None\n\
308Set or remove the completion display function.\n\
309The function is called as\n\
310 function(substitution, [matches], longest_match_length)\n\
311once each time matches need to be displayed.");
312
313static PyObject *
314set_startup_hook(PyObject *self, PyObject *args)
315{
316 return set_hook("startup_hook", &startup_hook, args);
317}
318
319PyDoc_STRVAR(doc_set_startup_hook,
320"set_startup_hook([function]) -> None\n\
321Set or remove the function invoked by the rl_startup_hook callback.\n\
322The function is called with no arguments just\n\
323before readline prints the first prompt.");
324
325
326#ifdef HAVE_RL_PRE_INPUT_HOOK
327
328/* Set pre-input hook */
329
330static PyObject *
331set_pre_input_hook(PyObject *self, PyObject *args)
332{
333 return set_hook("pre_input_hook", &pre_input_hook, args);
334}
335
336PyDoc_STRVAR(doc_set_pre_input_hook,
337"set_pre_input_hook([function]) -> None\n\
338Set or remove the function invoked by the rl_pre_input_hook callback.\n\
339The function is called with no arguments after the first prompt\n\
340has been printed and just before readline starts reading input\n\
341characters.");
342
343#endif
344
345
346/* Exported function to specify a word completer in Python */
347
348static PyObject *completer = NULL;
349
350static PyObject *begidx = NULL;
351static PyObject *endidx = NULL;
352
353
354/* Get the completion type for the scope of the tab-completion */
355static PyObject *
356get_completion_type(PyObject *self, PyObject *noarg)
357{
358 return PyInt_FromLong(rl_completion_type);
359}
360
361PyDoc_STRVAR(doc_get_completion_type,
362"get_completion_type() -> int\n\
363Get the type of completion being attempted.");
364
365
366/* Set bind -x Python command hook */
367
368static PyObject *
369set_bind_shell_command_hook(PyObject *self, PyObject *args)
370{
371 return set_hook("bind_shell_command_hook", &bind_shell_command_hook, args);
372}
373
374PyDoc_STRVAR(doc_set_bind_shell_command_hook,
375"set_bind_shell_command_hook([function]) -> None\n\
376Set or remove the function invoked by the rl_bind_keyseq_in_map callback.\n\
377The function is called with three arguments: the string to parse and evaluate,\n\
378the contents of the readline buffer to put in the READLINE_LINE env var,\n\
379and the int of the cursor's point in the buffer to put in READLINE_POINT.\n\
380It must return the READLINE_* vars in a tuple.");
381
382
383/* Get the beginning index for the scope of the tab-completion */
384
385static PyObject *
386get_begidx(PyObject *self, PyObject *noarg)
387{
388 Py_INCREF(begidx);
389 return begidx;
390}
391
392PyDoc_STRVAR(doc_get_begidx,
393"get_begidx() -> int\n\
394get the beginning index of the completion scope");
395
396
397/* Get the ending index for the scope of the tab-completion */
398
399static PyObject *
400get_endidx(PyObject *self, PyObject *noarg)
401{
402 Py_INCREF(endidx);
403 return endidx;
404}
405
406PyDoc_STRVAR(doc_get_endidx,
407"get_endidx() -> int\n\
408get the ending index of the completion scope");
409
410
411/* Set the tab-completion word-delimiters that readline uses */
412
413static PyObject *
414set_completer_delims(PyObject *self, PyObject *args)
415{
416 char *break_chars;
417
418 if (!PyArg_ParseTuple(args, "s:set_completer_delims", &break_chars)) {
419 return NULL;
420 }
421 /* Keep a reference to the allocated memory in the module state in case
422 some other module modifies rl_completer_word_break_characters
423 (see issue #17289). */
424 break_chars = strdup(break_chars);
425 if (break_chars) {
426 free(completer_word_break_characters);
427 completer_word_break_characters = break_chars;
428 rl_completer_word_break_characters = break_chars;
429 Py_RETURN_NONE;
430 }
431 else
432 return PyErr_NoMemory();
433}
434
435PyDoc_STRVAR(doc_set_completer_delims,
436"set_completer_delims(string) -> None\n\
437set the word delimiters for completion");
438
439/* _py_free_history_entry: Utility function to free a history entry. */
440
441#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0500
442
443/* Readline version >= 5.0 introduced a timestamp field into the history entry
444 structure; this needs to be freed to avoid a memory leak. This version of
445 readline also introduced the handy 'free_history_entry' function, which
446 takes care of the timestamp. */
447
448static void
449_py_free_history_entry(HIST_ENTRY *entry)
450{
451 histdata_t data = free_history_entry(entry);
452 free(data);
453}
454
455#else
456
457/* No free_history_entry function; free everything manually. */
458
459static void
460_py_free_history_entry(HIST_ENTRY *entry)
461{
462 if (entry->line)
463 free((void *)entry->line);
464 if (entry->data)
465 free(entry->data);
466 free(entry);
467}
468
469#endif
470
471static PyObject *
472py_remove_history(PyObject *self, PyObject *args)
473{
474 int entry_number;
475 HIST_ENTRY *entry;
476
477 if (!PyArg_ParseTuple(args, "i:remove_history_item", &entry_number))
478 return NULL;
479 if (entry_number < 0) {
480 PyErr_SetString(PyExc_ValueError,
481 "History index cannot be negative");
482 return NULL;
483 }
484 entry = remove_history(entry_number);
485 if (!entry) {
486 PyErr_Format(PyExc_ValueError,
487 "No history item at position %d",
488 entry_number);
489 return NULL;
490 }
491 /* free memory allocated for the history entry */
492 _py_free_history_entry(entry);
493 Py_RETURN_NONE;
494}
495
496PyDoc_STRVAR(doc_remove_history,
497"remove_history_item(pos) -> None\n\
498remove history item given by its position");
499
500static PyObject *
501py_replace_history(PyObject *self, PyObject *args)
502{
503 int entry_number;
504 char *line;
505 HIST_ENTRY *old_entry;
506
507 if (!PyArg_ParseTuple(args, "is:replace_history_item", &entry_number,
508 &line)) {
509 return NULL;
510 }
511 if (entry_number < 0) {
512 PyErr_SetString(PyExc_ValueError,
513 "History index cannot be negative");
514 return NULL;
515 }
516 old_entry = replace_history_entry(entry_number, line, (void *)NULL);
517 if (!old_entry) {
518 PyErr_Format(PyExc_ValueError,
519 "No history item at position %d",
520 entry_number);
521 return NULL;
522 }
523 /* free memory allocated for the old history entry */
524 _py_free_history_entry(old_entry);
525 Py_RETURN_NONE;
526}
527
528PyDoc_STRVAR(doc_replace_history,
529"replace_history_item(pos, line) -> None\n\
530replaces history item given by its position with contents of line");
531
532/* Add a line to the history buffer */
533
534static PyObject *
535py_add_history(PyObject *self, PyObject *args)
536{
537 char *line;
538
539 if(!PyArg_ParseTuple(args, "s:add_history", &line)) {
540 return NULL;
541 }
542 add_history(line);
543 Py_RETURN_NONE;
544}
545
546PyDoc_STRVAR(doc_add_history,
547"add_history(string) -> None\n\
548add an item to the history buffer");
549
550
551/* Get the tab-completion word-delimiters that readline uses */
552
553static PyObject *
554get_completer_delims(PyObject *self, PyObject *noarg)
555{
556 return PyString_FromString(rl_completer_word_break_characters);
557}
558
559PyDoc_STRVAR(doc_get_completer_delims,
560"get_completer_delims() -> string\n\
561get the word delimiters for completion");
562
563
564/* Set the completer function */
565
566static PyObject *
567set_completer(PyObject *self, PyObject *args)
568{
569 return set_hook("completer", &completer, args);
570}
571
572PyDoc_STRVAR(doc_set_completer,
573"set_completer([function]) -> None\n\
574Set or remove the completer function.\n\
575The function is called as function(text, state),\n\
576for state in 0, 1, 2, ..., until it returns a non-string.\n\
577It should return the next possible completion starting with 'text'.");
578
579
580static PyObject *
581get_completer(PyObject *self, PyObject *noargs)
582{
583 if (completer == NULL) {
584 Py_RETURN_NONE;
585 }
586 Py_INCREF(completer);
587 return completer;
588}
589
590PyDoc_STRVAR(doc_get_completer,
591"get_completer() -> function\n\
592\n\
593Returns current completer function.");
594
595/* Private function to get current length of history. XXX It may be
596 * possible to replace this with a direct use of history_length instead,
597 * but it's not clear whether BSD's libedit keeps history_length up to date.
598 * See issue #8065.*/
599
600static int
601_py_get_history_length(void)
602{
603 HISTORY_STATE *hist_st = history_get_history_state();
604 int length = hist_st->length;
605 /* the history docs don't say so, but the address of hist_st changes each
606 time history_get_history_state is called which makes me think it's
607 freshly malloc'd memory... on the other hand, the address of the last
608 line stays the same as long as history isn't extended, so it appears to
609 be malloc'd but managed by the history package... */
610 free(hist_st);
611 return length;
612}
613
614/* Exported function to get any element of history */
615
616static PyObject *
617get_history_item(PyObject *self, PyObject *args)
618{
619 int idx = 0;
620 HIST_ENTRY *hist_ent;
621
622 if (!PyArg_ParseTuple(args, "i:get_history_item", &idx))
623 return NULL;
624#ifdef __APPLE__
625 if (using_libedit_emulation) {
626 /* Older versions of libedit's readline emulation
627 * use 0-based indexes, while readline and newer
628 * versions of libedit use 1-based indexes.
629 */
630 int length = _py_get_history_length();
631
632 idx = idx - 1 + libedit_history_start;
633
634 /*
635 * Apple's readline emulation crashes when
636 * the index is out of range, therefore
637 * test for that and fail gracefully.
638 */
639 if (idx < (0 + libedit_history_start)
640 || idx >= (length + libedit_history_start)) {
641 Py_RETURN_NONE;
642 }
643 }
644#endif /* __APPLE__ */
645 if ((hist_ent = history_get(idx)))
646 return PyString_FromString(hist_ent->line);
647 else {
648 Py_RETURN_NONE;
649 }
650}
651
652PyDoc_STRVAR(doc_get_history_item,
653"get_history_item() -> string\n\
654return the current contents of history item at index.");
655
656
657/* Exported function to get current length of history */
658
659static PyObject *
660get_current_history_length(PyObject *self, PyObject *noarg)
661{
662 return PyInt_FromLong((long)_py_get_history_length());
663}
664
665PyDoc_STRVAR(doc_get_current_history_length,
666"get_current_history_length() -> integer\n\
667return the current (not the maximum) length of history.");
668
669
670/* Exported function to read the current line buffer */
671
672static PyObject *
673get_line_buffer(PyObject *self, PyObject *noarg)
674{
675 return PyString_FromString(rl_line_buffer);
676}
677
678PyDoc_STRVAR(doc_get_line_buffer,
679"get_line_buffer() -> string\n\
680return the current contents of the line buffer.");
681
682
683#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
684
685/* Exported function to clear the current history */
686
687static PyObject *
688py_clear_history(PyObject *self, PyObject *noarg)
689{
690 clear_history();
691 Py_RETURN_NONE;
692}
693
694PyDoc_STRVAR(doc_clear_history,
695"clear_history() -> None\n\
696Clear the current readline history.");
697#endif
698
699/* Added for OSH. We need to call this in our SIGWINCH handler so global
700 * variables in readline get updated. */
701static PyObject *
702py_resize_terminal(PyObject *self, PyObject *noarg)
703{
704 rl_resize_terminal();
705 Py_RETURN_NONE;
706}
707
708/* Exported function to insert text into the line buffer */
709
710static PyObject *
711insert_text(PyObject *self, PyObject *args)
712{
713 char *s;
714 if (!PyArg_ParseTuple(args, "s:insert_text", &s))
715 return NULL;
716 rl_insert_text(s);
717 Py_RETURN_NONE;
718}
719
720PyDoc_STRVAR(doc_insert_text,
721"insert_text(string) -> None\n\
722Insert text into the line buffer at the cursor position.");
723
724
725/* Redisplay the line buffer */
726
727static PyObject *
728redisplay(PyObject *self, PyObject *noarg)
729{
730 rl_redisplay();
731 Py_RETURN_NONE;
732}
733
734PyDoc_STRVAR(doc_redisplay,
735"redisplay() -> None\n\
736Change what's displayed on the screen to reflect the current\n\
737contents of the line buffer.");
738
739
740/* Functions added to implement the 'bind' builtin in OSH */
741
742/* -x/-X command keymaps */
743static Keymap emacs_cmd_map;
744static Keymap vi_insert_cmd_map;
745static Keymap vi_movement_cmd_map;
746
747/*
748 These forcibly cast between a Keymap* and a rl_command_func_t*. Readline
749 uses an additional `.type` field to keep track of the pointer's true type.
750*/
751#define RL_KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
752#define RL_FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
753
754static void
755_init_command_maps(void)
756{
757 emacs_cmd_map = rl_make_bare_keymap();
758 vi_insert_cmd_map = rl_make_bare_keymap();
759 vi_movement_cmd_map = rl_make_bare_keymap();
760
761 /* Ensure that Esc- and Ctrl-X are also keymaps */
762 emacs_cmd_map[CTRL('X')].type = ISKMAP;
763 emacs_cmd_map[CTRL('X')].function = RL_KEYMAP_TO_FUNCTION(rl_make_bare_keymap());
764 emacs_cmd_map[ESC].type = ISKMAP;
765 emacs_cmd_map[ESC].function = RL_KEYMAP_TO_FUNCTION(rl_make_bare_keymap());
766}
767
768static Keymap
769_get_associated_cmd_map(Keymap kmap)
770{
771 if (emacs_cmd_map == NULL)
772 _init_command_maps();
773
774 if (kmap == emacs_standard_keymap)
775 return emacs_cmd_map;
776 else if (kmap == vi_insertion_keymap)
777 return vi_insert_cmd_map;
778 else if (kmap == vi_movement_keymap)
779 return vi_movement_cmd_map;
780 else if (kmap == emacs_meta_keymap)
781 return (RL_FUNCTION_TO_KEYMAP(emacs_cmd_map, ESC));
782 else if (kmap == emacs_ctlx_keymap)
783 return (RL_FUNCTION_TO_KEYMAP(emacs_cmd_map, CTRL('X')));
784
785 return (Keymap) NULL;
786}
787
788/* List binding functions */
789static PyObject*
790list_funmap_names(PyObject *self, PyObject *args)
791{
792 rl_list_funmap_names();
793 Py_RETURN_NONE;
794}
795
796PyDoc_STRVAR(doc_list_funmap_names,
797"list_funmap_names() -> None\n\
798Print all of the available readline functions.");
799
800/* Print readline functions and their bindings */
801
802static PyObject*
803function_dumper(PyObject *self, PyObject *args)
804{
805 int print_readably;
806
807 if (!PyArg_ParseTuple(args, "i:function_dumper", &print_readably))
808 return NULL;
809
810 rl_function_dumper(print_readably);
811 Py_RETURN_NONE;
812}
813
814PyDoc_STRVAR(doc_list_function_dumper,
815"function_dumper(bool) -> None\n\
816Print all readline functions and their bindings.");
817
818/* Print macros, their bindings, and their string outputs */
819
820static PyObject*
821macro_dumper(PyObject *self, PyObject *args)
822{
823 int print_readably;
824
825 if (!PyArg_ParseTuple(args, "i:macro_dumper", &print_readably))
826 return NULL;
827
828 rl_macro_dumper(print_readably);
829 Py_RETURN_NONE;
830}
831
832PyDoc_STRVAR(doc_list_macro_dumper,
833"macro_dumper(bool) -> None\n\
834Print all readline sequences bound to macros and the strings they output.");
835
836
837/* List readline variables */
838
839static PyObject*
840variable_dumper(PyObject *self, PyObject *args)
841{
842 int print_readably;
843
844 if (!PyArg_ParseTuple(args, "i:variable_dumper", &print_readably))
845 return NULL;
846
847 rl_variable_dumper(print_readably);
848 Py_RETURN_NONE;
849}
850
851PyDoc_STRVAR(doc_list_variable_dumper,
852"variable_dumper(bool) -> None\n\
853List readline variables and their values.");
854
855
856/* Query bindings for a function name */
857
858// readline returns null-terminated string arrays
859void _strvec_dispose(char **strvec) {
860 register int i;
861
862 if (strvec == NULL)
863 return;
864
865 for (i = 0; strvec[i]; i++) {
866 free(strvec[i]);
867 }
868
869 free(strvec);
870}
871
872// Nicely prints a strvec with commas and an and
873// like '"foo", "bar", and "moop"'
874void _pprint_strvec_list(char **strvec) {
875 int i;
876
877 for (i = 0; strvec[i]; i++) {
878 printf("\"%s\"", strvec[i]);
879 if (strvec[i + 1]) {
880 printf(", ");
881 if (!strvec[i + 2])
882 printf("and ");
883 }
884 }
885}
886
887/*
888NB: readline (and bash) have a bug where they don't see certain keyseqs, even
889if the bindings work. E.g., if you bind a number key like "\C-7", it will be
890bound, but reporting code like query_bindings and function_dumper won't count it.
891*/
892
893static PyObject*
894query_bindings(PyObject *self, PyObject *args)
895{
896 char *fn_name;
897 rl_command_func_t *cmd_fn;
898 char **key_seqs;
899
900 if (!PyArg_ParseTuple(args, "s:query_bindings", &fn_name))
901 return NULL;
902
903 cmd_fn = rl_named_function(fn_name);
904
905 if (cmd_fn == NULL) {
906 PyErr_Format(PyExc_ValueError, "`%s': unknown function name", fn_name);
907 return NULL;
908 }
909
910 key_seqs = rl_invoking_keyseqs(cmd_fn);
911
912 if (!key_seqs) {
913 // print to stdout, but return an error
914 printf("%s is not bound to any keys.\n", fn_name);
915 PyErr_SetNone(PyExc_ValueError);
916 return NULL;
917 }
918
919 printf("%s can be invoked via ", fn_name);
920 _pprint_strvec_list(key_seqs);
921 printf(".\n");
922
923 _strvec_dispose(key_seqs);
924
925 Py_RETURN_NONE;
926}
927
928PyDoc_STRVAR(doc_query_bindings,
929"query_bindings(str) -> None\n\
930Query bindings to see what's bound to a given function.");
931
932
933static PyObject*
934unbind_rl_function(PyObject *self, PyObject *args)
935{
936 char *fn_name;
937 rl_command_func_t *cmd_fn;
938
939 if (!PyArg_ParseTuple(args, "s:unbind_rl_function", &fn_name))
940 return NULL;
941
942 cmd_fn = rl_named_function(fn_name);
943 if (cmd_fn == NULL) {
944 PyErr_Format(PyExc_ValueError, "`%s': unknown function name", fn_name);
945 return NULL;
946 }
947
948 rl_unbind_function_in_map(cmd_fn, rl_get_keymap());
949 Py_RETURN_NONE;
950}
951
952PyDoc_STRVAR(doc_unbind_rl_function,
953"unbind_rl_function(function_name) -> None\n\
954Unbind all keys bound to the named readline function in the current keymap.");
955
956
957static PyObject*
958print_shell_cmd_map(PyObject *self, PyObject *noarg)
959{
960 Keymap curr_map, cmd_map;
961
962 curr_map = rl_get_keymap();
963 cmd_map = _get_associated_cmd_map(curr_map);
964
965 if (cmd_map == NULL) {
966 PyErr_SetString(PyExc_ValueError, "Could not get shell command map for current keymap");
967 return NULL;
968 }
969
970 rl_set_keymap(cmd_map);
971 rl_macro_dumper(1);
972 rl_set_keymap(curr_map);
973
974 Py_RETURN_NONE;
975}
976
977PyDoc_STRVAR(doc_print_shell_cmd_map,
978"print_shell_cmd_map() -> None\n\
979Print all bindings for shell commands in the current keymap.");
980
981
982/* Support fns for bind -x */
983
984/*
985Checks to see if a bind -x command altered $READLINE_LINE. Compares the post-command
986$READLINE_LINE (passed as post_line) with the current readline buffer
987contents. If they differ, it replaces the buffer with the new version, and adds the old
988version to the undo stack.
989*/
990static void
991update_line_if_needed(char *post_line)
992{
993 if (strcmp(post_line, rl_line_buffer) != 0) {
994 rl_point = rl_end;
995
996 rl_add_undo(UNDO_BEGIN, 0, 0, 0);
997 rl_delete_text(0, rl_point);
998 rl_point = 0;
999 rl_end = 0;
1000 rl_mark = 0;
1001 rl_insert_text(post_line);
1002 rl_add_undo(UNDO_END, 0, 0, 0);
1003 }
1004}
1005
1006
1007/*
1008Checks to see if a bind -x command altered $READLINE_POINT. Compares the post-command
1009$READLINE_POINT (passed as post_point) with the current readline cursor point.
1010If they differ, it updates the cursor point to the new value.
1011*/
1012static void
1013update_cursor_if_needed(int post_point) {
1014 if (post_point != rl_point) {
1015 rl_point = post_point;
1016 if (rl_point > rl_end)
1017 rl_point = rl_end;
1018 else if (rl_point < 0)
1019 rl_point = 0;
1020 }
1021}
1022
1023/* Returns the shell command(s) associated with the current key sequence */
1024static char*
1025get_bound_command(Keymap cmd_map) {
1026 int type;
1027 char *cmd = (char *)rl_function_of_keyseq(rl_executing_keyseq, cmd_map, &type);
1028
1029 if (cmd == NULL || type != ISMACR) {
1030 PyErr_SetString(PyExc_RuntimeError,
1031 "Cannot find shell command bound to this key sequence");
1032 return NULL;
1033 }
1034
1035 return cmd;
1036}
1037
1038static void
1039clear_current_line(int use_ce) {
1040 if (use_ce) {
1041 rl_clear_visible_line();
1042 fflush(rl_outstream);
1043 } else {
1044 rl_crlf();
1045 }
1046}
1047
1048
1049/*
1050Main entry point for executing shell commands. Based on bash_execute_unix_command
1051
1052This function is called when a bind -x command is executed. It retrieves the
1053shell command(s) associated with the current key sequence, handles the
1054actual execution of the command, and updates the line and cursor position as
1055necessary.
1056*/
1057
1058static int
1059on_bind_shell_command_hook(int count /* unused */, int key /* unused */) {
1060 char *cmd;
1061 int use_ce;
1062 Keymap cmd_map;
1063 PyObject *r = NULL;
1064 #ifdef WITH_THREAD
1065 PyGILState_STATE gilstate;
1066 #endif
1067 int cmd_return_code;
1068 char *post_line_buffer;
1069 int post_point;
1070 int result;
1071
1072#ifdef WITH_THREAD
1073 gilstate = PyGILState_Ensure();
1074#endif
1075
1076 if (bind_shell_command_hook == NULL) {
1077 PyErr_SetString(PyExc_RuntimeError, "No bind_shell_command_hook set");
1078 return 1;
1079 }
1080
1081 cmd_map = _get_associated_cmd_map(rl_get_keymap());
1082 cmd = get_bound_command(cmd_map);
1083 if (!cmd) {
1084 PyErr_SetString(PyExc_RuntimeError, "on_bind_shell_command_hook: Cannot find shell command in keymap");
1085 rl_crlf();
1086 rl_forced_update_display();
1087 return 1;
1088 }
1089
1090 use_ce = rl_get_termcap("ce") != NULL;
1091 clear_current_line(use_ce);
1092
1093 r = PyObject_CallFunction(bind_shell_command_hook,
1094 "ssi", cmd, rl_line_buffer, rl_point);
1095 if (r == NULL) {
1096 PyErr_Print();
1097 result = 1;
1098 goto cleanup;
1099 }
1100 if (!PyArg_ParseTuple(r, "isi", &cmd_return_code, &post_line_buffer, &post_point)) {
1101 PyErr_SetString(PyExc_ValueError, "Expected (int, str, int) tuple from bind_shell_command_hook");
1102 result = 1;
1103 goto cleanup;
1104 }
1105
1106 update_line_if_needed(post_line_buffer);
1107 update_cursor_if_needed(post_point);
1108
1109
1110 /* Redraw the prompt */
1111 if (use_ce && cmd_return_code != 124) {
1112 rl_redraw_prompt_last_line();
1113 } else {
1114 rl_forced_update_display();
1115 }
1116
1117 result = 0;
1118
1119cleanup:
1120 Py_XDECREF(r);
1121#ifdef WITH_THREAD
1122 PyGILState_Release(gilstate);
1123#endif
1124
1125done:
1126 return result;
1127}
1128
1129
1130/* Maps a key sequence to arbitrary shell code (not built-in readline fns) */
1131static PyObject*
1132bind_shell_command(PyObject *self, PyObject *args) {
1133 const char *kseq;
1134 const char *cmd, *cparam;
1135 Keymap kmap, cmd_xmap;
1136
1137 if (!PyArg_ParseTuple(args, "ss:bind_shell_command", &kseq, &cparam)) {
1138 return NULL;
1139 }
1140
1141 /* readline will own the cmd string, so we need to make a copy */
1142 cmd = strdup(cparam);
1143 if (cmd == NULL) {
1144 return PyErr_NoMemory();
1145 }
1146
1147 kmap = rl_get_keymap();
1148 cmd_xmap = _get_associated_cmd_map(kmap);
1149
1150
1151 if (rl_generic_bind(ISMACR, kseq, (char *)cmd, cmd_xmap) != 0
1152 || rl_bind_keyseq_in_map (kseq, on_bind_shell_command_hook, kmap) != 0) {
1153 PyErr_Format(PyExc_RuntimeError, "Failed to bind key sequence '%s' to command '%s'", kseq, cmd);
1154 free(cmd);
1155 return NULL;
1156 }
1157
1158 Py_RETURN_NONE;
1159}
1160
1161PyDoc_STRVAR(doc_bind_shell_command,
1162"bind_shell_command(key_sequence, command) -> None\n\
1163Bind a key sequence to a shell command in the current keymap.");
1164
1165
1166/* Remove all bindings for a given keyseq */
1167
1168int
1169_unbind_shell_cmd(char *keyseq)
1170{
1171/* Unbind a key sequence from the current keymap's associated shell command map. */
1172Keymap cmd_map;
1173
1174 cmd_map = _get_associated_cmd_map(rl_get_keymap());
1175
1176 if (rl_bind_keyseq_in_map(keyseq, (rl_command_func_t *)NULL, cmd_map) != 0) {
1177 PyErr_Format(PyExc_ValueError, "'%s': can't unbind from shell command keymap", keyseq);
1178 return 0;
1179 }
1180
1181 return 1;
1182}
1183
1184static PyObject*
1185unbind_keyseq(PyObject *self, PyObject *args)
1186{
1187 char *seq, *keyseq;
1188 int kslen, type;
1189 rl_command_func_t *fn;
1190
1191 if (!PyArg_ParseTuple(args, "s:unbind_keyseq", &seq))
1192 return NULL;
1193
1194 /* Parse and check validity of keyseq */
1195 keyseq = (char *)malloc((2 * strlen(seq)) + 1);
1196 if (rl_translate_keyseq(seq, keyseq, &kslen) != 0) {
1197 free(keyseq);
1198 PyErr_Format(PyExc_ValueError, "'%s': invalid key sequence", seq);
1199 Py_RETURN_NONE;
1200 }
1201
1202 fn = rl_function_of_keyseq(keyseq, (Keymap)NULL, &type);
1203 free(keyseq);
1204
1205 if (!fn) {
1206 Py_RETURN_NONE;
1207 }
1208
1209 if (type == ISKMAP) {
1210 fn = ((Keymap)fn)[ANYOTHERKEY].function;
1211 }
1212
1213 if (rl_bind_keyseq(seq, (rl_command_func_t *)NULL) != 0) {
1214 PyErr_Format(PyExc_ValueError, "'%s': cannot unbind", seq);
1215 Py_RETURN_NONE;
1216 }
1217
1218 if (fn == on_bind_shell_command_hook) {
1219 _unbind_shell_cmd (seq);
1220 }
1221
1222 Py_RETURN_NONE;
1223}
1224
1225PyDoc_STRVAR(doc_unbind_keyseq,
1226"unbind_keyseq(sequence) -> None\n\
1227Unbind a key sequence from the current keymap.");
1228
1229
1230
1231/* Keymap toggling code */
1232static Keymap orig_keymap = NULL;
1233
1234static PyObject*
1235use_temp_keymap(PyObject *self, PyObject *args)
1236{
1237 char *keymap_name;
1238 Keymap new_keymap;
1239
1240 if (!PyArg_ParseTuple(args, "s:use_temp_keymap", &keymap_name))
1241 return NULL;
1242
1243 new_keymap = rl_get_keymap_by_name(keymap_name);
1244 if (new_keymap == NULL) {
1245 PyErr_Format(PyExc_ValueError, "`%s': unknown keymap name", keymap_name);
1246 return NULL;
1247 }
1248
1249 orig_keymap = rl_get_keymap();
1250 rl_set_keymap(new_keymap);
1251
1252 Py_RETURN_NONE;
1253}
1254
1255PyDoc_STRVAR(doc_use_temp_keymap,
1256"use_temp_keymap(keymap_name) -> None\n\
1257Temporarily switch to named keymap, saving the current one.");
1258
1259static PyObject*
1260restore_orig_keymap(PyObject *self, PyObject *args)
1261{
1262 if (orig_keymap != NULL) {
1263 rl_set_keymap(orig_keymap);
1264 orig_keymap = NULL;
1265 }
1266
1267 Py_RETURN_NONE;
1268}
1269
1270PyDoc_STRVAR(doc_restore_orig_keymap,
1271"restore_orig_keymap() -> None\n\
1272Restore the previously saved keymap if one exists.");
1273
1274/* Table of functions exported by the module */
1275
1276static struct PyMethodDef readline_methods[] = {
1277 {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind},
1278 {"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer},
1279 {"insert_text", insert_text, METH_VARARGS, doc_insert_text},
1280 {"redisplay", redisplay, METH_NOARGS, doc_redisplay},
1281 {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file},
1282 {"read_history_file", read_history_file,
1283 METH_VARARGS, doc_read_history_file},
1284 {"write_history_file", write_history_file,
1285 METH_VARARGS, doc_write_history_file},
1286 {"get_history_item", get_history_item,
1287 METH_VARARGS, doc_get_history_item},
1288 {"get_current_history_length", (PyCFunction)get_current_history_length,
1289 METH_NOARGS, doc_get_current_history_length},
1290 {"set_history_length", set_history_length,
1291 METH_VARARGS, set_history_length_doc},
1292 {"get_history_length", get_history_length,
1293 METH_NOARGS, get_history_length_doc},
1294 {"set_completer", set_completer, METH_VARARGS, doc_set_completer},
1295 {"get_completer", get_completer, METH_NOARGS, doc_get_completer},
1296 {"get_completion_type", get_completion_type,
1297 METH_NOARGS, doc_get_completion_type},
1298 {"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx},
1299 {"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx},
1300
1301 {"set_completer_delims", set_completer_delims,
1302 METH_VARARGS, doc_set_completer_delims},
1303 {"add_history", py_add_history, METH_VARARGS, doc_add_history},
1304 {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
1305 {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
1306 {"get_completer_delims", get_completer_delims,
1307 METH_NOARGS, doc_get_completer_delims},
1308
1309 {"set_completion_display_matches_hook", set_completion_display_matches_hook,
1310 METH_VARARGS, doc_set_completion_display_matches_hook},
1311 {"set_startup_hook", set_startup_hook,
1312 METH_VARARGS, doc_set_startup_hook},
1313 {"set_pre_input_hook", set_pre_input_hook,
1314 METH_VARARGS, doc_set_pre_input_hook},
1315 {"clear_history", py_clear_history, METH_NOARGS, doc_clear_history},
1316 {"resize_terminal", py_resize_terminal, METH_NOARGS, ""},
1317
1318 /* Functions added to implement the 'bind' builtin in OSH */
1319 {"list_funmap_names", list_funmap_names, METH_NOARGS, doc_list_funmap_names},
1320 {"function_dumper", function_dumper, METH_VARARGS, doc_list_function_dumper},
1321 {"macro_dumper", macro_dumper, METH_VARARGS, doc_list_macro_dumper},
1322 {"variable_dumper", variable_dumper, METH_VARARGS, doc_list_variable_dumper},
1323 {"query_bindings", query_bindings, METH_VARARGS, doc_query_bindings},
1324 {"unbind_rl_function", unbind_rl_function, METH_VARARGS, doc_unbind_rl_function},
1325 {"use_temp_keymap", use_temp_keymap, METH_VARARGS, doc_use_temp_keymap},
1326 {"restore_orig_keymap", restore_orig_keymap, METH_NOARGS, doc_restore_orig_keymap},
1327 {"print_shell_cmd_map", print_shell_cmd_map, METH_NOARGS, doc_print_shell_cmd_map},
1328 {"unbind_keyseq", unbind_keyseq, METH_VARARGS, doc_unbind_keyseq},
1329 {"bind_shell_command", bind_shell_command, METH_VARARGS, doc_bind_shell_command},
1330 {"set_bind_shell_command_hook", set_bind_shell_command_hook,
1331 METH_VARARGS, doc_set_bind_shell_command_hook},
1332 {0, 0}
1333};
1334
1335
1336/* C function to call the Python hooks. */
1337
1338static int
1339on_hook(PyObject *func)
1340{
1341 int result = 0;
1342 if (func != NULL) {
1343 PyObject *r;
1344#ifdef WITH_THREAD
1345 PyGILState_STATE gilstate = PyGILState_Ensure();
1346#endif
1347 r = PyObject_CallFunction(func, NULL);
1348 if (r == NULL)
1349 goto error;
1350 if (r == Py_None)
1351 result = 0;
1352 else {
1353 result = PyInt_AsLong(r);
1354 if (result == -1 && PyErr_Occurred())
1355 goto error;
1356 }
1357 Py_DECREF(r);
1358 goto done;
1359 error:
1360 PyErr_Clear();
1361 Py_XDECREF(r);
1362 done:
1363#ifdef WITH_THREAD
1364 PyGILState_Release(gilstate);
1365#endif
1366 return result;
1367 }
1368 return result;
1369}
1370
1371static int
1372#if defined(_RL_FUNCTION_TYPEDEF)
1373on_startup_hook(void)
1374#else
1375on_startup_hook()
1376#endif
1377{
1378 return on_hook(startup_hook);
1379}
1380
1381#ifdef HAVE_RL_PRE_INPUT_HOOK
1382static int
1383#if defined(_RL_FUNCTION_TYPEDEF)
1384on_pre_input_hook(void)
1385#else
1386on_pre_input_hook()
1387#endif
1388{
1389 return on_hook(pre_input_hook);
1390}
1391#endif
1392
1393
1394/* C function to call the Python completion_display_matches */
1395
1396#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
1397static void
1398on_completion_display_matches_hook(char **matches,
1399 int num_matches, int max_length)
1400{
1401 int i;
1402 PyObject *m=NULL, *s=NULL, *r=NULL;
1403#ifdef WITH_THREAD
1404 PyGILState_STATE gilstate = PyGILState_Ensure();
1405#endif
1406 m = PyList_New(num_matches);
1407 if (m == NULL)
1408 goto error;
1409 for (i = 0; i < num_matches; i++) {
1410 s = PyString_FromString(matches[i+1]);
1411 if (s == NULL)
1412 goto error;
1413 if (PyList_SetItem(m, i, s) == -1)
1414 goto error;
1415 }
1416
1417 r = PyObject_CallFunction(completion_display_matches_hook,
1418 "sOi", matches[0], m, max_length);
1419
1420 Py_DECREF(m); m=NULL;
1421
1422 if (r == NULL ||
1423 (r != Py_None && PyInt_AsLong(r) == -1 && PyErr_Occurred())) {
1424 goto error;
1425 }
1426 Py_XDECREF(r); r=NULL;
1427
1428 if (0) {
1429 error:
1430 PyErr_Clear();
1431 Py_XDECREF(m);
1432 Py_XDECREF(r);
1433 }
1434#ifdef WITH_THREAD
1435 PyGILState_Release(gilstate);
1436#endif
1437}
1438
1439#endif
1440
1441#ifdef HAVE_RL_RESIZE_TERMINAL
1442static volatile sig_atomic_t sigwinch_received;
1443static PyOS_sighandler_t sigwinch_ohandler;
1444
1445static void
1446readline_sigwinch_handler(int signum)
1447{
1448 sigwinch_received = 1;
1449 if (sigwinch_ohandler &&
1450 sigwinch_ohandler != SIG_IGN && sigwinch_ohandler != SIG_DFL)
1451 sigwinch_ohandler(signum);
1452}
1453#endif
1454
1455/* C function to call the Python completer. */
1456
1457static char *
1458on_completion(const char *text, int state)
1459{
1460 char *result = NULL;
1461 if (completer != NULL) {
1462 PyObject *r;
1463#ifdef WITH_THREAD
1464 PyGILState_STATE gilstate = PyGILState_Ensure();
1465#endif
1466 rl_attempted_completion_over = 1;
1467 r = PyObject_CallFunction(completer, "si", text, state);
1468 if (r == NULL)
1469 goto error;
1470 if (r == Py_None) {
1471 result = NULL;
1472 }
1473 else {
1474 char *s = PyString_AsString(r);
1475 if (s == NULL)
1476 goto error;
1477 result = strdup(s);
1478 }
1479 Py_DECREF(r);
1480 goto done;
1481 error:
1482 PyErr_Clear();
1483 Py_XDECREF(r);
1484 done:
1485#ifdef WITH_THREAD
1486 PyGILState_Release(gilstate);
1487#endif
1488 return result;
1489 }
1490 return result;
1491}
1492
1493
1494/* A more flexible constructor that saves the "begidx" and "endidx"
1495 * before calling the normal completer */
1496
1497static char **
1498flex_complete(const char *text, int start, int end)
1499{
1500#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1501 rl_completion_append_character ='\0';
1502#endif
1503#ifdef HAVE_RL_COMPLETION_SUPPRESS_APPEND
1504 rl_completion_suppress_append = 0;
1505#endif
1506 Py_XDECREF(begidx);
1507 Py_XDECREF(endidx);
1508 begidx = PyInt_FromLong((long) start);
1509 endidx = PyInt_FromLong((long) end);
1510 return completion_matches(text, *on_completion);
1511}
1512
1513
1514/* Helper to initialize GNU readline properly. */
1515
1516static void
1517setup_readline(void)
1518{
1519#ifdef SAVE_LOCALE
1520 char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
1521 if (!saved_locale)
1522 Py_FatalError("not enough memory to save locale");
1523#endif
1524
1525#ifdef __APPLE__
1526 /* the libedit readline emulation resets key bindings etc
1527 * when calling rl_initialize. So call it upfront
1528 */
1529 if (using_libedit_emulation)
1530 rl_initialize();
1531
1532 /* Detect if libedit's readline emulation uses 0-based
1533 * indexing or 1-based indexing.
1534 */
1535 add_history("1");
1536 if (history_get(1) == NULL) {
1537 libedit_history_start = 0;
1538 } else {
1539 libedit_history_start = 1;
1540 }
1541 clear_history();
1542#endif /* __APPLE__ */
1543
1544 using_history();
1545
1546 rl_readline_name = "oils";
1547#if defined(PYOS_OS2) && defined(PYCC_GCC)
1548 /* Allow $if term= in .inputrc to work */
1549 rl_terminal_name = getenv("TERM");
1550#endif
1551 /* Force rebind of TAB to insert-tab */
1552 rl_bind_key('\t', rl_insert);
1553 /* Bind both ESC-TAB and ESC-ESC to the completion function */
1554 rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
1555 rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
1556#ifdef HAVE_RL_RESIZE_TERMINAL
1557 /* Set up signal handler for window resize */
1558 sigwinch_ohandler = PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
1559#endif
1560 /* Set our hook functions */
1561 rl_startup_hook = on_startup_hook;
1562#ifdef HAVE_RL_PRE_INPUT_HOOK
1563 rl_pre_input_hook = on_pre_input_hook;
1564#endif
1565 /* Set our completion function */
1566 rl_attempted_completion_function = flex_complete;
1567 /* Set Python word break characters */
1568 completer_word_break_characters =
1569 rl_completer_word_break_characters =
1570 strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
1571 /* All nonalphanums except '.' */
1572
1573 begidx = PyInt_FromLong(0L);
1574 endidx = PyInt_FromLong(0L);
1575
1576#ifdef __APPLE__
1577 if (!using_libedit_emulation)
1578#endif
1579 {
1580 if (!isatty(STDOUT_FILENO)) {
1581 /* Issue #19884: stdout is not a terminal. Disable meta modifier
1582 keys to not write the ANSI sequence "\033[1034h" into stdout. On
1583 terminals supporting 8 bit characters like TERM=xterm-256color
1584 (which is now the default Fedora since Fedora 18), the meta key is
1585 used to enable support of 8 bit characters (ANSI sequence
1586 "\033[1034h").
1587
1588 With libedit, this call makes readline() crash. */
1589 rl_variable_bind ("enable-meta-key", "off");
1590 }
1591 }
1592
1593 /* Initialize (allows .inputrc to override)
1594 *
1595 * XXX: A bug in the readline-2.2 library causes a memory leak
1596 * inside this function. Nothing we can do about it.
1597 */
1598#ifdef __APPLE__
1599 if (using_libedit_emulation)
1600 rl_read_init_file(NULL);
1601 else
1602#endif /* __APPLE__ */
1603 rl_initialize();
1604
1605 RESTORE_LOCALE(saved_locale)
1606}
1607
1608/* Wrapper around GNU readline that handles signals differently. */
1609
1610
1611#if defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT)
1612
1613static char *completed_input_string;
1614static void
1615rlhandler(char *text)
1616{
1617 completed_input_string = text;
1618 rl_callback_handler_remove();
1619}
1620
1621static char *
1622readline_until_enter_or_signal(char *prompt, int *signal)
1623{
1624 char * not_done_reading = "";
1625 fd_set selectset;
1626
1627 *signal = 0;
1628#ifdef HAVE_RL_CATCH_SIGNAL
1629 rl_catch_signals = 0;
1630#endif
1631 /* OVM_MAIN: Oil is handling SIGWINCH, so readline shouldn't handle it.
1632 * Without this line, strace reveals that GNU readline is constantly
1633 * turning it on and off.
1634 * */
1635 rl_catch_sigwinch = 0;
1636
1637 rl_callback_handler_install (prompt, rlhandler);
1638 FD_ZERO(&selectset);
1639
1640 completed_input_string = not_done_reading;
1641
1642 while (completed_input_string == not_done_reading) {
1643 int has_input = 0;
1644
1645 while (!has_input)
1646 { struct timeval timeout = {0, 100000}; /* 0.1 seconds */
1647
1648 /* [Bug #1552726] Only limit the pause if an input hook has been
1649 defined. */
1650 struct timeval *timeoutp = NULL;
1651 if (PyOS_InputHook)
1652 timeoutp = &timeout;
1653#ifdef HAVE_RL_RESIZE_TERMINAL
1654 /* Update readline's view of the window size after SIGWINCH */
1655 if (sigwinch_received) {
1656 sigwinch_received = 0;
1657 rl_resize_terminal();
1658 }
1659#endif
1660 FD_SET(fileno(rl_instream), &selectset);
1661 /* select resets selectset if no input was available */
1662 has_input = select(fileno(rl_instream) + 1, &selectset,
1663 NULL, NULL, timeoutp);
1664 if(PyOS_InputHook) PyOS_InputHook();
1665 }
1666
1667 if(has_input > 0) {
1668 rl_callback_read_char();
1669 }
1670 else if (errno == EINTR) {
1671 int s;
1672#ifdef WITH_THREAD
1673 PyEval_RestoreThread(_PyOS_ReadlineTState);
1674#endif
1675 s = PyErr_CheckSignals();
1676#ifdef WITH_THREAD
1677 PyEval_SaveThread();
1678#endif
1679 if (s < 0) {
1680 rl_free_line_state();
1681#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0700
1682 rl_callback_sigcleanup();
1683#endif
1684 rl_cleanup_after_signal();
1685 rl_callback_handler_remove();
1686 *signal = 1;
1687 completed_input_string = NULL;
1688 }
1689 }
1690 }
1691
1692 return completed_input_string;
1693}
1694
1695
1696#else
1697
1698/* Interrupt handler */
1699
1700static jmp_buf jbuf;
1701
1702/* ARGSUSED */
1703static void
1704onintr(int sig)
1705{
1706 longjmp(jbuf, 1);
1707}
1708
1709
1710static char *
1711readline_until_enter_or_signal(char *prompt, int *signal)
1712{
1713 PyOS_sighandler_t old_inthandler;
1714 char *p;
1715
1716 *signal = 0;
1717
1718 old_inthandler = PyOS_setsig(SIGINT, onintr);
1719 if (setjmp(jbuf)) {
1720#ifdef HAVE_SIGRELSE
1721 /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
1722 sigrelse(SIGINT);
1723#endif
1724 PyOS_setsig(SIGINT, old_inthandler);
1725 *signal = 1;
1726 return NULL;
1727 }
1728 rl_event_hook = PyOS_InputHook;
1729 p = readline(prompt);
1730 PyOS_setsig(SIGINT, old_inthandler);
1731
1732 return p;
1733}
1734#endif /*defined(HAVE_RL_CALLBACK) && defined(HAVE_SELECT) */
1735
1736
1737static char *
1738call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
1739{
1740 size_t n;
1741 char *p, *q;
1742 int signal;
1743
1744#ifdef SAVE_LOCALE
1745 char *saved_locale = strdup(setlocale(LC_CTYPE, NULL));
1746 if (!saved_locale)
1747 Py_FatalError("not enough memory to save locale");
1748 setlocale(LC_CTYPE, "");
1749#endif
1750
1751 if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
1752 rl_instream = sys_stdin;
1753 rl_outstream = sys_stdout;
1754#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1755 rl_prep_terminal (1);
1756#endif
1757 }
1758
1759 p = readline_until_enter_or_signal(prompt, &signal);
1760
1761 /* we got an interrupt signal */
1762 if (signal) {
1763 RESTORE_LOCALE(saved_locale)
1764 return NULL;
1765 }
1766
1767 /* We got an EOF, return an empty string. */
1768 if (p == NULL) {
1769 p = PyMem_Malloc(1);
1770 if (p != NULL)
1771 *p = '\0';
1772 RESTORE_LOCALE(saved_locale)
1773 return p;
1774 }
1775
1776 /* we have a valid line */
1777 n = strlen(p);
1778 /* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and
1779 release the original. */
1780 q = p;
1781 p = PyMem_Malloc(n+2);
1782 if (p != NULL) {
1783 strncpy(p, q, n);
1784 p[n] = '\n';
1785 p[n+1] = '\0';
1786 }
1787 free(q);
1788 RESTORE_LOCALE(saved_locale)
1789 return p;
1790}
1791
1792
1793/* Initialize the module */
1794
1795PyDoc_STRVAR(doc_module,
1796"Importing this module enables command line editing using GNU readline.");
1797
1798#ifdef __APPLE__
1799PyDoc_STRVAR(doc_module_le,
1800"Importing this module enables command line editing using libedit readline.");
1801#endif /* __APPLE__ */
1802
1803PyMODINIT_FUNC
1804initline_input(void)
1805{
1806 PyObject *m;
1807
1808#ifdef __APPLE__
1809 if (strncmp(rl_library_version, libedit_version_tag, strlen(libedit_version_tag)) == 0) {
1810 using_libedit_emulation = 1;
1811 }
1812
1813 if (using_libedit_emulation)
1814 m = Py_InitModule4("line_input", readline_methods, doc_module_le,
1815 (PyObject *)NULL, PYTHON_API_VERSION);
1816 else
1817
1818#endif /* __APPLE__ */
1819
1820 m = Py_InitModule4("line_input", readline_methods, doc_module,
1821 (PyObject *)NULL, PYTHON_API_VERSION);
1822 if (m == NULL)
1823 return;
1824
1825 PyOS_ReadlineFunctionPointer = call_readline;
1826 setup_readline();
1827
1828 PyModule_AddIntConstant(m, "_READLINE_VERSION", RL_READLINE_VERSION);
1829 PyModule_AddIntConstant(m, "_READLINE_RUNTIME_VERSION", rl_readline_version);
1830}