More Vim-like search behavior

This patch activates the last aborted search when pressing the search shortcuts
('n' or 'N').

To avoid confusion, and to make things more predictable, I've chosen to always
reactivate an aborted search starting from the beginning (or end, in case of
'N' or '?') of the current page, as opposed to Vim which continues from the
next search term each time the search is reactivated.

Searching using '/' or '?' doesn't center the view at the current search term
like when using 'n' or 'N', so we fix this here.

Also, I managed to work around the issue of the thin rectangular margins that
show around the previously-highlighted search terms after the search is aborted
(either explicitly or as a result of following links), by redrawing the page
widget (only if it's visible) instead of redrawing the rectangles covering the
highlighted search terms.

Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
Marwan Tanager 2013-06-08 02:46:58 +02:00 committed by Sebastian Ramacher
parent 463545c3a3
commit cc3b9aea18
4 changed files with 70 additions and 28 deletions

View file

@ -106,6 +106,13 @@ cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpoi
}
} else {
zathura_page_set_visibility(page, false);
girara_list_t* results = NULL;
g_object_get(page_widget, "search-results", &results, NULL);
if (results != NULL) {
g_object_set(page_widget, "search-current", 0, NULL);
}
}
}

View file

@ -339,7 +339,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
return false;
}
bool firsthit = true;
zathura_error_t error = ZATHURA_ERROR_OK;
/* set search direction */
@ -352,10 +351,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
bool nohlsearch = false;
girara_setting_get(session, "nohlsearch", &nohlsearch);
if (nohlsearch == false) {
document_draw_search_results(zathura, true);
}
/* search pages */
for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
unsigned int index = (page_id + current_page_number) % number_of_pages;
@ -383,20 +378,21 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
}
g_object_set(page_widget, "search-results", result, NULL);
if (firsthit == true) {
if (page_id != 0) {
page_set_delayed(zathura, zathura_page_get_index(page));
}
if (argument->n == BACKWARD) {
/* start at bottom hit in page */
g_object_set(page_widget, "search-current", girara_list_size(result) - 1, NULL);
} else {
g_object_set(page_widget, "search-current", 0, NULL);
}
firsthit = false;
if (argument->n == BACKWARD) {
/* start at bottom hit in page */
g_object_set(page_widget, "search-current", girara_list_size(result) - 1, NULL);
} else {
g_object_set(page_widget, "search-current", 0, NULL);
}
}
girara_argument_t* arg = g_malloc0(sizeof(girara_argument_t));
arg->n = FORWARD;
sc_search(session, arg, NULL, 0);
g_free(arg);
return true;
}

View file

