This patch is not intended for application; the implementation is ugly
and only lightly tested.  But it does illustrate a facility I have
found useful.

There are two situations where I find myself wanting to open multiple
new buffers in conkeror and where there is enough state in the current
interaction to make it inconvenient to follow a single URL and then
repeat the interaction.

When using M-x follow-new-buffer-background (bound to a key) sometimes
I have narrowed down to a few links using the hints interaction and
want to load them all.

Similarly, when using C-u g sometimes when I have narrowed down to a
few links from my browser history using the minibuffer completion, I
want to load them all.

In both cases this patch allows the currently selected URL to be
followed with C-RET, returning to the same state of the minibuffer
interaction, ready to load another.

A proper implementation of this idea will need a larger restructure of
the minibuffer interaction and a better understanding of the coroutine
interface than I currently possess.

See also issue365: Open multiple links in conkeror
---
 modules/bindings/default/hints.js      |    1 +
 modules/bindings/default/minibuffer.js |    1 +
 modules/element.js                     |   20 +++++++++++---------
 modules/hints.js                       |   23 +++++++++++++++++++----
 modules/minibuffer-read.js             |   21 +++++++++++++++++----
 5 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/modules/bindings/default/hints.js 
b/modules/bindings/default/hints.js
index 6c244f2..08dd9b8 100644
--- a/modules/bindings/default/hints.js
+++ b/modules/bindings/default/hints.js
@@ -24,6 +24,7 @@ define_key(hint_keymap, "escape", "minibuffer-abort");
 define_key(hint_keymap, "M-escape", "minibuffer-abort");
 define_key(hint_keymap, "C-g", "minibuffer-abort");
 define_key(hint_keymap, "return", "hints-exit");
+define_key(hint_keymap, "C-return", "hints-exit-with-repeat");
 define_key(hint_keymap, "C-q", "hints-quote-next");
 
 
diff --git a/modules/bindings/default/minibuffer.js 
b/modules/bindings/default/minibuffer.js
index 70c083e..5c94666 100644
--- a/modules/bindings/default/minibuffer.js
+++ b/modules/bindings/default/minibuffer.js
@@ -16,6 +16,7 @@ define_fallthrough(minibuffer_base_keymap, 
match_any_unmodified_character);
 define_fallthrough(minibuffer_keymap, match_any_unmodified_character);
 
 define_key(minibuffer_keymap, "return", "exit-minibuffer");
+define_key(minibuffer_keymap, "C-return", "exit-minibuffer-with-repeat");
 define_key(minibuffer_keymap, "M-p", "minibuffer-history-previous");
 define_key(minibuffer_keymap, "M-n", "minibuffer-history-next");
 define_key(minibuffer_keymap, "C-g", "minibuffer-abort");
diff --git a/modules/element.js b/modules/element.js
index 28ac598..b9aa3c7 100644
--- a/modules/element.js
+++ b/modules/element.js
@@ -502,15 +502,17 @@ function follow (I, target) {
     if (target == null)
         target = FOLLOW_DEFAULT;
     I.target = target;
-    if (target == OPEN_CURRENT_BUFFER)
-        check_buffer(I.buffer, content_buffer);
-    var element = yield read_browser_object(I);
-    try {
-        element = load_spec(element);
-        if (I.forced_charset)
-            element.forced_charset = I.forced_charset;
-    } catch (e) {}
-    browser_object_follow(I.buffer, target, element);
+    do {
+        if (target == OPEN_CURRENT_BUFFER)
+            check_buffer(I.buffer, content_buffer);
+        var element = yield read_browser_object(I);
+        try {
+            element = load_spec(element);
+            if (I.forced_charset)
+                element.forced_charset = I.forced_charset;
+        } catch (e) {}
+        yield browser_object_follow(I.buffer, target, element);
+    } while (I.window.repeat_minibuffer);
 }
 
 function follow_new_buffer (I) {
diff --git a/modules/hints.js b/modules/hints.js
index 41e73c9..6210d3e 100644
--- a/modules/hints.js
+++ b/modules/hints.js
@@ -677,7 +677,7 @@ interactive("hints-previous", null,
         hints_next(I.window, I.minibuffer.check_state(hints_minibuffer_state), 
-I.p);
     });
 
