4

I need to have custom REPL input/output stream. for example I need to pass a piece of script to the REPL when some event happens and get it's output and do something with it.


To describe it more clear to you, I'm working on a vscode plugin (github: source code) which provides REPL. in my case I have a vscode WebView and from there, I get user input and then I want to pass that input to the node REPL and get its output and show it to user.

So, how would I achieve that? If you need more information please tell me. thanks in advance.

EDIT 1:

const replServer = repl.start({
    input: /* what should be here? */,
    output: /* what should be here? */
});

Edit 2: can anyone explain me what is the usage of input/output parameters in the above example?

  • how did you solve this problem? – Kelvin Omereshone Aug 14 '21 at 00:22
  • @KelvinOmereshone this problem didn't solved as I was expecting; instead I created a custom VM. see: https://stackoverflow.com/questions/67173347/javascript-do-all-evaluations-in-one-vm and https://stackoverflow.com/questions/67322922/context-preserving-eval – Mohammad Mostafa Dastjerdi Aug 14 '21 at 06:39
  • Interesting I was able to supply custom streams myself and it works but the issue of scope came up as if I declare a variable in the first run that variable will be said to be declared already even after exiting and restarting the REPL – Kelvin Omereshone Aug 17 '21 at 12:36
  • @KelvinOmereshone so can you share your approach with us as an answer to this question? it will be valuable. – Mohammad Mostafa Dastjerdi Aug 17 '21 at 13:28

2 Answers2

3

Here is a solution that worked for me.

const {
    PassThrough
} = require('stream')
const repl = require('repl')


const input = new PassThrough()
const output = new PassThrough()

output.setEncoding('utf-8')



const _repl = repl.start({
    prompt: 'awesomeRepl> ',
    input,
    output
})

_repl.on('exit', function() {
    // Do something when REPL exit
    console.log('Exited REPL...')
})


function evaluate(code) {
    let evaluatedCode = ''
    output.on('data', (chunk) => {
        evaluatedCode += chunk.toString()
        console.log(evaluatedCode)

    })

    input.write(`${code}\n`)
    return result

}

evaluate('2 + 2') // should return 4

Notice created the REPL instance outside the evaluate function so we don't create a new instance for every call of evaluate

1
  1. To create a repl server you just need to do
const repl = require('repl')
repl.start({prompt: "> ", input: input_stream, output: output_stream");

prompt is a string that is the prompt, stream is the input. input_stream needs to be a readable stream, output_stream needs to be a writable one. you can read more about streams here. Once the streams are working you can do

output_stream.on('data', (chunk) => {                                                                                                                                                            
   14   //whatever you do with the data                                                                                                                                                                     
   15 });                
404galore
  • 26
  • 3