1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/readline/readline.c (Readline.pre_input_hook)

(Readline.insert_text, Readline.redisplay): new function. An
  original patch was created by nagachika. [Feature #5785]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35513 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
kouji 2012-05-01 13:21:55 +00:00
parent 28b7df7820
commit 7a4b214558
4 changed files with 179 additions and 29 deletions

View file

@ -1,3 +1,9 @@
Tue May 1 22:18:45 2012 Kouji Takao <kouji.takao@gmail.com>
* ext/readline/readline.c (Readline.pre_input_hook)
(Readline.insert_text, Readline.redisplay): new function. An
original patch was created by nagachika. [Feature #5785]
Tue May 1 15:46:48 2012 Koichi Sasada <ko1@atdot.net>
* common.mk: "$(Q)-..." doesn't work on nmake.

View file

@ -83,6 +83,7 @@ have_readline_var("rl_point")
/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")
@ -93,6 +94,8 @@ have_readline_func("rl_emacs_editing_mode")
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")

View file

@ -61,6 +61,9 @@ static ID completion_proc, completion_case_fold;
#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;
#endif
#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
# define rl_filename_completion_function filename_completion_function
@ -468,6 +471,108 @@ readline_s_set_output(VALUE self, VALUE output)
return output;
}
#if defined(HAVE_RL_PRE_INPUT_HOOK)
/*
* call-seq:
* Readline.pre_input_hook = proc
*
* Specifies a Proc object +proc+ to call after the first prompt has
* been printed and just before readline starts reading input
* characters.
*
* See GNU Readline's rl_pre_input_hook variable.
*
* Raises ArgumentError if +proc+ does not respond to the call method.
*
* Raises SecurityError if $SAFE is 4.
*/
static VALUE
readline_s_set_pre_input_hook(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);
}
/*
* call-seq:
* Readline.pre_input_hook -> proc
*
* Returns a Proc object +proc+ to call after the first prompt has
* been printed and just before readline starts reading input
* characters. The default is nil.
*
* Raises SecurityError if $SAFE is 4.
*/
static VALUE
readline_s_get_pre_input_hook(VALUE self)
{
rb_secure(4);
return rb_attr_get(mReadline, id_pre_input_hook);
}
static int
readline_pre_input_hook(void)
{
VALUE proc;
proc = rb_attr_get(mReadline, id_pre_input_hook);
if (!NIL_P(proc))
rb_funcall(proc, rb_intern("call"), 0);
return 0;
}
#else
#define readline_s_set_pre_input_hook rb_f_notimplement
#define readline_s_get_pre_input_hook rb_f_notimplement
#endif
#if defined(HAVE_RL_INSERT_TEXT)
/*
* call-seq:
* Readline.insert_text(string) -> self
*
* Insert text into the line at the current cursor position.
*
* See GNU Readline's rl_insert_text function.
*
* Raises SecurityError if $SAFE is 4.
*/
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)
/*
* call-seq:
* Readline.redisplay -> self
*
* Change what's displayed on the screen to reflect the current
* contents.
*
* See GNU Readline's rl_redisplay function.
*
* Raises SecurityError if $SAFE is 4.
*/
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
@ -1537,6 +1642,9 @@ Init_readline()
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 = rb_intern("pre_input_hook");
#endif
mReadline = rb_define_module("Readline");
rb_define_module_function(mReadline, "readline",
@ -1595,6 +1703,14 @@ Init_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=",
readline_s_set_pre_input_hook, 1);
rb_define_singleton_method(mReadline, "pre_input_hook",
readline_s_get_pre_input_hook, 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");
@ -1678,6 +1794,9 @@ Init_readline()
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 = (Function *)readline_pre_input_hook;
#endif
#ifdef HAVE_RL_CATCH_SIGNALS
rl_catch_signals = 0;
#endif

View file

@ -1,34 +1,5 @@
begin
require "readline"
=begin
class << Readline
[
"line_buffer",
"point",
"set_screen_size",
"get_screen_size",
"vi_editing_mode",
"emacs_editing_mode",
"completion_append_character=",
"completion_append_character",
"basic_word_break_characters=",
"basic_word_break_characters",
"completer_word_break_characters=",
"completer_word_break_characters",
"basic_quote_characters=",
"basic_quote_characters",
"completer_quote_characters=",
"completer_quote_characters",
"filename_quote_characters=",
"filename_quote_characters",
"refresh_line",
].each do |method_name|
define_method(method_name.to_sym) do |*args|
raise NotImplementedError
end
end
end
=end
rescue LoadError
else
require "test/unit"
@ -77,6 +48,10 @@ class TestReadline < Test::Unit::TestCase
["point"],
["set_screen_size", 1, 1],
["get_screen_size"],
["pre_input_hook=", proc {}],
["pre_input_hook"],
["insert_text", ""],
["redisplay"],
]
method_args.each do |method_name, *args|
assert_raise(SecurityError, NotImplementedError,
@ -372,6 +347,53 @@ class TestReadline < Test::Unit::TestCase
end
end
def test_pre_input_hook
begin
pr = proc {}
assert_equal(Readline.pre_input_hook = pr, pr)
assert_equal(Readline.pre_input_hook, pr)
assert_nil(Readline.pre_input_hook = 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 if !/EditLine/n.match(Readline::VERSION)
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 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("hello world", line)
end
assert_equal("> hello world\n", stdout.read)
stdout.close
rescue NotImplementedError
ensure
begin
Readline.pre_input_hook = nil
rescue NotImplementedError
end
end
end if !/EditLine/n.match(Readline::VERSION)
private
def replace_stdio(stdin_path, stdout_path)