aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.old6
-rw-r--r--cmd.c20
-rw-r--r--edit.c67
-rw-r--r--edit.h2
-rw-r--r--powwow.help19
-rw-r--r--utils.c24
6 files changed, 109 insertions, 29 deletions
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 <static-completions}
+
+If the 'static-completions' file contains a number of #addstatic
+commands, all those words will always be possible to Tab-complete on.
+
@option
#option [+-=]<option> | 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");