[geany/geany-plugins] 1b8717: GeanyVC: Add a commit message history

Enrico Tröger git-noreply at xxxxx
Thu Mar 28 09:55:20 UTC 2019


Branch:      refs/heads/master
Author:      Enrico Tröger <enrico.troeger at uvena.de>
Committer:   Enrico Tröger <enrico.troeger at uvena.de>
Date:        Thu, 28 Mar 2019 09:55:20 UTC
Commit:      1b87179e2b785b8ae2edf9b2ecdafc4696a9e82f
             https://github.com/geany/geany-plugins/commit/1b87179e2b785b8ae2edf9b2ecdafc4696a9e82f

Log Message:
-----------
GeanyVC: Add a commit message history

Remember the last 10 commit messages and offer a dropdown in the commit
dialog to choose one of the last commit messages.


Modified Paths:
--------------
    geanyvc/src/geanyvc.c

Modified: geanyvc/src/geanyvc.c
153 lines changed, 153 insertions(+), 0 deletions(-)
===================================================================
@@ -84,6 +84,7 @@ static gboolean set_editor_menu_entries;
 static gboolean set_menubar_entry;
 static gint commit_dialog_width = 0;
 static gint commit_dialog_height = 0;
+static GSList *commit_message_history = NULL;
 
 static gchar *config_file;
 
@@ -155,6 +156,15 @@ enum
 	COUNT_KB
 };
 
+enum
+{
+	COMMIT_MESSAGE_HISTORY_DISPLAY_TEXT = 0,
+	COMMIT_MESSAGE_HISTORY_FULL_TEXT,
+	COMMIT_MESSAGE_HISTORY_ACTIVE,
+	COMMIT_MESSAGE_HISTORY_NUM_COLUMNS
+};
+#define COMMIT_MESSAGE_HISTORY_LENGTH 10
+
 
 GSList *get_commit_files_null(G_GNUC_UNUSED const gchar * dir)
 {
@@ -1319,6 +1329,90 @@ static void commit_tree_selection_changed_cb(GtkTreeSelection *sel, GtkTextView
 	g_free(path);
 }
 
+static void commit_message_update_cb(GtkWidget *widget, gpointer user_data)
+{
+	GtkTreeIter iter;
+
+	if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
+	{
+		gchar *commit_message;
+		GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
+		gboolean active = FALSE;
+
+		gtk_tree_model_get(model, &iter,
+			COMMIT_MESSAGE_HISTORY_FULL_TEXT, &commit_message,
+			COMMIT_MESSAGE_HISTORY_ACTIVE, &active, -1);
+
+		if (active)
+		{
+			GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(user_data));
+			gtk_text_buffer_set_text(buffer, commit_message, -1);
+		}
+		g_free(commit_message);
+	}
+}
+
+static GtkWidget *
+create_commit_message_history_combobox(void)
+{
+	GtkWidget *combobox;
+	GtkCellRenderer *renderer;
+	GtkTreeIter iter;
+	GtkListStore *store;
+	GSList *list_item;
+	GString *display_message_string;
+	gchar *display_message;
+
+	combobox = gtk_combo_box_new();
+	renderer = gtk_cell_renderer_text_new();
+	store = gtk_list_store_new(
+		COMMIT_MESSAGE_HISTORY_NUM_COLUMNS,
+		G_TYPE_STRING,
+		G_TYPE_STRING,
+		G_TYPE_BOOLEAN);
+
+	foreach_slist(list_item, commit_message_history)
+	{
+		display_message_string = g_string_new(list_item->data);
+		/* replace line breaks */
+		utils_string_replace_all(display_message_string, "\n", " ");
+		/* shorten commit message */
+		if (display_message_string->len > 80)
+		{
+			g_string_truncate(display_message_string, 80);
+			g_string_append(display_message_string, "...");
+		}
+		display_message = g_string_free(display_message_string, FALSE);
+
+		/* by _prepend() we reverse the list order for display on purpose:
+		 * most recent item should be on top */
+		gtk_list_store_prepend(store, &iter);
+		gtk_list_store_set(store, &iter,
+			COMMIT_MESSAGE_HISTORY_DISPLAY_TEXT, display_message,
+			COMMIT_MESSAGE_HISTORY_FULL_TEXT, list_item->data,
+			COMMIT_MESSAGE_HISTORY_ACTIVE, TRUE, -1);
+
+		g_free(display_message);
+	}
+
+	gtk_list_store_prepend(store, &iter);
+	gtk_list_store_set(store, &iter,
+		COMMIT_MESSAGE_HISTORY_DISPLAY_TEXT, _("Choose a previous commit message"),
+		COMMIT_MESSAGE_HISTORY_FULL_TEXT, NULL,
+		COMMIT_MESSAGE_HISTORY_ACTIVE, FALSE, -1);
+
+	gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(store));
+	gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0);
+	g_object_unref(store);
+
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
+	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), renderer,
+		"text", COMMIT_MESSAGE_HISTORY_DISPLAY_TEXT,
+		"sensitive", COMMIT_MESSAGE_HISTORY_ACTIVE, NULL);
+
+	return combobox;
+}
+
 static gboolean commit_text_line_number_update_cb(GtkWidget *widget, GdkEvent *event,
 												  gpointer user_data)
 {
@@ -1363,6 +1457,7 @@ create_commitDialog(void)
 	GtkWidget *bottom_vbox;
 	GtkWidget *commit_text_vbox;
 	GtkWidget *lineColumnLabel;
+	GtkWidget *commitMessageHistoryComboBox;
 	GtkTreeSelection *sel;
 
 	gchar *rcstyle = g_strdup_printf("style \"geanyvc-diff-font\"\n"
@@ -1476,6 +1571,11 @@ create_commitDialog(void)
 	gtk_box_pack_end(GTK_BOX(commit_text_vbox), lineColumnLabel, FALSE, TRUE, 0);
 	gtk_widget_show(lineColumnLabel);
 
+	/* last commit message dropdown */
+	commitMessageHistoryComboBox = create_commit_message_history_combobox();
+	gtk_box_pack_end(GTK_BOX(commit_text_vbox), commitMessageHistoryComboBox, FALSE, TRUE, 0);
+	gtk_widget_show(commitMessageHistoryComboBox);
+
 	dialog_action_area1 = gtk_dialog_get_action_area(GTK_DIALOG(commitDialog));
 	gtk_widget_show(dialog_action_area1);
 	gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area1), GTK_BUTTONBOX_END);
