[gedit-code-assistance/wip/arch] Rewrite for new dbus interfaces



commit d5a1d11d87953f4ba03ed3b8f63c91f17a5ad88c
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Sun Nov 10 15:27:13 2013 +0100

    Rewrite for new dbus interfaces

 src/gca-backend.vala        |  166 ++++++++++++++++++++++++++++++++-----------
 src/gca-dbus.vala           |   28 +++++++-
 src/gca-document.vala       |   48 +++++++------
 src/gca-remote-service.vala |    6 +--
 src/gca-view.vala           |    9 +++
 5 files changed, 185 insertions(+), 72 deletions(-)
---
diff --git a/src/gca-backend.vala b/src/gca-backend.vala
index ceff288..ef73398 100644
--- a/src/gca-backend.vala
+++ b/src/gca-backend.vala
@@ -23,33 +23,68 @@ namespace Gca
 class Backend : Object
 {
        private Gee.ArrayList<View> d_views;
+       private Gee.HashMap<string, View> d_paths;
        private string d_name;
        private DBus.Service d_service;
+       private DBus.Project d_project;
        private RemoteServices d_supported_services;
 
-       public static async Backend create(string language) throws IOError, DBusError
+       public static async Backend create(string language) throws Error
        {
                var name = "org.gnome.CodeAssist." + language;
                var path = "/org/gnome/CodeAssist/" + language;
 
+               var project = yield get_project(name, path);
+               var services = yield get_remote_services(name, path);
                var service = yield Bus.get_proxy<DBus.Service>(BusType.SESSION, name, path);
-               var services = yield service.supported_services();
 
-               return new Backend(name, service, services);
+               return new Backend(name, service, project, services);
        }
 
-       private Backend(string name, DBus.Service service, string[] services)
+       private static async RemoteServices get_remote_services(string name, string path) throws Error
+       {
+               RemoteServices ret = 0;
+
+               var intro = yield Bus.get_proxy<DBus.Introspectable>(BusType.SESSION, name, path + 
"/document");
+               var xml = yield intro.Introspect();
+
+               var node = new DBusNodeInfo.for_xml(xml);
+
+               foreach (var iface in node.interfaces)
+               {
+                       ret |= RemoteServices.parse(iface.name);
+               }
+
+               return ret;
+       }
+
+       private static async DBus.Project? get_project(string name, string path) throws Error
+       {
+               var intro = yield Bus.get_proxy<DBus.Introspectable>(BusType.SESSION, name, path);
+               var xml = yield intro.Introspect();
+
+               var serviceintro = new DBusNodeInfo.for_xml(xml);
+
+               DBus.Project? project = null;
+
+               if (serviceintro.lookup_interface("org.gnome.CodeAssist.Project") != null)
+               {
+                       project = yield Bus.get_proxy<DBus.Project>(BusType.SESSION, name, path);
+               }
+
+               return project;
+       }
+
+       private Backend(string name, DBus.Service service, DBus.Project? project, RemoteServices services)
        {
                d_name = name;
                d_service = service;
+               d_project = project;
 
                d_views = new Gee.ArrayList<View>();
-               d_supported_services = 0;
+               d_paths = new Gee.HashMap<string, View>();
 
-               foreach (var s in services)
-               {
-                       d_supported_services |= RemoteServices.parse(s);
-               }
+               d_supported_services = services;
        }
 
        public bool supports(RemoteServices services)
@@ -60,17 +95,32 @@ class Backend : Object
        public void register(View view)
        {
                d_views.add(view);
+               d_paths[view.document.path] = view;
 
                view.changed.connect(on_view_changed);
+               view.path_changed.connect(on_view_path_changed);
        }
 
        public void unregister(View view)
        {
                view.changed.disconnect(on_view_changed);
+               view.path_changed.disconnect(on_view_path_changed);
+
                d_views.remove(view);
+               d_paths.unset(view.document.path);
+       }
+
+       private void on_view_path_changed(View view, string? prevpath)
+       {
+               if (prevpath != null)
+               {
+                       d_paths.unset(prevpath);
+               }
+
+               d_paths[view.document.path] = view;
        }
 
-       private async DBus.UnsavedDocument? unsaved_document(View v)
+       private async string? unsaved_document(View v)
        {
                var doc = v.document;
 
@@ -78,12 +128,7 @@ class Backend : Object
                {
                        try
                        {
-                               var dp = yield doc.unsaved_data_path();
-
-                               return DBus.UnsavedDocument() {
-                                       path = doc.path,
-                                       data_path = dp
-                               };
+                               return yield doc.unsaved_data_path();
                        }
                        catch (Error e)
                        {
@@ -94,52 +139,72 @@ class Backend : Object
                return null;
        }
 
-       private async DBus.UnsavedDocument[] unsaved_documents(View primary)
+       private async DBus.OpenDocument[] open_documents(View primary)
        {
-               if ((d_supported_services & RemoteServices.MULTI_DOC) == 0)
-               {
-                       var unsaved = yield unsaved_document(primary);
+               var ret = new DBus.OpenDocument[d_views.size];
+               ret.length = 0;
 
-                       if (unsaved == null)
-                       {
-                               return new DBus.UnsavedDocument[0];
-                       }
+               foreach (var v in d_views)
+               {
+                       var dp = yield unsaved_document(v);
 
-                       return new DBus.UnsavedDocument[] {unsaved};
+                       ret += DBus.OpenDocument(){
+                               path = v.document.path,
+                               data_path = (dp == null ? "" : dp)
+                       };
                }
 
-               var unsaved = new DBus.UnsavedDocument[d_views.size];
-               unsaved.length = 0;
+               return ret;
+       }
 
-               foreach (var v in d_views)
-               {
-                       var u = yield unsaved_document(v);
+       private void parse_single(View view)
+       {
+               unsaved_document.begin(view, (obj, res) => {
+                       var data_path = unsaved_document.end(res);
+                       var path = view.document.path;
+                       var cursor = view.document.cursor;
+
+                       var options = new HashTable<string, Variant>(str_hash, str_equal);
 
-                       if (u != null)
+                       if (data_path == null)
                        {
-                               unsaved += u;
+                               data_path = path;
                        }
-               }
 
-               return unsaved;
+                       d_service.parse.begin(path, cursor, data_path, options, (obj, res) => {
+                               ObjectPath ret;
+
+                               try
+                               {
+                                       ret = d_service.parse.end(res);
+                               }
+                               catch (Error e)
+                               {
+                                       Log.debug("Failed to parse: %s", e.message);
+                                       return;
+                               }
+
+                               view.update(new RemoteDocument(d_name, ret));
+                       });
+               });
        }
 
-       private void parse(View view)
+       private void parse_project(View view)
        {
-               unsaved_documents.begin(view, (obj, res) => {
-                       var unsaved = unsaved_documents.end(res);
+               open_documents.begin(view, (obj, res) => {
+                       var docs = open_documents.end(res);
 
                        var path = view.document.path;
                        var cursor = view.document.cursor;
 
                        var options = new HashTable<string, Variant>(str_hash, str_equal);
 
-                       d_service.parse.begin(path, cursor, unsaved, options, (obj, res) => {
-                               ObjectPath ret;
+                       d_project.parse_all.begin(path, cursor, docs, options, (obj, res) => {
+                               DBus.RemoteDocument[] ret;
 
                                try
                                {
-                                       ret = d_service.parse.end(res);
+                                       ret = d_project.parse_all.end(res);
                                }
                                catch (Error e)
                                {
@@ -147,11 +212,30 @@ class Backend : Object
                                        return;
                                }
 
-                               view.update(new RemoteDocument(d_name, ret));
+                               foreach (var d in ret)
+                               {
+                                       if (d_paths.has_key(d.path))
+                                       {
+                                               var vw = d_paths[d.path];
+                                               vw.update(new RemoteDocument(d_name, d.remote_path));
+                                       }
+                               }
                        });
                });
        }
 
+       private void parse(View view)
+       {
+               if (d_project != null)
+               {
+                       parse_project(view);
+               }
+               else
+               {
+                       parse_single(view);
+               }
+       }
+
        private void on_view_changed(View view)
        {
                parse(view);
diff --git a/src/gca-dbus.vala b/src/gca-dbus.vala
index 3ef224a..4d8da83 100644
--- a/src/gca-dbus.vala
+++ b/src/gca-dbus.vala
@@ -20,12 +20,18 @@
 namespace Gca.DBus
 {
 
-public struct UnsavedDocument
+public struct OpenDocument
 {
        public string path;
        public string data_path;
 }
 
+public struct RemoteDocument
+{
+       public string path;
+       public ObjectPath remote_path;
+}
+
 public struct SourceLocation
 {
        public int64 line;
@@ -54,19 +60,35 @@ public struct Diagnostic
        public string message;
 }
 
+[DBus(name = "org.freedesktop.DBus.Introspectable")]
+interface Introspectable : Object
+{
+       public abstract async string Introspect() throws DBusError;
+}
+
 [DBus(name = "org.gnome.CodeAssist.Service")]
 interface Service : Object
 {
        public abstract async ObjectPath parse(string                     path,
                                               int64                      cursor,
-                                              UnsavedDocument[]          unsaved,
+                                              string                     data_path,
                                               HashTable<string, Variant> options) throws DBusError;
 
        public abstract async void dispose(string path) throws DBusError;
 
-       public abstract async string[] supported_services() throws DBusError;
 }
 
+[DBus(name = "org.gnome.CodeAssist.Project")]
+interface Project : Object
+{
+       public abstract async RemoteDocument[]
+       parse_all(string                     path,
+                 int64                      cursor,
+                 OpenDocument[]             documents,
+                 HashTable<string, Variant> options) throws DBusError;
+}
+
+
 [DBus(name = "org.gnome.CodeAssist.Document")]
 interface Document : Object
 {
diff --git a/src/gca-document.vala b/src/gca-document.vala
index 8d934bf..9e24c02 100644
--- a/src/gca-document.vala
+++ b/src/gca-document.vala
@@ -31,10 +31,11 @@ public class Document : Object
        private string? d_text;
        private File? d_location;
        private bool d_dispose_ran;
+       private string? d_path;
 
        private File? d_unsaved_file;
 
-       public signal void location_changed(File? previous_location);
+       public signal void path_changed(string? previous_path);
        public signal void changed();
 
        private static bool s_needs_tmp_chmod = true;
@@ -57,9 +58,11 @@ public class Document : Object
                d_document.modified_changed.connect(on_document_modified_changed);
                d_document.end_user_action.connect(on_document_end_user_action);
                d_document.notify["location"].connect(on_location_changed);
+               d_document.notify["shortname"].connect(on_shortname_changed);
                d_document.saved.connect(on_document_saved);
 
                d_location = null;
+               d_path = null;
 
                update_location();
        }
@@ -72,6 +75,7 @@ public class Document : Object
 
                        d_document.modified_changed.disconnect(on_document_modified_changed);
                        d_document.notify["location"].disconnect(on_location_changed);
+                       d_document.notify["shortname"].disconnect(on_shortname_changed);
 
                        d_document.end_user_action.disconnect(on_document_end_user_action);
                        d_document.saved.disconnect(on_document_saved);
@@ -82,41 +86,31 @@ public class Document : Object
                base.dispose();
        }
 
-       private void set_location(File? location)
+       private void update_path()
        {
-               if (location == d_location)
-               {
-                       return;
-               }
-
-               File? prev = d_location;
-               d_location = location;
+               var npath = path;
 
-               if ((prev == null) != (d_location == null))
+               if (npath != d_path)
                {
-                       location_changed(prev);
-               }
-               else if (prev != null && !prev.equal(d_location))
-               {
-                       location_changed(prev);
+                       var prevpath = d_path;
+                       d_path = npath;
+
+                       path_changed(prevpath);
                }
        }
 
        private void update_location()
        {
-               if (document.is_untitled())
+               if (document.is_untitled() || !document.is_local())
                {
-                       set_location(null);
-                       return;
+                       d_location = null;
                }
-
-               if (!document.is_local())
+               else
                {
-                       set_location(null);
-                       return;
+                       d_location = document.location;
                }
 
-               set_location(document.location);
+               update_path();
        }
 
        private void update_modified()
@@ -268,6 +262,9 @@ public class Document : Object
                try
                {
                        yield ostream.write_async(d_text.data);
+
+                       uint8[1] b = {'\n'};
+                       yield ostream.write_async(b);
                }
                catch (IOError e)
                {
@@ -312,6 +309,11 @@ public class Document : Object
        {
                emit_changed();
        }
+
+       private void on_shortname_changed()
+       {
+               update_path();
+       }
 }
 
 }
diff --git a/src/gca-remote-service.vala b/src/gca-remote-service.vala
index dc98fdd..9dbe5dc 100644
--- a/src/gca-remote-service.vala
+++ b/src/gca-remote-service.vala
@@ -25,8 +25,7 @@ enum RemoteServices
 {
        DIAGNOSTICS,
        SEMANTIC_VALUES,
-       SYMBOLS,
-       MULTI_DOC;
+       SYMBOLS;
 
        public static RemoteServices parse(string s)
        {
@@ -38,15 +37,12 @@ enum RemoteServices
                        return RemoteServices.SEMANTIC_VALUES;
                case "org.gnome.CodeAssist.Symbols":
                        return RemoteServices.SYMBOLS;
-               case "org.gnome.CodeAssist.MultiDoc":
-                       return RemoteServices.MULTI_DOC;
                }
 
                return 0;
        }
 }
 
-
 class RemoteDocument
 {
        private string d_service;
diff --git a/src/gca-view.vala b/src/gca-view.vala
index 5eb0c0d..e1e8e7d 100644
--- a/src/gca-view.vala
+++ b/src/gca-view.vala
@@ -41,6 +41,7 @@ class View : Object
        private RemoteService[] d_services;
 
        public signal void changed();
+       public signal void path_changed(string? prevpath);
 
        public View(Gedit.View view)
        {
@@ -108,6 +109,7 @@ class View : Object
 
                buf.notify["language"].disconnect(on_notify_language);
                d_document.changed.disconnect(on_document_changed);
+               d_document.path_changed.disconnect(on_document_path_changed);
 
                unregister_backend();
 
@@ -130,9 +132,16 @@ class View : Object
                buf.notify["language"].connect(on_notify_language);
 
                d_document.changed.connect(on_document_changed);
+               d_document.path_changed.connect(on_document_path_changed);
+
                update_backend();
        }
 
+       private void on_document_path_changed(string? prevpath)
+       {
+               path_changed(prevpath);
+       }
+
        private void on_document_changed()
        {
                d_scrollbar_marker.max_line = d_document.document.get_line_count();


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