diff --git a/README.md b/README.md index b801253ea..5a6a891f6 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ The following core Node.js modules (v8.7.0+) have been implemented: | [path](https://nodejs.org/api/path.html) | :heavy_check_mark: | | [process](https://nodejs.org/api/process.html) | :heavy_check_mark: | | [querystring](https://nodejs.org/api/querystring.html) | :heavy_check_mark: | -| [readline](https://nodejs.org/api/readline.html) | | -| [repl](https://nodejs.org/api/repl.html) | | +| [readline](https://nodejs.org/api/readline.html) | :heavy_check_mark: | +| [repl](https://nodejs.org/api/repl.html) | :heavy_check_mark: | | [stream](https://nodejs.org/api/stream.html) | | | [string-decoder](https://nodejs.org/api/string_decoder.html) | :heavy_check_mark: | | [timers](https://nodejs.org/api/timers.html) | :heavy_check_mark: | diff --git a/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala b/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala index 80a6e6e98..99b434604 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala @@ -51,7 +51,7 @@ trait Interface extends IEventEmitter { * If output is set to null or undefined when calling createInterface, nothing is displayed. * @example rl.question(query, callback) */ - def question(query: String, callback: js.Function): Unit = js.native + def question(query: String, callback: js.Function1[String, Any]): Unit = js.native /** * Resumes the readline input stream. @@ -71,7 +71,7 @@ trait Interface extends IEventEmitter { * This will also resume the input stream if it has been paused. * @example rl.write(data[, key]) */ - def write(data: String, key: js.Any): Unit = js.native + def write(data: String, key: Key): Unit = js.native /** * Writes data to output stream, unless output is set to null or undefined when calling createInterface. @@ -81,8 +81,16 @@ trait Interface extends IEventEmitter { */ def write(data: String): Unit = js.native + // TODO: [Symbol.asyncIterator]() } +class Key( + var ctrl: js.UndefOr[Boolean] = js.undefined, + var meta: js.UndefOr[Boolean] = js.undefined, + var shift: js.UndefOr[Boolean] = js.undefined, + var name: js.UndefOr[String] = js.undefined +) extends js.Object + /** * Readline Interface Companion */ diff --git a/app/current/src/main/scala/io/scalajs/nodejs/readline/Readline.scala b/app/current/src/main/scala/io/scalajs/nodejs/readline/Readline.scala index e0349e9a4..b6e857cd2 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/readline/Readline.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/readline/Readline.scala @@ -1,12 +1,13 @@ package io.scalajs.nodejs.readline import io.scalajs.nodejs.events.IEventEmitter +import io.scalajs.nodejs.stream.{Readable, Writable} import scala.scalajs.js import scala.scalajs.js.annotation.JSImport -/** - * Readline allows reading of a stream (such as process.stdin) on a line-by-line basis. +/**reading + * Readline allows of a stream (such as process.stdin) on a line-by-line basis. * To use this module, do require('readline'). * Note that once you've invoked this module, your Node.js program will not terminate until you've closed the interface. * @see https://nodejs.org/api/readline.html @@ -23,13 +24,13 @@ trait Readline extends IEventEmitter { * * @example readline.clearLine(stream, dir) */ - def clearLine(stream: js.Any, dir: Int): Unit = js.native + def clearLine(stream: Writable, dir: Int, callback: js.Function = js.native): Boolean = js.native /** * Clears the screen from the current position of the cursor down. * @example readline.clearScreenDown(stream) */ - def clearScreenDown(stream: js.Any): Unit = js.native + def clearScreenDown(stream: Writable, callback: js.Function = js.native): Boolean = js.native /** * Creates a readline Interface instance. @@ -41,13 +42,17 @@ trait Readline extends IEventEmitter { * Move cursor to the specified position in a given TTY stream. * @example readline.cursorTo(stream, x, y) */ - def cursorTo(stream: js.Any, x: Int, y: Int): Unit = js.native + def cursorTo(stream: Writable, x: Int, y: Int, callback: js.Function = js.native): Unit = js.native + def cursorTo(stream: Writable, x: Int, callback: js.Function): Unit = js.native + def cursorTo(stream: Writable, x: Int): Unit = js.native + + def emitKeypressEvents(stream: Readable, interface: Interface = js.native): Unit = js.native /** * Move cursor relative to it's current position in a given TTY stream. * @example readline.moveCursor(stream, dx, dy) */ - def moveCursor(stream: js.Any, dx: Int, dy: Int): Unit = js.native + def moveCursor(stream: Writable, dx: Int, dy: Int, callback: js.Function = js.native): Unit = js.native } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/readline/ReadlineOptions.scala b/app/current/src/main/scala/io/scalajs/nodejs/readline/ReadlineOptions.scala index e1582ff97..59601cece 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/readline/ReadlineOptions.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/readline/ReadlineOptions.scala @@ -7,9 +7,14 @@ import scala.scalajs.js /** * Readline Options */ -class ReadlineOptions(var input: js.UndefOr[Readable] = js.undefined, - var output: js.UndefOr[Writable] = js.undefined, - var completer: js.UndefOr[js.Function] = js.undefined, - var terminal: js.UndefOr[Boolean] = js.undefined, - var historySize: js.UndefOr[Int] = js.undefined) - extends js.Object +class ReadlineOptions( + var input: js.UndefOr[Readable] = js.undefined, + var output: js.UndefOr[Writable] = js.undefined, + var completer: js.UndefOr[js.Function] = js.undefined, + var terminal: js.UndefOr[Boolean] = js.undefined, + var historySize: js.UndefOr[Int] = js.undefined, + var prompt: js.UndefOr[String] = js.undefined, + var crlfDelay: js.UndefOr[Double] = js.undefined, + var removeHistoryDuplicates: js.UndefOr[Boolean] = js.undefined, + var escapeCodeTimeout: js.UndefOr[Double] = js.undefined +) extends js.Object diff --git a/app/current/src/main/scala/io/scalajs/nodejs/repl/REPL.scala b/app/current/src/main/scala/io/scalajs/nodejs/repl/REPL.scala index 427d90973..8695e0782 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/repl/REPL.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/repl/REPL.scala @@ -1,7 +1,7 @@ package io.scalajs.nodejs.repl import io.scalajs.nodejs.events.IEventEmitter -import io.scalajs.nodejs.net.Socket +import io.scalajs.nodejs.stream import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @@ -13,32 +13,31 @@ import scala.scalajs.js.annotation.JSImport */ @js.native trait REPL extends IEventEmitter { - var REPL_MODE_SLOPPY: String = js.native - var REPL_MODE_STRICT: String = js.native - var REPL_MODE_MAGIC: String = js.native + var REPL_MODE_SLOPPY: js.Symbol = js.native + var REPL_MODE_STRICT: js.Symbol = js.native - /** - * @example repl.start([options]) - */ - def start(options: REPLOptions): REPLServer = js.native - - /** - * @example repl.start([options]) - */ - def start(prompt: String, socket: Socket): REPLServer = js.native - - /** - * @example repl.start([options]) - */ - def start(prompt: String): REPLServer = js.native - - /** - * @example repl.start([options]) - */ - def start(): REPLServer = js.native + @deprecated("Use REPL_MODE_SLOPPY instead", "Node.js v6.0.0") + var REPL_MODE_MAGIC: js.UndefOr[js.Symbol] = js.native + def start(options: StartOptions = js.native): REPLServer = js.native + def start(prompt: String): REPLServer = js.native } +class StartOptions( + var prompt: js.UndefOr[String] = js.undefined, + var input: js.UndefOr[stream.Readable] = js.undefined, + var output: js.UndefOr[stream.Writable] = js.undefined, + var terminal: js.UndefOr[Boolean] = js.undefined, + var eval: js.UndefOr[js.Function4[String, js.Object, String, js.Function, Any]] = js.undefined, + var useColors: js.UndefOr[Boolean] = js.undefined, + var useGlobal: js.UndefOr[Boolean] = js.undefined, + var ignoreUndefined: js.UndefOr[Boolean] = js.undefined, + var writer: js.UndefOr[js.Function1[js.Any, Any]] = js.undefined, + var completer: js.UndefOr[js.Function] = js.undefined, + var replMode: js.UndefOr[js.Symbol] = js.undefined, + var breakEvalOnSigint: js.UndefOr[Boolean] = js.undefined +) extends js.Object + /** * REPL Singleton */ diff --git a/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala b/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala index c5763e438..41c804b28 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala @@ -1,9 +1,11 @@ package io.scalajs.nodejs.repl +import com.thoughtworks.enableIf import io.scalajs.nodejs.events.IEventEmitter import io.scalajs.nodejs.readline.Interface import scala.scalajs.js +import scala.scalajs.js.| /** * REPL Server @@ -16,6 +18,9 @@ trait REPLServer extends IEventEmitter with Interface { */ val context: REPLContext = js.native + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs10) + def clearBufferedCommand(): Unit = js.native + /** * The replServer.defineCommand() method is used to add new .-prefixed commands to the REPL instance. * Such commands are invoked by typing a period (.) followed by the keyword. The cmd is either a Function @@ -27,7 +32,7 @@ trait REPLServer extends IEventEmitter with Interface { * @param keyword The command keyword (without a leading . character). * @param cmd The function to invoke when the command is processed. */ - def defineCommand(keyword: String, cmd: js.Function0[Any]): Unit = js.native + def defineCommand(keyword: String, cmd: DefinedCommand | js.Function1[String, Any]): Unit = js.native /** * The replServer.displayPrompt() method readies the REPL instance for input from the user, printing the @@ -52,8 +57,16 @@ trait REPLServer extends IEventEmitter with Interface { */ def displayPrompt(): Unit = js.native + @enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12) + def setupHistory(historyPath: String, callback: js.Function2[io.scalajs.nodejs.Error, REPLServer, Any]): Unit = + js.native } +class DefinedCommand( + var action: js.Function1[String, Any], + var help: js.UndefOr[String] = js.undefined +) extends js.Object + /** * REPL Server Companion */ diff --git a/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala index 081ddc5c3..823a519e6 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala @@ -25,7 +25,7 @@ package object repl { * @param listener The listener callback */ @inline - def onExit(listener: () => Any): server.type = server.on("exit", listener) + def onExit(listener: () => Any): REPLServer = server.on("exit", listener) /** * The 'reset' event is emitted when the REPL's context is reset. This occurs whenever the .clear command @@ -35,7 +35,7 @@ package object repl { * @param listener The listener callback */ @inline - def onReset(listener: REPLContext => Any): server.type = server.on("reset", listener) + def onReset(listener: REPLContext => Any): REPLServer = server.on("reset", listener) } @@ -47,7 +47,7 @@ package object repl { *