[gedit-code-assistance] Added python backend



commit a5efb24d98170b740a5b068e486ba136cc3c386d
Author: Jesse van den Kieboom <jesse vandenkieboom epfl ch>
Date:   Wed Mar 14 19:05:34 2012 +0100

    Added python backend

 backends/Makefile.am                         |    4 +
 backends/python/Makefile.am                  |    9 ++
 backends/python/gcpbackendpython.plugin.in   |   13 +++
 backends/python/gcpbackendpython/Makefile.am |   11 ++
 backends/python/gcpbackendpython/__init__.py |   20 ++++
 backends/python/gcpbackendpython/backend.py  |   52 ++++++++++
 backends/python/gcpbackendpython/document.py |  140 ++++++++++++++++++++++++++
 configure.ac                                 |   27 +++++
 8 files changed, 276 insertions(+), 0 deletions(-)
---
diff --git a/backends/Makefile.am b/backends/Makefile.am
index b10ba8a..fa3fba4 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -4,4 +4,8 @@ if CLANG_ENABLED
 SUBDIRS += c
 endif
 
+if PYTHON_ENABLED
+SUBDIRS += python
+endif
+
 -include $(top_srcdir)/git.mk
diff --git a/backends/python/Makefile.am b/backends/python/Makefile.am
new file mode 100644
index 0000000..03e69c0
--- /dev/null
+++ b/backends/python/Makefile.am
@@ -0,0 +1,9 @@
+SUBDIRS = gcpbackendpython
+
+plugindir = $(GCP_BACKENDS_LIBS_DIR)
+plugin_DATA = gcpbackendpython.plugin
+
+EXTRA_DIST = \
+	gcpbackendpython.plugin
+
+-include $(top_srcdir)/git.mk
diff --git a/backends/python/gcpbackendpython.plugin.in b/backends/python/gcpbackendpython.plugin.in
new file mode 100644
index 0000000..e26f8c0
--- /dev/null
+++ b/backends/python/gcpbackendpython.plugin.in
@@ -0,0 +1,13 @@
+[Plugin]
+Module=gcpbackendpython
+Loader=python
+IAge=3
+Name=Code Assistance Python Backend
+Hidden=yes
+Builtin=yes
+Description=Code assistance backend for the Python language
+Authors=Jesse van den Kieboom <jessevdk gnome org>
+Copyright=Copyright  2012 Jesse van den Kieboom
+Website=http://www.gedit.org
+Version= VERSION@
+X-Languages=python
diff --git a/backends/python/gcpbackendpython/Makefile.am b/backends/python/gcpbackendpython/Makefile.am
new file mode 100644
index 0000000..5293c3f
--- /dev/null
+++ b/backends/python/gcpbackendpython/Makefile.am
@@ -0,0 +1,11 @@
+plugindir = $(GCP_BACKENDS_LIBS_DIR)/gcpbackendpython
+
+plugin_PYTHON = 	\
+	__init__.py	\
+	backend.py	\
+	document.py
+
+CLEANFILES = *.pyc
+DISTCLEANFILES = *.pyc
+
+-include $(top_srcdir)/git.mk
diff --git a/backends/python/gcpbackendpython/__init__.py b/backends/python/gcpbackendpython/__init__.py
new file mode 100644
index 0000000..ecd1bee
--- /dev/null
+++ b/backends/python/gcpbackendpython/__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/python/gcpbackendpython/backend.py b/backends/python/gcpbackendpython/backend.py
new file mode 100644
index 0000000..443d166
--- /dev/null
+++ b/backends/python/gcpbackendpython/backend.py
@@ -0,0 +1,52 @@
+# 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 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/python/gcpbackendpython/document.py b/backends/python/gcpbackendpython/document.py
new file mode 100644
index 0000000..6331061
--- /dev/null
+++ b/backends/python/gcpbackendpython/document.py
@@ -0,0 +1,140 @@
+# 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 gi.repository import GObject, Gcp, GLib, Gio
+
+import ast
+import threading
+
+class ParseThread(threading.Thread):
+    def __init__(self, doc, finishcb):
+        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.finishcb = finishcb
+
+        self.parse_error = None
+        self.ast = None
+
+        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.finishcb(self.ast, self.parse_error)
+
+    def run(self):
+        # Here we have the lock, reparse now
+        try:
+            self.ast = ast.parse(self.source_contents, self.source_file)
+        except Exception as e:
+            self.parse_error = 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, ast, error):
+        self.reparse_thread = None
+
+        diags = Gcp.SourceIndex()
+
+        if error:
+            loc = Gcp.SourceLocation.new(self.props.document.get_location(),
+                                     error.lineno,
+                                     error.offset)
+
+            diags.add(Gcp.Diagnostic.new(Gcp.DiagnosticSeverity.ERROR,
+                                         loc,
+                                         [],
+                                         [],
+                                         error.msg))
+
+        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 0088f89..d749e69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,6 +17,8 @@ AM_PROG_CC_STDC
 AC_HEADER_STDC
 AM_PROG_LIBTOOL
 
+AM_PATH_PYTHON
+
 AM_INIT_AUTOMAKE([1.11 tar-ustar dist-xz no-dist-gzip -Wno-portability])
 AM_MAINTAINER_MODE([enable])
 AM_SILENT_RULES([yes])
@@ -172,6 +174,27 @@ AC_DEFINE_UNQUOTED([GCP_BACKENDS_DATA_DIR], "$GCP_BACKENDS_DATA_DIR_EX", [Backen
 AC_DEFINE_UNQUOTED([GCP_LIBS_DIR], "$GCP_LIBS_DIR_EX", [Library dir])
 AC_DEFINE_UNQUOTED([GCP_DATA_DIR], "$GCP_DATA_DIR_EX", [Data dir])
 
+PYGOBJECT_REQUIRED=3.0.0
+
+AC_ARG_ENABLE([python],
+              AS_HELP_STRING([--enable-python[=@<:@no/auto/yes@:>@]],[Build with python support]),
+              [enable_python=$enableval],
+              [enable_python="auto"])
+
+if test "x$enable_python" = "xauto"; then
+	PKG_CHECK_EXISTS([pygobject-3.0 >= $PYGOBJECT_REQUIRED],
+	                 [enable_python=yes],[enable_python=no])
+fi
+
+if test "x$enable_python" = "xyes"; then
+	PKG_CHECK_MODULES(PYTHON, [pygobject-3.0 >= $PYGOBJECT_REQUIRED])
+
+	pyoverridesdir=`$PYTHON -c "import gi; print(gi._overridesdir)"`
+	AC_SUBST(pyoverridesdir)
+fi
+
+AM_CONDITIONAL(PYTHON_ENABLED, test x"$enable_python" = "xyes")
+
 AC_CONFIG_FILES([
 Makefile
 data/Makefile
@@ -181,6 +204,9 @@ backends/Makefile
 backends/c/Makefile
 backends/c/gcp-c-config.vala
 backends/c/gcpbackendc.plugin
+backends/python/Makefile
+backends/python/gcpbackendpython/Makefile
+backends/python/gcpbackendpython.plugin
 vapi/Makefile
 ])
 
@@ -199,5 +225,6 @@ Configuration:
 
 	backends:
 		c:		$clang_enabled ($LLVM_VERSION)
+		python:		$enable_python
 "
 



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