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:
parent
28b7df7820
commit
7a4b214558
4 changed files with 179 additions and 29 deletions
|
@ -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.
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue