diff --git a/blash.js b/blash.js
index 6e2c3a9..fa27ef5 100644
--- a/blash.js
+++ b/blash.js
@@ -9,6 +9,9 @@ function blash ()
/** Shell window object */
this.window = document.getElementById ( "blashWindow" );
+ /** Array containing the codes of the shell commands */
+ this.commands = new Array();
+
/** Escape sequences to be parsed in the prompt text */
this.promptSequences = new Array();
@@ -34,6 +37,25 @@ function blash ()
this.__open_spans = 0;
/**************************************/
+ this.loadCommand = function ( cmd )
+ {
+ var cmd_file = window.location.href;
+ cmd_file = cmd_file.replace ( /\/([a-zA-Z\.]+)$/, '/commands/' + cmd + ".json" );
+
+ var http = new XMLHttpRequest();
+ http.open ( "GET", cmd_file, true );
+
+ http.onreadystatechange = function ()
+ {
+ if ( http.readyState == 4 && http.status == 200 )
+ {
+ shell.commands.push ( eval ( '(' + http.responseText + ')' ));
+ }
+ }
+
+ http.send ( null );
+ }
+
this.prompt.focus();
var json_config = window.location.href;
@@ -58,11 +80,16 @@ function blash ()
banner.innerHTML = shell.json.banner;
shell.window.insertBefore ( banner, shell.promptText );
}
+
+ for ( var i in shell.json.commands )
+ {
+ shell.loadCommand ( shell.json.commands[i] );
+ }
}
}
http.send ( null );
-
+
this.getKey = function ( e )
{
var evt = ( window.event ) ? window.event : e;
@@ -79,12 +106,12 @@ function blash ()
this.history.push ( this.prompt.value );
this.history_index = -1;
- for ( i=0; i < this.json.commands.length && !cmd_found; i++ )
+ for ( i=0; i < this.commands.length && !cmd_found; i++ )
{
- if ( this.json.commands[i].name == cmd )
+ if ( this.commands[i].name == cmd )
{
cmd_found = true;
- var out = this.json.commands[i].action ( arg );
+ var out = this.commands[i].action ( arg );
if ( out.length > 0 )
{
@@ -189,13 +216,13 @@ function blash ()
} else {
var cmds = new Array();
- for ( var i in this.json.commands )
+ for ( var i in this.commands )
{
var re = new RegExp ( '^' + this.prompt.value );
- if ( this.json.commands[i].name.match ( re ))
+ if ( this.commands[i].name.match ( re ))
{
- cmds.push ( this.json.commands[i].name );
+ cmds.push ( this.commands[i].name );
}
}
diff --git a/blash.json b/blash.json
index 82aa1f3..2b42288 100644
--- a/blash.json
+++ b/blash.json
@@ -63,244 +63,10 @@
],
"commands" : [
- {
- "name" : "pwd",
-
- "info" : {
- "syntax" : "pwd",
- "brief" : "Print name of current/working directory",
- },
-
- "action" : function ( arg ) {
- if ( arg )
- {
- if ( arg.length > 0 )
- {
- return this.name + ": Too many arguments
";
- } else {
- return shell.path + '
';
- }
- } else {
- return shell.path + '
';
- }
- },
- },
-
- {
- "name" : "man",
-
- "info" : {
- "syntax" : "man <page>",
- "brief" : "Display the manual page for the command 'page'",
- },
-
- "action" : function ( arg ) {
- var out = '';
-
- if ( arg == undefined || arg.length == 0 )
- {
- return "What manual page do you want?
\n";
- }
-
- var cmd = shell.json.commands;
-
- if ( arg == 'blash' )
- {
- var commands = new Array();
- out = 'Type "man <command>" for a more detailed help on these commands
';
-
- for ( var i=0; i < cmd.length; i++ )
- {
- commands.push ( cmd[i].info.syntax );
- }
-
- commands.sort();
-
- for ( var i in commands )
- {
- out += '' + commands[i] + '
';
- }
-
- return out;
- }
-
- var found = false;
-
- for ( var i=0; i < cmd.length && !found; i++ )
- {
- if ( arg == cmd[i].name )
- {
- if ( cmd[i].info.syntax.length > 0 && cmd[i].info.brief.length > 0 )
- {
- found = true;
-
- out =
- '' + cmd[i].info.syntax + '
' +
- '' + cmd[i].info.brief + '
';
- }
- }
- }
-
- if ( !found )
- {
- return "No manual entry for " + arg + "
\n";
- }
-
- return out;
- },
- },
-
- {
- "name" : "ls",
-
- "info" : {
- "syntax" : "ls [path]",
- "brief" : "List directory contents",
- },
-
- "action" : function ( arg )
- {
- var dirs = new Array();
- var out = '';
- var exists = false;
-
- arg = arg.replace ( /\/$/, '' );
-
- if ( !arg || arg.length == 0 )
- {
- var re = new RegExp ( '^' + shell.path + '[^/]+$' );
- } else if ( arg && arg.length > 0 ) {
- var re = null;
-
- if ( arg.match ( /^\// ))
- {
- re = new RegExp ( '^' + arg + '/[^/]+$' );
- } else {
- re = new RegExp ( '^' + shell.path +
- (( shell.path == '/' ) ? '' : '/' ) +
- arg + '/[^/]+$' );
- }
- }
-
- for ( var i=0; i < shell.json.directories.length; i++ )
- {
- var dir = shell.json.directories[i];
-
- if ( dir.path.match ( re ))
- {
- exists = true;
- dir.path.match ( /\/([^\/]+)$/ );
- dirs.push ({
- "path" : RegExp.$1,
- "type" : dir.type,
- "href" : dir.href,
- });
- }
- }
-
- if ( dirs.length > 0 )
- {
- var ordered = false;
-
- // Directories go first
- while ( !ordered )
- {
- ordered = true;
-
- for ( var i=0; i < dirs.length-1; i++ )
- {
- for ( var j=i+1; j < dirs.length; j++ )
- {
- if ( dirs[i].type == 'file' && dirs[j].type == 'directory' )
- {
- var tmp = dirs[i];
- dirs[i] = dirs[j];
- dirs[j] = tmp;
- ordered = false;
- }
- }
- }
- }
-
- ordered = false;
-
- // Sort the names
- while ( !ordered )
- {
- ordered = true;
-
- for ( var i=0; i < dirs.length-1; i++ )
- {
- for ( var j=i+1; j < dirs.length; j++ )
- {
- if ( dirs[i].type == dirs[j].type && dirs[i].path > dirs[j].path )
- {
- var tmp = dirs[i];
- dirs[i] = dirs[j];
- dirs[j] = tmp;
- ordered = false;
- }
- }
- }
- }
-
- for ( var i in dirs )
- {
- if ( dirs[i] )
- {
- if ( dirs[i].path.length > 0 )
- {
- if ( dirs[i].type == 'directory' )
- {
- out += '' + dirs[i].path + '/
';
- } else {
- if ( dirs[i].href && dirs[i].href.length > 0 )
- {
- out += '' + dirs[i].path + '*
';
- } else {
- out += '' + dirs[i].path + '
';
- }
- }
- }
- }
- }
- }
-
- if ( !exists )
- {
- var re = null;
-
- if ( arg.match ( /^\// ))
- {
- re = new RegExp ( '^' + arg );
- } else {
- re = new RegExp ( '^' + shell.path +
- (( shell.path == '/' ) ? '' : '/' ) + arg );
- }
-
- for ( var i=0; i < shell.json.directories.length; i++ )
- {
- var dir = shell.json.directories[i];
-
- if ( dir.path.match ( re ))
- {
- exists = true;
- break;
- }
- }
-
- if ( !exists )
- {
- out = this.name + ": cannot access " + arg +
- ": No such file or directory
";
- } else {
- out = '';
- }
- }
-
- return out;
- }
- }
+ "cd",
+ "ls",
+ "man",
+ "pwd",
],
}
diff --git a/commands/cd.json b/commands/cd.json
new file mode 100644
index 0000000..881bf44
--- /dev/null
+++ b/commands/cd.json
@@ -0,0 +1,50 @@
+{
+ "name" : "cd",
+
+ "info" : {
+ "syntax" : "cd <directory>",
+ "brief" : "Change the current directory to the specified one",
+ },
+
+ "action" : function ( arg )
+ {
+ var out = '';
+
+ if ( !arg || arg.length == 0 )
+ {
+ return "Parameter expected
\n";
+ }
+
+ arg = arg.replace ( /\/$/, '' );
+
+ if ( arg.match ( /^[^\/]/ ))
+ {
+ arg = this.path + '/' + arg;
+ arg = arg.replace ( /\/+/, '/' );
+ }
+
+ var found = false;
+
+ for ( var i=0; i < shell.json.directories.length && !found; i++ )
+ {
+ if ( shell.json.directories[i].path == arg )
+ {
+ found = true;
+
+ if ( shell.json.directories[i].type != 'directory' )
+ {
+ return "cd: not a directory: " + arg + "
\n";
+ }
+ }
+ }
+
+ if ( !found )
+ {
+ return "cd: no such file or directory: " + arg + "
\n";
+ }
+
+ shell.path = arg;
+ return out;
+ },
+}
+
diff --git a/commands/ls.json b/commands/ls.json
new file mode 100644
index 0000000..d04d696
--- /dev/null
+++ b/commands/ls.json
@@ -0,0 +1,152 @@
+{
+ "name" : "ls",
+
+ "info" : {
+ "syntax" : "ls [path]",
+ "brief" : "List directory contents",
+ },
+
+ "action" : function ( arg )
+ {
+ var dirs = new Array();
+ var out = '';
+ var exists = false;
+
+ arg = arg.replace ( /\/$/, '' );
+
+ if ( !arg || arg.length == 0 )
+ {
+ var re = new RegExp ( '^' + shell.path + '[^/]+$' );
+ } else if ( arg && arg.length > 0 ) {
+ var re = null;
+
+ if ( arg.match ( /^\// ))
+ {
+ re = new RegExp ( '^' + arg + '/[^/]+$' );
+ } else {
+ re = new RegExp ( '^' + shell.path +
+ (( shell.path == '/' ) ? '' : '/' ) +
+ arg + '/[^/]+$' );
+ }
+ }
+
+ for ( var i=0; i < shell.json.directories.length; i++ )
+ {
+ var dir = shell.json.directories[i];
+
+ if ( dir.path.match ( re ))
+ {
+ exists = true;
+ dir.path.match ( /\/([^\/]+)$/ );
+ dirs.push ({
+ "path" : RegExp.$1,
+ "type" : dir.type,
+ "href" : dir.href,
+ });
+ }
+ }
+
+ if ( dirs.length > 0 )
+ {
+ var ordered = false;
+
+ // Directories go first
+ while ( !ordered )
+ {
+ ordered = true;
+
+ for ( var i=0; i < dirs.length-1; i++ )
+ {
+ for ( var j=i+1; j < dirs.length; j++ )
+ {
+ if ( dirs[i].type == 'file' && dirs[j].type == 'directory' )
+ {
+ var tmp = dirs[i];
+ dirs[i] = dirs[j];
+ dirs[j] = tmp;
+ ordered = false;
+ }
+ }
+ }
+ }
+
+ ordered = false;
+
+ // Sort the names
+ while ( !ordered )
+ {
+ ordered = true;
+
+ for ( var i=0; i < dirs.length-1; i++ )
+ {
+ for ( var j=i+1; j < dirs.length; j++ )
+ {
+ if ( dirs[i].type == dirs[j].type && dirs[i].path > dirs[j].path )
+ {
+ var tmp = dirs[i];
+ dirs[i] = dirs[j];
+ dirs[j] = tmp;
+ ordered = false;
+ }
+ }
+ }
+ }
+
+ for ( var i in dirs )
+ {
+ if ( dirs[i] )
+ {
+ if ( dirs[i].path.length > 0 )
+ {
+ if ( dirs[i].type == 'directory' )
+ {
+ out += '' + dirs[i].path + '/
';
+ } else {
+ if ( dirs[i].href && dirs[i].href.length > 0 )
+ {
+ out += '' + dirs[i].path + '*
';
+ } else {
+ out += '' + dirs[i].path + '
';
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( !exists )
+ {
+ var re = null;
+
+ if ( arg.match ( /^\// ))
+ {
+ re = new RegExp ( '^' + arg );
+ } else {
+ re = new RegExp ( '^' + shell.path +
+ (( shell.path == '/' ) ? '' : '/' ) + arg );
+ }
+
+ for ( var i=0; i < shell.json.directories.length; i++ )
+ {
+ var dir = shell.json.directories[i];
+
+ if ( dir.path.match ( re ))
+ {
+ exists = true;
+ break;
+ }
+ }
+
+ if ( !exists )
+ {
+ out = this.name + ": cannot access " + arg +
+ ": No such file or directory
";
+ } else {
+ out = '';
+ }
+ }
+
+ return out;
+ }
+}
+
diff --git a/commands/man.json b/commands/man.json
new file mode 100644
index 0000000..e6d8e2f
--- /dev/null
+++ b/commands/man.json
@@ -0,0 +1,64 @@
+{
+ "name" : "man",
+
+ "info" : {
+ "syntax" : "man <page>",
+ "brief" : "Display the manual page for the command 'page'",
+ },
+
+ "action" : function ( arg ) {
+ var out = '';
+
+ if ( arg == undefined || arg.length == 0 )
+ {
+ return "What manual page do you want?
\n";
+ }
+
+ var cmd = shell.json.commands;
+
+ if ( arg == 'blash' )
+ {
+ var commands = new Array();
+ out = 'Type "man <command>" for a more detailed help on these commands
';
+
+ for ( var i=0; i < cmd.length; i++ )
+ {
+ commands.push ( cmd[i].info.syntax );
+ }
+
+ commands.sort();
+
+ for ( var i in commands )
+ {
+ out += '' + commands[i] + '
';
+ }
+
+ return out;
+ }
+
+ var found = false;
+
+ for ( var i=0; i < cmd.length && !found; i++ )
+ {
+ if ( arg == cmd[i].name )
+ {
+ if ( cmd[i].info.syntax.length > 0 && cmd[i].info.brief.length > 0 )
+ {
+ found = true;
+
+ out =
+ '' + cmd[i].info.syntax + '
' +
+ '' + cmd[i].info.brief + '
';
+ }
+ }
+ }
+
+ if ( !found )
+ {
+ return "No manual entry for " + arg + "
\n";
+ }
+
+ return out;
+ },
+}
+
diff --git a/commands/pwd.json b/commands/pwd.json
new file mode 100644
index 0000000..67e0a98
--- /dev/null
+++ b/commands/pwd.json
@@ -0,0 +1,23 @@
+{
+ "name" : "pwd",
+
+ "info" : {
+ "syntax" : "pwd",
+ "brief" : "Print name of current/working directory",
+ },
+
+ "action" : function ( arg ) {
+ if ( arg )
+ {
+ if ( arg.length > 0 )
+ {
+ return this.name + ": Too many arguments
";
+ } else {
+ return shell.path + '
';
+ }
+ } else {
+ return shell.path + '
';
+ }
+ },
+}
+