Add initial OpenSearch search engine support
[conkeror.git] / modules / interactive.js
blobeab1b8ed59ae096567068b7595adffd0c7988057
1 require("utils.js");
3 var interactive_commands = new string_hashmap();
5 /**
6  * First argument is the command name.
7  *
8  * This is optionally followed by a documentation string.
9  *
10  * This is followed by the command function.
11  */
12 function interactive(name)
14     var doc = null;
15     var handler;
16     var offset = 1;
17     if (typeof(arguments[1]) == "string" || arguments[1] == null)
18     {
19         doc = arguments[1];
20         offset = 2;
21     }
22     handler = arguments[offset++];
23     var cmd = {
24         name: name,
25         handler: handler,
26         doc: doc,
27         shortdoc: get_shortdoc_string(doc),
28         source_code_reference: get_caller_source_code_reference() };
30     interactive_commands.put(name, cmd);
33 function interactive_error(str) {
34     var e = new Error(str);
35     e.__proto__ = interactive_error.prototype;
36     return e;
38 interactive_error.prototype.__proto__ = Error.prototype;
40 function interactive_context() {}
41 interactive_context.prototype = {
43     get P () this.prefix_argument,
45     get p () univ_arg_to_number(this.prefix_argument),
47     set p (default_value) univ_arg_to_number(this.prefix_argument, default_value),
49     get minibuffer () this.window.minibuffer,
51     get : function (x) this.buffer.get(x)
54 function handle_interactive_error(window, e) {
55     if (e instanceof interactive_error)
56         window.minibuffer.message(e.message);
57     else if (e instanceof abort)
58         window.minibuffer.message("Quit");
59     else {
60         dump_error(e);
61         window.minibuffer.message("call interactively: " + e);
62     }
65 // Any additional arguments specify "given" arguments to the function.
66 function call_interactively(I, command)
68     var handler;
69     var top_args;
71     I.__proto__ = interactive_context.prototype;
73     if (I.buffer == null)
74         I.buffer = I.window.buffers.current;
75     else if (I.window == null)
76         I.window = I.buffer.window;
78     var window = I.window;
80     if (typeof(command) == "function") {
81         // Special interactive command
82         command(I);
83         return;
84     }
86     var cmd = interactive_commands.get(command);
87     if (!cmd)
88     {
89         window.minibuffer.message("Invalid command: " + command);
90         return;
91     }
93     I.command = command;
95     var handler = cmd.handler;
96     
97     try {
98         var result = handler(I);
99         if (is_coroutine(result)) {
100             co_call(function() {
101                 try {
102                     yield result;
103                 } catch (e) {
104                     handle_interactive_error(window, e);
105                 }
106             }());
107         }
108     } catch (e)
109     {
110         handle_interactive_error(window, e);
111     }
115 I.f = interactive_method(
116     $doc = "Existing file",
117     $async = function (ctx, cont) {
118         keywords(arguments, $prompt = "File:", $initial_value = default_directory.path,
119                  $history = "file");
120         ctx.window.minibuffer.read(
121             $prompt = arguments.$prompt,
122             $initial_value = arguments.$initial_value,
123             $history = arguments.$history,
124             $callback = function(s) {
125                 var f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
126                 f.initWithPath(s);
127                 cont(f);
128             });
129     });
131 // FIXME: eventually they will differ, when completion for files is added
132 I.F = I.f;