| ... | ... |
@@ -14,9 +14,14 @@ double match(const char *needle, const char *haystack); |
| 14 | 14 |
int choices_capacity = 0; |
| 15 | 15 |
int choices_n = 0; |
| 16 | 16 |
const char **choices = NULL; |
| 17 |
+double *choices_score = NULL; |
|
| 18 |
+size_t *choices_sorted = NULL; |
|
| 17 | 19 |
|
| 18 | 20 |
void resize_choices(int new_capacity){
|
| 19 | 21 |
choices = realloc(choices, new_capacity * sizeof(const char *)); |
| 22 |
+ choices_score = realloc(choices_score, new_capacity * sizeof(double)); |
|
| 23 |
+ choices_sorted = realloc(choices_sorted, new_capacity * sizeof(size_t)); |
|
| 24 |
+ |
|
| 20 | 25 |
int i = choices_capacity; |
| 21 | 26 |
for(; i < new_capacity; i++){
|
| 22 | 27 |
choices[i] = NULL; |
| ... | ... |
@@ -48,14 +53,36 @@ void read_choices(){
|
| 48 | 53 |
free(line); |
| 49 | 54 |
} |
| 50 | 55 |
|
| 56 |
+size_t choices_available = 0; |
|
| 57 |
+ |
|
| 58 |
+static int cmpchoice(const void *p1, const void *p2) {
|
|
| 59 |
+ size_t idx1 = *(size_t *)p1; |
|
| 60 |
+ size_t idx2 = *(size_t *)p2; |
|
| 61 |
+ |
|
| 62 |
+ double score1 = choices_score[idx1]; |
|
| 63 |
+ double score2 = choices_score[idx2]; |
|
| 64 |
+ |
|
| 65 |
+ if(score1 == score2) |
|
| 66 |
+ return 0; |
|
| 67 |
+ else if(score1 < score2) |
|
| 68 |
+ return 1; |
|
| 69 |
+ else |
|
| 70 |
+ return -1; |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+ |
|
| 51 | 74 |
void run_search(char *needle){
|
| 75 |
+ choices_available = 0; |
|
| 52 | 76 |
int i; |
| 53 | 77 |
for(i = 0; i < choices_n; i++){
|
| 54 |
- double rank = match(needle, choices[i]); |
|
| 55 |
- if(rank > 0){
|
|
| 56 |
- printf("%s\n", choices[i]);
|
|
| 78 |
+ choices_score[i] = match(needle, choices[i]); |
|
| 79 |
+ if(choices_score[i] >= 0.0){
|
|
| 80 |
+ choices_sorted[choices_available++] = i; |
|
| 57 | 81 |
} |
| 58 | 82 |
} |
| 83 |
+ |
|
| 84 |
+ qsort(choices_sorted, choices_available, sizeof(size_t), cmpchoice); |
|
| 85 |
+ |
|
| 59 | 86 |
} |
| 60 | 87 |
|
| 61 | 88 |
int ttyin; |
| ... | ... |
@@ -112,12 +139,10 @@ void draw(){
|
| 112 | 139 |
const char *prompt = "> "; |
| 113 | 140 |
clear(); |
| 114 | 141 |
fprintf(ttyout, "%s%s\n", prompt, search); |
| 115 |
- for(i = 0; line < 10 && i < choices_n; i++){
|
|
| 116 |
- double rank = match(search, choices[i]); |
|
| 117 |
- if(rank > 0){
|
|
| 118 |
- fprintf(ttyout, "%s\n", choices[i]); |
|
| 119 |
- line++; |
|
| 120 |
- } |
|
| 142 |
+ run_search(search); |
|
| 143 |
+ for(i = 0; line < 10 && i < choices_available; i++){
|
|
| 144 |
+ fprintf(ttyout, "%s\n", choices[choices_sorted[i]]); |
|
| 145 |
+ line++; |
|
| 121 | 146 |
} |
| 122 | 147 |
fprintf(ttyout, "%c%c%iA", 0x1b, '[', line + 1); |
| 123 | 148 |
fprintf(ttyout, "%c%c%iG", 0x1b, '[', strlen(prompt) + strlen(search) + 1); |
| ... | ... |
@@ -128,18 +153,15 @@ void emit(){
|
| 128 | 153 |
/* ttyout should be flushed before outputting on stdout */ |
| 129 | 154 |
fclose(ttyout); |
| 130 | 155 |
|
| 131 |
- int i; |
|
| 132 |
- for(i = 0; i < choices_n; i++){
|
|
| 133 |
- double rank = match(search, choices[i]); |
|
| 134 |
- if(rank > 0){
|
|
| 135 |
- /* Output the first match */ |
|
| 136 |
- printf("%s\n", choices[i]);
|
|
| 137 |
- exit(EXIT_SUCCESS); |
|
| 138 |
- } |
|
| 156 |
+ run_search(search); |
|
| 157 |
+ if(choices_available){
|
|
| 158 |
+ /* output the first result */ |
|
| 159 |
+ printf("%s\n", choices[choices_sorted[0]]);
|
|
| 160 |
+ }else{
|
|
| 161 |
+ /* No match, output the query instead */ |
|
| 162 |
+ printf("%s\n", search);
|
|
| 139 | 163 |
} |
| 140 | 164 |
|
| 141 |
- /* No match, output the query instead */ |
|
| 142 |
- printf("%s\n", search);
|
|
| 143 | 165 |
exit(EXIT_SUCCESS); |
| 144 | 166 |
} |
| 145 | 167 |
|