[gnome-builder] vala-pack: port plugin to Python



commit 198965a2415b0fbe949602be92e93b10d9806f8a
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jan 3 18:43:48 2020 -0800

    vala-pack: port plugin to Python
    
    Now that we only have an indenter and error regex pipeline
    addin we can easily port this to Python3 and drop all of our
    usage of Vala.
    
    The gvls plugin will continue to provide IDE features for Vala
    but done from out-of-process.

 src/plugins/vala-pack/ide-vala-indenter.vala       | 184 ---------------------
 src/plugins/vala-pack/ide-vala-pipeline-addin.vala |  51 ------
 src/plugins/vala-pack/meson.build                  |  50 +-----
 src/plugins/vala-pack/vala-pack-plugin.vala        |  30 ----
 src/plugins/vala-pack/vala-pack.plugin             |   3 +-
 src/plugins/vala-pack/vala_pack_plugin.py          | 136 +++++++++++++++
 src/plugins/vala-pack/valaconfig.vapi              |   7 -
 7 files changed, 139 insertions(+), 322 deletions(-)
---
diff --git a/src/plugins/vala-pack/meson.build b/src/plugins/vala-pack/meson.build
index fcccfbdf8..63e5bcaff 100644
--- a/src/plugins/vala-pack/meson.build
+++ b/src/plugins/vala-pack/meson.build
@@ -1,54 +1,6 @@
 if get_option('plugin_vala')
 
