動作することがわかっているカスタム補完スクリプトを試して(毎日使用しています)、同じ問題に遭遇した後 (あなたのものと同じように装備したとき)、bash 4.1 のソースを調べてみることにしましたbash-4.1/builtins/read.def:edit_line()
。
old_attempted_completion_function = rl_attempted_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
if (itext)
{
old_startup_hook = rl_startup_hook;
rl_startup_hook = set_itext;
deftext = itext;
}
ret = readline (p);
rl_attempted_completion_function = old_attempted_completion_function;
old_attempted_completion_function = (rl_completion_func_t *)NULL;
beforereadline()
が呼び出されると、何らかの理由で完了関数が null にリセットされるようです。これは、bash ハッキングの長いひげだけが知っている可能性があります。したがって、read
ビルトインでこれを行うと、単にハードコードされて無効になる場合があります。
編集:これについてもう少し:read
組み込みの完了を停止するラッピングコードは、bash-2.05a と bash-2.05b の間で発生しました。そのバージョンのbash-2.05b/CWRU/changelog
ファイルで次のメモを見つけました。
- edit_line (read -e によって呼び出される) は、rl_attempted_completion_function を NULL に設定することで readline のファイル名補完を行うようになりました。
これは従来の見落としだと思います。プログラム可能な補完は長い道のりを歩んできましたので、あなたがやっていることは役に立ちます。たぶん、あなたがやっていることでそれが実現可能であれば、彼らにそれを追加するか、自分でパッチを当てるように頼むことができます.
残念ながら、これまでに思いついたもの以外に別の解決策はありませんが、少なくともそれが で機能しない理由read
はわかっています。
EDIT2:そうです、これは私がテストしたばかりのパッチで、「機能する」ようです。すべての単体テストと登録テストに合格し、パッチを適用した bash を使用してスクリプトを実行すると、期待どおりに次の出力が表示されます。
$ ./tabcompl.sh
waiting for commands
-> **<TAB>**
TAB hit output should these this when words you
->
ご覧のとおり、これらの 4 行とタイマー コードをコメント アウトして、rl_attempted_completion_function
いつread -t
指定されたかをリセットし、タイムアウトが発生しましたが、これは不要になりました。Chet に何かを送信する場合は、rl_attempted_completion_function
最初にジャンク全体を削除することをお勧めしますが、これにより、少なくともスクリプトが適切に動作できるようになります。
パッチ:
--- bash-4.1/builtins/read.def 2009-10-09 00:35:46.000000000 +0900
+++ bash-4.1-patched/builtins/read.def 2011-01-20 07:14:43.000000000 +0900
@@ -394,10 +394,12 @@
}
old_alrm = set_signal_handler (SIGALRM, sigalrm);
add_unwind_protect (reset_alarm, (char *)NULL);
+/*
#if defined (READLINE)
if (edit)
add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
#endif
+*/
falarm (tmsec, tmusec);
}
@@ -914,8 +916,10 @@
if (bash_readline_initialized == 0)
initialize_readline ();
+/*
old_attempted_completion_function = rl_attempted_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
+*/
if (itext)
{
old_startup_hook = rl_startup_hook;
@@ -923,8 +927,10 @@
deftext = itext;
}
ret = readline (p);
+/*
rl_attempted_completion_function = old_attempted_completion_function;
old_attempted_completion_function = (rl_completion_func_t *)NULL;
+*/
if (ret == 0)
return ret;
パッチを適用した bash は、スクリプトを使用する場所に配布するか、何らかの方法で利用できるようにする必要があることに注意してください...