@@ -1496,6 +1596,8 @@ create_commitDialog(void)
 		G_CALLBACK(commit_text_line_number_update_cb), lineColumnLabel);
 	g_signal_connect(textCommitMessage, "button-release-event",
 		G_CALLBACK(commit_text_line_number_update_cb), lineColumnLabel);
+	g_signal_connect(commitMessageHistoryComboBox, "changed",
+		G_CALLBACK(commit_message_update_cb), textCommitMessage);
 	/* initial setup */
 	commit_text_line_number_update_cb(textCommitMessage, NULL, lineColumnLabel);
 
@@ -1521,6 +1623,29 @@ create_commitDialog(void)
 	return commitDialog;
 }
 
+static void
+add_commit_message_to_history(const gchar *commit_message)
+{
+	GSList *list_item = NULL;
+	gchar *message = g_strdup(commit_message);
+
+	/* add commit message to the history */
+	commit_message_history = g_slist_append(commit_message_history, (gpointer)message);
+
+	/* House keeping: keep only a maximum of COMMIT_MESSAGE_HISTORY_LENGTH items and delete the rest
+	 * We remove the first element from the list as often as the list is too long.
+	 * While the loop is not the most efficient way, it should be ok since the list never has
+	 * much more than 10 items */
+	while (g_slist_length(commit_message_history) > COMMIT_MESSAGE_HISTORY_LENGTH)
+	{
+		list_item = commit_message_history; /* remember the element to delete */
+		commit_message_history = list_item->next; /* start the list with the next item */
+		/* delete the current item and its data */
+		list_item->next = NULL;
+		g_slist_free_full(list_item, g_free);
+	}
+}
+
 static void
 vccommit_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpointer gdata)
 {
@@ -1630,6 +1755,7 @@ vccommit_activated(G_GNUC_UNUSED GtkMenuItem * menuitem, G_GNUC_UNUSED gpointer
 		gtk_text_buffer_get_start_iter(mbuf, &begin);
 		gtk_text_buffer_get_end_iter(mbuf, &end);
 		message = gtk_text_buffer_get_text(mbuf, &begin, &end, FALSE);
+		add_commit_message_to_history(message);
 		gtk_tree_model_foreach(model, get_commit_files_foreach, &selected_files);
 		if (!EMPTY(message) && selected_files)
 		{
@@ -1795,6 +1921,8 @@ widgets;
 static void
 save_config(void)
 {
+	GSList *list_item = NULL;
+	gint list_item_count = 0;
 	GKeyFile *config = g_key_file_new();
 	gchar *config_dir = g_path_get_dirname(config_file);
 
@@ -1827,6 +1955,16 @@ save_config(void)
 			"commit_dialog_height", commit_dialog_height);
 	}
 
+	g_key_file_remove_group(config, "CommitMessageHistory", NULL); /* cleanup */
+	foreach_slist(list_item, commit_message_history)
+	{
+		gchar *key = g_strdup_printf("message_%d", list_item_count);
+		g_key_file_set_string(config, "CommitMessageHistory", key, list_item->data);
+		g_free(key);
+
+		list_item_count++;
+	}
+
 	if (!g_file_test(config_dir, G_FILE_TEST_IS_DIR)
 	    && utils_mkdir(config_dir, TRUE) != 0)
 	{
@@ -2009,6 +2147,8 @@ load_config(void)
 	GError *error = NULL;
 #endif
 
+	gchar **commit_message_history_keys, **ptr;
+	gchar *commit_message;
 	GKeyFile *config = g_key_file_new();
 
 	g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
@@ -2054,6 +2194,18 @@ load_config(void)
 	commit_dialog_height = utils_get_setting_integer(config, "CommitDialog",
 		"commit_dialog_height", 500);
 
+	commit_message_history_keys = g_key_file_get_keys(config,"CommitMessageHistory", NULL, NULL);
+	if (commit_message_history_keys != NULL)
+	{
+		foreach_strv(ptr, commit_message_history_keys)
+		{
+			commit_message = g_key_file_get_string(config, "CommitMessageHistory", *ptr, NULL);
+			/* do not free the newly allocated commit_message string as we need it later in the list,
+			 * will be finally freed when cleaning up the commit_message_history list */
+			commit_message_history = g_slist_append(commit_message_history, commit_message);
+		}
+		g_strfreev(commit_message_history_keys);
+	}
 	g_key_file_free(config);
 }
 
@@ -2408,5 +2560,6 @@ plugin_cleanup(void)
 	gtk_widget_destroy(menu_entry);
 	g_slist_free(VC);
 	VC = NULL;
+	g_slist_free_full(commit_message_history, g_free);
 	g_free(config_file);
 }



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Plugins-Commits mailing list