1
0
mirror of https://github.com/MidnightCommander/mc synced 2025-03-22 07:42:54 +03:00

Added usage of search engine.

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2010-04-14 09:24:08 +03:00 committed by Ilia Maslakov
parent e5dc79a441
commit 14fa0ea1e2
7 changed files with 591 additions and 477 deletions

@ -446,6 +446,7 @@
#define CK_DiffHelp 9034
#define CK_DiffMergeCurrentHunk 9035
#define CK_DiffSave 9036
#define CK_DiffContinueSearch 9037
/*
Process a block through a shell command: CK_Pipe_Block(i) executes shell_cmd[i].

@ -1,8 +1,10 @@
noinst_LTLIBRARIES = libdiffviewer.la
libdiffviewer_la_SOURCES = \
ydiff.c \
ydiff.h
internal.h \
search.c \
ydiff.c ydiff.h
libdiffviewer_la_CFLAGS = -I$(top_srcdir) \
$(GLIB_CFLAGS) $(PCRE_CFLAGS) \

147
src/diffviewer/internal.h Normal file

@ -0,0 +1,147 @@
#ifndef MC__DIFFVIEW_INTERNAL_H
#define MC__DIFFVIEW_INTERNAL_H
#include "lib/global.h"
#include "lib/mcconfig.h"
#include "lib/search.h"
#include "lib/tty/color.h"
#include "src/widget.h"
/*** typedefs(not structures) and defined constants **********************************************/
typedef int (*DFUNC) (void *ctx, int ch, int line, off_t off, size_t sz, const char *str);
typedef int PAIR[2];
#define error_dialog(h, s) query_dialog(h, s, D_ERROR, 1, _("&Dismiss"))
/*** enums ***************************************************************************************/
typedef enum
{
DATA_SRC_MEM = 0,
DATA_SRC_TMP = 1,
DATA_SRC_ORG = 2
} DSRC;
typedef enum
{
DIFF_NONE = 0,
DIFF_ADD = 1,
DIFF_DEL = 2,
DIFF_CHG = 3
} DiffState;
/*** structures declarations (and typedefs of structures)*****************************************/
typedef struct
{
int fd;
int pos;
int len;
char *buf;
int flags;
void *data;
} FBUF;
typedef struct
{
int a[2][2];
int cmd;
} DIFFCMD;
typedef struct
{
int off;
int len;
} BRACKET[2];
typedef struct
{
int ch;
int line;
union
{
off_t off;
size_t len;
} u;
void *p;
} DIFFLN;
typedef struct
{
FBUF *f;
GArray *a;
DSRC dsrc;
} PRINTER_CTX;
typedef struct WDiff_struct
{
Widget widget;
const char *args; /* Args passed to diff */
const char *file[2]; /* filenames */
const char *label[2];
FBUF *f[2];
const char *backup_sufix;
gboolean merged;
GArray *a[2];
GPtrArray *hdiff;
int ndiff; /* number of hunks */
DSRC dsrc; /* data source: memory or temporary file */
int view_quit:1; /* Quit flag */
int height;
int half1;
int half2;
int width1;
int width2;
int bias;
int new_frame;
int skip_rows;
int skip_cols;
int display_symbols;
int display_numbers;
int show_cr;
int tab_size;
int ord;
int full;
gboolean utf8;
/* converter for translation of text */
GIConv converter;
struct
{
int quality;
gboolean strip_trailing_cr;
gboolean ignore_tab_expansion;
gboolean ignore_space_change;
gboolean ignore_all_space;
gboolean ignore_case;
} opt;
/* Search variables */
struct
{
mc_search_t *handle;
gchar *last_string;
ssize_t last_found_line;
size_t last_accessed_num_line;
} search;
} WDiff;
/*** global variables defined in .c file *********************************************************/
/*** declarations of public functions ************************************************************/
/* search.c */
void dview_search_cmd (WDiff * dview);
void dview_continue_search_cmd (WDiff * dview);
/* ydiff.c */
void dview_update (WDiff * dview);
#endif /* MC__DIFFVIEW_INTERNAL_H */

310
src/diffviewer/search.c Normal file

