aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-02-17 21:34:00 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-02-18 16:50:40 +0100
commit498723377cbf5cdb36d8b64f41b219a515a84175 (patch)
treedbd82e2cc0fe74f7e63859735a4febd14e09cff2
parent55e285783ef99befcc01d7ed6f5594f87d6d8f6c (diff)
downloadvis-498723377cbf5cdb36d8b64f41b219a515a84175.tar.gz
vis-498723377cbf5cdb36d8b64f41b219a515a84175.tar.xz
Add infrastructure to register custom text object functions
-rw-r--r--vis-core.h3
-rw-r--r--vis-text-objects.c29
-rw-r--r--vis.c7
-rw-r--r--vis.h5
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,