new-tabs: fix bug in tab_bar_kill_buffer
[conkeror.git] / modules / command-line.js
blobfaacc18800840b5f87013cdd14164fbf8019a947
1 /**
2  * (C) Copyright 2007-2009 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 in_module(null);
11 var command_line_handlers = [];
13 define_variable("conkeror_started", false,
14     "True if conkeror has started, false if conkeror is still starting.");
16 define_variable("url_remoting_fn", load_url_in_new_window,
17     "The function given as the value of this variable gets called for "+
18     "each datum given on the command-line not a switch or the value of "+
19     "a switch.  Such data are typically urls.  Some typical values are "+
20     "load_url_in_new_window (default), load_url_in_new_buffer, or "+
21     "load_url_in_current_buffer.");
24  * load_url_in_new_window is a function intended for use as
25  * a value of `url_remoting_fn'.  Every url given on the
26  * command line will be loaded in a new window.
27  */
28 function load_url_in_new_window (url, ctx) {
29     make_window(buffer_creator(content_buffer,
30                                $opener = ctx,
31                                $load = url));
35  * load_url_in_new_buffer is a function intended for use as
36  * a value of `url_remoting_fn'.  Every url given on the
37  * command line will be loaded in a new buffer in the most
38  * recently used window, or a new window if none exist.
39  */
40 function load_url_in_new_buffer (url, ctx) {
41     create_buffer_in_current_window(
42         buffer_creator(content_buffer,
43                        $opener = ctx,
44                        $load = url),
45         OPEN_NEW_BUFFER, true /* focus the new window */);
49  * load_url_in_new_buffer_background is a function intended for use as a
50  * value of `url_remoting_fn'.  Every url given on the command line will
51  * be loaded in a new background buffer in the most recently used window,
52  * or a new window if none exist.
53  */
54 function load_url_in_new_buffer_background (url, ctx) {
55     create_buffer_in_current_window(
56         buffer_creator(content_buffer,
57                        $opener = ctx,
58                        $load = url),
59         OPEN_NEW_BUFFER_BACKGROUND, true /* focus the new window */);
63  * load_url_in_current_buffer is a function intended for use
64  * as a value of `url_remoting_fn'.  Every url given on the
65  * command line will be loaded in the current buffer of the
66  * most recently used window.  This makes it useful for only
67  * one url at a time.  When there are no conkeror windows
68  * open, the url will be loaded in a new window.
69  */
70 function load_url_in_current_buffer (url, ctx) {
71     var win = get_recent_conkeror_window();
72     if (win) {
73         browser_object_follow(win.buffers.current, OPEN_CURRENT_BUFFER, url);
74     } else {
75         load_url_in_new_window(url, ctx);
76     }
79 function command_line_handler (name, suppress_default, handler) {
80     command_line_handlers[name] = { suppress_default: suppress_default, func: handler };
83 function command_line_param_handler (name, suppress_default, handler) {
84     command_line_handlers[name] = { suppress_default: suppress_default,
85                                     param: true,
86                                     func: handler };
89 command_line_handler("batch", true);
90 command_line_param_handler("e", true, function (expr, ctx) {
91         eval(expr);
92     });
94 command_line_param_handler("E", false, function (expr, ctx) {});
96 command_line_param_handler("chrome", true, function (uri, ctx) {
97         try {
98             make_chrome_window(uri);
99         } catch (e) { dump_error(e); }
100     });
101 command_line_param_handler("q", false, function () {
102         dumpln ("w: -q may only be used as the first argument.");
103     });
105 command_line_param_handler("f", true, function (command, ctx) {
106         // hack to make sure we send this command to a window
107         ctx.window = get_recent_conkeror_window();
108         if (ctx.window)
109             ctx.buffer = ctx.window.buffers.current;
110         co_call(call_interactively(ctx, command));
111     });
113 command_line_param_handler("l", false, function (path, ctx) {
114         try {
115             load(ctx.command_line.resolveFile(path));
116         } catch (e) {
117             dump_error(e);
118         }
119     });
121 // note `u' must be called as +u because Mozilla consumes -u
122 command_line_handler("u", false, function (ctx) {
123         // hack to make sure we send this command to a window
124         if (! ctx.window) {
125             ctx.window = get_recent_conkeror_window();
126             ctx.buffer = ctx.window.buffers.current;
127         }
128         co_call(call_interactively(ctx, "universal-argument"));
129     });
131 function handle_command_line (cmdline) {
132     try {
133         this.command_line = [];
134         for (let i = 0, clen = cmdline.length; i < clen; ++i)
135             command_line.push(cmdline.getArgument(i));
137         var suppress_default = false;
138         var suppress_rc = false;
140         var i = 0;
142         /* -q must be the first argument, if it is given */
143         if (cmdline.length > 0 && cmdline.getArgument(0) == "-q") {
144             suppress_rc = true;
145             i++;
146         }
148         var initial_launch = (cmdline.state == cmdline.STATE_INITIAL_LAUNCH);
150         if (initial_launch) {
151             let j = i;
152             while (j + 1 < cmdline.length) {
153                 if (cmdline.getArgument(j) == "-E") {
154                     eval(cmdline.getArgument(j+1));
155                     cmdline.removeArguments(j, j+1);
156                 } else
157                     ++j;
158             }
160             let load_default_modules = get_pref("conkeror.loadDefaultModules");
161             let load_mods = new RegExp("^(" + get_pref("conkeror.loadModules") + ")$");
162             try {
163                 let branch = preferences.getBranch("conkeror.load.");
164                 for each (let m in branch.getChildList("", {})) {
165                     let val;
166                     try {
167                         val = branch.getIntPref(m);
168                     } catch (e) {
169                         dumpln("Error: Preference 'conkeror.load." + m + "' has non-integer value.");
170                     }
171                     if ((val > 0 && (load_default_modules > 0 ||
172                                      ((load_default_modules == 0) && branch.prefHasUserValue(m)))) ||
173                         (val >= 0 && load_mods.test(m)))
174                         require(m + ".js");
175                 }
176             } catch (e) {dump_error(e);}
177         }
179         if (! suppress_rc && initial_launch) {
180             try {
181                 load_rc();
182             } catch (e) {
183                 dump_error(e);
184             }
185         } else if (suppress_rc && ! initial_launch) {
186             dumpln("w: attempt to suppress loading of rc in remote invocation");
187         }
188         var ctx = new interactive_context();
189         ctx.command_line = cmdline;
190         ctx.local = { cwd: cmdline.resolveFile("."),
191                       __proto__: conkeror }
193         for (let clen = cmdline.length; i < clen; ++i) {
194             var arg = cmdline.getArgument(i);
195             if (arg[0] == '-' || arg[0] == '+') {
196                 var arg1 = arg.substring(1);
197                 if (arg1 in command_line_handlers) {
198                     var handler = command_line_handlers[arg1];
199                     if (handler.suppress_default)
200                         suppress_default = true;
201                     if (handler.func) {
202                         if (handler.param) {
203                             i++; // increment the argument counter to skip the parameter
204                             if (i >= cmdline.length) {
205                                 dump("w: ignoring command switch `"+arg+"' because no argument was provided.\n");
206                                 continue;
207                             }
208                             var param = cmdline.getArgument(i);
209                             handler.func(param, ctx);
210                         } else {
211                             handler.func(ctx);
212                         }
213                     }
214                     continue;
215                 } else {
216                     dump("w: unknown command switch `"+arg+"'.\n");
217                 }
218             } else {
219                 // something other than a switch was passed on the command
220                 // line.  suppress the default window, and call the
221                 // user-configurable remoting function on it.
222                 //
223                 suppress_default = true;
224                 url_remoting_fn(arg, ctx);
225             }
226         }
228         // we are greedy and handle all command line arguments.  remove
229         // everything from the command line object, so no other
230         // components can see them.
231         //
232         if (cmdline.length > 0) {
233             cmdline.removeArguments(0, cmdline.length - 1);
234         }
236         // no args were found for url_remoting_fn, and no switches
237         // explicitly suppressed the creation of a default window
238         // (e.g. -batch or -daemon)
239         //
240         if (! suppress_default) {
241             url_remoting_fn(homepage, ctx);
242         }
243     } catch (e) {
244         dumpln("Error processing command line.");
245         dump_error(e);
246     }
247     conkeror_started = true;
250 provide("command-line");