Find File: highlight result in viewer.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Egmont Koblinger 2015-10-04 15:32:28 +03:00 committed by Yury V. Zaytsev
parent 1a5f7f3fcf
commit 030fa4640a

View File

@ -111,6 +111,13 @@ typedef struct
char *ignore_dirs; char *ignore_dirs;
} find_file_options_t; } find_file_options_t;
typedef struct
{
char *dir;
gsize start;
gsize end;
} find_match_location_t;
/*** file scope variables ************************************************************************/ /*** file scope variables ************************************************************************/
/* button callbacks */ /* button callbacks */
@ -157,6 +164,8 @@ static struct timeval last_refresh;
static gboolean resuming; static gboolean resuming;
static int last_line; static int last_line;
static int last_pos; static int last_pos;
static off_t last_off;
static int last_i;
static size_t ignore_count = 0; static size_t ignore_count = 0;
@ -332,7 +341,7 @@ find_save_options (void)
static inline char * static inline char *
add_to_list (const char *text, void *data) add_to_list (const char *text, void *data)
{ {
return listbox_add_item (find_list, LISTBOX_APPEND_AT_END, 0, text, data, FALSE); return listbox_add_item (find_list, LISTBOX_APPEND_AT_END, 0, text, data, TRUE);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -364,9 +373,25 @@ found_num_update (void)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static void static void
get_list_info (char **file, char **dir) get_list_info (char **file, char **dir, gsize * start, gsize * end)
{ {
listbox_get_current (find_list, file, (void **) dir); find_match_location_t *location;
listbox_get_current (find_list, file, (void **) &location);
if (location != NULL)
{
if (dir != NULL)
*dir = location->dir;
if (start != NULL)
*start = location->start;
if (end != NULL)
*end = location->end;
}
else
{
if (dir != NULL)
*dir = NULL;
}
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -825,10 +850,11 @@ clear_stack (void)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static void static void
insert_file (const char *dir, const char *file) insert_file (const char *dir, const char *file, gsize start, gsize end)
{ {
char *tmp_name = NULL; char *tmp_name = NULL;
static char *dirname = NULL; static char *dirname = NULL;
find_match_location_t *location;
while (IS_PATH_SEP (dir[0]) && IS_PATH_SEP (dir[1])) while (IS_PATH_SEP (dir[0]) && IS_PATH_SEP (dir[1]))
dir++; dir++;
@ -849,16 +875,20 @@ insert_file (const char *dir, const char *file)
} }
tmp_name = g_strdup_printf (" %s", file); tmp_name = g_strdup_printf (" %s", file);
add_to_list (tmp_name, dirname); location = g_malloc (sizeof (*location));
location->dir = dirname;
location->start = start;
location->end = end;
add_to_list (tmp_name, location);
g_free (tmp_name); g_free (tmp_name);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static void static void
find_add_match (const char *dir, const char *file) find_add_match (const char *dir, const char *file, gsize start, gsize end)
{ {
insert_file (dir, file); insert_file (dir, file, start, end);
/* Don't scroll */ /* Don't scroll */
if (matches == 0) if (matches == 0)
@ -967,11 +997,14 @@ search_content (WDialog * h, const char *directory, const char *filename)
int line = 1; int line = 1;
int pos = 0; int pos = 0;
int n_read = 0; int n_read = 0;
off_t off = 0; /* file_fd's offset corresponding to strbuf[0] */
gboolean found = FALSE; gboolean found = FALSE;
gsize found_len; gsize found_len;
gsize found_start;
char result[BUF_MEDIUM]; char result[BUF_MEDIUM];
char *strbuf = NULL; /* buffer for fetched string */ char *strbuf = NULL; /* buffer for fetched string */
int strbuf_size = 0; int strbuf_size = 0;
int i = -1; /* compensate for a newline we'll add when we first enter the loop */
if (resuming) if (resuming)
{ {
@ -979,12 +1012,15 @@ search_content (WDialog * h, const char *directory, const char *filename)
resuming = FALSE; resuming = FALSE;
line = last_line; line = last_line;
pos = last_pos; pos = last_pos;
off = last_off;
i = last_i;
} }
while (!ret_val) while (!ret_val)
{ {
char ch = '\0'; char ch = '\0';
int i = 0; off += i + 1; /* the previous line, plus a newline character */
i = 0;
/* read to buffer and get line from there */ /* read to buffer and get line from there */
while (TRUE) while (TRUE)
@ -1002,7 +1038,10 @@ search_content (WDialog * h, const char *directory, const char *filename)
{ {
/* skip possible leading zero(s) */ /* skip possible leading zero(s) */
if (i == 0) if (i == 0)
{
off++;
continue; continue;
}
break; break;
} }
@ -1045,7 +1084,8 @@ search_content (WDialog * h, const char *directory, const char *filename)
} }
g_snprintf (result, sizeof (result), "%d:%s", line, filename); g_snprintf (result, sizeof (result), "%d:%s", line, filename);
find_add_match (directory, result); found_start = off + search_content_handle->normal_offset + 1; /* off by one: ticket 3280 */
find_add_match (directory, result, found_start, found_start + found_len);
found = TRUE; found = TRUE;
} }
@ -1073,6 +1113,8 @@ search_content (WDialog * h, const char *directory, const char *filename)
resuming = TRUE; resuming = TRUE;
last_line = line; last_line = line;
last_pos = pos; last_pos = pos;
last_off = off;
last_i = i;
ret_val = TRUE; ret_val = TRUE;
break; break;
default: default:
@ -1301,7 +1343,7 @@ do_search (WDialog * h)
if (search_ok) if (search_ok)
{ {
if (content_pattern == NULL) if (content_pattern == NULL)
find_add_match (directory, dp->d_name); find_add_match (directory, dp->d_name, 0, 0);
else if (search_content (h, directory, dp->d_name)) else if (search_content (h, directory, dp->d_name))
return 1; return 1;
} }
@ -1336,7 +1378,8 @@ init_find_vars (void)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static void static void
find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file) find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file, off_t search_start,
off_t search_end)
{ {
char *fullname = NULL; char *fullname = NULL;
const char *filename = NULL; const char *filename = NULL;
@ -1358,7 +1401,8 @@ find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file)
if (edit) if (edit)
edit_file_at_line (fullname_vpath, use_internal_edit != 0, line); edit_file_at_line (fullname_vpath, use_internal_edit != 0, line);
else else
view_file_at_line (fullname_vpath, unparsed_view, use_internal_view != 0, line); view_file_at_line (fullname_vpath, unparsed_view, use_internal_view != 0, line,
search_start, search_end);
vfs_path_free (fullname_vpath); vfs_path_free (fullname_vpath);
g_free (fullname); g_free (fullname);
} }
@ -1368,15 +1412,15 @@ find_do_view_edit (gboolean unparsed_view, gboolean edit, char *dir, char *file)
static cb_ret_t static cb_ret_t
view_edit_currently_selected_file (gboolean unparsed_view, gboolean edit) view_edit_currently_selected_file (gboolean unparsed_view, gboolean edit)
{ {
char *dir = NULL;
char *text = NULL; char *text = NULL;
find_match_location_t *location;
listbox_get_current (find_list, &text, (void **) &dir); listbox_get_current (find_list, &text, (void **) &location);
if ((text == NULL) || (dir == NULL)) if ((text == NULL) || (location == NULL) || (location->dir == NULL))
return MSG_NOT_HANDLED; return MSG_NOT_HANDLED;
find_do_view_edit (unparsed_view, edit, dir, text); find_do_view_edit (unparsed_view, edit, location->dir, text, location->start, location->end);
return MSG_HANDLED; return MSG_HANDLED;
} }
@ -1647,7 +1691,7 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs,
/* Clear variables */ /* Clear variables */
init_find_vars (); init_find_vars ();
get_list_info (&file_tmp, &dir_tmp); get_list_info (&file_tmp, &dir_tmp, NULL, NULL);
if (dir_tmp) if (dir_tmp)
*dirname = g_strdup (dir_tmp); *dirname = g_strdup (dir_tmp);
@ -1670,9 +1714,10 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs,
{ {
const char *lc_filename = NULL; const char *lc_filename = NULL;
WLEntry *le = LENTRY (entry->data); WLEntry *le = LENTRY (entry->data);
find_match_location_t *location = le->data;
char *p; char *p;
if ((le->text == NULL) || (le->data == NULL)) if ((le->text == NULL) || (location == NULL) || (location->dir == NULL))
continue; continue;
if (content_pattern != NULL) if (content_pattern != NULL)
@ -1680,7 +1725,7 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs,
else else
lc_filename = le->text + 4; lc_filename = le->text + 4;
name = mc_build_filename (le->data, lc_filename, (char *) NULL); name = mc_build_filename (location->dir, lc_filename, (char *) NULL);
/* skip initial start dir */ /* skip initial start dir */
if (start_dir_len < 0) if (start_dir_len < 0)
p = name; p = name;