[Geany] GITdiff plugin, need help

Yura Siamashka yurand2 at xxxxx
Sun Nov 4 02:43:41 UTC 2007


Hi

On Sat, Nov 03, 2007 at 06:55:35PM +0100, Enrico Tröger wrote:
> the code looks good (but I didn't test it, no git repo here).
Here is I belive last version of this patch. At least I don't need anything else
from it exept shortcut.

Changes:
1) it check if git is installed in system
2) run git diff in active file tab directory instead of working path.

If you find It is possible to include this in geany good, otherwise it will live here:
http://users.cosmostv.by/yurand/geanygitdiff/

you can always create git repositary with the following commands

$ mkdir testrep
$ cd testrep
$ git init-db
$ git config user.email "you at email.com"
$ git config user.name "Your Name"
$ echo foo > bar.txt
$ git add bar.txt
$ git commit -a -m "initial commit"

Best regards,
Yura Siamashka
-------------- 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,207 @@
+/*
+ *      gitdiff.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>
+ *      Copyright 2007 Yura Siamashka <yurand2 at gmail.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(27)
+
+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) && doc_list[i].file_name && 
+		     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, page;
+	GtkNotebook *book;
+	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);
+			book = GTK_NOTEBOOK(app->notebook);
+			page = gtk_notebook_page_num(book, GTK_WIDGET(doc_list[idx].sci));
+			gtk_notebook_set_current_page(book, page);
+			doc_list[idx].changed = FALSE;
+			documents->set_text_changed(idx);
+		}
+				
+		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(const gchar *dir)
+{
+	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(dir, 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;
+	gchar   *dir;
+
+	idx = documents->get_cur_idx();
+
+	if ( !(DOC_IDX_VALID(idx) && doc_list[idx].file_name != NULL &&
+			g_file_test(doc_list[idx].file_name, G_FILE_TEST_EXISTS)))
+		return;
+
+	if (doc_list[idx].changed)
+	{
+		documents->save_file(idx, FALSE);
+	}
+	dir = g_path_get_dirname(doc_list[idx].file_name);
+	
+	text = make_diff(dir);
+	if (text)
+		show_output(text, doc_list[idx].encoding);
+	g_free(text);
+	g_free(dir);
+}
+
+static gboolean have_git = FALSE;
+
+/* Called by Geany to initialize the plugin */
+void init(GeanyData *data)
+{
+	GtkWidget *gitdiff_item;
+	GtkTooltips	*tooltips = NULL;
+	gchar *tmp;
+	
+	tmp = g_find_program_in_path("git");
+	if (!tmp)
+		return;
+
+	have_git = TRUE;
+	g_free(tmp);	
+
+	tooltips = gtk_tooltips_new();
+
+	// 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);
+	
+	gtk_tooltips_set_tip (tooltips, gitdiff_item,
+		_("Make a diff from the repositary of the directory of the current active file"), 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()
+	if (have_git)
+		gtk_widget_destroy(plugin_fields->menu_item);
+}


More information about the Users mailing list