Skip to content

Commit 95ddf40

Browse files
committed
Do not reset the selection on arrival of new choices
... assuming it's still in bounds.
1 parent b38e545 commit 95ddf40

2 files changed

Lines changed: 38 additions & 24 deletions

File tree

pick.c

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static const char *choice_description(const struct choice *);
7777
static const char *choice_string(const struct choice *);
7878
static void delete_between(char *, size_t, size_t, size_t);
7979
static char *eager_strpbrk(const char *, const char *);
80-
static int filter_choices(size_t, size_t);
80+
static int filter_choices(size_t, size_t *);
8181
static size_t get_choices(int, ssize_t);
8282
static enum key get_key(const char **);
8383
static void handle_sigwinch(int);
@@ -86,7 +86,7 @@ static int isu8start(unsigned char);
8686
static int isword(const char *);
8787
static size_t min_match(const char *, size_t, ssize_t *,
8888
ssize_t *);
89-
static size_t print_choices(size_t, size_t);
89+
static void print_choices(size_t, size_t, size_t);
9090
static void print_line(const char *, size_t, int, ssize_t,
9191
ssize_t);
9292
static const struct choice *selected_choice(void);
@@ -383,6 +383,8 @@ selected_choice(void)
383383
choices_offset = choices_count;
384384
choices_count +=
385385
choices.length - length;
386+
} else {
387+
choices_reset = 1;
386388
}
387389
} else {
388390
nfds--; /* EOF */
@@ -556,9 +558,9 @@ selected_choice(void)
556558
choices_reset = 0;
557559
if (dofilter) {
558560
dochoices = filter_choices(choices_offset,
559-
choices_count);
561+
&choices_count);
560562
if (dochoices)
561-
dofilter = selection = yscroll = 0;
563+
dofilter = 0;
562564
}
563565

564566
tty_putp(cursor_invisible, 0);
@@ -569,9 +571,11 @@ selected_choice(void)
569571
xscroll = 0;
570572
print_line(&query[xscroll], query_length - xscroll, 0, -1, -1);
571573
if (dochoices) {
574+
if (selection >= choices_count)
575+
selection = yscroll = 0;
572576
if (selection - yscroll >= choices_lines)
573577
yscroll = selection - choices_lines + 1;
574-
choices_count = print_choices(yscroll, selection);
578+
print_choices(yscroll, choices_count, selection);
575579
}
576580
tty_putp(carriage_return, 1); /* move cursor to first column */
577581
for (i = j = 0; i < cursor_position; j++)
@@ -596,14 +600,15 @@ selected_choice(void)
596600
* Returns non-zero if the filtering was not aborted.
597601
*/
598602
int
599-
filter_choices(size_t offset, size_t nchoices)
603+
filter_choices(size_t offset, size_t *nchoices)
600604
{
601605
struct pollfd pfd;
602606
struct choice *c;
603607
size_t i, match_length;
608+
size_t n = 0;
604609
int nready;
605610

606-
for (i = offset; i < nchoices; i++) {
611+
for (i = offset; i < *nchoices; i++) {
607612
c = &choices.v[i];
608613
if (min_match(choice_string(c), 0,
609614
&c->match_start, &c->match_end) == INT_MAX) {
@@ -615,6 +620,8 @@ filter_choices(size_t offset, size_t nchoices)
615620
match_length = c->match_end - c->match_start;
616621
c->score = (double)query_length/match_length/c->length;
617622
}
623+
if (c->score > 0 || query_length == 0)
624+
n++;
618625

619626
if (i > 0 && i % 50 == 0) {
620627
pfd.fd = fileno(tty_in);
@@ -625,7 +632,8 @@ filter_choices(size_t offset, size_t nchoices)
625632
return 0;
626633
}
627634
}
628-
qsort(choices.v, nchoices, sizeof(struct choice), choice_cmp);
635+
qsort(choices.v, *nchoices, sizeof(struct choice), choice_cmp);
636+
*nchoices = offset + n;
629637

630638
return 1;
631639
}
@@ -941,25 +949,21 @@ print_line(const char *str, size_t len, int standout,
941949
}
942950

943951
/*
944-
* Output as many choices as possible starting from offset and return the number
945-
* of choices with a positive score. If the query is empty, all choices are
946-
* considered having a positive score.
952+
* Print length - offset number of choices.
947953
*/
948-
size_t
949-
print_choices(size_t offset, size_t selection)
954+
void
955+
print_choices(size_t offset, size_t length, size_t selection)
950956
{
951-
const struct choice *choice;
957+
const struct choice *c;
952958
size_t i;
953959

954-
for (i = offset; i < choices.length; i++) {
955-
choice = choices.v + i;
956-
if (choice->score == 0 && query_length > 0)
960+
for (i = offset; i < length; i++) {
961+
if (i - offset >= choices_lines)
957962
break;
958963

959-
if (i - offset < choices_lines)
960-
print_line(choice_string(choice), choice->length,
961-
i == selection, choice->match_start,
962-
choice->match_end);
964+
c = choices.v + i;
965+
print_line(choice_string(c), c->length, i == selection,
966+
c->match_start, c->match_end);
963967
}
964968

965969
if (i - offset < choices.length && i - offset < choices_lines) {
@@ -985,8 +989,6 @@ print_choices(size_t offset, size_t selection)
985989
tty_putp(tty_parm1(parm_up_cursor,
986990
i < choices_lines ? i : choices_lines), 1);
987991
}
988-
989-
return i;
990992
}
991993

992994
enum key

tests/key-printable.t

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ stdin:
3333
stdout:
3434
💩
3535

36-
description: changing the query resets vertical scroll
36+
description: changing the query does not reset the selection if it is still in bounds
3737
keys: \016 \016 \016 \016 \016 0 \n #DOWN ENTER
3838
env: LINES=5
3939
stdin:
@@ -43,4 +43,16 @@ stdin:
4343
04
4444
05
4545
stdout:
46+
05
47+
48+
description: changing the query does reset the selection if it is out of bounds
49+
keys: \016 \016 \016 \016 \016 1 \n #DOWN ENTER
50+
env: LINES=5
51+
stdin:
52+
01
53+
02
54+
03
55+
04
56+
05
57+
stdout:
4658
01

0 commit comments

Comments
 (0)