Project

General

Profile

Feature #5785 » readline_pre_input_hook2.patch

nagachika (Tomoyuki Chikanaga), 01/12/2012 11:27 AM

View differences:

ext/readline/extconf.rb
83 83
/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_event_hook")
84 84
/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_sigwinch")
85 85
/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_signals")
86
have_readline_var("rl_pre_input_hook")
86 87
have_readline_func("rl_cleanup_after_signal")
87 88
have_readline_func("rl_free_line_state")
88 89
have_readline_func("rl_clear_signals")
......
93 94
have_readline_func("replace_history_entry")
94 95
have_readline_func("remove_history")
95 96
have_readline_func("clear_history")
97
have_readline_func("rl_redisplay")
98
have_readline_func("rl_insert_text")
96 99
have_readline_macro("RL_PROMPT_START_IGNORE")
97 100
have_readline_macro("RL_PROMPT_END_IGNORE")
98 101
create_makefile("readline")
ext/readline/readline.c
61 61
#if USE_INSERT_IGNORE_ESCAPE
62 62
static ID id_orig_prompt, id_last_prompt;
63 63
#endif
64
#if defined(HAVE_RL_PRE_INPUT_HOOK)
65
static ID id_pre_input_hook_proc;
66
#endif
64 67

  
65 68
#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
66 69
# define rl_filename_completion_function filename_completion_function
......
468 471
    return output;
