1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-22 17:57:58 +01:00

merge new vimperator.io object

This commit is contained in:
Doug Kearns
2007-10-22 02:55:52 +00:00
parent dd3196f0b4
commit 05ab034753
4 changed files with 230 additions and 287 deletions

View File

@@ -237,7 +237,7 @@ vimperator.completion = (function() // {{{
}, //}}} }, //}}}
// TODO: support file:// and \ or / path separators on both platforms // TODO: support file:// and \ or / path separators on both platforms
get_file_completions: function(filter) //{{{ get_file_completions: function(filter)
{ {
// this is now also used as part of the url completion, so the // this is now also used as part of the url completion, so the
// substrings shouldn't be cleared for that case // substrings shouldn't be cleared for that case
@@ -252,35 +252,12 @@ vimperator.completion = (function() // {{{
var compl = matches[2] || ""; var compl = matches[2] || "";
var files = [], mapped = [];
try try
{ {
var fd = vimperator.io.fopen(dir); files = vimperator.io.readDirectory(dir);
} mapped = files.map(function(file) {
catch (e) return [[file.path], file.isDirectory() ? "Directory" : "File"];
{
// thrown if file does not exist
return [];
}
if (!fd)
return [];
try
{
var entries = fd.read();
var separator = fd.path.length == 1 ? "" : /\\/.test(fd.path) ? "\\" : "/";
var new_filter = fd.path + separator + compl;
if (!filter) return entries.map(function(file) {
var path = file.path;
if (file.isDirectory())
path += separator;
return [path, ""];
});
var mapped = entries.map(function(file) {
var path = file.path;
if (file.isDirectory())
path += separator;
return [[path], ""];
}); });
} }
catch (e) catch (e)
@@ -288,8 +265,9 @@ vimperator.completion = (function() // {{{
return []; return [];
} }
return build_longest_starting_substring(mapped, new_filter);
}, //}}} return build_longest_starting_substring(mapped, filter);
},
get_help_completions: function(filter) //{{{ get_help_completions: function(filter) //{{{
{ {

View File

@@ -27,153 +27,216 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
vimperator.io = {}; vimperator.io = (function()
vimperator.io.fopen = function(path, mode, perms, tmp)
{ {
return new vimperator.io.LocalFile(path, mode, perms, tmp); var environment_service = Components.classes["@mozilla.org/process/environment;1"]
} .getService(Components.interfaces.nsIEnvironment);
vimperator.io.LocalFile = function(file, mode, perms, tmp) // {{{ vimperator.log("Loading vimperator.io");
{
const PERM_IWOTH = 00002; /* write permission, others */
const PERM_IWGRP = 00020; /* write permission, group */
const MODE_RDONLY = 0x01; return {
const MODE_WRONLY = 0x02;
const MODE_RDWR = 0x04;
const MODE_CREATE = 0x08;
const MODE_APPEND = 0x10;
const MODE_TRUNCATE = 0x20;
const MODE_SYNC = 0x40;
const MODE_EXCL = 0x80;
const classes = Components.classes; MODE_RDONLY: 0x01,
const interfaces = Components.interfaces; MODE_WRONLY: 0x02,
MODE_RDWR: 0x04,
MODE_CREATE: 0x08,
MODE_APPEND: 0x10,
MODE_TRUNCATE: 0x20,
MODE_SYNC: 0x40,
MODE_EXCL: 0x80,
const LOCALFILE_CTRID = "@mozilla.org/file/local;1"; expandPath: function(path)
const FILEIN_CTRID = "@mozilla.org/network/file-input-stream;1";
const FILEOUT_CTRID = "@mozilla.org/network/file-output-stream;1";
const SCRIPTSTREAM_CTRID = "@mozilla.org/scriptableinputstream;1";
const nsIFile = interfaces.nsIFile;
const nsILocalFile = interfaces.nsILocalFile;
const nsIFileOutputStream = interfaces.nsIFileOutputStream;
const nsIFileInputStream = interfaces.nsIFileInputStream;
const nsIScriptableInputStream = interfaces.nsIScriptableInputStream;
if (typeof perms == "undefined")
perms = 0666 & ~(PERM_IWOTH | PERM_IWGRP);
if (typeof mode == "string")
{
switch (mode)
{ {
case ">": const WINDOWS = navigator.platform == "Win32";
mode = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
break; // TODO: proper pathname separator translation like Vim
case ">>": if (WINDOWS)
mode = MODE_WRONLY | MODE_CREATE | MODE_APPEND; path = path.replace('/', '\\', 'g');
break;
case "<": // expand "~" to VIMPERATOR_HOME or HOME (USERPROFILE or HOMEDRIVE\HOMEPATH on Windows if HOME is not set)
mode = MODE_RDONLY; if (/^~/.test(path))
break; {
default: var home = environment_service.get("VIMPERATOR_HOME");
throw "Invalid mode ``" + mode + "''";
if (!home)
home = environment_service.get("HOME");
if (WINDOWS && !home)
home = environment_service.get("USERPROFILE") ||
environment_service.get("HOMEDRIVE") + environment_service.get("HOMEPATH");
path = path.replace("~", home);
}
// expand any $ENV vars
var env_vars = path.match(/\$\w+\b/g); // this is naive but so is Vim and we like to be compatible
if (env_vars)
{
var expansion;
for (var i = 0; i < env_vars.length; i++)
{
expansion = environment_service.get(env_vars[i].replace("$", ""));
if (expansion)
path = path.replace(env_vars[i], expansion);
}
}
return path;
},
getPluginDir: function()
{
var plugin_dir;
if (navigator.platform == "Win32")
plugin_dir = "~/vimperator/plugin";
else
plugin_dir = "~/.vimperator/plugin";
plugin_dir = this.getFile(this.expandPath(plugin_dir));
return plugin_dir.exists() && plugin_dir.isDirectory() ? plugin_dir : null;
},
getRCFile: function()
{
var rc_file1 = this.getFile(this.expandPath("~/.vimperatorrc"));
var rc_file2 = this.getFile(this.expandPath("~/_vimperatorrc"));
if (navigator.platform == "Win32")
[rc_file1, rc_file2] = [rc_file2, rc_file1]
if (rc_file1.exists() && rc_file1.isFile())
return rc_file1;
else if (rc_file2.exists() && rc_file2.isFile())
return rc_file2;
else
return null;
},
// return a nsILocalFile for path where you can call isDirectory(), etc. on
// caller must check with .exists() if the returned file really exists
getFile: function(path)
{
var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(this.expandPath(path));
return file;
},
// TODO: make secure
// returns a nsILocalFile or null if it could not be created
createTempFile: function()
{
var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
if (navigator.platform == "Win32")
{
var dir = environment_service.get("TMP") || environment_service.get("TEMP") || "C:\\";
file.initWithPath(dir + "\\vimperator.tmp");
}
else
{
var dir = environment_service.get("TMP") || environment_service.get("TEMP") || "/tmp/";
file.initWithPath(dir + "/vimperator.tmp");
}
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0600);
if (!file.exists())
return null;
return file;
},
// file is either a full pathname or an instance of file instanceof nsILocalFile
readDirectory: function(file)
{
if (typeof file == "string")
file = this.getFile(file);
else if (!(file instanceof Components.interfaces.nsILocalFile))
throw Components.results.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
if (file.isDirectory())
{
var entries = file.directoryEntries;
var array = [];
while (entries.hasMoreElements())
{
var entry = entries.getNext();
entry.QueryInterface(Components.interfaces.nsIFile);
array.push(entry);
}
return array;
}
else
return []; // XXX: or should it throw an error, probably yes?
},
// file is either a full pathname or an instance of file instanceof nsILocalFile
// reads a file in "text" mode and returns the string
readFile: function(file)
{
var ifstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var icstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
var charset = "UTF-8";
if (typeof file == "string")
file = this.getFile(file);
else if (!(file instanceof Components.interfaces.nsILocalFile))
throw Components.results.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
ifstream.init(file, -1, 0, 0);
const replacementChar = Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
icstream.init(ifstream, charset, 4096, replacementChar); // 4096 bytes buffering
var buffer = "";
var str = {};
while (icstream.readString(4096, str) != 0)
buffer += str.value;
icstream.close();
ifstream.close();
return buffer;
},
// file is either a full pathname or an instance of file instanceof nsILocalFile
// default permission = 0644, only used when creating a new file, does not change permissions if the file exists
// mode can be ">" or ">>" in addition to the normal MODE_* flags
writeFile: function(file, buf, mode, perms)
{
var ofstream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
var ocstream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
.createInstance(Components.interfaces.nsIConverterOutputStream);
var charset = "UTF-8"; // Can be any character encoding name that Mozilla supports
if (typeof file == "string")
file = this.getFile(file);
else if (!(file instanceof Components.interfaces.nsILocalFile))
throw Components.results.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
if (mode == ">>")
mode = this.MODE_WRONLY | this.MODE_CREATE | this.MODE_APPEND;
else if (!mode || mode == ">")
mode = this.MODE_WRONLY | this.MODE_CREATE | this.MODE_TRUNCATE;
if (!perms)
perms = 0644;
ofstream.init(file, mode, perms, 0);
ocstream.init(ofstream, charset, 0, 0x0000);
ocstream.writeString(buf);
ocstream.close();
ofstream.close();
} }
} }
})();
if (typeof file == "string")
{
this.localFile = classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
this.localFile.initWithPath(file);
if (!this.localFile.exists())
throw "No such file or directory";
}
else if (file instanceof nsILocalFile)
{
this.localFile = file;
if (!this.localFile.exists())
throw "No such file or directory";
}
else
{
throw "bad type for argument |file|.";
}
this.path = this.localFile.path;
if (mode & (MODE_WRONLY | MODE_RDWR))
{
this.outputStream =
classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
this.outputStream.init(this.localFile, mode, perms, 0);
}
if (mode & (MODE_RDONLY | MODE_RDWR))
{
var is = classes[FILEIN_CTRID].createInstance(nsIFileInputStream);
is.init(this.localFile, mode, perms, tmp);
this.inputStream =
classes[SCRIPTSTREAM_CTRID].createInstance(nsIScriptableInputStream);
this.inputStream.init(is);
}
}
vimperator.io.LocalFile.prototype.write =
function fo_write(buf)
{
if (!("outputStream" in this))
throw "file not open for writing.";
return this.outputStream.write(buf, buf.length);
}
vimperator.io.LocalFile.prototype.read =
function fo_read(max)
{
if (this.localFile.isDirectory())
{
var entries = this.localFile.directoryEntries;
var array = [];
while (entries.hasMoreElements())
{
var entry = entries.getNext();
entry.QueryInterface(Components.interfaces.nsIFile);
array.push(entry);
}
return array;
}
if (!("inputStream" in this))
throw "file not open for reading.";
var av = this.inputStream.available();
if (typeof max == "undefined")
max = av;
if (!av)
return null;
var rv = this.inputStream.read(max);
return rv;
}
vimperator.io.LocalFile.prototype.close =
function fo_close()
{
if ("outputStream" in this)
this.outputStream.close();
if ("inputStream" in this)
this.inputStream.close();
}
vimperator.io.LocalFile.prototype.flush =
function fo_close()
{
return this.outputStream.flush();
}
//}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -864,14 +864,11 @@ function Mappings() //{{{
if (url.match(/^file:\/\//) || url.match(/^\//)) if (url.match(/^file:\/\//) || url.match(/^\//))
{ {
var stripedFilename = url.replace(/^(file:\/\/)?(.*)/, "$2"); var stripedFilename = url.replace(/^(file:\/\/)?(.*)/, "$2");
var file = vimperator.io.fopen(stripedFilename, '<'); var file = vimperator.io.getFile(stripedFilename);
if (!file) if (!file || !file.isDirectory())
return false; return false;
if (file.localFile.isDirectory())
return true;
else else
return false; return true;
} }
// for all other locations just check if the URL ends with / // for all other locations just check if the URL ends with /
if (url.match(/\/$/)) if (url.match(/\/$/))

View File

@@ -104,87 +104,6 @@ const vimperator = (function() //{{{
vimperator.echo("-- " + str_mode + str_extended + " --"); vimperator.echo("-- " + str_mode + str_extended + " --");
} }
function expandPath(path)
{
const WINDOWS = navigator.platform == "Win32";
// TODO: proper pathname separator translation like Vim
if (WINDOWS)
path = path.replace('/', '\\', 'g');
// expand "~" to VIMPERATOR_HOME or HOME (USERPROFILE or HOMEDRIVE\HOMEPATH on Windows if HOME is not set)
if (/^~/.test(path))
{
var home = environment_service.get("VIMPERATOR_HOME");
if (!home)
home = environment_service.get("HOME");
if (WINDOWS && !home)
home = environment_service.get("USERPROFILE") ||
environment_service.get("HOMEDRIVE") + environment_service.get("HOMEPATH");
path = path.replace("~", home);
}
// expand any $ENV vars
var env_vars = path.match(/\$\w+\b/g); // this is naive but so is Vim and we like to be compatible
if (env_vars)
{
var expansion;
for (var i = 0; i < env_vars.length; i++)
{
expansion = environment_service.get(env_vars[i].replace("$", ""));
if (expansion)
path = path.replace(env_vars[i], expansion);
}
}
return path;
}
// TODO: add this functionality to LocalFile or wait for Scriptable I/O in FUEL
function pathExists(path)
{
var p = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
p.initWithPath(expandPath(path));
return p.exists();
}
function getPluginDir()
{
var plugin_dir;
if (navigator.platform == "Win32")
plugin_dir = "~/vimperator/plugin";
else
plugin_dir = "~/.vimperator/plugin";
plugin_dir = expandPath(plugin_dir);
return pathExists(plugin_dir) ? plugin_dir : null;
}
function getRCFile()
{
var rc_file1 = expandPath("~/.vimperatorrc");
var rc_file2 = expandPath("~/_vimperatorrc");
if (navigator.platform == "Win32")
[rc_file1, rc_file2] = [rc_file2, rc_file1]
if (pathExists(rc_file1))
return rc_file1;
else if (pathExists(rc_file2))
return rc_file2;
else
return null;
}
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -652,7 +571,7 @@ const vimperator = (function() //{{{
{ {
const WINDOWS = navigator.platform == "Win32"; // FIXME: duplicated everywhere const WINDOWS = navigator.platform == "Win32"; // FIXME: duplicated everywhere
var fileout = getTempFile(); var fileout = vimperator.io.createTempFile();
if (!fileout) if (!fileout)
return ""; return "";
@@ -664,10 +583,8 @@ const vimperator = (function() //{{{
var filein = null; var filein = null;
if (input) if (input)
{ {
filein = getTempFile(); filein = vimperator.io.createTempFile();
var fdin = vimperator.io.fopen(filein, ">"); vimperator.io.writeFile(filein, input);
fdin.write(input);
fdin.close();
command += " < \"" + filein.path.replace('"', '\\"') + "\""; command += " < \"" + filein.path.replace('"', '\\"') + "\"";
} }
@@ -677,48 +594,38 @@ const vimperator = (function() //{{{
else else
res = this.run("sh", ["-c", command], true); res = this.run("sh", ["-c", command], true);
var fd = vimperator.io.fopen(fileout, "<"); var output = vimperator.io.readFile(fileout);
if (!fd)
return "";
var s = fd.read();
fd.close();
fileout.remove(false); fileout.remove(false);
if (filein) if (filein)
filein.remove(false); filein.remove(false);
// if there is only one \n at the end, chop it off // if there is only one \n at the end, chop it off
if (s && s.indexOf("\n") == s.length-1) if (output && output.indexOf("\n") == output.length-1)
s = s.substr(0, s.length-1); output = output.substr(0, output.length-1);
return s; return output;
}, },
// files which end in .js are sourced as pure javascript files, // files which end in .js are sourced as pure javascript files,
// no need (actually forbidden) to add: js <<EOF ... EOF around those files // no need (actually forbidden) to add: js <<EOF ... EOF around those files
source: function(filename, silent) source: function(filename, silent)
{ {
filename = expandPath(filename); filename = vimperator.io.expandPath(filename);
try try
{ {
var fd = vimperator.io.fopen(filename, "<"); var str = vimperator.io.readFile(filename);
if (!fd)
return;
var s = fd.read();
fd.close();
// handle pure javascript files specially // handle pure javascript files specially
if (filename.search("\.js$") != -1) if (filename.search("\.js$") != -1)
{ {
eval(s); eval(str);
} }
else else
{ {
var heredoc = ""; var heredoc = "";
var heredoc_end = null; // the string which ends the heredoc var heredoc_end = null; // the string which ends the heredoc
s.split("\n").forEach(function(line) str.split("\n").forEach(function(line)
{ {
if (heredoc_end) // we already are in a heredoc if (heredoc_end) // we already are in a heredoc
{ {
@@ -834,10 +741,10 @@ const vimperator = (function() //{{{
// make sourcing asynchronous, otherwise commands that open new tabs won't work // make sourcing asynchronous, otherwise commands that open new tabs won't work
setTimeout(function() { setTimeout(function() {
var rc_file = getRCFile(); var rc_file = vimperator.io.getRCFile();
if (rc_file) if (rc_file)
vimperator.source(rc_file, true); vimperator.source(rc_file.path, true);
else else
vimperator.log("No user RC file found", 3); vimperator.log("No user RC file found", 3);
@@ -845,15 +752,13 @@ const vimperator = (function() //{{{
var entries = []; var entries = [];
try try
{ {
var plugin_dir = getPluginDir(); var plugin_dir = vimperator.io.getPluginDir();
if (plugin_dir) if (plugin_dir)
{ {
var fd = vimperator.io.fopen(plugin_dir); var files = vimperator.io.readDirectory(plugin_dir.path);
var entries = fd.read();
fd.close();
vimperator.log("Sourcing plugin directory...", 3); vimperator.log("Sourcing plugin directory...", 3);
entries.forEach(function(file) { files.forEach(function(file) {
if (!file.isDirectory()) if (!file.isDirectory())
vimperator.source(file.path, false); vimperator.source(file.path, false);
}); });