|
7 | 7 | #include "dged/buffers.h" |
8 | 8 | #include "dged/minibuffer.h" |
9 | 9 |
|
| 10 | +#include "dged/vec.h" |
10 | 11 | #include "main/completion.h" |
11 | 12 |
|
12 | 13 | static bool is_space(const struct codepoint *c) { |
@@ -47,37 +48,39 @@ static struct region buffer_comp_render(void *data, |
47 | 48 | return region_new(begin, end); |
48 | 49 | } |
49 | 50 |
|
| 51 | +static struct s8 buffer_comp_filter_text(void *data) { |
| 52 | + struct buffer_completion *bc = (struct buffer_completion *)data; |
| 53 | + return s8(bc->buffer->name); |
| 54 | +} |
| 55 | + |
50 | 56 | static void buffer_comp_cleanup(void *data) { |
51 | 57 | struct buffer_completion *bc = (struct buffer_completion *)data; |
52 | 58 | free(bc); |
53 | 59 | } |
54 | 60 |
|
55 | | -struct needle_match_ctx { |
56 | | - const char *needle; |
57 | | - struct completion *completions; |
58 | | - uint32_t max_ncompletions; |
59 | | - uint32_t ncompletions; |
| 61 | +typedef VEC(struct completion) completion_vec; |
| 62 | + |
| 63 | +struct buffer_completions { |
| 64 | + completion_vec *completions; |
60 | 65 | on_buffer_selected_cb on_buffer_selected; |
61 | 66 | }; |
62 | 67 |
|
63 | | -static void buffer_matches(struct buffer *buffer, void *userdata) { |
64 | | - struct needle_match_ctx *ctx = (struct needle_match_ctx *)userdata; |
65 | | - |
66 | | - if (strncmp(ctx->needle, buffer->name, strlen(ctx->needle)) == 0 && |
67 | | - ctx->ncompletions < ctx->max_ncompletions) { |
68 | | - |
69 | | - struct buffer_completion *comp_data = |
70 | | - calloc(1, sizeof(struct buffer_completion)); |
71 | | - comp_data->buffer = buffer; |
72 | | - comp_data->on_buffer_selected = ctx->on_buffer_selected; |
73 | | - ctx->completions[ctx->ncompletions] = (struct completion){ |
74 | | - .render = buffer_comp_render, |
75 | | - .selected = buffer_comp_selected, |
76 | | - .cleanup = buffer_comp_cleanup, |
77 | | - .data = comp_data, |
78 | | - }; |
79 | | - ++ctx->ncompletions; |
80 | | - } |
| 68 | +static void fill_buffer_completions(struct buffer *buffer, void *userdata) { |
| 69 | + struct buffer_completions *ctx = (struct buffer_completions *)userdata; |
| 70 | + |
| 71 | + struct buffer_completion *comp_data = |
| 72 | + calloc(1, sizeof(struct buffer_completion)); |
| 73 | + comp_data->buffer = buffer; |
| 74 | + comp_data->on_buffer_selected = ctx->on_buffer_selected; |
| 75 | + |
| 76 | + struct completion comp = (struct completion){ |
| 77 | + .render = buffer_comp_render, |
| 78 | + .selected = buffer_comp_selected, |
| 79 | + .cleanup = buffer_comp_cleanup, |
| 80 | + .data = comp_data, |
| 81 | + .filter_text = buffer_comp_filter_text, |
| 82 | + }; |
| 83 | + VEC_PUSH(ctx->completions, comp); |
81 | 84 | } |
82 | 85 |
|
83 | 86 | static void buffer_complete(struct completion_context ctx, bool deletion, |
@@ -110,19 +113,17 @@ static void buffer_complete(struct completion_context ctx, bool deletion, |
110 | 113 | free(txt.text); |
111 | 114 | } |
112 | 115 |
|
113 | | - struct completion *completions = calloc(50, sizeof(struct completion)); |
114 | | - |
115 | | - struct needle_match_ctx match_ctx = (struct needle_match_ctx){ |
116 | | - .needle = needle, |
117 | | - .max_ncompletions = 50, |
118 | | - .completions = completions, |
119 | | - .ncompletions = 0, |
| 116 | + completion_vec completions; |
| 117 | + VEC_INIT(&completions, 32); |
| 118 | + struct buffer_completions match_ctx = (struct buffer_completions){ |
| 119 | + .completions = &completions, |
120 | 120 | .on_buffer_selected = pd->on_buffer_selected, |
121 | 121 | }; |
122 | 122 |
|
123 | | - buffers_for_each(buffers, buffer_matches, &match_ctx); |
124 | | - ctx.add_completions(match_ctx.completions, match_ctx.ncompletions); |
125 | | - free(completions); |
| 123 | + buffers_for_each(buffers, fill_buffer_completions, &match_ctx); |
| 124 | + ctx.add_completions(s8(needle), filter_contains, VEC_ENTRIES(&completions), |
| 125 | + VEC_SIZE(&completions)); |
| 126 | + VEC_DESTROY(&completions); |
126 | 127 | free(needle); |
127 | 128 | } |
128 | 129 |
|
|
0 commit comments