[Conkeror] [PATCH] Let completion functions set the match_required state.

David Kettler kettler at internode.on.net
Fri May 8 05:37:07 PDT 2009


Currently the match_required state is set at the beginning when input
is being read.  This commit allows completers to change that state
during the input.  In particular, this can be used to allow a webjump
with a limited set of valid inputs to prevent invalid inputs from
being accepted.

For example, the following webjump can now be defined and will only
allow valid bookmarks to be chosen.  Without $match_required, the webjump
will try to visit any arbitrary input, which is confusing and not useful.

  /* Access bookmarks via completion from a webjump. */
  define_webjump("bookmark",
                 function(term) {return term;},
                 $completer = history_completer($use_history = false,
                                                $use_bookmarks = true,
                                                $match_required = true));

Another example is in the upcoming index webjump feature.
---

Note: In merge_completers I think the destroy function needs something
like call_all('destroy'), rather than forward().
---
 modules/history.js               |    7 +++++--
 modules/minibuffer-completion.js |   17 +++++++++++++++--
 modules/minibuffer-read.js       |    6 ++++++
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/modules/history.js b/modules/history.js
index 2ca52de..be894d6 100644
--- a/modules/history.js
+++ b/modules/history.js
@@ -9,11 +9,13 @@
 const nav_history_service = Cc["@mozilla.org/browser/nav-history-service;1"]
     .getService(Ci.nsINavHistoryService);
 
-define_keywords("$use_webjumps", "$use_history", "$use_bookmarks");
+define_keywords("$use_webjumps", "$use_history", "$use_bookmarks",
+                "$match_required");
 function history_completer() {
     keywords(arguments);
     var use_history = arguments.$use_history;
     var use_bookmarks = arguments.$use_bookmarks;
+    let match_required = arguments.$match_required;
     return function (input, pos, conservative) {
         if (conservative && input.length == 0)
             return null;
@@ -36,7 +38,8 @@ function history_completer() {
                 get_string: function (i) root.getChild(i).uri,
                 get_description: function (i) root.getChild(i).title,
                 get_input_state: function (i) [root.getChild(i).uri],
-                destroy: function () { root.containerOpen = false; }
+                destroy: function () { root.containerOpen = false; },
+                get_match_required: function() match_required
                };
     }
 }
diff --git a/modules/minibuffer-completion.js b/modules/minibuffer-completion.js
index 503a09e..25cdebf 100644
--- a/modules/minibuffer-completion.js
+++ b/modules/minibuffer-completion.js
@@ -266,7 +266,7 @@ function merge_completers(completers) {
         var count = 0;
         for (let i = 0; i < completers.length; ++i) {
             let r = yield completers[i](input, pos, conservative);
-            if (r != null && r.count > 0) {
+            if (r != null && (r.count > 0 || "get_match_required" in r)) {
                 results.push(r);
                 count += r.count;
             }
@@ -288,11 +288,24 @@ function merge_completers(completers) {
                 return null;
             }
         }
+        function combine_or(name) {
+            return function() {
+                var b = false;
+                for (var j=0; j < results.length; j++) {
+                    var r = results[j];
+                    if (name in r && r[name] != null) {
+                        b = b || r[name].apply(this, arguments);
+                    }
+                }
+                return b;
+            }
+        }
         yield co_return({count: count,
                          get_string: forward('get_string'),
                          get_description: forward('get_description'),
                          get_input_state: forward('get_input_state'),
-                         destroy: forward('destroy')
+                         destroy: forward('destroy'),
+                         get_match_required: combine_or('get_match_required')
                         });
     };
 }
diff --git a/modules/minibuffer-read.js b/modules/minibuffer-read.js
index 53ec922..d72d9c0 100644
--- a/modules/minibuffer-read.js
+++ b/modules/minibuffer-read.js
@@ -78,6 +78,7 @@ function text_entry_minibuffer_state(continuation) {
         this.completions_display_element = null;
         this.selected_completion_index = -1;
         this.match_required  = !!arguments.$match_required;
+        this.match_required_default = this.match_required;
         if (this.match_required)
             this.default_completion = arguments.$default_completion;
     }
@@ -297,6 +298,11 @@ text_entry_minibuffer_state.prototype = {
         this.completions_valid = true;
         this.applied_common_prefix = false;
 
+        if (c && ("get_match_required" in c))
+            this.match_required = c.get_match_required();
+        if (this.match_required == null)
+            this.match_required = this.match_required_default;
+        
         let i = -1;
         if (c && c.count > 0) {
             if (this.match_required) {
-- 
1.6.2.4



More information about the Conkeror mailing list