diff --git a/common/components/protocols.js b/common/components/protocols.js index f070b2e2..5f346eb4 100644 --- a/common/components/protocols.js +++ b/common/components/protocols.js @@ -46,27 +46,6 @@ function redirect(to, orig, time) { return makeChannel(dataURL('text/html', html), ioService.newURI(to, null, null)); } -function AboutHandler() {} -AboutHandler.prototype = { - - classDescription: "About " + Dactyl.prototype.name + " Page", - - classID: Components.ID("81495d80-89ee-4c36-a88d-ea7c4e5ac63f"), - - contractID: "@mozilla.org/network/protocol/about;1?what=" + Dactyl.prototype.appname, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), - - newChannel: function (uri) { - let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService) - .newChannel("chrome://dactyl/content/about.xul", null, null); - channel.originalURI = uri; - return channel; - }, - - getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT, -}; - function ChromeData() {} ChromeData.prototype = { contractID: "@mozilla.org/network/protocol;1?name=chrome-data", @@ -178,6 +157,27 @@ Dactyl.prototype = { } }; +function AboutHandler() {} +AboutHandler.prototype = { + + classDescription: "About " + Dactyl.prototype.name + " Page", + + classID: Components.ID("81495d80-89ee-4c36-a88d-ea7c4e5ac63f"), + + contractID: "@mozilla.org/network/protocol/about;1?what=" + Dactyl.prototype.appname, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), + + newChannel: function (uri) { + let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService) + .newChannel("chrome://dactyl/content/about.xul", null, null); + channel.originalURI = uri; + return channel; + }, + + getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT, +}; + // A hack to get infermation about interfaces. // Doesn't belong here. function Shim() {} diff --git a/common/content/buffer.js b/common/content/buffer.js index 93b1a6aa..3765f7b0 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -670,7 +670,7 @@ const Buffer = Module("buffer", { try { window.urlSecurityCheck(url, doc.nodePrincipal); // we always want to save that link relative to the current working directory - options.setPref("browser.download.lastDir", io.getCurrentDirectory().path); + options.setPref("browser.download.lastDir", io.cwd); window.saveURL(url, text, null, true, skipPrompt, makeURI(url, doc.characterSet)); } catch (e) { @@ -1232,7 +1232,7 @@ const Buffer = Module("buffer", { // if browser.download.useDownloadDir = false then the "Save As" // dialog is used with this as the default directory // TODO: if we're going to do this shouldn't it be done in setCWD or the value restored? - options.setPref("browser.download.lastDir", io.getCurrentDirectory().path); + options.setPref("browser.download.lastDir", io.cwd); try { var contentDisposition = window.content diff --git a/common/content/dactyl.js b/common/content/dactyl.js index 2c042952..8932712b 100644 --- a/common/content/dactyl.js +++ b/common/content/dactyl.js @@ -2046,7 +2046,7 @@ const Dactyl = Module("dactyl", { } if (options["exrc"] && !dactyl.commandLineOptions.rcFile) { - let localRCFile = io.getRCFile(io.getCurrentDirectory().path); + let localRCFile = io.getRCFile(io.cwd); if (localRCFile && !localRCFile.equals(rcFile)) io.source(localRCFile.path, true); } diff --git a/common/content/io.js b/common/content/io.js index 060bfd1c..ec2076e8 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -39,7 +39,7 @@ function Script(file) { const IO = Module("io", { init: function () { this._processDir = services.get("directory").get("CurWorkD", Ci.nsIFile); - this._cwd = this._processDir; + this._cwd = this._processDir.path; this._oldcwd = null; this._lastRunCommand = ""; // updated whenever the users runs a command with :! @@ -66,6 +66,50 @@ const IO = Module("io", { services.get("downloadManager").addListener(this.downloadListener); }, + + // TODO: there seems to be no way, short of a new component, to change + // the process's CWD - see https://bugzilla.mozilla.org/show_bug.cgi?id=280953 + /** + * Returns the current working directory. + * + * It's not possible to change the real CWD of the process so this + * state is maintained internally. External commands run via + * {@link #system} are executed in this directory. + * + * @returns {nsIFile} + */ + get cwd() { + let dir = File(this._cwd); + + // NOTE: the directory could have been deleted underneath us so + // fallback to the process's CWD + if (dir.exists() && dir.isDirectory()) + return dir.path; + else + return this._processDir.path; + }, + + /** + * Sets the current working directory. + * + * @param {string} newDir The new CWD. This may be a relative or + * absolute path and is expanded by {@link #expandPath}. + */ + set cwd(newDir) { + newDir = newDir || "~"; + + if (newDir == "-") { + dactyl.assert(this._oldcwd != null, "E186: No previous directory"); + [this._cwd, this._oldcwd] = [this._oldcwd, this.cwd]; + } + else { + let dir = io.File(newDir); + dactyl.assert(dir.exists() && dir.isDirectory(), "E344: Can't find directory " + dir.path.quote()); + [this._cwd, this._oldcwd] = [dir.path, this.cwd]; + } + return this.cwd; + }, + destroy: function () { services.get("downloadManager").removeListener(this.downloadListener); for (let [, plugin] in Iterator(plugins.contexts)) @@ -79,7 +123,7 @@ const IO = Module("io", { */ File: Class("File", File, { init: function init(path, checkCWD) - init.supercall(this, path, (arguments.length < 2 || checkCWD) && io.getCurrentDirectory()) + init.supercall(this, path, (arguments.length < 2 || checkCWD) && io.cwd) }), /** @@ -106,53 +150,6 @@ const IO = Module("io", { */ expandPath: File.expandPath, - // TODO: there seems to be no way, short of a new component, to change - // the process's CWD - see https://bugzilla.mozilla.org/show_bug.cgi?id=280953 - /** - * Returns the current working directory. - * - * It's not possible to change the real CWD of the process so this - * state is maintained internally. External commands run via - * {@link #system} are executed in this directory. - * - * @returns {nsIFile} - */ - getCurrentDirectory: function () { - let dir = File(this._cwd.path); - - // NOTE: the directory could have been deleted underneath us so - // fallback to the process's CWD - if (dir.exists() && dir.isDirectory()) - return dir; - else - return this._processDir; - }, - - /** - * Sets the current working directory. - * - * @param {string} newDir The new CWD. This may be a relative or - * absolute path and is expanded by {@link #expandPath}. - */ - setCurrentDirectory: function (newDir) { - newDir = newDir || "~"; - - if (newDir == "-") - [this._cwd, this._oldcwd] = [this._oldcwd, this.getCurrentDirectory()]; - else { - let dir = io.File(newDir); - - if (!dir.exists() || !dir.isDirectory()) { - dactyl.echoerr("E344: Can't find directory " + dir.path.quote()); - return null; - } - - [this._cwd, this._oldcwd] = [dir, this.getCurrentDirectory()]; - } - - return this.getCurrentDirectory(); // XXX - }, - /** * Returns all directories named name in 'runtimepath'. * @@ -160,9 +157,9 @@ const IO = Module("io", { * @returns {nsIFile[]) */ getRuntimeDirectories: function (name) { - let dirs = File.getPathsFromPathList(options["runtimepath"]); + let dirs = options.get("runtimepath").values; - dirs = dirs.map(function (dir) File.joinPaths(dir, name)) + dirs = dirs.map(function (dir) File.joinPaths(dir, name, this.cwd)) .filter(function (dir) dir.exists() && dir.isDirectory() && dir.isReadable()); return dirs; }, @@ -179,8 +176,8 @@ const IO = Module("io", { getRCFile: function (dir, always) { dir = dir || "~"; - let rcFile1 = File.joinPaths(dir, "." + config.name + "rc"); - let rcFile2 = File.joinPaths(dir, "_" + config.name + "rc"); + let rcFile1 = File.joinPaths(dir, "." + config.name + "rc", this.cwd); + let rcFile2 = File.joinPaths(dir, "_" + config.name + "rc", this.cwd); if (dactyl.has("WINNT")) [rcFile1, rcFile2] = [rcFile2, rcFile1]; @@ -229,11 +226,11 @@ const IO = Module("io", { let dirs = services.get("environment").get("PATH").split(dactyl.has("WINNT") ? ";" : ":"); // Windows tries the CWD first TODO: desirable? if (dactyl.has("WINNT")) - dirs = [io.getCurrentDirectory().path].concat(dirs); + dirs = [io.cwd].concat(dirs); lookup: for (let [, dir] in Iterator(dirs)) { - file = File.joinPaths(dir, program); + file = File.joinPaths(dir, program, io.cwd); try { if (file.exists()) break; @@ -243,7 +240,7 @@ lookup: if (dactyl.has("WINNT")) { let extensions = services.get("environment").get("PATHEXT").split(";"); for (let [, extension] in Iterator(extensions)) { - file = File.joinPaths(dir, program + extension); + file = File.joinPaths(dir, program + extension, io.cwd); if (file.exists()) break lookup; } @@ -278,7 +275,7 @@ lookup: * @param {boolean} all Whether all found files should be sourced. */ sourceFromRuntimePath: function (paths, all) { - let dirs = File.getPathsFromPathList(options["runtimepath"]); + let dirs = options.get("runtimepath").values; let found = false; dactyl.echomsg("Searching for " + paths.join(" ").quote() + " in " + options["runtimepath"].quote(), 2); @@ -286,7 +283,7 @@ lookup: outer: for (let [, dir] in Iterator(dirs)) { for (let [, path] in Iterator(paths)) { - let file = File.joinPaths(dir, path); + let file = File.joinPaths(dir, path, this.cwd); dactyl.echomsg("Searching for " + file.path.quote(), 3); @@ -460,11 +457,11 @@ lookup: // TODO: implement 'shellredir' if (dactyl.has("WINNT")) { - command = "cd /D " + this._cwd.path + " && " + command + " > " + stdout.path + " 2>&1" + " < " + stdin.path; + command = "cd /D " + this.cwd + " && " + command + " > " + stdout.path + " 2>&1" + " < " + stdin.path; var res = this.run(options["shell"], options["shellcmdflag"].split(/\s+/).concat(command), true); } else { - cmd.write("cd " + escape(this._cwd.path) + "\n" + + cmd.write("cd " + escape(this.cwd) + "\n" + ["exec", ">" + escape(stdout.path), "2>&1", "<" + escape(stdin.path), escape(options["shell"]), options["shellcmdflag"], escape(command)].join(" ")); res = this.run("/bin/sh", ["-e", cmd.path], true); @@ -532,10 +529,6 @@ lookup: if (!arg) arg = "~"; - else if (arg == "-") { - dactyl.assert(io._oldcwd, "E186: No previous directory"); - arg = io._oldcwd.path; - } arg = File.expandPath(arg); @@ -543,28 +536,23 @@ lookup: // match in 'cdpath' // TODO: handle ../ and ./ paths if (File.isAbsolutePath(arg)) { - if (io.setCurrentDirectory(arg)) - dactyl.echomsg(io.getCurrentDirectory().path); + io.cwd = arg; + dactyl.echomsg(io.cwd); } else { - let dirs = File.getPathsFromPathList(options["cdpath"]); - let found = false; - + let dirs = options.get("cdpath").values; for (let [, dir] in Iterator(dirs)) { - dir = File.joinPaths(dir, arg); + dir = File.joinPaths(dir, arg, io.cwd); if (dir.exists() && dir.isDirectory() && dir.isReadable()) { - io.setCurrentDirectory(dir.path); - dactyl.echomsg(io.getCurrentDirectory().path); - found = true; - break; + io.cwd = dir.path; + dactyl.echomsg(io.cwd); + return; } } - if (!found) { - dactyl.echoerr("E344: Can't find directory " + arg.quote() + " in cdpath\n" - + "E472: Command failed"); - } + dactyl.echoerr("E344: Can't find directory " + arg.quote() + " in cdpath"); + dactyl.echoerr("E472: Command failed"); } }, { argCount: "?", @@ -580,7 +568,7 @@ lookup: commands.add(["pw[d]"], "Print the current directory name", - function () { dactyl.echomsg(io.getCurrentDirectory().path); }, + function () { dactyl.echomsg(io.cwd); }, { argCount: "0" }); commands.add([config.name.replace(/(.)(.*)/, "mk$1[$2rc]")], @@ -804,7 +792,7 @@ lookup: }); options.add(["cdpath", "cd"], "List of directories searched when executing :cd", - "stringlist", "," + (services.get("environment").get("CDPATH").replace(/[:;]/g, ",") || ","), + "stringlist", ["."].concat(services.get("environment").get("CDPATH").split(/[:;]/).filter(util.identity)).join(","), { setter: function (value) File.expandPathList(value) }); options.add(["runtimepath", "rtp"], diff --git a/common/locale/en-US/options.xml b/common/locale/en-US/options.xml index 8cab4094..599967f1 100644 --- a/common/locale/en-US/options.xml +++ b/common/locale/en-US/options.xml @@ -388,7 +388,7 @@ 'cd' 'cdpath' 'cdpath' 'cd' string - equivalent to $CDPATH or ,, + equivalent to $CDPATH or .

