[Geany] GITdiff plugin, need help
Yura Siamashka
yurand2 at xxxxx
Sat Nov 3 01:51:36 UTC 2007
Hi
Inspired by Enrico plugin wishlist and svn diff plugin, I decided to write
git (http://git.or.cz/) diff plugin.
Plugin should works the following way:
On button click (Any idea is it possible to make shortcut to plugin?):
1) If no diff output tab create *GIT-DIFF* tab and place diff there
2) If *GIT-DIFF* already exists, update it's content to latest diff and give focus to it
Well it almost works, exept few things:
1) if I click GITdiff button 2 times and try to close *GIT-DIFF* geany will crash. If I comment
geany_data->sci->set_text line it won't crash, Any idea what I am doing wrong?
2) How can I make tab active after I click GITdiff button? One of idea was always close
previous *GIT-DIFF* and open new document. But if I try to use documents->remove with index
It close tab with my program I want do make diff to instead of *GIT-DIFF*
Best regards,
Yura Semashko
-------------- next part --------------
Index: plugins/Makefile.am
===================================================================
--- plugins/Makefile.am (revision 2011)
+++ plugins/Makefile.am (working copy)
@@ -11,6 +11,7 @@
htmlchars_la_LDFLAGS = -module -avoid-version
export_la_LDFLAGS = -module -avoid-version
svndiff_la_LDFLAGS = -module -avoid-version
+gitdiff_la_LDFLAGS = -module -avoid-version
filebrowser_la_LDFLAGS = -module -avoid-version
if PLUGINS
@@ -21,6 +22,7 @@
htmlchars.la \
export.la \
svndiff.la \
+ gitdiff.la \
filebrowser.la
# Plugins not to be installed
@@ -32,6 +34,7 @@
htmlchars_la_SOURCES = htmlchars.c
export_la_SOURCES = export.c
svndiff_la_SOURCES = svndiff.c
+gitdiff_la_SOURCES = gitdiff.c
filebrowser_la_SOURCES = filebrowser.c
demoplugin_la_LIBADD = $(GTK_LIBS)
@@ -39,6 +42,7 @@
htmlchars_la_LIBADD = $(GTK_LIBS)
export_la_LIBADD = $(GTK_LIBS)
svndiff_la_LIBADD = $(GTK_LIBS)
+gitdiff_la_LIBADD = $(GTK_LIBS)
filebrowser_la_LIBADD = $(GTK_LIBS)
endif # PLUGINS
Index: plugins/gitdiff.c
===================================================================
--- plugins/gitdiff.c (revision 0)
+++ plugins/gitdiff.c (revision 0)
@@ -0,0 +1,178 @@
+/*
+ * svndiff.c - this file is part of Geany, a fast and lightweight IDE
+ *
+ * Copyright 2007 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
+ * Copyright 2007 Enrico Tr?ger <enrico.troeger at uvena.de>
+ * Copyright 2007 Nick Treleaven <nick.treleaven at btinternet.com>
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+/* GITdiff plugin */
+/* This small plugin uses git to generate a diff against the current
+ * version inside git tree.*/
+
+#include "geany.h"
+#include "support.h"
+#include "plugindata.h"
+#include "document.h"
+#include "filetypes.h"
+#include "utils.h"
+#include "project.h"
+#include "pluginmacros.h"
+
+PluginFields *plugin_fields;
+GeanyData *geany_data;
+
+VERSION_CHECK(25)
+
+PLUGIN_INFO(_("gitdiff"), _("Plugin to create a patch of a file against git"), VERSION)
+
+
+static int find_by_filename(const gchar* filename)
+{
+ gint i;
+ for (i = 0; i < doc_array->len; i++)
+ {
+ if ( DOC_IDX_VALID(i) && strcmp(doc_list[i].file_name, filename) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/* name_prefix should be in UTF-8, and can have a path. */
+static void show_output(const gchar *std_output, const gchar *force_encoding)
+{
+ gchar *text, *detect_enc = NULL;
+ gint idx;
+ gchar *filename = "*GIT-DIFF*";
+
+ // need to convert input text from the encoding of the original file into
+ // UTF-8 because internally Geany always needs UTF-8
+ if (force_encoding)
+ {
+ text = geany_data->encoding->convert_to_utf8_from_charset(
+ std_output, -1, force_encoding, TRUE);
+ }
+ else
+ {
+ text = geany_data->encoding->convert_to_utf8(std_output, -1, &detect_enc);
+ }
+ if (text)
+ {
+ idx = find_by_filename(filename);
+ if ( idx == -1)
+ {
+ idx = geany_data->document->new_file(filename,
+ geany_data->filetypes[GEANY_FILETYPES_DIFF], text);
+ }
+ else
+ {
+ geany_data->sci->set_text(doc_list[idx].sci, text);
+ }
+
+ geany_data->document->set_encoding(idx,
+ force_encoding ? force_encoding : detect_enc);
+ }
+ else
+ {
+ ui->set_statusbar(FALSE, _("Could not parse the output of git diff"));
+ }
+ g_free(text);
+ g_free(detect_enc);
+}
+
+
+static gchar *make_diff()
+{
+ gchar *std_output = NULL;
+ gchar *std_error = NULL;
+ gint exit_code;
+ gchar *command, *text = NULL;
+ gchar *argv[] = {"git", "diff", NULL};
+ gchar *env[] = {"PAGER=cat", NULL};
+
+ if (g_spawn_sync(NULL, argv, env, G_SPAWN_SEARCH_PATH, NULL, NULL, &std_output, &std_error, &exit_code, NULL))
+ {
+ if (! exit_code)
+ {
+ if (NZV(std_output))
+ {
+ text = std_output;
+ }
+ else
+ {
+ ui->set_statusbar(FALSE, _("No changes were made."));
+ }
+ }
+ else
+ { // GIT returns some error
+ dialogs->show_msgbox(1,
+ _("GIT exited with an error: \n%s."), g_strstrip(std_error));
+ }
+ }
+ else
+ {
+ ui->set_statusbar(FALSE,
+ _("Something went really wrong. Is there any git-binary in your path?"));
+ }
+ g_free(std_error);
+ return text;
+}
+
+/* Callback if menu item for a single file was activated */
+static void gitdiff_activated(GtkMenuItem *menuitem, gpointer gdata)
+{
+ gint idx;
+ gchar *text;
+
+ idx = documents->get_cur_idx();
+
+ g_return_if_fail(DOC_IDX_VALID(idx) && doc_list[idx].file_name != NULL);
+
+ if (doc_list[idx].changed)
+ {
+ documents->save_file(idx, FALSE);
+ }
+
+ text = make_diff();
+ if (text)
+ show_output(text, doc_list[idx].encoding);
+ g_free(text);
+}
+
+/* Called by Geany to initialize the plugin */
+void init(GeanyData *data)
+{
+ GtkWidget *gitdiff_item;
+
+ // Add an item to the Tools menu
+ gitdiff_item = gtk_menu_item_new_with_mnemonic(_("_GITdiff"));
+ gtk_widget_show(gitdiff_item);
+ gtk_container_add(GTK_CONTAINER(geany_data->tools_menu), gitdiff_item);
+ g_signal_connect(G_OBJECT(gitdiff_item), "activate", G_CALLBACK(gitdiff_activated), NULL);
+
+ // keep a pointer to the menu item, so we can remove it when the plugin is unloaded
+ plugin_fields->menu_item = gitdiff_item;
+
+}
+
+
+/* Called by Geany before unloading the plugin. */
+void cleanup()
+{
+ // remove the menu item added in init()
+ gtk_widget_destroy(plugin_fields->menu_item);
+}
More information about the Users
mailing list