Permalink
Browse files

Added REPL history tracking and loading

  • Loading branch information...
1 parent fcf8648 commit 6a9be085a0037d8a11cb91a302a2cdf1c9597f01 Mario Behrendt committed Dec 20, 2012
Showing with 69 additions and 2 deletions.
  1. +11 −0 README.md
  2. +31 −1 lib/index.js
  3. +27 −1 test/index.js
View
@@ -58,6 +58,17 @@ $ chuk db
to your shell, only the db section is loaded.
+## REPL history
+
+`chuk` automatically writes entered commands into a history file, which is then used to populate the repl's history on next boot of `chuk`.
+By default the file `.repl_history` within the current execution folder is used, but this can be changed by the setting the environment variable `REPL_HISTORY` like:
+
+```bash
+REPL_HISTORY='.custom_history' chuk
+```
+
+Using the env variable, one could maintain multiple separate history files within a single project for both writing and reading, which can be handy under special circumstances.
+
## Running the tests
```bash
View
@@ -1,4 +1,5 @@
-var cwd = process.cwd();
+var fs = require('fs')
+ , cwd = process.cwd();
function isFunction(thing) {
return 'function' === typeof thing;
@@ -27,11 +28,40 @@ function getInitFromConfig(env, config) {
}
}
+function addHistory(repl) {
+ var path = process.env.REPL_HISTORY || '.repl_history';
+
+ // Load previous history from file if it already exists
+ if (fs.existsSync(path)) {
+ repl.rli.history = fs.readFileSync(path, 'utf-8').split('\n').reverse();
+
+ // Reset last command, otherwise this would display an empty line
+ repl.rli.history.shift();
+ }
+
+ // Attach history listener
+ var handle = fs.openSync(path, 'a');
+ repl.rli.addListener('line', function(command) {
+ fs.write(handle, command + "\n");
+ });
+
+ // Close handle on exit
+ process.on('exit', function() {
+ fs.closeSync(handle);
+ });
+}
+
function chuk(env, config) {
var chukRepl = createRepl();
+
+ // Track and set repl history
+ addHistory(chukRepl);
+
+ // Load Chukfile
config = config || require(cwd + '/Chukfile');
var init = getInitFromConfig(env, config);
init(chukRepl.context);
+
return chukRepl;
}
View
@@ -1,4 +1,5 @@
-var chuk = require('../')
+var chuk = require('../')
+ , fs = require('fs')
, repl
, config = {
'foo': function(context) {
@@ -20,6 +21,7 @@ describe('chuk', function() {
repl.context.global.should.have.property('foo');
repl.context.global.foo.should.equal('bar');
});
+
it('should load chukfile configuration for given env', function() {
repl = chuk('foo', config);
repl.context.global.should.have.property('foo');
@@ -30,10 +32,34 @@ describe('chuk', function() {
repl.context.global.should.have.property('bar');
repl.context.global.bar.should.equal(123);
});
+
it('should load default configuration if no env given', function() {
repl = chuk(null, config);
repl.context.global.should.have.property('foo');
repl.context.global.should.not.have.property('bar');
repl.context.global.foo.should.equal('default');
});
+
+ it('should write to default history file', function() {
+ var command = 'var i = 1;'
+ , path = '.repl_history';
+
+ repl = chuk(null, config);
+ repl.rli.emit('line', command)
+ fs.existsSync(path).should.be.true;
+ fs.readFileSync(path, 'utf-8').should.include(command);
+ fs.unlink(path);
+ });
+
+ it('should use specified file if REPL_HISTORY is set', function() {
+ var command = 'var f = function() { return true };'
+ , path = '.custom_history';
+
+ process.env.REPL_HISTORY = path;
+ repl = chuk(null, config);
+ repl.rli.emit('line', command)
+ fs.existsSync(path).should.be.true;
+ fs.readFileSync(path, 'utf-8').should.include(command);
+ process.env.REPL_HISTORY = undefined;
+ })
});

0 comments on commit 6a9be08

Please sign in to comment.