Skip to content

Commit

Permalink
Change LS to output JSON listing of files. Add JSON pretty printer.
Browse files Browse the repository at this point in the history
  • Loading branch information
unconed committed May 9, 2011
1 parent 2cfedc3 commit 4378ebd
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 110 deletions.
40 changes: 40 additions & 0 deletions Node/misc.js
Expand Up @@ -124,3 +124,43 @@ exports.expandPath = function (path, callback) {
}
return callback(path);
}


/**
* JSON pretty printer.
*/
exports.JSONPretty = function (data) {
// Convert to JSON.
if (typeof data != 'string') {
data = JSON.stringify(data);
}

// Add spaces around operators and quotes.
data = data.replace(/("[^"]*"|'[^']*')?([\[{:,}\]](?!\s))/g, '$1$2 ');
data = data.replace(/(\S)([\]}])/g, '$1 $2');

// Add linebreaks around element/list separators.
data = data.replace(/[ \n\t]+([\]}])/g, " $1");
data = data.replace(/ ([\]}])/g, "\n$1");
data = data.replace(/(("[^"]*"|'[^']*')?[\[{,])[ \n\t]+/g, "$1 ");
data = data.replace(/(("[^"]*"|'[^']*')?[\[{,] )/g, "$1\n");

// Indent
var m = [],
indent = 0,
data = data.split("\n");

for (i in data) (function (line) {
// Count closing chars.
indent -= (m = line.match(/[\]}]/g)) && m.length;

// Two spaced indent.
line = Array(indent + 1).join(' ') + line;

// Count opening chars.
indent += (m = line.match(/[\[{]/g)) && m.length;
data[i] = line;
})(data[i]);

return data.join("\n");
}
4 changes: 2 additions & 2 deletions Node/shell/autocomplete.js
@@ -1,5 +1,5 @@
var fs = require('fs'),
builtin = require('shell/builtin');
builtin = require('shell/builtin/builtin');

/*
Expand Down Expand Up @@ -94,7 +94,7 @@ exports.autocomplete.prototype = {
*/
builtin: function (prefix) {
var matches = [];
for (i in builtin.shellCommands) {
for (i in builtin.commands) {
if (prefix == '' || i.indexOf(prefix) === 0) {
matches.push(exports.autocomplete.match(i, i + ' ', 'command'));
}
Expand Down
69 changes: 45 additions & 24 deletions Node/shell/builtin/ls.js
Expand Up @@ -10,38 +10,59 @@ var fs = require('fs'),
exports.main = function (tokens, pipes, exit) {

var out = new view.bridge(pipes.viewOut);

var hidden = false;

// Parse out directory references to list.
var items = [];
if (tokens.length <= 1) {
items.push(process.cwd());
}
else {
for (i in tokens) if (i > 0) {
for (i in tokens) if (i > 0) {
var m;
if (m = /-([aA])/(tokens[i])) {
switch (m[1]) {
case 'a':
case 'A':
hidden = true;
break;
}
}
else {
items.push(tokens[i]);
}
}

//application/json; schema=termkit.files
// Default to working directory.
if (!items.length) {
items.push(process.cwd());
}

// Prepare async job tracker.
var errors = 0;
var output = [];
var output = {};
var track = whenDone(function () {
for (i in output) {
// Output one directory listing at a time.
out.print(view.list(i, output[i]));
}

// Format data.
var data = JSON.stringify(output);

// Output headers.
var headers = new meta.headers();
headers.set({
'Content-Type': [ 'application/json', { schema: 'termkit.files' } ],
'Content-Length': data.length,
});

pipes.dataOut.write(headers.generate());

pipes.dataOut.write(data);

exit(errors == 0);
}); // whenDone

// Process arguments (list of paths).
for (var i in items) (function (i, path) {
for (var i in items) (function (i, key) {

output[i] = [];
output[key] = [];

// Expand path
expandPath(path, track(function (path) {
expandPath(key, track(function (path) {
// Stat the requested files / directories.
fs.stat(path, track(function (error, stats) {

Expand All @@ -51,20 +72,20 @@ exports.main = function (tokens, pipes, exit) {
// Scan contents of found directories.
fs.readdir(path, track(function (error, files) {
if (!error) {


// Sort files.
var children = [];
files.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});

for (var j in files) (function (j, child) {
// Stat each child.
fs.stat(composePath(child, path), track(function (error, stats) {
if (!error) {
output[i][j] = view.file(child, path, stats);
}
})); // fs.stat
})(j, files[j]); // for j in files
// Apply hidden filter.
if (!hidden) {
files = files.filter(function (file) { return file[0] != '.'; });
}

// Output files.
output[key] = files;
} // !error
})); // fs.readdir
} // isDirectory
Expand Down
89 changes: 47 additions & 42 deletions Node/shell/command.js
@@ -1,10 +1,9 @@
var EventEmitter = require("events").EventEmitter,
outputFormatter = require('shell/formatter').formatter;
spawn = require('child_process').spawn,
builtin = require('shell/builtin'),
view = require('view/view'),
meta = require('shell/meta'),

builtin = require('shell/builtin/builtin'),
async = require('misc').async,
whenDone = require('misc').whenDone,
returnObject = require('misc').returnObject,
Expand Down Expand Up @@ -144,48 +143,54 @@ exports.commandUnit.builtinCommand.prototype = new exports.commandUnit();
exports.commandUnit.builtinCommand.prototype.spawn = function () {
var that = this,
prefix = this.command[0];
if (this.handler = builtin.shellCommands[prefix]) {

// Make fake process.
var fake = new EventEmitter();
fake.stdin = new EventEmitter();
fake.stdout = new EventEmitter();
fake.stderr = new EventEmitter();

// Helper for converting strings to buffers.
function buffer(data) {
if (data.constructor != Buffer) {
data = new Buffer(data, 'utf8');
}
return data;
}

// Set up fake stdin.
fake.stdin.write = function (data) {
fake.stdin.emit('data', buffer(data));
};
fake.stdin.end = function () {
};

// Set up fake stdout.
fake.stdout.write = function (data) {
fake.stdout.emit('data', buffer(data));
};
fake.stdout.end = function () {
};

// Set up fake stderr.
fake.stderr.write = function (data) {
fake.stderr.emit('data', buffer(data));
};
fake.stderr.end = function () {
};

this.process = fake;
if (!builtin.commands[prefix]) {
prefix = 'null';
}
else {
throw "No such built-in command '" + prefix;

// Load handler.
try {
this.handler = require('builtin/' + prefix);
} catch (e) {
process.stderr.write('exception ' + e);
}

// Make fake process.
var fake = new EventEmitter();
fake.stdin = new EventEmitter();
fake.stdout = new EventEmitter();
fake.stderr = new EventEmitter();

// Helper for converting strings to buffers.
function buffer(data) {
if (data.constructor != Buffer) {
data = new Buffer(data, 'utf8');
}
return data;
}

// Set up fake stdin.
fake.stdin.write = function (data) {
fake.stdin.emit('data', buffer(data));
};
fake.stdin.end = function () {
};

// Set up fake stdout.
fake.stdout.write = function (data) {
fake.stdout.emit('data', buffer(data));
};
fake.stdout.end = function () {
};

// Set up fake stderr.
fake.stderr.write = function (data) {
fake.stderr.emit('data', buffer(data));
};
fake.stderr.end = function () {
};

this.process = fake;
};

exports.commandUnit.builtinCommand.prototype.go = function () {
Expand All @@ -206,7 +211,7 @@ exports.commandUnit.builtinCommand.prototype.go = function () {
};

async(function () {
that.handler.call(that, that.command, pipes, exit);
that.handler.main.call(that, that.command, pipes, exit);
});
};

Expand Down

0 comments on commit 4378ebd

Please sign in to comment.