Branch: refs/heads/master Author: Enrico Tröger enrico.troeger@uvena.de Committer: Enrico Tröger enrico.troeger@uvena.de Date: Thu, 28 Mar 2019 09:55:20 UTC Commit: 1b87179e2b785b8ae2edf9b2ecdafc4696a9e82f https://github.com/geany/geany-plugins/commit/1b87179e2b785b8ae2edf9b2ecdafc...
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).
plugins-commits@lists.geany.org