GNU readline
时间:2009-03-15 来源:yanghoo
GNU readline implement filename auto-complete by default, it will list all the files in the current directory. We can disable it by binds our TAB key to some other operation. In previous post, I simply abort the operation to ignore users hitting TABs.
Auto-complete are useful if only we can customize it. Well, readline allows us do it by assign our own callback functions. First of all, you may want to read up the manual from HERE. It does provides a c sample codes as well but I find it too complicated, here I provide a simplified version that can be compiled under c++.
view plainprint?
- #include <stdio.h>
- #include <stdlib.h>
- #include <readline/readline.h>
- #include <readline/history.h>
- static char** my_completion(const char*, int ,int);
- char* my_generator(const char*,int);
- char * dupstr (char*);
- void *xmalloc (int);
- char* cmd [] ={ "hello", "world", "hell" ,"word", "quit", " " };
- int main()
- {
- char *buf;
- rl_attempted_completion_function = my_completion;
- while((buf = readline("\n >> "))!=NULL) {
- //enable auto-complete
- rl_bind_key('\t',rl_complete);
- printf("cmd [%s]\n",buf);
- if (strcmp(buf,"quit")==0)
- break;
- if (buf[0]!=0)
- add_history(buf);
- }
- free(buf);
- return 0;
- }
- static char** my_completion( const char * text , int start, int end)
- {
- char **matches;
- matches = (char **)NULL;
- if (start == 0)
- matches = rl_completion_matches ((char*)text, &my_generator);
- else
- rl_bind_key('\t',rl_abort);
- return (matches);
- }
- char* my_generator(const char* text, int state)
- {
- static int list_index, len;
- char *name;
- if (!state) {
- list_index = 0;
- len = strlen (text);
- }
- while (name = cmd[list_index]) {
- list_index++;
- if (strncmp (name, text, len) == 0)
- return (dupstr(name));
- }
- /* If no names matched, then return NULL. */
- return ((char *)NULL);
- }
- char * dupstr (char* s) {
- char *r;
- r = (char*) xmalloc ((strlen (s) + 1));
- strcpy (r, s);
- return (r);
- }
- void * xmalloc (int size)
- {
- void *buf;
- buf = malloc (size);
- if (!buf) {
- fprintf (stderr, "Error: Out of memory. Exiting.'n");
- exit (1);
- }
- return buf;
- }
-
http://www.math.utah.edu/docs/info/rlman_2.html#SEC36
相关阅读 更多 +