aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-09-04 07:52:14 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-09-04 07:52:14 +0200
commitd4dfde906022618bd9e0cbcd3559625186f77407 (patch)
treee91333e934926335514ece77a7334d1c085d08a5
parent2deb344c3122e91a745734ce77b3e0967f169c2a (diff)
downloadvis-d4dfde906022618bd9e0cbcd3559625186f77407.tar.gz
vis-d4dfde906022618bd9e0cbcd3559625186f77407.tar.xz
Implement rudimentary mark handling
-rw-r--r--config.def.h95
-rw-r--r--vis.c15
-rw-r--r--vis.h18
3 files changed, 91 insertions, 37 deletions
diff --git a/config.def.h b/config.def.h
index fa08c98..82052e0 100644
--- a/config.def.h
+++ b/config.def.h
@@ -19,6 +19,9 @@ static void switchmode_to(Mode *new_mode);
enum {
VIS_MODE_BASIC,
+ VIS_MODE_MARK,
+ VIS_MODE_MARK_LINE,
+ VIS_MODE_MARK_SET,
VIS_MODE_MOVE,
VIS_MODE_TEXTOBJ,
VIS_MODE_OPERATOR,
@@ -59,6 +62,18 @@ void op_paste(OperatorContext *c) {
window_cursor_to(vis->win->win, pos + c->reg->len);
}
+static void mark_set(const Arg *arg) {
+ text_mark_set(vis->win->text, arg->i, window_cursor_get(vis->win->win));
+}
+
+static size_t mark_goto(const Arg *arg) {
+ return text_mark_get(vis->win->text, action.mark);
+}
+
+static size_t mark_line_goto(const Arg *arg) {
+ return text_line_start(vis->win->text, mark_goto(arg));
+}
+
static Operator ops[] = {
[OP_DELETE] = { op_delete, false },
[OP_CHANGE] = { op_change, false },
@@ -86,6 +101,8 @@ enum {
MOVE_BRACKET_MATCH,
MOVE_FILE_BEGIN,
MOVE_FILE_END,
+ MOVE_MARK,
+ MOVE_MARK_LINE,
};
static Movement moves[] = {
@@ -108,6 +125,8 @@ static Movement moves[] = {
[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 },
+ [MOVE_MARK] = { .cmd = mark_goto, .type = LINEWISE },
+ [MOVE_MARK_LINE] = { .cmd = mark_line_goto, .type = LINEWISE },
};
enum {
@@ -184,15 +203,6 @@ static void split(const Arg *arg) {
vis_window_split(vis, arg->s);
}
-static void mark_set(const Arg *arg) {
- vis_mark_set(vis, arg->i, window_cursor_get(vis->win->win));
-}
-
-static void mark_goto(const Arg *arg) {
- vis_mark_goto(vis, arg->i);
-}
-
-
void action_do(Action *a);
void action_reset(Action *a);
@@ -246,6 +256,18 @@ static void reg(const Arg *arg) {
action.reg = &vis->registers[arg->i];
}
+static void mark(const Arg *arg) {
+ action.mark = arg->i;
+ action.movement = &moves[MOVE_MARK];
+ action_do(&action);
+}
+
+static void mark_line(const Arg *arg) {
+ action.mark = arg->i;
+ action.movement = &moves[MOVE_MARK_LINE];
+ action_do(&action);
+}
+
void action_reset(Action *a) {
a->count = 1;
a->linewise = false;
@@ -270,11 +292,22 @@ void action_do(Action *a) {
for (int i = 0; i < a->count; i++) {
if (a->movement->txt)
pos = a->movement->txt(txt, pos);
- else
+ else if (a->movement->win)
pos = a->movement->win(win);
+ else
+ pos = a->movement->cmd(&a->arg);
+ if (pos == (size_t)-1)
+ break;
}
- c.range.start = MIN(start, pos);
- c.range.end = MAX(start, pos);
+
+ if (pos == (size_t)-1) {
+ c.range.start = start;
+ c.range.end = start;
+ } else {
+ c.range.start = MIN(start, pos);
+ c.range.end = MAX(start, pos);
+ }
+
if (!a->op) {
if (a->movement->type & CHARWISE)
window_scroll_to(win, pos);
@@ -461,8 +494,23 @@ static KeyBinding vis_registers[] = { /* {a-zA-Z0-9.%#:-"} */
};
static KeyBinding vis_marks[] = { /* {a-zA-Z} */
-// { { NONE('`'), NONE('a') }, mark, { .i = 1 } },
-// { { NONE('\''), NONE('a') }, mark, { .i = 1 } },
+ { { NONE('`'), NONE('a') }, mark, { .i = MARK_a } },
+ { { NONE('`'), NONE('b') }, mark, { .i = MARK_b } },
+ { { NONE('`'), NONE('c') }, mark, { .i = MARK_c } },
+ { /* empty last element, array terminator */ },
+};
+
+static KeyBinding vis_marks_line[] = { /* {a-zA-Z} */
+ { { NONE('\''), NONE('a') }, mark_line, { .i = MARK_a } },
+ { { NONE('\''), NONE('b') }, mark_line, { .i = MARK_b } },
+ { { NONE('\''), NONE('c') }, mark_line, { .i = MARK_c } },
+ { /* empty last element, array terminator */ },
+};
+
+static KeyBinding vis_marks_set[] = { /* {a-zA-Z} */
+ { { NONE('m'), NONE('a') }, mark_set, { .i = MARK_a } },
+ { { NONE('m'), NONE('b') }, mark_set, { .i = MARK_b } },
+ { { NONE('m'), NONE('c') }, mark_set, { .i = MARK_c } },
{ /* empty last element, array terminator */ },
};
@@ -526,9 +574,19 @@ static Mode vis_modes[] = {
.parent = NULL,
.bindings = basic_movement,
},
+ [VIS_MODE_MARK] = {
+ .name = "MARK",
+ .parent = &vis_modes[VIS_MODE_BASIC],
+ .bindings = vis_marks,
+ },
+ [VIS_MODE_MARK_LINE] = {
+ .name = "MARK-LINE",
+ .parent = &vis_modes[VIS_MODE_MARK],
+ .bindings = vis_marks_line,
+ },
[VIS_MODE_MOVE] = {
.name = "MOVE",
- .parent = &vis_modes[VIS_MODE_BASIC],
+ .parent = &vis_modes[VIS_MODE_MARK_LINE],
.bindings = vis_movements,
},
[VIS_MODE_TEXTOBJ] = {
@@ -554,9 +612,14 @@ static Mode vis_modes[] = {
.parent = &vis_modes[VIS_MODE_OPERATOR],
.bindings = vis_registers,
},
+ [VIS_MODE_MARK_SET] = {
+ .name = "MARK-SET",
+ .parent = &vis_modes[VIS_MODE_REGISTER],
+ .bindings = vis_marks_set,
+ },
[VIS_MODE_NORMAL] = {
.name = "NORMAL",
- .parent = &vis_modes[VIS_MODE_REGISTER],
+ .parent = &vis_modes[VIS_MODE_MARK_SET],
.bindings = vis_normal,
},
[VIS_MODE_VISUAL] = {
diff --git a/vis.c b/vis.c
index a83db2c..68928e8 100644
--- a/vis.c
+++ b/vis.c
@@ -192,21 +192,6 @@ void vis_window_prev(Vis *vis) {
vis_window_statusbar_draw(vis->win);
}
-void vis_mark_set(Vis *vis, Mark mark, size_t pos) {
- text_mark_set(vis->win->text, mark, pos);
-}
-
-void vis_mark_goto(Vis *vis, Mark mark) {
- VisWin *win = vis->win;
- size_t pos = text_mark_get(win->text, mark);
- if (pos != (size_t)-1)
- window_cursor_to(win->win, pos);
-}
-
-void vis_mark_clear(Vis *vis, Mark mark) {
- text_mark_clear(vis->win->text, mark);
-}
-
static void vis_windows_invalidate(Vis *vis, size_t start, size_t end) {
for (VisWin *win = vis->windows; win; win = win->next) {
if (vis->win != win && vis->win->text == win->text) {
diff --git a/vis.h b/vis.h
index 9c88c4e..5157842 100644
--- a/vis.h
+++ b/vis.h
@@ -32,6 +32,15 @@ enum Reg {
REG_LAST,
};
+enum Mark {
+ MARK_a,
+ MARK_b,
+ MARK_c,
+ // ...
+ MARK_z,
+ MARK_LAST,
+};
+
struct Vis {
int width, height; /* terminal size, available for all windows */
VisWin *windows; /* list of windows */
@@ -91,6 +100,7 @@ typedef struct {
} Operator;
typedef struct {
+ size_t (*cmd)(const Arg*);
size_t (*win)(Win*);
size_t (*txt)(Text*, size_t pos);
enum {
@@ -117,6 +127,8 @@ typedef struct {
Movement *movement;
TextObject *textobj;
Register *reg;
+ Mark mark;
+ Arg arg;
} Action;
typedef struct {
@@ -157,12 +169,6 @@ void vis_delete_key(Vis*);
void vis_insert(Vis*, size_t pos, const char *data, size_t len);
void vis_delete(Vis*, size_t pos, size_t len);
-// mark handling
-typedef int Mark;
-void vis_mark_set(Vis*, Mark, size_t pos);
-void vis_mark_goto(Vis*, Mark);
-void vis_mark_clear(Vis*, Mark);
-
// TODO comment
bool vis_syntax_load(Vis*, Syntax *syntaxes, Color *colors);
void vis_syntax_unload(Vis*);