Skip to content

Commit b9ee658

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

File tree

2 files changed

+38
-24
lines changed

2 files changed

+38
-24
lines changed

pick.c

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static const char *choice_description(const struct choice *);
7878
static const char *choice_string(const struct choice *);
7979
static void delete_between(char *, size_t, size_t, size_t);
8080
static char *eager_strpbrk(const char *, const char *);
81-
static int filter_choices(size_t, size_t);
81+
static int filter_choices(size_t, size_t *);
8282
static size_t get_choices(int, ssize_t);
8383
static enum key get_key(const char **);
8484
static void handle_sigwinch(int);
@@ -87,7 +87,7 @@ static int isu8start(unsigned char);
8787
static int isword(const char *);
8888
static size_t min_match(const char *, size_t, ssize_t *,
8989
ssize_t *);
90-
static size_t print_choices(size_t, size_t);
90+
static void print_choices(size_t, size_t, size_t);
9191
static void print_line(const char *, size_t, int, ssize_t,
9292
ssize_t);
9393
static const struct choice *selected_choice(void);
@@ -384,6 +384,8 @@ selected_choice(void)
384384
choices_offset = choices_count;
385385
choices_count +=
386386
choices.length - length;
387+
} else {
388+
choices_reset = 1;
387389
}
388390
} else {
389391
nfds--; /* EOF */
@@ -557,9 +559,9 @@ selected_choice(void)
557559
choices_reset = 0;
558560
if (dofilter) {
559561
dochoices = filter_choices(choices_offset,
560-
choices_count);
562+
&choices_count);
561563
if (dochoices)
562-
dofilter = selection = yscroll = 0;
564+
dofilter = 0;
563565
}
564566

565567
tty_putp(cursor_invisible, 0);
@@ -570,9 +572,11 @@ selected_choice(void)
570572
xscroll = 0;
571573
print_line(&query[xscroll], query_length - xscroll, 0, -1, -1);
572574
if (dochoices) {
575+
if (selection >= choices_count)
576+
selection = yscroll = 0;
573577
if (selection - yscroll >= choices_lines)
574578
yscroll = selection - choices_lines + 1;
575-
choices_count = print_choices(yscroll, selection);
579+
print_choices(yscroll, choices_count, selection);
576580
}
577581
tty_putp(carriage_return, 1); /* move cursor to first column */
578582
for (i = j = 0; i < cursor_position; j++)
@@ -597,14 +601,15 @@ selected_choice(void)
597601
* Returns non-zero if the filtering was not aborted.
598602
*/
599603
int
600-
filter_choices(size_t offset, size_t nchoices)
604+
filter_choices(size_t offset, size_t *nchoices)
601605
{
602606
struct pollfd pfd;
603607
struct choice *c;
604608
size_t i, match_length;
609+
size_t n = 0;
605610
int nready;
606611

607-
for (i = offset; i < nchoices; i++) {
612+
for (i = offset; i < *nchoices; i++) {
608613
c = &choices.v[i];
609614
if (min_match(choice_string(c), 0,
610615
&c->match_start, &c->match_end) == INT_MAX) {
@@ -616,6 +621,8 @@ filter_choices(size_t offset, size_t nchoices)
616621
match_length = c->match_end - c->match_start;
617622
c->score = (double)query_length/match_length/c->length;
618623
}
624+
if (c->score > 0 || query_length == 0)
625+
n++;
619626

620627
if (i > 0 && i % 50 == 0) {
621628
pfd.fd = fileno(tty_in);
@@ -626,7 +633,8 @@ filter_choices(size_t offset, size_t nchoices)
626633
return 0;
627634
}
628635
}
629-
qsort(choices.v, nchoices, sizeof(struct choice), choice_cmp);
636+
qsort(choices.v, *nchoices, sizeof(struct choice), choice_cmp);
637+
*nchoices = offset + n;
630638

631639
return 1;
632640
}
@@ -942,25 +950,21 @@ print_line(const char *str, size_t len, int standout,
942950
}
943951

944952
/*
945-
* Output as many choices as possible starting from offset and return the number
946-
* of choices with a positive score. If the query is empty, all choices are
947-
* considered having a positive score.
953+
* Print length - offset number of choices.
948954
*/
949-
size_t
950-
print_choices(size_t offset, size_t selection)
955+
void
956+
print_choices(size_t offset, size_t length, size_t selection)
951957
{
952-
const struct choice *choice;
958+
const struct choice *c;
953959
size_t i;
954960

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

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

966970
if (i - offset < choices.length && i - offset < choices_lines) {
@@ -986,8 +990,6 @@ print_choices(size_t offset, size_t selection)
986990
tty_putp(tty_parm1(parm_up_cursor,
987991
i < choices_lines ? i : choices_lines), 1);
988992
}
989-
990-
return i;
991993
}
992994

993995
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 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)