@ -0,0 +1,310 @@
/*
Search functions for diffviewer.
Copyright (C) 2010 The Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2010.
This file is part of the Midnight Commander.
The Midnight Commander is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#include <config.h>
#include <stdio.h>
#include "lib/global.h"
#include "lib/strutil.h"
#include "lib/tty/key.h"
#include "src/dialog.h"
#include "src/wtools.h"
#include "src/history.h"
#include "src/charsets.h"
#include "internal.h"
/*** global variables ****************************************************************************/
/*** file scope macro definitions ****************************************************************/
#define SEARCH_DLG_WIDTH 58
#define SEARCH_DLG_HEIGHT 13
/*** file scope type declarations ****************************************************************/
typedef struct mcdiffview_search_options_struct
{
mc_search_type_t type;
gboolean case_sens;
gboolean backwards;
gboolean whole_words;
gboolean all_codepages;
} mcdiffview_search_options_t;
/*** file scope variables ************************************************************************/
static mcdiffview_search_options_t mcdiffview_search_options = {
.type = MC_SEARCH_T_NORMAL,
.case_sens = FALSE,
.backwards = FALSE,
.whole_words = FALSE,
.all_codepages = FALSE,
};
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
#define DLG_BTN1_text N_("&Cancel")
#define DLG_BTN2_text N_("&OK")
static void
mcdiffview_dialog_fix_buttons_positions (QuickDialog * dlg)
{
size_t str_cancel_len, str_ok_len;
size_t first_start_position;
str_cancel_len = str_term_width1 (_(DLG_BTN1_text)) + 4;
str_ok_len = str_term_width1 (_(DLG_BTN2_text)) + 6;
first_start_position = (SEARCH_DLG_WIDTH - str_cancel_len - str_ok_len - 1) / 2;
dlg->widgets[1].relative_x = first_start_position;
dlg->widgets[0].relative_x = first_start_position + str_ok_len + 1;
}
/* --------------------------------------------------------------------------------------------- */
static gboolean
mcdiffview_dialog_search (WDiff * dview)
{
char *exp = NULL;
int qd_result;
size_t num_of_types;
gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
QuickWidget search_widgets[] = {
/* 0 */
QUICK_BUTTON (3, SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, DLG_BTN1_text,
B_CANCEL, NULL),
/* 1 */
QUICK_BUTTON (3, SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, DLG_BTN2_text,
B_ENTER, NULL),
/* 2 */
#ifdef HAVE_CHARSET
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT, N_("All charsets"),
&mcdiffview_search_options.all_codepages),
#endif
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 7, SEARCH_DLG_HEIGHT, N_("&Whole words"),
&mcdiffview_search_options.whole_words),
/* 3 */
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT, N_("&Backwards"),
&mcdiffview_search_options.backwards),
/* 4 */
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("case &Sensitive"),
&mcdiffview_search_options.case_sens),
/* 5 */
QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
num_of_types, (const char **) list_of_types,
(int *) &mcdiffview_search_options.type),
/* 6 */
QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
INPUT_LAST_TEXT, SEARCH_DLG_WIDTH - 6, 0,
MC_HISTORY_SHARED_SEARCH,
&exp),
/* 7 */
QUICK_LABEL (2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_(" Enter search string:")),
QUICK_END
};
QuickDialog search_input = {
SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, 0,
N_("Search"), "[Input Line Keys]",
search_widgets, 0
};
mcdiffview_dialog_fix_buttons_positions (&search_input);
qd_result = quick_dialog (&search_input);
g_strfreev (list_of_types);
if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
{
g_free (exp);
return FALSE;
}
#ifdef HAVE_CHARSET
{
GString *tmp = str_convert_to_input (exp);
if (tmp)
{
g_free (exp);
exp = g_string_free (tmp, FALSE);
}
}
#endif
g_free (dview->search.last_string);
dview->search.last_string = exp;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
static gboolean
mcdiffview_do_search_backward (WDiff * dview)
{
size_t ind;
DIFFLN *p;
dview->search.last_accessed_num_line--;
if (dview->search.last_accessed_num_line < 0)
return FALSE;
for (ind = dview->search.last_accessed_num_line; ind > 0; ind--)
{
p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, ind);
if (p->u.len == 0)
continue;
if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
{
dview->skip_rows = dview->search.last_found_line =
dview->search.last_accessed_num_line = ind;
return TRUE;
}
}
return FALSE;
}
/* --------------------------------------------------------------------------------------------- */
static gboolean
mcdiffview_do_search_forward (WDiff * dview)
{
size_t ind;
DIFFLN *p;
dview->search.last_accessed_num_line++;
if (dview->search.last_accessed_num_line > dview->a[dview->ord]->len)
return FALSE;
for (ind = dview->search.last_accessed_num_line; ind < dview->a[dview->ord]->len; ind++)
{
p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, ind);
if (p->u.len == 0)
continue;
if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
{
dview->skip_rows = dview->search.last_found_line =
dview->search.last_accessed_num_line = ind;
return TRUE;
}
}
return FALSE;
}
/* --------------------------------------------------------------------------------------------- */
static void
mcdiffview_do_search (WDiff * dview)
{
gboolean present_result = FALSE;
tty_enable_interrupt_key ();
if (mcdiffview_search_options.backwards)
{
present_result = mcdiffview_do_search_backward (dview);
}
else
{
present_result = mcdiffview_do_search_forward (dview);
}
tty_disable_interrupt_key ();
if (!present_result)
{
dview->search.last_found_line = -1;
error_dialog (_("Search"), _(" Search string not found "));
}
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
void
dview_search_cmd (WDiff * dview)
{
if (dview->dsrc != DATA_SRC_MEM)
{
error_dialog (_("Search"), _(" Search is disabled "));
return;
}
if (!mcdiffview_dialog_search (dview))
return;
mc_search_free (dview->search.handle);
dview->search.handle = mc_search_new (dview->search.last_string, -1);
if (dview->search.handle == NULL)
return;
dview->search.handle->search_type = mcdiffview_search_options.type;
dview->search.handle->is_all_charsets = mcdiffview_search_options.all_codepages;
dview->search.handle->is_case_sentitive = mcdiffview_search_options.case_sens;
dview->search.handle->whole_words = mcdiffview_search_options.whole_words;
mcdiffview_do_search (dview);
}
/* --------------------------------------------------------------------------------------------- */
void
dview_continue_search_cmd (WDiff * dview)
{
if (dview->dsrc != DATA_SRC_MEM)
{
error_dialog (_("Search"), _(" Search is disabled "));
return;
}
if (dview->search.handle == NULL)
{
dview_search_cmd (dview);
return;
}
mcdiffview_do_search (dview);
}
/* --------------------------------------------------------------------------------------------- */

@ -43,7 +43,6 @@
#include "src/keybind.h"
#include "src/cmd.h"
#include "src/dialog.h"
#include "src/widget.h"
#include "src/help.h"
#include "src/wtools.h"
#include "src/charsets.h"
@ -55,6 +54,7 @@
#include "src/selcodepage.h"
#include "ydiff.h"
#include "internal.h"
/*** global variables ****************************************************************************/
@ -79,9 +79,6 @@ do { \
#define OPTX 50
#define OPTY 16
#define SEARCH_DLG_WIDTH 58
#define SEARCH_DLG_HEIGHT 14
#define ADD_CH '+'
#define DEL_CH '-'
#define CHG_CH '*'
@ -93,26 +90,16 @@ do { \
#define TAB_SKIP(ts, pos) ((ts) - (pos) % (ts))
#define error_dialog(h, s) query_dialog(h, s, D_ERROR, 1, _("&Dismiss"))
#define FILE_DIRTY(fs) \
do { \
(fs)->pos = 0; \
(fs)->len = 0; \
} while (0)
#define IS_WHOLE_OR_DONT_CARE() \
(!whole || ( \
(i == 0 || strchr(wholechars, haystack[i - 1]) == NULL) && \
(i + nlen == hlen || strchr(wholechars, haystack[i + nlen]) == NULL) \
))
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
static const char *wholechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
@ -1909,6 +1896,11 @@ destroy_hdiff (WDiff * dview)
g_ptr_array_free (dview->hdiff, TRUE);
dview->hdiff = NULL;
}
mc_search_free (dview->search.handle);
dview->search.handle = NULL;
g_free (dview->search.last_string);
dview->search.last_string = NULL;
}
/* --------------------------------------------------------------------------------------------- */
@ -2347,7 +2339,12 @@ dview_init (WDiff * dview, const char *args, const char *file1, const char *file
dview->tab_size = 8;
dview->ord = 0;
dview->full = 0;
dview->last_found = -1;
dview->search.handle=NULL;
dview->search.last_string=NULL;
dview->search.last_found_line = -1;
dview->search.last_accessed_num_line = 0;
dview->opt.quality = 0;
dview->opt.strip_trailing_cr = 0;
@ -2532,7 +2529,7 @@ dview_display_file (const WDiff * dview, int ord, int r, int c, int height, int
}
if (f == NULL)
{
if (i == (size_t) dview->last_found)
if (i == (size_t) dview->search.last_found_line)
{
tty_setcolor (MARKED_SELECTED_COLOR);
}
@ -2719,92 +2716,6 @@ dview_status (const WDiff * dview, int ord, int width, int c)
/* --------------------------------------------------------------------------------------------- */
static void
dview_update (WDiff * dview)
{
int height = dview->height;
int width1;
int width2;
int last = dview->a[0]->len - 1;
if (dview->skip_rows > last)
{
dview->skip_rows = last;
}
if (dview->skip_rows < 0)
{
dview->skip_rows = 0;
}
if (dview->skip_cols < 0)
{
dview->skip_cols = 0;
}
if (height < 2)
{
return;
}
width1 = dview->half1 + dview->bias;
width2 = dview->half2 - dview->bias;
if (dview->full)
{
width1 = COLS;
width2 = 0;
}
if (dview->new_frame)
{
int xwidth = dview->display_symbols + dview->display_numbers;
tty_setcolor (NORMAL_COLOR);
if (width1 > 1)
{
tty_draw_box (1, 0, height, width1, FALSE);
}
if (width2 > 1)
{
tty_draw_box (1, width1, height, width2, FALSE);
}
if (xwidth)
{
xwidth++;
if (xwidth < width1 - 1)
{
tty_gotoyx (1, xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
tty_gotoyx (height, xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
tty_draw_vline (2, xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
}
if (xwidth < width2 - 1)
{
tty_gotoyx (1, width1 + xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
tty_gotoyx (height, width1 + xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
tty_draw_vline (2, width1 + xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
}
}
dview->new_frame = 0;
}
if (width1 > 2)
{
dview_status (dview, dview->ord, width1, 0);
dview_display_file (dview, dview->ord, 2, 1, height - 2, width1 - 2);
}
if (width2 > 2)
{
dview_status (dview, dview->ord ^ 1, width2, width1);
dview_display_file (dview, dview->ord ^ 1, 2, width1 + 1, height - 2, width2 - 2);
}
}
/* --------------------------------------------------------------------------------------------- */
static void
dview_redo (WDiff * dview)
{
@ -2819,265 +2730,6 @@ dview_redo (WDiff * dview)
/* --------------------------------------------------------------------------------------------- */
static const unsigned char *
memmem_dummy (const unsigned char *haystack, size_t i, size_t hlen, const unsigned char *needle,
size_t nlen, int whole)
{
for (; i + nlen <= hlen; i++)
{
if (haystack[i] == needle[0])
{
size_t j;
for (j = 1; j < nlen; j++)
{
if (haystack[i + j] != needle[j])
{
break;
}
}
if (j == nlen && IS_WHOLE_OR_DONT_CARE ())
{
return haystack + i;
}
}
}
return NULL;
}
/* --------------------------------------------------------------------------------------------- */
static const unsigned char *
memmem_dummy_nocase (const unsigned char *haystack, size_t i, size_t hlen,
const unsigned char *needle, size_t nlen, int whole)
{
for (; i + nlen <= hlen; i++)
{
if (toupper (haystack[i]) == toupper (needle[0]))
{
size_t j;
for (j = 1; j < nlen; j++)
{
if (toupper (haystack[i + j]) != toupper (needle[j]))
{
break;
}
}
if (j == nlen && IS_WHOLE_OR_DONT_CARE ())
{
return haystack + i;
}
}
}
return NULL;
}
/* --------------------------------------------------------------------------------------------- */
static const unsigned char *
search_string (const DIFFLN * p, size_t xpos, const void *needle, size_t nlen, int whole, int ccase)
{
const unsigned char *haystack = p->p;
size_t hlen = p->u.len;
if (xpos > hlen || nlen <= 0 || haystack == NULL || needle == NULL)
{
return NULL;
}
/* XXX I should use Boyer-Moore */
if (ccase)
{
return memmem_dummy (haystack, xpos, hlen, needle, nlen, whole);
}
else
{
return memmem_dummy_nocase (haystack, xpos, hlen, needle, nlen, whole);
}
}
/* --------------------------------------------------------------------------------------------- */
static int
dview_search_string (WDiff * dview, const char *needle, int ccase, int back, int whole)
{
size_t nlen = strlen (needle);
size_t xpos = 0;
int ord = dview->ord;
const DIFFLN *p;
size_t i = (size_t) dview->last_found;
if (back)
{
if (i == (size_t) - 1)
{
i = dview->skip_rows;
}
for (--i; i >= 0; i--)
{
const unsigned char *q;
p = (DIFFLN *) & g_array_index (dview->a[ord], DIFFLN, i);
q = search_string (p, xpos, needle, nlen, whole, ccase);
if (q != NULL)
{
return i;
}
}
}
else
{
if (i == (size_t) - 1)
{
i = dview->skip_rows - 1;
}
for (++i; i < dview->a[ord]->len; i++)
{
const unsigned char *q;
p = (DIFFLN *) & g_array_index (dview->a[ord], DIFFLN, i);
q = search_string (p, xpos, needle, nlen, whole, ccase);
if (q != NULL)
{
return i;
}
}
}
return -1;
}
/* --------------------------------------------------------------------------------------------- */
static void
dview_search (WDiff * dview, int again)
{
/* XXX some statics here, to be remembered between runs */
static char *searchopt_text = NULL;
static int searchopt_type;
static int searchopt_case;
static int searchopt_backwards;
static int searchopt_whole;
static int compiled = 0;
if (again < 0)
{
g_free (searchopt_text);
searchopt_text = NULL;
if (compiled)
{
compiled = 0;
/*XXX free search exp */
}
return;
}
if (dview->dsrc != DATA_SRC_MEM)
{
error_dialog (_("Search"), _(" Search is disabled "));
return;
}
if (!again || searchopt_text == NULL)
{
char *tsearchopt_text = NULL;
int tsearchopt_type = searchopt_type;
int tsearchopt_case = searchopt_case;
int tsearchopt_backwards = searchopt_backwards;
int tsearchopt_whole = searchopt_whole;
const char *search_str[] = {
N_("&Normal")
};
QuickWidget search_widgets[] = {
/* 0 */
QUICK_BUTTON (6, 10, 11, SEARCH_DLG_HEIGHT, N_("&Cancel"), B_CANCEL, NULL),
/* 1 */
QUICK_BUTTON (4, 10, 11, SEARCH_DLG_HEIGHT, N_("&Find all"), B_USER, NULL),
/* 2 */
QUICK_BUTTON (2, 10, 11, SEARCH_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL),
/* 3 */
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT, N_("&Whole words"),
&tsearchopt_whole),
/* 4 */
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT, N_("&Backwards"),
&tsearchopt_backwards),
/* 5 */
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("case &Sensitive"),
&tsearchopt_case),
/* 6 */
QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
1, (const char **) search_str, (int *) &tsearchopt_type),
/* 7 */
QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
tsearchopt_text, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH,
&tsearchopt_text),
/* 8 */
QUICK_LABEL (2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_(" Enter search string:")),
QUICK_END
};
QuickDialog search_input = {
SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, 0,
N_("Search"), "[Input Line Keys]",
search_widgets, 0
};
if (quick_dialog (&search_input) == B_CANCEL)
{
return;
}
if (tsearchopt_text == NULL || !*tsearchopt_text)
{
g_free (tsearchopt_text);
return;
}
g_free (searchopt_text);
searchopt_text = tsearchopt_text;
searchopt_type = tsearchopt_type;
searchopt_case = tsearchopt_case;
searchopt_backwards = tsearchopt_backwards;
searchopt_whole = tsearchopt_whole;
}
if (compiled)
{
compiled = 0;
/*XXX free search exp */
}
if (0 /*XXX new search exp */ )
{
error_dialog (_("Error"), _(" Cannot search "));
return;
}
compiled = 1;
if (searchopt_type == 0)
{
dview->last_found =
dview_search_string (dview, searchopt_text, searchopt_case, searchopt_backwards,
searchopt_whole);
}
if (dview->last_found == -1)
{
error_dialog (_("Search"), _(" Search string not found "));
}
else
{
dview->skip_rows = dview->last_found;
dview_update (dview);
}
}
/* --------------------------------------------------------------------------------------------- */
static void
dview_edit (WDiff * dview, int ord)
{
@ -3126,7 +2778,7 @@ dview_goto_cmd (WDiff * dview, int ord)
}
}
}
dview->skip_rows = i;
dview->skip_rows = dview->search.last_accessed_num_line = i;
snprintf (prev, sizeof (prev), "%d", newline);
}
g_free (input);
@ -3168,12 +2820,14 @@ dview_event (Gpm_Event * event, void *x)
if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN))
{
dview->skip_rows -= 2;
dview->search.last_accessed_num_line = dview->skip_rows;
dview_update (dview);
return result;
}
if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN))
{
dview->skip_rows += 2;
dview->search.last_accessed_num_line = dview->skip_rows;
dview_update (dview);
return result;
}
@ -3294,17 +2948,17 @@ dview_execute_cmd (WDiff * dview, unsigned long command)
dview_redo (dview);
break;
case CK_DiffNextHunk:
dview->skip_rows = find_next_hunk (dview->a[0], dview->skip_rows);
dview->skip_rows = dview->search.last_accessed_num_line = find_next_hunk (dview->a[0], dview->skip_rows);
break;
case CK_DiffPrevHunk:
dview->skip_rows = find_prev_hunk (dview->a[0], dview->skip_rows);
dview->skip_rows = dview->search.last_accessed_num_line = find_prev_hunk (dview->a[0], dview->skip_rows);
break;
case CK_DiffGoto:
dview_goto_cmd (dview, TRUE);
break;
/* what this?
case KEY_BACKSPACE:
dview->last_found = -1;
dview->search.last_found_line = -1;
break;
*/
case CK_DiffEditCurrent:
@ -3318,25 +2972,32 @@ dview_execute_cmd (WDiff * dview, unsigned long command)
dview_edit (dview, dview->ord ^ 1);
break;
case CK_DiffSearch:
dview_search (dview, 1);
dview_search_cmd (dview);
break;
case CK_DiffContinueSearch:
dview_continue_search_cmd (dview);
break;
case CK_DiffBOF:
dview->skip_rows = 0;
dview->skip_rows = dview->search.last_accessed_num_line = 0;
break;
case CK_DiffEOF:
dview->skip_rows = dview->a[0]->len - 1;
dview->skip_rows = dview->search.last_accessed_num_line = dview->a[0]->len - 1;
break;
case CK_DiffUp:
dview->skip_rows--;
dview->search.last_accessed_num_line = dview->skip_rows;
break;
case CK_DiffDown:
dview->skip_rows++;
dview->search.last_accessed_num_line = dview->skip_rows;
break;
case CK_DiffPageDown:
dview->skip_rows += dview->height - 2;
dview->search.last_accessed_num_line = dview->skip_rows;
break;
case CK_DiffPageUp:
dview->skip_rows -= dview->height - 2;
dview->search.last_accessed_num_line = dview->skip_rows;
break;
case CK_DiffLeft:
dview->skip_cols--;
@ -3512,7 +3173,6 @@ diff_view (const char *file1, const char *file2, const char *label1, const char
if (!error)
{
run_dlg (dview_dlg);
dview_search (dview, -1);
dview_fini (dview);
}
destroy_dlg (dview_dlg);
@ -3603,3 +3263,91 @@ dview_diff_cmd (WDiff *dview)
message (1, MSG_ERROR, _("Need two files to compare"));
}
}
/* --------------------------------------------------------------------------------------------- */
void
dview_update (WDiff * dview)
{
int height = dview->height;
int width1;
int width2;
int last = dview->a[0]->len - 1;
if (dview->skip_rows > last)
{
dview->skip_rows = dview->search.last_accessed_num_line = last;
}
if (dview->skip_rows < 0)
{
dview->skip_rows = dview->search.last_accessed_num_line = 0;
}
if (dview->skip_cols < 0)
{
dview->skip_cols = 0;
}
if (height < 2)
{
return;
}
width1 = dview->half1 + dview->bias;
width2 = dview->half2 - dview->bias;
if (dview->full)
{
width1 = COLS;
width2 = 0;
}
if (dview->new_frame)
{
int xwidth = dview->display_symbols + dview->display_numbers;
tty_setcolor (NORMAL_COLOR);
if (width1 > 1)
{
tty_draw_box (1, 0, height, width1, FALSE);
}
if (width2 > 1)
{
tty_draw_box (1, width1, height, width2, FALSE);
}
if (xwidth)
{
xwidth++;
if (xwidth < width1 - 1)
{
tty_gotoyx (1, xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
tty_gotoyx (height, xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
tty_draw_vline (2, xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
}
if (xwidth < width2 - 1)
{
tty_gotoyx (1, width1 + xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DTOPMIDDLE], FALSE);
tty_gotoyx (height, width1 + xwidth);
tty_print_alt_char (mc_tty_frm[MC_TTY_FRM_DBOTTOMMIDDLE], FALSE);
tty_draw_vline (2, width1 + xwidth, mc_tty_frm[MC_TTY_FRM_VERT], height - 2);
}
}
dview->new_frame = 0;
}
if (width1 > 2)
{
dview_status (dview, dview->ord, width1, 0);
dview_display_file (dview, dview->ord, 2, 1, height - 2, width1 - 2);
}
if (width2 > 2)
{
dview_status (dview, dview->ord ^ 1, width2, width1);
dview_display_file (dview, dview->ord ^ 1, 2, width1 + 1, height - 2, width2 - 2);
}
}
/* --------------------------------------------------------------------------------------------- */

@ -1,114 +1,18 @@
#ifndef MC_YDIFF_H
#define MC_YDIFF_H
#ifndef MC__DIFFVIEW_YDIFF_H
#define MC__DIFFVIEW_YDIFF_H
typedef struct
{
int fd;
int pos;
int len;
char *buf;
int flags;
void *data;
} FBUF;
/*** typedefs(not structures) and defined constants **********************************************/
struct WDiff_struct;
typedef struct
{
int a[2][2];
int cmd;
} DIFFCMD;
/*** enums ***************************************************************************************/
typedef int (*DFUNC) (void *ctx, int ch, int line, off_t off, size_t sz, const char *str);
/*** structures declarations (and typedefs of structures)*****************************************/
typedef struct
{
int off;
int len;
} BRACKET[2];
/*** global variables defined in .c file *********************************************************/
typedef int PAIR[2];
/*** declarations of public functions ************************************************************/
typedef enum
{
DATA_SRC_MEM = 0,
DATA_SRC_TMP = 1,
DATA_SRC_ORG = 2
} DSRC;
typedef struct
{
int ch;
int line;
union
{
off_t off;
size_t len;
} u;
void *p;
} DIFFLN;
typedef struct
{
FBUF *f;
GArray *a;
DSRC dsrc;
} PRINTER_CTX;
typedef struct
{
Widget widget;
const char *args; /* Args passed to diff */
const char *file[2]; /* filenames */
const char *label[2];
FBUF *f[2];
const char *backup_sufix;
gboolean merged;
GArray *a[2];
GPtrArray *hdiff;
int ndiff; /* number of hunks */
DSRC dsrc; /* data source: memory or temporary file */
int view_quit:1; /* Quit flag */
int height;
int half1;
int half2;
int width1;
int width2;
int bias;
int new_frame;
int skip_rows;
int skip_cols;
int display_symbols;
int display_numbers;
int show_cr;
int tab_size;
int ord;
int full;
ssize_t last_found;
gboolean utf8;
/* converter for translation of text */
GIConv converter;
struct
{
int quality;
gboolean strip_trailing_cr;
gboolean ignore_tab_expansion;
gboolean ignore_space_change;
gboolean ignore_all_space;
gboolean ignore_case;
} opt;
} WDiff;
typedef enum
{
DIFF_NONE = 0,
DIFF_ADD = 1,
DIFF_DEL = 2,
DIFF_CHG = 3
} DiffState;
void dview_diff_cmd (WDiff * dview);
void dview_diff_cmd (struct WDiff_struct * dview);
int diff_view (const char *file1, const char *file2, const char *label1, const char *label2);
#endif
#endif /* MC__DIFFVIEW_YDIFF_H */

@ -468,6 +468,7 @@ static name_keymap_t command_names[] = {
{ "DiffEditCurrent", CK_DiffEditCurrent},
{ "DiffEditOther", CK_DiffEditOther},
{ "DiffSearch", CK_DiffSearch},
{ "DiffContinueSearch", CK_DiffContinueSearch},
{ "DiffEOF", CK_DiffEOF},
{ "DiffBOF", CK_DiffBOF},
{ "DiffDown", CK_DiffDown},
@ -990,6 +991,7 @@ const global_keymap_t default_diff_keymap[] = {
{ KEY_F (4), CK_DiffEditCurrent, "F4" },
{ KEY_F (5), CK_DiffMergeCurrentHunk, "F5" },
{ KEY_F (7), CK_DiffSearch, "F7" },
{ KEY_F (17), CK_DiffContinueSearch, "S-F7" },
{ KEY_F (10), CK_DiffQuit, "F10" },
{ KEY_F (14), CK_DiffEditOther, "S-F4" },