[gnome-builder] highlighter: Added xml highlighter used for highlighting matching tags
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] highlighter: Added xml highlighter used for highlighting matching tags
- Date: Mon, 11 May 2015 22:10:42 +0000 (UTC)
commit 96000f81f9f00add85f1fdd42269c7ac01a4beee
Author: Dimitris Zenios <dimitris zenios gmail com>
Date: Tue May 12 00:48:07 2015 +0300
highlighter: Added xml highlighter used for highlighting matching tags
https://bugzilla.gnome.org/show_bug.cgi?id=746990
data/style-schemes/builder.xml | 1 +
libide/Makefile.am | 2 +
libide/xml/ide-xml-highlighter.c | 241 ++++++++++++++++++++++++++++++++++++++
libide/xml/ide-xml-highlighter.h | 33 +++++
libide/xml/ide-xml-language.c | 29 ++++-
5 files changed, 303 insertions(+), 3 deletions(-)
---
diff --git a/data/style-schemes/builder.xml b/data/style-schemes/builder.xml
index c8bb140..08a9205 100644
--- a/data/style-schemes/builder.xml
+++ b/data/style-schemes/builder.xml
@@ -138,6 +138,7 @@
<style name="xml:tags" foreground="chameleon3"/>
<style name="xml:namespace" bold="true"/>
+ <style name="xml:tag-match" underline="true"/>
<style name="js:object" foreground="chameleon3" bold="true"/>
<style name="js:constructors" foreground="pink1"/>
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 74c0cc4..fcaf482 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -222,6 +222,8 @@ libide_1_0_la_public_sources = \
xml/ide-xml-indenter.h \
xml/ide-xml-language.c \
xml/ide-xml-language.h \
+ xml/ide-xml-highlighter.c \
+ xml/ide-xml-highlighter.h \
ide-source-map.c \
ide-source-map.h \
ide-thread-pool.c \
diff --git a/libide/xml/ide-xml-highlighter.c b/libide/xml/ide-xml-highlighter.c
new file mode 100644
index 0000000..3c523c7
--- /dev/null
+++ b/libide/xml/ide-xml-highlighter.c
@@ -0,0 +1,241 @@
+/* ide-xml-highlighter.c
+ *
+ * Copyright (C) 2015 Dimitris Zenios <dimitris zenios 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "ide-xml-highlighter.h"
+#include "ide-context.h"
+#include "ide-buffer.h"
+#include "ide-xml.h"
+#include "ide-highlight-engine.h"
+
+#define HIGHLIGH_TIMEOUT_MSEC 250
+#define XML_TAG_MATCH_STYLE_NAME "xml:tag-match"
+
+struct _IdeXmlHighlighter
+{
+ IdeHighlighter parent_instance;
+
+ gboolean has_tags;
+ guint highlight_timeout;
+ GtkTextIter iter;
+ IdeBuffer *buffer;
+};
+
+G_DEFINE_TYPE (IdeXmlHighlighter, ide_xml_highlighter, IDE_TYPE_HIGHLIGHTER)
+
+static gboolean
+ide_xml_highlighter_highlight_timeout_handler (gpointer data)
+{
+ IdeXmlHighlighter *self = data;
+ IdeHighlightEngine *engine;
+ GtkTextTag *tag;
+ GtkTextIter start;
+ GtkTextIter end;
+ GtkTextBuffer *buffer;
+
+ g_assert (IDE_IS_XML_HIGHLIGHTER (self));
+
+ engine = ide_highlighter_get_highlight_engine (IDE_HIGHLIGHTER (self));
+ tag = ide_highlight_engine_get_style (engine, XML_TAG_MATCH_STYLE_NAME);
+
+ buffer = GTK_TEXT_BUFFER (self->buffer);
+
+ /*
+ * Clear previous tags.We could save the previous
+ * iters and clear only those locations but for
+ * now this should be ok
+ */
+ if (self->has_tags)
+ {
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ gtk_text_buffer_remove_tag (buffer,tag,&start,&end);
+
+ self->has_tags = FALSE;
+ }
+
+
+ if (ide_xml_in_element (&self->iter) && ide_xml_get_current_element (&self->iter,
+ &start,
+ &end))
+ {
+ GtkTextIter next_start;
+ GtkTextIter next_end;
+ IdeXmlElementTagType tag_type = ide_xml_get_element_tag_type (&start,
+ &end);
+
+ if ((tag_type == IDE_XML_ELEMENT_TAG_START &&
+ ide_xml_find_closing_element (&start,&end,
+ &next_start,&next_end)) ||
+ (tag_type == IDE_XML_ELEMENT_TAG_END &&
+ ide_xml_find_opening_element (&start,&end,
+ &next_start,&next_end)) ||
+ tag_type == IDE_XML_ELEMENT_TAG_START_END)
+ {
+
+ /*
+ * All iters point to the begining of < char and the
+ * beginning of > char.In our case we want to highlight everything that is
+ * between those two chars.This is the reason we move one char forward
+ * from the start iter
+ */
+ gtk_text_iter_forward_char (&start);
+ gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer),
+ tag,
+ &start,
+ &end);
+
+ if (tag_type != IDE_XML_ELEMENT_TAG_START_END)
+ {
+ gtk_text_iter_forward_char (&next_start);
+ gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer),
+ tag,
+ &next_start,
+ &next_end);
+ }
+
+ self->has_tags = TRUE;
+ }
+ }
+
+ self->highlight_timeout = 0;
+ return FALSE;
+}
+
+static void
+ide_xml_highlighter_cursor_moved_cb (GtkTextBuffer *buffer,
+ GtkTextIter *iter,
+ IdeXmlHighlighter *self)
+{
+ g_assert (IDE_IS_HIGHLIGHTER (self));
+
+ if (self->highlight_timeout != 0)
+ {
+ g_source_remove (self->highlight_timeout);
+ self->highlight_timeout = 0;
+ }
+
+ self->iter = *iter;
+ self->highlight_timeout = g_timeout_add (HIGHLIGH_TIMEOUT_MSEC,
+ ide_xml_highlighter_highlight_timeout_handler,
+ self);
+}
+
+
+static void
+ide_xml_highlighter_set_buffer (IdeXmlHighlighter *highlighter,
+ IdeBuffer *buffer)
+{
+ IdeXmlHighlighter *self = (IdeXmlHighlighter *)highlighter;
+
+ g_assert (IDE_IS_HIGHLIGHTER (self));
+ g_assert (IDE_IS_BUFFER (buffer));
+
+ if (self->buffer != buffer)
+ {
+ if (self->buffer != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (self->buffer,
+ G_CALLBACK (ide_xml_highlighter_cursor_moved_cb),
+ self);
+ ide_clear_weak_pointer (&self->buffer);
+ }
+
+ if (buffer != NULL)
+ {
+ g_signal_connect (buffer,
+ "cursor-moved",
+ G_CALLBACK (ide_xml_highlighter_cursor_moved_cb),
+ self);
+ ide_set_weak_pointer (&self->buffer, buffer);
+ }
+
+ }
+}
+
+static void
+ide_xml_highlighter_on_buffer_set (IdeHighlighter *self,
+ GParamSpec *pspec,
+ IdeBuffer *buffer)
+{
+ IdeXmlHighlighter *highlighter = IDE_XML_HIGHLIGHTER (self);
+
+ g_assert (IDE_IS_XML_HIGHLIGHTER (highlighter));
+
+ ide_xml_highlighter_set_buffer (highlighter, buffer);
+}
+
+static void
+ide_xml_highlighter_on_highlight_engine_set (IdeHighlighter *self,
+ GParamSpec *pspec,
+ gpointer *data)
+{
+ IdeXmlHighlighter *highlighter = IDE_XML_HIGHLIGHTER (self);
+ IdeHighlightEngine *engine = ide_highlighter_get_highlight_engine (self);
+
+ g_assert (IDE_IS_XML_HIGHLIGHTER (highlighter));
+ g_assert (engine != NULL);
+
+ ide_xml_highlighter_set_buffer (highlighter, ide_highlight_engine_get_buffer (engine));
+ g_signal_connect_object (engine,
+ "notify::buffer",
+ G_CALLBACK (ide_xml_highlighter_on_buffer_set),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+static void
+ide_xml_highlighter_constructed (GObject *object)
+{
+ IdeXmlHighlighter *self = (IdeXmlHighlighter *)object;
+
+ g_signal_connect (self,
+ "notify::highlight-engine",
+ G_CALLBACK (ide_xml_highlighter_on_highlight_engine_set),
+ NULL);
+}
+
+static void
+ide_xml_highlighter_engine_dispose (GObject *object)
+{
+ IdeXmlHighlighter *self = (IdeXmlHighlighter *)object;
+
+ if (self->highlight_timeout != 0)
+ {
+ g_source_remove (self->highlight_timeout);
+ self->highlight_timeout = 0;
+ }
+ ide_clear_weak_pointer (&self->buffer);
+
+ G_OBJECT_CLASS (ide_xml_highlighter_parent_class)->dispose (object);
+}
+
+static void
+ide_xml_highlighter_class_init (IdeXmlHighlighterClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = ide_xml_highlighter_engine_dispose;
+ object_class->constructed = ide_xml_highlighter_constructed;
+}
+
+static void
+ide_xml_highlighter_init (IdeXmlHighlighter *self)
+{
+}
diff --git a/libide/xml/ide-xml-highlighter.h b/libide/xml/ide-xml-highlighter.h
new file mode 100644
index 0000000..ce45c7f
--- /dev/null
+++ b/libide/xml/ide-xml-highlighter.h
@@ -0,0 +1,33 @@
+/* ide-xml-highlighter.h
+ *
+ * Copyright (C) 2015 Dimitris Zenios <dimitris zenios 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_XML_HIGHLIGHTER_H
+#define IDE_XML_HIGHLIGHTER_H
+
+#include "ide-highlighter.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_XML_HIGHLIGHTER (ide_xml_highlighter_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeXmlHighlighter, ide_xml_highlighter,
+ IDE, XML_HIGHLIGHTER, IdeHighlighter)
+
+G_END_DECLS
+
+#endif /* IDE_XML_HIGHLIGHTER_H */
diff --git a/libide/xml/ide-xml-language.c b/libide/xml/ide-xml-language.c
index 5c0173f..0695539 100644
--- a/libide/xml/ide-xml-language.c
+++ b/libide/xml/ide-xml-language.c
@@ -18,11 +18,14 @@
#include "ide-xml-language.h"
#include "ide-xml-indenter.h"
+#include "ide-xml-highlighter.h"
struct _IdeXmlLanguage
{
- IdeLanguage parent_instance;
- IdeXmlIndenter *indenter;
+ IdeLanguage parent_instance;
+
+ IdeXmlIndenter *indenter;
+ IdeXmlHighlighter *highlighter;
};
static void initable_iface_init (GInitableIface *iface);
@@ -51,6 +54,26 @@ ide_xml_language_get_indenter (IdeLanguage *language)
return IDE_INDENTER (self->indenter);
}
+static IdeHighlighter *
+ide_xml_language_get_highlighter (IdeLanguage *language)
+{
+ IdeXmlLanguage *self = (IdeXmlLanguage *)language;
+
+ g_return_val_if_fail (IDE_IS_XML_LANGUAGE (self), NULL);
+
+ if (!self->highlighter)
+ {
+ IdeContext *context;
+
+ context = ide_object_get_context (IDE_OBJECT (language));
+ self->highlighter = g_object_new (IDE_TYPE_XML_HIGHLIGHTER,
+ "context", context,
+ NULL);
+ }
+
+ return IDE_HIGHLIGHTER (self->highlighter);
+}
+
static void
ide_xml_language_finalize (GObject *object)
{
@@ -68,7 +91,7 @@ ide_xml_language_class_init (IdeXmlLanguageClass *klass)
IdeLanguageClass *language_class = IDE_LANGUAGE_CLASS (klass);
object_class->finalize = ide_xml_language_finalize;
-
+ language_class->get_highlighter = ide_xml_language_get_highlighter;
language_class->get_indenter = ide_xml_language_get_indenter;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]