List of directories searched when executing the :cd diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index 11c9a119..00f6e1d4 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -532,14 +532,6 @@ const File = Class("File", { expandPathList: function (list) list.map(this.expandPath), - getPathsFromPathList: function (list) { - if (!list) - return []; - // empty list item means the current directory - return list.replace(/,$/, "").split(",") - .map(function (dir) dir == "" ? io.getCurrentDirectory().path : dir); - }, - isAbsolutePath: function (path) { try { services.create("file").initWithPath(path); @@ -550,11 +542,12 @@ const File = Class("File", { } }, - joinPaths: function (head, tail) { - let path = this(head); + joinPaths: function (head, tail, cwd) { + let path = this(head, cwd); try { // FIXME: should only expand env vars and normalise path separators path.appendRelativePath(this.expandPath(tail, true)); + path.normalize(); } catch (e) { return { exists: function () false, __noSuchMethod__: function () { throw e; } }; diff --git a/pentadactyl/NEWS b/pentadactyl/NEWS index 8a78e6e0..180321e1 100644 --- a/pentadactyl/NEWS +++ b/pentadactyl/NEWS @@ -1,7 +1,7 @@ 1.0b1: * Extensive Firefox 4 support, including: - Tabs in :buffer completions and listings are grouped - by panorama groups + by panorama groups. - Only visible tabs are considered in tab numbering, gt/gn/gN, etc. * Improved startup time by a factor of 7. @@ -19,16 +19,18 @@ backspace. - Supports reverse incremental search. * IMPORTANT: Plugins are now loaded from the 'plugins/' - directory in 'runtimepath' rather than 'plugin/' - * IMPORTANT: Single quotes no longer treat \s specially + directory in 'runtimepath' rather than 'plugin/'. + * IMPORTANT: Single quotes no longer treat \s specially. I.e., 'fo\o''bar' ≡ fo\o'bar + * IMPORTANT: 'cdpath' no longer treats ‘,,’ specially. Use ‘.’ + instead. * Replaced 'focuscontent' with 'strictfocus' - * Added 'hintkeys' option - * Added 'altwildmode' and commandline key binding - * Added 'banghist' option + * Added 'hintkeys' option. + * Added 'altwildmode' and commandline key binding. + * Added 'banghist' option. * Added ‘transliterated’ option to 'hintmatching' * Added 'autocomplete' option for specifying which completion - contexts should be autocompleted + groups should be auto-completed. * Added -javascript option to :abbrev and :map * Added several new options to :map * Removed the :source line at the end of files generated by @@ -42,15 +44,15 @@ triggers when the URL begins as above. * Page zoom information is now shown in the status bar, and change in zoom status no longer appears in :messages. - * Added ZO, ZI, ZM, and ZR as aliases for zO, zI, zM, and zR + * Added ZO, ZI, ZM, and ZR as aliases for zO, zI, zM, and zR. * Completion list now behaves better when the multi-line output - window is displayed + window is displayed. * Major help system improvements: - - Plugins may now provide full-fledged ':help' documentation - - Add basic plugin authorship documentation + - Plugins may now provide full-fledged ':help' documentation. + - Add basic plugin authorship documentation. - The help system is newly modularized and features significant updates, rewrites, and formatting improvements. * Remove :edit, :tabedit, and :winedit aliases. - * Add 'jsdebugger' option - switch on/off javascript debugger service + * Add 'jsdebugger' option - switch on/off javascript debugger service. * Add "addons", "downloads", "extoptions" and "help" to the 'activate' option. diff --git a/pentadactyl/TODO b/pentadactyl/TODO index 0bb4aaf5..bb40b9a1 100644 --- a/pentadactyl/TODO +++ b/pentadactyl/TODO @@ -26,6 +26,7 @@ BUGS: (recent Mercurial regressions): 9 One of the recent completion fixes seems to have broken the caret position update. BLOCKER. +9 about:pentadactyl is currently about:undefined - visual caret mode is broken, requires a manual page focus first anyway or else it chucks, I haven't investigated --djk diff --git a/pentadactyl/chrome.manifest b/pentadactyl/chrome.manifest index 576e4d0d..e4a37883 100644 --- a/pentadactyl/chrome.manifest +++ b/pentadactyl/chrome.manifest @@ -18,8 +18,8 @@ component {8e4a8e2f-95a0-4d8f-90ac-fc9d7d8f5468} components/dactyl.js contract @dactyl.googlecode.com/base/dactyl {8e4a8e2f-95a0-4d8f-90ac-fc9d7d8f5468} component {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} components/commandline-handler.js -contract @mozilla.org/commandlinehandler/general-startup;1?type=pentadactyl {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} -category command-line-handler m-pentadactyl @mozilla.org/commandlinehandler/general-startup;1?type=pentadactyl +contract @mozilla.org/commandlinehandler/general-startup;1?type=dactyl {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} +category command-line-handler m-dactyl @mozilla.org/commandlinehandler/general-startup;1?type=dactyl component {c1b67a07-18f7-4e13-b361-2edcc35a5a0d} components/protocols.js contract @mozilla.org/network/protocol;1?name=chrome-data {c1b67a07-18f7-4e13-b361-2edcc35a5a0d} diff --git a/teledactyl/chrome.manifest b/teledactyl/chrome.manifest index 9e3bbe93..f2f6b9dc 100644 --- a/teledactyl/chrome.manifest +++ b/teledactyl/chrome.manifest @@ -20,8 +20,8 @@ component {8e4a8e2f-95a0-4d8f-90ac-fc9d7d8f5468} components/dactyl.js contract @dactyl.googlecode.com/base/dactyl {8e4a8e2f-95a0-4d8f-90ac-fc9d7d8f5468} component {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} components/commandline-handler.js -contract @mozilla.org/commandlinehandler/general-startup;1?type=teledactyl {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} -category command-line-handler m-teledactyl @mozilla.org/commandlinehandler/general-startup;1?type=pentadactyl +contract @mozilla.org/commandlinehandler/general-startup;1?type=dactyl {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} +category command-line-handler m-dactyl @mozilla.org/commandlinehandler/general-startup;1?type=dactyl component {c1b67a07-18f7-4e13-b361-2edcc35a5a0d} components/protocols.js contract @mozilla.org/network/protocol;1?name=chrome-data {c1b67a07-18f7-4e13-b361-2edcc35a5a0d} diff --git a/xulmus/chrome.manifest b/xulmus/chrome.manifest index ea07f1b5..7dd16f5a 100644 --- a/xulmus/chrome.manifest +++ b/xulmus/chrome.manifest @@ -18,8 +18,8 @@ component {8e4a8e2f-95a0-4d8f-90ac-fc9d7d8f5468} components/dactyl.js contract @dactyl.googlecode.com/base/dactyl {8e4a8e2f-95a0-4d8f-90ac-fc9d7d8f5468} component {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} components/commandline-handler.js -contract @mozilla.org/commandlinehandler/general-startup;1?type=xulmus {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} -category command-line-handler m-xulmus @mozilla.org/commandlinehandler/general-startup;1?type=pentadactyl +contract @mozilla.org/commandlinehandler/general-startup;1?type=mus {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} +category command-line-handler m-dactyl @mozilla.org/commandlinehandler/general-startup;1?type=dactyl component {c1b67a07-18f7-4e13-b361-2edcc35a5a0d} components/protocols.js contract @mozilla.org/network/protocol;1?name=chrome-data {c1b67a07-18f7-4e13-b361-2edcc35a5a0d}