Merge branch '265_viewer_search_nroffed_twice'

* 265_viewer_search_nroffed_twice:
  Fixed finds twice in backward direction in nroff'ed text
  fixed search result highlighting while search in backward direction
  Fixed broken search results highlighting
  Fixed broken search in nroffed text with one-byte charset encoding
  Fixed search for first symbol in string.
  Ticket #265: Search finds bold/underlined strings twice
This commit is contained in:
Slava Zanko 2011-07-19 09:52:20 +03:00
commit 1dc4c30eb9
4 changed files with 151 additions and 35 deletions

View File

@ -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)

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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)