PageRenderTime 64ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/stdlib/ext/readline/readline.c

https://github.com/kwatch/rubinius
C | 824 lines | 739 code | 80 blank | 5 comment | 90 complexity | 6729a3b2bcd135cda4f94c4a9ea15279 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, BSD-2-Clause
  1. /* readline.c -- GNU Readline module
  2. Copyright (C) 1997-2001 Shugo Maeda */
  3. #include "config.h"
  4. #include <errno.h>
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include <string.h>
  8. #ifdef HAVE_READLINE_READLINE_H
  9. #include <readline/readline.h>
  10. #endif
  11. #ifdef HAVE_READLINE_HISTORY_H
  12. #include <readline/history.h>
  13. #endif
  14. #ifdef HAVE_EDITLINE_READLINE_H
  15. #include <editline/readline.h>
  16. #endif
  17. #include "ruby.h"
  18. #include "rubyio.h"
  19. #include "rubysig.h"
  20. #ifdef HAVE_UNISTD_H
  21. #include <unistd.h>
  22. #endif
  23. static VALUE mReadline;
  24. #define TOLOWER(c) (isupper(c) ? tolower(c) : c)
  25. #define COMPLETION_PROC "completion_proc"
  26. #define COMPLETION_CASE_FOLD "completion_case_fold"
  27. static ID completion_proc, completion_case_fold;
  28. #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
  29. # define rl_filename_completion_function filename_completion_function
  30. #endif
  31. #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
  32. # define rl_username_completion_function username_completion_function
  33. #endif
  34. #ifndef HAVE_RL_COMPLETION_MATCHES
  35. # define rl_completion_matches completion_matches
  36. #endif
  37. static int readline_event(void);
  38. static char **readline_attempted_completion_function(const char *text,
  39. int start, int end);
  40. static int
  41. readline_event()
  42. {
  43. CHECK_INTS;
  44. rb_thread_schedule();
  45. return 0;
  46. }
  47. static VALUE
  48. readline_readline(argc, argv, self)
  49. int argc;
  50. VALUE *argv;
  51. VALUE self;
  52. {
  53. VALUE tmp, add_hist, result;
  54. char *prompt = NULL;
  55. char *buff;
  56. int status;
  57. OpenFile *ofp, *ifp;
  58. rb_secure(4);
  59. if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
  60. SafeStringValue(tmp);
  61. prompt = RSTRING(tmp)->ptr;
  62. }
  63. if (!isatty(0) && errno == EBADF) rb_raise(rb_eIOError, "stdin closed");
  64. Check_Type(rb_stdout, T_FILE);
  65. GetOpenFile(rb_stdout, ofp);
  66. rl_outstream = GetWriteFile(ofp);
  67. Check_Type(rb_stdin, T_FILE);
  68. GetOpenFile(rb_stdin, ifp);
  69. rl_instream = GetReadFile(ifp);
  70. buff = (char*)rb_protect((VALUE(*)_((VALUE)))readline, (VALUE)prompt,
  71. &status);
  72. if (status) {
  73. #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
  74. /* restore terminal mode and signal handler*/
  75. rl_cleanup_after_signal();
  76. #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
  77. /* restore terminal mode */
  78. if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */
  79. (*rl_deprep_term_function)();
  80. else
  81. #else
  82. rl_deprep_terminal();
  83. #endif
  84. rb_jump_tag(status);
  85. }
  86. if (RTEST(add_hist) && buff) {
  87. add_history(buff);
  88. }
  89. if (buff)
  90. result = rb_tainted_str_new2(buff);
  91. else
  92. result = Qnil;
  93. if (buff) free(buff);
  94. return result;
  95. }
  96. static VALUE
  97. readline_s_set_completion_proc(self, proc)
  98. VALUE self;
  99. VALUE proc;
  100. {
  101. rb_secure(4);
  102. if (!rb_respond_to(proc, rb_intern("call")))
  103. rb_raise(rb_eArgError, "argument must respond to `call'");
  104. return rb_ivar_set(mReadline, completion_proc, proc);
  105. }
  106. static VALUE
  107. readline_s_get_completion_proc(self)
  108. VALUE self;
  109. {
  110. rb_secure(4);
  111. return rb_attr_get(mReadline, completion_proc);
  112. }
  113. static VALUE
  114. readline_s_set_completion_case_fold(self, val)
  115. VALUE self;
  116. VALUE val;
  117. {
  118. rb_secure(4);
  119. return rb_ivar_set(mReadline, completion_case_fold, val);
  120. }
  121. static VALUE
  122. readline_s_get_completion_case_fold(self)
  123. VALUE self;
  124. {
  125. rb_secure(4);
  126. return rb_attr_get(mReadline, completion_case_fold);
  127. }
  128. static char **
  129. readline_attempted_completion_function(text, start, end)
  130. const char *text;
  131. int start;
  132. int end;
  133. {
  134. VALUE proc, ary, temp;
  135. char **result;
  136. int case_fold;
  137. int i, matches;
  138. proc = rb_attr_get(mReadline, completion_proc);
  139. if (NIL_P(proc))
  140. return NULL;
  141. #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
  142. rl_attempted_completion_over = 1;
  143. #endif
  144. case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));
  145. ary = rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(text));
  146. if (TYPE(ary) != T_ARRAY)
  147. ary = rb_Array(ary);
  148. matches = RARRAY(ary)->len;
  149. if (matches == 0)
  150. return NULL;
  151. result = ALLOC_N(char *, matches + 2);
  152. for (i = 0; i < matches; i++) {
  153. temp = rb_obj_as_string(RARRAY(ary)->ptr[i]);
  154. result[i + 1] = ALLOC_N(char, RSTRING(temp)->len + 1);
  155. strcpy(result[i + 1], RSTRING(temp)->ptr);
  156. }
  157. result[matches + 1] = NULL;
  158. if (matches == 1) {
  159. result[0] = strdup(result[1]);
  160. }
  161. else {
  162. register int i = 1;
  163. int low = 100000;
  164. while (i < matches) {
  165. register int c1, c2, si;
  166. if (case_fold) {
  167. for (si = 0;
  168. (c1 = TOLOWER(result[i][si])) &&
  169. (c2 = TOLOWER(result[i + 1][si]));
  170. si++)
  171. if (c1 != c2) break;
  172. } else {
  173. for (si = 0;
  174. (c1 = result[i][si]) &&
  175. (c2 = result[i + 1][si]);
  176. si++)
  177. if (c1 != c2) break;
  178. }
  179. if (low > si) low = si;
  180. i++;
  181. }
  182. result[0] = ALLOC_N(char, low + 1);
  183. strncpy(result[0], result[1], low);
  184. result[0][low] = '\0';
  185. }
  186. return result;
  187. }
  188. static VALUE
  189. readline_s_vi_editing_mode(self)
  190. VALUE self;
  191. {
  192. #ifdef HAVE_RL_VI_EDITING_MODE
  193. rb_secure(4);
  194. rl_vi_editing_mode(1,0);
  195. return Qnil;
  196. #else
  197. rb_notimplement();
  198. return Qnil; /* not reached */
  199. #endif /* HAVE_RL_VI_EDITING_MODE */
  200. }
  201. static VALUE
  202. readline_s_emacs_editing_mode(self)
  203. VALUE self;
  204. {
  205. #ifdef HAVE_RL_EMACS_EDITING_MODE
  206. rb_secure(4);
  207. rl_emacs_editing_mode(1,0);
  208. return Qnil;
  209. #else
  210. rb_notimplement();
  211. return Qnil; /* not reached */
  212. #endif /* HAVE_RL_EMACS_EDITING_MODE */
  213. }
  214. static VALUE
  215. readline_s_set_completion_append_character(self, str)
  216. VALUE self, str;
  217. {
  218. #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
  219. rb_secure(4);
  220. if (NIL_P(str)) {
  221. rl_completion_append_character = '\0';
  222. }
  223. else {
  224. SafeStringValue(str);
  225. if (RSTRING(str)->len == 0) {
  226. rl_completion_append_character = '\0';
  227. } else {
  228. rl_completion_append_character = RSTRING(str)->ptr[0];
  229. }
  230. }
  231. return self;
  232. #else
  233. rb_notimplement();
  234. return Qnil; /* not reached */
  235. #endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */
  236. }
  237. static VALUE
  238. readline_s_get_completion_append_character(self)
  239. VALUE self;
  240. {
  241. #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
  242. VALUE str;
  243. rb_secure(4);
  244. if (rl_completion_append_character == '\0')
  245. return Qnil;
  246. str = rb_str_new("", 1);
  247. RSTRING(str)->ptr[0] = rl_completion_append_character;
  248. return str;
  249. #else
  250. rb_notimplement();
  251. return Qnil; /* not reached */
  252. #endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */
  253. }
  254. static VALUE
  255. readline_s_set_basic_word_break_characters(self, str)
  256. VALUE self, str;
  257. {
  258. #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
  259. static char *basic_word_break_characters = NULL;
  260. rb_secure(4);
  261. SafeStringValue(str);
  262. if (basic_word_break_characters == NULL) {
  263. basic_word_break_characters =
  264. ALLOC_N(char, RSTRING(str)->len + 1);
  265. }
  266. else {
  267. REALLOC_N(basic_word_break_characters, char, RSTRING(str)->len + 1);
  268. }
  269. strncpy(basic_word_break_characters,
  270. RSTRING(str)->ptr, RSTRING(str)->len);
  271. basic_word_break_characters[RSTRING(str)->len] = '\0';
  272. rl_basic_word_break_characters = basic_word_break_characters;
  273. return self;
  274. #else
  275. rb_notimplement();
  276. return Qnil; /* not reached */
  277. #endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */
  278. }
  279. static VALUE
  280. readline_s_get_basic_word_break_characters(self, str)
  281. VALUE self, str;
  282. {
  283. #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
  284. rb_secure(4);
  285. if (rl_basic_word_break_characters == NULL)
  286. return Qnil;
  287. return rb_tainted_str_new2(rl_basic_word_break_characters);
  288. #else
  289. rb_notimplement();
  290. return Qnil; /* not reached */
  291. #endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */
  292. }
  293. static VALUE
  294. readline_s_set_completer_word_break_characters(self, str)
  295. VALUE self, str;
  296. {
  297. #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
  298. static char *completer_word_break_characters = NULL;
  299. rb_secure(4);
  300. SafeStringValue(str);
  301. if (completer_word_break_characters == NULL) {
  302. completer_word_break_characters =
  303. ALLOC_N(char, RSTRING(str)->len + 1);
  304. }
  305. else {
  306. REALLOC_N(completer_word_break_characters, char, RSTRING(str)->len + 1);
  307. }
  308. strncpy(completer_word_break_characters,
  309. RSTRING(str)->ptr, RSTRING(str)->len);
  310. completer_word_break_characters[RSTRING(str)->len] = '\0';
  311. rl_completer_word_break_characters = completer_word_break_characters;
  312. return self;
  313. #else
  314. rb_notimplement();
  315. return Qnil; /* not reached */
  316. #endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */
  317. }
  318. static VALUE
  319. readline_s_get_completer_word_break_characters(self, str)
  320. VALUE self, str;
  321. {
  322. #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
  323. rb_secure(4);
  324. if (rl_completer_word_break_characters == NULL)
  325. return Qnil;
  326. return rb_tainted_str_new2(rl_completer_word_break_characters);
  327. #else
  328. rb_notimplement();
  329. return Qnil; /* not reached */
  330. #endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */
  331. }
  332. static VALUE
  333. readline_s_set_basic_quote_characters(self, str)
  334. VALUE self, str;
  335. {
  336. #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
  337. static char *basic_quote_characters = NULL;
  338. rb_secure(4);
  339. SafeStringValue(str);
  340. if (basic_quote_characters == NULL) {
  341. basic_quote_characters =
  342. ALLOC_N(char, RSTRING(str)->len + 1);
  343. }
  344. else {
  345. REALLOC_N(basic_quote_characters, char, RSTRING(str)->len + 1);
  346. }
  347. strncpy(basic_quote_characters,
  348. RSTRING(str)->ptr, RSTRING(str)->len);
  349. basic_quote_characters[RSTRING(str)->len] = '\0';
  350. rl_basic_quote_characters = basic_quote_characters;
  351. return self;
  352. #else
  353. rb_notimplement();
  354. return Qnil; /* not reached */
  355. #endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */
  356. }
  357. static VALUE
  358. readline_s_get_basic_quote_characters(self, str)
  359. VALUE self, str;
  360. {
  361. #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
  362. rb_secure(4);
  363. if (rl_basic_quote_characters == NULL)
  364. return Qnil;
  365. return rb_tainted_str_new2(rl_basic_quote_characters);
  366. #else
  367. rb_notimplement();
  368. return Qnil; /* not reached */
  369. #endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */
  370. }
  371. static VALUE
  372. readline_s_set_completer_quote_characters(self, str)
  373. VALUE self, str;
  374. {
  375. #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
  376. static char *completer_quote_characters = NULL;
  377. rb_secure(4);
  378. SafeStringValue(str);
  379. if (completer_quote_characters == NULL) {
  380. completer_quote_characters =
  381. ALLOC_N(char, RSTRING(str)->len + 1);
  382. }
  383. else {
  384. REALLOC_N(completer_quote_characters, char, RSTRING(str)->len + 1);
  385. }
  386. strncpy(completer_quote_characters,
  387. RSTRING(str)->ptr, RSTRING(str)->len);
  388. completer_quote_characters[RSTRING(str)->len] = '\0';
  389. rl_completer_quote_characters = completer_quote_characters;
  390. return self;
  391. #else
  392. rb_notimplement();
  393. return Qnil; /* not reached */
  394. #endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */
  395. }
  396. static VALUE
  397. readline_s_get_completer_quote_characters(self, str)
  398. VALUE self, str;
  399. {
  400. #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
  401. rb_secure(4);
  402. if (rl_completer_quote_characters == NULL)
  403. return Qnil;
  404. return rb_tainted_str_new2(rl_completer_quote_characters);
  405. #else
  406. rb_notimplement();
  407. return Qnil; /* not reached */
  408. #endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */
  409. }
  410. static VALUE
  411. readline_s_set_filename_quote_characters(self, str)
  412. VALUE self, str;
  413. {
  414. #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
  415. static char *filename_quote_characters = NULL;
  416. rb_secure(4);
  417. SafeStringValue(str);
  418. if (filename_quote_characters == NULL) {
  419. filename_quote_characters =
  420. ALLOC_N(char, RSTRING(str)->len + 1);
  421. }
  422. else {
  423. REALLOC_N(filename_quote_characters, char, RSTRING(str)->len + 1);
  424. }
  425. strncpy(filename_quote_characters,
  426. RSTRING(str)->ptr, RSTRING(str)->len);
  427. filename_quote_characters[RSTRING(str)->len] = '\0';
  428. rl_filename_quote_characters = filename_quote_characters;
  429. return self;
  430. #else
  431. rb_notimplement();
  432. return Qnil; /* not reached */
  433. #endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */
  434. }
  435. static VALUE
  436. readline_s_get_filename_quote_characters(self, str)
  437. VALUE self, str;
  438. {
  439. #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
  440. rb_secure(4);
  441. if (rl_filename_quote_characters == NULL)
  442. return Qnil;
  443. return rb_tainted_str_new2(rl_filename_quote_characters);
  444. #else
  445. rb_notimplement();
  446. return Qnil; /* not reached */
  447. #endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */
  448. }
  449. static VALUE
  450. hist_to_s(self)
  451. VALUE self;
  452. {
  453. return rb_str_new2("HISTORY");
  454. }
  455. static VALUE
  456. hist_get(self, index)
  457. VALUE self;
  458. VALUE index;
  459. {
  460. HIST_ENTRY *entry;
  461. int i;
  462. rb_secure(4);
  463. i = NUM2INT(index);
  464. if (i < 0) {
  465. i += history_length;
  466. }
  467. entry = history_get(history_base + i);
  468. if (entry == NULL) {
  469. rb_raise(rb_eIndexError, "invalid index");
  470. }
  471. return rb_tainted_str_new2(entry->line);
  472. }
  473. static VALUE
  474. hist_set(self, index, str)
  475. VALUE self;
  476. VALUE index;
  477. VALUE str;
  478. {
  479. #ifdef HAVE_REPLACE_HISTORY_ENTRY
  480. HIST_ENTRY *entry;
  481. int i;
  482. rb_secure(4);
  483. i = NUM2INT(index);
  484. SafeStringValue(str);
  485. if (i < 0) {
  486. i += history_length;
  487. }
  488. entry = replace_history_entry(i, RSTRING(str)->ptr, NULL);
  489. if (entry == NULL) {
  490. rb_raise(rb_eIndexError, "invalid index");
  491. }
  492. return str;
  493. #else
  494. rb_notimplement();
  495. return Qnil; /* not reached */
  496. #endif
  497. }
  498. static VALUE
  499. hist_push(self, str)
  500. VALUE self;
  501. VALUE str;
  502. {
  503. rb_secure(4);
  504. SafeStringValue(str);
  505. add_history(RSTRING(str)->ptr);
  506. return self;
  507. }
  508. static VALUE
  509. hist_push_method(argc, argv, self)
  510. int argc;
  511. VALUE *argv;
  512. VALUE self;
  513. {
  514. VALUE str;
  515. rb_secure(4);
  516. while (argc--) {
  517. str = *argv++;
  518. SafeStringValue(str);
  519. add_history(RSTRING(str)->ptr);
  520. }
  521. return self;
  522. }
  523. static VALUE
  524. rb_remove_history(index)
  525. int index;
  526. {
  527. #ifdef HAVE_REMOVE_HISTORY
  528. HIST_ENTRY *entry;
  529. VALUE val;
  530. rb_secure(4);
  531. entry = remove_history(index);
  532. if (entry) {
  533. val = rb_tainted_str_new2(entry->line);
  534. free(entry->line);
  535. free(entry);
  536. return val;
  537. }
  538. return Qnil;
  539. #else
  540. rb_notimplement();
  541. return Qnil; /* not reached */
  542. #endif
  543. }
  544. static VALUE
  545. hist_pop(self)
  546. VALUE self;
  547. {
  548. rb_secure(4);
  549. if (history_length > 0) {
  550. return rb_remove_history(history_length - 1);
  551. } else {
  552. return Qnil;
  553. }
  554. }
  555. static VALUE
  556. hist_shift(self)
  557. VALUE self;
  558. {
  559. rb_secure(4);
  560. if (history_length > 0) {
  561. return rb_remove_history(0);
  562. } else {
  563. return Qnil;
  564. }
  565. }
  566. static VALUE
  567. hist_each(self)
  568. VALUE self;
  569. {
  570. HIST_ENTRY *entry;
  571. int i;
  572. rb_secure(4);
  573. for (i = 0; i < history_length; i++) {
  574. entry = history_get(history_base + i);
  575. if (entry == NULL)
  576. break;
  577. rb_yield(rb_tainted_str_new2(entry->line));
  578. }
  579. return self;
  580. }
  581. static VALUE
  582. hist_length(self)
  583. VALUE self;
  584. {
  585. rb_secure(4);
  586. return INT2NUM(history_length);
  587. }
  588. static VALUE
  589. hist_empty_p(self)
  590. VALUE self;
  591. {
  592. rb_secure(4);
  593. return history_length == 0 ? Qtrue : Qfalse;
  594. }
  595. static VALUE
  596. hist_delete_at(self, index)
  597. VALUE self;
  598. VALUE index;
  599. {
  600. int i;
  601. rb_secure(4);
  602. i = NUM2INT(index);
  603. if (i < 0)
  604. i += history_length;
  605. if (i < 0 || i > history_length - 1) {
  606. rb_raise(rb_eIndexError, "invalid index");
  607. }
  608. return rb_remove_history(i);
  609. }
  610. static VALUE
  611. filename_completion_proc_call(self, str)
  612. VALUE self;
  613. VALUE str;
  614. {
  615. VALUE result;
  616. char **matches;
  617. int i;
  618. matches = rl_completion_matches(StringValuePtr(str),
  619. rl_filename_completion_function);
  620. if (matches) {
  621. result = rb_ary_new();
  622. for (i = 0; matches[i]; i++) {
  623. rb_ary_push(result, rb_tainted_str_new2(matches[i]));
  624. free(matches[i]);
  625. }
  626. free(matches);
  627. if (RARRAY(result)->len >= 2)
  628. rb_ary_shift(result);
  629. }
  630. else {
  631. result = Qnil;
  632. }
  633. return result;
  634. }
  635. static VALUE
  636. username_completion_proc_call(self, str)
  637. VALUE self;
  638. VALUE str;
  639. {
  640. VALUE result;
  641. char **matches;
  642. int i;
  643. matches = rl_completion_matches(StringValuePtr(str),
  644. rl_username_completion_function);
  645. if (matches) {
  646. result = rb_ary_new();
  647. for (i = 0; matches[i]; i++) {
  648. rb_ary_push(result, rb_tainted_str_new2(matches[i]));
  649. free(matches[i]);
  650. }
  651. free(matches);
  652. if (RARRAY(result)->len >= 2)
  653. rb_ary_shift(result);
  654. }
  655. else {
  656. result = Qnil;
  657. }
  658. return result;
  659. }
  660. void
  661. Init_readline()
  662. {
  663. VALUE history, fcomp, ucomp;
  664. /* Allow conditional parsing of the ~/.inputrc file. */
  665. rl_readline_name = "Ruby";
  666. using_history();
  667. completion_proc = rb_intern(COMPLETION_PROC);
  668. completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
  669. mReadline = rb_define_module("Readline");
  670. rb_define_module_function(mReadline, "readline",
  671. readline_readline, -1);
  672. rb_define_singleton_method(mReadline, "completion_proc=",
  673. readline_s_set_completion_proc, 1);
  674. rb_define_singleton_method(mReadline, "completion_proc",
  675. readline_s_get_completion_proc, 0);
  676. rb_define_singleton_method(mReadline, "completion_case_fold=",
  677. readline_s_set_completion_case_fold, 1);
  678. rb_define_singleton_method(mReadline, "completion_case_fold",
  679. readline_s_get_completion_case_fold, 0);
  680. rb_define_singleton_method(mReadline, "vi_editing_mode",
  681. readline_s_vi_editing_mode, 0);
  682. rb_define_singleton_method(mReadline, "emacs_editing_mode",
  683. readline_s_emacs_editing_mode, 0);
  684. rb_define_singleton_method(mReadline, "completion_append_character=",
  685. readline_s_set_completion_append_character, 1);
  686. rb_define_singleton_method(mReadline, "completion_append_character",
  687. readline_s_get_completion_append_character, 0);
  688. rb_define_singleton_method(mReadline, "basic_word_break_characters=",
  689. readline_s_set_basic_word_break_characters, 1);
  690. rb_define_singleton_method(mReadline, "basic_word_break_characters",
  691. readline_s_get_basic_word_break_characters, 0);
  692. rb_define_singleton_method(mReadline, "completer_word_break_characters=",
  693. readline_s_set_completer_word_break_characters, 1);
  694. rb_define_singleton_method(mReadline, "completer_word_break_characters",
  695. readline_s_get_completer_word_break_characters, 0);
  696. rb_define_singleton_method(mReadline, "basic_quote_characters=",
  697. readline_s_set_basic_quote_characters, 1);
  698. rb_define_singleton_method(mReadline, "basic_quote_characters",
  699. readline_s_get_basic_quote_characters, 0);
  700. rb_define_singleton_method(mReadline, "completer_quote_characters=",
  701. readline_s_set_completer_quote_characters, 1);
  702. rb_define_singleton_method(mReadline, "completer_quote_characters",
  703. readline_s_get_completer_quote_characters, 0);
  704. rb_define_singleton_method(mReadline, "filename_quote_characters=",
  705. readline_s_set_filename_quote_characters, 1);
  706. rb_define_singleton_method(mReadline, "filename_quote_characters",
  707. readline_s_get_filename_quote_characters, 0);
  708. history = rb_obj_alloc(rb_cObject);
  709. rb_extend_object(history, rb_mEnumerable);
  710. rb_define_singleton_method(history,"to_s", hist_to_s, 0);
  711. rb_define_singleton_method(history,"[]", hist_get, 1);
  712. rb_define_singleton_method(history,"[]=", hist_set, 2);
  713. rb_define_singleton_method(history,"<<", hist_push, 1);
  714. rb_define_singleton_method(history,"push", hist_push_method, -1);
  715. rb_define_singleton_method(history,"pop", hist_pop, 0);
  716. rb_define_singleton_method(history,"shift", hist_shift, 0);
  717. rb_define_singleton_method(history,"each", hist_each, 0);
  718. rb_define_singleton_method(history,"length", hist_length, 0);
  719. rb_define_singleton_method(history,"size", hist_length, 0);
  720. rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
  721. rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
  722. rb_define_const(mReadline, "HISTORY", history);
  723. fcomp = rb_obj_alloc(rb_cObject);
  724. rb_define_singleton_method(fcomp, "call",
  725. filename_completion_proc_call, 1);
  726. rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp);
  727. ucomp = rb_obj_alloc(rb_cObject);
  728. rb_define_singleton_method(ucomp, "call",
  729. username_completion_proc_call, 1);
  730. rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
  731. #if defined HAVE_RL_LIBRARY_VERSION
  732. rb_define_const(mReadline, "VERSION", rb_str_new2(rl_library_version));
  733. #else
  734. rb_define_const(mReadline, "VERSION",
  735. rb_str_new2("2.0 or before version"));
  736. #endif
  737. rl_attempted_completion_function = readline_attempted_completion_function;
  738. #ifdef HAVE_RL_EVENT_HOOK
  739. rl_event_hook = readline_event;
  740. #endif
  741. #ifdef HAVE_RL_CLEAR_SIGNALS
  742. rl_clear_signals();
  743. #endif
  744. }