dthree / vorpal

Node's framework for interactive CLIs
http://vorpal.js.org
MIT License
5.64k stars 280 forks source link

List filter on fuzzy search #184

Open sandalsoft opened 8 years ago

sandalsoft commented 8 years ago

Crosspost from http://stackoverflow.com/questions/39925201/interactive-fuzzy-search-filter-on-list-with-vorpal. I know you like questions posted on SO for better Vorpal visibility, but I'm posting it here also in case any contributors have any ideas. If that's not appropriate, feel free to close.

First off, great framework! I really want to use it for my current project, but I'm not sure my use case is a good fit. I want to implement an interactive fuzzy search filter on a list within a vorpal shell. The flow would be something like:

Functionally similar to:

I would plugin my own fuzzy search functionality or possibly use the autocomplete (I haven't looked into this part yet). Either way, the searching logic I've got covered, it's the display piece that I'm not sure about.

I've read all of the issues on github and StackOverflow vorpal.js tagged posts and couldn't find anything similar. I'd love to be able to leverage all the functionality vorpal provides and not have to re-implement it with another library.

Is this possible with the current Vorpal API?

Thanks

MatthieuLemoine commented 7 years ago

The problem is that what you are trying to achieve is not a vorpal command as you need stdin to be in raw mode.

You could use the autocomplete with your own autocomplete function and implement your fuzzy search in it :

vorpal
    .command('fuzzy [filter]')
    .autocomplete(fuzzyAutocomplete)
    .description('Fuzzy search on list')
    .action(fuzzy.action);

function fuzzyAutocomplete() {
    const args = vorpal.ui.input().split(' ');
    const filter = args[1];
    // Fuzzy search logic
    return results;
  }

It would work but autocomplete results are not displayed in a list and you can't scroll autocomplete items with arrow keys.

Another solution is to implement a custom prompt type for inquirerjs based on the list prompt with support for a filter.

You could also implement this outside of vorpal as you don't really need Vorpal for that. It can be easily implemented using a Transform stream :

const Transform = require('stream').Transform;

const myFuzzyTransformStream = new Transform({
  transform(chunk, encoding, callback) {
    // Fuzzy search logic
  }
});
process.stdin.setRawMode(true);

process.stdin.pipe(myFuzzyTransformStream).pipe(process.stdout);

See Node stream documentation for more informations.