From 2a5b0cabaa1b2aba86e466cdc25486fa4c86e6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20H=C3=A5llberg?= Date: Sat, 17 Jan 2009 00:48:31 +0100 Subject: added #addstatic command Replaced old WORD_RETAIN function with separate, static list of words. diff --git a/ChangeLog.old b/ChangeLog.old index d228e5d..db6a835 100644 --- a/ChangeLog.old +++ b/ChangeLog.old @@ -1,3 +1,9 @@ +2009-01-05 dain + + * cmd.c, edit.c, edit.h, powwow.help, utils.c: Added an + '#addstatic' command to add permanent entries into the word + Tab-completion list. These words are not saved by #save. + 2008-12-31 dain * cmd.c: Added '#option list' to print all options and explanatory diff --git a/cmd.c b/cmd.c index f15bf5c..5a71442 100644 --- a/cmd.c +++ b/cmd.c @@ -47,8 +47,8 @@ /* local function declarations */ #define _ __P ((char *arg)) -static void cmd_help _, cmd_shell _, - cmd_action _, cmd_add _, cmd_alias _, cmd_at _, cmd_beep _, cmd_bind _, +static void cmd_help _, cmd_shell _, cmd_action _, cmd_add _, + cmd_addstatic _, cmd_alias _, cmd_at _, cmd_beep _, cmd_bind _, cmd_cancel _, cmd_capture _, cmd_clear _, cmd_connect _, cmd_cpu _, cmd_do _, cmd_delim _, cmd_edit _, cmd_emulate _, cmd_exe _, cmd_file _, cmd_for _, cmd_hilite _, cmd_history _, cmd_host _, @@ -91,6 +91,8 @@ cmdstruct default_commands[] = "\t\t\t\tdelete/list/define actions"), C("add", cmd_add, "{string|(expr)}\t\tadd the string to word completion list"), + C("addstatic", cmd_addstatic, + "{string|(expr)}\t\tadd the string to the static word completion list"), C("alias", cmd_alias, "[name[=[text]]]\t\tdelete/list/define aliases"), C("at", cmd_at, @@ -2670,7 +2672,7 @@ static char *trivial_eval __P3 (ptr *,pbuf, char *,arg, char *,name) return arg; } -static void cmd_add __P1 (char *,arg) +static void do_cmd_add __P2(char *,arg, int,is_static) { ptr pbuf = (ptr)0; char buf[BUFSIZE]; @@ -2680,11 +2682,21 @@ static void cmd_add __P1 (char *,arg) while (*arg) { arg = split_first_word(buf, BUFSIZE, arg); if (strlen(buf) >= MIN_WORDLEN) - put_word(buf); + (is_static ? put_static_word : put_word)(buf); } ptrdel(pbuf); } +static void cmd_add __P1 (char *,arg) +{ + do_cmd_add(arg, 0); +} + +static void cmd_addstatic __P1 (char *,arg) +{ + do_cmd_add(arg, 1); +} + static void cmd_put __P1 (char *,arg) { ptr pbuf = (ptr)0; diff --git a/edit.c b/edit.c index ba283ee..8f4a052 100644 --- a/edit.c +++ b/edit.c @@ -442,13 +442,41 @@ static void demote_word __P1 (int,i) words[wordindex].prev = words[words[wordindex].prev].next = i; } +static struct { + int size, used; + char **words; +} static_words; + +static int compl_next_word __P1 (int,i) +{ + if (i < 0) { + go_static: + --i; + if (-i - 1 >= static_words.used) + i = wordindex; + } else { + i = words[i].next; + if (i == wordindex || words[i].word == NULL) { + i = 0; + goto go_static; + } + } + return i; +} + +static char *compl_get_word __P1 (int,i) +{ + return i < 0 ? static_words.words[-i - 1] : words[i].word; +} + /* * match and complete a word referring to the word list */ void complete_word __P1 (char *,dummy) { /* - * GH: rewritten to allow circulating through history with repetitive command + * GH: rewritten to allow circulating through history with + * repetitive command * code stolen from cancan 2.6.3a * curr_word: index into words[] * comp_len length of current completition @@ -477,7 +505,7 @@ void complete_word __P1 (char *,dummy) /* k = chars to delete, n = position of starting word */ /* scan word list for next match */ - while ((p = words[curr_word = words[curr_word].next].word)) { + while ((p = compl_get_word(curr_word = compl_next_word(curr_word)))) { if (!strncasecmp(p, root, root_len) && *(p += root_len) && (n = strlen(p)) + edlen < BUFSIZE) { @@ -493,7 +521,8 @@ void complete_word __P1 (char *,dummy) input_delete_nofollow_chars(k); /* delete duplicate instances of the word */ - if (p && !(words[k = curr_word].flags & WORD_UNIQUE)) { + if (p && curr_word >= 0 + && !(words[k = curr_word].flags & WORD_UNIQUE)) { words[k].flags |= WORD_UNIQUE; p = words[k].word; n = words[k].next; @@ -555,21 +584,38 @@ static void default_completions __P0 (void) char buf[BUFSIZE]; cmdstruct *p; int i; - /* TODO: add some way to handle new commands going in the default completions list */ + /* TODO: add some way to handle new commands going in the default + * completions list */ for (i = 0, buf[0] = '#', p = commands; p != NULL; p = p -> next) - if (p->funct /*&& strlen(p->name) >= 3*/ ) { - if (++i >= MAX_WORDS) break; + if (p->funct) { strcpy(buf + 1, p->name); - if (!(words[i].word = my_strdup(buf))) - syserr("malloc"); - words[i].flags = WORD_UNIQUE | WORD_RETAIN; + put_static_word(buf); } + /* init 'words' double-linked list */ for (i = MAX_WORDS; i--; words[i].prev = i - 1, words[i].next = i + 1) ; words[0].prev = MAX_WORDS - 1; words[MAX_WORDS - 1].next = 0; } +void put_static_word __P1 (char *,s) +{ + if (static_words.used >= static_words.size) { + do { + static_words.size = static_words.size ? static_words.size * 2 : 16; + } while (static_words.used >= static_words.size); + static_words.words = realloc(static_words.words, + sizeof static_words.words[0] + * static_words.size); + } + + if ((s = my_strdup(s)) == NULL) { + errmsg("malloc"); + return; + } + static_words.words[static_words.used++] = s; +} + /* * put word in word completion ring */ @@ -581,8 +627,7 @@ void put_word __P1 (char *,s) return; } words[r].flags = 0; - while (words[r = words[r].prev].flags & WORD_RETAIN) - ; + r = words[r].prev; demote_word(r); wordindex = r; if (words[r].word) { diff --git a/edit.h b/edit.h index a81b97c..e49cea2 100644 --- a/edit.h +++ b/edit.h @@ -18,7 +18,6 @@ extern edit_function internal_functions[]; * words[wordindex].next is 2nd (first to search for completion) */ #define WORD_UNIQUE 1 /* word is unique in list */ -#define WORD_RETAIN 2 /* permanent (#command) */ typedef struct { char *word; int next, prev; @@ -54,6 +53,7 @@ void put_history __P ((char *str)); void complete_word __P ((char *dummy)); void complete_line __P ((char *dummy)); void put_word __P ((char *s)); +void put_static_word __P ((char *s)); void set_custom_delimeters __P ((char *s)); void to_input_line __P ((char *str)); void clear_line __P ((char *dummy)); diff --git a/powwow.help b/powwow.help index 5381235..82c7399 100644 --- a/powwow.help +++ b/powwow.help @@ -297,6 +297,25 @@ expression) to the word completion list. Example: #action >reply ^$1 tells you={#print;#add $1} (from now on, you can use TAB to complete that name) +@addstatic +#addstatic {text|(expression)} + +Add the text or result of expression (calculator is used to evaluate the +expression) to the static word completion list. Example: + +#addstatic Tintin Milou (from now on you can always use Tab to complete + these two names) + +Note that the static list is not saved when you run #save, and its +words will never be overwritten as new words are added. + +It is best used from your #init command, for example: + +#init ={#identify;#exe | list diff --git a/utils.c b/utils.c index b904c1f..58478c7 100644 --- a/utils.c +++ b/utils.c @@ -1211,19 +1211,17 @@ int save_settings __P0 (void) while (words[l = words[l].next].word) ; while (words[l = words[l].prev].word && failed > 0) { - if (~words[l].flags & WORD_RETAIN) { - pp = ptrmescape(pp, words[l].word, strlen(words[l].word), 0); - len = ptrlen(pp) + 1; - if (cl > 4 && cl + len >= 80) { - cl = 4; - failed = fprintf(f, "\n"); - flag = 0; - } - if (failed > 0) - failed = fprintf(f, "%s %s", flag ? "" : "#add", ptrdata(pp)); - cl += len; - flag = 1; - } + pp = ptrmescape(pp, words[l].word, strlen(words[l].word), 0); + len = ptrlen(pp) + 1; + if (cl > 4 && cl + len >= 80) { + cl = 4; + failed = fprintf(f, "\n"); + flag = 0; + } + if (failed > 0) + failed = fprintf(f, "%s %s", flag ? "" : "#add", ptrdata(pp)); + cl += len; + flag = 1; } if (failed > 0 && flag) failed = fprintf(f, "\n"); -- cgit v0.10.2