bun icon indicating copy to clipboard operation
bun copied to clipboard

CLI readline issues (enquirer)

Open sroussey opened this issue 2 years ago • 2 comments

What version of Bun is running?

0.5.6

What platform is your computer?

Darwin 22.3.0 arm64 arm

What steps can reproduce the bug?

const { MultiSelect } = require('enquirer');
 
const prompt = new MultiSelect({
  name: 'value',
  message: 'Pick your favorite colors',
  limit: 7,
  choices: [
    { name: 'aqua', value: '#00ffff' },
    { name: 'black', value: '#000000' },
    { name: 'blue', value: '#0000ff' },
    { name: 'fuchsia', value: '#ff00ff' },
    { name: 'gray', value: '#808080' },
    { name: 'green', value: '#008000' },
    { name: 'lime', value: '#00ff00' },
    { name: 'maroon', value: '#800000' },
    { name: 'navy', value: '#000080' },
    { name: 'olive', value: '#808000' },
    { name: 'purple', value: '#800080' },
    { name: 'red', value: '#ff0000' },
    { name: 'silver', value: '#c0c0c0' },
    { name: 'teal', value: '#008080' },
    { name: 'white', value: '#ffffff' },
    { name: 'yellow', value: '#ffff00' }
  ]
});
 
prompt.run()
  .then(answer => console.log('Answer:', answer))
  .catch(console.error);

What is the expected behavior?

See example on their site: https://www.npmjs.com/package/enquirer#multiselect-prompt

What do you see instead?

? Pick your favorite colors … ^[[B^[[D^[[Cssdg
687 |       // Parse the key modifier
688 |       keyCtrl = !!(modifier & 4);
689 |       keyMeta = !!(modifier & 10);
690 |       keyShift = !!(modifier & 1);
691 | 
692 |       keyCode = code;

Additional information

Several of the example code snippets fail with bun:

Multi-select prompt, Survey, and the basic Select are ones that I tried that failed. I did not try all. All the ones that require using arrow keys in particular don't work.

sroussey avatar Feb 10 '23 09:02 sroussey

This is probably caused by https://github.com/oven-sh/bun/issues/2025

Jarred-Sumner avatar Feb 10 '23 09:02 Jarred-Sumner

For the keyboard, part I checked the source which does use raw mode:

keypress.listen = (options = {}, onKeypress) => {
  let { stdin } = options;

  if (!stdin || (stdin !== process.stdin && !stdin.isTTY)) {
    throw new Error('Invalid stream passed');
  }

  let rl = readline.createInterface({ terminal: true, input: stdin });
  readline.emitKeypressEvents(stdin, rl);

  let on = (buf, key) => onKeypress(buf, keypress(buf, key), rl);
  let isRaw = stdin.isRaw;

  if (stdin.isTTY) stdin.setRawMode(true);
  stdin.on('keypress', on);
  rl.resume();

  let off = () => {
    if (stdin.isTTY) stdin.setRawMode(isRaw);
    stdin.removeListener('keypress', on);
    rl.pause();
    rl.close();
  };

  return off;
};

sroussey avatar Feb 10 '23 17:02 sroussey

Simple repro with ESM:

import Enquirer from 'enquirer';

const answers = await Enquirer.prompt([
  {
    type: 'input',
    name: 'first_name',
    message: "What's your first name",
  },
]);

console.log(answers);

colinhacks avatar Aug 15 '23 01:08 colinhacks

Fixed by @dylan-conway in Bun v0.8 image

Jarred-Sumner avatar Aug 25 '23 08:08 Jarred-Sumner