Feature #5785 » readline_pre_input_hook.patch
ext/readline/extconf.rb | ||
---|---|---|
/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_event_hook")
|
||
/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_sigwinch")
|
||
/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_signals")
|
||
have_readline_var("rl_pre_input_hook")
|
||
have_readline_func("rl_cleanup_after_signal")
|
||
have_readline_func("rl_free_line_state")
|
||
have_readline_func("rl_clear_signals")
|
||
... | ... | |
have_readline_func("replace_history_entry")
|
||
have_readline_func("remove_history")
|
||
have_readline_func("clear_history")
|
||
have_readline_func("rl_redisplay")
|
||
have_readline_func("rl_insert_text")
|
||
have_readline_macro("RL_PROMPT_START_IGNORE")
|
||
have_readline_macro("RL_PROMPT_END_IGNORE")
|
||
create_makefile("readline")
|
ext/readline/readline.c | ||
---|---|---|
#if USE_INSERT_IGNORE_ESCAPE
|
||
static ID id_orig_prompt, id_last_prompt;
|
||
#endif
|
||
#if defined(HAVE_RL_PRE_INPUT_HOOK)
|
||
static ID id_pre_input_hook_proc;
|
||
#endif
|
||
#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
|
||
# define rl_filename_completion_function filename_completion_function
|
||
... | ... | |
return output;
|
||
}
|
||
#if defined(HAVE_RL_PRE_INPUT_HOOK)
|
||
static VALUE
|
||
readline_s_set_pre_input_hook_proc(VALUE self, VALUE proc)
|
||
{
|
||
rb_secure(4);
|
||
if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
|
||
rb_raise(rb_eArgError, "argument must respond to `call'");
|
||
return rb_ivar_set(mReadline, id_pre_input_hook_proc, proc);
|
||
}
|
||
static VALUE
|
||
readline_s_get_pre_input_hook_proc(VALUE self)
|
||
{
|
||
rb_secure(4);
|
||
return rb_attr_get(mReadline, id_pre_input_hook_proc);
|
||
}
|
||
static int
|
||
readline_pre_input_hook(void)
|
||
{
|
||
VALUE proc;
|
||
proc = rb_attr_get(mReadline, id_pre_input_hook_proc);
|
||
if (!NIL_P(proc))
|
||
rb_funcall(proc, rb_intern("call"), 0);
|
||
return 0;
|
||
}
|
||
#else
|
||
#define readline_s_set_pre_input_hook_proc rb_f_notimplement
|
||
#define readline_s_get_pre_input_hook_proc rb_f_notimplement
|
||
#endif
|
||
#if defined(HAVE_RL_INSERT_TEXT)
|
||
static VALUE
|
||
readline_s_insert_text(VALUE self, VALUE str)
|
||
{
|
||
rb_secure(4);
|
||
OutputStringValue(str);
|
||
rl_insert_text(RSTRING_PTR(str));
|
||
return self;
|
||
}
|
||
#else
|
||
#define readline_s_insert_text rb_f_notimplement
|
||
#endif
|
||
#if defined(HAVE_RL_REDISPLAY)
|
||
static VALUE
|
||
readline_s_redisplay(VALUE self)
|
||
{
|
||
rb_secure(4);
|
||
rl_redisplay();
|
||
return self;
|
||
}
|
||
#else
|
||
#define readline_s_redisplay rb_f_notimplement
|
||
#endif
|
||
/*
|
||
* call-seq:
|
||
* Readline.completion_proc = proc
|
||
... | ... | |
completion_proc = rb_intern(COMPLETION_PROC);
|
||
completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
|
||
#if defined(HAVE_RL_PRE_INPUT_HOOK)
|
||
id_pre_input_hook_proc = rb_intern("pre_input_hook_proc");
|
||
#endif
|
||
mReadline = rb_define_module("Readline");
|
||
rb_define_module_function(mReadline, "readline",
|
||
... | ... | |
readline_s_get_filename_quote_characters, 0);
|
||
rb_define_singleton_method(mReadline, "refresh_line",
|
||
readline_s_refresh_line, 0);
|
||
rb_define_singleton_method(mReadline, "pre_input_hook_proc=",
|
||
readline_s_set_pre_input_hook_proc, 1);
|
||
rb_define_singleton_method(mReadline, "pre_input_hook_proc",
|
||
readline_s_get_pre_input_hook_proc, 0);
|
||
rb_define_singleton_method(mReadline, "insert_text",
|
||
readline_s_insert_text, 1);
|
||
rb_define_singleton_method(mReadline, "redisplay",
|
||
readline_s_redisplay, 0);
|
||
#if USE_INSERT_IGNORE_ESCAPE
|
||
CONST_ID(id_orig_prompt, "orig_prompt");
|
||
... | ... | |
rb_define_const(mReadline, "VERSION", version);
|
||
rl_attempted_completion_function = readline_attempted_completion_function;
|
||
#if defined(HAVE_RL_PRE_INPUT_HOOK)
|
||
rl_pre_input_hook = readline_pre_input_hook;
|
||
#endif
|
||
#if defined HAVE_RL_GETC_FUNCTION
|
||
rl_getc_function = readline_getc;
|
||
id_getbyte = rb_intern_const("getbyte");
|
test/readline/test_readline.rb | ||
---|---|---|
["point"],
|
||
["set_screen_size", 1, 1],
|
||
["get_screen_size"],
|
||
["pre_input_hook_proc=", proc {}],
|
||
["pre_input_hook_proc"],
|
||
["insert_text", ""],
|
||
["redisplay"],
|
||
]
|
||
method_args.each do |method_name, *args|
|
||
assert_raise(SecurityError, NotImplementedError,
|
||
... | ... | |
end
|
||
end
|
||
def test_pre_input_hook_proc
|
||
begin
|
||
pr = proc {}
|
||
assert_equal(Readline.pre_input_hook_proc = pr, pr)
|
||
assert_equal(Readline.pre_input_hook_proc, pr)
|
||
assert_nil(Readline.pre_input_hook_proc = nil)
|
||
rescue NotImplementedError
|
||
end
|
||
end
|
||
def test_insert_text
|
||
begin
|
||
str = "test_insert_text"
|
||
assert_equal(Readline.insert_text(str), Readline)
|
||
assert_equal(Readline.line_buffer, str)
|
||
assert_equal(Readline.line_buffer.encoding,
|
||
get_default_internal_encoding)
|
||
rescue NotImplementedError
|
||
end
|
||
end
|
||
def test_modify_text_in_pre_input_hook
|
||
begin
|
||
stdin = Tempfile.new("readline_redisplay_stdin")
|
||
stdout = Tempfile.new("readline_redisplay_stdout")
|
||
stdin.write("world\n")
|
||
stdin.close
|
||
Readline.pre_input_hook_proc = proc do
|
||
assert_equal(Readline.line_buffer, "")
|
||
Readline.insert_text("hello ")
|
||
Readline.redisplay
|
||
end
|
||
replace_stdio(stdin.path, stdout.path) do
|
||
line = Readline.readline("> ")
|
||
assert_equal(line, "hello world")
|
||
end
|
||
assert_equal(stdout.read, "> ")
|
||
stdout.close
|
||
#rescue NotImplementedError
|
||
ensure
|
||
begin
|
||
Readline.pre_input_hook_proc = nil
|
||
rescue NotImplementedError
|
||
end
|
||
end
|
||
end
|
||
private
|
||
def replace_stdio(stdin_path, stdout_path)
|