Skip to content

Commit

Permalink
Add infrastructure to register custom text object functions
Browse files Browse the repository at this point in the history
  • Loading branch information
martanne committed Feb 18, 2016
1 parent 55e2857 commit 4987233
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
3 changes: 3 additions & 0 deletions vis-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
29 changes: 24 additions & 5 deletions vis-text-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
7 changes: 5 additions & 2 deletions vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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) {
Expand Down
5 changes: 5 additions & 0 deletions vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 4987233

Please sign in to comment.