mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Ticket #2863 (mcdiff bidirectional merge enhancement)
Added feature for the mcdiff for the bidirectional merge. With F15 mcdiffviewer merge left panel to right panel direction. original patch by Gergely Szasz <szaszg@hu.inter.net> Signed-off-by: Ilia Maslakov <il.smind@gmail.com> added bind "MergeOther" into mc.keymap.default, mc.keymap.emacs. Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
This commit is contained in:
parent
961019d078
commit
d8aa98b7d4
@ -353,6 +353,7 @@ static name_keymap_t command_names[] = {
|
|||||||
{"HunkPrev", CK_HunkPrev},
|
{"HunkPrev", CK_HunkPrev},
|
||||||
{"EditOther", CK_EditOther},
|
{"EditOther", CK_EditOther},
|
||||||
{"Merge", CK_Merge},
|
{"Merge", CK_Merge},
|
||||||
|
{"MergeOther", CK_MergeOther},
|
||||||
#endif /* USE_DIFF_VIEW */
|
#endif /* USE_DIFF_VIEW */
|
||||||
|
|
||||||
{NULL, CK_IgnoreKey}
|
{NULL, CK_IgnoreKey}
|
||||||
|
@ -328,7 +328,8 @@ enum
|
|||||||
CK_HunkNext,
|
CK_HunkNext,
|
||||||
CK_HunkPrev,
|
CK_HunkPrev,
|
||||||
CK_EditOther,
|
CK_EditOther,
|
||||||
CK_Merge
|
CK_Merge,
|
||||||
|
CK_MergeOther
|
||||||
};
|
};
|
||||||
|
|
||||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||||
|
@ -432,6 +432,7 @@ Save = f2
|
|||||||
Edit = f4
|
Edit = f4
|
||||||
EditOther = f14
|
EditOther = f14
|
||||||
Merge = f5
|
Merge = f5
|
||||||
|
MergeOther = f15
|
||||||
Search = f7
|
Search = f7
|
||||||
SearchContinue = f17
|
SearchContinue = f17
|
||||||
Options = f9
|
Options = f9
|
||||||
|
@ -434,6 +434,7 @@ Save = f2
|
|||||||
Edit = f4
|
Edit = f4
|
||||||
EditOther = f14
|
EditOther = f14
|
||||||
Merge = f5
|
Merge = f5
|
||||||
|
MergeOther = f15
|
||||||
Search = f7
|
Search = f7
|
||||||
SearchContinue = f17
|
SearchContinue = f17
|
||||||
Options = f9
|
Options = f9
|
||||||
|
@ -84,7 +84,7 @@ typedef struct WDiff
|
|||||||
char *label[2];
|
char *label[2];
|
||||||
FBUF *f[2];
|
FBUF *f[2];
|
||||||
const char *backup_sufix;
|
const char *backup_sufix;
|
||||||
gboolean merged;
|
gboolean merged[2];
|
||||||
GArray *a[2];
|
GArray *a[2];
|
||||||
GPtrArray *hdiff;
|
GPtrArray *hdiff;
|
||||||
int ndiff; /* number of hunks */
|
int ndiff; /* number of hunks */
|
||||||
|
@ -2061,12 +2061,17 @@ get_current_hunk (WDiff * dview, int *start_line1, int *end_line1, int *start_li
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dview_remove_hunk (WDiff * dview, FILE * merge_file, int from1, int to1)
|
dview_remove_hunk (WDiff * dview, FILE * merge_file, int from1, int to1, gboolean merge_direction)
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
char buf[BUF_10K];
|
char buf[BUF_10K];
|
||||||
FILE *f0;
|
FILE *f0;
|
||||||
|
|
||||||
|
if (merge_direction)
|
||||||
|
f0 = fopen (dview->file[1], "r");
|
||||||
|
else
|
||||||
f0 = fopen (dview->file[0], "r");
|
f0 = fopen (dview->file[0], "r");
|
||||||
|
|
||||||
line = 0;
|
line = 0;
|
||||||
while (fgets (buf, sizeof (buf), f0) != NULL && line < from1 - 1)
|
while (fgets (buf, sizeof (buf), f0) != NULL && line < from1 - 1)
|
||||||
{
|
{
|
||||||
@ -2083,14 +2088,25 @@ dview_remove_hunk (WDiff * dview, FILE * merge_file, int from1, int to1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dview_add_hunk (WDiff * dview, FILE * merge_file, int from1, int from2, int to2)
|
dview_add_hunk (WDiff * dview, FILE * merge_file, int from1, int from2, int to2,
|
||||||
|
gboolean merge_direction)
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
char buf[BUF_10K];
|
char buf[BUF_10K];
|
||||||
FILE *f0;
|
FILE *f0;
|
||||||
FILE *f1;
|
FILE *f1;
|
||||||
|
|
||||||
|
if (merge_direction)
|
||||||
|
{
|
||||||
|
f0 = fopen (dview->file[1], "r");
|
||||||
|
f1 = fopen (dview->file[0], "r");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
f0 = fopen (dview->file[0], "r");
|
f0 = fopen (dview->file[0], "r");
|
||||||
f1 = fopen (dview->file[1], "r");
|
f1 = fopen (dview->file[1], "r");
|
||||||
|
}
|
||||||
|
|
||||||
line = 0;
|
line = 0;
|
||||||
while (fgets (buf, sizeof (buf), f0) != NULL && line < from1 - 1)
|
while (fgets (buf, sizeof (buf), f0) != NULL && line < from1 - 1)
|
||||||
{
|
{
|
||||||
@ -2113,14 +2129,25 @@ dview_add_hunk (WDiff * dview, FILE * merge_file, int from1, int from2, int to2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dview_replace_hunk (WDiff * dview, FILE * merge_file, int from1, int to1, int from2, int to2)
|
dview_replace_hunk (WDiff * dview, FILE * merge_file, int from1, int to1, int from2, int to2,
|
||||||
|
gboolean merge_direction)
|
||||||
{
|
{
|
||||||
int line1, line2;
|
int line1, line2;
|
||||||
char buf[BUF_10K];
|
char buf[BUF_10K];
|
||||||
FILE *f0;
|
FILE *f0;
|
||||||
FILE *f1;
|
FILE *f1;
|
||||||
|
|
||||||
|
if (merge_direction)
|
||||||
|
{
|
||||||
|
f0 = fopen (dview->file[1], "r");
|
||||||
|
f1 = fopen (dview->file[0], "r");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
f0 = fopen (dview->file[0], "r");
|
f0 = fopen (dview->file[0], "r");
|
||||||
f1 = fopen (dview->file[1], "r");
|
f1 = fopen (dview->file[1], "r");
|
||||||
|
}
|
||||||
|
|
||||||
line1 = 0;
|
line1 = 0;
|
||||||
while (fgets (buf, sizeof (buf), f0) != NULL && line1 < from1 - 1)
|
while (fgets (buf, sizeof (buf), f0) != NULL && line1 < from1 - 1)
|
||||||
{
|
{
|
||||||
@ -2145,27 +2172,32 @@ dview_replace_hunk (WDiff * dview, FILE * merge_file, int from1, int to1, int fr
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_merge_hunk (WDiff * dview)
|
do_merge_hunk (WDiff * dview, gboolean merge_direction)
|
||||||
{
|
{
|
||||||
int from1, to1, from2, to2;
|
int from1, to1, from2, to2;
|
||||||
int res;
|
int res;
|
||||||
int hunk;
|
int hunk;
|
||||||
|
int n_merge = merge_direction ? 1 : 0;
|
||||||
|
|
||||||
|
if (merge_direction)
|
||||||
|
hunk = get_current_hunk (dview, &from2, &to2, &from1, &to1);
|
||||||
|
else
|
||||||
hunk = get_current_hunk (dview, &from1, &to1, &from2, &to2);
|
hunk = get_current_hunk (dview, &from1, &to1, &from2, &to2);
|
||||||
|
|
||||||
if (hunk > 0)
|
if (hunk > 0)
|
||||||
{
|
{
|
||||||
int merge_file_fd;
|
int merge_file_fd;
|
||||||
FILE *merge_file;
|
FILE *merge_file;
|
||||||
vfs_path_t *merge_file_name_vpath = NULL;
|
vfs_path_t *merge_file_name_vpath = NULL;
|
||||||
|
|
||||||
if (!dview->merged)
|
if (!dview->merged[n_merge])
|
||||||
{
|
{
|
||||||
dview->merged = mc_util_make_backup_if_possible (dview->file[0], "~~~");
|
dview->merged[n_merge] = mc_util_make_backup_if_possible (dview->file[n_merge], "~~~");
|
||||||
if (!dview->merged)
|
if (!dview->merged[n_merge])
|
||||||
{
|
{
|
||||||
message (D_ERROR, MSG_ERROR,
|
message (D_ERROR, MSG_ERROR,
|
||||||
_("Cannot create backup file\n%s%s\n%s"),
|
_("Cannot create backup file\n%s%s\n%s"),
|
||||||
dview->file[0], "~~~", unix_error_string (errno));
|
dview->file[n_merge], "~~~", unix_error_string (errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2184,18 +2216,24 @@ do_merge_hunk (WDiff * dview)
|
|||||||
switch (hunk)
|
switch (hunk)
|
||||||
{
|
{
|
||||||
case DIFF_DEL:
|
case DIFF_DEL:
|
||||||
dview_remove_hunk (dview, merge_file, from1, to1);
|
if (merge_direction)
|
||||||
|
dview_add_hunk (dview, merge_file, from1, from2, to2, TRUE);
|
||||||
|
else
|
||||||
|
dview_remove_hunk (dview, merge_file, from1, to1, FALSE);
|
||||||
break;
|
break;
|
||||||
case DIFF_ADD:
|
case DIFF_ADD:
|
||||||
dview_add_hunk (dview, merge_file, from1, from2, to2);
|
if (merge_direction)
|
||||||
|
dview_remove_hunk (dview, merge_file, from1, to1, TRUE);
|
||||||
|
else
|
||||||
|
dview_add_hunk (dview, merge_file, from1, from2, to2, FALSE);
|
||||||
break;
|
break;
|
||||||
case DIFF_CHG:
|
case DIFF_CHG:
|
||||||
dview_replace_hunk (dview, merge_file, from1, to1, from2, to2);
|
dview_replace_hunk (dview, merge_file, from1, to1, from2, to2, merge_direction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fflush (merge_file);
|
fflush (merge_file);
|
||||||
fclose (merge_file);
|
fclose (merge_file);
|
||||||
res = rewrite_backup_content (merge_file_name_vpath, dview->file[0]);
|
res = rewrite_backup_content (merge_file_name_vpath, dview->file[n_merge]);
|
||||||
mc_unlink (merge_file_name_vpath);
|
mc_unlink (merge_file_name_vpath);
|
||||||
vfs_path_free (merge_file_name_vpath);
|
vfs_path_free (merge_file_name_vpath);
|
||||||
}
|
}
|
||||||
@ -2388,6 +2426,8 @@ dview_init (WDiff * dview, const char *args, const char *file1, const char *file
|
|||||||
dview->label[1] = g_strdup (label2);
|
dview->label[1] = g_strdup (label2);
|
||||||
dview->f[0] = f[0];
|
dview->f[0] = f[0];
|
||||||
dview->f[1] = f[1];
|
dview->f[1] = f[1];
|
||||||
|
dview->merged[0] = FALSE;
|
||||||
|
dview->merged[1] = FALSE;
|
||||||
dview->hdiff = NULL;
|
dview->hdiff = NULL;
|
||||||
dview->dsrc = dsrc;
|
dview->dsrc = dsrc;
|
||||||
dview->converter = str_cnv_from_term;
|
dview->converter = str_cnv_from_term;
|
||||||
@ -2722,7 +2762,7 @@ dview_status (const WDiff * dview, int ord, int width, int c)
|
|||||||
tty_gotoyx (0, c);
|
tty_gotoyx (0, c);
|
||||||
get_line_numbers (dview->a[ord], dview->skip_rows, &linenum, &lineofs);
|
get_line_numbers (dview->a[ord], dview->skip_rows, &linenum, &lineofs);
|
||||||
|
|
||||||
filename_width = width - 22;
|
filename_width = width - 24;
|
||||||
if (filename_width < 8)
|
if (filename_width < 8)
|
||||||
filename_width = 8;
|
filename_width = 8;
|
||||||
|
|
||||||
@ -2731,10 +2771,11 @@ dview_status (const WDiff * dview, int ord, int width, int c)
|
|||||||
vfs_path_free (vpath);
|
vfs_path_free (vpath);
|
||||||
buf = str_term_trim (path, filename_width);
|
buf = str_term_trim (path, filename_width);
|
||||||
if (ord == 0)
|
if (ord == 0)
|
||||||
tty_printf ("%-*s %6d+%-4d Col %-4d ", filename_width, buf, linenum, lineofs,
|
tty_printf ("%s%-*s %6d+%-4d Col %-4d ", dview->merged[ord] ? "* " : " ", filename_width,
|
||||||
dview->skip_cols);
|
buf, linenum, lineofs, dview->skip_cols);
|
||||||
else
|
else
|
||||||
tty_printf ("%-*s %6d+%-4d Dif %-4d ", filename_width, buf, linenum, lineofs, dview->ndiff);
|
tty_printf ("%s%-*s %6d+%-4d Dif %-4d ", dview->merged[ord] ? "* " : " ", filename_width,
|
||||||
|
buf, linenum, lineofs, dview->ndiff);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2875,10 +2916,16 @@ static gboolean
|
|||||||
dview_save (WDiff * dview)
|
dview_save (WDiff * dview)
|
||||||
{
|
{
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
if (!dview->merged)
|
if (dview->merged[0])
|
||||||
return res;
|
{
|
||||||
res = mc_util_unlink_backup_if_possible (dview->file[0], "~~~");
|
res = mc_util_unlink_backup_if_possible (dview->file[0], "~~~");
|
||||||
dview->merged = !res;
|
dview->merged[0] = !res;
|
||||||
|
}
|
||||||
|
if (dview->merged[1])
|
||||||
|
{
|
||||||
|
res = mc_util_unlink_backup_if_possible (dview->file[1], "~~~");
|
||||||
|
dview->merged[1] = !res;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2954,12 +3001,12 @@ dview_ok_to_exit (WDiff * dview)
|
|||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
int act;
|
int act;
|
||||||
|
|
||||||
if (!dview->merged)
|
if (!dview->merged[0] && !dview->merged[1])
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
act = query_dialog (_("Quit"), !mc_global.midnight_shutdown ?
|
act = query_dialog (_("Quit"), !mc_global.midnight_shutdown ?
|
||||||
_("File was modified. Save with exit?") :
|
_("File(s) was modified. Save with exit?") :
|
||||||
_("Midnight Commander is being shut down.\nSave modified file?"),
|
_("Midnight Commander is being shut down.\nSave modified file(s)?"),
|
||||||
D_NORMAL, 2, _("&Yes"), _("&No"));
|
D_NORMAL, 2, _("&Yes"), _("&No"));
|
||||||
|
|
||||||
/* Esc is No */
|
/* Esc is No */
|
||||||
@ -2978,6 +3025,8 @@ dview_ok_to_exit (WDiff * dview)
|
|||||||
case 1: /* No */
|
case 1: /* No */
|
||||||
if (mc_util_restore_from_backup_if_possible (dview->file[0], "~~~"))
|
if (mc_util_restore_from_backup_if_possible (dview->file[0], "~~~"))
|
||||||
res = mc_util_unlink_backup_if_possible (dview->file[0], "~~~");
|
res = mc_util_unlink_backup_if_possible (dview->file[0], "~~~");
|
||||||
|
if (mc_util_restore_from_backup_if_possible (dview->file[1], "~~~"))
|
||||||
|
res = mc_util_unlink_backup_if_possible (dview->file[1], "~~~");
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
@ -3061,7 +3110,11 @@ dview_execute_cmd (WDiff * dview, unsigned long command)
|
|||||||
dview_edit (dview, dview->ord);
|
dview_edit (dview, dview->ord);
|
||||||
break;
|
break;
|
||||||
case CK_Merge:
|
case CK_Merge:
|
||||||
do_merge_hunk (dview);
|
do_merge_hunk (dview, FALSE);
|
||||||
|
dview_redo (dview);
|
||||||
|
break;
|
||||||
|
case CK_MergeOther:
|
||||||
|
do_merge_hunk (dview, TRUE);
|
||||||
dview_redo (dview);
|
dview_redo (dview);
|
||||||
break;
|
break;
|
||||||
case CK_EditOther:
|
case CK_EditOther:
|
||||||
@ -3275,7 +3328,8 @@ static char *
|
|||||||
dview_get_title (const Dlg_head * h, size_t len)
|
dview_get_title (const Dlg_head * h, size_t len)
|
||||||
{
|
{
|
||||||
const WDiff *dview = (const WDiff *) find_widget_type (h, dview_callback);
|
const WDiff *dview = (const WDiff *) find_widget_type (h, dview_callback);
|
||||||
const char *modified = dview->merged ? " (*) " : " ";
|
const char *modified = " (*) ";
|
||||||
|
const char *notmodified = " ";
|
||||||
size_t len1;
|
size_t len1;
|
||||||
GString *title;
|
GString *title;
|
||||||
|
|
||||||
@ -3283,9 +3337,10 @@ dview_get_title (const Dlg_head * h, size_t len)
|
|||||||
|
|
||||||
title = g_string_sized_new (len);
|
title = g_string_sized_new (len);
|
||||||
g_string_append (title, _("Diff:"));
|
g_string_append (title, _("Diff:"));
|
||||||
g_string_append (title, modified);
|
g_string_append (title, dview->merged[0] ? modified : notmodified);
|
||||||
g_string_append (title, str_term_trim (dview->label[0], len1));
|
g_string_append (title, str_term_trim (dview->label[0], len1));
|
||||||
g_string_append (title, " | ");
|
g_string_append (title, " | ");
|
||||||
|
g_string_append (title, dview->merged[1] ? modified : notmodified);
|
||||||
g_string_append (title, str_term_trim (dview->label[1], len1));
|
g_string_append (title, str_term_trim (dview->label[1], len1));
|
||||||
|
|
||||||
return g_string_free (title, FALSE);
|
return g_string_free (title, FALSE);
|
||||||
|
@ -525,6 +525,7 @@ static const global_keymap_ini_t default_diff_keymap[] = {
|
|||||||
{"Edit", "f4"},
|
{"Edit", "f4"},
|
||||||
{"EditOther", "f14"},
|
{"EditOther", "f14"},
|
||||||
{"Merge", "f5"},
|
{"Merge", "f5"},
|
||||||
|
{"MergeOther", "f15"},
|
||||||
{"Search", "f7"},
|
{"Search", "f7"},
|
||||||
{"SearchContinue", "f17"},
|
{"SearchContinue", "f17"},
|
||||||
{"Options", "f9"},
|
{"Options", "f9"},
|
||||||
|
Loading…
Reference in New Issue
Block a user