From: Nobuhiro IMAI Date: 2011-04-30T14:40:07+09:00 Subject: [ruby-dev:43459] Re: Readline.completion_append_character ----Next_Part(Sat_Apr_30_14_40_05_2011_245)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit いまいです。 From: Takao Kouji Date: Sat, 30 Apr 2011 13:35:51 +0900 > 高尾です。 > >> GNU readline library での話ですが、6 系のものを使うと TAB キーでの補完 >> 後に Readline.completion_append_character がデフォルトの " " に戻ってし >> まいます。しかも、" " 以外にセットしても、補完された単語にはデフォルト >> の " " が付加されます。 > (省略) >> changelog に以下のように書いてあって、補完後にリセットされるのは意図的 >> なようです。Ruby の readline 側で何とかならないものでしょうか? > > 上記に関して確認させてください。 > > Readlineについて、いまいさんから2つの相談があったと認識しています。 はい。 > 1)GNU Readline 6の場合にReadline.completion_append_characterにnilを指定できない不具合がある > > nilをセットしても補完後にスペースが追加される問題ですね。 > こちらは原因を調査して対応したほうがよいと考えています。 そうですね。セットできないというか、セットしても効果が得られないと言う 感じです。nil に限らず、何をセットしても一度補完してしまうとデフォル ト値にリセットされてしまいます。 > 2)GNU Readline 6の場合でも5以前と同様の動作にしてほしい > > GNU Readline 6では、補完後にReadline.completion_append_characterがデ > フォルト値へリセットされるので、5以前と同様にリセットされないように > してほしいことで間違いないでしょうか。こちらについては、私はGNU > Readlineでそのような挙動なのであればそれに従ったほうがよいと思ってい > ます。GNU Readline本体では、何かしらの理由があってその方がよいと考え > て修正したのではないでしょうか。その恩恵を受けられる方がよいのではな > いでしょうか。それが問題であればGNU Readline本体を修正してもらう方が > よいと思います。 推測ですが、changelog を読む限り、GNU readline を利用するアプリケーショ ン側で rl_completion_append_character を変更すると、ライブラリ側で何か 問題が生じるので、補完する度にリセットするようになったのだと認識してい ます。必要に応じて、補完する関数(rl_attempted_completion_function か な?)を呼び出す度にアプリケーション側で rl_completion_append_character をセットしてね、ということなんじゃないでしょうか。 影響範囲がよく分かっていませんが、Ruby の readline 側で rl_completion_append_character 相当のものを保持しておいて、補完する時 にセットしてやればいいのではないでしょうか? やってみたら何か動いてそう、というレベルのものですが、参考までにパッチ を付けてみます。Ruby のスクリプトから readline.so を使う限りはこれでよ さそうですが、拡張ライブラリから直接 rl_completion_append_character を いじるようなことがある(のかどうかは分かってません)と破綻しちゃいそうです。 -- Nobuhiro IMAI Key fingerprint = E57F 2482 4074 13BC 3B9A 165B C689 5B16 A620 4657 ----Next_Part(Sat_Apr_30_14_40_05_2011_245)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="readline_completion_append_character.patch" diff --git a/ext/readline/readline.c b/ext/readline/readline.c index a313271..05bba2a 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -69,6 +69,9 @@ static ID id_orig_prompt, id_last_prompt; #endif static int (*history_get_offset_func)(int); +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER +static int readline_completion_append_character; +#endif static char **readline_attempted_completion_function(const char *text, int start, int end); @@ -561,6 +564,9 @@ readline_attempted_completion_function(const char *text, int start, int end) proc = rb_attr_get(mReadline, completion_proc); if (NIL_P(proc)) return NULL; +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + rl_completion_append_character = readline_completion_append_character; +#endif #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER rl_attempted_completion_over = 1; #endif @@ -800,14 +806,14 @@ readline_s_set_completion_append_character(VALUE self, VALUE str) { rb_secure(4); if (NIL_P(str)) { - rl_completion_append_character = '\0'; + readline_completion_append_character = '\0'; } else { OutputStringValue(str); if (RSTRING_LEN(str) == 0) { - rl_completion_append_character = '\0'; + readline_completion_append_character = '\0'; } else { - rl_completion_append_character = RSTRING_PTR(str)[0]; + readline_completion_append_character = RSTRING_PTR(str)[0]; } } return self; @@ -834,10 +840,10 @@ readline_s_get_completion_append_character(VALUE self) char buf[1]; rb_secure(4); - if (rl_completion_append_character == '\0') + if (readline_completion_append_character == '\0') return Qnil; - buf[0] = (char) rl_completion_append_character; + buf[0] = (char) readline_completion_append_character; return rb_locale_str_new(buf, 1); } #else @@ -1568,6 +1574,9 @@ Init_readline() #ifdef HAVE_RL_CLEAR_SIGNALS rl_clear_signals(); #endif +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + readline_completion_append_character = rl_completion_append_character; +#endif readline_s_set_input(mReadline, rb_stdin); } ----Next_Part(Sat_Apr_30_14_40_05_2011_245)----