diff --git a/lib/search/regex.c b/lib/search/regex.c index e1bbf1b0f..592d12507 100644 --- a/lib/search/regex.c +++ b/lib/search/regex.c @@ -816,6 +816,9 @@ mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data, if (current_chr == MC_SEARCH_CB_ABORT) break; + if (current_chr == MC_SEARCH_CB_INVALID) + continue; + current_pos++; if (current_chr == MC_SEARCH_CB_SKIP) diff --git a/src/viewer/internal.h b/src/viewer/internal.h index 8c078583f..249df6c99 100644 --- a/src/viewer/internal.h +++ b/src/viewer/internal.h @@ -315,6 +315,8 @@ mcview_nroff_t *mcview_nroff_seq_new (mcview_t * view); void mcview_nroff_seq_free (mcview_nroff_t **); nroff_type_t mcview_nroff_seq_info (mcview_nroff_t *); int mcview_nroff_seq_next (mcview_nroff_t *); +int mcview_nroff_seq_prev (mcview_nroff_t *); + /* plain.c: */ void mcview_display_text (mcview_t *); diff --git a/src/viewer/nroff.c b/src/viewer/nroff.c index f32279173..14fe42af3 100644 --- a/src/viewer/nroff.c +++ b/src/viewer/nroff.c @@ -82,10 +82,9 @@ mcview_nroff_get_char (mcview_nroff_t * nroff, int *ret_val, off_t nroff_index) return FALSE; } - if (!g_unichar_isprint (c)) - return FALSE; *ret_val = c; - return TRUE; + + return g_unichar_isprint (c); } /* --------------------------------------------------------------------------------------------- */ @@ -275,14 +274,20 @@ mcview__get_nroff_real_len (mcview_t * view, off_t start, off_t length) nroff = mcview_nroff_seq_new_num (view, start); if (nroff == NULL) return 0; - while (i < length) { - if (nroff->type != NROFF_TYPE_NONE) + switch (nroff->type) { - ret += 1 + nroff->char_width; + case NROFF_TYPE_BOLD: + ret += 1 + nroff->char_width; /* real char width and 0x8 */ + break; + case NROFF_TYPE_UNDERLINE: + ret += 2; /* underline symbol and ox8 */ + break; + default: + break; } - i++; + i += nroff->char_width; mcview_nroff_seq_next (nroff); } @@ -379,10 +384,73 @@ mcview_nroff_seq_next (mcview_nroff_t * nroff) nroff->prev_type = nroff->type; + switch (nroff->type) + { + case NROFF_TYPE_BOLD: + nroff->index += 1 + nroff->char_width; + break; + case NROFF_TYPE_UNDERLINE: + nroff->index += 2; + break; + default: + break; + } + nroff->index += nroff->char_width; - if (nroff->prev_type != NROFF_TYPE_NONE) - nroff->index += 2; + mcview_nroff_seq_info (nroff); + return nroff->current_char; +} + +/* --------------------------------------------------------------------------------------------- */ + +int +mcview_nroff_seq_prev (mcview_nroff_t * nroff) +{ + int prev; + off_t prev_index, prev_index2; + + if (nroff == NULL) + return -1; + + nroff->prev_type = NROFF_TYPE_NONE; + + if (nroff->index == 0) + return -1; + + prev_index = nroff->index - 1; + + while (prev_index != 0) + { + if (mcview_nroff_get_char (nroff, &nroff->current_char, prev_index)) + break; + prev_index--; + } + if (prev_index == 0) + { + nroff->index--; + mcview_nroff_seq_info (nroff); + return nroff->current_char; + } + + prev_index--; + + if (!mcview_get_byte (nroff->view, prev_index, &prev) || prev != '\b') + { + nroff->index = prev_index; + mcview_nroff_seq_info (nroff); + return nroff->current_char; + } + prev_index2 = prev_index - 1; + + while (prev_index2 != 0) + { + if (mcview_nroff_get_char (nroff, &prev, prev_index)) + break; + prev_index2--; + } + + nroff->index = (prev_index2 == 0) ? prev_index : prev_index2; mcview_nroff_seq_info (nroff); return nroff->current_char; } diff --git a/src/viewer/search.c b/src/viewer/search.c index 7e7d8e55f..b1c0712c3 100644 --- a/src/viewer/search.c +++ b/src/viewer/search.c @@ -53,7 +53,7 @@ /*** file scope variables ************************************************************************/ -static int search_cb_char_curr_index = 0; +static int search_cb_char_curr_index = -1; static char search_cb_char_buffer[6]; /*** file scope functions ************************************************************************/ @@ -81,6 +81,7 @@ mcview_find (mcview_t * view, gsize search_start, gsize * len) gsize search_end; view->search_numNeedSkipChar = 0; + search_cb_char_curr_index = -1; if (mcview_search_options.backwards) { @@ -96,7 +97,11 @@ mcview_find (mcview_t * view, gsize search_start, gsize * len) if (mc_search_run (view->search, (void *) view, search_start, search_end, len) && view->search->normal_offset == (off_t) search_start) + { + if (view->text_nroff_mode) + view->search->normal_offset++; return TRUE; + } search_start--; } @@ -115,17 +120,21 @@ mcview_find (mcview_t * view, gsize search_start, gsize * len) static void mcview_search_show_result (mcview_t * view, Dlg_head ** d, size_t match_len) { + int nroff_len; - view->search_start = view->search->normal_offset + - mcview__get_nroff_real_len (view, - view->search->start_buffer, - view->search->normal_offset - view->search->start_buffer); + nroff_len = + view->text_nroff_mode + ? mcview__get_nroff_real_len (view, view->search->start_buffer, + view->search->normal_offset - view->search->start_buffer) : 0; + view->search_start = view->search->normal_offset + nroff_len; if (!view->hex_mode) view->search_start++; - view->search_end = view->search_start + match_len + - mcview__get_nroff_real_len (view, view->search_start - 1, match_len); + nroff_len = + view->text_nroff_mode ? mcview__get_nroff_real_len (view, view->search_start - 1, + match_len) : 0; + view->search_end = view->search_start + match_len + nroff_len; if (view->hex_mode) { @@ -160,36 +169,50 @@ mcview_search_cmd_callback (const void *user_data, gsize char_offset) if (!view->text_nroff_mode) { if (!mcview_get_byte (view, char_offset, &lc_byte)) - return MC_SEARCH_CB_INVALID; + return MC_SEARCH_CB_OK; return lc_byte; } - if (view->search_numNeedSkipChar) + if (view->search_numNeedSkipChar != 0) { view->search_numNeedSkipChar--; return MC_SEARCH_CB_SKIP; } - if (search_cb_char_curr_index < view->search_nroff_seq->char_width) + if (search_cb_char_curr_index == -1 + || search_cb_char_curr_index >= view->search_nroff_seq->char_width) { - lc_byte = search_cb_char_buffer[search_cb_char_curr_index]; - search_cb_char_curr_index++; + if (search_cb_char_curr_index != -1) + mcview_nroff_seq_next (view->search_nroff_seq); - return (lc_byte != -1) ? lc_byte : MC_SEARCH_CB_INVALID; + search_cb_char_curr_index = 0; + if (view->search_nroff_seq->char_width > 1) + g_unichar_to_utf8 (view->search_nroff_seq->current_char, search_cb_char_buffer); + else + search_cb_char_buffer[0] = (char) view->search_nroff_seq->current_char; + + if (view->search_nroff_seq->type != NROFF_TYPE_NONE) + { + switch (view->search_nroff_seq->type) + { + case NROFF_TYPE_BOLD: + view->search_numNeedSkipChar = 1 + view->search_nroff_seq->char_width; /* real char width and 0x8 */ + break; + case NROFF_TYPE_UNDERLINE: + view->search_numNeedSkipChar = 2; /* underline symbol and ox8 */ + break; + default: + break; + } + } + return MC_SEARCH_CB_INVALID; } - mcview_nroff_seq_next (view->search_nroff_seq); - search_cb_char_curr_index = 0; - if (view->search_nroff_seq->char_width > 1) - g_unichar_to_utf8 (view->search_nroff_seq->current_char, search_cb_char_buffer); - else - search_cb_char_buffer[0] = (char) view->search_nroff_seq->current_char; + lc_byte = search_cb_char_buffer[search_cb_char_curr_index]; + search_cb_char_curr_index++; + return (lc_byte != -1) ? (unsigned char) lc_byte : MC_SEARCH_CB_INVALID; - if (view->search_nroff_seq->type != NROFF_TYPE_NONE) - view->search_numNeedSkipChar = 1 + view->search_nroff_seq->char_width; - - return MC_SEARCH_CB_SKIP; } /* --------------------------------------------------------------------------------------------- */ @@ -239,9 +262,29 @@ mcview_do_search (mcview_t * view) if (view->search_start != 0) { - search_start = mcview_search_options.backwards ? -2 : 0; - search_start += view->search_start + - mcview__get_nroff_real_len (view, view->search_start, 2) * search_start; + if (!view->text_nroff_mode) + search_start = view->search_start + (mcview_search_options.backwards ? -2 : 0); + else + { + if (mcview_search_options.backwards) + { + mcview_nroff_t *nroff; + nroff = mcview_nroff_seq_new_num (view, view->search_start); + if (mcview_nroff_seq_prev (nroff) != -1) + search_start = + -(mcview__get_nroff_real_len (view, nroff->index - 1, 2) + + nroff->char_width + 1); + else + search_start = -2; + + mcview_nroff_seq_free (&nroff); + } + else + { + search_start = mcview__get_nroff_real_len (view, view->search_start + 1, 2); + } + search_start += view->search_start; + } } if (mcview_search_options.backwards && (int) search_start < 0)