Simple mini shell
fshell=require('fshell')({config});
Any config properties undefined
or typeof()!==
will default to the values listed below:
.process: process
.textClr: 15
.cursorClr: 8
.cwdClr: 2
.fileClr: 6
.dirClr: 5
.errClr: 1
.history: 100
.escape: '\x1b'
.onExit: function(code=0)
.onKey: function(key={sequence:'',name:'',ctrl:false,meta:false,shift:false})
Returns the config object with the added properties:
.cmd: function(str,...) //Call commands
.addCmd: function(obj,...) //Add commands
.renameCmd: function(str,str,...) //Rename commands
.delCmd: function(str,...) //Delete commands
.getCmds: function() //Get array of command names
.addFlag: function(str,...) //Add option
.delFlag: function(str,...) //Delete option
.getFlags: function() //Get array of option strings
.error: function({}||(str,str,str,str,str)) //Log pretty format errors
fstdin properties:
.line: '' //Read-only current stdin
.key: function(str||obj,...) //Trigger keys
.prompt: function(obj,...) //Prompt user
.font: function(int) //Returns color code string
.back: function(int) //Returns color code string
An incoming string will be parsed first for the echo echo-in echo-out
flags and the command, ex: echo ls
The remainder of the string is parsed as arguments for the command until encountering a space, |
, &
, or end of line.
To echo the input, or successful output, or both of a command execution, begin the line with echo-in
, echo-out
, or echo
:
'echo-in mk hi/hi.js'
prints:
[mk-0](hi/hi.js)
-----------------------------------------------------------
'echo-out mk hi.js, hello/'
prints: (print order based on async completion)
[mk-1](hello/)
[mk-0](hi.js)
-----------------------------------------------------------
'echo ls'
prints:
[ls-0]()
...command output...
[ls-0](${current directory})
To execute a command multiple times separate the argument sets with a comma ,
:
mk hi.js, hello.js
rm hi.js, hello.js
To execute multiple independent commands in one line:
- Use a single
&
- The commands will be executed regardless of the
end()
call of the prior command - Since most commands are asynchronous, this can cause unexpected behaviour
mk hi.js & rm hello.js //expected behaviour
mk hi.js & rm hi.js //unexpected behaviour
To execute multiple dependent commands in one line:
- Use a double
&&
- The following command will be executed only if the prior command calls the
end()
function mk hi.js && rm hi.js //expected behaviour
To pipe the end()
value of one command into the next command:
- Use a
|
- The value passed to
end()
from each execution will be spread to the next command in front of any existing arguments
'mk hi.js | rm'
make and remove hi.js
-----------------------------------------------------------
'mk hi/hi.js | mv greetings/'
make hi/hi.js recursively and move to greetings/
if greetings/ does not exist it is created
-----------------------------------------------------------
'mk hi.js, greetings/ | mv'
make hi.js and greetings/ and move hi.js into greetings/
- Execute commands
- Include the command and arguments in one string the same as typing on the command line and pressing return
- Example:
cmd('mk hi/hi.js && rm hi/ -r')
- Add a command if not previously defined
- Requires an object with the properties:
.name : ''
.func : function(){}
- Functions will always be passed the first two parameters
( flags, end )
; the remaining arguments are spread in order( flags, end, arg1, arg2, arg3, ...)
flags
is an object containing the flags passed in the argument set for the commandaddCmd({ name:'hw' ,func:(flags,end)=>{ if(flags.about)console.log('I print "Hello world!"'); else console.log('Hello world!'); } });
end
is a function, called when the command is fully finished- Accepts one argument to pass to a piped command
- Required for
&
,&&
, and|
pipe functionality
addCmd({ name:'hw' ,func:(flags,end)=>{ if(flags.about)console.log('I print "Hello world!"'); else console.log('Hello world!'); end('Hello world!'); } });
- Rename a command
- Example:
renameCmd('mv','move','cp','copy')
- Delete a command by name
- Example:
delCmd('mv','cp')
- Get an array list of command name strings
- Example:
getCmds()
- Add a flag if not already defined
- Do not include the
-
- Example:
addFlag('version')
- Delete a flag if defined
- Do not include the
-
- Example:
delFlag('version')
- Get an array list of flag name strings
- Example:
getFlags()
- Pretty print error messages
- Pass 5 optional string parameters:
error(command name, errno, code, path, message)
- Or add the command name to the error object and pass the object as the first parameter
err.cmd = command name
error(err)
Flags are options and are parsed out of the argument string.
A flag begins with a dash, ex: -about -last -r -x
.
Use the addFlag()
and delFlag()
functions to add and remove flags.
The current default flags are:
-about
- Get description of the command. When using the about flag, the corresponding command will not be executed
-last
- Used with the
cd
command to change directory to the last working directory
-r
- Recursive flag used with the
rm
command to recursively empty directories
-x
- Overwrite flag used with the
mk
,cp
, andmv
commands to overwrite files and directories when existing
While default flags are removable, they are irreplacable in the default commands.
The pre-existing commands may be renamed or deleted.
- Print a list of available commands
cmds
- Set the current working directory colour code integer
.cwdclr [int]
- Set the stdin text colour code integer
.textclr [int]
- Set the stdin cursor colour code integer
.cursorclr [int]
- Set the stdin scroll maximum history integer
.history [int]
- Set the 'ls' command file colour code integer
.fileclr [int]
- Set the 'ls' command directory colour code integer
.dirclr [int]
- Exit the fshell process and call the
onExit()
function; by defaultint = 0
exit [optional int]
- Print the current directory
cwd
- Change the current directory
cd [directory]
- List a directory or array; by default
directory = current
ls [optional directory]
- Make a file or directory
- Defaults to file, to create a directory add
/
to the name - Requires the
-x
flag to overwrite existing files mk [file || directory+/]
'mk hi'
makes file named 'hi'
-----------------------------------------------------------
'mk hi/'
makes directory named 'hi'
-----------------------------------------------------------
'mk hi/hi'
makes directory (if non-existant) named 'hi' and makes file named 'hi' in the directory
- Remove files and directories
- Requires
-r
recursive flag to remove non-empty directory rm [file || directory]
- Copy files and directories to another directory
- Will accept
.
or*
at the path end to select all inside that directory cp [source file(s) || directory] [target directory]
'mk hi/hi.js,hi/hello.js,hi/yo.js'
'cp hi/ greetings/'
copy the 'hi' directory into the 'greetings' directory (created if non-existant)
-----------------------------------------------------------
'mk hi/hi.js,hi/hello.js,hi/yo.js'
'cp hi/* greetings/'
copy all inside the 'hi' directory into the 'greetings' directory (created if non-existant)
- Move files and directories to another directory
- Will accept
.
or*
at the path end to select all inside that directory mv [source file(s) || directory] [target directory]
'mk hi/hi.js,hi/hello.js,hi/yo.js'
'mv hi/ greetings/'
move the 'hi' directory into the 'greetings' directory (created if non-existant)
-----------------------------------------------------------
'mk hi/hi.js,hi/hello.js,hi/yo.js'
'mv hi/* greetings/'
move all inside the 'hi' directory into the 'greetings' directory (created if non-existant)
- Pass arguments to a separate OS shell process
ex [arguments...]
'echo ex echo "Hello world!", "echo Hello back!"'
prints:
[ex-0](echo, Hello world!)
[ex-1](echo Hello back!)
[ex-0](Hello world!)
[ex-1](Hello back!)
-----------------------------------------------------------
'ex touch hi.js hello.js'
use separate OS shell to create hi.js and hello.js