Skip to content

Commit 32d1a53

Browse files
committed
Insert new choices after previously matched ones
If the user already has supplied a query that yields M (where M > 0) matches, inserting the K newly read choices after index M only requires searching through M + K choices instead of N (where N being all choices). This improves performance when the user types a query faster than the input pace on stdin.
1 parent 90530a8 commit 32d1a53

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

pick.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static const char *choice_string(const struct choice *);
7676
static void delete_between(char *, size_t, size_t, size_t);
7777
static char *eager_strpbrk(const char *, const char *);
7878
static int filter_choices(size_t);
79-
static size_t get_choices(int);
79+
static size_t get_choices(int, size_t);
8080
static enum key get_key(const char **);
8181
static void handle_sigwinch(int);
8282
static int isu8cont(unsigned char);
@@ -224,14 +224,16 @@ usage(int status)
224224
}
225225

226226
size_t
227-
get_choices(int fd)
227+
get_choices(int fd, size_t insert)
228228
{
229229
static const char *ifs;
230230
static char *buf;
231231
static size_t length, offset;
232232
static size_t size = BUFSIZ;
233+
struct choice *new, *old, tmp;
233234
char *desc, *start, *stop;
234235
ssize_t n;
236+
size_t dchoices, i, nchoices;
235237

236238
if (ifs == NULL && ((ifs = getenv("IFS")) == NULL || *ifs == '\0'))
237239
ifs = " ";
@@ -256,6 +258,7 @@ get_choices(int fd)
256258
choices.size = 16;
257259
}
258260

261+
nchoices = choices.length;
259262
start = buf + offset;
260263
while ((stop = strchr(start, '\n')) != NULL) {
261264
*stop = '\0';
@@ -287,6 +290,18 @@ get_choices(int fd)
287290
start = stop + 1;
288291
}
289292
offset = start - buf;
293+
dchoices = choices.length - nchoices;
294+
if (dchoices == 0 || nchoices == 0)
295+
return n;
296+
297+
/* Move new choices after the given insert index. */
298+
for (i = 0; i < dchoices; i++) {
299+
old = choices.v + insert + i;
300+
new = choices.v + nchoices + i;
301+
tmp = *new;
302+
*new = *old;
303+
*old = tmp;
304+
}
290305

291306
return n;
292307
}
@@ -353,9 +368,15 @@ selected_choice(void)
353368

354369
length = choices.length;
355370
if (doread) {
356-
if (get_choices(STDIN_FILENO)) {
357-
if (query_length > 0)
371+
if (get_choices(STDIN_FILENO, choices_count)) {
372+
if (query_length > 0) {
358373
dofilter = 1;
374+
if (choices_count > 0) {
375+
query_grew = 1;
376+
choices_count +=
377+
choices.length - length;
378+
}
379+
}
359380
} else {
360381
nfds = 1; /* EOF */
361382
}

0 commit comments

Comments
 (0)