diff options
Diffstat (limited to 'lib/internal/repl.js')
-rw-r--r-- | lib/internal/repl.js | 160 |
1 files changed, 2 insertions, 158 deletions
diff --git a/lib/internal/repl.js b/lib/internal/repl.js index e58752e76e..321f4ab29e 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -1,24 +1,10 @@ 'use strict'; -const { Interface } = require('readline'); const REPL = require('repl'); -const path = require('path'); -const fs = require('fs'); -const os = require('os'); -const util = require('util'); -const debug = util.debuglog('repl'); + module.exports = Object.create(REPL); module.exports.createInternalRepl = createRepl; -// XXX(chrisdickinson): The 15ms debounce value is somewhat arbitrary. -// The debounce is to guard against code pasted into the REPL. -const kDebounceHistoryMS = 15; - -function _writeToOutput(repl, message) { - repl._writeToOutput(message); - repl._refreshLine(); -} - function createRepl(env, opts, cb) { if (typeof opts === 'function') { cb = opts; @@ -55,151 +41,9 @@ function createRepl(env, opts, cb) { if (!Number.isNaN(historySize) && historySize > 0) { opts.historySize = historySize; } else { - // XXX(chrisdickinson): set here to avoid affecting existing applications - // using repl instances. opts.historySize = 1000; } const repl = REPL.start(opts); - if (opts.terminal) { - return setupHistory(repl, env.NODE_REPL_HISTORY, cb); - } - - repl._historyPrev = _replHistoryMessage; - cb(null, repl); -} - -function setupHistory(repl, historyPath, ready) { - // Empty string disables persistent history - if (typeof historyPath === 'string') - historyPath = historyPath.trim(); - - if (historyPath === '') { - repl._historyPrev = _replHistoryMessage; - return ready(null, repl); - } - - if (!historyPath) { - try { - historyPath = path.join(os.homedir(), '.node_repl_history'); - } catch (err) { - _writeToOutput(repl, '\nError: Could not get the home directory.\n' + - 'REPL session history will not be persisted.\n'); - - debug(err.stack); - repl._historyPrev = _replHistoryMessage; - return ready(null, repl); - } - } - - var timer = null; - var writing = false; - var pending = false; - repl.pause(); - // History files are conventionally not readable by others: - // https://github.com/nodejs/node/issues/3392 - // https://github.com/nodejs/node/pull/3394 - fs.open(historyPath, 'a+', 0o0600, oninit); - - function oninit(err, hnd) { - if (err) { - // Cannot open history file. - // Don't crash, just don't persist history. - _writeToOutput(repl, '\nError: Could not open history file.\n' + - 'REPL session history will not be persisted.\n'); - debug(err.stack); - - repl._historyPrev = _replHistoryMessage; - repl.resume(); - return ready(null, repl); - } - fs.close(hnd, onclose); - } - - function onclose(err) { - if (err) { - return ready(err); - } - fs.readFile(historyPath, 'utf8', onread); - } - - function onread(err, data) { - if (err) { - return ready(err); - } - - if (data) { - repl.history = data.split(/[\n\r]+/, repl.historySize); - } else { - repl.history = []; - } - - fs.open(historyPath, 'r+', onhandle); - } - - function onhandle(err, hnd) { - if (err) { - return ready(err); - } - fs.ftruncate(hnd, 0, (err) => { - repl._historyHandle = hnd; - repl.on('line', online); - - // Reading the file data out erases it - repl.once('flushHistory', function() { - repl.resume(); - ready(null, repl); - }); - flushHistory(); - }); - } - - // ------ history listeners ------ - function online() { - repl._flushing = true; - - if (timer) { - clearTimeout(timer); - } - - timer = setTimeout(flushHistory, kDebounceHistoryMS); - } - - function flushHistory() { - timer = null; - if (writing) { - pending = true; - return; - } - writing = true; - const historyData = repl.history.join(os.EOL); - fs.write(repl._historyHandle, historyData, 0, 'utf8', onwritten); - } - - function onwritten(err, data) { - writing = false; - if (pending) { - pending = false; - online(); - } else { - repl._flushing = Boolean(timer); - if (!repl._flushing) { - repl.emit('flushHistory'); - } - } - } -} - - -function _replHistoryMessage() { - if (this.history.length === 0) { - _writeToOutput( - this, - '\nPersistent history support disabled. ' + - 'Set the NODE_REPL_HISTORY environment\nvariable to ' + - 'a valid, user-writable path to enable.\n' - ); - } - this._historyPrev = Interface.prototype._historyPrev; - return this._historyPrev(); + repl.setupHistory(opts.terminal ? env.NODE_REPL_HISTORY : '', cb); } |