@ -86,7 +86,7 @@ enum properties_e {
PROP_SEARCH_RESULTS,
PROP_SEARCH_RESULTS_LENGTH,
PROP_SEARCH_RESULTS_CURRENT,
PROP_DRAW_SEACH_RESULTS,
PROP_DRAW_SEARCH_RESULTS,
PROP_LAST_VIEW,
};
@ -131,8 +131,8 @@ zathura_page_widget_class_init(ZathuraPageClass* class)
g_param_spec_int("search-current", "search-current", "The current search result", -1, INT_MAX, 0, G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_SEARCH_RESULTS_LENGTH,
g_param_spec_int("search-length", "search-length", "The number of search results", -1, INT_MAX, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_DRAW_SEACH_RESULTS,
g_param_spec_boolean("draw-search-results", "draw-search-results", "Set to true if search results should be drawn", FALSE, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_DRAW_SEARCH_RESULTS,
g_param_spec_boolean("draw-search-results", "draw-search-results", "Set to true if search results should be drawn", FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_LAST_VIEW,
g_param_spec_int64("last-view", "last-view", "Last time the page has been viewed", -1, G_MAXINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
@ -154,7 +154,7 @@ zathura_page_widget_init(ZathuraPage* widget)
priv->search.list = NULL;
priv->search.current = INT_MAX;
priv->search.draw = true;
priv->search.draw = false;
priv->images.list = NULL;
priv->images.retrieved = false;
@ -269,8 +269,19 @@ zathura_page_widget_set_property(GObject* object, guint prop_id, const GValue* v
}
break;
}
case PROP_DRAW_SEACH_RESULTS:
case PROP_DRAW_SEARCH_RESULTS:
priv->search.draw = g_value_get_boolean(value);
/*
* we do the following instead of only redrawing the rectangles of the
* search results in order to avoid the rectangular margins that appear
* around the search terms after their highlighted rectangular areas are
* redrawn without highlighting.
*/
if (priv->search.list != NULL && zathura_page_get_visibility(priv->page)) {
gtk_widget_queue_draw(GTK_WIDGET(object));
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@ -299,6 +310,9 @@ zathura_page_widget_get_property(GObject* object, guint prop_id, GValue* value,
case PROP_LAST_VIEW:
g_value_set_int64(value, priv->last_view);
break;
case PROP_DRAW_SEARCH_RESULTS:
g_value_set_boolean(value, priv->search.draw);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}

View file

@ -34,7 +34,7 @@ draw_links(zathura_t* zathura)
}
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
g_object_set(page_widget, "search-results", NULL, NULL);
g_object_set(page_widget, "draw-search-results", FALSE, NULL);
if (zathura_page_get_visibility(page) == true) {
g_object_set(page_widget, "draw-links", TRUE, NULL);
@ -71,9 +71,10 @@ sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
continue;
}
g_object_set(zathura_page_get_widget(zathura, page), "draw-links", FALSE, NULL);
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
g_object_set(page_widget, "draw-links", FALSE, NULL);
if (clear_search == true) {
g_object_set(zathura_page_get_widget(zathura, page), "search-results", NULL, NULL);
g_object_set(page_widget, "draw-search-results", FALSE, NULL);
}
}
}
@ -890,8 +891,23 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
const int num_pages = zathura_document_get_number_of_pages(zathura->document);
const int cur_page = zathura_document_get_current_page_number(zathura->document);
const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document);
const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document);
GtkWidget *cur_page_widget = zathura_page_get_widget(zathura, zathura_document_get_page(zathura->document, cur_page));
bool nohlsearch, first_time_after_abort, draw;
nohlsearch = first_time_after_abort = draw = false;
girara_setting_get(session, "nohlsearch", &nohlsearch);
if (nohlsearch == false) {
g_object_get(cur_page_widget, "draw-search-results", &draw, NULL);
if (draw == false) {
first_time_after_abort = true;
}
document_draw_search_results(zathura, true);
}
int diff = argument->n == FORWARD ? 1 : -1;
if (zathura->global.search_direction == BACKWARD)
@ -900,7 +916,7 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
zathura_page_t* target_page = NULL;
int target_idx = 0;
for (int page_id = 0; page_id < num_pages; ++page_id) {
for (unsigned int page_id = 0; page_id < num_pages; ++page_id) {
int tmp = cur_page + diff * page_id;
zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages);
if (page == NULL) {
@ -916,6 +932,12 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
continue;
}
if (first_time_after_abort == true && num_search_results > 0) {
target_page = page;
target_idx = diff == 1 ? 0 : num_search_results - 1;
break;
}
if (diff == 1 && current < num_search_results - 1) {
/* the next result is on the same page */
target_page = page;
@ -932,7 +954,6 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
for (int npage_id = 1; page_id < num_pages; ++npage_id) {
int ntmp = cur_page + diff * (page_id + npage_id);
zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages);
zathura_document_set_current_page_number(zathura->document, zathura_page_get_index(npage));
GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage);
g_object_get(npage_page_widget, "search-length", &num_search_results, NULL);
if (num_search_results != 0) {
@ -959,6 +980,10 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
page_offset_t offset;
page_calculate_offset(zathura, target_page, &offset);
if (zathura_page_get_index(target_page) != cur_page) {
page_set(zathura, zathura_page_get_index(target_page));
}
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1;
zathura_adjustment_set_value(view_vadjustment, y);