Skip to content

Commit

Permalink
Add infrastructure to add custom motion functions
Browse files Browse the repository at this point in the history
A motion function can be registered with vis_motion_register(...)
the returned id (if non negative) can then be used as an argument
to vis_motion(...)
  • Loading branch information
martanne committed Feb 18, 2016
1 parent 58df451 commit 44ff1f9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 1 deletion.
4 changes: 4 additions & 0 deletions vis-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "text-regex.h"
#include "map.h"
#include "ring-buffer.h"
#include "array.h"

/* a mode contains a set of key bindings which are currently valid.
*
Expand Down Expand Up @@ -59,13 +60,15 @@ typedef struct { /* Motion implementation, takes a cursor postion and returns a
size_t (*vis)(Vis*, Text*, size_t pos);
size_t (*view)(Vis*, View*);
size_t (*win)(Vis*, Win*, size_t pos);
size_t (*user)(Vis*, Win*, void*, size_t pos);
enum {
LINEWISE = VIS_MOTIONTYPE_LINEWISE, /* should the covered range be extended to whole lines? */
CHARWISE = VIS_MOTIONTYPE_CHARWISE, /* scrolls window content until position is visible */
INCLUSIVE = 1 << 2, /* should new position be included in operator range? */
IDEMPOTENT = 1 << 3, /* does the returned postion remain the same if called multiple times? */
JUMP = 1 << 4,
} type;
void *data;
} Movement;

typedef struct {
Expand Down Expand Up @@ -165,6 +168,7 @@ struct Vis {
Map *actions; /* registered editor actions / special keys commands */
lua_State *lua; /* lua context used for syntax highligthing */
VisEvent *event;
Array motions;
};

/** stuff used by multiple of the vis-* files */
Expand Down
27 changes: 26 additions & 1 deletion vis-motions.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "text-motions.h"
#include "text-objects.h"
#include "text-util.h"
#include "util.h"

/** utility functions */

Expand Down Expand Up @@ -210,6 +211,23 @@ void vis_motion_type(Vis *vis, enum VisMotionType type) {
vis->action.type = type;
}

int vis_motion_register(Vis *vis, enum VisMotionType type, void *data,
size_t (*motion)(Vis*, Win*, void*, size_t pos)) {

Movement *move = calloc(1, sizeof *move);
if (!move)
return -1;

move->user = motion;
move->type = type;
move->data = data;

if (array_add(&vis->motions, move))
return VIS_MOVE_LAST + array_length(&vis->motions) - 1;
free(move);
return -1;
}

bool vis_motion(Vis *vis, enum VisMotion motion, ...) {
va_list ap;
va_start(ap, motion);
Expand Down Expand Up @@ -287,7 +305,14 @@ bool vis_motion(Vis *vis, enum VisMotion motion, ...) {
break;
}

vis->action.movement = &vis_motions[motion];
if (motion < LENGTH(vis_motions))
vis->action.movement = &vis_motions[motion];
else
vis->action.movement = array_get(&vis->motions, motion - VIS_MOVE_LAST);

if (!vis->action.movement)
goto err;

va_end(ap);
action_do(vis, &vis->action);
return true;
Expand Down
3 changes: 3 additions & 0 deletions vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ void vis_free(Vis *vis) {
buffer_release(&vis->input_queue);
for (int i = 0; i < VIS_MODE_INVALID; i++)
map_free(vis_modes[i].bindings);
array_release_full(&vis->motions);
free(vis);
}

Expand Down Expand Up @@ -488,6 +489,8 @@ void action_do(Vis *vis, Action *a) {
pos = a->movement->view(vis, view);
else if (a->movement->win)
pos = a->movement->win(vis, win, pos);
else if (a->movement->user)
pos = a->movement->user(vis, win, a->movement->data, pos);
if (pos == EPOS || a->movement->type & IDEMPOTENT)
break;
}
Expand Down
7 changes: 7 additions & 0 deletions vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ enum VisMotion {
VIS_MOVE_TOTILL_REVERSE,
VIS_MOVE_SEARCH_FORWARD,
VIS_MOVE_SEARCH_BACKWARD,
VIS_MOVE_LAST, /* denotes the end of all motions */
};

/* set motion to perform, the following take an additional argument:
Expand Down Expand Up @@ -275,6 +276,12 @@ enum VisMotionType {
/* force certain motion to behave in line or character wise mode */
void vis_motion_type(Vis *vis, enum VisMotionType);

/* register a motion function, if positive the return value can be used
* as an id for the vis_motion funntion. A negative return value indicates
* an error */
int vis_motion_register(Vis*, enum VisMotionType, void *data,
size_t (*motion)(Vis*, Win*, void*, size_t pos));

enum VisTextObject {
VIS_TEXTOBJECT_INNER_WORD,
VIS_TEXTOBJECT_OUTER_WORD,
Expand Down

0 comments on commit 44ff1f9

Please sign in to comment.