469 472
}
470 473

  
474
#if defined(HAVE_RL_PRE_INPUT_HOOK)
475
static VALUE
476
readline_s_set_pre_input_hook_proc(VALUE self, VALUE proc)
477
{
478
    rb_secure(4);
479
    if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
480
	rb_raise(rb_eArgError, "argument must respond to `call'");
481
    return rb_ivar_set(mReadline, id_pre_input_hook_proc, proc);
482
}
483

  
484
static VALUE
485
readline_s_get_pre_input_hook_proc(VALUE self)
486
{
487
    rb_secure(4);
488
    return rb_attr_get(mReadline, id_pre_input_hook_proc);
489
}
490

  
491
static int
492
readline_pre_input_hook(void)
493
{
494
    VALUE proc;
495

  
496
    proc = rb_attr_get(mReadline, id_pre_input_hook_proc);
497
    if (!NIL_P(proc))
498
	rb_funcall(proc, rb_intern("call"), 0);
499
    return 0;
500
}
501
#else
502
#define readline_s_set_pre_input_hook_proc rb_f_notimplement
503
#define readline_s_get_pre_input_hook_proc rb_f_notimplement
504
#endif
505

  
506
#if defined(HAVE_RL_INSERT_TEXT)
507
static VALUE
508
readline_s_insert_text(VALUE self, VALUE str)
509
{
510
    rb_secure(4);
511
    OutputStringValue(str);
512
    rl_insert_text(RSTRING_PTR(str));
513
    return self;
514
}
515
#else
516
#define readline_s_insert_text rb_f_notimplement
517
#endif
518

  
519
#if defined(HAVE_RL_REDISPLAY)
520
static VALUE
521
readline_s_redisplay(VALUE self)
522
{
523
    rb_secure(4);
524
    rl_redisplay();
525
    return self;
526
}
527
#else
528
#define readline_s_redisplay rb_f_notimplement
529
#endif
530

  
471 531
/*
472 532
 * call-seq:
473 533
 *   Readline.completion_proc = proc
......
1531 1591

  
1532 1592
    completion_proc = rb_intern(COMPLETION_PROC);
1533 1593
    completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
1594
#if defined(HAVE_RL_PRE_INPUT_HOOK)
1595
    id_pre_input_hook_proc = rb_intern("pre_input_hook_proc");
1596
#endif
1534 1597

  
1535 1598
    mReadline = rb_define_module("Readline");
1536 1599
    rb_define_module_function(mReadline, "readline",
......
1589 1652
			       readline_s_get_filename_quote_characters, 0);
1590 1653
    rb_define_singleton_method(mReadline, "refresh_line",
1591 1654
			       readline_s_refresh_line, 0);
1655
    rb_define_singleton_method(mReadline, "pre_input_hook_proc=",
1656
			       readline_s_set_pre_input_hook_proc, 1);
1657
    rb_define_singleton_method(mReadline, "pre_input_hook_proc",
1658
			       readline_s_get_pre_input_hook_proc, 0);
1659
    rb_define_singleton_method(mReadline, "insert_text",
1660
			       readline_s_insert_text, 1);
1661
    rb_define_singleton_method(mReadline, "redisplay",
1662
			       readline_s_redisplay, 0);
1592 1663

  
1593 1664
#if USE_INSERT_IGNORE_ESCAPE
1594 1665
    CONST_ID(id_orig_prompt, "orig_prompt");
......
1672 1743
    rb_define_const(mReadline, "VERSION", version);
1673 1744

  
1674 1745
    rl_attempted_completion_function = readline_attempted_completion_function;
1746
#if defined(HAVE_RL_PRE_INPUT_HOOK)
1747
    rl_pre_input_hook = readline_pre_input_hook;
1748
#endif
1749
#if defined HAVE_RL_GETC_FUNCTION
1750
    rl_getc_function = readline_getc;
1751
    id_getbyte = rb_intern_const("getbyte");
1752
#elif defined HAVE_RL_EVENT_HOOK
1753
    rl_event_hook = readline_event;
1754
#endif
1675 1755
#ifdef HAVE_RL_CATCH_SIGNALS
1676 1756
    rl_catch_signals = 0;
1677 1757
#endif
test/readline/test_readline.rb
70 70
       ["point"],
71 71
       ["set_screen_size", 1, 1],
72 72
       ["get_screen_size"],
73
       ["pre_input_hook_proc=", proc {}],
74
       ["pre_input_hook_proc"],
75
       ["insert_text", ""],
76
       ["redisplay"],
73 77
      ]
74 78
    method_args.each do |method_name, *args|
75 79
      assert_raise(SecurityError, NotImplementedError,
......
324 328
    end
325 329
  end
326 330

  
331
  def test_pre_input_hook_proc
332
    begin
333
      pr = proc {}
334
      assert_equal(Readline.pre_input_hook_proc = pr, pr)
335
      assert_equal(Readline.pre_input_hook_proc, pr)
336
      assert_nil(Readline.pre_input_hook_proc = nil)
337
    rescue NotImplementedError
338
    end
339
  end
340

  
341
  def test_insert_text
342
    begin
343
      str = "test_insert_text"
344
      assert_equal(Readline.insert_text(str), Readline)
345
      assert_equal(Readline.line_buffer, str)
346
      assert_equal(Readline.line_buffer.encoding,
347
                   get_default_internal_encoding)
348
    rescue NotImplementedError
349
    end
350
  end
351

  
352
  def test_modify_text_in_pre_input_hook
353
    begin
354
      stdin = Tempfile.new("readline_redisplay_stdin")
355
      stdout = Tempfile.new("readline_redisplay_stdout")
356
      stdin.write("world\n")
357
      stdin.close
358
      Readline.pre_input_hook_proc = proc do
359
        assert_equal(Readline.line_buffer, "")
360
        Readline.insert_text("hello ")
361
        Readline.redisplay
362
      end
363
      replace_stdio(stdin.path, stdout.path) do
364
        line = Readline.readline("> ")
365
        assert_equal(line, "hello world")
366
      end
367
      assert_equal(stdout.read, "> ")
368
      stdout.close
369
    #rescue NotImplementedError
370
    ensure
371
      begin
372
        Readline.pre_input_hook_proc = nil
373
      rescue NotImplementedError
374
      end
375
    end
376
  end
377

  
327 378
  private
328 379

  
329 380
  def replace_stdio(stdin_path, stdout_path)