1 /* readline.c -- GNU Readline module
2 Copyright (C) 1997-2001 Shugo Maeda */
8 #include <readline/readline.h>
9 #include <readline/history.h>
15 static VALUE mReadline
;
17 #define TOLOWER(c) (isupper(c) ? tolower(c) : c)
19 #define COMPLETION_PROC "completion_proc"
20 #define COMPLETION_CASE_FOLD "completion_case_fold"
21 static ID completion_proc
, completion_case_fold
;
23 static int readline_event(void);
24 static char **readline_attempted_completion_function(const char *text
,
36 readline_readline(VALUE self
, VALUE tmp
, VALUE add_hist
)
45 prompt
= rb_str_get_char_ptr(tmp
);
47 if (!isatty(0) && errno
== EBADF
) rb_raise(rb_eIOError
, "stdin closed");
49 buff
= readline(prompt
);
52 buff
= (char*)rb_protect((VALUE(*)_((VALUE
)))readline
, (VALUE
)prompt
,
55 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
56 /* restore terminal mode and signal handler*/
57 rl_cleanup_after_signal();
58 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
59 /* restore terminal mode */
60 (*rl_deprep_term_function
)();
68 if (RTEST(add_hist
) && buff
) {
73 result
= rb_tainted_str_new2(buff
);
83 readline_s_set_completion_proc(self
, proc
)
88 if (!rb_respond_to(proc
, rb_intern("call")))
89 rb_raise(rb_eArgError
, "argument must respond to `call'");
90 return rb_ivar_set(mReadline
, completion_proc
, proc
);
94 readline_s_get_completion_proc(self
)
98 return rb_attr_get(mReadline
, completion_proc
);
102 readline_s_set_completion_case_fold(self
, val
)
107 return rb_ivar_set(mReadline
, completion_case_fold
, val
);
111 readline_s_get_completion_case_fold(self
)
115 return rb_attr_get(mReadline
, completion_case_fold
);
119 readline_attempted_completion_function(text
, start
, end
)
124 VALUE proc
, ary
, temp
;
129 proc
= rb_attr_get(mReadline
, completion_proc
);
132 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
133 rl_attempted_completion_over
= 1;
135 case_fold
= RTEST(rb_attr_get(mReadline
, completion_case_fold
));
136 ary
= rb_funcall(proc
, rb_intern("call"), 1, rb_tainted_str_new2(text
));
139 matches
= rb_ary_size(ary
);
140 if (matches
== 0) return NULL
;
141 result
= ALLOC_N(char *, matches
+ 2);
142 for (i
= 0; i
< matches
; i
++) {
143 temp
= rb_obj_as_string(rb_ary_entry(ary
, i
));
144 result
[i
+ 1] = rb_str_get_char_ptr(temp
);
146 result
[matches
+ 1] = NULL
;
149 result
[0] = strdup(result
[1]);
155 while (i
< matches
) {
156 register int c1
, c2
, si
;
160 (c1
= TOLOWER(result
[i
][si
])) &&
161 (c2
= TOLOWER(result
[i
+ 1][si
]));
166 (c1
= result
[i
][si
]) &&
167 (c2
= result
[i
+ 1][si
]);
172 if (low
> si
) low
= si
;
175 result
[0] = ALLOC_N(char, low
+ 1);
176 strncpy(result
[0], result
[1], low
);
177 result
[0][low
] = '\0';
184 readline_s_set_completion_append_character(self
, str
)
189 rl_completion_append_character
= '\0';
192 SafeStringValue(str
);
193 if (rb_str_get_char_len(str
) == 0) {
194 rl_completion_append_character
= '\0';
196 rl_completion_append_character
= rb_str_get_char(str
, 0);
203 readline_s_get_completion_append_character(self
)
209 if (rl_completion_append_character
== '\0')
212 return rb_str_new((char*)&rl_completion_append_character
, 1);
216 readline_s_set_basic_word_break_characters(self
, str
)
221 SafeStringValue(str
);
223 rl_basic_word_break_characters
= rb_str_get_char_ptr(str
);
229 readline_s_get_basic_word_break_characters(self
, str
)
233 if (rl_basic_word_break_characters
== NULL
)
235 return rb_tainted_str_new2(rl_basic_word_break_characters
);
239 readline_s_set_completer_word_break_characters(self
, str
)
243 SafeStringValue(str
);
245 rl_completer_word_break_characters
= rb_str_get_char_ptr(str
);
251 readline_s_get_completer_word_break_characters(self
, str
)
255 if (rl_completer_word_break_characters
== NULL
)
257 return rb_tainted_str_new2(rl_completer_word_break_characters
);
261 readline_s_set_completer_quote_characters(self
, str
)
264 static char *completer_quote_characters
= NULL
;
267 SafeStringValue(str
);
269 rl_completer_quote_characters
= rb_str_get_char_ptr(str
);
275 readline_s_get_completer_quote_characters(self
, str
)
279 if (rl_completer_quote_characters
== NULL
)
281 return rb_tainted_str_new2(rl_completer_quote_characters
);
288 return rb_str_new2("HISTORY");
292 hist_get(self
, index
)
304 entry
= history_get(history_base
+ i
);
306 rb_raise(rb_eIndexError
, "invalid index");
308 return rb_tainted_str_new2(entry
->line
);
312 hist_set(self
, index
, str
)
323 SafeStringValue(str
);
327 data
= rb_str_get_char_ptr(str
);
328 entry
= replace_history_entry(i
, data
, NULL
);
331 rb_raise(rb_eIndexError
, "invalid index");
343 SafeStringValue(str
);
344 data
= rb_str_get_char_ptr(str
);
351 hist_push_method(argc
, argv
, self
)
362 SafeStringValue(str
);
363 data
= rb_str_get_char_ptr(str
);
371 rb_remove_history(index
)
378 entry
= remove_history(index
);
380 val
= rb_tainted_str_new2(entry
->line
);
381 free((char*)entry
->line
);
393 if (history_length
> 0) {
394 return rb_remove_history(history_length
- 1);
405 if (history_length
> 0) {
406 return rb_remove_history(0);
420 for (i
= 0; i
< history_length
; i
++) {
421 entry
= history_get(history_base
+ i
);
424 rb_yield(rb_tainted_str_new2(entry
->line
));
434 return INT2NUM(history_length
);
442 return history_length
== 0 ? Qtrue
: Qfalse
;
446 hist_delete_at(self
, index
)
456 if (i
< 0 || i
> history_length
- 1) {
457 rb_raise(rb_eIndexError
, "invalid index");
459 return rb_remove_history(i
);
465 VALUE history
, fcomp
, ucomp
;
467 /* Allow conditional parsing of the ~/.inputrc file. */
468 rl_readline_name
= "Ruby";
472 completion_proc
= rb_intern(COMPLETION_PROC
);
473 completion_case_fold
= rb_intern(COMPLETION_CASE_FOLD
);
475 mReadline
= rb_define_module("Readline");
476 rb_define_singleton_method(mReadline
, "perform_readline",
477 readline_readline
, 2);
478 rb_define_singleton_method(mReadline
, "completion_proc=",
479 readline_s_set_completion_proc
, 1);
480 rb_define_singleton_method(mReadline
, "completion_proc",
481 readline_s_get_completion_proc
, 0);
482 rb_define_singleton_method(mReadline
, "completion_case_fold=",
483 readline_s_set_completion_case_fold
, 1);
484 rb_define_singleton_method(mReadline
, "completion_case_fold",
485 readline_s_get_completion_case_fold
, 0);
486 rb_define_singleton_method(mReadline
, "completion_append_character=",
487 readline_s_set_completion_append_character
, 1);
488 rb_define_singleton_method(mReadline
, "completion_append_character",
489 readline_s_get_completion_append_character
, 0);
490 rb_define_singleton_method(mReadline
, "basic_word_break_characters=",
491 readline_s_set_basic_word_break_characters
, 1);
492 rb_define_singleton_method(mReadline
, "basic_word_break_characters",
493 readline_s_get_basic_word_break_characters
, 0);
494 rb_define_singleton_method(mReadline
, "completer_word_break_characters=",
495 readline_s_set_completer_word_break_characters
, 1);
496 rb_define_singleton_method(mReadline
, "completer_word_break_characters",
497 readline_s_get_completer_word_break_characters
, 0);
498 rb_define_singleton_method(mReadline
, "completer_quote_characters=",
499 readline_s_set_completer_quote_characters
, 1);
500 rb_define_singleton_method(mReadline
, "completer_quote_characters",
501 readline_s_get_completer_quote_characters
, 0);
503 history
= rb_obj_alloc(rb_cObject
);
504 rb_define_singleton_method(history
,"to_s", hist_to_s
, 0);
505 rb_define_singleton_method(history
,"[]", hist_get
, 1);
506 rb_define_singleton_method(history
,"[]=", hist_set
, 2);
507 rb_define_singleton_method(history
,"<<", hist_push
, 1);
508 rb_define_singleton_method(history
,"push", hist_push_method
, -1);
509 rb_define_singleton_method(history
,"pop", hist_pop
, 0);
510 rb_define_singleton_method(history
,"shift", hist_shift
, 0);
511 rb_define_singleton_method(history
,"each", hist_each
, 0);
512 rb_define_singleton_method(history
,"length", hist_length
, 0);
513 rb_define_singleton_method(history
,"size", hist_length
, 0);
514 rb_define_singleton_method(history
,"empty?", hist_empty_p
, 0);
515 rb_define_singleton_method(history
,"delete_at", hist_delete_at
, 1);
516 rb_define_const(mReadline
, "HISTORY", history
);
518 rb_define_const(mReadline
, "VERSION", rb_str_new2(rl_library_version
));
520 rl_attempted_completion_function
= readline_attempted_completion_function
;