[pure-lang-svn] SF.net SVN: pure-lang: [232] pure/trunk/lexer.ll
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-06-14 20:10:18
|
Revision: 232 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=232&view=rev Author: agraef Date: 2008-06-14 13:10:24 -0700 (Sat, 14 Jun 2008) Log Message: ----------- Add completion_matches command. Modified Paths: -------------- pure/trunk/lexer.ll Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-06-14 19:37:36 UTC (rev 231) +++ pure/trunk/lexer.ll 2008-06-14 20:10:24 UTC (rev 232) @@ -122,6 +122,83 @@ { return s.sym->s < t.sym->s; } + +/* This is a watered-down version of the command completion routine from + pure.cc, used to implement the completion_matches command used by + pure-mode.el. This isn't perfect, since it will also complete command names + when not at the beginning of the line, but since the location inside the + line isn't passed to completion_matches, it's the best that we can do right + now. */ + +static const char *commands[] = { + "cd", "clear", "extern", "help", "infix", "infixl", "infixr", "let", "list", + "ls", "nullary", "override", "postfix", "prefix", "pwd", "quit", "run", + "save", "stats", "underride", "using", 0 +}; + +static char * +command_generator(const char *text, int state) +{ + static int list_index, len; + static env::iterator it, end; + const char *name; + + /* New match. */ + if (!state) { + list_index = 0; + assert(interpreter::g_interp); + it = interpreter::g_interp->globenv.begin(); + end = interpreter::g_interp->globenv.end(); + len = strlen(text); + } + + /* Return the next name which partially matches from the + command list. */ + while ((name = commands[list_index])) { + list_index++; + if (strncmp(name, text, len) == 0) + return strdup(name); + } + + /* Return the next name which partially matches from the + symbol list. */ + while (it != end) { + assert(it->first > 0); + symbol& sym = interpreter::g_interp->symtab.sym(it->first); + it++; + if (strncmp(sym.s.c_str(), text, len) == 0) + return strdup(sym.s.c_str()); + } + + /* If no names matched, then return NULL. */ + return 0; +} + +static char ** +pure_completion(const char *text, int start, int end) +{ + return rl_completion_matches(text, command_generator); +} + +static void list_completions(const char *s) +{ + char **matches = pure_completion(s, 0, strlen(s)); + if (matches) { + if (matches[0]) + if (!matches[1]) { + printf("%s\n", matches[0]); + free(matches[0]); + } else { + int i; + free(matches[0]); + for (i = 1; matches[i]; i++) { + printf("%s\n", matches[i]); + free(matches[i]); + } + } + free(matches); + } +} %} %option noyywrap nounput debug @@ -593,6 +670,15 @@ else exit(0); } +^completion_matches.* { + // completion_matches command is only permitted in interactive mode + if (!interp.interactive) REJECT; + const char *s = yytext+18; + if (*s && !isspace(*s)) REJECT; + while (isspace(*s)) ++s; + yylloc->step(); + list_completions(s); +} {int} { mpz_t *z = (mpz_t*)malloc(sizeof(mpz_t)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |