aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vis-core.h1
-rw-r--r--vis-modes.c33
-rw-r--r--vis.c32
-rw-r--r--vis.h2
4 files changed, 52 insertions, 16 deletions
diff --git a/vis-core.h b/vis-core.h
index 6554410..3093a92 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -119,6 +119,7 @@ struct Win {
View *view; /* currently displayed part of underlying text */
RingBuffer *jumplist; /* LRU jump management */
ChangeList changelist; /* state for iterating through least recently changes */
+ Mode modes[VIS_MODE_LAST]; /* overlay mods used for per window key bindings */
Win *prev, *next; /* neighbouring windows */
};
diff --git a/vis-modes.c b/vis-modes.c
index 8e245a3..0b85ed7 100644
--- a/vis-modes.c
+++ b/vis-modes.c
@@ -20,14 +20,35 @@ void mode_set(Vis *vis, Mode *new_mode) {
vis->win->ui->draw_status(vis->win->ui);
}
-bool vis_mode_map(Vis *vis, enum VisMode modeid, const char *key, const KeyBinding *binding) {
- Mode *mode = mode_get(vis, modeid);
- return mode && map_put(mode->bindings, key, binding);
+static bool mode_map(Mode *mode, const char *key, const KeyBinding *binding) {
+ if (!mode)
+ return false;
+ if (!mode->bindings) {
+ mode->bindings = map_new();
+ if (!mode->bindings)
+ return false;
+ }
+ return map_put(mode->bindings, key, binding);
+}
+
+bool vis_mode_map(Vis *vis, enum VisMode id, const char *key, const KeyBinding *binding) {
+ return id < LENGTH(vis_modes) && mode_map(&vis_modes[id], key, binding);
+}
+
+bool vis_window_mode_map(Win *win, enum VisMode id, const char *key, const KeyBinding *binding) {
+ return id < LENGTH(win->modes) && mode_map(&win->modes[id], key, binding);
+}
+
+static bool mode_unmap(Mode *mode, const char *key) {
+ return mode && mode->bindings && map_delete(mode->bindings, key);
+}
+
+bool vis_mode_unmap(Vis *vis, enum VisMode id, const char *key) {
+ return id < LENGTH(vis_modes) && mode_unmap(&vis_modes[id], key);
}
-bool vis_mode_unmap(Vis *vis, enum VisMode modeid, const char *key) {
- Mode *mode = mode_get(vis, modeid);
- return mode && map_delete(mode->bindings, key);
+bool vis_window_mode_unmap(Win *win, enum VisMode id, const char *key) {
+ return id < LENGTH(win->modes) && mode_unmap(&win->modes[id], key);
}
/** mode switching event handlers */
diff --git a/vis.c b/vis.c
index 7af4654..8e033ca 100644
--- a/vis.c
+++ b/vis.c
@@ -150,6 +150,8 @@ static void window_free(Win *win) {
if (vis && vis->ui)
vis->ui->window_free(win->ui);
view_free(win->view);
+ for (size_t i = 0; i < LENGTH(win->modes); i++)
+ map_free(win->modes[i].bindings);
ringbuf_free(win->jumplist);
free(win);
}
@@ -174,6 +176,8 @@ static Win *window_new_file(Vis *vis, File *file) {
vis->windows = win;
vis->win = win;
vis->ui->window_focus(win->ui);
+ for (size_t i = 0; i < LENGTH(win->modes); i++)
+ win->modes[i].parent = &vis_modes[i];
if (vis->event && vis->event->win_open)
vis->event->win_open(vis, win);
return win;
@@ -199,6 +203,12 @@ bool vis_window_split(Win *original) {
Win *win = window_new_file(original->vis, original->file);
if (!win)
return false;
+ for (size_t i = 0; i < LENGTH(win->modes); i++) {
+ if (original->modes[i].bindings)
+ win->modes[i].bindings = map_new();
+ if (win->modes[i].bindings)
+ map_copy(win->modes[i].bindings, original->modes[i].bindings);
+ }
win->file = original->file;
win->file->refcount++;
view_syntax_set(win->view, view_syntax_get(original->view));
@@ -296,11 +306,6 @@ Vis *vis_new(Ui *ui, VisEvent *event) {
vis->ui->init(vis->ui, vis);
vis->tabwidth = 8;
vis->expandtab = false;
- for (int i = 0; i < VIS_MODE_LAST; i++) {
- Mode *mode = &vis_modes[i];
- if (!(mode->bindings = map_new()))
- goto err;
- }
if (!(vis->prompt = calloc(1, sizeof(Win))))
goto err;
if (!(vis->prompt->file = calloc(1, sizeof(File))))
@@ -341,10 +346,8 @@ void vis_free(Vis *vis) {
map_free(vis->options);
map_free(vis->actions);
buffer_release(&vis->input_queue);
- for (int i = 0; i < VIS_MODE_LAST; i++) {
- Mode *mode = &vis_modes[i];
- map_free(mode->bindings);
- }
+ for (int i = 0; i < VIS_MODE_LAST; i++)
+ map_free(vis_modes[i].bindings);
free(vis);
}
@@ -694,7 +697,16 @@ static const char *vis_keys_raw(Vis *vis, Buffer *buf, const char *input) {
prefix = false;
binding = NULL;
- for (Mode *mode = vis->mode; mode && !binding && !prefix; mode = mode->parent) {
+ Mode *mode = vis->mode;
+ for (size_t i = 0; i < LENGTH(vis->win->modes); i++) {
+ if (mode == &vis_modes[i]) {
+ if (vis->win->modes[i].bindings)
+ mode = &vis->win->modes[i];
+ break;
+ }
+ }
+
+ for (; mode && !binding && !prefix; mode = mode->parent) {
binding = map_get(mode->bindings, start);
/* "<" is never treated as a prefix because it is used to denote
* special key symbols */
diff --git a/vis.h b/vis.h
index 2008724..d783eea 100644
--- a/vis.h
+++ b/vis.h
@@ -134,8 +134,10 @@ void vis_mode_switch(Vis*, enum VisMode);
/* in the specified mode: map a given key to a binding (binding->key is ignored),
* fails if key is already mapped */
bool vis_mode_map(Vis*, enum VisMode, const char *key, const KeyBinding*);
+bool vis_window_mode_map(Win*, enum VisMode, const char *key, const KeyBinding*);
/* in the specified mode: unmap a given key, fails if the key is not currently mapped */
bool vis_mode_unmap(Vis*, enum VisMode, const char *key);
+bool vis_window_mode_unmap(Win*, enum VisMode, const char *key);
/* get the current mode's status line indicator */
const char *vis_mode_status(Vis*);
/* associates the special pseudo key <keyaction->name> with the given key action.