aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-02-17 20:59:26 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-02-18 16:50:40 +0100
commit44ff1f95ecc14521fb2a1cec67a628140fc46598 (patch)
tree61e5439273640ebd33747637d6e8359a1dee056b
parent58df45177a7db63223c8459be7aef727a0cc22f7 (diff)
downloadvis-44ff1f95ecc14521fb2a1cec67a628140fc46598.tar.gz
vis-44ff1f95ecc14521fb2a1cec67a628140fc46598.tar.xz
Add infrastructure to add custom motion functions
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(...)
-rw-r--r--vis-core.h4
-rw-r--r--vis-motions.c27
-rw-r--r--vis.c3
-rw-r--r--vis.h7
4 files changed, 40 insertions, 1 deletions
diff --git a/vis-core.h b/vis-core.h
index a201828..b1330c7 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -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.
*
@@ -59,6 +60,7 @@ 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 */
@@ -66,6 +68,7 @@ typedef struct { /* Motion implementation, takes a cursor postion and returns a
IDEMPOTENT = 1 << 3, /* does the returned postion remain the same if called multiple times? */
JUMP = 1 << 4,
} type;
+ void *data;
} Movement;
typedef struct {
@@ -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 */
diff --git a/vis-motions.c b/vis-motions.c
index e0db048..6111d3e 100644
--- a/vis-motions.c
+++ b/vis-motions.c
@@ -5,6 +5,7 @@
#include "text-motions.h"
#include "text-objects.h"
#include "text-util.h"
+#include "util.h"
/** utility functions */
@@ -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);
@@ -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;
diff --git a/vis.c b/vis.c
index 35516de..ccea1f1 100644
--- a/vis.c
+++ b/vis.c
@@ -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);
}
@@ -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;
}
diff --git a/vis.h b/vis.h
index 19cdb43..42bd88a 100644
--- a/vis.h
+++ b/vis.h
@@ -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:
@@ -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,