{"id":13646132,"url":"https://github.com/Unrepl/unrepl","last_synced_at":"2025-04-21T17:32:07.093Z","repository":{"id":65536003,"uuid":"83671966","full_name":"Unrepl/unrepl","owner":"Unrepl","description":"A common ground for better Clojure REPLs","archived":false,"fork":false,"pushed_at":"2019-05-28T13:56:11.000Z","size":257,"stargazers_count":231,"open_issues_count":15,"forks_count":17,"subscribers_count":20,"default_branch":"master","last_synced_at":"2024-11-09T19:41:25.365Z","etag":null,"topics":["clojure","repl"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Unrepl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-02T11:48:00.000Z","updated_at":"2024-05-31T07:42:21.000Z","dependencies_parsed_at":"2023-01-27T23:25:13.568Z","dependency_job_id":null,"html_url":"https://github.com/Unrepl/unrepl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unrepl%2Funrepl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unrepl%2Funrepl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unrepl%2Funrepl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unrepl%2Funrepl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Unrepl","download_url":"https://codeload.github.com/Unrepl/unrepl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250100610,"owners_count":21374974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","repl"],"created_at":"2024-08-02T01:02:49.148Z","updated_at":"2025-04-21T17:32:03.340Z","avatar_url":"https://github.com/Unrepl.png","language":"Clojure","funding_links":[],"categories":["Clojure"],"sub_categories":[],"readme":"# unrepl\n\nA REPL-centric approach to tooling, by means of a general purpose stream-based REPL protocol.\n\nUnrepl is the common base for a set of REPL protocols.  It is meant as an upgrade-path from a more basic [nREPL](https://nrepl.xyz) or [Socket REPL](https://clojure.org/reference/repl_and_main#_launching_a_socket_server), and allows different Unrepl-based clients to implement their own extensions to the REPL protocol (e.g. for IDE integration).  Such Unrepl-based clients would send their own server payload (\"blob\") through the basic REPL connection into the target process, to upgrade the server side of this connection with the desired features.  After this upgrade, the client could use the new features on the existing REPL connection.\n\nThe benefit of this process is, that the target process does not need to include REPL code beyond Socket REPL, which is already included in Clojure 1.8+.  Everything else is loaded only when needed and can be extended according to the needs of the client.  Due to the shared common base, it should be easy to share parts of the server implementation between different Unrepl derivatives.\n\nThus Unrepl is intended for toolsmiths and not something a regular user will usually come in direct contact with.  Assuming someone uses \"MyIDE\", they would setup a \"MyIDE REPL\" connection to their program from the \"MyIDE\" UI, and \"MyIDE\" would transparently upgrade the REPL connection to something they could brand as the \"MyIDE REPL\" experience, without the user noticing that something like Unrepl even exists.\n\nUnrepl is really a meant as a foundation for derivative private works used by clients.\n\n## What's \"the blob\"?\n\nThe blob is a piece of clojure code sent to bootstrap an unrepl implementation. It's expected to be static and opaque.\n\n## Why this hypermedia nonsense if the unrepl implementation is private to the client?\n\nWell it decouples the client and its unrepl implementation, making it easier for the client maintainer to reuse or share code of their server implementation with other tools maintainers.\n\nFurthermore if you start considering that a client may ship several blobs (eg one for Clojure, one for Clojurescript) then it allows the client to behave properly independently on the nature of the endpoint. \n\n## Usage\n\nIf you are a simple user, you don't need to care about unrepl proper, not even add it to your project deps. Just use one of the existing clients:\n\n * [Unravel](https://github.com/Unrepl/unravel) a command-line client,\n * [Spiral](https://github.com/Unrepl/spiral) an Emacs one.\n * [Vimpire](https://bitbucket.org/kotarak/vimpire) ([git](https://github.com/kotarak/vimpire)) for Vim\n\nIf you want to develop a client or just understand better what's happening under the hood then try:\n\n```sh\ngit clone https://github.com/Unrepl/unrepl.git\ncd unrepl\n# start a plain repl (non unrepl, non nrepl), so using the clojure command line tools:\nclojure -J-Dclojure.server.repl=\"{:port 5555,:accept clojure.core.server/repl,:server-daemon false}\" \u0026 \n# generate the blob\nclj -m unrepl.make-blob\n# connect, upgrade and enjoy!\nrlwrap cat resources/unrepl/blob.clj - | nc localhost 5555\n```\n\n## Background\n\nImagine a protocol so flexible that you can upgrade it to anything you want.\n\nThis protocol exists, it's a REPL. A standard repl (clojure.main or the socket repl) is not perfect for tooling but it provides a common minimal ground: an input and output streams of characters. Both can be hijacked to install your own handler, including another REPL better suited for its client.\n\nREPL: the ultimate content negotiation protocol!\n\nThe present repository suggests representations for machine-to-machine REPLs and provides a reference implementation.\n\nA REPL is, by nature, a very sequential process: it reads, then evals, then prints, and then starts over. One REPL = One thread. Concurrency is achieved by having several REPLs.\n\nA REPL is also stateful, it is a connected protocol, so the context doesn't need to be transferred constantly.\n\nA REPL is meant for evaluating code.\n\nSome tooling needs (e.g. autocompletion) may be better serviced by a separate connection, which should not necessarily be a REPL (but may have started as a REPL upgraded to something else.)\n\nParts of this specification assumes two REPLs: the main (or user) REPL and the control (or client) REPL.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FUnrepl%2Funrepl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FUnrepl%2Funrepl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FUnrepl%2Funrepl/lists"}