From 4044529191ffc5f84a0a6e632f774517c1b81726 Mon Sep 17 00:00:00 2001 From: Stephen Collins Date: Sun, 5 May 2019 03:27:11 -0600 Subject: [PATCH] Add toggle comment and toggle comment block actions w/ keybindings (#290) --- xed/resources/css/xed-style.css | 11 +++ xed/resources/ui/xed-shortcuts.ui | 14 +++ xed/resources/ui/xed-ui.xml | 3 + xed/xed-commands-edit.c | 153 ++++++++++++++++++++++++++++++ xed/xed-commands.h | 2 + xed/xed-ui.h | 4 + 6 files changed, 187 insertions(+) diff --git a/xed/resources/css/xed-style.css b/xed/resources/css/xed-style.css index 1807e87..4cfd084 100644 --- a/xed/resources/css/xed-style.css +++ b/xed/resources/css/xed-style.css @@ -11,3 +11,14 @@ min-height: 0; min-width: 0; } + +/*remove a keybinding so that we can use it for toggling comments*/ +@binding-set xed-view-bindings +{ + unbind "slash"; +} + +textview +{ + -gtk-key-bindings: xed-view-bindings; +} diff --git a/xed/resources/ui/xed-shortcuts.ui b/xed/resources/ui/xed-shortcuts.ui index ad6ae4d..8ca7b60 100644 --- a/xed/resources/ui/xed-shortcuts.ui +++ b/xed/resources/ui/xed-shortcuts.ui @@ -327,6 +327,20 @@ Decrement number at cursor + + + 1 + <ctrl><shift>slash + Toggle comment block + + + + + 1 + <ctrl>slash + Toggle comment + + diff --git a/xed/resources/ui/xed-ui.xml b/xed/resources/ui/xed-ui.xml index e9f9dfd..4285d41 100644 --- a/xed/resources/ui/xed-ui.xml +++ b/xed/resources/ui/xed-ui.xml @@ -38,6 +38,9 @@ + + + diff --git a/xed/xed-commands-edit.c b/xed/xed-commands-edit.c index e6010d7..2e67337 100644 --- a/xed/xed-commands-edit.c +++ b/xed/xed-commands-edit.c @@ -169,3 +169,156 @@ _xed_cmd_edit_preferences (GtkAction *action, xed_show_preferences_dialog (window); } + +void +_xed_cmd_edit_toggle_comment (GtkAction *action, + XedWindow *window) +{ + XedView *active_view; + GtkSourceBuffer *active_document; + GtkSourceLanguage *language; + const gchar *comment_text; + gint start_line; + gint end_line; + gint i; + gboolean is_comment = FALSE; + GtkTextIter start_iter; + GtkTextIter end_iter; + + xed_debug (DEBUG_COMMANDS); + + active_view = xed_window_get_active_view (window); + + if (active_view == NULL) + { + return; + } + + active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); + language = gtk_source_buffer_get_language (active_document); + + if (language == NULL) + { + return; + } + + comment_text = gtk_source_language_get_metadata (language, "line-comment-start"); + + if (comment_text == NULL) + { + return; + } + + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter); + start_line = gtk_text_iter_get_line (&start_iter); + end_line = gtk_text_iter_get_line (&end_iter); + + gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (active_document)); // begin + + // if some lines are already commented, consider the whole block commented and uncomment them + for (i = start_line; i <= end_line; i++) + { + GtkTextIter start_line_iter; + GtkTextIter end_line_iter; + const gchar *line_text; + + gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (active_document), &start_line_iter, i); + end_line_iter = start_line_iter; + gtk_text_iter_forward_to_line_end (&end_line_iter); + + line_text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (active_document), &start_line_iter, &end_line_iter, TRUE); + if (g_str_has_prefix (line_text, comment_text)) + { + is_comment = TRUE; + end_line_iter = start_line_iter; + gtk_text_iter_forward_chars (&end_line_iter, strlen(comment_text)); + gtk_text_buffer_delete (GTK_TEXT_BUFFER (active_document), &start_line_iter, &end_line_iter); + } + } + + // only comment if nothing was commented to begin with + if (!is_comment) + { + for (i = start_line; i <= end_line; i++) + { + GtkTextIter insert_iter; + + gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (active_document), &insert_iter, i); + gtk_text_buffer_insert (GTK_TEXT_BUFFER (active_document), &insert_iter, comment_text, -1); + } + } + + gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (active_document)); // end +} + +void +_xed_cmd_edit_toggle_comment_block (GtkAction *action, + XedWindow *window) +{ + XedView *active_view; + GtkSourceBuffer *active_document; + GtkSourceLanguage *language; + const gchar *start_text; + const gchar *end_text; + GtkTextIter start_iter; + GtkTextIter end_iter; + gchar *selected_text; + gchar *insert_text; + + xed_debug (DEBUG_COMMANDS); + + active_view = xed_window_get_active_view (window); + + if (active_view == NULL) + { + return; + } + + active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); + language = gtk_source_buffer_get_language (active_document); + + if (language == NULL) + { + return; + } + + start_text = gtk_source_language_get_metadata (language, "block-comment-start"); + end_text = gtk_source_language_get_metadata (language, "block-comment-end"); + + if (start_text == NULL || end_text == NULL) + { + return; + } + + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter); + + selected_text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter, TRUE); + + if (g_str_has_prefix (selected_text, start_text) && g_str_has_suffix (selected_text, end_text)) + { + gint start = strlen (start_text); + gint end = strlen (end_text); + const gchar *tmp = selected_text + start; + insert_text = g_strndup (tmp , strlen(selected_text) - start - end); + } + else + { + insert_text = g_strconcat (start_text, selected_text, end_text, NULL); + } + + gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (active_document)); // begin + + // replace the selected text with the commented/uncommented version + gtk_text_buffer_delete (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter); + gtk_text_buffer_insert (GTK_TEXT_BUFFER (active_document), &end_iter, insert_text, -1); + + // move selection back where it was + gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (active_document), &start_iter, + gtk_text_iter_get_offset (&end_iter) - strlen (insert_text)); + gtk_text_buffer_select_range (GTK_TEXT_BUFFER (active_document), &start_iter, &end_iter); + + gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (active_document)); // end + + g_free (selected_text); + g_free (insert_text); +} diff --git a/xed/xed-commands.h b/xed/xed-commands.h index eb6c451..0ac942e 100644 --- a/xed/xed-commands.h +++ b/xed/xed-commands.h @@ -42,6 +42,8 @@ void _xed_cmd_edit_paste (GtkAction *action, XedWindow *window); void _xed_cmd_edit_delete (GtkAction *action, XedWindow *window); void _xed_cmd_edit_select_all (GtkAction *action, XedWindow *window); void _xed_cmd_edit_preferences (GtkAction *action, XedWindow *window); +void _xed_cmd_edit_toggle_comment (GtkAction *action, XedWindow *window); +void _xed_cmd_edit_toggle_comment_block (GtkAction *action, XedWindow *window); void _xed_cmd_view_show_toolbar (GtkAction *action, XedWindow *window); void _xed_cmd_view_show_statusbar (GtkAction *action, XedWindow *window); diff --git a/xed/xed-ui.h b/xed/xed-ui.h index 20ec7e8..550463e 100644 --- a/xed/xed-ui.h +++ b/xed/xed-ui.h @@ -102,6 +102,10 @@ static const GtkActionEntry xed_menu_entries[] = N_("Delete the selected text"), G_CALLBACK (_xed_cmd_edit_delete) }, { "EditSelectAll", "edit-select-all-symbolic", N_("Select _All"), "A", N_("Select the entire document"), G_CALLBACK (_xed_cmd_edit_select_all) }, + { "EditToggleComment", NULL, N_("_Toggle Comment"), "slash", + N_("Comment"), G_CALLBACK (_xed_cmd_edit_toggle_comment) }, + { "EditToggleCommentBlock", NULL, N_("Toggle Comment _Block"), "question", + N_("Comment Block"), G_CALLBACK (_xed_cmd_edit_toggle_comment_block) }, /* View menu */ { "ViewHighlightMode", NULL, N_("_Highlight Mode"), "H",