aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-09-08 17:27:25 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-09-08 17:27:25 +0200
commite7b6ac1574ba4dad280e6a45beb52dac4e3ea2e9 (patch)
treec77ced81181dcb972afc2b52e7425ddc29228319
parent403ee5284a70f778b379041c169f72a7586c59ee (diff)
downloadvis-e7b6ac1574ba4dad280e6a45beb52dac4e3ea2e9.tar.gz
vis-e7b6ac1574ba4dad280e6a45beb52dac4e3ea2e9.tar.xz
Hook up search as a movement
-rw-r--r--config.def.h44
-rw-r--r--main.c10
-rw-r--r--text-motions.c30
-rw-r--r--text-motions.h3
-rw-r--r--text.c6
-rw-r--r--text.h4
-rw-r--r--vis.c51
-rw-r--r--vis.h4
8 files changed, 77 insertions, 75 deletions
diff --git a/config.def.h b/config.def.h
index f93bbac..3b5437e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -68,6 +68,16 @@ void op_paste(OperatorContext *c) {
window_cursor_to(vis->win->win, pos + c->reg->len);
}
+static size_t search_forward(const Arg *arg) {
+ size_t pos = window_cursor_get(vis->win->win);
+ return text_search_forward(vis->win->text, pos, vis->search_pattern);
+}
+
+static size_t search_backward(const Arg *arg) {
+ size_t pos = window_cursor_get(vis->win->win);
+ return text_search_backward(vis->win->text, pos, vis->search_pattern);
+}
+
static void mark_set(const Arg *arg) {
text_mark_set(vis->win->text, arg->i, window_cursor_get(vis->win->win));
}
@@ -165,6 +175,8 @@ enum {
MOVE_FILE_END,
MOVE_MARK,
MOVE_MARK_LINE,
+ MOVE_SEARCH_FORWARD,
+ MOVE_SEARCH_BACKWARD,
};
static Movement moves[] = {
@@ -195,6 +207,8 @@ static Movement moves[] = {
[MOVE_RIGHT_TILL] = { .cmd = till, .type = LINEWISE },
[MOVE_MARK] = { .cmd = mark_goto, .type = LINEWISE },
[MOVE_MARK_LINE] = { .cmd = mark_line_goto, .type = LINEWISE },
+ [MOVE_SEARCH_FORWARD] = { .cmd = search_forward, .type = LINEWISE },
+ [MOVE_SEARCH_BACKWARD] = { .cmd = search_backward, .type = LINEWISE },
};
enum {
@@ -477,8 +491,24 @@ static void prompt(const Arg *arg) {
static void prompt_enter(const Arg *arg) {
char *s = vis_prompt_get(vis);
fprintf(stderr, "prompt: %s\n", s);
- free(s);
switchmode(&(const Arg){ .i = VIS_MODE_NORMAL });
+ switch (vis->prompt->title[0]) {
+ case '/':
+ case '?':
+ text_regex_free(vis->search_pattern);
+ if (!(vis->search_pattern = text_regex_new()) ||
+ text_regex_compile(vis->search_pattern, s, REG_EXTENDED)) {
+ action_reset(&action);
+ } else {
+ movement(&(const Arg){ .i = vis->prompt->title[0] == '/' ?
+ MOVE_SEARCH_FORWARD : MOVE_SEARCH_BACKWARD });
+ }
+ break;
+ case ':':
+ /* TODO : parse command */
+ break;
+ }
+ free(s);
}
static void prompt_up(const Arg *arg) {
@@ -526,7 +556,7 @@ static KeyBinding basic_movement[] = {
static KeyBinding vis_movements[] = {
BACKSPACE( movement, i, MOVE_CHAR_PREV ),
- { { NONE('H') }, 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 } },
@@ -554,7 +584,9 @@ static KeyBinding vis_movements[] = {
{ { NONE('F') }, movement_key, { .i = MOVE_LEFT_TO } },
{ { NONE('t') }, movement_key, { .i = MOVE_RIGHT_TILL } },
{ { NONE('T') }, movement_key, { .i = MOVE_LEFT_TILL } },
- { /* empty last element, array terminator */ },
+ { { NONE('/') }, prompt, { .s = "/" } },
+ { { NONE('?') }, prompt, { .s = "?" } },
+ { /* empty last element, array terminator */ },
};
// TODO: factor out prefix [ia] into spearate mode which sets a flag
@@ -660,8 +692,8 @@ static KeyBinding vis_normal[] = {
{ { CONTROL('F') }, cursor, { .m = window_page_up } },
{ { CONTROL('B') }, cursor, { .m = window_page_down } },
{ { NONE('.') }, repeat, { } },
- { { NONE('n') }, find_forward, { .s = "if" } },
- { { NONE('N') }, find_backward, { .s = "if" } },
+ { { NONE('n') }, movement, { .i = MOVE_SEARCH_FORWARD } },
+ { { NONE('N') }, movement, { .i = MOVE_SEARCH_BACKWARD } },
{ { NONE('x') }, call, { .f = vis_delete_key } },
{ { NONE('i') }, switchmode, { .i = VIS_MODE_INSERT } },
{ { NONE('v') }, switchmode, { .i = VIS_MODE_VISUAL } },
@@ -670,8 +702,6 @@ static KeyBinding vis_normal[] = {
{ { CONTROL('R') }, call, { .f = vis_redo } },
{ { CONTROL('L') }, call, { .f = vis_draw } },
{ { NONE(':') }, prompt, { .s = ":" } },
- { { NONE('/') }, prompt, { .s = "/" } },
- { { NONE('?') }, prompt, { .s = "?" } },
{ /* empty last element, array terminator */ },
};
diff --git a/main.c b/main.c
index 18bb5b4..7078f44 100644
--- a/main.c
+++ b/main.c
@@ -104,8 +104,6 @@ typedef struct {
static Key getkey(void);
static void cursor(const Arg *arg);
static void call(const Arg *arg);
-static void find_forward(const Arg *arg);
-static void find_backward(const Arg *arg);
#include "config.h"
@@ -119,14 +117,6 @@ static void call(const Arg *arg) {
arg->f(vis);
}
-static void find_forward(const Arg *arg) {
- vis_search(vis, arg->s, 1);
-}
-
-static void find_backward(const Arg *arg) {
- vis_search(vis, arg->s, -1);
-}
-
typedef struct Screen Screen;
static struct Screen {
int w, h;
diff --git a/text-motions.c b/text-motions.c
index fc87950..7696ff0 100644
--- a/text-motions.c
+++ b/text-motions.c
@@ -296,3 +296,33 @@ size_t text_bracket_match(Text *txt, size_t pos) {
return pos; /* no match found */
}
+
+size_t text_search_forward(Text *txt, size_t pos, Regex *regex) {
+ int start = pos + 1;
+ int end = text_size(txt);
+ RegexMatch match[1];
+ bool found = !text_search_range_forward(txt, start, end - start, regex, 1, match, 0);
+
+ if (!found) {
+ start = 0;
+ end = pos;
+ found = !text_search_range_forward(txt, start, end, regex, 1, match, 0);
+ }
+
+ return found ? match[0].start : pos;
+}
+
+size_t text_search_backward(Text *txt, size_t pos, Regex *regex) {
+ int start = 0;
+ int end = pos;
+ RegexMatch match[1];
+ bool found = !text_search_range_backward(txt, start, end, regex, 1, match, 0);
+
+ if (!found) {
+ start = pos + 1;
+ end = text_size(txt);
+ found = !text_search_range_backward(txt, start, end - start, regex, 1, match, 0);
+ }
+
+ return found ? match[0].start : pos;
+}
diff --git a/text-motions.h b/text-motions.h
index aa87170..b99815d 100644
--- a/text-motions.h
+++ b/text-motions.h
@@ -65,4 +65,7 @@ size_t text_section_prev(Text*, size_t pos);
/* search coresponding '(', ')', '{', '}', '[', ']', '>', '<', '"', ''' */
size_t text_bracket_match(Text*, size_t pos);
+size_t text_search_forward(Text *txt, size_t pos, Regex *regex);
+size_t text_search_backward(Text *txt, size_t pos, Regex *regex);
+
#endif
diff --git a/text.c b/text.c
index 8c775da..3e7ce40 100644
--- a/text.c
+++ b/text.c
@@ -1055,10 +1055,12 @@ int text_regex_compile(Regex *regex, const char *string, int cflags) {
}
void text_regex_free(Regex *r) {
+ if (!r)
+ return;
regfree(&r->regex);
}
-int text_search_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
+int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
char *buf = malloc(len + 1);
if (!buf)
return REG_NOMATCH;
@@ -1076,7 +1078,7 @@ int text_search_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmat
return ret;
}
-int text_search_backward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
+int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
char *buf = malloc(len + 1);
if (!buf)
return REG_NOMATCH;
diff --git a/text.h b/text.h
index 27693ef..ea490b3 100644
--- a/text.h
+++ b/text.h
@@ -72,8 +72,8 @@ typedef struct {
Regex *text_regex_new(void);
int text_regex_compile(Regex *r, const char *regex, int cflags);
void text_regex_free(Regex *r);
-int text_search_forward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);
-int text_search_backward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);
+int text_search_range_forward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);
+int text_search_range_backward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);
// TMP
void text_debug(Text*);
diff --git a/vis.c b/vis.c
index 8487a69..ec5bf6d 100644
--- a/vis.c
+++ b/vis.c
@@ -9,8 +9,6 @@ static void vis_window_free(VisWin *win);
static void vis_window_split_internal(Vis *vis, const char *filename);
static void vis_windows_invalidate(Vis *vis, size_t start, size_t end);
static void vis_window_draw(VisWin *win);
-static void vis_search_forward(Vis *vis, Regex *regex);
-static void vis_search_backward(Vis *vis, Regex *regex);
static void vis_windows_arrange_horizontal(Vis *vis);
static void vis_windows_arrange_vertical(Vis *vis);
@@ -53,55 +51,6 @@ void vis_statusbar_set(Vis *vis, vis_statusbar_t statusbar) {
vis->statusbar = statusbar;
}
-static void vis_search_forward(Vis *vis, Regex *regex) {
- VisWin *win = vis->win;
- int pos = window_cursor_get(win->win) + 1;
- int end = text_size(win->text);
- RegexMatch match[1];
- bool found = false;
- if (text_search_forward(win->text, pos, end - pos, regex, 1, match, 0)) {
- pos = 0;
- end = window_cursor_get(win->win);
- if (!text_search_forward(win->text, pos, end, regex, 1, match, 0))
- found = true;
- } else {
- found = true;
- }
- if (found)
- window_cursor_to(win->win, match[0].start);
-}
-
-static void vis_search_backward(Vis *vis, Regex *regex) {
- VisWin *win = vis->win;
- int pos = 0;
- int end = window_cursor_get(win->win);
- RegexMatch match[1];
- bool found = false;
- if (text_search_backward(win->text, pos, end, regex, 1, match, 0)) {
- pos = window_cursor_get(win->win) + 1;
- end = text_size(win->text);
- if (!text_search_backward(win->text, pos, end - pos, regex, 1, match, 0))
- found = true;
- } else {
- found = true;
- }
- if (found)
- window_cursor_to(win->win, match[0].start);
-}
-
-void vis_search(Vis *vis, const char *s, int direction) {
- Regex *regex = text_regex_new();
- if (!regex)
- return;
- if (!text_regex_compile(regex, s, REG_EXTENDED)) {
- if (direction >= 0)
- vis_search_forward(vis, regex);
- else
- vis_search_backward(vis, regex);
- }
- text_regex_free(regex);
-}
-
void vis_snapshot(Vis *vis) {
text_snapshot(vis->win->text);
}
diff --git a/vis.h b/vis.h
index b35208e..3fc9dad 100644
--- a/vis.h
+++ b/vis.h
@@ -56,6 +56,7 @@ struct Vis {
Syntax *syntaxes; /* NULL terminated array of syntax definitions */
Register registers[REG_LAST];
Prompt *prompt;
+ Regex *search_pattern;
void (*windows_arrange)(Vis*); /* current layout which places the windows */
vis_statusbar_t statusbar; /* configurable user hook to draw statusbar */
};
@@ -103,15 +104,12 @@ void vis_delete(Vis*, size_t pos, size_t len);
bool vis_syntax_load(Vis*, Syntax *syntaxes, Color *colors);
void vis_syntax_unload(Vis*);
-void vis_search(Vis*, const char *regex, int direction);
-
bool vis_window_new(Vis*, const char *filename);
void vis_window_split(Vis*, const char *filename);
void vis_window_vsplit(Vis*, const char *filename);
void vis_window_next(Vis*);
void vis_window_prev(Vis*);
-
char *vis_prompt_get(Vis *vis);
void vis_prompt_set(Vis *vis, const char *line);
void vis_prompt_show(Vis *vis, const char *title);