1

タブ補完を機能させようとしています..私は非常に混乱しており、何をすべきかわかりません。私のコードを見て、どうすれば修正できるか教えてください。

ちなみにrl_attempted_completion_functionオンラインチュートリアルで入手したので使っていますが、C++の関数です。変更せずに置き換えるには、どの関数を使用できますか。

ありがとう

   static char** completion( const char * text , int start,  int end){
            char **matches;
            matches = (char **)NULL;

            if (start == 0)
                    matches = rl_completion_matches ((char*)text, &generator);

            return (matches);
    }

    char* generator(const char* text, int state) {
            int index, len;
            char *comm;
            if (!state) {
                    index = 0;
                    len = (int)strlen (text);
            }

            while ( (*comm = newEnv[index])) {
                    index++;
                    if (strncmp (comm, text, len) == 0)
                            return ((comm));
            }
            return NULL;
    }

    int main (int argc,  char * argv[]) {

            using_history();
            rl_readline_name = basename(argv[0]);

            rl_attempted_completion_function = completion;

            while ( readline(">> ")!= NULL )  
                    rl_bind_key('\t',rl_complete);

            return 0;
    }
4

3 に答える 3

2

私はこれに気づきます:

char *comm;
...
while ( (*comm = newEnv[index])) {

の戻り値の型が何であるかはわかりませんが、何も指していないので、 ではなくnewEnvに入れたいと思うでしょう。comm*commcomm

于 2011-08-30T01:20:18.833 に答える
1

あなたのコードは、readline マニュアルの例と非常によく似ています。私が見るバグは、ジェネレーター関数で index と len をstaticと宣言していないことです。

于 2015-06-19T22:41:25.620 に答える
0

Tom Zych からの一番の回答で述べたように、次のように変更*comm = newEnv[index]する必要があります。comm = newEnv[index]

しかし、このままでは他にもいくつかの問題があります

1 つは、次の 2 つの変数を静的にする必要があることです。

int index, len;

そのように: static int index, len;

そうしないと、常に最初の一致が返されます (一致した場合、無限ループに陥る可能性があると思います)。これらを静的にすると、ゼロ以外の状態の後続の呼び出しが最後の一致から始まる一致を探すようになります。私が正しく理解していれば、各タブ補完リクエストの最初の補完候補検索で 0 の状態が得られます (これにより、静的インデックスが 0 にリセットされます)。

状態が 0 になったときに入力の長さだけを探すのは最適化ですが (同じ入力を取得するので、それを「キャッシュ」することができます)、静的インデックスはそうではありません: 必要です

次に、変更する必要があります

return ((comm));

return strdup(comm);

最後に、補完を次のように変更します。

char **completion(const char *text, int start, int end)
{
    return rl_completion_matches(text, generator);
}

0 開始チェックは必要ありません

また、次のように、newEnv 配列の末尾に NULL 値があることを確認してください。

char* envVar[] = {"a", "b", NULL};

余談ですがgenerator、内部で使用する前に、前方宣言または定義していることを確認してくださいcompletion

于 2020-09-18T21:40:17.703 に答える