Rebel Readline

repository·master·Indexed 20 days ago

https://github.com/bhauman/rebel-readline

A high-performance, feature-rich terminal REPL for Clojure and other Clojure dialects. It provides advanced terminal capabilities including multi-line editing, auto-indentation, TAB completion, and inline evaluation. The project includes support for ClojureScript via rebel-readline-cljs and nREPL connectivity via rebel-readline-nrepl.

Tokens
5.3K
Snippets
19
Records
27
Agent score
73%

What's inside rebel-readline

  1. Overview of Rebel Readline purpose and design

    master

    Rebel Readline is designed to provide an enhanced terminal-based readline experience specifically for Clojure programmers. Its primary goal is to facilitate a fluid interactive programming workflow (such as inline-eval) for newcomers and for developers in situations where a full editor-REPL setup is unavailable (e.g., debugging live systems via a spartan terminal).

    Key Design Priorities

    • Minimal Dependencies: Maintains a shallow dependency tree. It uses JLine to handle cross-platform terminal manipulation.
    • Clojure-Centric UX: Leverages S-expressions (sexps) to provide superior text manipulation compared to standard readline libraries.
    • Non-Intrusive: Does not interfere with the input stream when not actively reading a line.
    • Separation of Concerns: The library manages input/readline but is not responsible for REPL output, though it can provide utilities like querying or redisplaying the last line with error pointers.
    • Extensibility: Follows an Emacs-like philosophy where behavior is open and customizable, allowing users to programmatically modify or opt-in to features like paredit.
  2. How Services work in Rebel Readline

    master

    The line reader provides advanced features like completion, documentation, source, apropos, and eval. To enable these, you must supply a Service when creating a rebel-readline.clojure.line-reader.

    • rebel-readline.services.clojure.local: The most common service. It queries the local Clojure process to provide features. This is the recommended service for standard Clojure REPLs.
    • rebel-readline.clojure.service.simple: Use this for remote REPLs like nREPL, SocketREPL, or pREPL where a local service isn't available. While it won't provide full context-aware features, multi-line editing, syntax highlighting, and auto-indenting will still work.

    Mental Model: The service provides the 'intelligence' (the data for completion/docs), while the line-reader provides the 'interface' (the terminal manipulation and UI).

  3. Connect to an nREPL server

    master

    Once an nREPL server is running, use rebel-readline-nrepl to connect.

    If you installed it as a Clojure Tool (using the :nrebel alias), you can connect by specifying the port. If a .nrepl-port file exists in your current directory, the port is detected automatically.

    If the port file is located elsewhere, use the :port-file parameter.

    # Connect via specific port
    clojure -T:nrebel :port 7888
    
    # Connect using automatic .nrepl-port detection
    clojure -T:nrebel
    
    # Connect using a specific port file
    clojure -T:nrebel :port-file '"subproject/.nrepl-port"'
    
    # Connect to a specific host
    clojure -T:nrebel :host localhost :port 7888
  4. Install rebel-readline-nrepl as a Clojure Tool

    master

    To use rebel-readline-nrepl as a global Clojure tool, add it to your ~/.clojure/deps.edn file under an alias. This allows you to run the client from any directory using the clojure -T:<alias> syntax.

    Note: If you are using Java 22 or later, you should include --enable-native-access=ALL-UNNAMED in your :jvm-opts to suppress JLine native access warnings.

    {
      :aliases {
        :nrebel {
          :extra-deps {com.bhauman/rebel-readline-nrepl {:mvn/version "0.1.11"}}
          :exec-fn rebel-readline.nrepl/connect
          :exec-args {:background-print false} ;; Optional configuration parameters
          :main-opts ["-m" "rebel-readline.nrepl.main"]
          :jvm-opts ["--enable-native-access=ALL-UNNAMED"]
        }
      }
    }
  5. Install rebel-readline-nrepl from Git

    master

    You can install the latest version directly from the Git repository. Because the repository contains multiple subprojects, you must specify the :deps/root as rebel-readline-nrepl.

    clojure -Ttools install-latest :lib com.github.bhauman/rebel-readline :coord '{:git/url "https://github.com/bhauman/rebel-readline.git" :deps/root "rebel-readline-nrepl"}' :as nrebel
  6. Install and run Rebel Readline via Leiningen

    master

    To use Rebel Readline with Leiningen, add the dependency to your project.clj: [com.bhauman/rebel-readline "0.1.11"]

    Then start the REPL using trampoline to ensure the terminal is handled correctly:

    lein trampoline run -m rebel-readline.main

    To simplify usage, you can add an alias to your project.clj:

    :aliases {"rebl" ["trampoline" "run" "-m" "rebel-readline.main"]}

    Now you can start the REPL with:

    lein rebl

    You can also install it globally by adding it to your $HOME/.lein/profiles.clj under the :user key.

  7. Install Rebel Readline as a Clojure Tool

    master

    You can install Rebel Readline as a tool from the latest Git release tag using the Clojure CLI tools:

    1. Install the tool:
    clojure -Ttools install-latest :lib com.github.bhauman/rebel-readline :coord '{:git/url "https://github.com/bhauman/rebel-readline.git" :deps/root "rebel-readline"}' :as rebel
    1. Launch the REPL from any project directory:
    clojure -Trebel repl
    clojure -Ttools install-latest :lib com.github.bhauman/rebel-readline :coord '{:git/url "https://github.com/bhauman/rebel-readline.git" :deps/root "rebel-readline"}' :as rebel
    
    clojure -Trebel repl
  8. Quick start with rebel-readline-cljs via Clojure CLI

    master

    To quickly try rebel-readline-cljs without setting up a full project, use the Clojure CLI tools. This will start a Node-backed ClojureScript REPL using the Rebel readline editor.

    Requirements:

    • Clojure CLI tools installed.
    • Java 21 or newer.
    • Node.js available on your PATH.

    Note on Java 22+: On Java 22 and newer, JLine may emit native access warnings. While the REPL will still function, you can suppress these warnings by passing -J--enable-native-access=ALL-UNNAMED to the clojure command. Avoid using the clj command, as it wraps the process with rlwrap, which interferes with the Rebel readline editor.

    # Standard start
    clojure -Sdeps '{:deps {com.bhauman/rebel-readline-cljs {:mvn/version "0.1.11"}}}' -m rebel-readline.cljs.main
    
    # Start with Java native access warnings suppressed
    clojure -J--enable-native-access=ALL-UNNAMED -Sdeps '{:deps {com.bhauman/rebel-readline-cljs {:mvn/version "0.1.11"}}}' -m rebel-readline.cljs.main
  9. Integrate rebel-readline-nrepl into your project

    master

    To include the client directly in your project's dependencies, add it to your project's deps.edn file under an alias.

    {:aliases
     {:nrebelly
      {:extra-deps {com.bhauman/rebel-readline-nrepl {:mvn/version "0.1.11"}}
       :exec-fn rebel-readline.nrepl/connect
       :exec-args {:host "localhost"
                   :port-file "subproject/.nrepl-port"}}}}
  10. Install Rebel Readline via deps.edn Aliases

    master

    To integrate Rebel Readline into your development workflow, add an alias to your ~/.clojure/deps.edn file. This allows you to launch the REPL easily in any project directory.

    Add the following to your :aliases map:

    {:aliases {:rebel {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.11"}}
                       :exec-fn rebel-readline.tool/repl
                       :exec-args {}
                       :main-opts ["-m" "rebel-readline.main"]}}}

    Usage:

    • Launch with: clojure -Xrebel
    • Or as a standalone tool: clojure -T:rebel
  11. Install Rebel Readline with Leiningen

    master

    To use Rebel Readline in a Leiningen project, add the dependency to your project.clj:

    [com.bhauman/rebel-readline "0.1.11"]

    To start the REPL: Use lein trampoline run -m rebel-readline.main.

    Recommended: Create an alias in project.clj to simplify launching:

    :aliases {"
    ebl" ["trampoline" "run" "-m" "rebel-readline.main"]}

    Now you can start the REPL using lein rebl.

    [com.bhauman/rebel-readline "0.1.11"]
    
    :aliases {"rebl" ["trampoline" "run" "-m" "rebel-readline.main"]}