From d34ed26989a4775c3b5fd97355d72ef4a6552c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Fri, 6 Nov 2015 22:05:44 +0100 Subject: vis: move motions to separate file --- vis-core.h | 2 + vis-motions.c | 269 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vis.c | 262 -------------------------------------------------------- vis.h | 1 + 4 files changed, 272 insertions(+), 262 deletions(-) create mode 100644 vis-motions.c diff --git a/vis-core.h b/vis-core.h index 564ab69..21c6be4 100644 --- a/vis-core.h +++ b/vis-core.h @@ -158,4 +158,6 @@ struct Vis { /* TODO: make part of Vis struct? enable dynamic modes? */ extern Mode vis_modes[VIS_MODE_LAST]; +extern Movement moves[MOVE_INVALID]; + #endif \ No newline at end of file diff --git a/vis-motions.c b/vis-motions.c new file mode 100644 index 0000000..b0a6f09 --- /dev/null +++ b/vis-motions.c @@ -0,0 +1,269 @@ +#include "vis-core.h" +#include "text-motions.h" +#include "text-objects.h" +#include "text-util.h" + +/** movements which can be used besides the one in text-motions.h and view.h */ + +/* search in forward direction for the word under the cursor */ +static size_t search_word_forward(Vis*, Text *txt, size_t pos); +/* search in backward direction for the word under the cursor */ +static size_t search_word_backward(Vis*, Text *txt, size_t pos); +/* search again for the last used search pattern */ +static size_t search_forward(Vis*, Text *txt, size_t pos); +static size_t search_backward(Vis*, Text *txt, size_t pos); +/* goto action.mark */ +static size_t mark_goto(Vis*, File *txt, size_t pos); +/* goto first non-blank char on line pointed by action.mark */ +static size_t mark_line_goto(Vis*, File *txt, size_t pos); +/* goto to next occurence of action.key to the right */ +static size_t to(Vis*, Text *txt, size_t pos); +/* goto to position before next occurence of action.key to the right */ +static size_t till(Vis*, Text *txt, size_t pos); +/* goto to next occurence of action.key to the left */ +static size_t to_left(Vis*, Text *txt, size_t pos); +/* goto to position after next occurence of action.key to the left */ +static size_t till_left(Vis*, Text *txt, size_t pos); +/* goto line number action.count */ +static size_t line(Vis*, Text *txt, size_t pos); +/* goto to byte action.count on current line */ +static size_t column(Vis*, Text *txt, size_t pos); +/* goto the action.count-th line from top of the focused window */ +static size_t view_lines_top(Vis*, View*); +/* goto the start of middle line of the focused window */ +static size_t view_lines_middle(Vis*, View*); +/* goto the action.count-th line from bottom of the focused window */ +static size_t view_lines_bottom(Vis*, View*); +/* navigate the change list */ +static size_t window_changelist_next(Vis*, Win*, size_t pos); +static size_t window_changelist_prev(Vis*, Win*, size_t pos); +/* navigate the jump list */ +static size_t window_jumplist_next(Vis*, Win*, size_t pos); +static size_t window_jumplist_prev(Vis*, Win*, size_t pos); +static size_t window_nop(Vis*, Win*, size_t pos); + +Movement moves[] = { + [MOVE_LINE_UP] = { .cur = view_line_up, .type = LINEWISE }, + [MOVE_LINE_DOWN] = { .cur = view_line_down, .type = LINEWISE }, + [MOVE_SCREEN_LINE_UP] = { .cur = view_screenline_up, }, + [MOVE_SCREEN_LINE_DOWN] = { .cur = view_screenline_down, }, + [MOVE_SCREEN_LINE_BEGIN] = { .cur = view_screenline_begin, .type = CHARWISE }, + [MOVE_SCREEN_LINE_MIDDLE] = { .cur = view_screenline_middle, .type = CHARWISE }, + [MOVE_SCREEN_LINE_END] = { .cur = view_screenline_end, .type = CHARWISE|INCLUSIVE }, + [MOVE_LINE_PREV] = { .txt = text_line_prev, }, + [MOVE_LINE_BEGIN] = { .txt = text_line_begin, }, + [MOVE_LINE_START] = { .txt = text_line_start, }, + [MOVE_LINE_FINISH] = { .txt = text_line_finish, .type = INCLUSIVE }, + [MOVE_LINE_LASTCHAR] = { .txt = text_line_lastchar, .type = INCLUSIVE }, + [MOVE_LINE_END] = { .txt = text_line_end, }, + [MOVE_LINE_NEXT] = { .txt = text_line_next, }, + [MOVE_LINE] = { .vis = line, .type = LINEWISE|IDEMPOTENT|JUMP}, + [MOVE_COLUMN] = { .vis = column, .type = CHARWISE|IDEMPOTENT}, + [MOVE_CHAR_PREV] = { .txt = text_char_prev, .type = CHARWISE }, + [MOVE_CHAR_NEXT] = { .txt = text_char_next, .type = CHARWISE }, + [MOVE_LINE_CHAR_PREV] = { .txt = text_line_char_prev, .type = CHARWISE }, + [MOVE_LINE_CHAR_NEXT] = { .txt = text_line_char_next, .type = CHARWISE }, + [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_LONGWORD_START_PREV] = { .txt = text_longword_start_prev, .type = CHARWISE }, + [MOVE_LONGWORD_START_NEXT] = { .txt = text_longword_start_next, .type = CHARWISE }, + [MOVE_LONGWORD_END_PREV] = { .txt = text_longword_end_prev, .type = CHARWISE|INCLUSIVE }, + [MOVE_LONGWORD_END_NEXT] = { .txt = text_longword_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|JUMP }, + [MOVE_PARAGRAPH_NEXT] = { .txt = text_paragraph_next, .type = LINEWISE|JUMP }, + [MOVE_FUNCTION_START_PREV] = { .txt = text_function_start_prev, .type = LINEWISE|JUMP }, + [MOVE_FUNCTION_START_NEXT] = { .txt = text_function_start_next, .type = LINEWISE|JUMP }, + [MOVE_FUNCTION_END_PREV] = { .txt = text_function_end_prev, .type = LINEWISE|JUMP }, + [MOVE_FUNCTION_END_NEXT] = { .txt = text_function_end_next, .type = LINEWISE|JUMP }, + [MOVE_BRACKET_MATCH] = { .txt = text_bracket_match, .type = INCLUSIVE|JUMP }, + [MOVE_FILE_BEGIN] = { .txt = text_begin, .type = LINEWISE|JUMP }, + [MOVE_FILE_END] = { .txt = text_end, .type = LINEWISE|JUMP }, + [MOVE_LEFT_TO] = { .vis = to_left, }, + [MOVE_RIGHT_TO] = { .vis = to, .type = INCLUSIVE }, + [MOVE_LEFT_TILL] = { .vis = till_left, }, + [MOVE_RIGHT_TILL] = { .vis = till, .type = INCLUSIVE }, + [MOVE_MARK] = { .file = mark_goto, .type = JUMP|IDEMPOTENT }, + [MOVE_MARK_LINE] = { .file = mark_line_goto, .type = LINEWISE|JUMP|IDEMPOTENT}, + [MOVE_SEARCH_WORD_FORWARD] = { .vis = search_word_forward, .type = JUMP }, + [MOVE_SEARCH_WORD_BACKWARD]= { .vis = search_word_backward, .type = JUMP }, + [MOVE_SEARCH_NEXT] = { .vis = search_forward, .type = JUMP }, + [MOVE_SEARCH_PREV] = { .vis = search_backward, .type = JUMP }, + [MOVE_WINDOW_LINE_TOP] = { .view = view_lines_top, .type = LINEWISE|JUMP|IDEMPOTENT }, + [MOVE_WINDOW_LINE_MIDDLE] = { .view = view_lines_middle, .type = LINEWISE|JUMP|IDEMPOTENT }, + [MOVE_WINDOW_LINE_BOTTOM] = { .view = view_lines_bottom, .type = LINEWISE|JUMP|IDEMPOTENT }, + [MOVE_CHANGELIST_NEXT] = { .win = window_changelist_next, .type = INCLUSIVE }, + [MOVE_CHANGELIST_PREV] = { .win = window_changelist_prev, .type = INCLUSIVE }, + [MOVE_JUMPLIST_NEXT] = { .win = window_jumplist_next, .type = INCLUSIVE }, + [MOVE_JUMPLIST_PREV] = { .win = window_jumplist_prev, .type = INCLUSIVE }, + [MOVE_NOP] = { .win = window_nop, .type = IDEMPOTENT }, +}; + +/** utility functions */ + +static char *get_word_at(Text *txt, size_t pos) { + Filerange word = text_object_word(txt, pos); + if (!text_range_valid(&word)) + return NULL; + size_t len = word.end - word.start; + char *buf = malloc(len+1); + if (!buf) + return NULL; + len = text_bytes_get(txt, word.start, len, buf); + buf[len] = '\0'; + return buf; +} + +/** movement implementations */ + +static size_t search_word_forward(Vis *vis, Text *txt, size_t pos) { + char *word = get_word_at(txt, pos); + if (word && !text_regex_compile(vis->search_pattern, word, REG_EXTENDED)) + pos = text_search_forward(txt, pos, vis->search_pattern); + free(word); + return pos; +} + +static size_t search_word_backward(Vis *vis, Text *txt, size_t pos) { + char *word = get_word_at(txt, pos); + if (word && !text_regex_compile(vis->search_pattern, word, REG_EXTENDED)) + pos = text_search_backward(txt, pos, vis->search_pattern); + free(word); + return pos; +} + +static size_t search_forward(Vis *vis, Text *txt, size_t pos) { + return text_search_forward(txt, pos, vis->search_pattern); +} + +static size_t search_backward(Vis *vis, Text *txt, size_t pos) { + return text_search_backward(txt, pos, vis->search_pattern); +} + +static size_t mark_goto(Vis *vis, File *file, size_t pos) { + return text_mark_get(file->text, file->marks[vis->action.mark]); +} + +static size_t mark_line_goto(Vis *vis, File *file, size_t pos) { + return text_line_start(file->text, mark_goto(vis, file, pos)); +} + +static size_t to(Vis *vis, Text *txt, size_t pos) { + char c; + size_t hit = text_line_find_next(txt, pos+1, vis->search_char); + if (!text_byte_get(txt, hit, &c) || c != vis->search_char[0]) + return pos; + return hit; +} + +static size_t till(Vis *vis, Text *txt, size_t pos) { + size_t hit = to(vis, txt, pos); + if (hit != pos) + return text_char_prev(txt, hit); + return pos; +} + +static size_t to_left(Vis *vis, Text *txt, size_t pos) { + char c; + if (pos == 0) + return pos; + size_t hit = text_line_find_prev(txt, pos-1, vis->search_char); + if (!text_byte_get(txt, hit, &c) || c != vis->search_char[0]) + return pos; + return hit; +} + +static size_t till_left(Vis *vis, Text *txt, size_t pos) { + size_t hit = to_left(vis, txt, pos); + if (hit != pos) + return text_char_next(txt, hit); + return pos; +} + +static size_t line(Vis *vis, Text *txt, size_t pos) { + return text_pos_by_lineno(txt, vis->action.count); +} + +static size_t column(Vis *vis, Text *txt, size_t pos) { + return text_line_offset(txt, pos, vis->action.count); +} + +static size_t view_lines_top(Vis *vis, View *view) { + return view_screenline_goto(view, vis->action.count); +} + +static size_t view_lines_middle(Vis *vis, View *view) { + int h = view_height_get(view); + return view_screenline_goto(view, h/2); +} + +static size_t view_lines_bottom(Vis *vis, View *view) { + int h = view_height_get(vis->win->view); + return view_screenline_goto(vis->win->view, h - vis->action.count); +} + +static size_t window_changelist_next(Vis *vis, Win *win, size_t pos) { + ChangeList *cl = &win->changelist; + Text *txt = win->file->text; + time_t state = text_state(txt); + if (cl->state != state) + cl->index = 0; + else if (cl->index > 0 && pos == cl->pos) + cl->index--; + size_t newpos = text_history_get(txt, cl->index); + if (newpos == EPOS) + cl->index++; + else + cl->pos = newpos; + cl->state = state; + return cl->pos; +} + +static size_t window_changelist_prev(Vis *vis, Win *win, size_t pos) { + ChangeList *cl = &win->changelist; + Text *txt = win->file->text; + time_t state = text_state(txt); + if (cl->state != state) + cl->index = 0; + else if (pos == cl->pos) + win->changelist.index++; + size_t newpos = text_history_get(txt, cl->index); + if (newpos == EPOS) + cl->index--; + else + cl->pos = newpos; + cl->state = state; + return cl->pos; +} + +static size_t window_jumplist_next(Vis *vis, Win *win, size_t cur) { + while (win->jumplist) { + Mark mark = ringbuf_next(win->jumplist); + if (!mark) + return cur; + size_t pos = text_mark_get(win->file->text, mark); + if (pos != EPOS && pos != cur) + return pos; + } + return cur; +} + +static size_t window_jumplist_prev(Vis *vis, Win *win, size_t cur) { + while (win->jumplist) { + Mark mark = ringbuf_prev(win->jumplist); + if (!mark) + return cur; + size_t pos = text_mark_get(win->file->text, mark); + if (pos != EPOS && pos != cur) + return pos; + } + return cur; +} + +static size_t window_nop(Vis *vis, Win *win, size_t pos) { + return pos; +} + diff --git a/vis.c b/vis.c index 03734f7..6bf64d7 100644 --- a/vis.c +++ b/vis.c @@ -489,105 +489,6 @@ static Operator ops[] = { [OP_CURSOR_SOL] = { op_cursor }, }; -/** movements which can be used besides the one in text-motions.h and view.h */ - -/* search in forward direction for the word under the cursor */ -static size_t search_word_forward(Vis*, Text *txt, size_t pos); -/* search in backward direction for the word under the cursor */ -static size_t search_word_backward(Vis*, Text *txt, size_t pos); -/* search again for the last used search pattern */ -static size_t search_forward(Vis*, Text *txt, size_t pos); -static size_t search_backward(Vis*, Text *txt, size_t pos); -/* goto action.mark */ -static size_t mark_goto(Vis*, File *txt, size_t pos); -/* goto first non-blank char on line pointed by action.mark */ -static size_t mark_line_goto(Vis*, File *txt, size_t pos); -/* goto to next occurence of action.key to the right */ -static size_t to(Vis*, Text *txt, size_t pos); -/* goto to position before next occurence of action.key to the right */ -static size_t till(Vis*, Text *txt, size_t pos); -/* goto to next occurence of action.key to the left */ -static size_t to_left(Vis*, Text *txt, size_t pos); -/* goto to position after next occurence of action.key to the left */ -static size_t till_left(Vis*, Text *txt, size_t pos); -/* goto line number action.count */ -static size_t line(Vis*, Text *txt, size_t pos); -/* goto to byte action.count on current line */ -static size_t column(Vis*, Text *txt, size_t pos); -/* goto the action.count-th line from top of the focused window */ -static size_t view_lines_top(Vis*, View*); -/* goto the start of middle line of the focused window */ -static size_t view_lines_middle(Vis*, View*); -/* goto the action.count-th line from bottom of the focused window */ -static size_t view_lines_bottom(Vis*, View*); -/* navigate the change list */ -static size_t window_changelist_next(Vis*, Win*, size_t pos); -static size_t window_changelist_prev(Vis*, Win*, size_t pos); -/* navigate the jump list */ -static size_t window_jumplist_next(Vis*, Win*, size_t pos); -static size_t window_jumplist_prev(Vis*, Win*, size_t pos); -static size_t window_nop(Vis*, Win*, size_t pos); - -static Movement moves[] = { - [MOVE_LINE_UP] = { .cur = view_line_up, .type = LINEWISE }, - [MOVE_LINE_DOWN] = { .cur = view_line_down, .type = LINEWISE }, - [MOVE_SCREEN_LINE_UP] = { .cur = view_screenline_up, }, - [MOVE_SCREEN_LINE_DOWN] = { .cur = view_screenline_down, }, - [MOVE_SCREEN_LINE_BEGIN] = { .cur = view_screenline_begin, .type = CHARWISE }, - [MOVE_SCREEN_LINE_MIDDLE] = { .cur = view_screenline_middle, .type = CHARWISE }, - [MOVE_SCREEN_LINE_END] = { .cur = view_screenline_end, .type = CHARWISE|INCLUSIVE }, - [MOVE_LINE_PREV] = { .txt = text_line_prev, }, - [MOVE_LINE_BEGIN] = { .txt = text_line_begin, }, - [MOVE_LINE_START] = { .txt = text_line_start, }, - [MOVE_LINE_FINISH] = { .txt = text_line_finish, .type = INCLUSIVE }, - [MOVE_LINE_LASTCHAR] = { .txt = text_line_lastchar, .type = INCLUSIVE }, - [MOVE_LINE_END] = { .txt = text_line_end, }, - [MOVE_LINE_NEXT] = { .txt = text_line_next, }, - [MOVE_LINE] = { .vis = line, .type = LINEWISE|IDEMPOTENT|JUMP}, - [MOVE_COLUMN] = { .vis = column, .type = CHARWISE|IDEMPOTENT}, - [MOVE_CHAR_PREV] = { .txt = text_char_prev, .type = CHARWISE }, - [MOVE_CHAR_NEXT] = { .txt = text_char_next, .type = CHARWISE }, - [MOVE_LINE_CHAR_PREV] = { .txt = text_line_char_prev, .type = CHARWISE }, - [MOVE_LINE_CHAR_NEXT] = { .txt = text_line_char_next, .type = CHARWISE }, - [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_LONGWORD_START_PREV] = { .txt = text_longword_start_prev, .type = CHARWISE }, - [MOVE_LONGWORD_START_NEXT] = { .txt = text_longword_start_next, .type = CHARWISE }, - [MOVE_LONGWORD_END_PREV] = { .txt = text_longword_end_prev, .type = CHARWISE|INCLUSIVE }, - [MOVE_LONGWORD_END_NEXT] = { .txt = text_longword_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|JUMP }, - [MOVE_PARAGRAPH_NEXT] = { .txt = text_paragraph_next, .type = LINEWISE|JUMP }, - [MOVE_FUNCTION_START_PREV] = { .txt = text_function_start_prev, .type = LINEWISE|JUMP }, - [MOVE_FUNCTION_START_NEXT] = { .txt = text_function_start_next, .type = LINEWISE|JUMP }, - [MOVE_FUNCTION_END_PREV] = { .txt = text_function_end_prev, .type = LINEWISE|JUMP }, - [MOVE_FUNCTION_END_NEXT] = { .txt = text_function_end_next, .type = LINEWISE|JUMP }, - [MOVE_BRACKET_MATCH] = { .txt = text_bracket_match, .type = INCLUSIVE|JUMP }, - [MOVE_FILE_BEGIN] = { .txt = text_begin, .type = LINEWISE|JUMP }, - [MOVE_FILE_END] = { .txt = text_end, .type = LINEWISE|JUMP }, - [MOVE_LEFT_TO] = { .vis = to_left, }, - [MOVE_RIGHT_TO] = { .vis = to, .type = INCLUSIVE }, - [MOVE_LEFT_TILL] = { .vis = till_left, }, - [MOVE_RIGHT_TILL] = { .vis = till, .type = INCLUSIVE }, - [MOVE_MARK] = { .file = mark_goto, .type = JUMP|IDEMPOTENT }, - [MOVE_MARK_LINE] = { .file = mark_line_goto, .type = LINEWISE|JUMP|IDEMPOTENT}, - [MOVE_SEARCH_WORD_FORWARD] = { .vis = search_word_forward, .type = JUMP }, - [MOVE_SEARCH_WORD_BACKWARD]= { .vis = search_word_backward, .type = JUMP }, - [MOVE_SEARCH_NEXT] = { .vis = search_forward, .type = JUMP }, - [MOVE_SEARCH_PREV] = { .vis = search_backward, .type = JUMP }, - [MOVE_WINDOW_LINE_TOP] = { .view = view_lines_top, .type = LINEWISE|JUMP|IDEMPOTENT }, - [MOVE_WINDOW_LINE_MIDDLE] = { .view = view_lines_middle, .type = LINEWISE|JUMP|IDEMPOTENT }, - [MOVE_WINDOW_LINE_BOTTOM] = { .view = view_lines_bottom, .type = LINEWISE|JUMP|IDEMPOTENT }, - [MOVE_CHANGELIST_NEXT] = { .win = window_changelist_next, .type = INCLUSIVE }, - [MOVE_CHANGELIST_PREV] = { .win = window_changelist_prev, .type = INCLUSIVE }, - [MOVE_JUMPLIST_NEXT] = { .win = window_jumplist_next, .type = INCLUSIVE }, - [MOVE_JUMPLIST_PREV] = { .win = window_jumplist_prev, .type = INCLUSIVE }, - [MOVE_NOP] = { .win = window_nop, .type = IDEMPOTENT }, -}; - static TextObject textobjs[] = { [TEXT_OBJ_INNER_WORD] = { text_object_word }, [TEXT_OBJ_OUTER_WORD] = { text_object_word_outer }, @@ -1098,169 +999,6 @@ static size_t op_replace(Vis *vis, Text *txt, OperatorContext *c) { return c->newpos != EPOS ? c->newpos : c->pos; } -/** movement implementations of type: size_t (*move)(const Arg*) */ - -static char *get_word_at(Text *txt, size_t pos) { - Filerange word = text_object_word(txt, pos); - if (!text_range_valid(&word)) - return NULL; - size_t len = word.end - word.start; - char *buf = malloc(len+1); - if (!buf) - return NULL; - len = text_bytes_get(txt, word.start, len, buf); - buf[len] = '\0'; - return buf; -} - -static size_t search_word_forward(Vis *vis, Text *txt, size_t pos) { - char *word = get_word_at(txt, pos); - if (word && !text_regex_compile(vis->search_pattern, word, REG_EXTENDED)) - pos = text_search_forward(txt, pos, vis->search_pattern); - free(word); - return pos; -} - -static size_t search_word_backward(Vis *vis, Text *txt, size_t pos) { - char *word = get_word_at(txt, pos); - if (word && !text_regex_compile(vis->search_pattern, word, REG_EXTENDED)) - pos = text_search_backward(txt, pos, vis->search_pattern); - free(word); - return pos; -} - -static size_t search_forward(Vis *vis, Text *txt, size_t pos) { - return text_search_forward(txt, pos, vis->search_pattern); -} - -static size_t search_backward(Vis *vis, Text *txt, size_t pos) { - return text_search_backward(txt, pos, vis->search_pattern); -} - -static size_t mark_goto(Vis *vis, File *file, size_t pos) { - return text_mark_get(file->text, file->marks[vis->action.mark]); -} - -static size_t mark_line_goto(Vis *vis, File *file, size_t pos) { - return text_line_start(file->text, mark_goto(vis, file, pos)); -} - -static size_t to(Vis *vis, Text *txt, size_t pos) { - char c; - size_t hit = text_line_find_next(txt, pos+1, vis->search_char); - if (!text_byte_get(txt, hit, &c) || c != vis->search_char[0]) - return pos; - return hit; -} - -static size_t till(Vis *vis, Text *txt, size_t pos) { - size_t hit = to(vis, txt, pos); - if (hit != pos) - return text_char_prev(txt, hit); - return pos; -} - -static size_t to_left(Vis *vis, Text *txt, size_t pos) { - char c; - if (pos == 0) - return pos; - size_t hit = text_line_find_prev(txt, pos-1, vis->search_char); - if (!text_byte_get(txt, hit, &c) || c != vis->search_char[0]) - return pos; - return hit; -} - -static size_t till_left(Vis *vis, Text *txt, size_t pos) { - size_t hit = to_left(vis, txt, pos); - if (hit != pos) - return text_char_next(txt, hit); - return pos; -} - -static size_t line(Vis *vis, Text *txt, size_t pos) { - return text_pos_by_lineno(txt, vis->action.count); -} - -static size_t column(Vis *vis, Text *txt, size_t pos) { - return text_line_offset(txt, pos, vis->action.count); -} - -static size_t view_lines_top(Vis *vis, View *view) { - return view_screenline_goto(view, vis->action.count); -} - -static size_t view_lines_middle(Vis *vis, View *view) { - int h = view_height_get(view); - return view_screenline_goto(view, h/2); -} - -static size_t view_lines_bottom(Vis *vis, View *view) { - int h = view_height_get(vis->win->view); - return view_screenline_goto(vis->win->view, h - vis->action.count); -} - -static size_t window_changelist_next(Vis *vis, Win *win, size_t pos) { - ChangeList *cl = &win->changelist; - Text *txt = win->file->text; - time_t state = text_state(txt); - if (cl->state != state) - cl->index = 0; - else if (cl->index > 0 && pos == cl->pos) - cl->index--; - size_t newpos = text_history_get(txt, cl->index); - if (newpos == EPOS) - cl->index++; - else - cl->pos = newpos; - cl->state = state; - return cl->pos; -} - -static size_t window_changelist_prev(Vis *vis, Win *win, size_t pos) { - ChangeList *cl = &win->changelist; - Text *txt = win->file->text; - time_t state = text_state(txt); - if (cl->state != state) - cl->index = 0; - else if (pos == cl->pos) - win->changelist.index++; - size_t newpos = text_history_get(txt, cl->index); - if (newpos == EPOS) - cl->index--; - else - cl->pos = newpos; - cl->state = state; - return cl->pos; -} - -static size_t window_jumplist_next(Vis *vis, Win *win, size_t cur) { - while (win->jumplist) { - Mark mark = ringbuf_next(win->jumplist); - if (!mark) - return cur; - size_t pos = text_mark_get(win->file->text, mark); - if (pos != EPOS && pos != cur) - return pos; - } - return cur; -} - -static size_t window_jumplist_prev(Vis *vis, Win *win, size_t cur) { - while (win->jumplist) { - Mark mark = ringbuf_prev(win->jumplist); - if (!mark) - return cur; - size_t pos = text_mark_get(win->file->text, mark); - if (pos != EPOS && pos != cur) - return pos; - } - return cur; -} - -static size_t window_nop(Vis *vis, Win *win, size_t pos) { - return pos; -} - /** action processing: execut the operator / movement / text object */ static void window_jumplist_add(Win *win, size_t pos) { diff --git a/vis.h b/vis.h index 78d8ad1..b3871b6 100644 --- a/vis.h +++ b/vis.h @@ -209,6 +209,7 @@ enum VisMotion { MOVE_JUMPLIST_NEXT, MOVE_JUMPLIST_PREV, MOVE_NOP, + MOVE_INVALID, /* pseudo motions: keep them at the end to save space in array definition */ MOVE_TOTILL_REPEAT, MOVE_TOTILL_REVERSE, -- cgit v1.2.3