-add_languages('vala')
-
-valac = meson.get_compiler('vala')
-libvala_version = run_command(valac.cmd_array()[0], '--api-version').stdout().strip()
-libvala = dependency('libvala-@0@'.format(libvala_version))
-
-vala_sources = [
-  'valaconfig.vapi',
-  'ide-vala-indenter.vala',
-  'ide-vala-pipeline-addin.vala',
-  'vala-pack-plugin.vala',
-]
-
-vala_deps = [
-  libpeas_dep,
-  libide_vapi,
-  libgtksource_dep,
-  libvte_dep,
-  libdazzle_dep,
-  libtemplate_glib_dep,
-  libjsonrpc_glib_dep,
-  libgiounix_dep,
-]
-
-shared_module('plugin-vala-pack', vala_sources,
-         dependencies: vala_deps,
-              install: true,
-          install_dir: plugindir,
-        install_rpath: pkglibdir_abs,
-  include_directories: [include_directories('.')] + libide_include_directories,
-            vala_args: [ '--target-glib=2.52',
-                         '--pkg=posix',
-                         '--pkg=libpeas-1.0',
-                         '--pkg=gtksourceview-4',
-                         '--pkg=gio-2.0',
-                         '--pkg=gio-unix-2.0',
-                         '--pkg=libdazzle-1.0',
-                         '--pkg=template-glib-1.0',
-                         '--pkg=vte-2.91',
-                         '--pkg=jsonrpc-glib-1.0',
-                       ],
-               c_args: [ '-DVALA_VERSION="@0@"'.format(libvala_version),
-                         '-DLOG_DOMAIN="vala-pack"',
-                         '-DGETTEXT_PACKAGE="gnome-builder"',
-                         '-DPACKAGE_DATADIR="@0@"'.format(join_paths(get_option('prefix'), 
get_option('datadir'), 'gnome-builder')),
-                         '-DPACKAGE_LIBEXECDIR="@0@"'.format(join_paths(get_option('prefix'), 
get_option('libexecdir'))),
-                         '-Wno-incompatible-pointer-types',
-                       ],
-)
+install_data('vala_pack_plugin.py', install_dir: plugindir)
 
 configure_file(
           input: 'vala-pack.plugin',
diff --git a/src/plugins/vala-pack/vala-pack.plugin b/src/plugins/vala-pack/vala-pack.plugin
index eb5a06eaf..b8e4ef987 100644
--- a/src/plugins/vala-pack/vala-pack.plugin
+++ b/src/plugins/vala-pack/vala-pack.plugin
@@ -1,9 +1,10 @@
 [Plugin]
 Authors=Christian Hergert <christian hergert me>
 Builtin=true
-Module=plugin-vala-pack
 Copyright=Copyright © 2015-2020 Christian Hergert
 Description=Provides various language features for Vala
+Loader=python3
+Module=vala_pack_plugin
 Name=Vala Language Pack
 X-Builder-ABI=@PACKAGE_ABI@
 X-Indenter-Languages-Priority=0
diff --git a/src/plugins/vala-pack/vala_pack_plugin.py b/src/plugins/vala-pack/vala_pack_plugin.py
new file mode 100644
index 000000000..45665c958
--- /dev/null
+++ b/src/plugins/vala-pack/vala_pack_plugin.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+#
+# vala_pack_plugin.py
+#
+# Copyright 2020 Christian Hergert <christian hergert me>
+#
+# 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/>.
+#
+
+from gi.repository import GLib
+from gi.repository import Gdk
+from gi.repository import Ide
+
+_ERROR_REGEX = (
+    "(?<filename>[a-zA-Z0-9\\-\\.\\/_]+.vala):" +
+    "(?<line>\\d+).(?<column>\\d+)-(?<line2>\\d+).(?<column2>\\d+): " +
+    "(?<level>[\\w\\s]+): " +
+    "(?<message>.*)"
+)
+
+class ValaPipelineAddin(Ide.Object, Ide.PipelineAddin):
+    error_format = 0
+
+    def do_load(self, pipeline):
+        self.error_format = pipeline.add_error_format(_ERROR_REGEX, GLib.RegexCompileFlags.OPTIMIZE)
+
+    def do_unload(self, pipeline):
+        pipeline.remove_error_format(self.error_format)
+
+def copy_indent(iter):
+    begin = iter.copy()
+    begin.set_line_offset(0)
+    end = begin.copy()
+    while not end.ends_line() and end.get_char().isspace() and end.forward_char():
+        # Do nothing
+        pass
+    return begin.get_slice(end)
+
+def get_line_text(iter):
+    begin = iter.copy()
+    end = iter.copy()
+    begin.set_line_offset(0)
+    if not end.ends_line():
+        end.forward_to_line_end()
+    return begin.get_slice(end)
+
+def is_newline_in_braces(iter):
+    prev = iter.copy()
+    next = iter.copy()
+    prev.backward_char()
+    next.forward_char()
+    return prev.get_char() == '{' and iter.get_char() == '\n' and next.get_char() == '}'
+
+def is_newline_keyval(keyval):
+    return keyval in (Gdk.KEY_Return, Gdk.KEY_KP_Enter)
+
+def in_comment(iter):
+    buffer = iter.get_buffer()
+    copy = iter.copy()
+    copy.backward_char()
+    return buffer.iter_has_context_class(copy, 'comment')
+
+def indent_comment(iter):
+    line = get_line_text(iter).strip()
+
+    # Continue with another single line comment
+    if line.startswith('//'):
+        return copy_indent(iter) + '// '
+
+    # Comment is closed, copy indent, possibly trimming extra space
+    if line.endswith('*/'):
+        if line.startswith('*'):
+            str = copy_indent(iter)
+            if str.endswith(' '):
+                str = str[:-1]
+            return str
+
+    if line.startswith('/*') and not line.endswith('*/'):
+        return copy_indent(iter) + ' * '
+    elif line.startswith('*'):
+        return copy_indent(iter) + '* '
+
+    return copy_indent(iter)
+
+class ValaIndenter(Ide.Object, Ide.Indenter):
+
+    def do_is_trigger(self, key):
+        return key.keyval in (Gdk.KEY_Return, Gdk.KEY_KP_Enter, Gdk.KEY_slash)
+
+    def do_format(self, text_view, begin, end, key):
+        was_newline = is_newline_keyval(key.keyval)
+        copy = end.copy()
+
+        # Move us back to the jsut inserted character
+        copy.backward_char()
+
+        # If we are in a comment, continue the indentation
+        if in_comment(copy):
+            # Maybe close a multi-line comment
+            if copy.get_char() == '/':
+                close = copy.copy()
+
+                if close.backward_char() and close.get_char() == ' ' and close.backward_char() and 
close.get_char() == '*' :
+                    begin.backward_char()
+                    begin.backward_char()
+                    return ('/', 0)
+
+            if was_newline:
+                return (indent_comment(copy), 0)
+
+        if is_newline_in_braces(copy):
+            prefix = copy_indent(copy)
+
+            if text_view.get_insert_spaces_instead_of_tabs():
+                indent = "    "
+            else:
+                indent = '\t'
+
+            return (prefix + indent + "\n" + prefix, -(len(prefix) + 1))
+
+        if was_newline:
+            return (copy_indent(copy), 0)
+
+        return (None, 0)
+


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