19 #include RUBY_EXTCONF_H
22 #include "ruby/config.h"
26 #ifdef HAVE_READLINE_READLINE_H
27 #include <readline/readline.h>
29 #ifdef HAVE_READLINE_HISTORY_H
30 #include <readline/history.h>
32 #ifdef HAVE_EDITLINE_READLINE_H
33 #include <editline/readline.h>
43 #ifdef HAVE_SYS_STAT_H
49 #define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
50 #ifndef USE_INSERT_IGNORE_ESCAPE
51 # if !defined(HAVE_EDITLINE_READLINE_H) && defined(HAVE_RL_PROMPT_START_IGNORE) && defined(HAVE_RL_PROMPT_END_IGNORE)
52 # define USE_INSERT_IGNORE_ESCAPE 1
54 # define USE_INSERT_IGNORE_ESCAPE 0
58 #define COMPLETION_PROC "completion_proc"
59 #define COMPLETION_CASE_FOLD "completion_case_fold"
61 #if USE_INSERT_IGNORE_ESCAPE
62 static ID id_orig_prompt, id_last_prompt;
65 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
66 # define rl_filename_completion_function filename_completion_function
68 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
69 # define rl_username_completion_function username_completion_function
71 #ifndef HAVE_RL_COMPLETION_MATCHES
72 # define rl_completion_matches completion_matches
77 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
78 static int readline_completion_append_character;
84 #define OutputStringValue(str) do {\
85 SafeStringValue(str);\
86 (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
125 #if defined HAVE_RL_GETC_FUNCTION
126 static VALUE readline_instream;
127 static ID id_getbyte;
130 #define rl_getc(f) EOF
133 static int readline_getc(
FILE *);
139 if (!readline_instream)
return rl_getc(input);
141 if (rl_instream != ifp->
stdio_file)
return rl_getc(input);
146 static int prior_key =
'0';
148 if (prior_key > 0xff) {
152 if (PeekConsoleInput((HANDLE)_get_osfhandle(ifp->
fd), &ir, 1, &n)) {
154 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
158 ReadConsoleInput((HANDLE)_get_osfhandle(ifp->
fd), &ir, 1, &n);
161 HANDLE h = (HANDLE)_get_osfhandle(ifp->
fd);
170 c =
rb_funcall(readline_instream, id_getbyte, 0, 0);
174 #elif defined HAVE_RL_EVENT_HOOK
177 static int readline_event(
void);
190 #if USE_INSERT_IGNORE_ESCAPE
192 insert_ignore_escape(
VALUE self,
VALUE prompt)
196 const char *s0, *s, *e;
198 static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
202 if (orig_prompt == prompt)
return last_prompt;
204 if (
NIL_P(last_prompt)) {
211 while (s < e && *s) {
213 case RL_PROMPT_START_IGNORE:
218 case RL_PROMPT_END_IGNORE:
224 if (++s < e && *s ==
'[') {
227 while (++s < e && *s) {
237 else if (!(
'0' <= *s && *s <=
'9' || *s ==
';')) {
268 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
269 readline_completion_append_character = rl_completion_append_character;
271 return (
VALUE)readline((
char *)prompt);
369 if (
rb_scan_args(argc, argv,
"02", &tmp, &add_hist) > 0) {
371 #if USE_INSERT_IGNORE_ESCAPE
372 tmp = insert_ignore_escape(
self, tmp);
381 int fd =
fileno(rl_outstream);
382 if (fd < 0 ||
fstat(fd, &stbuf) != 0) {
391 #if USE_INSERT_IGNORE_ESCAPE
397 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
399 #if defined HAVE_RL_FREE_LINE_STATE
400 rl_free_line_state();
402 rl_cleanup_after_signal();
403 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
405 if (rl_deprep_term_function !=
NULL)
406 (*rl_deprep_term_function)();
409 rl_deprep_terminal();
414 if (
RTEST(add_hist) && buff) {
422 if (buff)
free(buff);
444 #ifdef HAVE_RL_GETC_FUNCTION
445 readline_instream =
input;
603 #ifdef HAVE_RL_LINE_BUFFER
619 if (rl_line_buffer == NULL)
624 #define readline_s_get_line_buffer rb_f_notimplement
648 #define readline_s_get_point rb_f_notimplement
654 VALUE proc, ary, temp;
664 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
665 rl_completion_append_character = readline_completion_append_character;
667 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
668 rl_attempted_completion_over = 1;
675 if (matches == 0)
return NULL;
676 result = (
char**)
malloc((matches + 2)*
sizeof(
char*));
680 for (i = 0; i < matches; i++) {
688 result[matches + 1] =
NULL;
691 result[0] =
strdup(result[1]);
694 const char *result1 = result[1];
695 long low =
strlen(result1);
697 for (i = 1; i < matches; ++
i) {
701 const char *p2 = result[i + 1];
704 for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
716 result[0] =
ALLOC_N(
char, low + 1);
717 strncpy(result[0], result[1], low);
718 result[0][low] =
'\0';
724 #ifdef HAVE_RL_SET_SCREEN_SIZE
745 #define readline_s_set_screen_size rb_f_notimplement
748 #ifdef HAVE_RL_GET_SCREEN_SIZE
768 rl_get_screen_size(&rows, &columns);
775 #define readline_s_get_screen_size rb_f_notimplement
778 #ifdef HAVE_RL_VI_EDITING_MODE
794 rl_vi_editing_mode(1,0);
798 #define readline_s_vi_editing_mode rb_f_notimplement
801 #ifdef HAVE_RL_EDITING_MODE
819 #define readline_s_vi_editing_mode_p rb_f_notimplement
822 #ifdef HAVE_RL_EMACS_EDITING_MODE
838 rl_emacs_editing_mode(1,0);
842 #define readline_s_emacs_editing_mode rb_f_notimplement
845 #ifdef HAVE_RL_EDITING_MODE
863 #define readline_s_emacs_editing_mode_p rb_f_notimplement
866 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
910 rl_completion_append_character =
'\0';
915 rl_completion_append_character =
'\0';
917 rl_completion_append_character =
RSTRING_PTR(str)[0];
923 #define readline_s_set_completion_append_character rb_f_notimplement
926 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
944 if (rl_completion_append_character ==
'\0')
947 buf[0] = (char) rl_completion_append_character;
951 #define readline_s_get_completion_append_character rb_f_notimplement
954 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
970 static char *basic_word_break_characters =
NULL;
974 if (basic_word_break_characters ==
NULL) {
975 basic_word_break_characters =
981 strncpy(basic_word_break_characters,
983 basic_word_break_characters[
RSTRING_LEN(str)] =
'\0';
984 rl_basic_word_break_characters = basic_word_break_characters;
988 #define readline_s_set_basic_word_break_characters rb_f_notimplement
991 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1007 if (rl_basic_word_break_characters ==
NULL)
1012 #define readline_s_get_basic_word_break_characters rb_f_notimplement
1015 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1031 static char *completer_word_break_characters =
NULL;
1035 if (completer_word_break_characters ==
NULL) {
1036 completer_word_break_characters =
1042 strncpy(completer_word_break_characters,
1044 completer_word_break_characters[
RSTRING_LEN(str)] =
'\0';
1045 rl_completer_word_break_characters = completer_word_break_characters;
1049 #define readline_s_set_completer_word_break_characters rb_f_notimplement
1052 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1068 if (rl_completer_word_break_characters ==
NULL)
1073 #define readline_s_get_completer_word_break_characters rb_f_notimplement
1076 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1090 static char *basic_quote_characters =
NULL;
1094 if (basic_quote_characters ==
NULL) {
1095 basic_quote_characters =
1101 strncpy(basic_quote_characters,
1104 rl_basic_quote_characters = basic_quote_characters;
1109 #define readline_s_set_basic_quote_characters rb_f_notimplement
1112 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1127 if (rl_basic_quote_characters ==
NULL)
1132 #define readline_s_get_basic_quote_characters rb_f_notimplement
1135 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1152 static char *completer_quote_characters =
NULL;
1156 if (completer_quote_characters ==
NULL) {
1157 completer_quote_characters =
1164 completer_quote_characters[
RSTRING_LEN(str)] =
'\0';
1165 rl_completer_quote_characters = completer_quote_characters;
1170 #define readline_s_set_completer_quote_characters rb_f_notimplement
1173 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1189 if (rl_completer_quote_characters ==
NULL)
1194 #define readline_s_get_completer_quote_characters rb_f_notimplement
1197 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1212 static char *filename_quote_characters =
NULL;
1216 if (filename_quote_characters ==
NULL) {
1217 filename_quote_characters =
1224 filename_quote_characters[
RSTRING_LEN(str)] =
'\0';
1225 rl_filename_quote_characters = filename_quote_characters;
1230 #define readline_s_set_filename_quote_characters rb_f_notimplement
1233 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1249 if (rl_filename_quote_characters ==
NULL)
1254 #define readline_s_get_filename_quote_characters rb_f_notimplement
1257 #ifdef HAVE_RL_REFRESH_LINE
1270 rl_refresh_line(0, 0);
1274 #define readline_s_refresh_line rb_f_notimplement
1286 return history_base + offset;
1298 HIST_ENTRY *entry =
NULL;
1304 i += history_length;
1309 if (entry ==
NULL) {
1315 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1319 HIST_ENTRY *entry =
NULL;
1326 i += history_length;
1331 if (entry == NULL) {
1337 #define hist_set rb_f_notimplement
1366 #ifdef HAVE_REMOVE_HISTORY
1371 entry = remove_history(index);
1374 free((
void *) entry->line);
1389 if (history_length > 0) {
1400 if (history_length > 0) {
1416 for (i = 0; i < history_length; i++) {
1429 return INT2NUM(history_length);
1447 i += history_length;
1448 if (i < 0 || i > history_length - 1) {
1454 #ifdef HAVE_CLEAR_HISTORY
1463 #define hist_clear rb_f_notimplement
1477 for (i = 0; matches[
i]; i++) {
1502 for (i = 0; matches[
i]; i++) {
1522 rl_readline_name = (
char *)
"Ruby";
1524 #if defined HAVE_RL_GETC_FUNCTION
1528 rl_getc_function = readline_getc;
1530 #elif defined HAVE_RL_EVENT_HOOK
1531 rl_event_hook = readline_event;
1597 #if USE_INSERT_IGNORE_ESCAPE
1598 CONST_ID(id_orig_prompt,
"orig_prompt");
1599 CONST_ID(id_last_prompt,
"last_prompt");
1645 #if defined HAVE_RL_LIBRARY_VERSION
1647 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
1654 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1655 if (replace_history_entry(0,
"a",
NULL) ==
NULL) {
1659 #ifdef HAVE_CLEAR_HISTORY
1663 HIST_ENTRY *entry = remove_history(0);
1665 free((
char *)entry->line);
1679 #ifdef HAVE_RL_CATCH_SIGNALS
1680 rl_catch_signals = 0;
1683 #ifdef HAVE_RL_CLEAR_SIGNALS