Project

General

Profile

Feature #5785 » readline_pre_input_hook.patch

nagachika (Tomoyuki Chikanaga), 12/21/2011 06:39 PM

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
57 57
#if USE_INSERT_IGNORE_ESCAPE
58 58
static ID id_orig_prompt, id_last_prompt;
59 59
#endif
60
#if defined(HAVE_RL_PRE_INPUT_HOOK)
61
static ID id_pre_input_hook_proc;
62
#endif
60 63

  
61 64
#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
62 65
# define rl_filename_completion_function filename_completion_function
......
451 454
    return output;
452 455
}
453 456

  
457
#if defined(HAVE_RL_PRE_INPUT_HOOK)
458
static VALUE
459
readline_s_set_pre_input_hook_proc(VALUE self, VALUE proc)
460
{
461
    rb_secure(4);
462
    if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
463
	rb_raise(rb_eArgError, "argument must respond to `call'");
464
    return rb_ivar_set(mReadline, id_pre_input_hook_proc, proc);
465
}
466

  
467
static VALUE
468
readline_s_get_pre_input_hook_proc(VALUE self)
469
{
470
    rb_secure(4);
471
    return rb_attr_get(mReadline, id_pre_input_hook_proc);
472
}
473

  
474
static int
475
readline_pre_input_hook(void)
476
{
477
    VALUE proc;
478

  
479
    proc = rb_attr_get(mReadline, id_pre_input_hook_proc);
480
    if (!NIL_P(proc))
481
	rb_funcall(proc, rb_intern("call"), 0);
482
    return 0;
483
}
484
#else
485
#define readline_s_set_pre_input_hook_proc rb_f_notimplement
486
#define readline_s_get_pre_input_hook_proc rb_f_notimplement
487
#endif
488

  
489
#if defined(HAVE_RL_INSERT_TEXT)
490
static VALUE
491
readline_s_insert_text(VALUE self, VALUE str)
492
{
493
    rb_secure(4);
494
    OutputStringValue(str);
495
    rl_insert_text(RSTRING_PTR(str));
496
    return self;
497
}
498
#else
499
#define readline_s_insert_text rb_f_notimplement
500
#endif
501

  
502
#if defined(HAVE_RL_REDISPLAY)
503
static VALUE
504
readline_s_redisplay(VALUE self)
505
{
506
    rb_secure(4);
507
    rl_redisplay();
508
    return self;
509
}
510
#else
511
#define readline_s_redisplay rb_f_notimplement
512
#endif
513

  
454 514
/*
455 515
 * call-seq:
456 516
 *   Readline.completion_proc = proc
......
1499 1559

  
1500 1560
    completion_proc = rb_intern(COMPLETION_PROC);
1501 1561
    completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
1562
#if defined(HAVE_RL_PRE_INPUT_HOOK)
1563
    id_pre_input_hook_proc = rb_intern("pre_input_hook_proc");
1564
#endif
1502 1565

  
1503 1566
    mReadline = rb_define_module("Readline");
1504 1567
    rb_define_module_function(mReadline, "readline",
......
1557 1620
			       readline_s_get_filename_quote_characters, 0);
1558 1621
    rb_define_singleton_method(mReadline, "refresh_line",
1559 1622
			       readline_s_refresh_line, 0);
1623
    rb_define_singleton_method(mReadline, "pre_input_hook_proc=",
1624
			       readline_s_set_pre_input_hook_proc, 1);
1625
    rb_define_singleton_method(mReadline, "pre_input_hook_proc",
1626
			       readline_s_get_pre_input_hook_proc, 0);
1627
    rb_define_singleton_method(mReadline, "insert_text",
1628
			       readline_s_insert_text, 1);
1629
    rb_define_singleton_method(mReadline, "redisplay",
1630
			       readline_s_redisplay, 0);
1560 1631

  
1561 1632
#if USE_INSERT_IGNORE_ESCAPE
1562 1633
    CONST_ID(id_orig_prompt, "orig_prompt");
......
1640 1711
    rb_define_const(mReadline, "VERSION", version);
1641 1712

  
1642 1713
    rl_attempted_completion_function = readline_attempted_completion_function;
1714
#if defined(HAVE_RL_PRE_INPUT_HOOK)
1715
    rl_pre_input_hook = readline_pre_input_hook;
1716
#endif
1643 1717
#if defined HAVE_RL_GETC_FUNCTION
1644 1718
    rl_getc_function = readline_getc;
1645 1719
    id_getbyte = rb_intern_const("getbyte");
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,
......
283 287
    end
284 288
  end
285 289

  
290
  def test_pre_input_hook_proc
291
    begin
292
      pr = proc {}
293
      assert_equal(Readline.pre_input_hook_proc = pr, pr)
294
      assert_equal(Readline.pre_input_hook_proc, pr)
295
      assert_nil(Readline.pre_input_hook_proc = nil)
296
    rescue NotImplementedError
297
    end
298
  end
299

  
300
  def test_insert_text
301
    begin
302
      str = "test_insert_text"
303
      assert_equal(Readline.insert_text(str), Readline)
304
      assert_equal(Readline.line_buffer, str)
305
      assert_equal(Readline.line_buffer.encoding,
306
                   get_default_internal_encoding)
307
    rescue NotImplementedError
308
    end
309
  end
310

  
311
  def test_modify_text_in_pre_input_hook
312
    begin
313
      stdin = Tempfile.new("readline_redisplay_stdin")
314
      stdout = Tempfile.new("readline_redisplay_stdout")
315
      stdin.write("world\n")
316
      stdin.close
317
      Readline.pre_input_hook_proc = proc do
318
        assert_equal(Readline.line_buffer, "")
319
        Readline.insert_text("hello ")
320
        Readline.redisplay
321
      end
322
      replace_stdio(stdin.path, stdout.path) do
323
        line = Readline.readline("> ")
324
        assert_equal(line, "hello world")
325
      end
326
      assert_equal(stdout.read, "> ")
327
      stdout.close
328
    #rescue NotImplementedError
329
    ensure
330
      begin
331
        Readline.pre_input_hook_proc = nil
332
      rescue NotImplementedError
333
      end
334
    end
335
  end
336

  
286 337
  private
287 338

  
288 339
  def replace_stdio(stdin_path, stdout_path)