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:
parent
d3b337c58d
commit
38f5ffefe1
2 changed files with 105 additions and 0 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue