{"id":13442291,"url":"https://github.com/clojure-emacs/orchard","last_synced_at":"2025-05-14T12:11:13.874Z","repository":{"id":28163238,"uuid":"116295134","full_name":"clojure-emacs/orchard","owner":"clojure-emacs","description":"A fertile ground for Clojure tooling","archived":false,"fork":false,"pushed_at":"2025-04-25T20:47:17.000Z","size":1974,"stargazers_count":328,"open_issues_count":24,"forks_count":53,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-04-25T21:24:43.830Z","etag":null,"topics":["cider","clojure","orchard","tooling"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clojure-emacs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"bbatsov","patreon":"bbatsov","open_collective":"cider","custom":"https://www.paypal.me/bbatsov"}},"created_at":"2018-01-04T18:44:56.000Z","updated_at":"2025-04-23T06:12:48.000Z","dependencies_parsed_at":"2023-09-27T18:49:48.113Z","dependency_job_id":"c2efe51a-06ab-4b3c-8046-d0090f7fe7e9","html_url":"https://github.com/clojure-emacs/orchard","commit_stats":{"total_commits":605,"total_committers":45,"mean_commits":"13.444444444444445","dds":0.6462809917355372,"last_synced_commit":"a1a6509f8742b891aedd82fe4e8f7656b36ae632"},"previous_names":[],"tags_count":79,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Forchard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Forchard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Forchard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure-emacs%2Forchard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clojure-emacs","download_url":"https://codeload.github.com/clojure-emacs/orchard/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140760,"owners_count":22021219,"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":["cider","clojure","orchard","tooling"],"created_at":"2024-07-31T03:01:43.959Z","updated_at":"2025-05-14T12:11:13.862Z","avatar_url":"https://github.com/clojure-emacs.png","language":"Clojure","funding_links":["https://github.com/sponsors/bbatsov","https://patreon.com/bbatsov","https://opencollective.com/cider","https://www.paypal.me/bbatsov"],"categories":["Clojure"],"sub_categories":[],"readme":"[![CircleCI](https://img.shields.io/circleci/build/github/clojure-emacs/orchard/master.svg)](https://circleci.com/gh/clojure-emacs/orchard/tree/master)\n[![Coverage](https://codecov.io/gh/clojure-emacs/orchard/branch/master/graph/badge.svg)](https://codecov.io/gh/clojure-emacs/orchard/)\n[![Clojars Project](https://img.shields.io/clojars/v/cider/orchard.svg)](https://clojars.org/cider/orchard)\n[![cljdoc badge](https://cljdoc.org/badge/cider/orchard)](https://cljdoc.org/d/cider/orchard/CURRENT)\n[![downloads badge](https://versions.deps.co/cider/orchard/downloads.svg)](https://clojars.org/cider/orchard)\n\n# Orchard\n\nA Clojure library designed to provide common functionality for Clojure\ndevelopment tools (e.g. Clojure editor plugins and IDEs).\n\nRight now `orchard` provides functionality like:\n\n- enhanced apropos\n- classpath utils (alternative for `java.classpath`)\n- value [inspector](https://github.com/clojure-emacs/orchard/blob/master/doc/inspector.org)\n- Java class handling utilities\n- utilities for dealing with metadata\n- namespace utilities\n- fetching ClojureDocs documentation\n- finding function dependencies (other functions invoked by a function) and usages\n- function tracer (alternative for `tools.trace`)\n- simple function profiler\n- fast pretty printing (alternative for `clojure.pprint`)\n- eldoc (function signature) utilities\n- indention data inference\n- stacktrace analysis\n\n## Why?\n\nMuch of the tooling code required to build Clojure editors and smart REPLs\nis tool-agnostic and *should* be reused between tools, instead of copied\nand altered in each and every tool.\n\nHaving a common tooling foundation typically means:\n\n- Better foundation (e.g. more functionality, good documentation, etc) with more contributors\n- Less work for tool authors as they don't have to reinvent the wheel for every tool\n- Happier end users\n\n## Design\n\nOrchard is meant to be used to build programmer tooling relying on inspecting the state of a running REPL.\nREPL-powered tooling has been a core Lisp idea for many years and there are many Clojure libraries\nin that space (e.g. `compliment`, `tools.trace`, `sayid`, etc).\n\nOne thing to keep in mind is that Orchard relies (mostly) on runtime information, not the source code itself.\nIn simple terms - only code that's loaded (evaluated) will be taken under consideration. That's pretty different\nfrom the static analysis approach taken by tools for most programming languages where it's not possible to\neasily inspect the state of running program.\n\nSome other design goals are listed bellow.\n\n### No Runtime Dependencies\n\nOrchard is meant to run alongside your application and we can't have a\ndev tools library interfere with your app right? Dependency collisions are nasty problems which are best solved\nby making sure there can't be any shared libraries to cause the conflict.\n\n### API Optimized for Editors\n\nCode editors can't know what symbols resolve to without consulting a REPL that's why they would typically\nsend a combination of a symbol name and some ns (e.g. the current namespace), so they can be resolved to\nsome var on which an operation would be invoked.\n\nThat's why the majority of the functions in Orchard take a combination of a ns and a symbol instead of a var.\nProbably down the road we'll provide var-friendly versions of most functions as well.\n\n### REPL Agnostic\n\nNo matter whether you're using nREPL, a socket REPL, or prepl, Orchard has your back. nREPL clients might\nopt to wrap some of the Orchard functionality in middleware for convenience (as `cider-nrepl` does), but they\ncan just eval away if they please.\n\n## API Documentation\n\nDocumentation for the master branch as well as tagged releases are available\n[here](https://cljdoc.org/d/cider/orchard).\n\n## Usage\n\n**orchard requires Clojure 1.10+ and Java 8+.**\n\n\u003e [!NOTE]\n\u003e\n\u003e Java 8 is soft-deprecated in Orchard since version 0.29. Core Orchard functionality continues to work on JDK 8, but these following features don't:\n\u003e\n\u003e - Java sources parsing\n\nJust add `orchard` as a dependency and start hacking.\n\n```clojure\n[cider/orchard \"0.34.3\"]\n```\n\nConsult the [API documentation](https://cljdoc.org/d/cider/orchard/CURRENT) to get a better idea about the\nfunctionality that's provided.\n\n## Dealing with Java sources\n\nOrchard interacts with Java source files (`.java` files) in several ways:\n\n- Locates the Java source files to enable the \"jump to definition\" functionality.\n  - Also enables \"jump to file:line\" from the printed stacktrace (a CIDER feature).\n- Parses Java sources to extract additional information about Java interop\n  targets (constructors, methods).\n  - Allows jumping directly to method definition in the Java source file.\n  - Extends the documentation for interop targets with Javadoc comments, exact\n    method argument names.\n\nCurrently, Orchard is able to find Java source files in the following places:\n\n- On the classpath.\n- In the `src.zip` archive that comes together with most JDK distributions.\n- For clases that come from Maven-downloaded dependencies — in the special\n  `-sources.jar` artifact that resides next to the main artifact in the `~/.m2`\n  directory. The sources artifact has to be downloaded ahead of time.\n\nOrchard provides\n`orchard.java.source-files/download-sources-jar-for-coordinates` function to\ndownload the sources by invoking a subprocess with one of the supported build\ntools (Clojure CLI or Leiningen). You can call this function at any point of\ntime on your own. Alternatively, you can bind the dynamic variable\n`orchard.java.source-files/*download-sources-jar-fn*` to a function which\naccepts a Class object, and Orchard will call this function automatically when\nit fails to locate a Java source file for the class. Usage example:\n\n```clj\n(binding [src-files/*download-sources-jar-fn*\n          #(src-files/download-sources-jar-for-coordinates\n            (src-files/infer-maven-coordinates-for-class %))]\n  (class-\u003esource-file-url \u003cclass-arg\u003e))\n```\n\nIf the source file can be located, this is usually enough for basic \"jump to\nsource\" functionality. For a more precise \"jump to definition\" and for\nJavadoc-based documentation, Orcard will attempt to parse the source file.\n\n## Development\n\nHaving JDK sources archive (`$JAVA_HOME/lib/src.zip`) is important for\ndevelopment of Java-related features in Orchard. Certain features parse those\nJava sources as a source of information. The archive doesn't need to be on the\nclasspath, it just need to exist in the distribution.\n\nYou can install Orchard locally like this:\n\n```shell\nPROJECT_VERSION=99.99 make install\n```\n\nFor releasing to [Clojars](https://clojars.org/):\n\n```shell\ngit tag -a vX.Y.Z -m \"Release X.Y.Z\"\ngit push --tags\ngit push\n```\n\n### Tests and formatting\n\nTo run the CI tasks locally use:\n\n``` shell\nmake test cljfmt kondo eastwood\n```\n\n## Caveats and Known Issues\n\n### `xref/fn-deps` and `xref/fn-refs` limitations\n\nThese functions use a Clojure compiler implementation detail to find references to other function var dependencies.\n\nYou can find a more in-depth explanation in this [post](https://lukas-domagala.de/blog/clojure-analysis-and-introspection.html).\n\nThe important implications from this are:\n\n- very fast\n- functions marked with meta `:inline` will not be found (`inc`, `+`, ...)\n- redefining function vars that include lambdas will still return the dependencies of the old plus the new ones\n-[explanation](https://lukas-domagala.de/blog/clojure-compiler-class-cache.html))\n- does not work on AoT compiled functions\n\n### Java 8 support\n\nAs noted earlier Java 8 is soft-deprecated in Orchard since version 0.29. Core\nOrchard funcitonality continues to work on JDK 8, but the following features\ndon't:\n\n- Java sources parsing\n\nWe are aware that some people are stuck using Java 8 and we'll keep supporting\nfor as long as we can, but it's no longer a priority for us that every feature\nworks with Java 8.\n\n## History\n\nOriginally [SLIME][] was the most\npopular way to program in Clojure with Emacs and a lot of useful\nfunctionality was created for it to support things like code\ncompletion, value inspection, finding references, apropos and so\non. This functionality was implemented as a swank adapter written in\nClojure and lived in the\n[swank-clojure][] project.\n\nSubsequently [CIDER][] and\n[cider-nrepl][] replaced\nSLIME and swank, and much code was moved from `swank-clojure` to\n`cider-nrepl` and continued to evolve there.\n\n\u003e [!TIP]\n\u003e\n\u003e You can watch the presentation [The Evolution of the Emacs tooling for\n\u003e Clojure](https://www.youtube.com/watch?v=4X-1fJm25Ww\u0026list=PLZdCLR02grLoc322bYirANEso3mmzvCiI\u0026index=6)\n\u003e to learn more about all of this.\n\nThis project is an effort to prevent repeating the mistakes of the\npast - `cider-nrepl` was split into two libraries, so that non-nREPL\nclients can make of use of the general functionality contained in\n`cider-nrepl` (e.g. things like `apropos`, `inspect`, etc).\n\n## License\n\nCopyright © 2018-2025 Bozhidar Batsov \u0026 contributors\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n\n[SLIME]: https://github.com/slime/slime\n[swank-clojure]: https://github.com/technomancy/swank-clojure\n[CIDER]: https://github.com/clojure-emacs/cider\n[cider-nrepl]:https://github.com/clojure-emacs/cider-nrepl\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure-emacs%2Forchard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclojure-emacs%2Forchard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure-emacs%2Forchard/lists"}