Tab Completion in C (readline library)
I have been trying to get tab completion working.. I am very confused and don't know what to do. Could you please take a look at my code and tell me how I could possibly fix it.
By the way I used rl_attempted_completion_function
since I got it from an online tutorial but it is an C++ function. What functio开发者_运维百科n can I use to replace it without making changes.
Thanks
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;
}
I notice this:
char *comm;
...
while ( (*comm = newEnv[index])) {
I don't know what the return type of newEnv
is, but you probably want to put it in comm
, not *comm
, because you didn't point comm
at anything.
Your code is very similar to an example in the readline manual. The bug I see is that you have not declared index and len in the generator function to be static.
As mentioned in the top answer from Tom Zych, you should change *comm = newEnv[index]
to comm = newEnv[index]
But I also see a couple other problems with this as-is
For one, these two variables should be static:
int index, len;
Like so: static int index, len;
Otherwise, you are always returning the first match (And I think you might end up with an infinite loop if there is a match). Making these static makes it so that subsequent calls for a non zero state look for matches starting from the last match. You will get a state of 0 for the first completion suggestion search of each tab completion request, if I'm understanding correctly (Which will reset the static index to 0)
Only looking for the length of the input when you get a state of 0 is an optimization (Since you will get the same input, you can sort of "cache" it), but the static index is not: It is required
Next, you should change
return ((comm));
To
return strdup(comm);
And finally, change completion to:
char **completion(const char *text, int start, int end)
{
return rl_completion_matches(text, generator);
}
The 0 start check is not needed
Also, make sure your newEnv array has a NULL value at the end, like so:
char* envVar[] = {"a", "b", NULL};
As an aside, make sure you're forward declaring or defining generator
before you use it within completion
精彩评论