mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 04:22:34 +03:00
Added events for diffviewer
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
e67562edb6
commit
5dbb548479
@ -1,10 +1,19 @@
|
||||
noinst_LTLIBRARIES = libdiffviewer.la
|
||||
|
||||
libdiffviewer_la_SOURCES = \
|
||||
events.c \
|
||||
execute.c execute.h \
|
||||
internal.h \
|
||||
options.c options.h \
|
||||
search.c \
|
||||
tools.c \
|
||||
ydiff.c ydiff.h
|
||||
|
||||
if CHARSET
|
||||
libdiffviewer_la_SOURCES += charset.c charset.h
|
||||
endif
|
||||
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS)
|
||||
|
||||
libdiffviewer_la_LIBADD = ../../lib/libmc.la
|
||||
|
105
src/diffviewer/charset.c
Normal file
105
src/diffviewer/charset.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
Search functions for diffviewer.
|
||||
|
||||
Copyright (C) 2010-2014
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2010.
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2012
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "lib/strutil.h"
|
||||
#include "lib/tty/key.h"
|
||||
#include "lib/widget.h"
|
||||
#include "lib/charsets.h"
|
||||
|
||||
#include "src/history.h"
|
||||
#include "src/selcodepage.h"
|
||||
|
||||
#include "internal.h"
|
||||
#include "charset.h"
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
mc_diffviewer_set_codeset (WDiff * dview)
|
||||
{
|
||||
const char *encoding_id = NULL;
|
||||
|
||||
dview->utf8 = TRUE;
|
||||
encoding_id =
|
||||
get_codepage_id (mc_global.source_codepage >=
|
||||
0 ? mc_global.source_codepage : mc_global.display_codepage);
|
||||
if (encoding_id != NULL)
|
||||
{
|
||||
GIConv conv;
|
||||
|
||||
conv = str_crt_conv_from (encoding_id);
|
||||
if (conv != INVALID_CONV)
|
||||
{
|
||||
if (dview->converter != str_cnv_from_term)
|
||||
str_close_conv (dview->converter);
|
||||
dview->converter = conv;
|
||||
}
|
||||
dview->utf8 = (gboolean) str_isutf8 (encoding_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
gboolean
|
||||
mc_diffviewer_cmd_select_encoding_show_dialog (const gchar * event_group_name,
|
||||
const gchar * event_name, gpointer init_data,
|
||||
gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (do_select_codepage ())
|
||||
mc_diffviewer_set_codeset (dview);
|
||||
mc_diffviewer_reread (dview);
|
||||
tty_touch_screen ();
|
||||
repaint_screen ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
22
src/diffviewer/charset.h
Normal file
22
src/diffviewer/charset.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef MC__DIFFVIEW_CHARSET_H
|
||||
#define MC__DIFFVIEW_CHARSET_H
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
gboolean mc_diffviewer_cmd_select_encoding_show_dialog (const gchar * event_group_name,
|
||||
const gchar * event_name,
|
||||
gpointer init_data, gpointer data);
|
||||
|
||||
void mc_diffviewer_set_codeset (WDiff * dview);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC__DIFFVIEW_CHARSET_H */
|
683
src/diffviewer/events.c
Normal file
683
src/diffviewer/events.c
Normal file
@ -0,0 +1,683 @@
|
||||
/*
|
||||
Events diffviewer.
|
||||
|
||||
Copyright (C) 2010-2014
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2010.
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2012
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "lib/event.h"
|
||||
#include "lib/strutil.h"
|
||||
#include "lib/vfs/vfs.h" /* mc_opendir, mc_readdir, mc_closedir, */
|
||||
#include "lib/tty/key.h"
|
||||
#include "lib/widget.h"
|
||||
|
||||
#include "src/filemanager/cmd.h" /* edit_file_at_line(), view_other_cmd() */
|
||||
#include "src/history.h"
|
||||
#include "src/setup.h"
|
||||
|
||||
#include "internal.h"
|
||||
#include "options.h"
|
||||
|
||||
#ifdef HAVE_CHARSET
|
||||
#include "charset.h"
|
||||
#endif
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MC_DVIEW_SPLIT_EQUAL = 1,
|
||||
MC_DVIEW_SPLIT_FULL,
|
||||
MC_DVIEW_SPLIT_MORE,
|
||||
MC_DVIEW_SPLIT_LESS,
|
||||
} mc_diffviewer_split_type_t;
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_show_symbols (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->display_symbols ^= 1;
|
||||
dview->new_frame = 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_show_numbers (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->display_numbers ^= mc_diffviewer_calc_nwidth ((const GArray ** const) dview->a);
|
||||
dview->new_frame = 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_split_views (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
mc_diffviewer_split_type_t split_type;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (init_data == NULL)
|
||||
return TRUE;
|
||||
|
||||
split_type = (mc_diffviewer_split_type_t) init_data;
|
||||
|
||||
if (split_type == MC_DVIEW_SPLIT_FULL)
|
||||
{
|
||||
dview->full ^= 1;
|
||||
dview->new_frame = 1;
|
||||
}
|
||||
else if (!dview->full)
|
||||
{
|
||||
switch (split_type)
|
||||
{
|
||||
case MC_DVIEW_SPLIT_EQUAL:
|
||||
dview->bias = 0;
|
||||
break;
|
||||
case MC_DVIEW_SPLIT_MORE:
|
||||
mc_diffviewer_compute_split (dview, 1);
|
||||
break;
|
||||
case MC_DVIEW_SPLIT_LESS:
|
||||
mc_diffviewer_compute_split (dview, -1);
|
||||
break;
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
dview->new_frame = 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_set_tab_size (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
|
||||
if (init_data != NULL)
|
||||
dview->tab_size = (int) (intptr_t) init_data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_swap (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->ord ^= 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_redo (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (dview->display_numbers)
|
||||
{
|
||||
int old;
|
||||
|
||||
old = dview->display_numbers;
|
||||
dview->display_numbers = mc_diffviewer_calc_nwidth ((const GArray **) dview->a);
|
||||
dview->new_frame = (old != dview->display_numbers);
|
||||
}
|
||||
mc_diffviewer_reread (dview);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_hunk_next (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
const GArray *a;
|
||||
diff_place_t diff_place;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
|
||||
diff_place = (diff_place_t) init_data;
|
||||
a = dview->a[diff_place];
|
||||
|
||||
while ((size_t) dview->skip_rows < a->len
|
||||
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch != EQU_CH)
|
||||
dview->skip_rows++;
|
||||
while ((size_t) dview->skip_rows < a->len
|
||||
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch == EQU_CH)
|
||||
dview->skip_rows++;
|
||||
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_hunk_prev (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
const GArray *a;
|
||||
diff_place_t diff_place;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
|
||||
diff_place = (diff_place_t) init_data;
|
||||
a = dview->a[diff_place];
|
||||
|
||||
while (dview->skip_rows > 0
|
||||
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch != EQU_CH)
|
||||
dview->skip_rows--;
|
||||
while (dview->skip_rows > 0
|
||||
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch == EQU_CH)
|
||||
dview->skip_rows--;
|
||||
while (dview->skip_rows > 0
|
||||
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch != EQU_CH)
|
||||
dview->skip_rows--;
|
||||
if (dview->skip_rows > 0 && (size_t) dview->skip_rows < a->len)
|
||||
dview->skip_rows++;
|
||||
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_line (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
diff_place_t ord = (diff_place_t) init_data;
|
||||
/* *INDENT-OFF* */
|
||||
static const char *title[2] = {
|
||||
N_("Goto line (left)"),
|
||||
N_("Goto line (right)")
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
static char prev[256];
|
||||
/* XXX some statics here, to be remembered between runs */
|
||||
|
||||
int newline;
|
||||
char *input;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
|
||||
input =
|
||||
input_dialog (_(title[ord]), _("Enter line:"), MC_HISTORY_YDIFF_GOTO_LINE, prev,
|
||||
INPUT_COMPLETE_NONE);
|
||||
if (input != NULL)
|
||||
{
|
||||
const char *s = input;
|
||||
|
||||
if (mc_diffviewer_scan_deci (&s, &newline) == 0 && *s == '\0')
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
if (newline > 0)
|
||||
{
|
||||
for (; i < dview->a[ord]->len; i++)
|
||||
{
|
||||
const DIFFLN *p;
|
||||
|
||||
p = &g_array_index (dview->a[ord], DIFFLN, i);
|
||||
if (p->line == newline)
|
||||
break;
|
||||
}
|
||||
}
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = (ssize_t) i;
|
||||
g_snprintf (prev, sizeof (prev), "%d", newline);
|
||||
}
|
||||
g_free (input);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_edit (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
diff_place_t diff_place = (diff_place_t) init_data;
|
||||
|
||||
WDialog *h;
|
||||
gboolean h_modal;
|
||||
int linenum, lineofs;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
switch (diff_place)
|
||||
{
|
||||
case DIFF_CURRENT:
|
||||
diff_place = dview->ord;
|
||||
break;
|
||||
case DIFF_OTHER:
|
||||
diff_place = dview->ord ^ 1;
|
||||
break;
|
||||
case DIFF_LEFT:
|
||||
case DIFF_RIGHT:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dview->dsrc == DATA_SRC_TMP)
|
||||
{
|
||||
error_dialog (_("Edit"), _("Edit is disabled"));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
h = WIDGET (dview)->owner;
|
||||
h_modal = h->modal;
|
||||
|
||||
mc_diffviewer_get_line_numbers (dview->a[diff_place], dview->skip_rows, &linenum, &lineofs);
|
||||
h->modal = TRUE; /* not allow edit file in several editors */
|
||||
{
|
||||
vfs_path_t *tmp_vpath;
|
||||
|
||||
tmp_vpath = vfs_path_from_str (dview->file[diff_place]);
|
||||
edit_file_at_line (tmp_vpath, use_internal_edit != 0, linenum);
|
||||
vfs_path_free (tmp_vpath);
|
||||
}
|
||||
h->modal = h_modal;
|
||||
mc_event_raise (MCEVENT_GROUP_DIFFVIEWER, "redo", dview);
|
||||
mc_diffviewer_update (dview);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_top (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_bottom (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->skip_rows = dview->search.last_accessed_num_line = dview->a[DIFF_LEFT]->len - 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_up (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (dview->skip_rows > 0)
|
||||
{
|
||||
dview->skip_rows--;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_down (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->skip_rows++;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_page_up (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (dview->height > 2)
|
||||
{
|
||||
dview->skip_rows -= dview->height - 2;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_page_down (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (dview->height > 2)
|
||||
{
|
||||
dview->skip_rows += dview->height - 2;
|
||||
dview->search.last_accessed_num_line = dview->skip_rows;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_left (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->skip_cols -= (int) (intptr_t) init_data;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_right (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->skip_cols += (int) (intptr_t) init_data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_goto_start_of_line (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->skip_cols = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_quit (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
dview->view_quit = 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
static gboolean
|
||||
mc_diffviewer_cmd_save_changes (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
gboolean res;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (dview->merged[DIFF_LEFT])
|
||||
{
|
||||
res = mc_util_unlink_backup_if_possible (dview->file[DIFF_LEFT], "~~~");
|
||||
dview->merged[DIFF_LEFT] = !res;
|
||||
}
|
||||
if (dview->merged[DIFF_RIGHT])
|
||||
{
|
||||
res = mc_util_unlink_backup_if_possible (dview->file[DIFF_RIGHT], "~~~");
|
||||
dview->merged[DIFF_RIGHT] = !res;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
mc_diffviewer_init_events (GError ** error)
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
event_init_group_t core_group_events[] =
|
||||
{
|
||||
{"run", mc_diffviewer_cmd_run, NULL},
|
||||
{"show_symbols", mc_diffviewer_cmd_show_symbols, NULL},
|
||||
{"show_numbers", mc_diffviewer_cmd_show_numbers, NULL},
|
||||
{"split_full", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_FULL},
|
||||
{"split_equal", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_EQUAL},
|
||||
{"split_more", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_MORE},
|
||||
{"split_less", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_LESS},
|
||||
{"tab_size_2", mc_diffviewer_cmd_set_tab_size, (void *) 2},
|
||||
{"tab_size_3", mc_diffviewer_cmd_set_tab_size, (void *) 3},
|
||||
{"tab_size_4", mc_diffviewer_cmd_set_tab_size, (void *) 4},
|
||||
{"tab_size_8", mc_diffviewer_cmd_set_tab_size, (void *) 8},
|
||||
{"swap", mc_diffviewer_cmd_swap, NULL},
|
||||
{"redo", mc_diffviewer_cmd_redo, NULL},
|
||||
{"hunk_next", mc_diffviewer_cmd_hunk_next, (void *) DIFF_LEFT},
|
||||
{"hunk_prev", mc_diffviewer_cmd_hunk_prev, (void *) DIFF_LEFT},
|
||||
{"goto_line", mc_diffviewer_cmd_goto_line, (void *) DIFF_RIGHT},
|
||||
|
||||
{"edit_current", mc_diffviewer_cmd_edit, (void *) DIFF_CURRENT},
|
||||
{"edit_other", mc_diffviewer_cmd_edit, (void *) DIFF_OTHER},
|
||||
{"edit_left", mc_diffviewer_cmd_edit, (void *) DIFF_LEFT},
|
||||
{"edit_right", mc_diffviewer_cmd_edit, (void *) DIFF_RIGHT},
|
||||
|
||||
{"merge_from_left_to_right", mc_diffviewer_cmd_merge, (void *) DIFF_LEFT},
|
||||
{"merge_from_right_to_left", mc_diffviewer_cmd_merge, (void *) DIFF_RIGHT},
|
||||
{"merge_from_current_to_other", mc_diffviewer_cmd_merge, (void *) DIFF_CURRENT},
|
||||
{"merge_from_other_to_current", mc_diffviewer_cmd_merge, (void *) DIFF_OTHER},
|
||||
{"search", mc_diffviewer_cmd_search, NULL},
|
||||
{"continue_search", mc_diffviewer_cmd_continue_search, NULL},
|
||||
{"goto_top", mc_diffviewer_cmd_goto_top, NULL},
|
||||
{"goto_bottom", mc_diffviewer_cmd_goto_bottom, NULL},
|
||||
{"goto_up", mc_diffviewer_cmd_goto_up, NULL},
|
||||
{"goto_down", mc_diffviewer_cmd_goto_down, NULL},
|
||||
{"goto_page_up", mc_diffviewer_cmd_goto_page_up, NULL},
|
||||
{"goto_page_down", mc_diffviewer_cmd_goto_page_down, NULL},
|
||||
{"goto_left", mc_diffviewer_cmd_goto_left, (void *) 1},
|
||||
{"goto_left_quick", mc_diffviewer_cmd_goto_left, (void *) 8},
|
||||
{"goto_right", mc_diffviewer_cmd_goto_right, (void *) 1},
|
||||
{"goto_right_quick", mc_diffviewer_cmd_goto_right, (void *) 8},
|
||||
{"goto_start_of_line", mc_diffviewer_cmd_goto_start_of_line, (void *) 8},
|
||||
{"quit", mc_diffviewer_cmd_quit, (void *) 8},
|
||||
{"save_changes", mc_diffviewer_cmd_save_changes, (void *) 8},
|
||||
|
||||
{"options_show_dialog", mc_diffviewer_cmd_options_show_dialog, NULL},
|
||||
{"options_save", mc_diffviewer_cmd_options_save, NULL},
|
||||
{"options_load", mc_diffviewer_cmd_options_load, NULL},
|
||||
#ifdef HAVE_CHARSET
|
||||
{"select_encoding_show_dialog", mc_diffviewer_cmd_select_encoding_show_dialog, NULL},
|
||||
#endif /* HAVE_CHARSET */
|
||||
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
event_init_t standard_events[] =
|
||||
{
|
||||
{MCEVENT_GROUP_DIFFVIEWER, core_group_events},
|
||||
{NULL, NULL}
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
mc_event_mass_add (standard_events, error);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
643
src/diffviewer/execute.c
Normal file
643
src/diffviewer/execute.c
Normal file
@ -0,0 +1,643 @@
|
||||
/*
|
||||
Search functions for diffviewer.
|
||||
|
||||
Copyright (C) 2010-2014
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2010.
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2012
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "lib/strescape.h" /* strutils_glob_escape() */
|
||||
#include "lib/vfs/vfs.h" /* mc_opendir, mc_readdir, mc_closedir, */
|
||||
#include "lib/widget.h"
|
||||
#include "lib/util.h"
|
||||
|
||||
#include "execute.h"
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
#define FILE_READ_BUF 4096
|
||||
#define FILE_FLAG_TEMP (1 << 0)
|
||||
|
||||
#define FILE_DIRTY(fs) \
|
||||
do \
|
||||
{ \
|
||||
(fs)->pos = 0; \
|
||||
(fs)->len = 0; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Free file structure without closing the file.
|
||||
*
|
||||
* @param fs file structure
|
||||
* @return 0 on success, non-zero on error
|
||||
*/
|
||||
|
||||
static int
|
||||
f_free (FBUF * fs)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (fs->flags & FILE_FLAG_TEMP)
|
||||
{
|
||||
rv = unlink (fs->data);
|
||||
g_free (fs->data);
|
||||
}
|
||||
g_free (fs->buf);
|
||||
g_free (fs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Create pipe stream to process.
|
||||
*
|
||||
* @param cmd shell command line
|
||||
* @param flags open mode, either O_RDONLY or O_WRONLY
|
||||
*
|
||||
* @return file structure
|
||||
*/
|
||||
|
||||
static FBUF *
|
||||
p_open (const char *cmd, int flags)
|
||||
{
|
||||
FILE *f;
|
||||
FBUF *fs;
|
||||
const char *type = NULL;
|
||||
|
||||
if (flags == O_RDONLY)
|
||||
type = "r";
|
||||
else if (flags == O_WRONLY)
|
||||
type = "w";
|
||||
|
||||
if (type == NULL)
|
||||
return NULL;
|
||||
|
||||
fs = mc_diffviewer_file_dopen (0);
|
||||
if (fs == NULL)
|
||||
return NULL;
|
||||
|
||||
f = popen (cmd, type);
|
||||
if (f == NULL)
|
||||
{
|
||||
f_free (fs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs->fd = fileno (f);
|
||||
fs->data = f;
|
||||
return fs;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* diff parse *************************************************************** */
|
||||
/**
|
||||
* Parse line for diff statement.
|
||||
*
|
||||
* @param p string to parse
|
||||
* @param ops list of diff statements
|
||||
* @return 0 if success, otherwise non-zero
|
||||
*/
|
||||
|
||||
static int
|
||||
scan_line (const char *p, GArray * ops)
|
||||
{
|
||||
DIFFCMD op;
|
||||
|
||||
int f1, f2;
|
||||
int t1, t2;
|
||||
int cmd;
|
||||
int range;
|
||||
|
||||
/* handle the following cases:
|
||||
* NUMaNUM[,NUM]
|
||||
* NUM[,NUM]cNUM[,NUM]
|
||||
* NUM[,NUM]dNUM
|
||||
* where NUM is a positive integer
|
||||
*/
|
||||
|
||||
if (mc_diffviewer_scan_deci (&p, &f1) != 0 || f1 < 0)
|
||||
return -1;
|
||||
|
||||
f2 = f1;
|
||||
range = 0;
|
||||
if (*p == ',')
|
||||
{
|
||||
p++;
|
||||
if (mc_diffviewer_scan_deci (&p, &f2) != 0 || f2 < f1)
|
||||
return -1;
|
||||
|
||||
range = 1;
|
||||
}
|
||||
|
||||
cmd = *p++;
|
||||
if (cmd == 'a')
|
||||
{
|
||||
if (range != 0)
|
||||
return -1;
|
||||
}
|
||||
else if (cmd != 'c' && cmd != 'd')
|
||||
return -1;
|
||||
|
||||
if (mc_diffviewer_scan_deci (&p, &t1) != 0 || t1 < 0)
|
||||
return -1;
|
||||
|
||||
t2 = t1;
|
||||
range = 0;
|
||||
if (*p == ',')
|
||||
{
|
||||
p++;
|
||||
if (mc_diffviewer_scan_deci (&p, &t2) != 0 || t2 < t1)
|
||||
return -1;
|
||||
|
||||
range = 1;
|
||||
}
|
||||
|
||||
if (cmd == 'd' && range != 0)
|
||||
return -1;
|
||||
|
||||
op.a[0][0] = f1;
|
||||
op.a[0][1] = f2;
|
||||
op.cmd = cmd;
|
||||
op.a[1][0] = t1;
|
||||
op.a[1][1] = t2;
|
||||
g_array_append_val (ops, op);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Parse diff output and extract diff statements.
|
||||
*
|
||||
* @param f stream to read from
|
||||
* @param ops list of diff statements to fill
|
||||
* @return positive number indicating number of hunks, otherwise negative
|
||||
*/
|
||||
|
||||
static int
|
||||
scan_diff (FBUF * f, GArray * ops)
|
||||
{
|
||||
int sz;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
while ((sz = mc_diffviewer_file_gets (buf, sizeof (buf) - 1, f)) != 0)
|
||||
{
|
||||
if (isdigit (buf[0]))
|
||||
{
|
||||
if (buf[sz - 1] != '\n')
|
||||
return -1;
|
||||
|
||||
buf[sz] = '\0';
|
||||
if (scan_line (buf, ops) != 0)
|
||||
return -1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
while (buf[sz - 1] != '\n' && (sz = mc_diffviewer_file_gets (buf, sizeof (buf), f)) != 0)
|
||||
;
|
||||
}
|
||||
|
||||
return ops->len;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Close pipe stream.
|
||||
*
|
||||
* @param fs structure
|
||||
* @return 0 on success, non-zero on error
|
||||
*/
|
||||
|
||||
static int
|
||||
p_close (FBUF * fs)
|
||||
{
|
||||
int rv = -1;
|
||||
|
||||
if (fs != NULL)
|
||||
{
|
||||
rv = pclose (fs->data);
|
||||
f_free (fs);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Invoke diff and extract diff statements.
|
||||
*
|
||||
* @param args extra arguments to be passed to diff
|
||||
* @param extra more arguments to be passed to diff
|
||||
* @param file1 first file to compare
|
||||
* @param file2 second file to compare
|
||||
* @param ops list of diff statements to fill
|
||||
*
|
||||
* @return positive number indicating number of hunks, otherwise negative
|
||||
*/
|
||||
|
||||
int
|
||||
mc_diffviewer_execute (const char *args, const char *extra, const char *file1, const char *file2,
|
||||
GArray * ops)
|
||||
{
|
||||
static const char *opt =
|
||||
" --old-group-format='%df%(f=l?:,%dl)d%dE\n'"
|
||||
" --new-group-format='%dea%dF%(F=L?:,%dL)\n'"
|
||||
" --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)\n'"
|
||||
" --unchanged-group-format=''";
|
||||
|
||||
int rv;
|
||||
FBUF *f;
|
||||
char *cmd;
|
||||
int code;
|
||||
char *file1_esc, *file2_esc;
|
||||
|
||||
/* escape potential $ to avoid shell variable substitutions in popen() */
|
||||
file1_esc = strutils_shell_escape (file1);
|
||||
file2_esc = strutils_shell_escape (file2);
|
||||
cmd = g_strdup_printf ("diff %s %s %s %s %s", args, extra, opt, file1_esc, file2_esc);
|
||||
g_free (file1_esc);
|
||||
g_free (file2_esc);
|
||||
|
||||
if (cmd == NULL)
|
||||
return -1;
|
||||
|
||||
f = p_open (cmd, O_RDONLY);
|
||||
g_free (cmd);
|
||||
|
||||
if (f == NULL)
|
||||
return -1;
|
||||
|
||||
rv = scan_diff (f, ops);
|
||||
code = p_close (f);
|
||||
|
||||
if (rv < 0 || code == -1 || !WIFEXITED (code) || WEXITSTATUS (code) == 2)
|
||||
rv = -1;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Close file.
|
||||
* @note if this is temporary file, it is deleted
|
||||
*
|
||||
* @param fs file structure
|
||||
* @return 0 on success, non-zero on error
|
||||
*/
|
||||
|
||||
int
|
||||
mc_diffviewer_file_close (FBUF * fs)
|
||||
{
|
||||
int rv = -1;
|
||||
|
||||
if (fs != NULL)
|
||||
{
|
||||
rv = close (fs->fd);
|
||||
f_free (fs);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Read decimal number from string.
|
||||
*
|
||||
* @param[in,out] str string to parse
|
||||
* @param[out] n extracted number
|
||||
* @return 0 if success, otherwise non-zero
|
||||
*/
|
||||
|
||||
int
|
||||
mc_diffviewer_scan_deci (const char **str, int *n)
|
||||
{
|
||||
const char *p = *str;
|
||||
char *q;
|
||||
|
||||
errno = 0;
|
||||
*n = strtol (p, &q, 10);
|
||||
if (errno != 0 || p == q)
|
||||
return -1;
|
||||
*str = q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Seek into file.
|
||||
* @note avoids thrashing read cache when possible
|
||||
*
|
||||
* @param fs file structure
|
||||
* @param off offset
|
||||
* @param whence seek directive: SEEK_SET, SEEK_CUR or SEEK_END
|
||||
*
|
||||
* @return position in file, starting from begginning
|
||||
*/
|
||||
|
||||
off_t
|
||||
mc_diffviewer_file_seek (FBUF * fs, off_t off, int whence)
|
||||
{
|
||||
off_t rv;
|
||||
|
||||
if (fs->len && whence != SEEK_END)
|
||||
{
|
||||
rv = lseek (fs->fd, 0, SEEK_CUR);
|
||||
if (rv != -1)
|
||||
{
|
||||
if (whence == SEEK_CUR)
|
||||
{
|
||||
whence = SEEK_SET;
|
||||
off += rv - fs->len + fs->pos;
|
||||
}
|
||||
if (off - rv >= -fs->len && off - rv <= 0)
|
||||
{
|
||||
fs->pos = fs->len + off - rv;
|
||||
return off;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = lseek (fs->fd, off, whence);
|
||||
if (rv != -1)
|
||||
FILE_DIRTY (fs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Read a line of bytes from file until newline or EOF.
|
||||
* @note does not stop on null-byte
|
||||
* @note buf will not be null-terminated
|
||||
*
|
||||
* @param buf destination buffer
|
||||
* @param size size of buffer
|
||||
* @param fs file structure
|
||||
*
|
||||
* @return number of bytes read
|
||||
*/
|
||||
|
||||
size_t
|
||||
mc_diffviewer_file_gets (char *buf, size_t size, FBUF * fs)
|
||||
{
|
||||
size_t j = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int i;
|
||||
int stop = 0;
|
||||
|
||||
for (i = fs->pos; j < size && i < fs->len && !stop; i++, j++)
|
||||
{
|
||||
buf[j] = fs->buf[i];
|
||||
if (buf[j] == '\n')
|
||||
stop = 1;
|
||||
}
|
||||
fs->pos = i;
|
||||
|
||||
if (j == size || stop)
|
||||
break;
|
||||
|
||||
fs->pos = 0;
|
||||
fs->len = read (fs->fd, fs->buf, FILE_READ_BUF);
|
||||
}
|
||||
while (fs->len > 0);
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Seek to the beginning of file, thrashing read cache.
|
||||
*
|
||||
* @param fs file structure
|
||||
*
|
||||
* @return 0 if success, non-zero on error
|
||||
*/
|
||||
|
||||
off_t
|
||||
mc_diffviewer_file_reset (FBUF * fs)
|
||||
{
|
||||
off_t rv;
|
||||
|
||||
rv = lseek (fs->fd, 0, SEEK_SET);
|
||||
if (rv != -1)
|
||||
FILE_DIRTY (fs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Open a binary file in specified mode.
|
||||
*
|
||||
* @param filename file name
|
||||
* @param flags open mode, a combination of O_RDONLY, O_WRONLY, O_RDWR
|
||||
*
|
||||
* @return file structure
|
||||
*/
|
||||
|
||||
FBUF *
|
||||
mc_diffviewer_file_open (const char *filename, int flags)
|
||||
{
|
||||
int fd;
|
||||
FBUF *fs;
|
||||
|
||||
fs = mc_diffviewer_file_dopen (0);
|
||||
if (fs == NULL)
|
||||
return NULL;
|
||||
|
||||
fd = open (filename, flags);
|
||||
if (fd < 0)
|
||||
{
|
||||
f_free (fs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs->fd = fd;
|
||||
return fs;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Write bytes to file.
|
||||
* @note thrashes read cache
|
||||
*
|
||||
* @param fs file structure
|
||||
* @param buf source buffer
|
||||
* @param size size of buffer
|
||||
*
|
||||
* @return number of written bytes, -1 on error
|
||||
*/
|
||||
|
||||
ssize_t
|
||||
mc_diffviewer_file_write (FBUF * fs, const char *buf, size_t size)
|
||||
{
|
||||
ssize_t rv;
|
||||
|
||||
rv = write (fs->fd, buf, size);
|
||||
if (rv >= 0)
|
||||
FILE_DIRTY (fs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Truncate file to the current position.
|
||||
* @note thrashes read cache
|
||||
*
|
||||
* @param fs file structure
|
||||
*
|
||||
* @return current file size on success, negative on error
|
||||
*/
|
||||
|
||||
off_t
|
||||
mc_diffviewer_file_trunc (FBUF * fs)
|
||||
{
|
||||
off_t off;
|
||||
|
||||
off = lseek (fs->fd, 0, SEEK_CUR);
|
||||
if (off != -1)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = ftruncate (fs->fd, off);
|
||||
if (rv != 0)
|
||||
off = -1;
|
||||
else
|
||||
FILE_DIRTY (fs);
|
||||
}
|
||||
return off;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Alocate file structure and associate file descriptor to it.
|
||||
*
|
||||
* @param fd file descriptor
|
||||
* @return file structure
|
||||
*/
|
||||
|
||||
FBUF *
|
||||
mc_diffviewer_file_dopen (int fd)
|
||||
{
|
||||
FBUF *fs;
|
||||
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
fs = g_try_malloc (sizeof (FBUF));
|
||||
if (fs == NULL)
|
||||
return NULL;
|
||||
|
||||
fs->buf = g_try_malloc (FILE_READ_BUF);
|
||||
if (fs->buf == NULL)
|
||||
{
|
||||
g_free (fs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs->fd = fd;
|
||||
FILE_DIRTY (fs);
|
||||
fs->flags = 0;
|
||||
fs->data = NULL;
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Try to open a temporary file.
|
||||
* @note the name is not altered if this function fails
|
||||
*
|
||||
* @param[out] name address of a pointer to store the temporary name
|
||||
* @return file descriptor on success, negative on error
|
||||
*/
|
||||
|
||||
static int
|
||||
open_temp (void **name)
|
||||
{
|
||||
int fd;
|
||||
vfs_path_t *diff_file_name = NULL;
|
||||
|
||||
fd = mc_mkstemps (&diff_file_name, "mcdiff", NULL);
|
||||
if (fd == -1)
|
||||
{
|
||||
message (D_ERROR, MSG_ERROR,
|
||||
_("Cannot create temporary diff file\n%s"), unix_error_string (errno));
|
||||
return -1;
|
||||
}
|
||||
*name = g_strdup (vfs_path_as_str (diff_file_name));
|
||||
vfs_path_free (diff_file_name);
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Open a binary temporary file in R/W mode.
|
||||
* @note the file will be deleted when closed
|
||||
*
|
||||
* @return file structure
|
||||
*/
|
||||
|
||||
FBUF *
|
||||
mc_diffviewer_file_temp (void)
|
||||
{
|
||||
int fd;
|
||||
FBUF *fs;
|
||||
|
||||
fs = mc_diffviewer_file_dopen (0);
|
||||
if (fs == NULL)
|
||||
return NULL;
|
||||
|
||||
fd = open_temp (&fs->data);
|
||||
if (fd < 0)
|
||||
{
|
||||
f_free (fs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs->fd = fd;
|
||||
fs->flags = FILE_FLAG_TEMP;
|
||||
return fs;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
45
src/diffviewer/execute.h
Normal file
45
src/diffviewer/execute.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef MC__DIFFVIEW_EXECUTE_H
|
||||
#define MC__DIFFVIEW_EXECUTE_H
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/*** 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;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
int mc_diffviewer_scan_deci (const char **str, int *n);
|
||||
int mc_diffviewer_file_close (FBUF * fs);
|
||||
int mc_diffviewer_execute (const char *args, const char *extra, const char *file1,
|
||||
const char *file2, GArray * ops);
|
||||
off_t mc_diffviewer_file_seek (FBUF * fs, off_t off, int whence);
|
||||
size_t mc_diffviewer_file_gets (char *buf, size_t size, FBUF * fs);
|
||||
off_t mc_diffviewer_file_reset (FBUF * fs);
|
||||
FBUF *mc_diffviewer_file_open (const char *filename, int flags);
|
||||
ssize_t mc_diffviewer_file_write (FBUF * fs, const char *buf, size_t size);
|
||||
off_t mc_diffviewer_file_trunc (FBUF * fs);
|
||||
FBUF *mc_diffviewer_file_dopen (int fd);
|
||||
FBUF *mc_diffviewer_file_temp (void);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC__DIFFVIEW_EXECUTE_H */
|
@ -7,6 +7,8 @@
|
||||
#include "lib/tty/color.h"
|
||||
#include "lib/widget.h"
|
||||
|
||||
#include "execute.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);
|
||||
@ -14,6 +16,11 @@ typedef int PAIR[2];
|
||||
|
||||
#define error_dialog(h, s) query_dialog(h, s, D_ERROR, 1, _("&Dismiss"))
|
||||
|
||||
#define ADD_CH '+'
|
||||
#define DEL_CH '-'
|
||||
#define CHG_CH '*'
|
||||
#define EQU_CH ' '
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
typedef enum
|
||||
@ -27,7 +34,9 @@ typedef enum
|
||||
{
|
||||
DIFF_LEFT = 0,
|
||||
DIFF_RIGHT = 1,
|
||||
DIFF_COUNT = 2
|
||||
DIFF_COUNT = 2,
|
||||
DIFF_CURRENT = 3,
|
||||
DIFF_OTHER = 4
|
||||
} diff_place_t;
|
||||
|
||||
typedef enum
|
||||
@ -40,23 +49,6 @@ typedef enum
|
||||
|
||||
/*** 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;
|
||||
@ -146,8 +138,32 @@ typedef struct WDiff
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
void mc_diffviewer_init_events (GError ** error);
|
||||
|
||||
/* search.c */
|
||||
void dview_search_cmd (WDiff * dview);
|
||||
void dview_continue_search_cmd (WDiff * dview);
|
||||
gboolean mc_diffviewer_cmd_search (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data);
|
||||
gboolean mc_diffviewer_cmd_continue_search (const gchar * event_group_name,
|
||||
const gchar * event_name, gpointer init_data,
|
||||
gpointer data);
|
||||
|
||||
|
||||
int mc_diffviewer_calc_nwidth (const GArray ** const a);
|
||||
void mc_diffviewer_compute_split (WDiff * dview, int i);
|
||||
int mc_diffviewer_get_line_numbers (const GArray * a, size_t pos, int *linenum, int *lineofs);
|
||||
void mc_diffviewer_reread (WDiff * dview);
|
||||
void mc_diffviewer_update (WDiff * dview);
|
||||
|
||||
void mc_diffviewer_destroy_hdiff (WDiff * dview);
|
||||
void mc_diffviewer_deinit (WDiff * dview);
|
||||
|
||||
int mc_diffviewer_redo_diff (WDiff * dview);
|
||||
gboolean mc_diffviewer_cmd_merge (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data);
|
||||
|
||||
gboolean mc_diffviewer_cmd_run (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC__DIFFVIEW_INTERNAL_H */
|
||||
|
183
src/diffviewer/options.c
Normal file
183
src/diffviewer/options.c
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
Search functions for diffviewer.
|
||||
|
||||
Copyright (C) 2010-2014
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2010.
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2012
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "lib/strutil.h"
|
||||
#include "lib/tty/key.h"
|
||||
#include "lib/widget.h"
|
||||
|
||||
#include "src/history.h"
|
||||
|
||||
#include "internal.h"
|
||||
#include "options.h"
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
gboolean
|
||||
mc_diffviewer_cmd_options_save (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
mc_config_set_bool (mc_main_config, "DiffView", "show_symbols",
|
||||
dview->display_symbols != 0 ? TRUE : FALSE);
|
||||
mc_config_set_bool (mc_main_config, "DiffView", "show_numbers",
|
||||
dview->display_numbers != 0 ? TRUE : FALSE);
|
||||
mc_config_set_int (mc_main_config, "DiffView", "tab_size", dview->tab_size);
|
||||
|
||||
mc_config_set_int (mc_main_config, "DiffView", "diff_quality", dview->opt.quality);
|
||||
|
||||
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_tws",
|
||||
dview->opt.strip_trailing_cr);
|
||||
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_all_space",
|
||||
dview->opt.ignore_all_space);
|
||||
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_space_change",
|
||||
dview->opt.ignore_space_change);
|
||||
mc_config_set_bool (mc_main_config, "DiffView", "diff_tab_expansion",
|
||||
dview->opt.ignore_tab_expansion);
|
||||
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_case", dview->opt.ignore_case);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
gboolean
|
||||
mc_diffviewer_cmd_options_load (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
gboolean show_numbers, show_symbols;
|
||||
int tab_size;
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
show_symbols = mc_config_get_bool (mc_main_config, "DiffView", "show_symbols", FALSE);
|
||||
if (show_symbols)
|
||||
dview->display_symbols = 1;
|
||||
show_numbers = mc_config_get_bool (mc_main_config, "DiffView", "show_numbers", FALSE);
|
||||
if (show_numbers)
|
||||
dview->display_numbers = mc_diffviewer_calc_nwidth ((const GArray ** const) dview->a);
|
||||
tab_size = mc_config_get_int (mc_main_config, "DiffView", "tab_size", 8);
|
||||
if (tab_size > 0 && tab_size < 9)
|
||||
dview->tab_size = tab_size;
|
||||
else
|
||||
dview->tab_size = 8;
|
||||
|
||||
dview->opt.quality = mc_config_get_int (mc_main_config, "DiffView", "diff_quality", 0);
|
||||
|
||||
dview->opt.strip_trailing_cr =
|
||||
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_tws", FALSE);
|
||||
dview->opt.ignore_all_space =
|
||||
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_all_space", FALSE);
|
||||
dview->opt.ignore_space_change =
|
||||
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_space_change", FALSE);
|
||||
dview->opt.ignore_tab_expansion =
|
||||
mc_config_get_bool (mc_main_config, "DiffView", "diff_tab_expansion", FALSE);
|
||||
dview->opt.ignore_case =
|
||||
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_case", FALSE);
|
||||
|
||||
dview->new_frame = 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
gboolean
|
||||
mc_diffviewer_cmd_options_show_dialog (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
const char *quality_str[] = {
|
||||
N_("No&rmal"),
|
||||
N_("&Fastest (Assume large files)"),
|
||||
N_("&Minimal (Find a smaller set of change)")
|
||||
};
|
||||
|
||||
quick_widget_t quick_widgets[] = {
|
||||
/* *INDENT-OFF* */
|
||||
QUICK_START_GROUPBOX (N_("Diff algorithm")),
|
||||
QUICK_RADIO (3, (const char **) quality_str, (int *) &dview->opt.quality, NULL),
|
||||
QUICK_STOP_GROUPBOX,
|
||||
QUICK_START_GROUPBOX (N_("Diff extra options")),
|
||||
QUICK_CHECKBOX (N_("&Ignore case"), &dview->opt.ignore_case, NULL),
|
||||
QUICK_CHECKBOX (N_("Ignore tab &expansion"), &dview->opt.ignore_tab_expansion, NULL),
|
||||
QUICK_CHECKBOX (N_("Ignore &space change"), &dview->opt.ignore_space_change, NULL),
|
||||
QUICK_CHECKBOX (N_("Ignore all &whitespace"), &dview->opt.ignore_all_space, NULL),
|
||||
QUICK_CHECKBOX (N_("Strip &trailing carriage return"), &dview->opt.strip_trailing_cr,
|
||||
NULL),
|
||||
QUICK_STOP_GROUPBOX,
|
||||
QUICK_BUTTONS_OK_CANCEL,
|
||||
QUICK_END
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
quick_dialog_t qdlg = {
|
||||
-1, -1, 56,
|
||||
N_("Diff Options"), "[Diff Options]",
|
||||
quick_widgets, NULL, NULL
|
||||
};
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (quick_dialog (&qdlg) != B_CANCEL)
|
||||
mc_diffviewer_reread (dview);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
26
src/diffviewer/options.h
Normal file
26
src/diffviewer/options.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef MC__DIFFVIEW_OPTIONS_H
|
||||
#define MC__DIFFVIEW_OPTIONS_H
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
gboolean mc_diffviewer_cmd_options_save (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data);
|
||||
|
||||
gboolean mc_diffviewer_cmd_options_load (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data);
|
||||
|
||||
gboolean mc_diffviewer_cmd_options_show_dialog (const gchar * event_group_name,
|
||||
const gchar * event_name, gpointer init_data,
|
||||
gpointer data);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC__DIFFVIEW_OPTIONS_H */
|
@ -236,18 +236,26 @@ mcdiffview_do_search (WDiff * dview)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
void
|
||||
dview_search_cmd (WDiff * dview)
|
||||
gboolean
|
||||
mc_diffviewer_cmd_search (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
(void) init_data;
|
||||
|
||||
if (dview->dsrc != DATA_SRC_MEM)
|
||||
{
|
||||
error_dialog (_("Search"), _("Search is disabled"));
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!mcdiffview_dialog_search (dview))
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
mc_search_free (dview->search.handle);
|
||||
#ifdef HAVE_CHARSET
|
||||
@ -257,7 +265,7 @@ dview_search_cmd (WDiff * dview)
|
||||
#endif
|
||||
|
||||
if (dview->search.handle == NULL)
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
dview->search.handle->search_type = mcdiffview_search_options.type;
|
||||
#ifdef HAVE_CHARSET
|
||||
@ -267,19 +275,27 @@ dview_search_cmd (WDiff * dview)
|
||||
dview->search.handle->whole_words = mcdiffview_search_options.whole_words;
|
||||
|
||||
mcdiffview_do_search (dview);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/* event callback */
|
||||
|
||||
void
|
||||
dview_continue_search_cmd (WDiff * dview)
|
||||
gboolean
|
||||
mc_diffviewer_cmd_continue_search (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WDiff *dview = (WDiff *) data;
|
||||
|
||||
if (dview->dsrc != DATA_SRC_MEM)
|
||||
error_dialog (_("Search"), _("Search is disabled"));
|
||||
else if (dview->search.handle == NULL)
|
||||
dview_search_cmd (dview);
|
||||
return mc_diffviewer_cmd_search (event_group_name, event_name, init_data, data);
|
||||
else
|
||||
mcdiffview_do_search (dview);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
2002
src/diffviewer/tools.c
Normal file
2002
src/diffviewer/tools.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,40 @@
|
||||
#ifndef MC__DIFFVIEW_YDIFF_H
|
||||
#define MC__DIFFVIEW_YDIFF_H
|
||||
|
||||
#include "src/filemanager/panel.h"
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mc_run_mode_t run_mode;
|
||||
gboolean ret_value;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
WPanel *first;
|
||||
WPanel *second;
|
||||
} panel;
|
||||
struct
|
||||
{
|
||||
const char *first;
|
||||
const char *second;
|
||||
} file;
|
||||
} data;
|
||||
} ev_diffviewer_run_t;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
gboolean dview_diff_cmd (const void *f0, const void *f1);
|
||||
void mc_diffviewer_init (GError ** error);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC__DIFFVIEW_YDIFF_H */
|
||||
|
@ -1181,14 +1181,17 @@ compare_dirs_cmd (void)
|
||||
void
|
||||
diff_view_cmd (void)
|
||||
{
|
||||
ev_diffviewer_run_t event_info;
|
||||
|
||||
/* both panels must be in the list mode */
|
||||
if (get_current_type () != view_listing || get_other_type () != view_listing)
|
||||
return;
|
||||
|
||||
if (get_current_index () == 0)
|
||||
dview_diff_cmd (current_panel, other_panel);
|
||||
else
|
||||
dview_diff_cmd (other_panel, current_panel);
|
||||
event_info.run_mode = mc_global.mc_run_mode;
|
||||
event_info.data.panel.first = current_panel;
|
||||
event_info.data.panel.second = other_panel;
|
||||
|
||||
mc_event_raise (MCEVENT_GROUP_DIFFVIEWER, "run", &event_info);
|
||||
|
||||
if (mc_global.mc_run_mode == MC_RUN_FULL)
|
||||
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
||||
|
@ -1007,7 +1007,16 @@ mc_maybe_editor_or_viewer (void)
|
||||
}
|
||||
#ifdef USE_DIFF_VIEW
|
||||
case MC_RUN_DIFFVIEWER:
|
||||
ret = dview_diff_cmd (mc_run_param0, mc_run_param1);
|
||||
{
|
||||
ev_diffviewer_run_t event_info;
|
||||
|
||||
event_info.run_mode = mc_global.mc_run_mode;
|
||||
event_info.data.file.first = mc_run_param0;
|
||||
event_info.data.file.second = mc_run_param1;
|
||||
|
||||
mc_event_raise (MCEVENT_GROUP_DIFFVIEWER, "run", &event_info);
|
||||
ret = event_info.ret_value;
|
||||
}
|
||||
break;
|
||||
#endif /* USE_DIFF_VIEW */
|
||||
default:
|
||||
@ -1736,7 +1745,7 @@ quiet_quit_cmd (void)
|
||||
|
||||
/** Run the main dialog that occupies the whole screen */
|
||||
gboolean
|
||||
do_nc (void)
|
||||
do_nc (GError ** error)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
@ -1744,6 +1753,10 @@ do_nc (void)
|
||||
edit_stack_init ();
|
||||
#endif
|
||||
|
||||
#ifdef USE_DIFF_VIEW
|
||||
mc_diffviewer_init (error);
|
||||
#endif
|
||||
|
||||
midnight_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, dialog_colors, midnight_callback,
|
||||
midnight_event, "[main]", NULL, DLG_NONE);
|
||||
|
||||
|
@ -45,7 +45,7 @@ void load_hint (gboolean force);
|
||||
void change_panel (void);
|
||||
void save_cwds_stat (void);
|
||||
gboolean quiet_quit_cmd (void);
|
||||
gboolean do_nc (void);
|
||||
gboolean do_nc (GError **);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
|
@ -415,7 +415,14 @@ main (int argc, char *argv[])
|
||||
if (mc_global.midnight_shutdown)
|
||||
exit_code = EXIT_SUCCESS;
|
||||
else
|
||||
exit_code = do_nc ()? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
exit_code = do_nc (&error) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
message (D_ERROR, _("Warning"), "%s", error->message);
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
|
||||
/* Save the tree store */
|
||||
(void) tree_store_save ();
|
||||
|
Loading…
Reference in New Issue
Block a user