summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-16 12:35:04 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-16 12:35:04 +0000
commit9c2c4f50211009ab77c3455eee242a0693b03732 (patch)
tree9c6bd1ca6cb3e04f8fe383bb042e7923f638f1f8 /ext
parent357bdaebde0a162cd77d108ffdfae428080a3887 (diff)
merges r30496 and r30519 from trunk into ruby_1_9_2.
-- * ext/readline/readline.c: apply a patch from Nobuyoshi Nakada. fixed #3616 [ruby-core:31484] IRB + readline incorrectly counts non-printing characters in prompt -- * ext/readline/extconf.rb: new checks for RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE. [ruby-core:34331] * ext/readline/readline.c: enables USE_INSERT_IGNORE_ESCAPE only if RL_PROMPT_{START,END}_IGNORE are available to get rid of compilation error with libedit. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_2@30569 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/readline/extconf.rb6
-rw-r--r--ext/readline/readline.c99
2 files changed, 105 insertions, 0 deletions
diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb
index 14c2099b6d..5dc7a6a3ae 100644
--- a/ext/readline/extconf.rb
+++ b/ext/readline/extconf.rb
@@ -19,6 +19,10 @@ def have_readline_func(func)
return have_func(func, $readline_headers)
end
+def have_readline_macro(macro)
+ return have_macro(macro, $readline_headers)
+end
+
dir_config('curses')
dir_config('ncurses')
dir_config('termcap')
@@ -76,4 +80,6 @@ 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_macro("RL_PROMPT_START_IGNORE")
+have_readline_macro("RL_PROMPT_END_IGNORE")
create_makefile("readline")
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 2963fa2dfc..dccfe5e8b0 100644
--- a/ext/readline/readline.c
+++ b/ext/readline/readline.c
@@ -43,10 +43,20 @@
static VALUE mReadline;
#define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
+#ifndef USE_INSERT_IGNORE_ESCAPE
+# if !defined(HAVE_EDITLINE_READLINE_H) && defined(HAVE_RL_PROMPT_START_IGNORE) && defined(HAVE_RL_PROMPT_END_IGNORE)
+# define USE_INSERT_IGNORE_ESCAPE 1
+# else
+# define USE_INSERT_IGNORE_ESCAPE 0
+# endif
+#endif
#define COMPLETION_PROC "completion_proc"
#define COMPLETION_CASE_FOLD "completion_case_fold"
static ID completion_proc, completion_case_fold;
+#if USE_INSERT_IGNORE_ESCAPE
+static ID id_orig_prompt, id_last_prompt;
+#endif
#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
# define rl_filename_completion_function filename_completion_function
@@ -141,6 +151,81 @@ readline_event(void)
}
#endif
+#if USE_INSERT_IGNORE_ESCAPE
+static VALUE
+insert_ignore_escape(VALUE self, VALUE prompt)
+{
+ VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt);
+ int ignoring = 0;
+ const char *s0, *s, *e;
+ long len;
+ static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
+
+ prompt = rb_str_new_shared(prompt);
+ last_prompt = rb_attr_get(self, id_last_prompt);
+ if (orig_prompt == prompt) return last_prompt;
+ len = RSTRING_LEN(prompt);
+ if (NIL_P(last_prompt)) {
+ last_prompt = rb_str_tmp_new(len);
+ }
+
+ s = s0 = RSTRING_PTR(prompt);
+ e = s0 + len;
+ rb_str_set_len(last_prompt, 0);
+ while (s < e && *s) {
+ switch (*s) {
+ case RL_PROMPT_START_IGNORE:
+ ignoring = -1;
+ rb_str_cat(last_prompt, s0, ++s - s0);
+ s0 = s;
+ break;
+ case RL_PROMPT_END_IGNORE:
+ ignoring = 0;
+ rb_str_cat(last_prompt, s0, ++s - s0);
+ s0 = s;
+ break;
+ case '\033':
+ if (++s < e && *s == '[') {
+ rb_str_cat(last_prompt, s0, s - s0 - 1);
+ s0 = s - 1;
+ while (++s < e && *s) {
+ if (ISALPHA(*s)) {
+ if (!ignoring) {
+ ignoring = 1;
+ rb_str_cat(last_prompt, ignore_code+0, 1);
+ }
+ rb_str_cat(last_prompt, s0, ++s - s0);
+ s0 = s;
+ break;
+ }
+ else if (!('0' <= *s && *s <= '9' || *s == ';')) {
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ if (ignoring > 0) {
+ ignoring = 0;
+ rb_str_cat(last_prompt, ignore_code+1, 1);
+ }
+ s++;
+ break;
+ }
+ }
+ if (ignoring > 0) {
+ ignoring = 0;
+ rb_str_cat(last_prompt, ignore_code+1, 1);
+ }
+ rb_str_cat(last_prompt, s0, s - s0);
+
+ rb_ivar_set(self, id_orig_prompt, prompt);
+ rb_ivar_set(self, id_last_prompt, last_prompt);
+
+ return last_prompt;
+}
+#endif
+
static VALUE
readline_get(VALUE prompt)
{
@@ -244,6 +329,10 @@ readline_readline(int argc, VALUE *argv, VALUE self)
rb_secure(4);
if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
OutputStringValue(tmp);
+#if USE_INSERT_IGNORE_ESCAPE
+ tmp = insert_ignore_escape(self, tmp);
+ rb_str_locktmp(tmp);
+#endif
prompt = RSTRING_PTR(tmp);
}
@@ -253,6 +342,11 @@ readline_readline(int argc, VALUE *argv, VALUE self)
rl_prep_terminal(1);
#endif
buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status);
+#if USE_INSERT_IGNORE_ESCAPE
+ if (prompt) {
+ rb_str_unlocktmp(tmp);
+ }
+#endif
if (status) {
#if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
/* restore terminal mode and signal handler*/
@@ -1377,6 +1471,11 @@ Init_readline()
rb_define_singleton_method(mReadline, "refresh_line",
readline_s_refresh_line, 0);
+#if USE_INSERT_IGNORE_ESCAPE
+ CONST_ID(id_orig_prompt, "orig_prompt");
+ CONST_ID(id_last_prompt, "last_prompt");
+#endif
+
history = rb_obj_alloc(rb_cObject);
rb_extend_object(history, rb_mEnumerable);
rb_define_singleton_method(history,"to_s", hist_to_s, 0);