diff --git a/moo.kdevelop b/moo.kdevelop
index dcbe0ff4..9c952df1 100644
--- a/moo.kdevelop
+++ b/moo.kdevelop
@@ -24,7 +24,7 @@
.
false
-
+
C
@@ -39,7 +39,7 @@
./medit
executable
/
-
+
false
false
@@ -198,12 +198,12 @@
-
+
--g-fatal-warnings
-
-
-
-
+
+
+
+
true
false
true
@@ -268,16 +268,16 @@
-
+
A new empty GAP source file
-
+
A new empty C++ file.
-
+
A new empty header file for C/C++.
-
+
A new empty C file.
@@ -304,7 +304,7 @@
-
+
set
m_,_
theValue
diff --git a/moo/mooedit/mooedit.c b/moo/mooedit/mooedit.c
index 802bf6a9..e1a6b80b 100644
--- a/moo/mooedit/mooedit.c
+++ b/moo/mooedit/mooedit.c
@@ -1320,3 +1320,306 @@ moo_edit_get_bookmarks_in_range (MooEdit *edit,
return g_slist_reverse (range);
}
+
+
+/*****************************************************************************/
+/* Comment/uncomment
+ */
+
+/* TODO: all this stuff, it's pretty lame */
+
+static gboolean
+has_comments (MooEdit *edit,
+ gboolean *single_line,
+ gboolean *multi_line)
+{
+ MooLang *lang;
+
+ lang = moo_text_view_get_lang (MOO_TEXT_VIEW (edit));
+
+ *single_line = lang->line_comment != NULL;
+ *multi_line = lang->block_comment_start &&
+ lang->block_comment_end;
+
+ return *single_line || *multi_line;
+}
+
+
+static void
+line_comment (GtkTextBuffer *buffer,
+ const char *comment_string,
+ GtkTextIter *start,
+ GtkTextIter *end)
+{
+ int first, last, i;
+ GtkTextIter iter;
+ char *comment_and_space;
+
+ g_return_if_fail (comment_string && comment_string[0]);
+
+ first = gtk_text_iter_get_line (start);
+ last = gtk_text_iter_get_line (end);
+
+ if (!gtk_text_iter_equal (start, end) && gtk_text_iter_starts_line (end))
+ last -= 1;
+
+ comment_and_space = g_strdup_printf ("%s ", comment_string);
+
+ for (i = first; i <= last; ++i)
+ {
+ gtk_text_buffer_get_iter_at_line (buffer, &iter, i);
+
+ if (gtk_text_iter_ends_line (&iter))
+ gtk_text_buffer_insert (buffer, &iter, comment_string, -1);
+ else
+ gtk_text_buffer_insert (buffer, &iter, comment_and_space, -1);
+ }
+
+ g_free (comment_and_space);
+}
+
+
+static void
+line_uncomment (GtkTextBuffer *buffer,
+ const char *comment_string,
+ GtkTextIter *start,
+ GtkTextIter *end)
+{
+ int first, last, i;
+ guint chars;
+
+ g_return_if_fail (comment_string && comment_string[0]);
+
+ first = gtk_text_iter_get_line (start);
+ last = gtk_text_iter_get_line (end);
+
+ if (!gtk_text_iter_equal (start, end) && gtk_text_iter_starts_line (end))
+ last -= 1;
+
+ chars = g_utf8_strlen (comment_string, -1);
+
+ for (i = first; i <= last; ++i)
+ {
+ char *text;
+
+ gtk_text_buffer_get_iter_at_line (buffer, start, i);
+ *end = *start;
+ gtk_text_iter_forward_chars (end, chars);
+ text = gtk_text_iter_get_slice (start, end);
+
+ if (!strcmp (comment_string, text))
+ {
+ if (gtk_text_iter_get_char (end) == ' ')
+ gtk_text_iter_forward_char (end);
+ gtk_text_buffer_delete (buffer, start, end);
+ }
+
+ g_free (text);
+ }
+}
+
+
+static void
+iter_to_line_end (GtkTextIter *iter)
+{
+ if (!gtk_text_iter_ends_line (iter))
+ gtk_text_iter_forward_to_line_end (iter);
+}
+
+static void
+block_comment (GtkTextBuffer *buffer,
+ const char *comment_start,
+ const char *comment_end,
+ GtkTextIter *start,
+ GtkTextIter *end)
+{
+ GtkTextMark *end_mark;
+
+ g_return_if_fail (comment_start && comment_start[0]);
+ g_return_if_fail (comment_end && comment_end[0]);
+
+ if (gtk_text_iter_equal (start, end))
+ {
+ gtk_text_iter_set_line_offset (start, 0);
+ iter_to_line_end (end);
+ }
+ else
+ {
+ if (gtk_text_iter_starts_line (end))
+ {
+ gtk_text_iter_backward_line (end);
+ iter_to_line_end (end);
+ }
+ }
+
+ end_mark = gtk_text_buffer_create_mark (buffer, NULL, end, FALSE);
+ gtk_text_buffer_insert (buffer, start, comment_start, -1);
+ gtk_text_buffer_get_iter_at_mark (buffer, start, end_mark);
+ gtk_text_buffer_insert (buffer, start, comment_end, -1);
+ gtk_text_buffer_delete_mark (buffer, end_mark);
+}
+
+
+static void
+block_uncomment (GtkTextBuffer *buffer,
+ const char *comment_start,
+ const char *comment_end,
+ GtkTextIter *start,
+ GtkTextIter *end)
+{
+ GtkTextIter start1, start2, end1, end2;
+ GtkTextMark *mark1, *mark2;
+ GtkTextIter limit;
+ gboolean found;
+
+ g_return_if_fail (comment_start && comment_start[0]);
+ g_return_if_fail (comment_end && comment_end[0]);
+
+ if (!gtk_text_iter_equal (start, end) && gtk_text_iter_starts_line (end))
+ {
+ gtk_text_iter_backward_line (end);
+ iter_to_line_end (end);
+ }
+
+ limit = *end;
+ found = moo_text_search_forward (start, comment_start, 0,
+ &start1, &start2,
+ &limit);
+
+ if (!found)
+ {
+ gtk_text_iter_set_line_offset (&limit, 0);
+ found = gtk_text_iter_backward_search (start, comment_start, 0,
+ &start1, &start2,
+ &limit);
+ }
+
+ if (!found)
+ return;
+
+ limit = start2;
+ found = gtk_text_iter_backward_search (end, comment_end, 0,
+ &end1, &end2, &limit);
+
+ if (!found)
+ {
+ limit = *end;
+ iter_to_line_end (&limit);
+ found = moo_text_search_forward (end, comment_end, 0,
+ &end1, &end2, &limit);
+ }
+
+ if (!found)
+ return;
+
+ g_assert (gtk_text_iter_compare (&start2, &end1) < 0);
+
+ mark1 = gtk_text_buffer_create_mark (buffer, NULL, &end1, FALSE);
+ mark2 = gtk_text_buffer_create_mark (buffer, NULL, &end2, FALSE);
+ gtk_text_buffer_delete (buffer, &start1, &start2);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end1, mark1);
+ gtk_text_buffer_get_iter_at_mark (buffer, &end2, mark2);
+ gtk_text_buffer_delete (buffer, &end1, &end2);
+ gtk_text_buffer_delete_mark (buffer, mark1);
+ gtk_text_buffer_delete_mark (buffer, mark2);
+}
+
+
+static void
+begin_comment_action (MooEdit *edit)
+{
+ gtk_text_buffer_begin_user_action (get_buffer (edit));
+ moo_text_buffer_begin_interactive_action (get_moo_buffer (edit));
+}
+
+static void
+end_comment_action (MooEdit *edit)
+{
+ gtk_text_buffer_end_user_action (get_buffer (edit));
+ moo_text_buffer_end_interactive_action (get_moo_buffer (edit));
+}
+
+
+void
+moo_edit_comment (MooEdit *edit)
+{
+ MooLang *lang;
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+ gboolean has_selection, single_line, multi_line;
+ gboolean adjust_selection = FALSE, move_insert = FALSE;
+ int sel_start_line, sel_start_offset;
+
+ g_return_if_fail (MOO_IS_EDIT (edit));
+
+ lang = moo_text_view_get_lang (MOO_TEXT_VIEW (edit));
+
+ if (!has_comments (edit, &single_line, &multi_line))
+ return;
+
+ buffer = get_buffer (edit);
+ has_selection = gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+
+ begin_comment_action (edit);
+
+ if (has_selection)
+ {
+ GtkTextIter iter;
+ adjust_selection = TRUE;
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter,
+ gtk_text_buffer_get_insert (buffer));
+ move_insert = gtk_text_iter_equal (&iter, &start);
+ sel_start_line = gtk_text_iter_get_line (&start);
+ sel_start_offset = gtk_text_iter_get_line_offset (&start);
+ }
+
+ /* FIXME */
+ if (single_line)
+ line_comment (buffer, lang->line_comment, &start, &end);
+ else
+ block_comment (buffer, lang->block_comment_start,
+ lang->block_comment_end, &start, &end);
+
+
+ if (adjust_selection)
+ {
+ const char *mark = move_insert ? "insert" : "selection_bound";
+ gtk_text_buffer_get_iter_at_line_offset (buffer, &start,
+ sel_start_line,
+ sel_start_offset);
+ gtk_text_buffer_move_mark_by_name (buffer, mark, &start);
+ }
+
+ end_comment_action (edit);
+}
+
+
+void
+moo_edit_uncomment (MooEdit *edit)
+{
+ MooLang *lang;
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+ gboolean single_line, multi_line;
+
+ g_return_if_fail (MOO_IS_EDIT (edit));
+
+ lang = moo_text_view_get_lang (MOO_TEXT_VIEW (edit));
+
+ if (!has_comments (edit, &single_line, &multi_line))
+ return;
+
+ buffer = get_buffer (edit);
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+
+ begin_comment_action (edit);
+
+ /* FIXME */
+ if (single_line)
+ line_uncomment (buffer, lang->line_comment, &start, &end);
+ else
+ block_uncomment (buffer, lang->block_comment_start,
+ lang->block_comment_end, &start, &end);
+
+ end_comment_action (edit);
+}
diff --git a/moo/mooedit/mooedit.h b/moo/mooedit/mooedit.h
index 958e4595..918e3008 100644
--- a/moo/mooedit/mooedit.h
+++ b/moo/mooedit/mooedit.h
@@ -179,6 +179,9 @@ GSList *moo_edit_get_bookmarks_in_range(MooEdit *edit,
int first_line,
int last_line);
+void moo_edit_comment (MooEdit *edit);
+void moo_edit_uncomment (MooEdit *edit);
+
G_END_DECLS
diff --git a/moo/mooedit/mooeditwindow.c b/moo/mooedit/mooeditwindow.c
index fa8d1073..e7b097f4 100644
--- a/moo/mooedit/mooeditwindow.c
+++ b/moo/mooedit/mooeditwindow.c
@@ -561,6 +561,24 @@ static void moo_edit_window_class_init (MooEditWindowClass *klass)
"condition::sensitive", "has-open-document",
NULL);
+ moo_window_class_new_action (window_class, "Comment",
+ "name", "Comment",
+ "label", "Comment",
+ "tooltip", "Comment",
+ "closure-callback", moo_edit_comment,
+ "closure-proxy-func", moo_edit_window_get_active_doc,
+ "condition::sensitive", "has-open-document",
+ NULL);
+
+ moo_window_class_new_action (window_class, "Uncomment",
+ "name", "Uncomment",
+ "label", "Uncomment",
+ "tooltip", "Uncomment",
+ "closure-callback", moo_edit_uncomment,
+ "closure-proxy-func", moo_edit_window_get_active_doc,
+ "condition::sensitive", "has-open-document",
+ NULL);
+
moo_window_class_new_action_custom (window_class, LANG_ACTION_ID,
(MooWindowActionFunc) create_lang_action,
NULL, NULL);
diff --git a/moo/mooedit/moolang.c b/moo/mooedit/moolang.c
index 6db77461..d95ff017 100644
--- a/moo/mooedit/moolang.c
+++ b/moo/mooedit/moolang.c
@@ -354,6 +354,9 @@ _moo_lang_free (MooLang *lang)
g_free (lang->sample);
g_free (lang->brackets);
+ g_free (lang->line_comment);
+ g_free (lang->block_comment_start);
+ g_free (lang->block_comment_end);
g_slist_foreach (lang->mime_types, (GFunc) g_free, NULL);
g_slist_free (lang->mime_types);
diff --git a/moo/mooedit/moolang.h b/moo/mooedit/moolang.h
index a4330b7b..d5e868f7 100644
--- a/moo/mooedit/moolang.h
+++ b/moo/mooedit/moolang.h
@@ -56,9 +56,9 @@ struct _MooLang {
GSList *extensions; /* list of globs */
char *brackets;
- char *single_line_comment;
- char *multi_line_comment_start;
- char *multi_line_comment_end;
+ char *line_comment;
+ char *block_comment_start;
+ char *block_comment_end;
char *sample;
diff --git a/moo/mooedit/moolangmgr.c b/moo/mooedit/moolangmgr.c
index f6ca36dc..c5977016 100644
--- a/moo/mooedit/moolangmgr.c
+++ b/moo/mooedit/moolangmgr.c
@@ -636,8 +636,15 @@ moo_lang_finish_build (MooLang *lang,
moo_lang_parse_mime_types (lang, xml->mimetypes);
if (xml->extensions)
moo_lang_parse_extensions (lang, xml->extensions);
+
if (xml->general)
+ {
lang->brackets = g_strdup (xml->general->brackets);
+ lang->line_comment = g_strdup (xml->general->single_line_start);
+ lang->block_comment_start = g_strdup (xml->general->multi_line_start);
+ lang->block_comment_end = g_strdup (xml->general->multi_line_end);
+ }
+
lang->sample = g_strdup (xml->sample);
for (l = xml->syntax->contexts; l != NULL; l = l->next)
diff --git a/moo/moopython/mooedit-pygtk.defs b/moo/moopython/mooedit-pygtk.defs
index e18a8c4c..4296f72c 100644
--- a/moo/moopython/mooedit-pygtk.defs
+++ b/moo/moopython/mooedit-pygtk.defs
@@ -98,9 +98,9 @@
'("GSList*" "mime_types")
'("GSList*" "extensions")
'("char*" "brackets")
- '("char*" "single_line_comment")
- '("char*" "multi_line_comment_start")
- '("char*" "multi_line_comment_end")
+ '("char*" "line_comment")
+ '("char*" "block_comment_start")
+ '("char*" "block_comment_end")
'("char*" "sample")
)
)
diff --git a/tests/medit-ui.xml b/tests/medit-ui.xml
index 599dc28d..49772d2b 100644
--- a/tests/medit-ui.xml
+++ b/tests/medit-ui.xml
@@ -34,6 +34,9 @@
+
+
+
-