readline: consider newlines for cursor position
authorYazhong Liu <yorkiefixer@gmail.com>
Sun, 9 Mar 2014 06:46:54 +0000 (14:46 +0800)
committerNathan Rajlich <nathan@tootallnate.net>
Wed, 12 Mar 2014 17:47:17 +0000 (14:47 -0300)
Fixes #7266.
Closes #7279.

lib/readline.js
test/simple/test-readline-interface.js

index c5d04b9..1fa217c 100644 (file)
@@ -563,6 +563,7 @@ Interface.prototype._historyPrev = function() {
 Interface.prototype._getDisplayPos = function(str) {
   var offset = 0;
   var col = this.columns;
+  var row = 0;
   var code;
   str = stripVTControlCharacters(str);
   for (var i = 0, len = str.length; i < len; i++) {
@@ -570,6 +571,11 @@ Interface.prototype._getDisplayPos = function(str) {
     if (code >= 0x10000) { // surrogates
       i++;
     }
+    if (code === 0x0a) { // new line \n
+      offset = 0;
+      row += 1;
+      continue;
+    }
     if (isFullWidthCodePoint(code)) {
       if ((offset + 1) % col === 0) {
         offset++;
@@ -580,7 +586,7 @@ Interface.prototype._getDisplayPos = function(str) {
     }
   }
   var cols = offset % col;
-  var rows = (offset - cols) / col;
+  var rows = row + (offset - cols) / col;
   return {cols: cols, rows: rows};
 };
 
index d88f64a..930cf22 100644 (file)
@@ -206,6 +206,32 @@ FakeInput.prototype.end = function() {};
   assert.equal(callCount, 1);
   rli.close();
 
+  if (terminal) {
+    // question
+    fi = new FakeInput();
+    rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+    expectedLines = ['foo'];
+    rli.question(expectedLines[0], function() {
+      rli.close();
+    });
+    var cursorPos = rli._getCursorPos();
+    assert.equal(cursorPos.rows, 0);
+    assert.equal(cursorPos.cols, expectedLines[0].length);
+    rli.close();
+
+    // sending a multi-line question
+    fi = new FakeInput();
+    rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
+    expectedLines = ['foo', 'bar'];
+    rli.question(expectedLines.join('\n'), function() {
+      rli.close();
+    });
+    var cursorPos = rli._getCursorPos();
+    assert.equal(cursorPos.rows, expectedLines.length - 1);
+    assert.equal(cursorPos.cols, expectedLines.slice(-1)[0].length);
+    rli.close();
+  }
+
   // wide characters should be treated as two columns.
   assert.equal(readline.isFullWidthCodePoint('a'.charCodeAt(0)), false);
   assert.equal(readline.isFullWidthCodePoint('あ'.charCodeAt(0)), true);