Skip to content

Commit

Permalink
Fix buffer list switch and search/replace
Browse files Browse the repository at this point in the history
Fix the buffer list return key action when buffers have the same name.
Previously, it would pick the first it could find in the buffer list
with the correct buffer name instead of the selected one. Now it uses
text properties to pass the actual buffer pointer along instead.

This however exposed a problem with the clearing of properties and where
in the frame it happens. Search and replace highlighting assumed that
they could color things in their respective command executions. However,
ideally coloring should happen in update functions so now both search
and replace implement the coloring in update hooks for the buffer
they are operating on. For replace, this was already kinda how it
worked and could be adapted with minimal effort. Search on the other
hand needed a bit more rework.
  • Loading branch information
abbec committed Jun 23, 2024
1 parent 67271d0 commit e0901a1
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 139 deletions.
6 changes: 5 additions & 1 deletion src/dged/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ static struct kill_ring {
uint64_t found_at = -1; \
VEC_FOR_EACH_INDEXED(hooks, struct name##_hook *h, idx) { \
if (h->id == id) { \
callback(h->userdata); \
if (callback != NULL) { \
callback(h->userdata); \
} \
found_at = idx; \
break; \
} \
Expand Down Expand Up @@ -1073,6 +1075,8 @@ static void apply_properties(struct command_list *cmds,
}
break;
}
case TextProperty_Data:
break;
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/dged/buffer_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,4 @@ void buffer_view_update(struct buffer_view *view,
// draw buffer commands nested inside this command list
command_list_draw_command_list(params->commands, buf_cmds);
timer_stop(render_buffer_timer);

// TODO: move to somewhere where more correct if buffers
// are in more than one view (same with buffer hooks).
buffer_clear_text_properties(view->buffer);
}
2 changes: 2 additions & 0 deletions src/dged/text.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ bool text_line_contains_unicode(struct text *text, uint32_t line);

enum text_property_type {
TextProperty_Colors,
TextProperty_Data,
};

struct text_property_colors {
Expand All @@ -72,6 +73,7 @@ struct text_property {
enum text_property_type type;
union {
struct text_property_colors colors;
void *userdata;
};
};

Expand Down
33 changes: 19 additions & 14 deletions src/main/cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

int32_t _abort(struct command_ctx ctx, int argc, const char *argv[]) {
abort_replace();
abort_search();
abort_completion();
disable_completion(minibuffer_buffer());
minibuffer_abort_prompt();
Expand Down Expand Up @@ -253,6 +254,12 @@ void buffer_to_list_line(struct buffer *buffer, void *userdata) {
.set_fg = true,
.fg = Color_Blue,
}});

buffer_add_text_property(
listbuf, (struct location){.line = begin.line, .col = 0},
(struct location){.line = begin.line,
.col = buffer_num_chars(listbuf, begin.line)},
(struct text_property){.type = TextProperty_Data, .userdata = buffer});
}
}

Expand All @@ -261,22 +268,18 @@ int32_t buflist_visit_cmd(struct command_ctx ctx, int argc,
struct window *w = ctx.active_window;

struct buffer_view *bv = window_buffer_view(w);
struct text_chunk text = buffer_line(bv->buffer, bv->dot.line);

char *end = (char *)memchr(text.text, ' ', text.nbytes);

if (end != NULL) {
uint32_t len = end - (char *)text.text;
char *bufname = (char *)malloc(len + 1);
strncpy(bufname, (const char *)text.text, len);
bufname[len] = '\0';

struct buffer *target = buffers_find(ctx.buffers, bufname);
free(bufname);
if (target != NULL) {
window_set_buffer(w, target);
struct text_property *props[16] = {0};
uint32_t nprops;
buffer_get_text_properties(bv->buffer, bv->dot, props, 16, &nprops);

for (uint32_t propi = 0; propi < nprops; ++propi) {
struct text_property *p = props[propi];
if (p->type == TextProperty_Data) {
window_set_buffer(w, p->userdata);
return 0;
}
}

return 0;
}

Expand Down Expand Up @@ -497,6 +500,8 @@ void register_global_commands(struct commands *commands,
register_search_replace_commands(commands);
}

void teardown_global_commands(void) { cleanup_search_replace(); }

#define BUFFER_VIEW_WRAPCMD(fn) \
static int32_t fn##_cmd(struct command_ctx ctx, int argc, \
const char *argv[]) { \
Expand Down
1 change: 1 addition & 0 deletions src/main/cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ struct commands;

void register_global_commands(struct commands *commands,
void (*terminate_cb)());
void teardown_global_commands(void);

void register_buffer_commands(struct commands *commands);

Expand Down
12 changes: 12 additions & 0 deletions src/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ void segfault() {
}

#define INVALID_WATCH -1

static void clear_buffer_props(struct buffer *buffer, void *userdata) {
(void)userdata;

buffer_clear_text_properties(buffer);
}

struct watched_file {
uint32_t watch_id;
struct buffer *buffer;
Expand Down Expand Up @@ -344,6 +351,10 @@ int main(int argc, char *argv[]) {
display_resized = false;
}

// TODO: maybe this should be hidden behind something
// The placement is correct though.
buffers_for_each(&buflist, clear_buffer_props, NULL);

/* Update all windows together with the buffers in them. */
struct timer *update_windows = timer_start("update-windows");
windows_update(frame_alloc, frame_time);
Expand Down Expand Up @@ -459,6 +470,7 @@ int main(int argc, char *argv[]) {
}

timers_destroy();
teardown_global_commands();
destroy_completion();
windows_destroy();
minibuffer_destroy();
Expand Down
Loading

0 comments on commit e0901a1

Please sign in to comment.