prompts icon indicating copy to clipboard operation
prompts copied to clipboard

💡plugin API

Open brody4hire opened this issue 5 years ago • 6 comments

The one major thing I miss right now in comparison to Inquirer is a list of choices with a separator ref: https://github.com/SBoudrias/Inquirer.js#separator

I do not miss the "reactive interface", would rather see this kind of thing as a higher-layer wrapper.

An ability to extend with plugins would be really nice. It looks like Inquirer offers this kind of capability.

I don't know if this idea would warrant a rewrite or not. In case of a rewrite, I would favor an approach like this: https://understandlegacycode.com/blog/avoid-rewriting-a-legacy-system-from-scratch-by-strangling-it/

brody4hire avatar Feb 26 '20 04:02 brody4hire

Thank you @brodybits. This should be a part of prompts. I'll make it a part of the next rewrite

terkelg avatar Mar 18 '20 00:03 terkelg

For me, even the ability to extend/add onto existing elements would be useful. An example is a situation I had where I wanted a select prompt to support tapping r to reload the list of elements.

In the current form, it's very hacky, but you can abuse the first render to do some overriding:

async askForIssue() {
    let issues = jira.listIssues();
    let reloading = false;

    let result = await prompts({
        type: 'select',
        name: 'issue',
        message: 'Select issue from JIRA:',
        choices: issues.map(issue => ({ title: issue.fields.summary, value: issue })),
        onRender: function () {
            if (this.firstRender) {
                this._ = (c, key) => {
                    if (c === 'r') {
                        reloading = true;
                        this.selection.title = 'Reloading issues...';
                        this.abort();
                    }
                }
            }
        }
    });

    // If user pressed R, refresh and ask again.
    if (reloading) return askForIssue();
    return result.issue;
}

You can also override render, again, a little ugly:

                    // Save old render
                    this._render = this.render;
                    this.render = function () {
                        let addl = chalk.dim(`\n(Press r to reload issues.)`);

                        this._render();
                        if (!this.done) {
                            // Write out the extra stuff and add it to output buffer
                            this.out.write(addl);
                            this.outputText += addl;
                        }
                    };
                    // Force a quick reload on firstRender so our new render runs
                    setTimeout(() => this.render(), 5);

These would be my two most-requested use cases: the ability to take an existing Element and extend it to by adding a couple key presses, or by wrapping and modifying the render() to add/remove text from it.

elliot-nelson avatar Apr 22 '20 17:04 elliot-nelson

I'm surprised you found a way to do it @elliot-nelson. I love small hacks and tweaks where you bend the system into a pretzel. That being said I agree – it's far from ideal. Developer experience will be my main priority for the next major version.

I am quite busy rewriting other modules but I will get to Prompts eventually. This feedback is important and I appreciate it ✋

terkelg avatar Apr 22 '20 19:04 terkelg

I recently discovered enquirer which seems to offer this functionality already, all working on a single dependency on ansi-colors. It also offers really nice forms and snippets functionality.

I think the ideal architecture would be an extremely lean core, just for text input for example, and everything else in plugins.

That said, rewrite has combined costs of delays, missing functionality, and losing bug fixes. https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/

brody4hire avatar Jul 09 '20 17:07 brody4hire

For anyone else looking, I was able to hack together separators/dividers in "select" type lists for expo-cli like this.

Screen Shot 2020-11-17 at 10 00 52 PM

EvanBacon avatar Nov 17 '20 21:11 EvanBacon

That's super cool @EvanBacon – thank you for sharing!

terkelg avatar Nov 17 '20 21:11 terkelg