diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-09-08 17:27:25 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-09-08 17:27:25 +0200 |
| commit | e7b6ac1574ba4dad280e6a45beb52dac4e3ea2e9 (patch) | |
| tree | c77ced81181dcb972afc2b52e7425ddc29228319 | |
| parent | 403ee5284a70f778b379041c169f72a7586c59ee (diff) | |
| download | vis-e7b6ac1574ba4dad280e6a45beb52dac4e3ea2e9.tar.gz vis-e7b6ac1574ba4dad280e6a45beb52dac4e3ea2e9.tar.xz | |
Hook up search as a movement
| -rw-r--r-- | config.def.h | 44 | ||||
| -rw-r--r-- | main.c | 10 | ||||
| -rw-r--r-- | text-motions.c | 30 | ||||
| -rw-r--r-- | text-motions.h | 3 | ||||
| -rw-r--r-- | text.c | 6 | ||||
| -rw-r--r-- | text.h | 4 | ||||
| -rw-r--r-- | vis.c | 51 | ||||
| -rw-r--r-- | vis.h | 4 |
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 */ }, }; @@ -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 @@ -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; @@ -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*); @@ -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); } @@ -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); |
