Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 9cc2228354cf4b9d6529f96cd4d6a15b21a67d98 @tj committed Jul 28, 2012
Showing with 966 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +4 −0 .npmignore
  3. +5 −0 History.md
  4. +7 −0 Makefile
  5. +140 −0 Readme.md
  6. +16 −0 bin/shell
  7. +14 −0 examples/profile.js
  8. +13 −0 examples/replay.js
  9. +2 −0 index.js
  10. +106 −0 lib/builtins.js
  11. +387 −0 lib/nshell.js
  12. +62 −0 lib/process.js
  13. +131 −0 lib/utils.js
  14. +21 −0 package.json
  15. +56 −0 test/utils.js
@@ -0,0 +1,2 @@
+node_modules
+test.js
@@ -0,0 +1,4 @@
+support
+test
+examples
+*.sock
@@ -0,0 +1,5 @@
+
+0.0.1 / 2010-01-03
+==================
+
+ * Initial release
@@ -0,0 +1,7 @@
+
+test:
+ @./node_modules/.bin/mocha \
+ --require should \
+ --reporter spec
+
+.PHONY: test
140 Readme.md
@@ -0,0 +1,140 @@
+
+# nshell
+
+ A work-in-progress scriptable shell written with node.
+
+## Installation
+
+ $ npm install -g nshell
+
+ For now clone and:
+
+ $ npm install
+ $ ./bin/shell
+
+## About
+
+ Just started this as a quick proof of concept,
+ but it's kinda fun! Keep in mind this is not an
+ attempt to become a POSIX shell.
+
+## Features
+
+ Small set of features so far:
+
+ - PS1
+ - pipelining
+ - auto-cd
+ - aliases
+ - sources `~/.profile.js`
+ - saves history to `~/.nshell-history`
+ - brace expansion
+ - filename auto-completion
+ - `.`, `cd`, `which`, `exit`, `!!` builtins
+
+### ~/.profile.js
+
+ By default `nshell(1)` currently sources `~/.profile.js`,
+ this is where you can put config much like other shells.
+
+### PS1
+
+ Change your __PS1__ prompt by exporting a string:
+
+```js
+exports.PS1 = "tj> ";
+```
+
+ Or create something more dynamic and fancy
+ by exporting a function:
+
+```js
+var colors = [31, 32, 33, 34, 35, 36];
+
+exports.PS1 = function(){
+ var color = colors[Math.random() * colors.length | 0];
+ return '\033[' + color + 'm>\033[m ';
+};
+```
+
+### Brace expansion
+
+ Brace expansion works as you'd expect:
+
+```
+> touch foobar
+> touch foobaz
+> rm foo{bar,baz}
+```
+
+### Auto-cd
+
+ By default `nshell(1)` auto-chdirs when
+ the given line is a directory.
+
+```
+> pwd
+> /Users/tj/projects/nshell
+> node_modules/commander
+> pwd
+> /Users/tj/projects/nshell/node_modules/commander
+> ../..
+> pwd
+/Users/tj/projects/nshell
+```
+
+### Aliases
+
+```js
+shell.alias('GET', 'burl GET');
+shell.alias('HEAD', 'burl -I');
+shell.alias('POST', 'burl POST');
+shell.alias('PUT', 'burl PUT');
+shell.alias('PATCH', 'burl PATCH');
+shell.alias('DELETE', 'burl DELETE');
+shell.alias('DEL', 'burl DELETE');
+shell.alias('OPTIONS', 'burl OPTIONS');
+```
+
+## Debugging
+
+```js
+$ DEBUG=nshell ./bin/shell
+> cat Readme.md
+ nshell cmd [{"name":"cat","argv":["Readme.md"]}] +1.1m
+ nshell env {} +0ms
+ nshell which cat +0ms
+ nshell found /bin/cat +2ms
+ nshell spawn /bin/cat ["Readme.md"] +0ms
+ nshell exit 0 +5ms
+ nshell prompt +0ms
+```
+
+## Todo
+
+ tons of shit
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,16 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var program = require('commander')
+ , Shell = require('..');
+
+// options
+
+program.parse(process.argv);
+
+// shell
+
+shell = new Shell(process);
@@ -0,0 +1,14 @@
+
+// source with:
+// > . examples/profile
+
+console.log('loaded!');
+
+var colors = [31, 32, 33, 34, 35, 36];
+
+// export a string or function
+
+exports.PS1 = function(){
+ var color = colors[Math.random() * colors.length | 0];
+ return '\033[' + color + 'm>\033[m ';
+};
@@ -0,0 +1,13 @@
+
+// source with:
+// > . examples/replay
+
+console.log('loaded!');
+
+// repeat the previous command on
+// blank lines. great for automating
+// things like `make test`.
+
+shell.on('blank', function(){
+ shell.exec(shell.lastCommand);
+});
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/nshell');
@@ -0,0 +1,106 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Process = require('./process');
+
+/**
+ * . <filename>
+ */
+
+exports['.'] = function(cmd, shell){
+ var proc = new Process;
+
+ // args required
+ if (!cmd.argv.length) {
+ process.nextTick(function(){
+ proc.error('<filename> required\n');
+ proc.exit(1);
+ });
+
+ return proc;
+ }
+
+ // source
+ shell.source(cmd.argv[0]);
+ process.nextTick(function(){
+ proc.exit(0);
+ });
+
+ return proc;
+};
+
+/**
+ * !! [arg ...]
+ */
+
+exports['!!'] = function(cmd, shell){
+ var proc = new Process;
+
+ shell.rl.history.shift();
+ var last = shell.rl.history[0];
+ last += cmd.argv.join(' ');
+ shell.exec(last);
+
+ return proc;
+};
+
+/**
+ * cd <path>
+ */
+
+exports.cd = function(cmd, shell){
+ var proc = new Process;
+
+ // args required
+ if (!cmd.argv.length) {
+ process.nextTick(function(){
+ proc.error('<path> required\n');
+ proc.exit(1);
+ });
+
+ return proc;
+ }
+
+ // chdir
+ process.chdir(cmd.argv[0]);
+
+ return proc;
+};
+
+/**
+ * which <name>
+ */
+
+exports.which = function(cmd, shell){
+ var proc = new Process;
+
+ // args required
+ if (!cmd.argv.length) {
+ process.nextTick(function(){
+ proc.error('<name> required\n');
+ proc.exit(1);
+ });
+
+ return proc;
+ }
+
+ // lookup
+ process.nextTick(function(){
+ var path = shell.which(cmd.argv[0]);
+ if (!path) return proc.exit(1);
+ proc.write(path + '\n');
+ proc.exit(0);
+ });
+
+ return proc;
+};
+
+/**
+ * exit <status>
+ */
+
+exports.exit = function(cmd, shell){
+ process.exit(parseInt(cmd.argv[0], 10) || 0);
+};
Oops, something went wrong.

0 comments on commit 9cc2228

Please sign in to comment.