|
Ruby 1.9.2p290(2011-07-09revision32553)
|
00001 /************************************************ 00002 00003 readline.c - GNU Readline module 00004 00005 $Author: yugui $ 00006 created at: Wed Jan 20 13:59:32 JST 1999 00007 00008 Copyright (C) 1997-2008 Shugo Maeda 00009 Copyright (C) 2008-2009 TAKAO Kouji 00010 00011 $Id: readline.c 30569 2011-01-16 12:35:04Z yugui $ 00012 00013 Contact: 00014 - TAKAO Kouji <kouji at takao7 dot net> (current maintainer) 00015 00016 ************************************************/ 00017 00018 #ifdef RUBY_EXTCONF_H 00019 #include RUBY_EXTCONF_H 00020 #endif 00021 00022 #include "ruby/config.h" 00023 #include <errno.h> 00024 #include <stdio.h> 00025 #include <string.h> 00026 #ifdef HAVE_READLINE_READLINE_H 00027 #include <readline/readline.h> 00028 #endif 00029 #ifdef HAVE_READLINE_HISTORY_H 00030 #include <readline/history.h> 00031 #endif 00032 #ifdef HAVE_EDITLINE_READLINE_H 00033 #include <editline/readline.h> 00034 #endif 00035 00036 #include "ruby/ruby.h" 00037 #include "ruby/io.h" 00038 00039 #ifdef HAVE_UNISTD_H 00040 #include <unistd.h> 00041 #endif 00042 00043 static VALUE mReadline; 00044 00045 #define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper" 00046 #ifndef USE_INSERT_IGNORE_ESCAPE 00047 # if !defined(HAVE_EDITLINE_READLINE_H) && defined(HAVE_RL_PROMPT_START_IGNORE) && defined(HAVE_RL_PROMPT_END_IGNORE) 00048 # define USE_INSERT_IGNORE_ESCAPE 1 00049 # else 00050 # define USE_INSERT_IGNORE_ESCAPE 0 00051 # endif 00052 #endif 00053 00054 #define COMPLETION_PROC "completion_proc" 00055 #define COMPLETION_CASE_FOLD "completion_case_fold" 00056 static ID completion_proc, completion_case_fold; 00057 #if USE_INSERT_IGNORE_ESCAPE 00058 static ID id_orig_prompt, id_last_prompt; 00059 #endif 00060 00061 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION 00062 # define rl_filename_completion_function filename_completion_function 00063 #endif 00064 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION 00065 # define rl_username_completion_function username_completion_function 00066 #endif 00067 #ifndef HAVE_RL_COMPLETION_MATCHES 00068 # define rl_completion_matches completion_matches 00069 #endif 00070 00071 static int (*history_get_offset_func)(int); 00072 00073 static char **readline_attempted_completion_function(const char *text, 00074 int start, int end); 00075 00076 #define OutputStringValue(str) do {\ 00077 SafeStringValue(str);\ 00078 str = rb_str_conv_enc(str, rb_enc_get(str), rb_locale_encoding());\ 00079 } while (0)\ 00080 00081 00082 /* 00083 * Document-class: Readline 00084 * 00085 * The Readline module provides interface for GNU Readline. 00086 * This module defines a number of methods to facilitate completion 00087 * and accesses input history from the Ruby interpreter. 00088 * This module supported Edit Line(libedit) too. 00089 * libedit is compatible with GNU Readline. 00090 * 00091 * GNU Readline:: http://www.gnu.org/directory/readline.html 00092 * libedit:: http://www.thrysoee.dk/editline/ 00093 * 00094 * Reads one inputted line with line edit by Readline.readline method. 00095 * At this time, the facilitatation completion and the key 00096 * bind like Emacs can be operated like GNU Readline. 00097 * 00098 * require "readline" 00099 * while buf = Readline.readline("> ", true) 00100 * p buf 00101 * end 00102 * 00103 * The content that the user input can be recorded to the history. 00104 * The history can be accessed by Readline::HISTORY constant. 00105 * 00106 * require "readline" 00107 * while buf = Readline.readline("> ", true) 00108 * p Readline::HISTORY.to_a 00109 * print("-> ", buf, "\n") 00110 * end 00111 * 00112 * Most of methods raise SecurityError exception if $SAFE is 4. 00113 * 00114 * Documented by TAKAO Kouji <kouji at takao7 dot net>. 00115 */ 00116 00117 #if defined HAVE_RL_GETC_FUNCTION 00118 static VALUE readline_instream; 00119 static ID id_getbyte; 00120 00121 static int readline_getc(FILE *); 00122 static int 00123 readline_getc(FILE *input) 00124 { 00125 rb_io_t *ifp = 0; 00126 VALUE c; 00127 if (!readline_instream) return rl_getc(input); 00128 GetOpenFile(readline_instream, ifp); 00129 if (rl_instream != ifp->stdio_file) return rl_getc(input); 00130 c = rb_funcall(readline_instream, id_getbyte, 0, 0); 00131 if (NIL_P(c)) return EOF; 00132 return NUM2CHR(c); 00133 } 00134 #elif defined HAVE_RL_EVENT_HOOK 00135 #define BUSY_WAIT 0 00136 00137 static int readline_event(void); 00138 static int 00139 readline_event(void) 00140 { 00141 #if BUSY_WAIT 00142 rb_thread_schedule(); 00143 #else 00144 fd_set rset; 00145 00146 FD_ZERO(&rset); 00147 FD_SET(fileno(rl_instream), &rset); 00148 rb_thread_select(fileno(rl_instream) + 1, &rset, NULL, NULL, NULL); 00149 return 0; 00150 #endif 00151 } 00152 #endif 00153 00154 #if USE_INSERT_IGNORE_ESCAPE 00155 static VALUE 00156 insert_ignore_escape(VALUE self, VALUE prompt) 00157 { 00158 VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt); 00159 int ignoring = 0; 00160 const char *s0, *s, *e; 00161 long len; 00162 static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE}; 00163 00164 prompt = rb_str_new_shared(prompt); 00165 last_prompt = rb_attr_get(self, id_last_prompt); 00166 if (orig_prompt == prompt) return last_prompt; 00167 len = RSTRING_LEN(prompt); 00168 if (NIL_P(last_prompt)) { 00169 last_prompt = rb_str_tmp_new(len); 00170 } 00171 00172 s = s0 = RSTRING_PTR(prompt); 00173 e = s0 + len; 00174 rb_str_set_len(last_prompt, 0); 00175 while (s < e && *s) { 00176 switch (*s) { 00177 case RL_PROMPT_START_IGNORE: 00178 ignoring = -1; 00179 rb_str_cat(last_prompt, s0, ++s - s0); 00180 s0 = s; 00181 break; 00182 case RL_PROMPT_END_IGNORE: 00183 ignoring = 0; 00184 rb_str_cat(last_prompt, s0, ++s - s0); 00185 s0 = s; 00186 break; 00187 case '\033': 00188 if (++s < e && *s == '[') { 00189 rb_str_cat(last_prompt, s0, s - s0 - 1); 00190 s0 = s - 1; 00191 while (++s < e && *s) { 00192 if (ISALPHA(*s)) { 00193 if (!ignoring) { 00194 ignoring = 1; 00195 rb_str_cat(last_prompt, ignore_code+0, 1); 00196 } 00197 rb_str_cat(last_prompt, s0, ++s - s0); 00198 s0 = s; 00199 break; 00200 } 00201 else if (!('0' <= *s && *s <= '9' || *s == ';')) { 00202 break; 00203 } 00204 } 00205 } 00206 break; 00207 default: 00208 if (ignoring > 0) { 00209 ignoring = 0; 00210 rb_str_cat(last_prompt, ignore_code+1, 1); 00211 } 00212 s++; 00213 break; 00214 } 00215 } 00216 if (ignoring > 0) { 00217 ignoring = 0; 00218 rb_str_cat(last_prompt, ignore_code+1, 1); 00219 } 00220 rb_str_cat(last_prompt, s0, s - s0); 00221 00222 rb_ivar_set(self, id_orig_prompt, prompt); 00223 rb_ivar_set(self, id_last_prompt, last_prompt); 00224 00225 return last_prompt; 00226 } 00227 #endif 00228 00229 static VALUE 00230 readline_get(VALUE prompt) 00231 { 00232 return (VALUE)readline((char *)prompt); 00233 } 00234 00235 /* 00236 * call-seq: 00237 * Readline.readline(prompt = "", add_hist = false) -> string or nil 00238 * 00239 * Shows the +prompt+ and reads the inputted line with line editing. 00240 * The inputted line is added to the history if +add_hist+ is true. 00241 * 00242 * Returns nil when the inputted line is empty and user inputs EOF 00243 * (Presses ^D on UNIX). 00244 * 00245 * Raises IOError exception if below conditions are satisfied. 00246 * 1. stdin is not tty. 00247 * 2. stdin was closed. (errno is EBADF after called isatty(2).) 00248 * 00249 * This method supports thread. Switchs the thread context when waits 00250 * inputting line. 00251 * 00252 * Supports line edit when inputs line. Provides VI and Emacs editing mode. 00253 * Default is Emacs editing mode. 00254 * 00255 * NOTE: Terminates ruby interpreter and does not return the terminal 00256 * status after user pressed '^C' when wait inputting line. 00257 * Give 3 examples that avoid it. 00258 * 00259 * * Catches the Interrupt exception by pressed ^C after returns 00260 * terminal status: 00261 * 00262 * require "readline" 00263 * 00264 * stty_save = `stty -g`.chomp 00265 * begin 00266 * while buf = Readline.readline 00267 * p buf 00268 * end 00269 * rescue Interrupt 00270 * system("stty", stty_save) 00271 * exit 00272 * end 00273 * end 00274 * end 00275 * 00276 * * Catches the INT signal by pressed ^C after returns terminal 00277 * status: 00278 * 00279 * require "readline" 00280 * 00281 * stty_save = `stty -g`.chomp 00282 * trap("INT") { system "stty", stty_save; exit } 00283 * 00284 * while buf = Readline.readline 00285 * p buf 00286 * end 00287 * 00288 * * Ignores pressing ^C: 00289 * 00290 * require "readline" 00291 * 00292 * trap("INT", "SIG_IGN") 00293 * 00294 * while buf = Readline.readline 00295 * p buf 00296 * end 00297 * 00298 * Can make as follows with Readline::HISTORY constant. 00299 * It does not record to the history if the inputted line is empty or 00300 * the same it as last one. 00301 * 00302 * require "readline" 00303 * 00304 * while buf = Readline.readline("> ", true) 00305 * # p Readline::HISTORY.to_a 00306 * Readline::HISTORY.pop if /^\s*$/ =~ buf 00307 * 00308 * begin 00309 * if Readline::HISTORY[Readline::HISTORY.length-2] == buf 00310 * Readline::HISTORY.pop 00311 * end 00312 * rescue IndexError 00313 * end 00314 * 00315 * # p Readline::HISTORY.to_a 00316 * print "-> ", buf, "\n" 00317 * end 00318 * 00319 * Raises SecurityError exception if $SAFE is 4. 00320 */ 00321 static VALUE 00322 readline_readline(int argc, VALUE *argv, VALUE self) 00323 { 00324 VALUE tmp, add_hist, result; 00325 char *prompt = NULL; 00326 char *buff; 00327 int status; 00328 00329 rb_secure(4); 00330 if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) { 00331 OutputStringValue(tmp); 00332 #if USE_INSERT_IGNORE_ESCAPE 00333 tmp = insert_ignore_escape(self, tmp); 00334 rb_str_locktmp(tmp); 00335 #endif 00336 prompt = RSTRING_PTR(tmp); 00337 } 00338 00339 if (!isatty(fileno(rl_instream)) && errno == EBADF) rb_raise(rb_eIOError, "closed stdin"); 00340 00341 #ifdef _WIN32 00342 rl_prep_terminal(1); 00343 #endif 00344 buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status); 00345 #if USE_INSERT_IGNORE_ESCAPE 00346 if (prompt) { 00347 rb_str_unlocktmp(tmp); 00348 } 00349 #endif 00350 if (status) { 00351 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL 00352 /* restore terminal mode and signal handler*/ 00353 rl_free_line_state(); 00354 rl_cleanup_after_signal(); 00355 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION 00356 /* restore terminal mode */ 00357 if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */ 00358 (*rl_deprep_term_function)(); 00359 else 00360 #else 00361 rl_deprep_terminal(); 00362 #endif 00363 rb_jump_tag(status); 00364 } 00365 00366 if (RTEST(add_hist) && buff) { 00367 add_history(buff); 00368 } 00369 if (buff) { 00370 result = rb_locale_str_new_cstr(buff); 00371 } 00372 else 00373 result = Qnil; 00374 if (buff) free(buff); 00375 return result; 00376 } 00377 00378 /* 00379 * call-seq: 00380 * Readline.input = input 00381 * 00382 * Specifies a File object +input+ that is input stream for 00383 * Readline.readline method. 00384 * 00385 * Raises SecurityError exception if $SAFE is 4. 00386 */ 00387 static VALUE 00388 readline_s_set_input(VALUE self, VALUE input) 00389 { 00390 rb_io_t *ifp; 00391 00392 rb_secure(4); 00393 Check_Type(input, T_FILE); 00394 GetOpenFile(input, ifp); 00395 rl_instream = rb_io_stdio_file(ifp); 00396 #ifdef HAVE_RL_GETC_FUNCTION 00397 readline_instream = input; 00398 #endif 00399 return input; 00400 } 00401 00402 /* 00403 * call-seq: 00404 * Readline.output = output 00405 * 00406 * Specifies a File object +output+ that is output stream for 00407 * Readline.readline method. 00408 * 00409 * Raises SecurityError exception if $SAFE is 4. 00410 */ 00411 static VALUE 00412 readline_s_set_output(VALUE self, VALUE output) 00413 { 00414 rb_io_t *ofp; 00415 00416 rb_secure(4); 00417 Check_Type(output, T_FILE); 00418 GetOpenFile(output, ofp); 00419 rl_outstream = rb_io_stdio_file(ofp); 00420 return output; 00421 } 00422 00423 /* 00424 * call-seq: 00425 * Readline.completion_proc = proc 00426 * 00427 * Specifies a Proc object +proc+ to determine completion behavior. It 00428 * should take input-string, and return an array of completion 00429 * candidates. 00430 * 00431 * Set default if +proc+ is nil. 00432 * 00433 * Raises ArgumentError exception if +proc+ does not respond to call method. 00434 * 00435 * Raises SecurityError exception if $SAFE is 4. 00436 */ 00437 static VALUE 00438 readline_s_set_completion_proc(VALUE self, VALUE proc) 00439 { 00440 rb_secure(4); 00441 if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call"))) 00442 rb_raise(rb_eArgError, "argument must respond to `call'"); 00443 return rb_ivar_set(mReadline, completion_proc, proc); 00444 } 00445 00446 /* 00447 * call-seq: 00448 * Readline.completion_proc -> proc 00449 * 00450 * Returns the completion Proc object. 00451 * 00452 * Raises SecurityError exception if $SAFE is 4. 00453 */ 00454 static VALUE 00455 readline_s_get_completion_proc(VALUE self) 00456 { 00457 rb_secure(4); 00458 return rb_attr_get(mReadline, completion_proc); 00459 } 00460 00461 /* 00462 * call-seq: 00463 * Readline.completion_case_fold = bool 00464 * 00465 * Sets whether or not to ignore case on completion. 00466 * 00467 * Raises SecurityError exception if $SAFE is 4. 00468 */ 00469 static VALUE 00470 readline_s_set_completion_case_fold(VALUE self, VALUE val) 00471 { 00472 rb_secure(4); 00473 return rb_ivar_set(mReadline, completion_case_fold, val); 00474 } 00475 00476 /* 00477 * call-seq: 00478 * Readline.completion_case_fold -> bool 00479 * 00480 * Returns true if completion ignores case. If no, returns false. 00481 * 00482 * NOTE: Returns the same object that is specified by 00483 * Readline.completion_case_fold= method. 00484 * 00485 * require "readline" 00486 * 00487 * Readline.completion_case_fold = "This is a String." 00488 * p Readline.completion_case_fold # => "This is a String." 00489 * 00490 * Raises SecurityError exception if $SAFE is 4. 00491 */ 00492 static VALUE 00493 readline_s_get_completion_case_fold(VALUE self) 00494 { 00495 rb_secure(4); 00496 return rb_attr_get(mReadline, completion_case_fold); 00497 } 00498 00499 #ifdef HAVE_RL_LINE_BUFFER 00500 /* 00501 * call-seq: 00502 * Readline.line_buffer -> string 00503 * 00504 * Returns the full line that is being edited. This is useful from 00505 * within the complete_proc for determining the context of the 00506 * completion request. 00507 * 00508 * The length of +Readline.line_buffer+ and GNU Readline's rl_end are 00509 * same. 00510 */ 00511 static VALUE 00512 readline_s_get_line_buffer(VALUE self) 00513 { 00514 rb_secure(4); 00515 if (rl_line_buffer == NULL) 00516 return Qnil; 00517 return rb_locale_str_new_cstr(rl_line_buffer); 00518 } 00519 #else 00520 #define readline_s_get_line_buffer rb_f_notimplement 00521 #endif 00522 00523 #ifdef HAVE_RL_POINT 00524 /* 00525 * call-seq: 00526 * Readline.point -> int 00527 * 00528 * Returns the index of the current cursor position in 00529 * +Readline.line_buffer+. 00530 * 00531 * The index in +Readline.line_buffer+ which matches the start of 00532 * input-string passed to completion_proc is computed by subtracting 00533 * the length of input-string from +Readline.point+. 00534 * 00535 * start = (the length of input-string) - Readline.point 00536 */ 00537 static VALUE 00538 readline_s_get_point(VALUE self) 00539 { 00540 rb_secure(4); 00541 return INT2NUM(rl_point); 00542 } 00543 #else 00544 #define readline_s_get_point rb_f_notimplement 00545 #endif 00546 00547 static char ** 00548 readline_attempted_completion_function(const char *text, int start, int end) 00549 { 00550 VALUE proc, ary, temp; 00551 char **result; 00552 int case_fold; 00553 long i, matches; 00554 00555 proc = rb_attr_get(mReadline, completion_proc); 00556 if (NIL_P(proc)) 00557 return NULL; 00558 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER 00559 rl_attempted_completion_over = 1; 00560 #endif 00561 case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold)); 00562 ary = rb_funcall(proc, rb_intern("call"), 1, rb_locale_str_new_cstr(text)); 00563 if (TYPE(ary) != T_ARRAY) 00564 ary = rb_Array(ary); 00565 matches = RARRAY_LEN(ary); 00566 if (matches == 0) 00567 return NULL; 00568 result = ALLOC_N(char *, matches + 2); 00569 for (i = 0; i < matches; i++) { 00570 temp = rb_obj_as_string(RARRAY_PTR(ary)[i]); 00571 result[i + 1] = ALLOC_N(char, RSTRING_LEN(temp) + 1); 00572 strcpy(result[i + 1], RSTRING_PTR(temp)); 00573 } 00574 result[matches + 1] = NULL; 00575 00576 if (matches == 1) { 00577 result[0] = strdup(result[1]); 00578 } 00579 else { 00580 register int i = 1; 00581 int low = 100000; 00582 00583 while (i < matches) { 00584 register int c1, c2, si; 00585 00586 if (case_fold) { 00587 for (si = 0; 00588 (c1 = TOLOWER(result[i][si])) && 00589 (c2 = TOLOWER(result[i + 1][si])); 00590 si++) 00591 if (c1 != c2) break; 00592 } else { 00593 for (si = 0; 00594 (c1 = result[i][si]) && 00595 (c2 = result[i + 1][si]); 00596 si++) 00597 if (c1 != c2) break; 00598 } 00599 00600 if (low > si) low = si; 00601 i++; 00602 } 00603 result[0] = ALLOC_N(char, low + 1); 00604 strncpy(result[0], result[1], low); 00605 result[0][low] = '\0'; 00606 } 00607 00608 return result; 00609 } 00610 00611 #ifdef HAVE_RL_SET_SCREEN_SIZE 00612 /* 00613 * call-seq: 00614 * Readline.set_screen_size(rows, columns) -> self 00615 * 00616 * Set terminal size to +rows+ and +columns+. 00617 * 00618 * See GNU Readline's rl_set_screen_size function. 00619 * 00620 * Raises NotImplementedError if the using readline library does not support. 00621 * 00622 * Raises SecurityError exception if $SAFE is 4. 00623 */ 00624 static VALUE 00625 readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns) 00626 { 00627 rb_secure(4); 00628 rl_set_screen_size(NUM2INT(rows), NUM2INT(columns)); 00629 return self; 00630 } 00631 #else 00632 #define readline_s_set_screen_size rb_f_notimplement 00633 #endif 00634 00635 #ifdef HAVE_RL_GET_SCREEN_SIZE 00636 /* 00637 * call-seq: 00638 * Readline.get_screen_size -> [rows, columns] 00639 * 00640 * Returns the terminal's rows and columns. 00641 * 00642 * See GNU Readline's rl_get_screen_size function. 00643 * 00644 * Raises NotImplementedError if the using readline library does not support. 00645 * 00646 * Raises SecurityError exception if $SAFE is 4. 00647 */ 00648 static VALUE 00649 readline_s_get_screen_size(VALUE self) 00650 { 00651 int rows, columns; 00652 VALUE res; 00653 00654 rb_secure(4); 00655 rl_get_screen_size(&rows, &columns); 00656 res = rb_ary_new(); 00657 rb_ary_push(res, INT2NUM(rows)); 00658 rb_ary_push(res, INT2NUM(columns)); 00659 return res; 00660 } 00661 #else 00662 #define readline_s_get_screen_size rb_f_notimplement 00663 #endif 00664 00665 #ifdef HAVE_RL_VI_EDITING_MODE 00666 /* 00667 * call-seq: 00668 * Readline.vi_editing_mode -> nil 00669 * 00670 * Specifies VI editing mode. See the manual of GNU Readline for 00671 * details of VI editing mode. 00672 * 00673 * Raises NotImplementedError if the using readline library does not support. 00674 * 00675 * Raises SecurityError exception if $SAFE is 4. 00676 */ 00677 static VALUE 00678 readline_s_vi_editing_mode(VALUE self) 00679 { 00680 rb_secure(4); 00681 rl_vi_editing_mode(1,0); 00682 return Qnil; 00683 } 00684 #else 00685 #define readline_s_vi_editing_mode rb_f_notimplement 00686 #endif 00687 00688 #ifdef HAVE_RL_EDITING_MODE 00689 /* 00690 * call-seq: 00691 * Readline.vi_editing_mode? -> bool 00692 * 00693 * Returns true if vi mode is active. Returns false if not. 00694 * 00695 * Raises NotImplementedError if the using readline library does not support. 00696 * 00697 * Raises SecurityError exception if $SAFE is 4. 00698 */ 00699 static VALUE 00700 readline_s_vi_editing_mode_p(VALUE self) 00701 { 00702 rb_secure(4); 00703 return rl_editing_mode == 0 ? Qtrue : Qfalse; 00704 } 00705 #else 00706 #define readline_s_vi_editing_mode_p rb_f_notimplement 00707 #endif 00708 00709 #ifdef HAVE_RL_EMACS_EDITING_MODE 00710 /* 00711 * call-seq: 00712 * Readline.emacs_editing_mode -> nil 00713 * 00714 * Specifies Emacs editing mode. The default is this mode. See the 00715 * manual of GNU Readline for details of Emacs editing mode. 00716 * 00717 * Raises NotImplementedError if the using readline library does not support. 00718 * 00719 * Raises SecurityError exception if $SAFE is 4. 00720 */ 00721 static VALUE 00722 readline_s_emacs_editing_mode(VALUE self) 00723 { 00724 rb_secure(4); 00725 rl_emacs_editing_mode(1,0); 00726 return Qnil; 00727 } 00728 #else 00729 #define readline_s_emacs_editing_mode rb_f_notimplement 00730 #endif 00731 00732 #ifdef HAVE_RL_EDITING_MODE 00733 /* 00734 * call-seq: 00735 * Readline.emacs_editing_mode? -> bool 00736 * 00737 * Returns true if emacs mode is active. Returns false if not. 00738 * 00739 * Raises NotImplementedError if the using readline library does not support. 00740 * 00741 * Raises SecurityError exception if $SAFE is 4. 00742 */ 00743 static VALUE 00744 readline_s_emacs_editing_mode_p(VALUE self) 00745 { 00746 rb_secure(4); 00747 return rl_editing_mode == 1 ? Qtrue : Qfalse; 00748 } 00749 #else 00750 #define readline_s_emacs_editing_mode_p rb_f_notimplement 00751 #endif 00752 00753 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER 00754 /* 00755 * call-seq: 00756 * Readline.completion_append_character = char 00757 * 00758 * Specifies a character to be appended on completion. 00759 * Nothing will be appended if an empty string ("") or nil is 00760 * specified. 00761 * 00762 * For example: 00763 * require "readline" 00764 * 00765 * Readline.readline("> ", true) 00766 * Readline.completion_append_character = " " 00767 * 00768 * Result: 00769 * > 00770 * Input "/var/li". 00771 * 00772 * > /var/li 00773 * Press TAB key. 00774 * 00775 * > /var/lib 00776 * Completes "b" and appends " ". So, you can continuously input "/usr". 00777 * 00778 * > /var/lib /usr 00779 * 00780 * NOTE: Only one character can be specified. When "string" is 00781 * specified, sets only "s" that is the first. 00782 * 00783 * require "readline" 00784 * 00785 * Readline.completion_append_character = "string" 00786 * p Readline.completion_append_character # => "s" 00787 * 00788 * Raises NotImplementedError if the using readline library does not support. 00789 * 00790 * Raises SecurityError exception if $SAFE is 4. 00791 */ 00792 static VALUE 00793 readline_s_set_completion_append_character(VALUE self, VALUE str) 00794 { 00795 rb_secure(4); 00796 if (NIL_P(str)) { 00797 rl_completion_append_character = '\0'; 00798 } 00799 else { 00800 OutputStringValue(str); 00801 if (RSTRING_LEN(str) == 0) { 00802 rl_completion_append_character = '\0'; 00803 } else { 00804 rl_completion_append_character = RSTRING_PTR(str)[0]; 00805 } 00806 } 00807 return self; 00808 } 00809 #else 00810 #define readline_s_set_completion_append_character rb_f_notimplement 00811 #endif 00812 00813 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER 00814 /* 00815 * call-seq: 00816 * Readline.completion_append_character -> char 00817 * 00818 * Returns a string containing a character to be appended on 00819 * completion. The default is a space (" "). 00820 * 00821 * Raises NotImplementedError if the using readline library does not support. 00822 * 00823 * Raises SecurityError exception if $SAFE is 4. 00824 */ 00825 static VALUE 00826 readline_s_get_completion_append_character(VALUE self) 00827 { 00828 char buf[1]; 00829 00830 rb_secure(4); 00831 if (rl_completion_append_character == '\0') 00832 return Qnil; 00833 00834 buf[0] = (char) rl_completion_append_character; 00835 return rb_locale_str_new(buf, 1); 00836 } 00837 #else 00838 #define readline_s_get_completion_append_character rb_f_notimplement 00839 #endif 00840 00841 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS 00842 /* 00843 * call-seq: 00844 * Readline.basic_word_break_characters = string 00845 * 00846 * Sets the basic list of characters that signal a break between words 00847 * for the completer routine. The default is the characters which 00848 * break words for completion in Bash: "\t\n\"\\'`@$><=;|&{(". 00849 * 00850 * Raises NotImplementedError if the using readline library does not support. 00851 * 00852 * Raises SecurityError exception if $SAFE is 4. 00853 */ 00854 static VALUE 00855 readline_s_set_basic_word_break_characters(VALUE self, VALUE str) 00856 { 00857 static char *basic_word_break_characters = NULL; 00858 00859 rb_secure(4); 00860 OutputStringValue(str); 00861 if (basic_word_break_characters == NULL) { 00862 basic_word_break_characters = 00863 ALLOC_N(char, RSTRING_LEN(str) + 1); 00864 } 00865 else { 00866 REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1); 00867 } 00868 strncpy(basic_word_break_characters, 00869 RSTRING_PTR(str), RSTRING_LEN(str)); 00870 basic_word_break_characters[RSTRING_LEN(str)] = '\0'; 00871 rl_basic_word_break_characters = basic_word_break_characters; 00872 return self; 00873 } 00874 #else 00875 #define readline_s_set_basic_word_break_characters rb_f_notimplement 00876 #endif 00877 00878 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS 00879 /* 00880 * call-seq: 00881 * Readline.basic_word_break_characters -> string 00882 * 00883 * Gets the basic list of characters that signal a break between words 00884 * for the completer routine. 00885 * 00886 * Raises NotImplementedError if the using readline library does not support. 00887 * 00888 * Raises SecurityError exception if $SAFE is 4. 00889 */ 00890 static VALUE 00891 readline_s_get_basic_word_break_characters(VALUE self, VALUE str) 00892 { 00893 rb_secure(4); 00894 if (rl_basic_word_break_characters == NULL) 00895 return Qnil; 00896 return rb_locale_str_new_cstr(rl_basic_word_break_characters); 00897 } 00898 #else 00899 #define readline_s_get_basic_word_break_characters rb_f_notimplement 00900 #endif 00901 00902 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS 00903 /* 00904 * call-seq: 00905 * Readline.completer_word_break_characters = string 00906 * 00907 * Sets the basic list of characters that signal a break between words 00908 * for rl_complete_internal(). The default is the value of 00909 * Readline.basic_word_break_characters. 00910 * 00911 * Raises NotImplementedError if the using readline library does not support. 00912 * 00913 * Raises SecurityError exception if $SAFE is 4. 00914 */ 00915 static VALUE 00916 readline_s_set_completer_word_break_characters(VALUE self, VALUE str) 00917 { 00918 static char *completer_word_break_characters = NULL; 00919 00920 rb_secure(4); 00921 OutputStringValue(str); 00922 if (completer_word_break_characters == NULL) { 00923 completer_word_break_characters = 00924 ALLOC_N(char, RSTRING_LEN(str) + 1); 00925 } 00926 else { 00927 REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1); 00928 } 00929 strncpy(completer_word_break_characters, 00930 RSTRING_PTR(str), RSTRING_LEN(str)); 00931 completer_word_break_characters[RSTRING_LEN(str)] = '\0'; 00932 rl_completer_word_break_characters = completer_word_break_characters; 00933 return self; 00934 } 00935 #else 00936 #define readline_s_set_completer_word_break_characters rb_f_notimplement 00937 #endif 00938 00939 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS 00940 /* 00941 * call-seq: 00942 * Readline.completer_word_break_characters -> string 00943 * 00944 * Gets the basic list of characters that signal a break between words 00945 * for rl_complete_internal(). 00946 * 00947 * Raises NotImplementedError if the using readline library does not support. 00948 * 00949 * Raises SecurityError exception if $SAFE is 4. 00950 */ 00951 static VALUE 00952 readline_s_get_completer_word_break_characters(VALUE self, VALUE str) 00953 { 00954 rb_secure(4); 00955 if (rl_completer_word_break_characters == NULL) 00956 return Qnil; 00957 return rb_locale_str_new_cstr(rl_completer_word_break_characters); 00958 } 00959 #else 00960 #define readline_s_get_completer_word_break_characters rb_f_notimplement 00961 #endif 00962 00963 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS 00964 /* 00965 * call-seq: 00966 * Readline.basic_quote_characters = string 00967 * 00968 * Sets a list of quote characters which can cause a word break. 00969 * 00970 * Raises NotImplementedError if the using readline library does not support. 00971 * 00972 * Raises SecurityError exception if $SAFE is 4. 00973 */ 00974 static VALUE 00975 readline_s_set_basic_quote_characters(VALUE self, VALUE str) 00976 { 00977 static char *basic_quote_characters = NULL; 00978 00979 rb_secure(4); 00980 OutputStringValue(str); 00981 if (basic_quote_characters == NULL) { 00982 basic_quote_characters = 00983 ALLOC_N(char, RSTRING_LEN(str) + 1); 00984 } 00985 else { 00986 REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1); 00987 } 00988 strncpy(basic_quote_characters, 00989 RSTRING_PTR(str), RSTRING_LEN(str)); 00990 basic_quote_characters[RSTRING_LEN(str)] = '\0'; 00991 rl_basic_quote_characters = basic_quote_characters; 00992 00993 return self; 00994 } 00995 #else 00996 #define readline_s_set_basic_quote_characters rb_f_notimplement 00997 #endif 00998 00999 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS 01000 /* 01001 * call-seq: 01002 * Readline.basic_quote_characters -> string 01003 * 01004 * Gets a list of quote characters which can cause a word break. 01005 * 01006 * Raises NotImplementedError if the using readline library does not support. 01007 * 01008 * Raises SecurityError exception if $SAFE is 4. 01009 */ 01010 static VALUE 01011 readline_s_get_basic_quote_characters(VALUE self, VALUE str) 01012 { 01013 rb_secure(4); 01014 if (rl_basic_quote_characters == NULL) 01015 return Qnil; 01016 return rb_locale_str_new_cstr(rl_basic_quote_characters); 01017 } 01018 #else 01019 #define readline_s_get_basic_quote_characters rb_f_notimplement 01020 #endif 01021 01022 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS 01023 /* 01024 * call-seq: 01025 * Readline.completer_quote_characters = string 01026 * 01027 * Sets a list of characters which can be used to quote a substring of 01028 * the line. Completion occurs on the entire substring, and within 01029 * the substring Readline.completer_word_break_characters are treated 01030 * as any other character, unless they also appear within this list. 01031 * 01032 * Raises NotImplementedError if the using readline library does not support. 01033 * 01034 * Raises SecurityError exception if $SAFE is 4. 01035 */ 01036 static VALUE 01037 readline_s_set_completer_quote_characters(VALUE self, VALUE str) 01038 { 01039 static char *completer_quote_characters = NULL; 01040 01041 rb_secure(4); 01042 OutputStringValue(str); 01043 if (completer_quote_characters == NULL) { 01044 completer_quote_characters = 01045 ALLOC_N(char, RSTRING_LEN(str) + 1); 01046 } 01047 else { 01048 REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1); 01049 } 01050 strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str)); 01051 completer_quote_characters[RSTRING_LEN(str)] = '\0'; 01052 rl_completer_quote_characters = completer_quote_characters; 01053 01054 return self; 01055 } 01056 #else 01057 #define readline_s_set_completer_quote_characters rb_f_notimplement 01058 #endif 01059 01060 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS 01061 /* 01062 * call-seq: 01063 * Readline.completer_quote_characters -> string 01064 * 01065 * Gets a list of characters which can be used to quote a substring of 01066 * the line. 01067 * 01068 * Raises NotImplementedError if the using readline library does not support. 01069 * 01070 * Raises SecurityError exception if $SAFE is 4. 01071 */ 01072 static VALUE 01073 readline_s_get_completer_quote_characters(VALUE self, VALUE str) 01074 { 01075 rb_secure(4); 01076 if (rl_completer_quote_characters == NULL) 01077 return Qnil; 01078 return rb_locale_str_new_cstr(rl_completer_quote_characters); 01079 } 01080 #else 01081 #define readline_s_get_completer_quote_characters rb_f_notimplement 01082 #endif 01083 01084 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS 01085 /* 01086 * call-seq: 01087 * Readline.filename_quote_characters = string 01088 * 01089 * Sets a list of characters that cause a filename to be quoted by the completer 01090 * when they appear in a completed filename. The default is nil. 01091 * 01092 * Raises NotImplementedError if the using readline library does not support. 01093 * 01094 * Raises SecurityError exception if $SAFE is 4. 01095 */ 01096 static VALUE 01097 readline_s_set_filename_quote_characters(VALUE self, VALUE str) 01098 { 01099 static char *filename_quote_characters = NULL; 01100 01101 rb_secure(4); 01102 OutputStringValue(str); 01103 if (filename_quote_characters == NULL) { 01104 filename_quote_characters = 01105 ALLOC_N(char, RSTRING_LEN(str) + 1); 01106 } 01107 else { 01108 REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1); 01109 } 01110 strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str)); 01111 filename_quote_characters[RSTRING_LEN(str)] = '\0'; 01112 rl_filename_quote_characters = filename_quote_characters; 01113 01114 return self; 01115 } 01116 #else 01117 #define readline_s_set_filename_quote_characters rb_f_notimplement 01118 #endif 01119 01120 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS 01121 /* 01122 * call-seq: 01123 * Readline.filename_quote_characters -> string 01124 * 01125 * Gets a list of characters that cause a filename to be quoted by the completer 01126 * when they appear in a completed filename. 01127 * 01128 * Raises NotImplementedError if the using readline library does not support. 01129 * 01130 * Raises SecurityError exception if $SAFE is 4. 01131 */ 01132 static VALUE 01133 readline_s_get_filename_quote_characters(VALUE self, VALUE str) 01134 { 01135 rb_secure(4); 01136 if (rl_filename_quote_characters == NULL) 01137 return Qnil; 01138 return rb_locale_str_new_cstr(rl_filename_quote_characters); 01139 } 01140 #else 01141 #define readline_s_get_filename_quote_characters rb_f_notimplement 01142 #endif 01143 01144 #ifdef HAVE_RL_REFRESH_LINE 01145 /* 01146 * call-seq: 01147 * Readline.refresh_line -> nil 01148 * 01149 * Clear the current input line. 01150 * 01151 * Raises SecurityError exception if $SAFE is 4. 01152 */ 01153 static VALUE 01154 readline_s_refresh_line(VALUE self) 01155 { 01156 rb_secure(4); 01157 rl_refresh_line(0, 0); 01158 return Qnil; 01159 } 01160 #else 01161 #define readline_s_refresh_line rb_f_notimplement 01162 #endif 01163 01164 static VALUE 01165 hist_to_s(VALUE self) 01166 { 01167 return rb_str_new_cstr("HISTORY"); 01168 } 01169 01170 static int 01171 history_get_offset_history_base(int offset) 01172 { 01173 return history_base + offset; 01174 } 01175 01176 static int 01177 history_get_offset_0(int offset) 01178 { 01179 return offset; 01180 } 01181 01182 static VALUE 01183 hist_get(VALUE self, VALUE index) 01184 { 01185 HIST_ENTRY *entry = NULL; 01186 int i; 01187 01188 rb_secure(4); 01189 i = NUM2INT(index); 01190 if (i < 0) { 01191 i += history_length; 01192 } 01193 if (i >= 0) { 01194 entry = history_get(history_get_offset_func(i)); 01195 } 01196 if (entry == NULL) { 01197 rb_raise(rb_eIndexError, "invalid index"); 01198 } 01199 return rb_locale_str_new_cstr(entry->line); 01200 } 01201 01202 #ifdef HAVE_REPLACE_HISTORY_ENTRY 01203 static VALUE 01204 hist_set(VALUE self, VALUE index, VALUE str) 01205 { 01206 HIST_ENTRY *entry = NULL; 01207 int i; 01208 01209 rb_secure(4); 01210 i = NUM2INT(index); 01211 OutputStringValue(str); 01212 if (i < 0) { 01213 i += history_length; 01214 } 01215 if (i >= 0) { 01216 entry = replace_history_entry(i, RSTRING_PTR(str), NULL); 01217 } 01218 if (entry == NULL) { 01219 rb_raise(rb_eIndexError, "invalid index"); 01220 } 01221 return str; 01222 } 01223 #else 01224 #define hist_set rb_f_notimplement 01225 #endif 01226 01227 static VALUE 01228 hist_push(VALUE self, VALUE str) 01229 { 01230 rb_secure(4); 01231 OutputStringValue(str); 01232 add_history(RSTRING_PTR(str)); 01233 return self; 01234 } 01235 01236 static VALUE 01237 hist_push_method(int argc, VALUE *argv, VALUE self) 01238 { 01239 VALUE str; 01240 01241 rb_secure(4); 01242 while (argc--) { 01243 str = *argv++; 01244 OutputStringValue(str); 01245 add_history(RSTRING_PTR(str)); 01246 } 01247 return self; 01248 } 01249 01250 static VALUE 01251 rb_remove_history(int index) 01252 { 01253 #ifdef HAVE_REMOVE_HISTORY 01254 HIST_ENTRY *entry; 01255 VALUE val; 01256 01257 rb_secure(4); 01258 entry = remove_history(index); 01259 if (entry) { 01260 val = rb_locale_str_new_cstr(entry->line); 01261 free((void *) entry->line); 01262 free(entry); 01263 return val; 01264 } 01265 return Qnil; 01266 #else 01267 rb_notimplement(); 01268 return Qnil; /* not reached */ 01269 #endif 01270 } 01271 01272 static VALUE 01273 hist_pop(VALUE self) 01274 { 01275 rb_secure(4); 01276 if (history_length > 0) { 01277 return rb_remove_history(history_length - 1); 01278 } else { 01279 return Qnil; 01280 } 01281 } 01282 01283 static VALUE 01284 hist_shift(VALUE self) 01285 { 01286 rb_secure(4); 01287 if (history_length > 0) { 01288 return rb_remove_history(0); 01289 } else { 01290 return Qnil; 01291 } 01292 } 01293 01294 static VALUE 01295 hist_each(VALUE self) 01296 { 01297 HIST_ENTRY *entry; 01298 int i; 01299 01300 RETURN_ENUMERATOR(self, 0, 0); 01301 01302 rb_secure(4); 01303 for (i = 0; i < history_length; i++) { 01304 entry = history_get(history_get_offset_func(i)); 01305 if (entry == NULL) 01306 break; 01307 rb_yield(rb_locale_str_new_cstr(entry->line)); 01308 } 01309 return self; 01310 } 01311 01312 static VALUE 01313 hist_length(VALUE self) 01314 { 01315 rb_secure(4); 01316 return INT2NUM(history_length); 01317 } 01318 01319 static VALUE 01320 hist_empty_p(VALUE self) 01321 { 01322 rb_secure(4); 01323 return history_length == 0 ? Qtrue : Qfalse; 01324 } 01325 01326 static VALUE 01327 hist_delete_at(VALUE self, VALUE index) 01328 { 01329 int i; 01330 01331 rb_secure(4); 01332 i = NUM2INT(index); 01333 if (i < 0) 01334 i += history_length; 01335 if (i < 0 || i > history_length - 1) { 01336 rb_raise(rb_eIndexError, "invalid index"); 01337 } 01338 return rb_remove_history(i); 01339 } 01340 01341 #ifdef HAVE_CLEAR_HISTORY 01342 static VALUE 01343 hist_clear(VALUE self) 01344 { 01345 rb_secure(4); 01346 clear_history(); 01347 return self; 01348 } 01349 #else 01350 #define hist_clear rb_f_notimplement 01351 #endif 01352 01353 static VALUE 01354 filename_completion_proc_call(VALUE self, VALUE str) 01355 { 01356 VALUE result; 01357 char **matches; 01358 int i; 01359 01360 matches = rl_completion_matches(StringValuePtr(str), 01361 rl_filename_completion_function); 01362 if (matches) { 01363 result = rb_ary_new(); 01364 for (i = 0; matches[i]; i++) { 01365 rb_ary_push(result, rb_locale_str_new_cstr(matches[i])); 01366 free(matches[i]); 01367 } 01368 free(matches); 01369 if (RARRAY_LEN(result) >= 2) 01370 rb_ary_shift(result); 01371 } 01372 else { 01373 result = Qnil; 01374 } 01375 return result; 01376 } 01377 01378 static VALUE 01379 username_completion_proc_call(VALUE self, VALUE str) 01380 { 01381 VALUE result; 01382 char **matches; 01383 int i; 01384 01385 matches = rl_completion_matches(StringValuePtr(str), 01386 rl_username_completion_function); 01387 if (matches) { 01388 result = rb_ary_new(); 01389 for (i = 0; matches[i]; i++) { 01390 rb_ary_push(result, rb_locale_str_new_cstr(matches[i])); 01391 free(matches[i]); 01392 } 01393 free(matches); 01394 if (RARRAY_LEN(result) >= 2) 01395 rb_ary_shift(result); 01396 } 01397 else { 01398 result = Qnil; 01399 } 01400 return result; 01401 } 01402 01403 void 01404 Init_readline() 01405 { 01406 VALUE history, fcomp, ucomp, version; 01407 01408 /* Allow conditional parsing of the ~/.inputrc file. */ 01409 rl_readline_name = (char *)"Ruby"; 01410 01411 using_history(); 01412 01413 completion_proc = rb_intern(COMPLETION_PROC); 01414 completion_case_fold = rb_intern(COMPLETION_CASE_FOLD); 01415 01416 mReadline = rb_define_module("Readline"); 01417 rb_define_module_function(mReadline, "readline", 01418 readline_readline, -1); 01419 rb_define_singleton_method(mReadline, "input=", 01420 readline_s_set_input, 1); 01421 rb_define_singleton_method(mReadline, "output=", 01422 readline_s_set_output, 1); 01423 rb_define_singleton_method(mReadline, "completion_proc=", 01424 readline_s_set_completion_proc, 1); 01425 rb_define_singleton_method(mReadline, "completion_proc", 01426 readline_s_get_completion_proc, 0); 01427 rb_define_singleton_method(mReadline, "completion_case_fold=", 01428 readline_s_set_completion_case_fold, 1); 01429 rb_define_singleton_method(mReadline, "completion_case_fold", 01430 readline_s_get_completion_case_fold, 0); 01431 rb_define_singleton_method(mReadline, "line_buffer", 01432 readline_s_get_line_buffer, 0); 01433 rb_define_singleton_method(mReadline, "point", 01434 readline_s_get_point, 0); 01435 rb_define_singleton_method(mReadline, "set_screen_size", 01436 readline_s_set_screen_size, 2); 01437 rb_define_singleton_method(mReadline, "get_screen_size", 01438 readline_s_get_screen_size, 0); 01439 rb_define_singleton_method(mReadline, "vi_editing_mode", 01440 readline_s_vi_editing_mode, 0); 01441 rb_define_singleton_method(mReadline, "vi_editing_mode?", 01442 readline_s_vi_editing_mode_p, 0); 01443 rb_define_singleton_method(mReadline, "emacs_editing_mode", 01444 readline_s_emacs_editing_mode, 0); 01445 rb_define_singleton_method(mReadline, "emacs_editing_mode?", 01446 readline_s_emacs_editing_mode_p, 0); 01447 rb_define_singleton_method(mReadline, "completion_append_character=", 01448 readline_s_set_completion_append_character, 1); 01449 rb_define_singleton_method(mReadline, "completion_append_character", 01450 readline_s_get_completion_append_character, 0); 01451 rb_define_singleton_method(mReadline, "basic_word_break_characters=", 01452 readline_s_set_basic_word_break_characters, 1); 01453 rb_define_singleton_method(mReadline, "basic_word_break_characters", 01454 readline_s_get_basic_word_break_characters, 0); 01455 rb_define_singleton_method(mReadline, "completer_word_break_characters=", 01456 readline_s_set_completer_word_break_characters, 1); 01457 rb_define_singleton_method(mReadline, "completer_word_break_characters", 01458 readline_s_get_completer_word_break_characters, 0); 01459 rb_define_singleton_method(mReadline, "basic_quote_characters=", 01460 readline_s_set_basic_quote_characters, 1); 01461 rb_define_singleton_method(mReadline, "basic_quote_characters", 01462 readline_s_get_basic_quote_characters, 0); 01463 rb_define_singleton_method(mReadline, "completer_quote_characters=", 01464 readline_s_set_completer_quote_characters, 1); 01465 rb_define_singleton_method(mReadline, "completer_quote_characters", 01466 readline_s_get_completer_quote_characters, 0); 01467 rb_define_singleton_method(mReadline, "filename_quote_characters=", 01468 readline_s_set_filename_quote_characters, 1); 01469 rb_define_singleton_method(mReadline, "filename_quote_characters", 01470 readline_s_get_filename_quote_characters, 0); 01471 rb_define_singleton_method(mReadline, "refresh_line", 01472 readline_s_refresh_line, 0); 01473 01474 #if USE_INSERT_IGNORE_ESCAPE 01475 CONST_ID(id_orig_prompt, "orig_prompt"); 01476 CONST_ID(id_last_prompt, "last_prompt"); 01477 #endif 01478 01479 history = rb_obj_alloc(rb_cObject); 01480 rb_extend_object(history, rb_mEnumerable); 01481 rb_define_singleton_method(history,"to_s", hist_to_s, 0); 01482 rb_define_singleton_method(history,"[]", hist_get, 1); 01483 rb_define_singleton_method(history,"[]=", hist_set, 2); 01484 rb_define_singleton_method(history,"<<", hist_push, 1); 01485 rb_define_singleton_method(history,"push", hist_push_method, -1); 01486 rb_define_singleton_method(history,"pop", hist_pop, 0); 01487 rb_define_singleton_method(history,"shift", hist_shift, 0); 01488 rb_define_singleton_method(history,"each", hist_each, 0); 01489 rb_define_singleton_method(history,"length", hist_length, 0); 01490 rb_define_singleton_method(history,"size", hist_length, 0); 01491 rb_define_singleton_method(history,"empty?", hist_empty_p, 0); 01492 rb_define_singleton_method(history,"delete_at", hist_delete_at, 1); 01493 rb_define_singleton_method(history,"clear", hist_clear, 0); 01494 01495 /* 01496 * The history buffer. It extends Enumerable module, so it behaves 01497 * just like an array. 01498 * For example, gets the fifth content that the user input by 01499 * HISTORY[4]. 01500 */ 01501 rb_define_const(mReadline, "HISTORY", history); 01502 01503 fcomp = rb_obj_alloc(rb_cObject); 01504 rb_define_singleton_method(fcomp, "call", 01505 filename_completion_proc_call, 1); 01506 /* 01507 * The Object with the call method that is a completion for filename. 01508 * This is sets by Readline.completion_proc= method. 01509 */ 01510 rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp); 01511 01512 ucomp = rb_obj_alloc(rb_cObject); 01513 rb_define_singleton_method(ucomp, "call", 01514 username_completion_proc_call, 1); 01515 /* 01516 * The Object with the call method that is a completion for usernames. 01517 * This is sets by Readline.completion_proc= method. 01518 */ 01519 rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp); 01520 history_get_offset_func = history_get_offset_history_base; 01521 #if defined HAVE_RL_LIBRARY_VERSION 01522 version = rb_str_new_cstr(rl_library_version); 01523 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY 01524 if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION, 01525 strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) { 01526 add_history("1"); 01527 if (history_get(history_get_offset_func(0)) == NULL) { 01528 history_get_offset_func = history_get_offset_0; 01529 } 01530 #if !defined HAVE_CLEAR_HISTORY 01531 clear_history(); 01532 #else 01533 { 01534 HIST_ENTRY *entry = remove_history(0); 01535 if (entry) { 01536 free((char *)entry->line); 01537 free(entry); 01538 } 01539 } 01540 #endif 01541 } 01542 #endif 01543 #else 01544 version = rb_str_new_cstr("2.0 or prior version"); 01545 #endif 01546 /* Version string of GNU Readline or libedit. */ 01547 rb_define_const(mReadline, "VERSION", version); 01548 01549 rl_attempted_completion_function = readline_attempted_completion_function; 01550 #if defined HAVE_RL_GETC_FUNCTION 01551 rl_getc_function = readline_getc; 01552 id_getbyte = rb_intern_const("getbyte"); 01553 #elif defined HAVE_RL_EVENT_HOOK 01554 rl_event_hook = readline_event; 01555 #endif 01556 #ifdef HAVE_RL_CATCH_SIGNALS 01557 rl_catch_signals = 0; 01558 #endif 01559 #ifdef HAVE_RL_CATCH_SIGWINCH 01560 rl_catch_sigwinch = 0; 01561 #endif 01562 #ifdef HAVE_RL_CLEAR_SIGNALS 01563 rl_clear_signals(); 01564 #endif 01565 01566 readline_s_set_input(mReadline, rb_stdin); 01567 } 01568
1.7.3