Input history deduplication

If the entered input is the same as the previous item in the history,
the history remains unmodified. If the item was seen previously, history
is re-arranged to bring that item to the front.
This commit is contained in:
Peter Farley 2024-11-10 10:38:20 -06:00
commit 7a612b8a0c

View file

@ -466,6 +466,55 @@ ingest_thread(void *arg)
return NULL; return NULL;
} }
/* Add an item to the input history, doing nothing if the line is the same as
* the previous, and re-arranging history if the line was seen previously. */
static void
history_add(const char *line)
{
ingest.history_pos = ingest.history_len;
if (*line == '\0') {
/* Line is empty. */
return;
}
if (ingest.history_len != 0) {
if (!strcmp(ingest.history[ingest.history_len - 1], line)) {
/* Line is a repeat of the previous history item. */
return;
}
for (unsigned i = 0; i < ingest.history_len - 1; i++) {
if (!strcmp(ingest.history[i], line)) {
/* Re-arrange history to move item to the front */
char *history_item = ingest.history[i];
memcpy(&ingest.history[i], &ingest.history[i+1],
(ingest.history_len - (i + 1)) * sizeof(ingest.history[0]));
ingest.history[ingest.history_len - 1] = history_item;
if (ingest.history_fd) {
fseek(ingest.history_fd, 0, SEEK_SET);
for (unsigned i = 0; i < ingest.history_len; i++) {
fwrite(ingest.history[i], 1, strlen(ingest.history[i]), ingest.history_fd);
fwrite("\n", 1, 1, ingest.history_fd);
}
}
return;
}
}
}
ingest.history_len++;
ingest.history = realloc(ingest.history, ingest.history_len * sizeof(char *));
ingest.history[ingest.history_pos] = strdup(ingest.inbuf);
ingest.history_pos++;
if (ingest.history_fd) {
fwrite(line, 1, strlen(line), ingest.history_fd);
fwrite("\n", 1, 1, ingest.history_fd);
}
}
static int static int
mode_normal(int ch) mode_normal(int ch)
{ {
@ -492,17 +541,7 @@ mode_normal(int ch)
} }
/* store in history */ /* store in history */
ingest.history_pos = ingest.history_len; history_add(ingest.inbuf);
if (ingest.inlen > 0) {
ingest.history_len++;
ingest.history = realloc(ingest.history, ingest.history_len * sizeof(char *));
ingest.history[ingest.history_pos] = strdup(ingest.inbuf);
ingest.history_pos++;
if (ingest.history_fd) {
fwrite(ingest.inbuf, 1, strlen(ingest.inbuf), ingest.history_fd);
fwrite("\n", 1, 1, ingest.history_fd);
}
}
memset(ingest.inbuf, 0, sizeof(ingest.inbuf)); memset(ingest.inbuf, 0, sizeof(ingest.inbuf));
ingest.inpos = 0; ingest.inpos = 0;