-function hints_exit (window, s) {
+function hints_exit (window, s, repeat) {
     var cur = s.manager.current_hint_number;
     var elem = null;
     if (cur > 0 && cur <= s.manager.valid_hints.length)
@@ -687,7 +687,10 @@ function hints_exit (window, s) {
     if (elem !== null) {
         var c = s.continuation;
         delete s.continuation;
-        window.minibuffer.pop_state();
+        if (repeat)
+            window.repeat_minibuffer = s;
+        else
+            window.minibuffer.pop_state();
         if (c)
             c(elem);
     }
@@ -698,6 +701,11 @@ interactive("hints-exit", null,
         hints_exit(I.window, I.minibuffer.check_state(hints_minibuffer_state));
     });
 
+interactive("hints-exit-with-repeat", null,
+    function (I) {
+        hints_exit(I.window, I.minibuffer.check_state(hints_minibuffer_state), 
true);
+    });
+
 interactive("hints-quote-next", null,
     function (I) {
         I.overlay_keymap = hint_quote_next_keymap;
@@ -709,8 +717,15 @@ define_keywords("$buffer");
 minibuffer.prototype.read_hinted_element = function () {
     keywords(arguments);
     var buf = arguments.$buffer;
-    var s = new hints_minibuffer_state(this, (yield CONTINUATION), buf, 
forward_keywords(arguments));
-    this.push_state(s);
+    var s = this.window.repeat_minibuffer;
+    this.window.repeat_minibuffer = null;
+    var c = yield CONTINUATION;
+    if (s)
+        s.continuation = c;
+    else {
+        s = new hints_minibuffer_state(this, c, buf, 
forward_keywords(arguments));
+        this.push_state(s);
+    }
     var result = yield SUSPEND;
     yield co_return(result);
 };
diff --git a/modules/minibuffer-read.js b/modules/minibuffer-read.js
index c980b84..2a38637 100644
--- a/modules/minibuffer-read.js
+++ b/modules/minibuffer-read.js
@@ -410,7 +410,7 @@ interactive("minibuffer-complete", null,
 interactive("minibuffer-complete-previous", null,
     function (I) { minibuffer_complete(I.window, -I.p); });
 
-function exit_minibuffer (window) {
+function exit_minibuffer (window, repeat) {
     var m = window.minibuffer;
     var s = m.current_state;
     if (! (s instanceof text_entry_minibuffer_state))
@@ -447,7 +447,10 @@ function exit_minibuffer (window) {
     }
     var cont = s.continuation;
     delete s.continuation;
-    m.pop_state();
+    if (repeat)
+        window.repeat_minibuffer = s;
+    else
+        m.pop_state();
     if (cont) {
         if (s.match_required)
             cont(match);
@@ -458,6 +461,9 @@ function exit_minibuffer (window) {
 interactive("exit-minibuffer", null,
     function (I) { exit_minibuffer(I.window); });
 
+interactive("exit-minibuffer-with-repeat", null,
+    function (I) { exit_minibuffer(I.window, true); });
+
 function minibuffer_history_next (window, count) {
     var m = window.minibuffer;
     var s = m.current_state;
@@ -499,8 +505,15 @@ interactive("minibuffer-history-previous", null,
 
 // Define the asynchronous minibuffer.read function
 minibuffer.prototype.read = function () {
-    var s = new text_entry_minibuffer_state(this, (yield CONTINUATION), 
forward_keywords(arguments));
-    this.push_state(s);
+    var s = this.window.repeat_minibuffer;
+    this.window.repeat_minibuffer = null;
+    var c = yield CONTINUATION;
+    if (s)
+        s.continuation = c;
+    else {
+        s = new text_entry_minibuffer_state(this, c, 
forward_keywords(arguments));
+        this.push_state(s);
+    }
     var result = yield SUSPEND;
     yield co_return(result);
 };
-- 
1.7.9.1

_______________________________________________
Conkeror mailing list
[email protected]
https://www.mozdev.org/mailman/listinfo/conkeror

Reply via email to