From 498723377cbf5cdb36d8b64f41b219a515a84175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Wed, 17 Feb 2016 21:34:00 +0100 Subject: Add infrastructure to register custom text object functions --- vis-core.h | 3 +++ vis-text-objects.c | 29 ++++++++++++++++++++++++----- vis.c | 7 +++++-- vis.h | 5 +++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/vis-core.h b/vis-core.h index b1330c7..15b4167 100644 --- a/vis-core.h +++ b/vis-core.h @@ -76,11 +76,13 @@ typedef struct { * representing the text object containing the position. */ Filerange (*txt)(Text*, size_t pos); Filerange (*vis)(Vis*, Text*, size_t pos); + Filerange (*user)(Vis*, Win*, void *data, size_t pos); enum { INNER = 1 << 0, /* whether the object should include */ OUTER = 1 << 1, /* the delimiting symbols or not */ SPLIT = 1 << 2, /* whether multiple applications will yield a split range */ } type; + void *data; } TextObject; /* a macro is just a sequence of symbolic keys as received from ui->getkey */ @@ -169,6 +171,7 @@ struct Vis { lua_State *lua; /* lua context used for syntax highligthing */ VisEvent *event; Array motions; + Array textobjects; }; /** stuff used by multiple of the vis-* files */ diff --git a/vis-text-objects.c b/vis-text-objects.c index 5869e86..ebb7384 100644 --- a/vis-text-objects.c +++ b/vis-text-objects.c @@ -2,13 +2,32 @@ #include "text-objects.h" #include "util.h" +int vis_textobject_register(Vis *vis, int type, void *data, + Filerange (*textobject)(Vis*, Win*, void*, size_t pos)) { + + TextObject *obj = calloc(1, sizeof *obj); + if (!obj) + return -1; + + obj->user = textobject; + obj->type = type; + obj->data = data; + + if (array_add(&vis->textobjects, obj)) + return LENGTH(vis_textobjects) + array_length(&vis->textobjects) - 1; + free(obj); + return -1; +} + bool vis_textobject(Vis *vis, enum VisTextObject id) { - if (id < LENGTH(vis_textobjects)) { + if (id < LENGTH(vis_textobjects)) vis->action.textobj = &vis_textobjects[id]; - action_do(vis, &vis->action); - return true; - } - return false; + else + vis->action.textobj = array_get(&vis->textobjects, id - LENGTH(vis_textobjects)); + if (!vis->action.textobj) + return false; + action_do(vis, &vis->action); + return true; } static Filerange search_forward(Vis *vis, Text *txt, size_t pos) { diff --git a/vis.c b/vis.c index ccea1f1..0d4fd9d 100644 --- a/vis.c +++ b/vis.c @@ -378,6 +378,7 @@ void vis_free(Vis *vis) { for (int i = 0; i < VIS_MODE_INVALID; i++) map_free(vis_modes[i].bindings); array_release_full(&vis->motions); + array_release_full(&vis->textobjects); free(vis); } @@ -524,11 +525,13 @@ void action_do(Vis *vis, Action *a) { else c.range.start = c.range.end = pos; for (int i = 0; i < count; i++) { - Filerange r; + Filerange r = text_range_empty(); if (a->textobj->txt) r = a->textobj->txt(txt, pos); - else + else if (a->textobj->vis) r = a->textobj->vis(vis, txt, pos); + else if (a->textobj->user) + r = a->textobj->user(vis, win, a->textobj->data, pos); if (!text_range_valid(&r)) break; if (a->textobj->type & OUTER) { diff --git a/vis.h b/vis.h index 84779d6..614d34a 100644 --- a/vis.h +++ b/vis.h @@ -317,6 +317,11 @@ enum VisTextObject { bool vis_textobject(Vis*, enum VisTextObject); +/* register a new text object, if successful the returned id is positive + * and can be used as argument for the vis_textobject function. */ +int vis_textobject_register(Vis*, int type, void *data, + Filerange (*textobject)(Vis*, Win*, void*, size_t pos)); + /* macro REPEAT and INVALID should be considered as implementation details (TODO: hide them?) */ enum VisMacro { VIS_MACRO_a, VIS_MACRO_b, VIS_MACRO_c, VIS_MACRO_d, VIS_MACRO_e, -- cgit v1.2.3