Skip to content

Commit

Permalink
GeanyVC: Support the use of external diff-tool in directory context
Browse files Browse the repository at this point in the history
  • Loading branch information
nomadbyte committed Apr 25, 2022
1 parent 097644f commit a6e64a8
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 49 deletions.
149 changes: 100 additions & 49 deletions geanyvc/src/geanyvc.c
Expand Up @@ -201,6 +201,12 @@ free_commit_list(GSList * lst)
g_slist_free(lst);
}

int
commititem_compare_by_path(const CommitItem * a, const CommitItem * b)
{
return (g_strcmp0(a->path, b->path));
}

gchar *
find_subdir_path(const gchar * filename, const gchar * subdir)
{
Expand Down Expand Up @@ -597,14 +603,64 @@ get_command_exit_status(gint exit_code)
return (SPAWN_WIFEXITED(exit_code) ? SPAWN_WEXITSTATUS(exit_code) : exit_code);
}

static void
diff_external(const VC_RECORD * vc, const gchar * filename)
{
gchar *new, *old;
gchar *localename;

g_return_if_fail(vc);
g_return_if_fail(filename);
g_return_if_fail(get_external_diff_viewer());

/* 1) rename file to file.geany.~NEW~
2) revert file
3) rename file to file.geanyvc.~BASE~
4) rename file.geany.~NEW~ to origin file
5) show diff
*/
localename = utils_get_locale_from_utf8(filename);

new = g_strconcat(filename, ".geanyvc.~NEW~", NULL);
setptr(new, utils_get_locale_from_utf8(new));

old = g_strconcat(filename, ".geanyvc.~BASE~", NULL);
setptr(old, utils_get_locale_from_utf8(old));

if (g_rename(localename, new) != 0)
{
g_warning(_
("geanyvc: diff_external: Unable to rename '%s' to '%s'"),
localename, new);
goto end;
}

execute_command(vc, NULL, NULL, filename, VC_COMMAND_REVERT_FILE, NULL, NULL);

if (g_rename(localename, old) != 0)
{
g_warning(_
("geanyvc: diff_external: Unable to rename '%s' to '%s'"),
localename, old);
g_rename(new, localename);
goto end;
}
g_rename(new, localename);

vc_external_diff(old, localename);
g_unlink(old);
end:
g_free(old);
g_free(new);
g_free(localename);
}

/* Callback if menu item for a single file was activated */
static void
vcdiff_file_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpointer gdata)
{
gchar *text = NULL;
gchar *new, *old;
gchar *name;
gchar *localename;
const VC_RECORD *vc;
GeanyDocument *doc;

Expand All @@ -625,48 +681,7 @@ vcdiff_file_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpoint
if (set_external_diff && get_external_diff_viewer())
{
g_free(text);

/* 1) rename file to file.geany.~NEW~
2) revert file
3) rename file to file.geanyvc.~BASE~
4) rename file.geany.~NEW~ to origin file
5) show diff
*/
localename = utils_get_locale_from_utf8(doc->file_name);

new = g_strconcat(doc->file_name, ".geanyvc.~NEW~", NULL);
SETPTR(new, utils_get_locale_from_utf8(new));

old = g_strconcat(doc->file_name, ".geanyvc.~BASE~", NULL);
SETPTR(old, utils_get_locale_from_utf8(old));

if (g_rename(localename, new) != 0)
{
g_warning(_
("geanyvc: vcdiff_file_activated: Unable to rename '%s' to '%s'"),
localename, new);
goto end;
}

execute_command(vc, NULL, NULL, doc->file_name,
VC_COMMAND_REVERT_FILE, NULL, NULL);

if (g_rename(localename, old) != 0)
{
g_warning(_
("geanyvc: vcdiff_file_activated: Unable to rename '%s' to '%s'"),
localename, old);
g_rename(new, localename);
goto end;
}
g_rename(new, localename);

vc_external_diff(old, localename);
g_unlink(old);
end:
g_free(old);
g_free(new);
g_free(localename);
diff_external(vc, doc->file_name);
return;
}
else
Expand Down Expand Up @@ -722,11 +737,47 @@ vcdiff_dir_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, gpointer data)
execute_command(vc, &text, NULL, dir, VC_COMMAND_DIFF_DIR, NULL, NULL);
if (text)
{
gchar *name;
name = g_strconcat(dir, ".vc.diff", NULL);
show_output(text, name, doc->encoding, NULL, 0);
g_free(text);
g_free(name);
if (set_external_diff && get_external_diff_viewer())
{
GSList *lst;

g_free(text);
lst = vc->get_commit_files(dir);

if (lst)
{
GSList *list_item = NULL;
gchar *prev_path = NULL;

/* - sort the file-list by path; some files may appear with
multiple statuses (e.g. Modified and Added)
- diff each file only once
*/
g_slist_sort(lst,(GCompareFunc)commititem_compare_by_path);

foreach_slist(list_item, lst)
{
CommitItem *item = (CommitItem *)(list_item->data);

if (flags & FLAG_DIR && !g_str_has_prefix(item->path, dir)) continue;

if (g_strcmp0(item->path, prev_path))
{
diff_external(vc, item->path);
prev_path = item->path;
}
}
free_commit_list(lst);
}
}
else
{
gchar *name;
name = g_strconcat(dir, ".vc.diff", NULL);
show_output(text, name, doc->encoding, NULL, 0);
g_free(text);
g_free(name);
}
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions geanyvc/src/geanyvc.h
Expand Up @@ -130,6 +130,8 @@ typedef struct _CommitItem
#define REGISTER_VC(vc,enable) {extern VC_RECORD VC_##vc;if(enable){path = g_find_program_in_path(VC_##vc.program); \
if (path) { g_free(path); VC = g_slist_append(VC, &VC_##vc);} }}

int commititem_compare_by_path(const CommitItem * a, const CommitItem * b);

/* Blank functions and values */
GSList *get_commit_files_null(const gchar * dir);
extern const gchar *NO_ENV[];
Expand Down

0 comments on commit a6e64a8

Please sign in to comment.