X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=common%2Fmodules%2Fio.jsm;h=9e717d74ed51ebd217ea017e821b017e7a7ef7c7;hb=8b6fcae7eaa413bc62d645d2d0c99835c47265e6;hp=5eefcc17b6bb6aeaceecae247a49df9035a36846;hpb=9044153cb63835e39b9de8ec4ade237c03e3888a;p=dactyl.git diff --git a/common/modules/io.jsm b/common/modules/io.jsm index 5eefcc1..9e717d7 100644 --- a/common/modules/io.jsm +++ b/common/modules/io.jsm @@ -1,22 +1,24 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott -// Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2011 by Kris Maglione +// Copyright (c) 2007-2012 by Doug Kearns +// Copyright (c) 2008-2012 Kris Maglione // Some code based on Venkman // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. -/* use strict */ +"use strict"; try { -Components.utils.import("resource://dactyl/bootstrap.jsm"); defineModule("io", { exports: ["IO", "io"], require: ["services"] -}, this); +}); -this.lazyRequire("config", ["config"]); -this.lazyRequire("contexts", ["Contexts", "contexts"]); +lazyRequire("config", ["config"]); +lazyRequire("contexts", ["Contexts", "contexts"]); +lazyRequire("storage", ["File", "storage"]); +lazyRequire("styles", ["styles"]); +lazyRequire("template", ["template"]); // TODO: why are we passing around strings rather than file objects? /** @@ -41,26 +43,6 @@ var IO = Module("io", { this._lastRunCommand = ""; // updated whenever the users runs a command with :! this._scriptNames = []; - - this.downloadListener = { - onDownloadStateChange: function (state, download) { - if (download.state == services.downloadManager.DOWNLOAD_FINISHED) { - let url = download.source.spec; - let title = download.displayName; - let file = download.targetFile.path; - let size = download.size; - - dactyl.echomsg({ domains: [util.getHost(url)], message: _("io.downloadFinished", title, file) }, - 1, modules.commandline.ACTIVE_WINDOW); - modules.autocommands.trigger("DownloadPost", { url: url, title: title, file: file, size: size }); - } - }, - onStateChange: function () {}, - onProgressChange: function () {}, - onSecurityChange: function () {} - }; - - services.downloadManager.addListener(this.downloadListener); }, CommandFileMode: Class("CommandFileMode", modules.CommandMode, { @@ -84,10 +66,6 @@ var IO = Module("io", { } }), - destroy: function destroy() { - services.downloadManager.removeListener(this.downloadListener); - }, - /** * Returns all directories named *name* in 'runtimepath'. * @@ -173,7 +151,7 @@ var IO = Module("io", { dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); } - if (/\.js,$/.test(filename)) + if (/\.jsm$/.test(filename)) sourceJSM(); else if (/\.js$/.test(filename)) { try { @@ -190,12 +168,14 @@ var IO = Module("io", { sourceJSM(); } else { + if (e instanceof Finished) + return; if (e.fileName && !(e instanceof FailedAssertion)) try { e.fileName = util.fixURI(e.fileName); if (e.fileName == uri.spec) e.fileName = filename; - e.echoerr = <>{e.fileName}:{e.lineNumber}: {e}; + e.echoerr = [e.fileName, ":", e.lineNumber, ": ", e].join(""); } catch (e) {} throw e; @@ -331,14 +311,19 @@ var IO = Module("io", { * * @returns {File} */ - createTempFile: function createTempFile(name) { - if (name instanceof Ci.nsIFile) + createTempFile: function createTempFile(name, type) { + if (name instanceof Ci.nsIFile) { var file = name.clone(); + if (!type || type == "file") + file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, octal(666)); + else + file.createUnique(Ci.nsIFile.DIRECTORY_TYPE, octal(777)); + } else { file = services.directory.get("TmpD", Ci.nsIFile); file.append(this.config.tempFile + (name ? "." + name : "")); + file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, octal(666)); } - file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, octal(600)); services.externalApp.deleteTemporaryFileOnExit(file); @@ -378,7 +363,7 @@ var IO = Module("io", { file = util.getFile(file); if (file && file.exists() && file.isFile() && file.isReadable()) { // let jar = services.zipReader.getZip(file); Crashes. - let jar = services.ZipReader(file); + let jar = services.ZipReader(file.file); try { let filter = RegExp("^" + util.regexp.escape(decodeURI(path)) + "[^/]*/?$"); @@ -414,7 +399,8 @@ var IO = Module("io", { if (bin instanceof File || File.isAbsolutePath(bin)) return this.File(bin); - let dirs = services.environment.get("PATH").split(config.OS.isWindows ? ";" : ":"); + let dirs = services.environment.get("PATH") + .split(config.OS.pathListSep); // Windows tries the CWD first TODO: desirable? if (config.OS.isWindows) dirs = [io.cwd].concat(dirs); @@ -460,7 +446,7 @@ var IO = Module("io", { return -1; } - let process = services.Process(file); + let process = services.Process(file.file); process.run(false, args.map(String), args.length); try { if (callable(blocking)) @@ -487,10 +473,12 @@ var IO = Module("io", { // TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is // fixed use that instead of a tmpfile /** - * Runs *command* in a subshell and returns the output in a string. The - * shell used is that specified by the 'shell' option. + * Runs *command* in a subshell and returns the output. The shell used is + * that specified by the 'shell' option. * - * @param {string} command The command to run. + * @param {string|[string]} command The command to run. This can be a shell + * command string or an array of strings (a command and arguments) + * which will be escaped and concatenated. * @param {string} input Any input to be provided to the command on stdin. * @param {function(object)} callback A callback to be called when * the command completes. @optional @@ -556,7 +544,8 @@ var IO = Module("io", { * otherwise, the return value of *func*. */ withTempFiles: function withTempFiles(func, self, checked, ext) { - let args = array(util.range(0, func.length)).map(bind("createTempFile", this, ext)).array; + let args = array(util.range(0, func.length)) + .map(bind("createTempFile", this, ext)).array; try { if (!args.every(util.identity)) return false; @@ -588,7 +577,7 @@ var IO = Module("io", { */ PATH_SEP: deprecated("File.PATH_SEP", { get: function PATH_SEP() File.PATH_SEP }) }, { - commands: function init_commands(dactyl, modules, window) { + commands: function initCommands(dactyl, modules, window) { const { commands, completion, io } = modules; commands.add(["cd", "chd[ir]"], @@ -651,6 +640,7 @@ var IO = Module("io", { try { file.write(lines.join("\n")); + dactyl.echomsg(_("io.writing", file.path.quote()), 2); } catch (e) { dactyl.echoerr(_("io.notWriteable", file.path.quote())); @@ -662,24 +652,65 @@ var IO = Module("io", { completer: function (context) completion.file(context, true) }); - commands.add(["mks[yntax]"], - "Generate a Vim syntax file", + commands.add(["mkv[imruntime]"], + "Create and install Vim runtime files for " + config.appName, function (args) { - let runtime = config.OS.isWindows ? "~/vimfiles/" : "~/.vim/"; - let file = io.File(runtime + "syntax/" + config.name + ".vim"); - if (args.length) - file = io.File(args[0]); + dactyl.assert(args.length <= 1, _("io.oneFileAllowed")); + + if (args.length) { + var rtDir = io.File(args[0]); + dactyl.assert(rtDir.exists(), _("io.noSuchDir", rtDir.path.quote())); + } + else + rtDir = io.File(config.OS.isWindows ? "~/vimfiles/" : "~/.vim/"); + + dactyl.assert(!rtDir.exists() || rtDir.isDirectory(), _("io.eNotDir", rtDir.path.quote())); + + let rtItems = { ftdetect: {}, ftplugin: {}, syntax: {} }; + + // require bang if any of the paths exist + for (let [type, item] in iter(rtItems)) { + let file = io.File(rtDir).child(type, config.name + ".vim"); + dactyl.assert(!file.exists() || args.bang, _("io.exists", file.path.quote())); + item.file = file; + } + + rtItems.ftdetect.template = // {{{ +literal(/*" Vim filetype detection file +
+ +au BufNewFile,BufRead *rc*,*. set filetype= +*/);//}}} + rtItems.ftplugin.template = // {{{ +literal(/*" Vim filetype plugin file +
- if (file.exists() && file.isDirectory() || args[0] && /\/$/.test(args[0])) - file.append(config.name + ".vim"); - dactyl.assert(!file.exists() || args.bang, _("io.exists")); +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim - let template = util.compileMacro( +let b:undo_ftplugin = "setl com< cms< fo< ofu< | unlet! b:browsefilter" -" TODO: make this specific - shared dactyl config? +setlocal comments=:\" +setlocal commentstring=\"%s +setlocal formatoptions-=t formatoptions+=croql +setlocal omnifunc=syntaxcomplete#Complete + +if has("gui_win32") && !exists("b:browsefilter") + let b:browsefilter = " Config Files (*.)\t*.\n" . + \ "All Files (*.*)\t*.*\n" +endif + +let &cpo = s:cpo_save +unlet s:cpo_save +*/);//}}} + rtItems.syntax.template = // {{{ +literal(/*" Vim syntax file +
if exists("b:current_syntax") finish @@ -756,11 +787,13 @@ let b:current_syntax = "" let &cpo = s:cpo_save unlet s:cpo_save -" vim: tw=130 et ts=4 sw=4: -]]>, true); +" vim: tw=130 et ts=8 sts=4 sw=4: +*/);//}}} + + const { options } = modules; const WIDTH = 80; - function wrap(prefix, items, sep) { + function wrap(prefix, items, sep) {//{{{ sep = sep || " "; let width = 0; let lines = []; @@ -777,11 +810,16 @@ unlet s:cpo_save } lines.last.pop(); return lines.map(function (l) l.join("")).join("\n").replace(/\s+\n/gm, "\n"); - } + }//}}} - const { commands, options } = modules; - file.write(template({ + let params = { // {{{ + header: ['" Language: ' + config.appName + ' configuration file', + '" Maintainer: Doug Kearns ', + '" Version: ' + config.version].join("\n"), name: config.name, + appname: config.appName, + fileext: config.fileExtension, + maintainer: "Doug Kearns ", autocommands: wrap("syn keyword " + config.name + "AutoEvent ", keys(config.autocommands)), commands: wrap("syn keyword " + config.name + "Command ", @@ -792,11 +830,22 @@ unlet s:cpo_save array(o.realNames for (o in options) if (o.type == "boolean")) .flatten().map(String.quote), ", ") + "]" - })); + }; // }}} + + for (let { file, template } in values(rtItems)) { + try { + file.write(util.compileMacro(template, true)(params)); + dactyl.echomsg(_("io.writing", file.path.quote()), 2); + } + catch (e) { + dactyl.echoerr(_("io.notWriteable", file.path.quote())); + dactyl.log(_("error.notWriteable", file.path, e.message)); + } + } }, { argCount: "?", bang: true, - completer: function (context) completion.file(context, true), + completer: function (context) completion.directory(context, true), literal: 1 }); @@ -869,7 +918,7 @@ unlet s:cpo_save result.output += "\n" + _("io.shellReturn", result.returnValue); modules.commandline.command = args.commandName.replace("run", "$& ") + arg; - modules.commandline.commandOutput({result.output}); + modules.commandline.commandOutput(["span", { highlight: "CmdOutput" }, result.output]); modules.autocommands.trigger("ShellCmdPost", {}); }, { @@ -880,7 +929,7 @@ unlet s:cpo_save literal: 0 }); }, - completion: function init_completion(dactyl, modules, window) { + completion: function initCompletion(dactyl, modules, window) { const { completion, io } = modules; completion.charset = function (context) { @@ -992,7 +1041,7 @@ unlet s:cpo_save }; completion.addUrlCompleter("file", "Local files", function (context, full) { - let match = util.regexp( (?P @@ -1003,7 +1052,7 @@ unlet s:cpo_save ) (?P \/[^\/]* )? $ - ]]>, "x").exec(context.filter); + */), "x").exec(context.filter); if (match) { if (!match.path) { context.key = match.proto; @@ -1028,7 +1077,7 @@ unlet s:cpo_save completion.file(context, full); }); }, - javascript: function init_javascript(dactyl, modules, window) { + javascript: function initJavascript(dactyl, modules, window) { modules.JavaScript.setCompleter([File, File.expandPath], [function (context, obj, args) { context.quote[2] = ""; @@ -1047,7 +1096,7 @@ unlet s:cpo_save input: true }); }, - options: function init_options(dactyl, modules, window) { + options: function initOptions(dactyl, modules, window) { const { completion, options } = modules; var shell, shellcmdflag;