From f8f35f3fda9faf1c410c74d048c1e6b91f154426 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Sun, 14 Jun 2015 15:52:51 -0400 Subject: [PATCH] Enable wrapping around when searching Configurable via `wrap-search`, on by default. --- NEWS.adoc | 1 + include/tig/options.h | 1 + src/search.c | 51 ++++++++++++++++++++++++++++++++++----------------- tigrc | 1 + 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/NEWS.adoc b/NEWS.adoc index e3a1fe9..a94d17a 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -17,6 +17,7 @@ Improvements: - See `contrib/vim.tigrc` for Vim-like keybindings. (GH #273, #351) - Add GitHub inspired file finder to search for and open any file. (GH #342) - Highlight search results, configurable via `search-result` color. + - Wrap around when searching, configurable via `wrap-search` setting. - Add `search` keymap for navigation file finder search results. - Populate `%(file)` with file names from diff stat. (GH #404) - `tig --merge` implies `--boundary` similar to gitk. diff --git a/include/tig/options.h b/include/tig/options.h index cc38b12..8805c80 100644 --- a/include/tig/options.h +++ b/include/tig/options.h @@ -71,6 +71,7 @@ typedef struct view_column *view_settings; _(tree_view, view_settings, VIEW_NO_FLAGS) \ _(vertical_split, enum vertical_split, VIEW_RESET_DISPLAY | VIEW_DIFF_LIKE) \ _(wrap_lines, bool, VIEW_NO_FLAGS) \ + _(wrap_search, bool, VIEW_NO_FLAGS) \ #define DEFINE_OPTION_EXTERNS(name, type, flags) extern type opt_##name; OPTION_INFO(DEFINE_OPTION_EXTERNS) diff --git a/src/search.c b/src/search.c index c64b4cf..0bac7ef 100644 --- a/src/search.c +++ b/src/search.c @@ -86,10 +86,39 @@ setup_and_find_next(struct view *view, enum request request) } static enum status_code +find_next_match_line(struct view *view, int direction, bool wrapped) +{ + /* Note, `i` is unsigned and will wrap around in which case it + * will become bigger than view->matched_lines. */ + size_t i = direction > 0 ? 0 : view->matched_lines - 1; + + for (; i < view->matched_lines; i += direction) { + size_t lineno = view->matched_line[i]; + + if (direction > 0) { + if (!wrapped && lineno <= view->pos.lineno) + continue; + if (wrapped && lineno > view->pos.lineno) + continue; + } else { + if (!wrapped && lineno >= view->pos.lineno) + continue; + if (wrapped && lineno < view->pos.lineno) + continue; + } + + select_view_line(view, lineno); + return success("Line %zu matches '%s' (%zu of %zu)", lineno + 1, view->grep, i + 1, view->matched_lines); + } + + return -1; +} + +static enum status_code find_next_match(struct view *view, enum request request) { + enum status_code code; int direction; - size_t i; if (!*view->grep) { if (!*view->env->search) @@ -115,23 +144,11 @@ find_next_match(struct view *view, enum request request) if (!view->matched_lines && !find_matches(view)) return ERROR_OUT_OF_MEMORY; - /* Note, `i` is unsigned and will wrap around in which case it - * will become bigger than view->matched_lines. */ - i = direction > 0 ? 0 : view->matched_lines - 1; - for (; i < view->matched_lines; i += direction) { - size_t lineno = view->matched_line[i]; - - if (direction > 0 && lineno <= view->pos.lineno) - continue; - - if (direction < 0 && lineno >= view->pos.lineno) - continue; - - select_view_line(view, lineno); - return success("Line %zu matches '%s' (%zu of %zu)", lineno + 1, view->grep, i + 1, view->matched_lines); - } + code = find_next_match_line(view, direction, false); + if (code != SUCCESS && opt_wrap_search) + code = find_next_match_line(view, direction, true); - return success("No match found for '%s'", view->grep); + return code == SUCCESS ? code : success("No match found for '%s'", view->grep); } void diff --git a/tigrc b/tigrc index 540d5c3..95d3f8a 100644 --- a/tigrc +++ b/tigrc @@ -101,6 +101,7 @@ set show-notes = yes # When non-bool passed as `--show-notes=...` (diff) set refresh-mode = auto # Enum: manual, auto, after-command, periodic set refresh-interval = 10 # Interval in seconds between refreshes set ignore-case = no # Ignore case when searching? +set wrap-search = yes # Wrap around to top/bottom of view when searching set focus-child = yes # Move focus to child view when opened? set horizontal-scroll = 50% # Number of columns to scroll as % of width set split-view-height = 67% # Height of the bottom view for horizontal splits -- 2.11.4.GIT