Skip to content
Browse files

readline: re-add the Interface#close() method; rename "end" to "close"

The idea here is to reduce the number of times that `setRawMode()` is called
on the `input` stream, since it is expensive, and simply pause()/resume()
should not call it.

So now `setRawMode()` only gets called at the beginning of the Interface
instance, and then when `Interface#close()` is called.

Test case included.
  • Loading branch information...
1 parent 86bd9b6 commit 9c3559f0adce15f400c6792270cde40c1b67c017 @TooTallNate TooTallNate committed
Showing with 104 additions and 13 deletions.
  1. +17 −13 lib/readline.js
  2. +87 −0 test/simple/test-readline-setRawMode.js
View
30 lib/readline.js
@@ -91,7 +91,7 @@ function Interface(input, output, completer, terminal) {
self._normalWrite(data);
});
input.on('end', function() {
- self.emit('end');
+ self.close();
});
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder('utf8');
@@ -236,13 +236,21 @@ Interface.prototype._refreshLine = function() {
};
-Interface.prototype.pause = function() {
- if (this.paused) return;
+Interface.prototype.close = function() {
+ if (this.closed) return;
if (this.terminal) {
if (typeof this.input.setRawMode === 'function') {
- this.input.setRawMode(true);
+ this.input.setRawMode(false);
}
}
+ this.pause();
+ this.closed = true;
+ this.emit('close');
+};
+
+
+Interface.prototype.pause = function() {
+ if (this.paused) return;
this.input.pause();
this.paused = true;
this.emit('pause');
@@ -250,12 +258,8 @@ Interface.prototype.pause = function() {
Interface.prototype.resume = function() {
+ if (!this.paused) return;
this.input.resume();
- if (this.terminal) {
- if (typeof this.input.setRawMode === 'function') {
- this.input.setRawMode(true);
- }
- }
this.paused = false;
this.emit('resume');
};
@@ -584,8 +588,8 @@ Interface.prototype._ttyWrite = function(s, key) {
if (this.listeners('SIGINT').length) {
this.emit('SIGINT');
} else {
- // Pause the stream
- this.pause();
+ // This readline instance is finished
+ this.close();
}
break;
@@ -595,8 +599,8 @@ Interface.prototype._ttyWrite = function(s, key) {
case 'd': // delete right or EOF
if (this.cursor === 0 && this.line.length === 0) {
- this.pause();
- this.emit('end');
+ // This readline instance is finished
+ this.close();
} else if (this.cursor < this.line.length) {
this._deleteRight();
}
View
87 test/simple/test-readline-setRawMode.js
@@ -0,0 +1,87 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+
+
+var assert = require('assert');
+var readline = require('readline');
+var Stream = require('stream');
+
+var stream = new Stream();
+var expectedRawMode = true;
+var rawModeCalled = false;
+var resumeCalled = false;
+var pauseCalled = false;
+
+stream.setRawMode = function(mode) {
+ rawModeCalled = true;
+ assert.equal(mode, expectedRawMode);
+};
+stream.resume = function() {
+ resumeCalled = true;
+};
+stream.pause = function() {
+ pauseCalled = true;
+};
+
+// when the "readline" starts in "terminal" mode,
+// then setRawMode(true) should be called
+var rli = readline.createInterface({
+ input: stream,
+ output: stream,
+ terminal: true
+});
+assert(rli.terminal)
+assert(rawModeCalled);
+assert(resumeCalled);
+assert(!pauseCalled);
+
+
+// pause() should call *not* call setRawMode()
+rawModeCalled = false;
+resumeCalled = false;
+pauseCalled = false;
+rli.pause();
+assert(!rawModeCalled);
+assert(!resumeCalled);
+assert(pauseCalled);
+
+
+// resume() should *not* call setRawMode()
+rawModeCalled = false;
+resumeCalled = false;
+pauseCalled = false;
+rli.resume();
+assert(!rawModeCalled);
+assert(resumeCalled);
+assert(!pauseCalled);
+
+
+// close() should call setRawMode(false)
+expectedRawMode = false;
+rawModeCalled = false;
+resumeCalled = false;
+pauseCalled = false;
+rli.close();
+assert(rawModeCalled);
+assert(!resumeCalled);
+assert(pauseCalled);
+

0 comments on commit 9c3559f

Please sign in to comment.
Something went wrong with that request. Please try again.