[gnome-shell] runDialog: Remove the use of file monitors for file completion



commit 40d9ed535b58daf7d69b5ef5310042a655d3cd01
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Mar 6 21:10:41 2013 -0500

    runDialog: Remove the use of file monitors for file completion
    
    Launching the run dialog to open the looking glass or something
    like that shouldn't install a bunch of file monitors that monitor
    every IO change to the home and system directories.
    
    Instead, simply scan all the paths when trying to complete.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=695338

 js/ui/runDialog.js |  172 +++++++++++----------------------------------------
 1 files changed, 37 insertions(+), 135 deletions(-)
---
diff --git a/js/ui/runDialog.js b/js/ui/runDialog.js
index f35b557..bedea40 100644
--- a/js/ui/runDialog.js
+++ b/js/ui/runDialog.js
@@ -30,138 +30,6 @@ const EXEC_ARG_KEY = 'exec-arg';
 
 const DIALOG_GROW_TIME = 0.1;
 
-const CommandCompleter = new Lang.Class({
-    Name: 'CommandCompleter',
-
-    _init : function() {
-        this._changedCount = 0;
-        this._paths = GLib.getenv('PATH').split(':');
-        this._paths.push(GLib.get_home_dir());
-        this._valid = false;
-        this._updateInProgress = false;
-        this._childs = new Array(this._paths.length);
-        this._monitors = new Array(this._paths.length);
-        for (let i = 0; i < this._paths.length; i++) {
-            this._childs[i] = [];
-            let file = Gio.file_new_for_path(this._paths[i]);
-            let info;
-            try {
-                info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
-            } catch (e) {
-                // FIXME catchall
-                this._paths[i] = null;
-                continue;
-            }
-
-            if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
-                continue;
-
-            this._paths[i] = file.get_path();
-            this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
-            if (this._monitors[i] != null) {
-                this._monitors[i].connect('changed', Lang.bind(this, this._onChanged));
-            }
-        }
-        this._paths = this._paths.filter(function(a) {
-            return a != null;
-        });
-        this._update(0);
-    },
-
-    update : function() {
-        if (this._valid)
-            return;
-        this._update(0);
-    },
-
-    _update : function(i) {
-        if (i == 0 && this._updateInProgress)
-            return;
-        this._updateInProgress = true;
-        this._changedCount = 0;
-        this._i = i;
-        if (i >= this._paths.length) {
-            this._valid = true;
-            this._updateInProgress = false;
-            return;
-        }
-        let file = Gio.file_new_for_path(this._paths[i]);
-        this._childs[this._i] = [];
-        FileUtils.listDirAsync(file, Lang.bind(this, function (files) {
-            for (let i = 0; i < files.length; i++) {
-                this._childs[this._i].push(files[i].get_name());
-            }
-            this._update(this._i + 1);
-        }));
-    },
-
-    _onChanged : function(m, f, of, type) {
-        if (!this._valid)
-            return;
-        let path = f.get_parent().get_path();
-        let k = undefined;
-        for (let i = 0; i < this._paths.length; i++) {
-            if (this._paths[i] == path)
-                k = i;
-        }
-        if (k === undefined) {
-            return;
-        }
-        if (type == Gio.FileMonitorEvent.CREATED) {
-            this._childs[k].push(f.get_basename());
-        }
-        if (type == Gio.FileMonitorEvent.DELETED) {
-            this._changedCount++;
-            if (this._changedCount > MAX_FILE_DELETED_BEFORE_INVALID) {
-                this._valid = false;
-            }
-            let name = f.get_basename();
-            this._childs[k] = this._childs[k].filter(function(e) {
-                return e != name;
-            });
-        }
-        if (type == Gio.FileMonitorEvent.UNMOUNTED) {
-            this._childs[k] = [];
-        }
-    },
-
-    getCompletion: function(text) {
-        let common = '';
-        let notInit = true;
-        if (!this._valid) {
-            this._update(0);
-            return common;
-        }
-        function _getCommon(s1, s2) {
-            let k = 0;
-            for (; k < s1.length && k < s2.length; k++) {
-                if (s1[k] != s2[k])
-                    break;
-            }
-            if (k == 0)
-                return '';
-            return s1.substr(0, k);
-        }
-        function _hasPrefix(s1, prefix) {
-            return s1.indexOf(prefix) == 0;
-        }
-        for (let i = 0; i < this._childs.length; i++) {
-            for (let k = 0; k < this._childs[i].length; k++) {
-                if (!_hasPrefix(this._childs[i][k], text))
-                    continue;
-                if (notInit) {
-                    common = this._childs[i][k];
-                    notInit = false;
-                }
-                common = _getCommon(common, this._childs[i][k]);
-            }
-        }
-        if (common.length)
-            return common.substr(text.length);
-        return common;
-    }
-});
-
 const RunDialog = new Lang.Class({
     Name: 'RunDialog',
     Extends: ModalDialog.ModalDialog,
@@ -242,8 +110,6 @@ const RunDialog = new Lang.Class({
                            key: Clutter.Escape }]);
 
         this._pathCompleter = new Gio.FilenameCompleter();
-        this._commandCompleter = new CommandCompleter();
-        this._group.connect('notify::visible', Lang.bind(this._commandCompleter, 
this._commandCompleter.update));
 
         this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
                                                      entry: this._entryText });
@@ -277,11 +143,47 @@ const RunDialog = new Lang.Class({
         }));
     },
 
+    _getCommandCompletion: function(text) {
+        function _getCommon(s1, s2) {
+            if (s1 == null)
+                return s2;
+
+            let k = 0;
+            for (; k < s1.length && k < s2.length; k++) {
+                if (s1[k] != s2[k])
+                    break;
+            }
+            if (k == 0)
+                return '';
+            return s1.substr(0, k);
+        }
+
+        let paths = GLib.getenv('PATH').split(':');
+        paths.push(GLib.get_home_dir());
+        let someResults = paths.map(function(path) {
+            let file = Gio.File.new_for_path(path);
+            let fileEnum = file.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
+            let info;
+            let results = [];
+            while ((info = fileEnum.next_file(null))) {
+                let name = info.get_name();
+                if (name.slice(0, text.length) == text)
+                    results.push(name);
+            }
+            return results;
+        });
+        let results = someResults.reduce(function(a, b) {
+            return a.concat(b);
+        }, []);
+        let common = results.reduce(_getCommon, null);
+        return common.substr(text.length);
+    },
+
     _getCompletion : function(text) {
         if (text.indexOf('/') != -1) {
             return this._pathCompleter.get_completion_suffix(text);
         } else {
-            return this._commandCompleter.getCompletion(text);
+            return this._getCommandCompletion(text);
         }
     },
 


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