2 * (C) Copyright 2007-2008 John J. Foerch
3 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
5 * Use, modification, and distribution are subject to the terms specified in the
11 var interactive_commands = new string_hashmap();
14 * name: string name of the command.
16 * doc: Documentation string, may be null.
18 * handler: A function to handle the command.
20 * The $prefix keyword, when true, means that the command
21 * is a prefix-command.
23 define_keywords("$prefix", "$browser_object", "$prompt");
24 function interactive(name, doc, handler)
30 browser_object: arguments.$browser_object,
31 prefix: arguments.$prefix,
33 shortdoc: get_shortdoc_string(doc),
34 prompt: arguments.$prompt,
35 source_code_reference: get_caller_source_code_reference() };
37 interactive_commands.put(name, cmd);
41 function interactive_error(str) {
42 var e = new Error(str);
43 e.__proto__ = interactive_error.prototype;
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) {
65 if (e instanceof interactive_error) {
66 window.minibuffer.message(e.message);
67 } else if (e instanceof abort) {
68 window.minibuffer.message("Quit");
71 window.minibuffer.message("call interactively: " + e);
75 function call_interactively(I, command)
80 I.__proto__ = interactive_context.prototype;
84 I.buffer = I.window.buffers.current;
85 } else if (I.buffer) {
86 I.window = I.buffer.window;
89 var window = I.window;
91 if (typeof(command) == "function") {
92 // Special interactive command
97 var cmd = interactive_commands.get(command);
99 handle_interactive_error(
101 interactive_error("Invalid command: " + command));
107 // if the default is a non-null literal, it always overrides.
108 if (cmd.browser_object != null &&
109 (! (cmd.browser_object instanceof browser_object_class)))
111 I.browser_object = cmd.browser_object;
114 // if no browser-object was specified interactively, use a
115 // default, possibly specified by the page-mode.
116 if (I.browser_object == null) {
118 (I.buffer && I.buffer.default_browser_object_classes[command]) ||
122 handler = cmd.handler;
125 while (typeof(handler) == "string") {
126 let parent = interactive_commands.get(handler);
127 handler = parent.handler;
128 if (handler == command) {
129 throw (interactive_error("circular command alias, "+command));
133 var result = handler(I);
134 if (is_coroutine(result)) {
139 handle_interactive_error(window, e);
145 handle_interactive_error(window, e);
150 function alternates () {
151 let alts = Array.prototype.slice.call(arguments, 0);
152 return function (I) {
154 if (I.prefix_argument instanceof Array) {
155 let num = I.prefix_argument = I.prefix_argument[0];
156 while (num >= 4 && index + 1 < alts.length) {
161 yield alts[index](I);
167 * Utility functions for use in the rc to alter the behavior
168 * of interactive commands.
170 function set_handler (name, handler) {
171 var cmd = interactive_commands.get(name);
172 cmd.handler = handler;
175 function set_default_browser_object (name, browser_object) {
176 var cmd = interactive_commands.get(name);
177 cmd.browser_object = browser_object;