Home

Awesome

readline

GitHub release (latest by date including pre-releases) GitHub (Pre-)Release Date GitHub last commit GitHub

readline provides Scala Native bindings for the GNU Readline Library.

Overview

The goal of this project is to provide an easy-to-use Scala Native facade for the portion of the library that is often used to create REPL's. An example REPL application is provided below that just echos what is typed, however the example also shows how to use readline's history feature including not adding duplicates to the history.

The more "programmer friendly" part of this library is found in the io.github.edadma.readline.facade package. That's the only package you need to import from, as seen in the example below. The other package in the library is io.github.edadma.readline.extern which provides for interaction with the Readline C library using Scala Native interoperability elements from the so-call unsafe namespace. There are no public declarations in the io.github.edadma.readline.facade package that use unsafe types in their parameter or return types, making it a pure Scala facade. Consequently, you never have to worry about memory allocation or type conversions.

Usage

To use this library, libreadline-dev needs to be installed:

sudo apt install libreadline-dev

Include the following in your project/plugins.sbt:

addSbtPlugin("com.codecommit" % "sbt-github-packages" % "0.5.2")

Include the following in your build.sbt:

resolvers += Resolver.githubPackages("edadma")

libraryDependencies += "io.github.edadma" %%% "readline" % "0.1.2"

Use the following import in your code:

import io.github.edadma.readline.facade._

Example

This example provides the skeleton for a REPL with history support, including making sure duplicates don't get added to the history.

import io.github.edadma.readline.facade._

import scala.annotation.tailrec

import Console._

object Main extends App {

  val homeDir       = System.getProperty("user.home")
  val HISTORY_FILE  = s"$homeDir/.my_readline_history"
  var historyExists = read_history(HISTORY_FILE)

  @tailrec
  def repl(): Unit = {
    val prompt = s"${CYAN}type something$RESET> "
    val line   = readline(prompt)

    if (line != null) {
      val s = line.trim

      if (s nonEmpty) {
        println(s"type typed '$s'")

        // do something with 's'

        val prev = history_get(history_base + history_length - 1)

        if (prev == null || prev != s) {
          add_history(s) // only add to history if it's not a duplicate of the previous item

          if (historyExists == 0)
            append_history(1, HISTORY_FILE)
          else {
            historyExists = 0
            write_history(HISTORY_FILE)
          }
        }
      }

      repl()
    }
  }

  repl()

}

Readline C library documentation

The official documentation for the Readline library can be found at readline. The official documentation for the history library can be found at history.

License

LGPL-3.0