Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

ANSI escape codes show up in output when pressing arrow keys, e.g., ^[[A^[[B^[[C^[[D #22

Closed
specious opened this issue Sep 30, 2015 · 9 comments

Comments

@specious
Copy link

ANSI escape codes (e.g., ^[[A^[[B^[[C^[[D) show up in the output when user input is being acquired using readline-sync@1.2.21

Here's a screenshot of the behavior when using bitly-client@1.0.1, where the sequence "up, down, right, left" was recorded as an input of "[A[B[C[D":

ANSI escape codes in bitly-client@1.0.1

Here's a test script that exhibits the behavior:

console.log('You typed: ' + require('readline-sync').question('Type here: '));

Expected behavior I think is for left and right keys to move the caret and up/down arrows to flip through the input history (if enabled). I tested in several terminal emulators on OS X 10.9 with the same results.

@anseki
Copy link
Owner

anseki commented Oct 1, 2015

Hi specious, thanks for your post.

readlineSync deliberately ignore the keys that control something. (e.g. arrow, backspace, home, etc.)
Some platforms (and environments) don't support the ANSI escape sequence. For example, Windows that is non-POSIX without ansi.sys.
Some samples in README use the ANSI escape sequence, those are parsed by Node or another library. (But some samples might not work fine in some environments.)

And current Node doesn't support controlling the readline system library (e.g. like the bash). stty and emulation editable readline are needed (system calling or native add-on). And it has problems in Windows.
readlineSync will not support controlling keys until Node supports those. And it's not used to non-CLI such as ncurses for TUI.

I think that, if you want to let your program run in many environments, you should not use the ANSI escape sequence, or you should consider some measures such as chalk
that recommend cmder.

@anseki
Copy link
Owner

anseki commented Oct 6, 2015

There is no reply, and I close this issue.
If not solved, please reopen it.

@anseki anseki closed this as completed Oct 6, 2015
@specious
Copy link
Author

@anseki, I don't quite follow what you're saying.

For bitly-client, I switched to using the much simpler read module, which handles arrow keys intuitively and doesn't print escape codes.

@anseki
Copy link
Owner

anseki commented Oct 17, 2015

As I said, that behavior differs depending on the environment. That is, it calls the readline system library such as GNU readline.

For example, your sample code in Win 8.1 + Node v4.2.1 or Node v0.12.6:

console.log('You typed: ' + require('readline-sync').question('Type here: '));

First, I typed the text only, 2 times.
01

And then, I pushed the UP, DOWN, RIGHT, LEFT keys. I didn't type character.
02

  1. When UP key was pushed, bar that is last typed text (i.e. history) was shown.
  2. When DOWN key was pushed, nothing changed. (no text at next of bar in history.)
  3. When RIGHT key was pushed, nothing changed. The cursor already positioned at right side of bar.
  4. When LEFT key was pushed, the cursor moved to left.

And then, I pushed the UP key again, and foo was shown.

If you want to let the user use arrow keys in many environments, you should test it in each environments.


The "read" module is wrapper of Readline that is core module.
Remember, readlineSync is "Synchronous Readline". If you don't need "Synchronous", you don't need readlineSync.
And you need no module such as "read" module, if you want to just read text.

For example:

var readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});

readline.question('Type here: ', function(answer) {
  console.log('You typed: ', answer);
  readline.close();
});

@anseki
Copy link
Owner

anseki commented Oct 17, 2015

Of course, I will update readlineSync when those keys be controllable.

@specious
Copy link
Author

@anseki, thank you for your reply, and I appreciate the suggestion to just use readline if that's all I need.

I just switched to using native readline with await so the code flow remains linear.

I originally thought that readline-sync was just an easy way to use readline without needing a callback. Now I took a closer look and realised it doesn't use readline at all and reads stdin directly. So, I take it the point of using readline-sync is to be able to read keyboard input without the calling function having to become asynchronous.

For what it's worth, I just tested the latest readline-sync 1.4.10 in my terminal on a linux system, and it still doesn't let me edit the line and instead prints these same control characters. In other words, it prints control characters instead of moving the cursor on my system.

However, if I run the application with rlwrap, then the line becomes editable.

@anseki
Copy link
Owner

anseki commented Nov 10, 2021

Hi @specious, thank you for the comment.
I think that the readlineSync is not required now since we can write asynchronous code easily by await, etc.

@specious
Copy link
Author

One would think, but what if you've got a synchronous function that other modules depend on (for example getPassword()) and it used to read the password from a file using fs.readFileSync(). And now you want to modify it to ask the user for the password. If you use an async function to do that, then your function will become async too, and all the modules will have to be updated to call it like an async function. Asynchronicity has this cascading effect.

As I understand, in some cases an API update may seem too bothersome.

@anseki
Copy link
Owner

anseki commented Nov 10, 2021

Yes I know that the module is rather used for Utility Methods.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants