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: apply a patch from Nobuyoshi Nakada.

fixed #3616 [ruby-core:31484] IRB + readline incorrectly counts
  non-printing characters in prompt


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30496 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
kouji 2011-01-09 05:54:33 +00:00
parent d3b337c58d
commit 38f5ffefe1
2 changed files with 105 additions and 0 deletions

View file

@ -1,3 +1,9 @@
Sun Jan 9 14:47:50 2011 TAKAO Kouji <kouji@takao7.net>
* ext/readline/readline.c: apply a patch from Nobuyoshi Nakada.
fixed #3616 [ruby-core:31484] IRB + readline incorrectly counts
non-printing characters in prompt
Sat Jan 8 21:47:26 2011 Tanaka Akira <akr@fsij.org>
* enum.c (enum_sort_by): use rb_ary_resize.

View file

@ -43,10 +43,20 @@
static VALUE mReadline;
#define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
#ifndef USE_INSERT_IGNORE_ESCAPE
# ifndef HAVE_EDITLINE_READLINE_H
# 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
@ -145,6 +155,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)
{
@ -248,6 +333,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);
}
@ -257,6 +346,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*/
@ -1383,6 +1477,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);