rename browser-follow-next/previous to follow-next/previous
[conkeror.git] / modules / interactive.js
blobd68ca5dd25a26d2d0e4d23b16878cbe8881fa5cf
1 /**
2  * (C) Copyright 2007-2008 John J. Foerch
3  * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
4  *
5  * Use, modification, and distribution are subject to the terms specified in the
6  * COPYING file.
7 **/
9 require("utils.js");
11 var interactive_commands = new string_hashmap();
13 /**
14  * First argument is the command name.
15  *
16  * This is optionally followed by a documentation string.
17  *
18  * This is followed by the command function.
19  */
20 function interactive(name)
22     var doc = null;
23     var handler;
24     var offset = 1;
25     if (typeof(arguments[1]) == "string" || arguments[1] == null)
26     {
27         doc = arguments[1];
28         offset = 2;
29     }
30     handler = arguments[offset++];
31     var cmd = {
32         name: name,
33         handler: handler,
34         doc: doc,
35         shortdoc: get_shortdoc_string(doc),
36         source_code_reference: get_caller_source_code_reference() };
38     interactive_commands.put(name, cmd);
41 function interactive_error(str) {
42     var e = new Error(str);
43     e.__proto__ = interactive_error.prototype;
44     return e;
46 interactive_error.prototype.__proto__ = Error.prototype;
48 function interactive_context() {}
49 interactive_context.prototype = {
51     get P () this.prefix_argument,
53     get p () univ_arg_to_number(this.prefix_argument),
55     set p (default_value) univ_arg_to_number(this.prefix_argument, default_value),
57     get minibuffer () this.window.minibuffer,
59     get : function (x) this.buffer.get(x)
62 function handle_interactive_error(window, e) {
63     if (e instanceof interactive_error)
64         window.minibuffer.message(e.message);
65     else if (e instanceof abort)
66         window.minibuffer.message("Quit");
67     else {
68         dump_error(e);
69         window.minibuffer.message("call interactively: " + e);
70     }
73 // Any additional arguments specify "given" arguments to the function.
74 function call_interactively(I, command)
76     var handler;
77     var top_args;
79     I.__proto__ = interactive_context.prototype;
81     if (I.buffer == null)
82         I.buffer = I.window.buffers.current;
83     else if (I.window == null)
84         I.window = I.buffer.window;
86     var window = I.window;
88     if (typeof(command) == "function") {
89         // Special interactive command
90         command(I);
91         return;
92     }
94     var cmd = interactive_commands.get(command);
95     if (!cmd)
96     {
97         window.minibuffer.message("Invalid command: " + command);
98         return;
99     }
101     I.command = command;
103     var handler = cmd.handler;
105     try {
106         var result = handler(I);
107         if (is_coroutine(result)) {
108             co_call(function() {
109                 try {
110                     yield result;
111                 } catch (e) {
112                     handle_interactive_error(window, e);
113                 }
114             }());
115         }
116     } catch (e)
117     {
118         handle_interactive_error(window, e);
119     }
123 I.f = interactive_method(
124     $doc = "Existing file",
125     $async = function (ctx, cont) {
126         keywords(arguments, $prompt = "File:", $initial_value = default_directory.path,
127                  $history = "file");
128         ctx.window.minibuffer.read(
129             $prompt = arguments.$prompt,
130             $initial_value = arguments.$initial_value,
131             $history = arguments.$history,
132             $callback = function(s) {
133                 var f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
134                 f.initWithPath(s);
135                 cont(f);
136             });
137     });
139 // FIXME: eventually they will differ, when completion for files is added
140 I.F = I.f;