ext/readline/readline.c


DEFINITIONS

This source file includes following functions.
  1. readline_event
  2. readline_readline
  3. readline_s_set_completion_proc
  4. readline_s_get_completion_proc
  5. readline_s_set_completion_case_fold
  6. readline_s_get_completion_case_fold
  7. readline_attempted_completion_function
  8. readline_s_vi_editing_mode
  9. readline_s_emacs_editing_mode
  10. readline_s_set_completion_append_character
  11. readline_s_get_completion_append_character
  12. readline_s_set_basic_word_break_characters
  13. readline_s_get_basic_word_break_characters
  14. readline_s_set_completer_word_break_characters
  15. readline_s_get_completer_word_break_characters
  16. readline_s_set_basic_quote_characters
  17. readline_s_get_basic_quote_characters
  18. readline_s_set_completer_quote_characters
  19. readline_s_get_completer_quote_characters
  20. readline_s_set_filename_quote_characters
  21. readline_s_get_filename_quote_characters
  22. rb_remove_history
  23. hist_to_s
  24. hist_get
  25. hist_set
  26. hist_push
  27. hist_push_method
  28. hist_pop
  29. hist_shift
  30. hist_each
  31. hist_length
  32. hist_empty_p
  33. hist_delete_at
  34. filename_completion_proc_call
  35. username_completion_proc_call
  36. Init_readline


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