aboutsummaryrefslogtreecommitdiff
path: root/config.def.h
diff options
context:
space:
mode:
Diffstat (limited to 'config.def.h')
-rw-r--r--config.def.h413
1 files changed, 340 insertions, 73 deletions
diff --git a/config.def.h b/config.def.h
index eef2d55..66e3044 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,11 +3,137 @@
#define KEY(k) { .str = { '\0' }, .code = KEY_##k }
#define CONTROL(k) NONE((k)&0x1F)
#define META(k) { .str = { ESC, (k) }, .code = 0 }
-#define BACKSPACE(func, arg) \
- { { KEY(BACKSPACE) }, (func), { .m = (arg) } }, \
- { { CONTROL('H') }, (func), { .m = (arg) } }, \
- { { NONE(127) }, (func), { .m = (arg) } }, \
- { { CONTROL('B') }, (func), { .m = (arg) } }
+#define BACKSPACE(func, name, arg) \
+ { { KEY(BACKSPACE) }, (func), { .name = (arg) } }, \
+ { { CONTROL('H') }, (func), { .name = (arg) } }, \
+ { { NONE(127) }, (func), { .name = (arg) } }, \
+ { { CONTROL('B') }, (func), { .name = (arg) } }
+
+static void switchmode(const Arg *arg);
+
+enum {
+ VIS_MODE_BASIC,
+ VIS_MODE_MOVE,
+ VIS_MODE_TEXTOBJ,
+ VIS_MODE_OPERATOR,
+ VIS_MODE_NORMAL,
+ VIS_MODE_VISUAL,
+ VIS_MODE_INSERT,
+ VIS_MODE_REPLACE,
+};
+
+enum {
+ OP_DELETE,
+ OP_CHANGE,
+ OP_YANK,
+};
+
+void op_delete(OperatorContext *c) {
+ if (c->range.start == (size_t)-1)
+ return;
+ size_t len = c->range.end - c->range.start;
+ text_delete(editor_text_get(editor), c->range.start, len);
+ if (c->pos > c->range.start)
+ editor_cursor_to(editor, c->range.start);
+ editor_draw(editor);
+}
+
+void op_change(OperatorContext *c) {
+ op_delete(c);
+ switchmode(&(const Arg){ .i = VIS_MODE_INSERT });
+}
+
+void op_yank(OperatorContext *c) {}
+
+static Operator *ops[] = {
+ [OP_DELETE] = op_delete,
+ [OP_CHANGE] = op_change,
+ [OP_YANK] = op_yank,
+};
+
+enum {
+ MOVE_CHAR_PREV,
+ MOVE_CHAR_NEXT,
+ MOVE_LINE_UP,
+ MOVE_LINE_DOWN,
+ MOVE_LINE_BEGIN,
+ MOVE_LINE_START,
+ MOVE_LINE_FINISH,
+ MOVE_LINE_END,
+ MOVE_WORD_START_PREV,
+ MOVE_WORD_START_NEXT,
+ MOVE_WORD_END_PREV,
+ MOVE_WORD_END_NEXT,
+ MOVE_SENTENCE_PREV,
+ MOVE_SENTENCE_NEXT,
+ MOVE_PARAGRAPH_PREV,
+ MOVE_PARAGRAPH_NEXT,
+ MOVE_BRACKET_MATCH,
+ MOVE_FILE_BEGIN,
+ MOVE_FILE_END,
+};
+
+static Movement moves[] = {
+ [MOVE_CHAR_PREV] = { .win = editor_char_prev },
+ [MOVE_CHAR_NEXT] = { .win = editor_char_next },
+ [MOVE_LINE_UP] = { .win = editor_line_up },
+ [MOVE_LINE_DOWN] = { .win = editor_line_down },
+ [MOVE_LINE_BEGIN] = { .txt = text_line_begin, .type = LINEWISE },
+ [MOVE_LINE_START] = { .txt = text_line_start, .type = LINEWISE },
+ [MOVE_LINE_FINISH] = { .txt = text_line_finish, .type = LINEWISE },
+ [MOVE_LINE_END] = { .txt = text_line_end, .type = LINEWISE },
+ [MOVE_WORD_START_PREV] = { .txt = text_word_start_prev, .type = CHARWISE },
+ [MOVE_WORD_START_NEXT] = { .txt = text_word_start_next, .type = CHARWISE },
+ [MOVE_WORD_END_PREV] = { .txt = text_word_end_prev, .type = CHARWISE|INCLUSIVE },
+ [MOVE_WORD_END_NEXT] = { .txt = text_word_end_next, .type = CHARWISE|INCLUSIVE },
+ [MOVE_SENTENCE_PREV] = { .txt = text_sentence_prev, .type = LINEWISE },
+ [MOVE_SENTENCE_NEXT] = { .txt = text_sentence_next, .type = LINEWISE },
+ [MOVE_PARAGRAPH_PREV] = { .txt = text_paragraph_prev, .type = LINEWISE },
+ [MOVE_PARAGRAPH_NEXT] = { .txt = text_paragraph_next, .type = LINEWISE },
+ [MOVE_BRACKET_MATCH] = { .txt = text_bracket_match, .type = LINEWISE|INCLUSIVE },
+ [MOVE_FILE_BEGIN] = { .txt = text_begin, .type = LINEWISE },
+ [MOVE_FILE_END] = { .txt = text_end, .type = LINEWISE },
+};
+
+enum {
+ TEXT_OBJ_WORD,
+ TEXT_OBJ_SENTENCE,
+ TEXT_OBJ_PARAGRAPH,
+ TEXT_OBJ_OUTER_SQUARE_BRACKET,
+ TEXT_OBJ_INNER_SQUARE_BRACKET,
+ TEXT_OBJ_OUTER_CURLY_BRACKET,
+ TEXT_OBJ_INNER_CURLY_BRACKET,
+ TEXT_OBJ_OUTER_ANGLE_BRACKET,
+ TEXT_OBJ_INNER_ANGLE_BRACKET,
+ TEXT_OBJ_OUTER_PARANTHESE,
+ TEXT_OBJ_INNER_PARANTHESE,
+ TEXT_OBJ_OUTER_QUOTE,
+ TEXT_OBJ_INNER_QUOTE,
+ TEXT_OBJ_OUTER_SINGLE_QUOTE,
+ TEXT_OBJ_INNER_SINGLE_QUOTE,
+ TEXT_OBJ_OUTER_BACKTICK,
+ TEXT_OBJ_INNER_BACKTICK,
+};
+
+static TextObject textobjs[] = {
+ [TEXT_OBJ_WORD] = { text_object_word },
+ [TEXT_OBJ_SENTENCE] = { text_object_sentence },
+ [TEXT_OBJ_PARAGRAPH] = { text_object_paragraph },
+ [TEXT_OBJ_OUTER_SQUARE_BRACKET] = { text_object_square_bracket, OUTER },
+ [TEXT_OBJ_INNER_SQUARE_BRACKET] = { text_object_square_bracket, INNER },
+ [TEXT_OBJ_OUTER_CURLY_BRACKET] = { text_object_curly_bracket, OUTER },
+ [TEXT_OBJ_INNER_CURLY_BRACKET] = { text_object_curly_bracket, INNER },
+ [TEXT_OBJ_OUTER_ANGLE_BRACKET] = { text_object_angle_bracket, OUTER },
+ [TEXT_OBJ_INNER_ANGLE_BRACKET] = { text_object_angle_bracket, INNER },
+ [TEXT_OBJ_OUTER_PARANTHESE] = { text_object_paranthese, OUTER },
+ [TEXT_OBJ_INNER_PARANTHESE] = { text_object_paranthese, INNER },
+ [TEXT_OBJ_OUTER_QUOTE] = { text_object_quote, OUTER },
+ [TEXT_OBJ_INNER_QUOTE] = { text_object_quote, INNER },
+ [TEXT_OBJ_OUTER_SINGLE_QUOTE] = { text_object_single_quote, OUTER },
+ [TEXT_OBJ_INNER_SINGLE_QUOTE] = { text_object_single_quote, INNER },
+ [TEXT_OBJ_OUTER_BACKTICK] = { text_object_backtick, OUTER },
+ [TEXT_OBJ_INNER_BACKTICK] = { text_object_backtick, INNER },
+};
/* draw a statubar, do whatever you want with the given curses window */
static void statusbar(WINDOW *win, bool active, const char *filename, int line, int col) {
@@ -25,16 +151,6 @@ static void statusbar(WINDOW *win, bool active, const char *filename, int line,
}
}
-static void switchmode(const Arg *arg);
-enum {
- VIS_MODE_BASIC,
- VIS_MODE_MOVE,
- VIS_MODE_NORMAL,
- VIS_MODE_VISUAL,
- VIS_MODE_INSERT,
- VIS_MODE_REPLACE,
-};
-
void quit(const Arg *arg) {
endwin();
exit(0);
@@ -51,6 +167,81 @@ static void mark_set(const Arg *arg) {
static void mark_goto(const Arg *arg) {
editor_mark_goto(editor, arg->i);
}
+
+static Action action;
+void action_do(Action *a);
+
+static void count(const Arg *arg) {
+ action.count = action.count * 10 + arg->i;
+}
+
+static void operator(const Arg *arg) {
+ action.op = ops[arg->i];
+}
+
+static bool operator_unknown(Key *key1, Key *key2) {
+ action.op = NULL;
+ return true;
+}
+
+static void movement(const Arg *arg) {
+ action.movement = &moves[arg->i];
+ action_do(&action);
+}
+
+static void textobj(const Arg *arg) {
+ action.textobj = &textobjs[arg->i];
+ action_do(&action);
+}
+
+void action_reset(Action *a) {
+ a->count = 0;
+ a->op = NULL;
+ a->movement = NULL;
+ a->textobj = NULL;
+ a->reg = NULL;
+}
+
+void action_do(Action *a) {
+ Text *txt = editor_text_get(editor);
+ OperatorContext c;
+ size_t pos = editor_cursor_get(editor);
+ c.pos = pos;
+ if (a->count == 0)
+ a->count = 1;
+ if (a->movement) {
+ size_t start = pos;
+ for (int i = 0; i < a->count; i++) {
+ if (a->movement->txt)
+ pos = a->movement->txt(txt, pos);
+ else
+ pos = a->movement->win(editor);
+ }
+ c.range.start = MIN(start, pos);
+ c.range.end = MAX(start, pos);
+ if (!a->op) {
+ if (a->movement->type & CHARWISE)
+ editor_scroll_to(editor, pos);
+ else
+ editor_cursor_to(editor, pos);
+ } else if (a->movement->type & INCLUSIVE) {
+ Iterator it = text_iterator_get(txt, c.range.end);
+ text_iterator_char_next(&it, NULL);
+ c.range.end = it.pos;
+ }
+ } else if (a->textobj) {
+ c.range = a->textobj->range(txt, pos);
+ if (c.range.start != (size_t)-1 && a->textobj->type == OUTER) {
+ c.range.start--;
+ c.range.end++;
+ }
+ }
+ c.count = a->count;
+ if (a->op)
+ a->op(&c);
+ action_reset(a);
+}
+
/* use vim's
:help motion
:h operator
@@ -58,57 +249,133 @@ static void mark_goto(const Arg *arg) {
as reference
*/
-static KeyBinding movement[] = {
- { { KEY(LEFT) }, cursor, { .m = editor_char_prev } },
- { { KEY(RIGHT) }, cursor, { .m = editor_char_next } },
- { { KEY(UP) }, cursor, { .m = editor_line_up } },
- { { KEY(DOWN) }, cursor, { .m = editor_line_down } },
+static KeyBinding basic_movement[] = {
+ { { KEY(LEFT) }, movement, { .i = MOVE_CHAR_PREV } },
+ { { KEY(RIGHT) }, movement, { .i = MOVE_CHAR_NEXT } },
+ { { KEY(UP) }, movement, { .i = MOVE_LINE_UP } },
+ { { KEY(DOWN) }, movement, { .i = MOVE_LINE_DOWN } },
{ { KEY(PPAGE) }, cursor, { .m = editor_page_up } },
{ { KEY(NPAGE) }, cursor, { .m = editor_page_down } },
- { { KEY(HOME) }, cursor, { .m = editor_line_start } },
- { { KEY(END) }, cursor, { .m = editor_line_end } },
+ { { KEY(HOME) }, movement, { .i = MOVE_LINE_START } },
+ { { KEY(END) }, movement, { .i = MOVE_LINE_FINISH } },
// temporary until we have a way to enter user commands
{ { CONTROL('c') }, quit, },
{ /* empty last element, array terminator */ },
};
-static KeyBinding vis_movement[] = {
- BACKSPACE( cursor, editor_char_prev ),
- { { NONE(' ') }, cursor, { .m = editor_char_next } },
+#if 0
+static KeyBinding vis_commands[] = {
+ // DEMO STUFF
+ { { NONE('5') }, line, { .i = 50 } },
+ { { NONE('s') }, mark_set, { .i = 0 } },
+ { { NONE('9') }, mark_goto, { .i = 0 } },
+
+ { /* empty last element, array terminator */ },
+};
+#endif
+
+static KeyBinding vis_movements[] = {
+ BACKSPACE( movement, i, MOVE_CHAR_PREV ),
+ { { NONE('h') }, movement, { .i = MOVE_CHAR_PREV } },
+ { { NONE(' ') }, movement, { .i = MOVE_CHAR_NEXT } },
+ { { NONE('l') }, movement, { .i = MOVE_CHAR_NEXT } },
+ { { NONE('k') }, movement, { .i = MOVE_LINE_UP } },
+ { { CONTROL('P') }, movement, { .i = MOVE_LINE_UP } },
+ { { NONE('j') }, movement, { .i = MOVE_LINE_DOWN } },
+ { { CONTROL('J') }, movement, { .i = MOVE_LINE_DOWN } },
+ { { CONTROL('N') }, movement, { .i = MOVE_LINE_DOWN } },
+ { { KEY(ENTER) }, movement, { .i = MOVE_LINE_DOWN } },
+ { { NONE('0') }, movement, { .i = MOVE_LINE_BEGIN } },
+ { { NONE('^') }, movement, { .i = MOVE_LINE_START } },
+ { { NONE('g'), NONE('_') }, movement, { .i = MOVE_LINE_FINISH } },
+ { { NONE('$') }, movement, { .i = MOVE_LINE_END } },
+ { { NONE('%') }, movement, { .i = MOVE_BRACKET_MATCH } },
+ { { NONE('b') }, movement, { .i = MOVE_WORD_START_PREV } },
+ { { KEY(SLEFT) }, movement, { .i = MOVE_WORD_START_PREV } },
+ { { NONE('w') }, movement, { .i = MOVE_WORD_START_NEXT } },
+ { { KEY(SRIGHT) }, movement, { .i = MOVE_WORD_START_NEXT } },
+ { { NONE('g'), NONE('e') }, movement, { .i = MOVE_WORD_END_PREV } },
+ { { NONE('e') }, movement, { .i = MOVE_WORD_END_NEXT } },
+ { { NONE('{') }, movement, { .i = MOVE_PARAGRAPH_PREV } },
+ { { NONE('}') }, movement, { .i = MOVE_PARAGRAPH_NEXT } },
+ { { NONE('(') }, movement, { .i = MOVE_SENTENCE_PREV } },
+ { { NONE(')') }, movement, { .i = MOVE_SENTENCE_NEXT } },
+ { { NONE('g'), NONE('g') }, movement, { .i = MOVE_FILE_BEGIN } },
+ { { NONE('G') }, movement, { .i = MOVE_FILE_END } },
+ { /* empty last element, array terminator */ },
+};
+
+// TODO: factor out prefix [ia] into spearate mode which sets a flag
+static KeyBinding vis_textobjs[] = {
+ { { NONE('a'), NONE('w') }, textobj, { .i = TEXT_OBJ_WORD } },
+ { { NONE('i'), NONE('w') }, textobj, { .i = TEXT_OBJ_WORD } },
+ { { NONE('a'), NONE('s') }, textobj, { .i = TEXT_OBJ_SENTENCE } },
+ { { NONE('i'), NONE('s') }, textobj, { .i = TEXT_OBJ_SENTENCE } },
+ { { NONE('a'), NONE('p') }, textobj, { .i = TEXT_OBJ_PARAGRAPH } },
+ { { NONE('i'), NONE('p') }, textobj, { .i = TEXT_OBJ_PARAGRAPH } },
+ { { NONE('a'), NONE('[') }, textobj, { .i = TEXT_OBJ_OUTER_SQUARE_BRACKET } },
+ { { NONE('a'), NONE(']') }, textobj, { .i = TEXT_OBJ_OUTER_SQUARE_BRACKET } },
+ { { NONE('i'), NONE('[') }, textobj, { .i = TEXT_OBJ_INNER_SQUARE_BRACKET } },
+ { { NONE('i'), NONE(']') }, textobj, { .i = TEXT_OBJ_INNER_SQUARE_BRACKET } },
+ { { NONE('a'), NONE('(') }, textobj, { .i = TEXT_OBJ_OUTER_PARANTHESE } },
+ { { NONE('a'), NONE(')') }, textobj, { .i = TEXT_OBJ_OUTER_PARANTHESE } },
+ { { NONE('a'), NONE('b') }, textobj, { .i = TEXT_OBJ_OUTER_PARANTHESE } },
+ { { NONE('i'), NONE('(') }, textobj, { .i = TEXT_OBJ_INNER_PARANTHESE } },
+ { { NONE('i'), NONE(')') }, textobj, { .i = TEXT_OBJ_INNER_PARANTHESE } },
+ { { NONE('i'), NONE('b') }, textobj, { .i = TEXT_OBJ_INNER_PARANTHESE } },
+ { { NONE('a'), NONE('<') }, textobj, { .i = TEXT_OBJ_OUTER_ANGLE_BRACKET } },
+ { { NONE('a'), NONE('>') }, textobj, { .i = TEXT_OBJ_OUTER_ANGLE_BRACKET } },
+ { { NONE('i'), NONE('<') }, textobj, { .i = TEXT_OBJ_INNER_ANGLE_BRACKET } },
+ { { NONE('i'), NONE('>') }, textobj, { .i = TEXT_OBJ_INNER_ANGLE_BRACKET } },
+ { { NONE('a'), NONE('{') }, textobj, { .i = TEXT_OBJ_OUTER_CURLY_BRACKET } },
+ { { NONE('a'), NONE('}') }, textobj, { .i = TEXT_OBJ_OUTER_CURLY_BRACKET } },
+ { { NONE('a'), NONE('B') }, textobj, { .i = TEXT_OBJ_OUTER_CURLY_BRACKET } },
+ { { NONE('i'), NONE('{') }, textobj, { .i = TEXT_OBJ_INNER_CURLY_BRACKET } },
+ { { NONE('i'), NONE('}') }, textobj, { .i = TEXT_OBJ_INNER_CURLY_BRACKET } },
+ { { NONE('i'), NONE('B') }, textobj, { .i = TEXT_OBJ_INNER_CURLY_BRACKET } },
+ { { NONE('a'), NONE('"') }, textobj, { .i = TEXT_OBJ_OUTER_QUOTE } },
+ { { NONE('i'), NONE('"') }, textobj, { .i = TEXT_OBJ_INNER_QUOTE } },
+ { { NONE('a'), NONE('\'') }, textobj, { .i = TEXT_OBJ_OUTER_SINGLE_QUOTE } },
+ { { NONE('i'), NONE('\'') }, textobj, { .i = TEXT_OBJ_INNER_SINGLE_QUOTE } },
+ { { NONE('a'), NONE('`') }, textobj, { .i = TEXT_OBJ_OUTER_BACKTICK } },
+ { { NONE('i'), NONE('`') }, textobj, { .i = TEXT_OBJ_INNER_BACKTICK } },
+};
+
+static KeyBinding vis_operators[] = {
+ { { NONE('1') }, count, { .i = 1 } },
+ { { NONE('2') }, count, { .i = 2 } },
+ { { NONE('3') }, count, { .i = 3 } },
+ { { NONE('4') }, count, { .i = 4 } },
+ { { NONE('5') }, count, { .i = 5 } },
+ { { NONE('6') }, count, { .i = 6 } },
+ { { NONE('7') }, count, { .i = 7 } },
+ { { NONE('8') }, count, { .i = 8 } },
+ { { NONE('9') }, count, { .i = 9 } },
+ { { NONE('d') }, operator, { .i = OP_DELETE } },
+ { { NONE('c') }, operator, { .i = OP_CHANGE } },
+ { { NONE('y') }, operator, { .i = OP_YANK } },
+ { /* empty last element, array terminator */ },
+};
+
+static KeyBinding vis_registers[] = { /* {a-zA-Z0-9.%#:-"} */
+// { { NONE('"'), NONE('a') }, reg, { .i = 1 } },
+ { /* empty last element, array terminator */ },
+};
+
+static KeyBinding vis_marks[] = { /* {a-zA-Z} */
+// { { NONE('`'), NONE('a') }, mark, { .i = 1 } },
+// { { NONE('\''), NONE('a') }, mark, { .i = 1 } },
+ { /* empty last element, array terminator */ },
+};
+
+static KeyBinding vis_normal[] = {
{ { CONTROL('w'), NONE('c') }, split, { .s = NULL } },
{ { CONTROL('w'), NONE('j') }, call, { .f = editor_window_next } },
{ { CONTROL('w'), NONE('k') }, call, { .f = editor_window_prev } },
- { { NONE('h') }, cursor, { .m = editor_char_prev } },
- { { NONE('l') }, cursor, { .m = editor_char_next } },
- { { NONE('k') }, cursor, { .m = editor_line_up } },
- { { CONTROL('P') }, cursor, { .m = editor_line_up } },
- { { NONE('j') }, cursor, { .m = editor_line_down } },
- { { CONTROL('J') }, cursor, { .m = editor_line_down } },
- { { CONTROL('N') }, cursor, { .m = editor_line_down } },
- { { KEY(ENTER) }, cursor, { .m = editor_line_down } },
- { { NONE('0') }, cursor, { .m = editor_line_begin } },
- { { NONE('^') }, cursor, { .m = editor_line_start } },
- { { NONE('g'), NONE('_') }, cursor, { .m = editor_line_finish } },
- { { NONE('$') }, cursor, { .m = editor_line_end } },
{ { CONTROL('F') }, cursor, { .m = editor_page_up } },
{ { CONTROL('B') }, cursor, { .m = editor_page_down } },
- { { NONE('%') }, cursor, { .m = editor_bracket_match } },
- { { NONE('b') }, cursor, { .m = editor_word_start_prev } },
- { { KEY(SLEFT) }, cursor, { .m = editor_word_start_prev } },
- { { NONE('w') }, cursor, { .m = editor_word_start_next } },
- { { KEY(SRIGHT) }, cursor, { .m = editor_word_start_next } },
- { { NONE('g'), NONE('e') }, cursor, { .m = editor_word_end_prev } },
- { { NONE('e') }, cursor, { .m = editor_word_end_next } },
- { { NONE('}') }, cursor, { .m = editor_paragraph_next } },
- { { NONE('{') }, cursor, { .m = editor_paragraph_prev } },
- { { NONE(')') }, cursor, { .m = editor_sentence_next } },
- { { NONE('(') }, cursor, { .m = editor_sentence_prev } },
- { { NONE('g'), NONE('g') }, cursor, { .m = editor_file_begin } },
- { { NONE('G') }, cursor, { .m = editor_file_end } },
- { /* empty last element, array terminator */ },
-};
-
-static KeyBinding vis_normal[] = {
+ { { NONE('n') }, find_forward, { .s = "if" } },
+ { { NONE('p') }, find_backward, { .s = "if" } },
{ { NONE('x') }, cursor, { .m = editor_delete } },
{ { NONE('i') }, switchmode, { .i = VIS_MODE_INSERT } },
{ { NONE('v') }, switchmode, { .i = VIS_MODE_VISUAL } },
@@ -116,12 +383,6 @@ static KeyBinding vis_normal[] = {
{ { NONE('u') }, call, { .f = editor_undo } },
{ { CONTROL('R') }, call, { .f = editor_redo } },
{ { CONTROL('L') }, call, { .f = editor_draw } },
- // DEMO STUFF
- { { NONE('n') }, find_forward, { .s = "if" } },
- { { NONE('p') }, find_backward, { .s = "if" } },
- { { NONE('5') }, line, { .i = 50 } },
- { { NONE('s') }, mark_set, { .i = 0 } },
- { { NONE('9') }, mark_goto, { .i = 0 } },
{ /* empty last element, array terminator */ },
};
@@ -139,10 +400,10 @@ static void vis_visual_leave(void) {
}
static KeyBinding vis_insert[] = {
- { { NONE(ESC) }, switchmode, { .i = VIS_MODE_NORMAL } },
- { { CONTROL('D') }, cursor, { .m = editor_delete } },
- BACKSPACE( cursor, editor_backspace ),
- { /* empty last element, array terminator */ },
+ { { NONE(ESC) }, switchmode, { .i = VIS_MODE_NORMAL } },
+ { { CONTROL('D') }, cursor, { .m = editor_delete } },
+ BACKSPACE( cursor, m, editor_backspace ),
+ { /* empty last element, array terminator */ },
};
static bool vis_insert_input(const char *str, size_t len) {
@@ -152,8 +413,6 @@ static bool vis_insert_input(const char *str, size_t len) {
static KeyBinding vis_replace[] = {
{ { NONE(ESC) }, switchmode, { .i = VIS_MODE_NORMAL } },
- { { CONTROL('D') }, cursor, { .m = editor_delete } },
- BACKSPACE( cursor, editor_backspace ),
{ /* empty last element, array terminator */ },
};
@@ -165,19 +424,27 @@ static bool vis_replace_input(const char *str, size_t len) {
static Mode vis[] = {
[VIS_MODE_BASIC] = {
.parent = NULL,
- .bindings = movement,
+ .bindings = basic_movement,
},
[VIS_MODE_MOVE] = {
.parent = &vis[VIS_MODE_BASIC],
- .bindings = vis_movement,
+ .bindings = vis_movements,
},
- [VIS_MODE_NORMAL] = {
+ [VIS_MODE_TEXTOBJ] = {
.parent = &vis[VIS_MODE_MOVE],
+ .bindings = vis_textobjs,
+ },
+ [VIS_MODE_OPERATOR] = {
+ .parent = &vis[VIS_MODE_MOVE],
+ .bindings = vis_operators,
+ },
+ [VIS_MODE_NORMAL] = {
+ .parent = &vis[VIS_MODE_OPERATOR],
.bindings = vis_normal,
},
[VIS_MODE_VISUAL] = {
.name = "VISUAL",
- .parent = &vis[VIS_MODE_MOVE],
+ .parent = &vis[VIS_MODE_OPERATOR],
.bindings = vis_visual,
.enter = vis_visual_enter,
.leave = vis_visual_leave,
@@ -190,7 +457,7 @@ static Mode vis[] = {
},
[VIS_MODE_REPLACE] = {
.name = "REPLACE",
- .parent = &vis[VIS_MODE_BASIC],
+ .parent = &vis[VIS_MODE_INSERT],
.bindings = vis_replace,
.input = vis_replace_input,
},
@@ -234,7 +501,7 @@ XXX: CONTROL(' ') = 0, ^Space Go forward one word
#if 1
static KeyBinding nano_keys[] = {
{ { CONTROL('D') }, cursor, { .m = editor_delete } },
- BACKSPACE( cursor, editor_backspace ),
+ BACKSPACE( cursor, m, editor_backspace ),
{ { KEY(LEFT) }, cursor, { .m = editor_char_prev } },
{ { KEY(RIGHT) }, cursor, { .m = editor_char_next } },
{ { CONTROL('F') }, cursor, { .m = editor_char_next } },
@@ -270,7 +537,7 @@ static KeyBinding nano_keys[] = {
#endif
static Mode nano[] = {
- { .parent = NULL, .bindings = movement, },
+ { .parent = NULL, .bindings = basic_movement, },
{ .parent = &nano[0], .bindings = nano_keys, .input = vis_insert_input, },
};