[gedit-code-assistance] Added XML backend. Only deals with parse errors at this point.



commit 1ebb92ad53185d61f87077438a13a189f27a9d81
Author: Jono <jono foodnotblogs com>
Date:   Thu Mar 22 15:19:54 2012 -0400

    Added XML backend. Only deals with parse errors at this point.

 backends/Makefile.am                   |    4 +
 backends/xml/Makefile.am               |    9 ++
 backends/xml/gcpbackendxml.plugin.in   |   13 +++
 backends/xml/gcpbackendxml/Makefile.am |   11 +++
 backends/xml/gcpbackendxml/__init__.py |   20 +++++
 backends/xml/gcpbackendxml/backend.py  |   52 +++++++++++
 backends/xml/gcpbackendxml/document.py |  147 ++++++++++++++++++++++++++++++++
 configure.ac                           |   16 ++++
 8 files changed, 272 insertions(+), 0 deletions(-)
---
diff --git a/backends/Makefile.am b/backends/Makefile.am
index fa3fba4..97d0bae 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -8,4 +8,8 @@ if PYTHON_ENABLED
 SUBDIRS += python
 endif
 
+if XML_ENABLED
+SUBDIRS += xml
+endif
+
 -include $(top_srcdir)/git.mk
diff --git a/backends/xml/Makefile.am b/backends/xml/Makefile.am
new file mode 100644
index 0000000..f970f4c
--- /dev/null
+++ b/backends/xml/Makefile.am
@@ -0,0 +1,9 @@
+SUBDIRS = gcpbackendxml
+
+plugindir = $(GCP_BACKENDS_LIBS_DIR)
+plugin_DATA = gcpbackendxml.plugin
+
+EXTRA_DIST = \
+	gcpbackendxml.plugin
+
+-include $(top_srcdir)/git.mk
diff --git a/backends/xml/gcpbackendxml.plugin.in b/backends/xml/gcpbackendxml.plugin.in
new file mode 100644
index 0000000..357e23c
--- /dev/null
+++ b/backends/xml/gcpbackendxml.plugin.in
@@ -0,0 +1,13 @@
+[Plugin]
+Module=gcpbackendxml
+Loader=python
+IAge=3
+Name=Code Assistance XML Backend
+Hidden=yes
+Builtin=yes
+Description=Code assistance backend for XML
+Authors=Jono Finger <jono foodnotblogs com>
+Copyright=Copyright  2012 Jono Finger
+Website=http://www.gedit.org
+Version= VERSION@
+X-Languages=xml
diff --git a/backends/xml/gcpbackendxml/Makefile.am b/backends/xml/gcpbackendxml/Makefile.am
new file mode 100644
index 0000000..d252eb5
--- /dev/null
+++ b/backends/xml/gcpbackendxml/Makefile.am
@@ -0,0 +1,11 @@
+plugindir = $(GCP_BACKENDS_LIBS_DIR)/gcpbackendxml
+
+plugin_XML = 	\
+	__init__.py	\
+	backend.py	\
+	document.py
+
+CLEANFILES = *.pyc
+DISTCLEANFILES = *.pyc
+
+-include $(top_srcdir)/git.mk
diff --git a/backends/xml/gcpbackendxml/__init__.py b/backends/xml/gcpbackendxml/__init__.py
new file mode 100644
index 0000000..ecd1bee
--- /dev/null
+++ b/backends/xml/gcpbackendxml/__init__.py
@@ -0,0 +1,20 @@
+# gcp python backend
+# Copyright (C) 2012  Jesse van den Kieboom <jessevdk gnome org>
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+from backend import Backend
+
+# ex:ts=8:et:
diff --git a/backends/xml/gcpbackendxml/backend.py b/backends/xml/gcpbackendxml/backend.py
new file mode 100644
index 0000000..e39edca
--- /dev/null
+++ b/backends/xml/gcpbackendxml/backend.py
@@ -0,0 +1,52 @@
+# gcp xml backend
+# Copyright (C) 2012  Jesse van den Kieboom <jessevdk gnome org>
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+from gi.repository import GObject, Gcp
+from document import Document
+
+class Backend(GObject.Object, Gcp.Backend):
+    size = GObject.property(type=int, flags = GObject.PARAM_READABLE)
+
+    def __init__(self):
+        GObject.Object.__init__(self)
+
+        self.documents = []
+
+    def do_get_property(self, spec):
+        if spec.name == 'size':
+            return len(self.documents)
+
+        GObject.Object.do_get_property(self, spec)
+
+    def do_register_document(self, doc):
+        d = Document(document=doc)
+        self.documents.append(d)
+
+        d.connect('changed', self.on_document_changed)
+        return d
+
+    def do_unregister_document(self, doc):
+        doc.disconnect_by_func(self.on_document_changed)
+        self.documents.remove(doc)
+
+    def do_get(self, idx):
+        return self.documents[idx]
+
+    def on_document_changed(self, doc):
+        doc.update()
+
+# ex:ts=4:et:
diff --git a/backends/xml/gcpbackendxml/document.py b/backends/xml/gcpbackendxml/document.py
new file mode 100644
index 0000000..0809362
--- /dev/null
+++ b/backends/xml/gcpbackendxml/document.py
@@ -0,0 +1,147 @@
+# gcp xml backend
+# Copyright (C) 2012  Jono Finger <jono foodnotblogs 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+from gi.repository import GObject, Gcp, GLib, Gio
+
+from lxml import etree
+import threading
+
+class ParseThread(threading.Thread):
+    def __init__(self, doc, finishCallBack):
+        threading.Thread.__init__(self)
+
+        self.source_file = None
+
+        doc = doc.props.document
+
+        if doc.get_location():
+            self.source_file = doc.get_location().get_path()
+
+        if not self.source_file:
+            self.source_file = '<unknown>'
+
+        bounds = doc.get_bounds()
+        self.source_contents = bounds[0].get_text(bounds[1])
+
+        self.clock = threading.Lock()
+        self.cancelled = False
+        self.finishCallBack = finishCallBack
+
+        self.parse_errors = []
+
+        self.idle_finish = 0
+
+    def cancel(self):
+        self.clock.acquire()
+        self.cancelled = True
+
+        if self.idle_finish != 0:
+            GLib.source_remove(self.idle_finish)
+
+        self.clock.release()
+
+    def finish_in_idle(self):
+        self.finishCallBack(self.parse_errors)
+
+    def run(self):
+
+        try:
+            etree.clear_error_log()
+            parser = etree.XMLParser()
+            xml = etree.fromstring(self.source_contents, parser)
+
+        except etree.XMLSyntaxError as e:
+            for error in e.error_log:
+                self.parse_errors.append((error.line, error.column, error.message))
+
+        except Exception as e:
+            self.parse_errors.append((0, 0, "unknown error " + str(e)))
+
+        self.clock.acquire()
+
+        if not self.cancelled:
+            self.idle_finish = GLib.idle_add(self.finish_in_idle)
+
+        self.clock.release()
+
+class Document(Gcp.Document, Gcp.DiagnosticSupport):
+    def __init__(self, **kwargs):
+
+        Gcp.Document.__init__(self, **kwargs)
+
+        self.reparse_timeout = 0
+        self.diagnostics = Gcp.SourceIndex()
+        self.reparse_thread = None
+        self.tags = None
+        self.diagnostics_lock = threading.Lock()
+
+    def do_get_diagnostic_tags(self):
+        return self.tags
+
+    def do_set_diagnostic_tags(self, tags):
+        self.tags = tags
+
+    def update(self):
+        # Need to parse ourselves again
+        if self.reparse_timeout != 0:
+            GLib.source_remove(self.reparse_timeout)
+
+        if self.reparse_thread != None:
+            self.reparse_thread.cancel()
+            self.reparse_thread = None
+
+        self.reparse_timeout = GLib.timeout_add(300, self.on_reparse_timeout)
+
+    def on_reparse_timeout(self):
+        self.reparse_timeout = 0
+
+        self.reparse_thread = ParseThread(self, self.on_parse_finished)
+        self.reparse_thread.run()
+
+        return False
+
+    def on_parse_finished(self, errors):
+        self.reparse_thread = None
+
+        diags = Gcp.SourceIndex()
+
+        for error in errors:
+            loc = Gcp.SourceLocation.new(self.props.document.get_location(),
+                                     error[0],
+                                     error[1])
+
+            diags.add(Gcp.Diagnostic.new(Gcp.DiagnosticSeverity.ERROR,
+                                         loc,
+                                         [],
+                                         [],
+                                         error[2]))
+
+        self.diagnostics_lock.acquire()
+        self.diagnostics = diags
+        self.diagnostics_lock.release()
+
+        self.emit('diagnostics-updated')
+
+    def do_begin_diagnostics(self):
+        self.diagnostics_lock.acquire()
+        return self.diagnostics
+
+    def do_end_diagnostics(self):
+        self.diagnostics_lock.release()
+
+# vi:ex:ts=4:et
+
diff --git a/configure.ac b/configure.ac
index e993c73..36ddbab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -198,6 +198,18 @@ fi
 
 AM_CONDITIONAL(PYTHON_ENABLED, test x"$enable_python" = "xyes")
 
+AC_ARG_ENABLE([xml],
+              AS_HELP_STRING([--enable-xml[=@<:@no/auto/yes@:>@]],[Build with XML support]),
+              [enable_xml=$enableval],
+              [enable_xml="auto"])
+
+if test "x$enable_xml" = "xauto"; then
+	PKG_CHECK_EXISTS([pygobject-3.0 >= $PYGOBJECT_REQUIRED],
+	                 [enable_xml=yes],[enable_xml=no])
+fi
+
+AM_CONDITIONAL(XML_ENABLED, test x"$enable_xml" = "xyes")
+
 AC_CONFIG_FILES([
 Makefile
 data/Makefile
@@ -210,6 +222,9 @@ backends/c/gcpbackendc.plugin
 backends/python/Makefile
 backends/python/gcpbackendpython/Makefile
 backends/python/gcpbackendpython.plugin
+backends/xml/Makefile
+backends/xml/gcpbackendxml/Makefile
+backends/xml/gcpbackendxml.plugin
 vapi/Makefile
 ])
 
@@ -229,5 +244,6 @@ Configuration:
 	backends:
 		c:		$clang_enabled ($LLVM_VERSION)
 		python:		$enable_python
+		xml:		$enable_xml
 "
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]