summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.dir-locals.el21
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md10
-rw-r--r--.travis.yml53
-rw-r--r--CHANGELOG.md46
-rw-r--r--Cask1
-rw-r--r--Dockerfile2
-rw-r--r--Makefile19
-rw-r--r--README.md6
-rw-r--r--ROADMAP.md87
-rw-r--r--cider-apropos.el2
-rw-r--r--cider-browse-ns.el10
-rw-r--r--cider-browse-spec.el50
-rw-r--r--cider-cheatsheet.el577
-rw-r--r--cider-classpath.el2
-rw-r--r--cider-client.el111
-rw-r--r--cider-common.el44
-rw-r--r--cider-compat.el2
-rw-r--r--cider-debug.el2
-rw-r--r--cider-doc.el19
-rw-r--r--cider-eldoc.el28
-rw-r--r--cider-grimoire.el2
-rw-r--r--cider-inspector.el4
-rw-r--r--cider-interaction.el121
-rw-r--r--cider-macroexpansion.el2
-rw-r--r--cider-mode.el79
-rw-r--r--cider-overlays.el8
-rw-r--r--cider-popup.el2
-rw-r--r--cider-profile.el207
-rw-r--r--cider-repl-history.el10
-rw-r--r--cider-repl.el315
-rw-r--r--cider-resolve.el2
-rw-r--r--cider-scratch.el2
-rw-r--r--cider-selector.el2
-rw-r--r--cider-stacktrace.el9
-rw-r--r--cider-test.el322
-rw-r--r--cider-util.el62
-rw-r--r--cider.el560
-rw-r--r--doc/additional_packages.md22
-rw-r--r--doc/cider-refcard.tex2
-rw-r--r--doc/clojurescript.md215
-rw-r--r--doc/code_completion.md17
-rw-r--r--doc/configuration.md205
-rw-r--r--doc/hacking_on_cider.md8
-rw-r--r--doc/images/dynamic_font_lock_off.pngbin0 -> 126143 bytes
-rw-r--r--doc/images/dynamic_font_lock_on.pngbin0 -> 126438 bytes
-rw-r--r--doc/images/reader_conditionals.pngbin0 -> 137479 bytes
-rw-r--r--doc/index.md5
-rw-r--r--doc/installation.md8
-rw-r--r--doc/interactive_programming.md3
-rw-r--r--doc/navigating_stacktraces.md2
-rw-r--r--doc/running_tests.md18
-rw-r--r--doc/troubleshooting.md65
-rw-r--r--doc/up_and_running.md139
-rw-r--r--doc/using_the_repl.md50
-rw-r--r--mkdocs.yml3
-rw-r--r--nrepl-client.el54
-rw-r--r--nrepl-dict.el2
-rw-r--r--test/cider-apropos-tests.el2
-rw-r--r--test/cider-browse-ns-tests.el2
-rw-r--r--test/cider-classpath-tests.el2
-rw-r--r--test/cider-client-tests.el45
-rw-r--r--test/cider-common-tests.el13
-rw-r--r--test/cider-debug-tests.el2
-rw-r--r--test/cider-eldoc-tests.el2
-rw-r--r--test/cider-error-parsing-tests.el2
-rw-r--r--test/cider-grimoire-tests.el2
-rw-r--r--test/cider-interaction-tests.el20
-rw-r--r--test/cider-overlay-tests.el2
-rw-r--r--test/cider-repl-tests.el14
-rw-r--r--test/cider-selector-tests.el2
-rw-r--r--test/cider-stacktrace-tests.el2
-rw-r--r--test/cider-tests--no-auto.el2
-rw-r--r--test/cider-tests.el59
-rw-r--r--test/cider-util-tests.el6
-rw-r--r--test/nrepl-bencode-tests.el2
-rw-r--r--test/nrepl-client-tests.el2
-rw-r--r--test/nrepl-dict-tests.el2
-rw-r--r--test/scripts/cider-bytecomp-warnings.el46
-rw-r--r--test/scripts/cider-checks.el33
-rw-r--r--test/utils/cider-connection-test-utils.el2
-rwxr-xr-xtravis-ci/install-gnutls.sh51
81 files changed, 2971 insertions, 965 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index 09c620c3..4eefbbfe 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,7 +1,7 @@
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
-((nil
+((emacs-lisp-mode
(bug-reference-url-format . "https://github.com/clojure-emacs/cider/issues/%s")
(indent-tabs-mode)
(fill-column . 80)
@@ -9,7 +9,24 @@
(emacs-lisp-docstring-fill-column . 75)
(checkdoc-symbol-words . ("top-level" "major-mode" "macroexpand-all" "print-level" "print-length"))
(checkdoc-package-keywords-flag)
- (checkdoc-arguments-in-order-flag))
+ (checkdoc-arguments-in-order-flag)
+ (checkdoc-verb-check-experimental-flag)
+ (elisp-lint-indent-specs . ((if-let* . 2)
+ (when-let* . 1)
+ (let* . defun)
+ (nrepl-dbind-response . 2)
+ (cider-save-marker . 1)
+ (cider-propertize-region . 1)
+ (cider--make-result-overlay . 1)
+ ;; need better solution for indenting cl-flet bindings
+ (multiline-comment-handler . defun) ;; cl-flet
+ (insert-label . defun) ;; cl-flet
+ (insert-align-label . defun) ;; cl-flet
+ (insert-rect . defun) ;; cl-flet
+ (cl-defun . 2)
+ (with-parsed-tramp-file-name . 2)
+ (thread-first . 1)
+ (thread-last . 1))))
(emacs-lisp-mode
(bug-reference-bug-regexp . "#\\(?2:[[:digit:]]+\\)")))
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 8c5fca30..d0a5e169 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -9,10 +9,10 @@ by checking the relevant checkboxes):
- [ ] The commits are consistent with our [contribution guidelines][1]
- [ ] You've added tests (if possible) to cover your change(s)
- [ ] All tests are passing (`make test`)
-- [ ] The new code is not generating bytecode or `M-x checkdoc` warnings
-- [ ] You've updated the changelog (if adding/changing user-visible functionality)
-- [ ] You've updated the readme (if adding/changing user-visible functionality)
-- [ ] You've updated the refcard (if you made changes to the commands listed there)
+- [ ] All code passes the linter (`make lint`) which is based on [`elisp-lint`](https://github.com/gonewest818/elisp-lint) and includes
+ - [byte-compilation](https://www.gnu.org/software/emacs/manual/html_node/elisp/Byte-Compilation.html), [`checkdoc`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Tips.html), [check-declare](https://www.gnu.org/software/emacs/manual/html_node/elisp/Declaring-Functions.html), packaging metadata, indentation, and trailing whitespace checks.
+- [ ] You've updated the [changelog][3] (if adding/changing user-visible functionality)
+- [ ] You've updated the [user manual][4] (if adding/changing user-visible functionality)
Thanks!
@@ -21,3 +21,5 @@ manual][2] extremely useful.*
[1]: https://github.com/clojure-emacs/cider/blob/master/.github/CONTRIBUTING.md
[2]: https://cider.readthedocs.io/en/latest/hacking_on_cider/
+[3]: https://github.com/clojure-emacs/cider/blob/master/CHANGELOG.md
+[4]: https://github.com/clojure-emacs/cider/tree/master/doc
diff --git a/.travis.yml b/.travis.yml
index ad31a0ad..0f61f262 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,19 +1,6 @@
sudo: false
language: emacs-lisp
-addons:
- apt:
- packages:
- - autogen
- - ca-certificates
- - curl
- - gcc
- - libgmp-dev
- - m4
- - make
- - pkg-config
- - xz-utils
-
cache:
directories:
- $HOME/local
@@ -23,26 +10,42 @@ env:
- PATH=$HOME/local/bin:$HOME/local/evm/bin:$HOME/local/cask/bin:$PATH
matrix:
- EMACS_BINARY=emacs-24.4-travis MAKE_TEST=test
- - EMACS_BINARY=emacs-24.4-travis MAKE_TEST=test-bytecomp
- EMACS_BINARY=emacs-24.5-travis MAKE_TEST=test
- - EMACS_BINARY=emacs-24.5-travis MAKE_TEST=test-bytecomp
- EMACS_BINARY=emacs-25.1-travis MAKE_TEST=test
- - EMACS_BINARY=emacs-25.1-travis MAKE_TEST=test-bytecomp
- EMACS_BINARY=emacs-25.2-travis MAKE_TEST=test
- - EMACS_BINARY=emacs-25.2-travis MAKE_TEST=test-bytecomp
- EMACS_BINARY=emacs-25.3-travis MAKE_TEST=test
- - EMACS_BINARY=emacs-25.3-travis MAKE_TEST=test-bytecomp
- - EMACS_BINARY=emacs-25.3-travis MAKE_TEST=test-checks
- EMACS_BINARY=emacs-26-pretest-travis MAKE_TEST=test
- - EMACS_BINARY=emacs-26-pretest-travis MAKE_TEST=test-bytecomp
- - EMACS_BINARY=emacs-26-pretest-travis MAKE_TEST=test-checks
- EMACS_BINARY=emacs-git-snapshot-travis MAKE_TEST=test
- - EMACS_BINARY=emacs-git-snapshot-travis MAKE_TEST=test-bytecomp
- - EMACS_BINARY=emacs-git-snapshot-travis MAKE_TEST=test-checks
+
+stages:
+ - check
+ - test
+
+jobs:
+ include:
+ # linting for code quality
+ - stage: check
+ env: EMACS_BINARY=emacs-24.4-travis MAKE_TEST=lint
+ - stage: check
+ env: EMACS_BINARY=emacs-24.5-travis MAKE_TEST=lint
+ - stage: check
+ env: EMACS_BINARY=emacs-25.1-travis MAKE_TEST=lint
+ - stage: check
+ env: EMACS_BINARY=emacs-25.2-travis MAKE_TEST=lint
+ - stage: check
+ env: EMACS_BINARY=emacs-25.3-travis MAKE_TEST=lint
+ - stage: check
+ env: EMACS_BINARY=emacs-26-pretest-travis MAKE_TEST=lint
+ - stage: check
+ env: EMACS_BINARY=emacs-git-snapshot-travis MAKE_TEST=lint
+
+ # "matrix" of tests is implicit in the "test" stage
+
+ allow_failures:
+ - env: EMACS_BINARY=emacs-git-snapshot-travis MAKE_TEST=test
+ - env: EMACS_BINARY=emacs-git-snapshot-travis MAKE_TEST=lint
before_script:
- - sh travis-ci/install-gnutls.sh
- - gnutls-cli -v
- sh travis-ci/install-evm.sh
- evm install $EMACS_BINARY --use --skip
- sh travis-ci/install-cask.sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7462d38..a69c5809 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,52 @@
## master (unreleased)
+## 0.17.0 (2018-05-07)
+
+### New features
+
+* [#2248](https://github.com/clojure-emacs/cider/pull/2248): `cider-repl` can now display recognized images in the REPL buffer.
+* [#2172](https://github.com/clojure-emacs/cider/pull/2172): Render diffs for expected / actual test results.
+* [#2167](https://github.com/clojure-emacs/cider/pull/2167): Add new defcustom `cider-jdk-src-paths`. Configure it to connect stack trace links to Java source code.
+* [#2161](https://github.com/clojure-emacs/cider/issues/2161): Add new interactive command `cider-eval-defun-to-point` which is bound to `C-c C-v (C-)z`. It evaluates the current top-level form up to the point.
+* [#2113](https://github.com/clojure-emacs/cider/issues/2113): Add new interactive commands `cider-eval-last-sexp-in-context` (bound to `C-c C-v (C-)c`) and `cider-eval-sexp-at-point-in-context` (bound to `C-c C-v (C-)b`).
+* Add new interactive command `cider-repl-set-type`.
+* [#1976](https://github.com/clojure-emacs/cider/issues/1976): Add new interactive command `cider-connect-clojurescript`.
+* Add a menu for `cider-browse-ns-mode`.
+* [#2160](https://github.com/clojure-emacs/cider/issues/2160): Make it possible to configure the default `*print-level*` and `*print-length*` via defcustoms (`cider-repl-print-level` and `cider-repl-print-length`).
+* New interactive command `cider-cheatsheet` allows you to browse the Clojure Cheatsheet with an Emacs interface.
+* [#2191](https://github.com/clojure-emacs/cider/issues/2191): Add support for jacking-in just with the `clojure` command-line tool and `tools.deps`.
+* Make it possible to start a Nashorn ClojureScript REPL.
+* [#2235](https://github.com/clojure-emacs/cider/pull/2235): Make the REPL ignore blank input rather than evaluating.
+* [#2241](https://github.com/clojure-emacs/cider/pull/2241): Make `cider-test-ediff` diff eval'ed values.
+* Add support for shadow-cljs to `cider-jack-in`.
+* [#2244](https://github.com/clojure-emacs/cider/issues/2244): Display the REPL type in the modeline.
+* [#2238](https://github.com/clojure-emacs/cider/pull/2238): Allow specifying predicates for entries in `cider-jack-in-lein-plugins` and `cider-jack-in-nrepl-middlewares`.
+* Add support for test selectors. If test all or all loaded is called with a prefix ask for filter test selectors in the minibuffer and only run those tests in the project which match the filters. Add variation of test namespace which asks for filter selectors the same way and only runs a subset of the namespace tests.
+* Add a configuration variable allowing to control whether server output should be redirected to the REPL (`cider-redirect-server-output-to-repl`).
+
+### Bugs Fixed
+
+* [#1913](https://github.com/clojure-emacs/cider/issues/1913): Fix `cider-toggle-buffer-connection` to allow cycling of connection and restoring all connections in cljc buffers.
+* [#2148](https://github.com/clojure-emacs/cider/issues/2148): Fix `jump to definition` working properly when remote `cider-jack-in` and `cider-connect`.
+* Font-lock failed assertions even in tests that were evaluated interactively.
+* [#2102](https://github.com/clojure-emacs/cider/issues/2102): Make `cider-format-buffer` handle mismatched parens gracefully.
+
+### Changes
+
+* [#2163](https://github.com/clojure-emacs/cider/issues/2163): Add `cider-browse-spec-regex`, and changed `cider-browse-spec-all` to use it.
+* [#2029](https://github.com/clojure-emacs/cider/pull/2154): Make cider-doc use cider-browse-spec functionality to print the spec part of the doc buffer
+* [#2151](https://github.com/clojure-emacs/cider/pull/2151): Improve formatting of spec in `cider-doc` buffer.
+* Remove support for CLJX.
+* Fix `cider-eval-region` masking `clojure-refactor-map` in `cider-repl-mode`.
+* [#2171](https://github.com/clojure-emacs/cider/issues/2171): Update `See Also` mappings for Clojure 1.9.
+* [#2202](https://github.com/clojure-emacs/cider/issues/2202): Make `cider-jack-in-clojurescript` prompt from the ClojureScript REPL type to use.
+* [#2202](https://github.com/clojure-emacs/cider/issues/2202): Don't try to start a ClojureScript REPL before checking whether that's possible or not.
+* [orchard#24](https://github.com/clojure-emacs/orchard/pull/24): Inspector now separately renders clickable keys and values when inspecting maps.
+* [orchard#24](https://github.com/clojure-emacs/orchard/pull/24): Inspector now remembers the current page of each level of nesting when navigating big and nested collection.
+* Require piggieback 0.3 or newer.
+* Drops support for Rhino in favour of the modern Nashorn.
+
## 0.16.0 (2017-12-28)
### New Features
diff --git a/Cask b/Cask
index 5efaac0a..9f97c365 100644
--- a/Cask
+++ b/Cask
@@ -6,5 +6,6 @@
(files "*.el" (:exclude ".dir-locals.el"))
(development
+ (depends-on "elisp-lint")
(depends-on "buttercup")
(depends-on "markdown-mode"))
diff --git a/Dockerfile b/Dockerfile
index 58a1cb32..e610bdea 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM travisci/ci-garnet:packer-1490989530
+FROM travisci/ci-garnet:packer-1512502276-986baf0
RUN apt-get update -y \
&& apt-get install -y \
diff --git a/Makefile b/Makefile
index 93c0d966..5f95e4e9 100644
--- a/Makefile
+++ b/Makefile
@@ -5,9 +5,10 @@ VERSION = $(shell git describe --tags --abbrev=0 | sed 's/^v//')
PACKAGE_NAME = cider-$(VERSION)
ELS = $(wildcard *.el)
+LINTELS = $(filter-out cider-autoloads.el,$(ELS))
OBJECTS = $(ELS:.el=.elc)
-.PHONY: elpa build version test test-checks test-bytecomp test-all clean elpaclean run-cider
+.PHONY: elpa build version test lint clean elpaclean run-cider
.depend: $(ELS)
@echo Compute dependencies
@@ -34,15 +35,15 @@ version:
test: version build
$(CASK) exec buttercup -L . -L ./test/utils/
-test-checks: version elpa
- $(CASK) exec $(EMACS) --no-site-file --no-site-lisp --batch \
- -l test/scripts/cider-checks.el ./
+lint: version elpa
+ $(CASK) exec $(EMACS) -Q --batch \
+ --eval "(setq enable-local-variables :safe)" \
+ -l elisp-lint.el -f elisp-lint-files-batch \
+ --no-package-format \
+ --no-fill-column \
+ $(LINTELS)
-test-bytecomp: version elpa
- $(CASK) exec $(EMACS) --no-site-file --no-site-lisp --batch \
- -l test/scripts/cider-bytecomp-warnings.el $(ELS)
-
-test-all: test-checks test-bytecomp test
+test-all: lint test
clean:
rm -f .depend $(OBJECTS)
diff --git a/README.md b/README.md
index bb358f63..227c61ce 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ CIDER is the successor to the now deprecated combination of using [SLIME][] +
The instructions that follow are meant to get you from zero to a running CIDER
REPL in under 5 minutes. See the
-[official manual](http://cider.readthedocs.org/en/latest/) for (way) more
+[official manual](http://cider.readthedocs.io/en/latest/) for (way) more
details.
### Installation
@@ -91,7 +91,7 @@ In Clojure(Script) buffers the command `cider-connect` is bound to <kbd>C-c M-c<
CIDER packs a ton of functionality and you really want to be familiar with it,
so you can fully empower your workflow. The best way to get acquainted with all
available features is to go over the entire
-[CIDER manual](http://cider.readthedocs.org/).
+[CIDER manual](http://cider.readthedocs.io/).
If you're into video lessons, you might also check out
this [intro to CIDER demo](https://www.youtube.com/watch?v=aYA4AAjLfT0) as well.
@@ -244,7 +244,7 @@ site. [[Become a sponsor](https://opencollective.com/cider#sponsor)]
## License
-Copyright © 2012-2017 Tim King, Phil Hagelberg, Bozhidar Batsov, Artur Malabarba and
+Copyright © 2012-2018 Tim King, Phil Hagelberg, Bozhidar Batsov, Artur Malabarba and
[contributors](https://github.com/clojure-emacs/cider/contributors).
Distributed under the GNU General Public License, version 3
diff --git a/ROADMAP.md b/ROADMAP.md
new file mode 100644
index 00000000..daf9df1a
--- /dev/null
+++ b/ROADMAP.md
@@ -0,0 +1,87 @@
+# CIDER Roadmap (as of May, 2018)
+
+That's a very high-level roadmap for CIDER. It focuses on the most
+important challenges we need to tackle.
+
+It's meant to give users a general idea about the direction we
+envision for the project's future, and collaborators a good list of
+high-impact tasks to tackle.
+
+## Major Missing Features
+
+* find-references (https://github.com/clojure-emacs/cider/issues/1840)
+* basic refactoring stuff (potentially related to the merger of stuff from clj-refactor.el)
+* highlight symbol occurrences (https://github.com/clojure-emacs/cider/issues/1461)
+* macrostep style of macro expansion (https://github.com/clojure-emacs/cider/issues/1850)
+
+## Internal improvements
+
+* replace usages of Elisp's `read` with `parseclj`
+* break down `cider-interaction.el` and remove this file completely
+* improve the connection management (https://github.com/clojure-emacs/cider/pull/2069)
+* improve nREPL callback handling (https://github.com/clojure-emacs/cider/issues/1099)
+* better handling for huge output/results (we can warn users about it, truncate it in the REPL and store the whole result internally, etc)
+
+## Better ClojureScript support
+
+### Make it easier to start ClojureScript REPLs
+
+* Implement some deps injection for ClojureScript REPLs
+* Providing meaningful errors when starting ClojureScript REPLs
+* Make it possible to have a project with only a ClojureScript REPL
+* Merge cljs-tooling into orchard and evolve it a bit (under
+ consideration, might be better to keep it a separate library)
+* Add ability to restart a ClojureScript REPL (https://github.com/clojure-emacs/cider/issues/1874)
+
+### Add ClojureScript support for more commands
+
+* clojure.test
+* tracing
+
+### Always show meaningful errors if a command is not supported under ClojureScript
+
+Right now it's very confusing if you try to run a Clojure-only command with a ClojureScript REPL.
+You'd get some really weird error instead of something nice like "command X is not supported for ClojureScript".
+
+### Add debugging support for ClojureScript
+
+There's a bit of info on the subject [here](https://github.com/clojure-emacs/cider/issues/1416).
+
+## Gradual merger with refactor-nrepl
+
+It would make sense to move some important refactor-nrepl
+functionality into CIDER, provided it doesn't depend on anything
+complex (e.g. building an AST for the entire project).
+
+Below follow a few such candidates.
+
+This merger also relies on collaboration from the refactor-nrepl team.
+
+### Move hotload deps to CIDER
+
+### Move the ns-cleanup functionality to CIDER
+
+## Socket REPL support (and potentially unrepl/prepl support as well)
+
+Eventually we want to support socket REPLs of any kind (plain, unrepl,
+prepl) in the same manner we support nREPL today (meaning everything
+should work with them). The bulk of the work to achieve this is
+related to making the CIDER client and server code nREPL agnostic,
+so. Work for this is already underway with respect to the server code
+(that's the `orchard` project), but hasn't started on the client
+(Emacs) side.
+
+### Decouple the CIDER code from nREPL
+
+* Isolate the connection-specific code in a couple of client libraries and build a
+generic API on top of them dispatching based on the connection type.
+
+### Implement a socket REPL client
+
+That should be relatively straightforward, as the communication
+protocol for the socket REPL is pretty simple. `parseclj` should be
+used to "encode/decode" EDN data.
+
+### Transition everything non-nREPL specific to Orchard
+
+Already in progress, a lot of functionality already lives is orchard as of version 0.1.
diff --git a/cider-apropos.el b/cider-apropos.el
index ee214622..c92d521c 100644
--- a/cider-apropos.el
+++ b/cider-apropos.el
@@ -1,6 +1,6 @@
;;; cider-apropos.el --- Apropos functionality for Clojure -*- lexical-binding: t -*-
-;; Copyright © 2014-2017 Jeff Valk, Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
;;
;; Author: Jeff Valk <jv@jeffvalk.com>
diff --git a/cider-browse-ns.el b/cider-browse-ns.el
index 8bb755dc..f6a93fce 100644
--- a/cider-browse-ns.el
+++ b/cider-browse-ns.el
@@ -1,6 +1,6 @@
;;; cider-browse-ns.el --- CIDER namespace browser
-;; Copyright © 2014-2017 John Andrews, Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 John Andrews, Bozhidar Batsov and CIDER contributors
;; Author: John Andrews <john.m.andrews@gmail.com>
@@ -41,6 +41,7 @@
(require 'cider-compat)
(require 'cider-util)
(require 'nrepl-dict)
+(require 'easymenu)
(defconst cider-browse-ns-buffer "*cider-ns-browser*")
(add-to-list 'cider-ancillary-buffers cider-browse-ns-buffer)
@@ -58,6 +59,13 @@
(define-key map "^" #'cider-browse-ns-all)
(define-key map "n" #'next-line)
(define-key map "p" #'previous-line)
+ (easy-menu-define cider-browse-ns-mode-menu map
+ "Menu for CIDER's namespace browser"
+ '("Namespace Browser"
+ ["Show doc" cider-browse-ns-doc-at-point]
+ ["Go to definition" cider-browse-ns-find-at-point]
+ "--"
+ ["Browse all namespaces" cider-browse-ns-all]))
map))
(defvar cider-browse-ns-mouse-map
diff --git a/cider-browse-spec.el b/cider-browse-spec.el
index da4440b2..b88ca300 100644
--- a/cider-browse-spec.el
+++ b/cider-browse-spec.el
@@ -36,12 +36,12 @@
(require 'cider-client)
(require 'cider-compat)
-(require 'cider-interaction)
(require 'cider-util)
(require 'cl-lib)
(require 'nrepl-dict)
(require 'seq)
(require 'subr-x)
+(require 'help-mode)
;; The buffer names used by the spec browser
(defconst cider-browse-spec-buffer "*cider-spec-browser*")
@@ -233,16 +233,32 @@ Display TITLE at the top and SPECS are indented underneath."
;; prettier (s/fspec )
((cider--spec-fn-p form-tag "fspec")
(thread-last (seq-partition (cl-rest form) 2)
+ (cl-remove-if (lambda (s) (and (stringp (cl-second s))
+ (string-empty-p (cl-second s)))))
(mapcar (lambda (s)
- (concat "\n" (cl-first s) " " (cider-browse-spec--pprint (cl-second s)))))
+ (format "\n%-11s: %s" (pcase (cl-first s)
+ (":args" "arguments")
+ (":ret" "returns")
+ (":fn" "invariants"))
+ (cider-browse-spec--pprint (cl-second s)))))
(cl-reduce #'concat)
- (format "(s/fspec \n %s)")))
+ (format "%s")))
;; every other with no special management
(t (format "(%s %s)"
(cider-browse-spec--pprint form-tag)
(string-join (mapcar #'cider-browse-spec--pprint (cl-rest form)) " "))))))
(t (format "%s" form))))
+(defun cider-browse-spec--pprint-indented (spec-form)
+ "Indent (pretty-print) and font-lock SPEC-FORM.
+Return the result as a string."
+ (with-temp-buffer
+ (clojure-mode)
+ (insert (cider-browse-spec--pprint spec-form))
+ (indent-region (point-min) (point-max))
+ (cider--font-lock-ensure)
+ (buffer-string)))
+
(defun cider-browse-spec--draw-spec-buffer (buffer spec spec-form)
"Reset contents of BUFFER and draws everything needed to browse the SPEC-FORM.
Display SPEC as a title and uses `cider-browse-spec--pprint' to display
@@ -252,12 +268,7 @@ a more user friendly representation of SPEC-FORM."
(cider--help-setup-xref (list #'cider-browse-spec spec) nil buffer)
(goto-char (point-max))
(insert (cider-font-lock-as-clojure spec) "\n\n")
- (insert (with-temp-buffer
- (clojure-mode)
- (insert (cider-browse-spec--pprint spec-form))
- (indent-region (point-min) (point-max))
- (cider--font-lock-ensure)
- (buffer-string)))
+ (insert (cider-browse-spec--pprint-indented spec-form))
(cider--make-back-forward-xrefs)
(current-buffer))))
@@ -320,16 +331,12 @@ Generates a new example for the current spec."
(cider-symbol-at-point))))
(cider-browse-spec--browse spec))
-;;;###autoload
-(defun cider-browse-spec-all (&optional arg)
- "Open list of specs in a popup buffer.
-
-With a prefix argument ARG, prompts for a regexp to filter specs.
-No filter applied if the regexp is the empty string."
- (interactive "P")
+(defun cider-browse-spec-regex (regex)
+ "Open the list of specs that matches REGEX in a popup buffer.
+Displays all specs when REGEX is nil."
(cider-ensure-connected)
(cider-ensure-op-supported "spec-list")
- (let ((filter-regex (if arg (read-string "Filter regex: ") "")))
+ (let ((filter-regex (or regex "")))
(with-current-buffer (cider-popup-buffer cider-browse-spec-buffer t)
(let ((specs (cider-sync-request:spec-list filter-regex)))
(cider-browse-spec--draw-list-buffer (current-buffer)
@@ -338,6 +345,15 @@ No filter applied if the regexp is the empty string."
(format "All specs matching regex `%s' in registry" filter-regex))
specs)))))
+;;;###autoload
+(defun cider-browse-spec-all (&optional arg)
+ "Open list of specs in a popup buffer.
+
+With a prefix argument ARG, prompts for a regexp to filter specs.
+No filter applied if the regexp is the empty string."
+ (interactive "P")
+ (cider-browse-spec-regex (if arg (read-string "Filter regex: ") "")))
+
(provide 'cider-browse-spec)
;;; cider-browse-spec.el ends here
diff --git a/cider-cheatsheet.el b/cider-cheatsheet.el
new file mode 100644
index 00000000..d870c5a5
--- /dev/null
+++ b/cider-cheatsheet.el
@@ -0,0 +1,577 @@
+;;; cider-cheatsheet.el --- Quick reference for Clojure -*- lexical-binding: t -*-
+
+;; Copyright © 2018 Kris Jenkins, Bozhidar Batsov and CIDER contributors
+;;
+;; Author: Kris Jenkins <krisajenkins@gmail.com>
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; A quick reference system for Clojure. Fast, searchable & available offline.
+
+;; Mostly taken from Kris Jenkins' `clojure-cheatsheet'
+;; See: https://github.com/clojure-emacs/clojure-cheatsheet
+
+;;; Code:
+
+(require 'cider-doc)
+(require 'seq)
+
+(defconst cider-cheatsheet-hierarchy
+ '(("Primitives"
+ ("Numbers"
+ ("Arithmetic"
+ (clojure.core + - * / quot rem mod dec inc max min))
+ ("Compare"
+ (clojure.core = == not= < > <= >= compare))
+ ("Bitwise"
+ (clojure.core bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor unsigned-bit-shift-right))
+ ("Cast"
+ (clojure.core byte short long int float double bigdec bigint biginteger num rationalize))
+ ("Test"
+ (clojure.core nil? some? identical? zero? pos? neg? even? odd?))
+ ("Random"
+ (clojure.core rand rand-int))
+ ("BigDecimal"
+ (clojure.core with-precision))
+ ("Ratios"
+ (clojure.core numerator denominator ratio?))
+ ("Arbitrary Precision Arithmetic"
+ (clojure.core +\' -\' *\' inc\' dec\'))
+ ("Unchecked"
+ (clojure.core *unchecked-math*
+ unchecked-add
+ unchecked-add-int
+ unchecked-byte
+ unchecked-char
+ unchecked-dec
+ unchecked-dec-int
+ unchecked-divide-int
+ unchecked-double
+ unchecked-float
+ unchecked-inc
+ unchecked-inc-int
+ unchecked-int
+ unchecked-long
+ unchecked-multiply
+ unchecked-multiply-int
+ unchecked-negate
+ unchecked-negate-int
+ unchecked-remainder-int
+ unchecked-short
+ unchecked-subtract
+ unchecked-subtract-int)))
+
+ ("Strings"
+ ("Create"
+ (clojure.core str format))
+ ("Use"
+ (clojure.core count get subs compare)
+ (clojure.string join escape split split-lines replace replace-first reverse re-quote-replacement index-of last-index-of starts-with? ends-with? includes?))
+ ("Regex"
+ (clojure.core re-find re-seq re-matches re-pattern re-matcher re-groups)
+ (clojure.string replace replace-first re-quote-replacement))
+ ("Letters"
+ (clojure.string capitalize lower-case upper-case))
+ ("Trim"
+ (clojure.string trim trim-newline triml trimr))
+ ("Test"
+ (clojure.core char char? string?)
+ (clojure.string blank?)))
+
+ ("Other"
+ ("Characters"
+ (clojure.core char char-name-string char-escape-string))
+ ("Keywords"
+ (clojure.core keyword keyword? find-keyword))
+ ("Symbols"
+ (clojure.core symbol symbol? gensym))
+ ("Data Readers"
+ (clojure.core *data-readers* default-data-readers *default-data-reader-fn*))))
+
+ ("Collections"
+ ("Generic Ops"
+ (clojure.core count bounded-count empty not-empty into conj))
+ ("Tree Walking"
+ (clojure.walk walk prewalk prewalk-demo prewalk-replace postwalk postwalk-demo postwalk-replace keywordize-keys stringify-keys))
+ ("Content tests"
+ (clojure.core distinct? empty? every? not-every? some not-any?))
+ ("Capabilities"
+ (clojure.core sequential? associative? sorted? counted? reversible?))
+ ("Type tests"
+ (clojure.core type class coll? list? vector? set? map? seq?
+ number? integer? float? decimal? class? rational? ratio?
+ chunked-seq? reduced? special-symbol? record?))
+ ("Lists"
+ ("Create"
+ (clojure.core list list*))
+ ("Examine"
+ (clojure.core first nth peek))
+ ("Change"
+ (clojure.core cons conj rest pop)))
+
+ ("Vectors"
+ ("Create"
+ (clojure.core vec vector vector-of))
+ ("Examine"
+ (clojure.core get peek))
+
+ ("Change"
+ (clojure.core assoc pop subvec replace conj rseq))
+ ("Ops"
+ (clojure.core mapv filterv reduce-kv)))
+
+ ("Sets"
+ ("Create"
+ (clojure.core set hash-set sorted-set sorted-set-by))
+ ("Examine"
+ (clojure.core get contains?))
+ ("Change"
+ (clojure.core conj disj))
+ ("Relational Algebra"
+ (clojure.set join select project union difference intersection))
+ ("Get map"
+ (clojure.set index rename-keys rename map-invert))
+ ("Test"
+ (clojure.set subset? superset?))
+ ("Sorted Sets"
+ (clojure.core rseq subseq rsubseq)))
+
+ ("Maps"
+ ("Create"
+ (clojure.core hash-map array-map zipmap sorted-map sorted-map-by bean frequencies group-by))
+ ("Examine"
+ (clojure.core get get-in contains? find keys vals map-entry?))
+ ("Change"
+ (clojure.core assoc assoc-in dissoc merge merge-with select-keys update update-in))
+ ("Entry"
+ (clojure.core key val))
+ ("Sorted Maps"
+ (clojure.core rseq subseq rsubseq)))
+
+ ("Hashes"
+ (clojure.core hash hash-ordered-coll hash-unordered-coll mix-collection-hash))
+
+ ("Volatiles"
+ (clojure.core volatile! volatile? vreset! vswap!)))
+
+ ("Functions"
+ ("Create"
+ (clojure.core fn defn defn- definline identity constantly comp complement partial juxt memfn memoize fnil every-pred some-fn trampoline))
+ ("Call"
+ (clojure.core -> ->> some-> some->> as-> cond-> cond->>))
+ ("Test"
+ (clojure.core fn? ifn?)))
+
+ ("Transducers"
+ ("Create"
+ (clojure.core cat dedupe distinct drop drop-while filter halt-when interpose keep keep-indexed map map-indexed mapcat partition-all partition-by random-sample remove replace take take-nth take-while))
+ ("Call"
+ (clojure.core ->Eduction eduction into sequence transduce completing run!))
+ ("Early Termination"
+ (clojure.core deref reduced reduced? ensure-reduced unreduced)))
+
+ ("Spec"
+ ("Operations"
+ (clojure.spec.alpha valid? conform unform explain explain-data explain-str explain-out form describe assert check-asserts check-asserts?))
+ ("Generator Ops"
+ (clojure.spec.alpha gen exercise exercise-fn))
+ ("Defn & Registry"
+ (clojure.spec.alpha def fdef registry get-spec spec? spec with-gen))
+ ("Logical"
+ (clojure.spec.alpha and or))
+ ("Collection"
+ (clojure.spec.alpha coll-of map-of every every-kv keys merge))
+ ("Regex "
+ (clojure.spec.alpha cat alt * + \? & keys*))
+ ("Range"
+ (clojure.spec.alpha int-in inst-in double-in int-in-range? inst-in-range?))
+ ("Custom Explain"
+ (clojure.spec.alpha explain-printer *explain-out*))
+ ("Other"
+ (clojure.spec.alpha nilable multi-spec fspec conformer))
+
+ ("Predicates with test.check generators"
+ ("Numbers"
+ (clojure.core number? rational? integer? ratio? decimal? float? zero? double? int? nat-int? neg-int? pos-int?))
+ ("Symbols & Keywords"
+ (clojure.core keyword? symbol? ident? qualified-ident? qualified-keyword? qualified-symbol? simple-ident? simple-keyword? simple-symbol?))
+ ("Scalars"
+ (clojure.core string? true? false? nil? some? boolean? bytes? inst? uri? uuid?))
+ ("Collections"
+ (clojure.core list? map? set? vector? associative? coll? sequential? seq? empty? indexed? seqable?))
+ ("Other"
+ (clojure.core any?))))
+
+ ("Other"
+ ("XML"
+ (clojure.core xml-seq)
+ (clojure.xml parse))
+ ("REPL"
+ (clojure.core *1 *2 *3 *e *print-dup* *print-length* *print-level* *print-meta* *print-readably*))
+ ("EDN"
+ (clojure.edn read read-string))
+ ("Compiling Code & Class Generation"
+ (clojure.core *compile-files* *compile-path* *file* *warn-on-reflection* compile gen-class gen-interface loaded-libs test))
+ ("Misc"
+ (clojure.core eval force name *clojure-version* clojure-version *command-line-args*))
+ ("Pretty Printing"
+ (clojure.pprint pprint print-table pp *print-right-margin*))
+ ("Browser / Shell"
+ (clojure.java.browse browse-url)
+ (clojure.java.shell sh with-sh-dir with-sh-env)))
+
+ ("Vars & Global Environment"
+ ("Def Variants"
+ (:special def)
+ (clojure.core defn defn- definline defmacro defmethod defmulti defonce defrecord))
+ ("Interned Vars"
+ (:special var)
+ (clojure.core declare intern binding find-var))
+ ("Var Objects"
+ (clojure.core with-local-vars var-get var-set alter-var-root var?))
+ ("Var Validators"
+ (clojure.core set-validator! get-validator)))
+
+ ("Reader Conditionals"
+ (clojure.core reader-conditional reader-conditional? tagged-literal tagged-literal?))
+
+ ("Abstractions"
+ ("Protocols"
+ (clojure.core defprotocol extend extend-type extend-protocol reify extends? satisfies? extenders))
+ ("Records & Types"
+ (clojure.core defrecord deftype))
+ ("Multimethods"
+ ("Define"
+ (clojure.core defmulti defmethod))
+ ("Dispatch"
+ (clojure.core get-method methods))
+ ("Remove"
+ (clojure.core remove-method remove-all-methods))
+ ("Prefer"
+ (clojure.core prefer-method prefers))
+ ("Relation"
+ (clojure.core derive isa? parents ancestors descendants make-hierarchy))))
+
+ ("Macros"
+ ("Create"
+ (clojure.core defmacro definline))
+ ("Debug"
+ (clojure.core macroexpand-1 macroexpand)
+ (clojure.walk macroexpand-all))
+ ("Branch"
+ (clojure.core and or when when-not when-let when-first if-not if-let cond condp case))
+ ("Loop"
+ (clojure.core for doseq dotimes while))
+ ("Arrange"
+ (clojure.core .. doto ->))
+ ("Scope"
+ (clojure.core binding locking time)
+ (clojure.core with-in-str with-local-vars with-open with-out-str with-precision with-redefs with-redefs-fn))
+ ("Lazy"
+ (clojure.core lazy-cat lazy-seq delay delay?))
+ ("Doc"
+ (clojure.core assert comment)
+ (clojure.repl doc dir dir-fn source-fn)))
+
+ ("Java Interop"
+ ("General"
+ (:special new set!)
+ (clojure.core .. doto bean comparator enumeration-seq import iterator-seq memfn definterface supers bases))
+ ("Cast"
+ (clojure.core boolean byte short char int long float double bigdec bigint num cast biginteger))
+ ("Exceptions"
+ (:special throw try catch finally)
+ (clojure.core ex-info ex-data Throwable->map StackTraceElement->vec)
+ (clojure.repl pst))
+ ("Arrays"
+ ("Create"
+ (clojure.core boolean-array byte-array double-array char-array float-array int-array long-array make-array object-array short-array to-array))
+ ("Manipulate"
+ (clojure.core aclone aget aset alength amap areduce aset-int aset-long aset-short aset-boolean aset-byte aset-char aset-double aset-float))
+ ("Cast"
+ (clojure.core booleans bytes chars doubles floats ints longs shorts)))
+ ("Proxy"
+ ("Create"
+ (clojure.core proxy get-proxy-class construct-proxy init-proxy))
+ ("Misc"
+ (clojure.core proxy-mappings proxy-super update-proxy))))
+
+ ("Namespaces"
+ ("Current"
+ (clojure.core *ns*))
+ ("Create Switch"
+ (clojure.core ns in-ns create-ns))
+ ("Add"
+ (clojure.core alias import intern refer refer-clojure))
+ ("Find"
+ (clojure.core all-ns find-ns))
+ ("Examine"
+ (clojure.core ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers))
+ ("From symbol"
+ (clojure.core resolve namespace ns-resolve the-ns))
+ ("Remove"
+ (clojure.core ns-unalias ns-unmap remove-ns)))
+ ("Loading"
+ ("Load libs"
+ (clojure.core require use import refer))
+ ("List Loaded"
+ (clojure.core loaded-libs))
+ ("Load Misc"
+ (clojure.core load load-file load-reader load-string)))
+
+ ("Concurrency"
+ ("Atoms"
+ (clojure.core atom swap! swap-vals! reset! reset-vals! compare-and-set!))
+ ("Futures"
+ (clojure.core future future-call future-cancel future-cancelled? future-done? future?))
+ ("Threads"
+ (clojure.core bound-fn bound-fn* get-thread-bindings pop-thread-bindings push-thread-bindings))
+
+ ("Misc"
+ (clojure.core locking pcalls pvalues pmap seque promise deliver))
+
+ ("Refs & Transactions"
+ ("Create"
+ (clojure.core ref))
+ ("Examine"
+ (clojure.core deref))
+ ("Transaction"
+ (clojure.core sync dosync io!))
+ ("In Transaction"
+ (clojure.core ensure ref-set alter commute))
+ ("Validators"
+ (clojure.core get-validator set-validator!))
+ ("History"
+ (clojure.core ref-history-count ref-max-history ref-min-history)))
+
+ ("Agents & Asynchronous Actions"
+ ("Create"
+ (clojure.core agent))
+ ("Examine"
+ (clojure.core agent-error))
+ ("Change State"
+ (clojure.core send send-off restart-agent send-via set-agent-send-executor! set-agent-send-off-executor!))
+ ("Block Waiting"
+ (clojure.core await await-for))
+ ("Ref Validators"
+ (clojure.core get-validator set-validator!))
+ ("Watchers"
+ (clojure.core add-watch remove-watch))
+ ("Thread Handling"
+ (clojure.core shutdown-agents))
+ ("Error"
+ (clojure.core error-handler set-error-handler! error-mode set-error-mode!))
+ ("Misc"
+ (clojure.core *agent* release-pending-sends))))
+
+ ("Sequences"
+ ("Creating a Lazy Seq"
+ ("From Collection"
+ (clojure.core seq sequence keys vals rseq subseq rsubseq))
+ ("From Producer Fn"
+ (clojure.core lazy-seq repeatedly iterate))
+ ("From Constant"
+ (clojure.core repeat range))
+ ("From Other"
+ (clojure.core file-seq line-seq resultset-seq re-seq tree-seq xml-seq iterator-seq enumeration-seq))
+ ("From Seq"
+ (clojure.core keep keep-indexed)))
+
+ ("Seq in, Seq out"
+ ("Get shorter"
+ (clojure.core distinct dedupe filter remove for))
+ ("Get longer"
+ (clojure.core cons conj concat lazy-cat mapcat cycle interleave interpose)))
+ ("Tail-items"
+ (clojure.core rest nthrest fnext nnext drop drop-while take-last for))
+ ("Head-items"
+ (clojure.core take take-nth take-while butlast drop-last for))
+ ("Change"
+ (clojure.core conj concat distinct flatten group-by partition partition-all partition-by split-at split-with filter remove replace shuffle random-sample))
+ ("Rearrange"
+ (clojure.core reverse sort sort-by compare))
+ ("Process items"
+ (clojure.core map pmap map-indexed mapcat for replace seque))
+
+ ("Using a Seq"
+ ("Extract item"
+ (clojure.core first second last rest next ffirst nfirst fnext nnext nth nthnext rand-nth when-first max-key min-key))
+ ("Construct coll"
+ (clojure.core zipmap into reduce reductions set vec into-array to-array-2d))
+ ("Pass to fn"
+ (clojure.core apply))
+ ("Search"
+ (clojure.core some filter))
+ ("Force evaluation"
+ (clojure.core doseq dorun doall))
+ ("Check for forced"
+ (clojure.core realized?))))
+
+ ("Zippers"
+ ("Create"
+ (clojure.zip zipper seq-zip vector-zip xml-zip))
+ ("Get loc"
+ (clojure.zip up down left right leftmost rightmost))
+ ("Get seq"
+ (clojure.zip lefts rights path children))
+ ("Change"
+ (clojure.zip make-node replace edit insert-child insert-left insert-right append-child remove))
+ ("Move"
+ (clojure.zip next prev))
+ ("XML"
+ (clojure.data.zip.xml attr attr= seq-test tag= text text= xml-> xml1->))
+ ("Misc"
+ (clojure.zip root node branch? end?)))
+
+ ("Documentation"
+ ("REPL"
+ (clojure.repl doc find-doc apropos source pst)
+ (clojure.java.javadoc javadoc)))
+
+ ("Transients"
+ ("Create"
+ (clojure.core transient persistent!))
+ ("Change"
+ (clojure.core conj! pop! assoc! dissoc! disj!)))
+ ("Misc"
+ ("Compare"
+ (clojure.core = == identical? not= not compare)
+ (clojure.data diff))
+ ("Test"
+ (clojure.core true? false? nil? instance?)))
+
+ ("IO"
+ ("To/from ..."
+ (clojure.core spit slurp))
+ ("To *out*"
+ (clojure.core pr prn print printf println newline)
+ (clojure.pprint print-table))
+ ("To writer"
+ (clojure.pprint pprint cl-format))
+ ("To string"
+ (clojure.core format with-out-str pr-str prn-str print-str println-str))
+ ("From *in*"
+ (clojure.core read-line read))
+ ("From reader"
+ (clojure.core line-seq read))
+ ("From string"
+ (clojure.core read-string with-in-str))
+ ("Open"
+ (clojure.core with-open)
+ (clojure.java.io reader writer input-stream output-stream))
+ ("Interop"
+ (clojure.java.io make-writer make-reader make-output-stream make-input-stream))
+ ("Misc"
+ (clojure.core flush file-seq *in* *out* *err*)
+ (clojure.java.io file copy delete-file resource as-file as-url as-relative-path make-parents)))
+
+ ("Metadata"
+ (clojure.core meta with-meta alter-meta! reset-meta! vary-meta))
+
+ ("Special Forms"
+ (:special def if do quote var recur throw try monitor-enter monitor-exit)
+ (clojure.core fn loop)
+ ("Binding / Destructuring"
+ (clojure.core let fn letfn defn defmacro loop for doseq if-let if-some when-let when-some)))
+
+ ("Async"
+ ("Main"
+ (clojure.core.async go go-loop <! <!! >! >!! chan put! take take! close! timeout offer! poll! promise-chan))
+ ("Choice"
+ (clojure.core.async alt! alt!! alts! alts!! do-alts))
+ ("Buffering"
+ (clojure.core.async buffer dropping-buffer sliding-buffer unblocking-buffer?))
+ ("Pipelines"
+ (clojure.core.async pipeline pipeline-async pipeline-blocking))
+ ("Threading"
+ (clojure.core.async thread thread-call))
+ ("Mixing"
+ (clojure.core.async admix solo-mode mix unmix unmix-all toggle merge pipe unique))
+ ("Multiples"
+ (clojure.core.async mult tap untap untap-all))
+ ("Publish/Subscribe"
+ (clojure.core.async pub sub unsub unsub-all))
+ ("Higher Order"
+ (clojure.core.async filter< filter> map map< map> mapcat< mapcat> partition partition-by reduce remove< remove> split))
+ ("Pre-Populate"
+ (clojure.core.async into onto-chan to-chan)))
+ ("Unit Tests"
+ ("Defining"
+ (clojure.test deftest deftest- testing is are))
+ ("Running"
+ (clojure.test run-tests run-all-tests test-vars))
+ ("Fixtures"
+ (clojure.test use-fixtures join-fixtures compose-fixtures))))
+ "A data structure for Clojure cheatsheet information.
+
+It's a tree, where the head of each list determines the context of the rest
+of the list. The head may be:
+
+ - A string, in which case it's a (sub)heading for the rest of the items.
+
+ - A symbol, in which case it's the Clojure namespace of the symbols that
+ follow it.
+
+ - The keyword :special, in which case it's a Clojure special form
+
+ - Any other keyword, in which case it's a typed item that will be passed
+ through.
+
+Note that some Clojure symbols appear in more than once. This is entirely
+intentional. For instance, `map` belongs in the sections on collections
+and transducers.")
+
+(defun cider-cheatsheet--expand-vars (list)
+ "Expand the symbols in LIST to fully-qualified var names.
+
+This list is supposed to have the following format:
+
+ (my-ns var1 var2 var3)"
+ (let ((ns (car list))
+ (vars (cdr list)))
+ (if (eq ns :special)
+ (mapcar #'symbol-name vars)
+ (mapcar (lambda (var) (format "%s/%s" ns var)) vars))))
+
+(defun cider-cheatsheet--select-var (var-list)
+ "Expand the symbols in VAR-LIST to fully-qualified var names.
+
+The list can hold one or more lists inside - one per each namespace."
+ (let ((namespaced-vars (seq-mapcat #'cider-cheatsheet--expand-vars
+ (seq-remove (lambda (list)
+ (eq (car list) :url))
+ var-list))))
+ (cider-doc-lookup (completing-read "Select var: " namespaced-vars))))
+
+;;;###autoload
+(defun cider-cheatsheet ()
+ "Navigate `cider-cheatsheet-hierarchy' with `completing-read'.
+
+When you make it to a Clojure var its doc buffer gets displayed."
+ (interactive)
+ (let ((cheatsheet-data cider-cheatsheet-hierarchy))
+ (while (stringp (caar cheatsheet-data))
+ (let* ((sections (mapcar #'car cheatsheet-data))
+ (sel-section (completing-read "Select cheatsheet section: " sections))
+ (section-data (seq-find (lambda (elem) (equal (car elem) sel-section)) cheatsheet-data)))
+ (setq cheatsheet-data (cdr section-data))))
+ (cider-cheatsheet--select-var cheatsheet-data)))
+
+(provide 'cider-cheatsheet)
+
+;;; cider-cheatsheet.el ends here
diff --git a/cider-classpath.el b/cider-classpath.el
index 5dbbf3b0..85223237 100644
--- a/cider-classpath.el
+++ b/cider-classpath.el
@@ -1,6 +1,6 @@
;;; cider-classpath.el --- Basic Java classpath browser
-;; Copyright © 2014-2017 Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
diff --git a/cider-client.el b/cider-client.el
index 68c2513f..df5b1431 100644
--- a/cider-client.el
+++ b/cider-client.el
@@ -1,6 +1,6 @@
-;;; cider-client.el --- A layer of abstraction above the actual client code. -*- lexical-binding: t -*-
+;;; cider-client.el --- A layer of abstraction above low-level nREPL client code. -*- lexical-binding: t -*-
-;; Copyright © 2013-2017 Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov
;;
;; Author: Bozhidar Batsov <bozhidar@batsov.com>
@@ -21,7 +21,7 @@
;;; Commentary:
-;; A layer of abstraction above the actual client code.
+;; A layer of abstraction above the low-level nREPL client code.
;;; Code:
@@ -162,11 +162,11 @@ precedence over other connections associated with the same project.
If ALL-CONNECTIONS is non-nil, the return value is a list and all matching
connections are returned, instead of just the most recent."
(when-let* ((project-directory (or project-directory
- (clojure-project-dir (cider-current-dir))))
- (fn (if all-connections #'seq-filter #'seq-find)))
+ (clojure-project-dir (cider-current-dir))))
+ (fn (if all-connections #'seq-filter #'seq-find)))
(or (funcall fn (lambda (conn)
(when-let* ((conn-proj-dir (with-current-buffer conn
- nrepl-project-dir)))
+ nrepl-project-dir)))
(equal (file-truename project-directory)
(file-truename conn-proj-dir))))
cider-connections)
@@ -180,7 +180,7 @@ connections are returned, instead of just the most recent."
(defun cider-connection-type-for-buffer (&optional buffer)
"Return the matching connection type (clj or cljs) for BUFFER.
-In cljc and cljx buffers return \"multi\". This function infers connection
+In cljc buffers return \"multi\". This function infers connection
type based on the major mode. See `cider-project-connections-types' for a
list of types of actual connections within a project. BUFFER defaults to
the `current-buffer'."
@@ -188,7 +188,6 @@ the `current-buffer'."
(cond
((derived-mode-p 'clojurescript-mode) "cljs")
((derived-mode-p 'clojurec-mode) "multi")
- ((derived-mode-p 'clojurex-mode) "multi")
((derived-mode-p 'clojure-mode) "clj")
(cider-repl-type))))
@@ -225,14 +224,35 @@ such a link cannot be established automatically."
(when conn
(setq-local cider-connections (list conn)))))
-(defun cider-toggle-buffer-connection ()
- "Toggle the current buffer's connection between Clojure and ClojureScript."
- (interactive)
+(defun cider-toggle-buffer-connection (&optional restore-all)
+ "Toggle the current buffer's connection between Clojure and ClojureScript.
+
+Default behavior of a cljc buffer is to send eval commands to both Clojure
+and ClojureScript. This function sets a local buffer variable to hide one
+or the other. Optional argument RESTORE-ALL undo any toggled behavior by
+using the default list of connections."
+ (interactive "P")
(cider-ensure-connected)
- (let ((other-conn (cider-other-connection)))
- (if other-conn
- (setq-local cider-connections (list other-conn))
- (user-error "No other connection available"))))
+ (if restore-all
+ (progn
+ (kill-local-variable 'cider-connections)
+ (let ((types (mapcar #'cider--connection-type (cider-connections))))
+ (message (format "CIDER connections available: %s" types))))
+ (let ((current-conn (cider-current-connection))
+ (was-local (local-variable-p 'cider-connections))
+ (original-connections (cider-connections)))
+ ;; we set the local variable to eclipse all connections in favor of the
+ ;; toggled connection. to recover the full list we must remove the
+ ;; obfuscation
+ (kill-local-variable 'cider-connections)
+ (if-let* ((other-conn (cider-other-connection current-conn)))
+ (progn
+ (setq-local cider-connections (list other-conn))
+ (message "Connection set to %s" (cider--connection-type other-conn)))
+ (progn
+ (when was-local
+ (setq-local cider-connections original-connections))
+ (user-error "No other connection available"))))))
(defun cider-clear-buffer-local-connection ()
"Remove association between the current buffer and a connection."
@@ -307,7 +327,7 @@ at all."
Only return connections in the same project or nil.
CONNECTION defaults to `cider-current-connection'."
(when-let* ((connection (or connection (cider-current-connection)))
- (connection-type (cider--connection-type connection)))
+ (connection-type (cider--connection-type connection)))
(cider-current-connection (pcase connection-type
(`"clj" "cljs")
(_ "clj")))))
@@ -318,16 +338,16 @@ CONNECTION defaults to `cider-current-connection'."
"Hacky way to find a ClojureScript REPL.
DO NOT USE THIS FUNCTION.
It was written only to be used in `cider-map-connections', as a workaround
-to a still-undetermined bug in the state-stracker backend."
+to a still-undetermined bug in the state-tracker backend."
(when-let* ((project-connections (cider-find-connection-buffer-for-project-directory
- nil :all-connections))
- (cljs-conn
- ;; So we have multiple connections. Look for the connection type we
- ;; want, prioritizing the current project.
- (or (seq-find (lambda (c) (string-match "\\bCLJS\\b" (buffer-name c)))
- project-connections)
- (seq-find (lambda (c) (string-match "\\bCLJS\\b" (buffer-name c)))
- (cider-connections)))))
+ nil :all-connections))
+ (cljs-conn
+ ;; So we have multiple connections. Look for the connection type we
+ ;; want, prioritizing the current project.
+ (or (seq-find (lambda (c) (with-current-buffer c (equal cider-repl-type "cljs")))
+ project-connections)
+ (seq-find (lambda (c) (with-current-buffer c (equal cider-repl-type "cljs")))
+ (cider-connections)))))
(unless cider--has-warned-about-bad-repl-type
(setq cider--has-warned-about-bad-repl-type t)
(read-key
@@ -341,7 +361,7 @@ to a still-undetermined bug in the state-stracker backend."
"Call FUNCTION once for each appropriate connection.
The function is called with one argument, the connection buffer.
The appropriate connections are found by inspecting the current buffer. If
-the buffer is associated with a .cljc or .cljx file, BODY will be executed
+the buffer is associated with a .cljc file, BODY will be executed
multiple times.
WHICH is one of the following keywords identifying which connections to map
@@ -351,9 +371,8 @@ over.
there is no Clojure connection (use this for commands only
supported in Clojure).
:cljs - Like :clj, but demands a ClojureScript connection instead.
- :both - In `clojurec-mode' or `clojurex-mode' act on both connections,
- otherwise function like :any. Obviously, this option might run
- FUNCTION twice.
+ :both - In `clojurec-mode' act on both connections, otherwise function
+ like :any. Obviously, this option might run FUNCTION twice.
If ANY-MODE is non-nil, :clj and :cljs don't signal errors due to being in
the wrong major mode (they still signal if the desired connection type
@@ -362,7 +381,7 @@ connection but can be invoked from any buffer (like `cider-refresh')."
(cl-labels ((err (msg) (user-error (concat "`%s' " msg) this-command)))
;; :both in a clj or cljs buffer just means :any.
(let* ((which (if (and (eq which :both)
- (not (cider--cljc-or-cljx-buffer-p)))
+ (not (cider--cljc-buffer-p)))
:any
which))
(curr
@@ -761,9 +780,17 @@ result, and is included in the request if non-nil."
"pprint-fn" ,(or pprint-fn (cider--pprint-fn)))
(and right-margin `("print-right-margin" ,right-margin))))
+(defun cider--nrepl-content-type-plist ()
+ "Plist to be appended to an eval request to make it use content-types."
+ '("content-type" "true"))
+
(defun cider-tooling-eval (input callback &optional ns)
"Send the request INPUT and register the CALLBACK as the response handler.
-NS specifies the namespace in which to evaluate the request."
+NS specifies the namespace in which to evaluate the request.
+
+Requests evaluated in the tooling nREPL session don't affect the
+thread-local bindings of the primary eval nREPL session (e.g. this is not
+going to clobber *1/2/3)."
;; namespace forms are always evaluated in the "user" namespace
(nrepl-request:eval input
callback
@@ -771,6 +798,24 @@ NS specifies the namespace in which to evaluate the request."
ns nil nil nil t ; tooling
))
+(defun cider-sync-tooling-eval (input &optional ns)
+ "Send the request INPUT and evaluate in synchronously.
+NS specifies the namespace in which to evaluate the request.
+
+Requests evaluated in the tooling nREPL session don't affect the
+thread-local bindings of the primary eval nREPL session (e.g. this is not
+going to clobber *1/2/3)."
+ ;; namespace forms are always evaluated in the "user" namespace
+ (nrepl-sync-request:eval input
+ (cider-current-connection)
+ ns
+ t ; tooling
+ ))
+
+(defun cider-library-present-p (lib)
+ "Check whether LIB is present on the classpath."
+ (seq-find (lambda (s) (string-match-p (concat lib ".*\\.jar") s)) (cider-sync-request:classpath)))
+
(defalias 'cider-current-repl-buffer #'cider-current-connection
"The current REPL buffer.
Return the REPL buffer given by `cider-current-connection'.")
@@ -1161,8 +1206,10 @@ default connection."
(append (cdr cider-connections)
(list (car cider-connections))))
(message "Default nREPL connection: %s"
- (cider--connection-info (car cider-connections)))))
+ (cider--connection-info (car cider-connections)))))
+
+(declare-function cider-connect "cider")
(defun cider-replicate-connection (&optional conn)
"Establish a new connection based on an existing connection.
The new connection will use the same host and port.
diff --git a/cider-common.el b/cider-common.el
index 55a23798..657bd822 100644
--- a/cider-common.el
+++ b/cider-common.el
@@ -1,6 +1,6 @@
;;; cider-common.el --- Common use functions -*- lexical-binding: t; -*-
-;; Copyright © 2015-2017 Artur Malabarba
+;; Copyright © 2015-2018 Artur Malabarba
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
@@ -123,23 +123,34 @@ create a valid path."
(match-string 1 filename)
filename)))
+(defun cider-make-tramp-prefix (method user host)
+ "Constructs a Tramp file prefix from METHOD, USER, HOST.
+It originated from Tramp's `tramp-make-tramp-file-name'. The original be
+forced to make full file name with `with-parsed-tramp-file-name', not providing
+prefix only option."
+ (concat tramp-prefix-format
+ (unless (zerop (length method))
+ (concat method tramp-postfix-method-format))
+ (unless (zerop (length user))
+ (concat user tramp-postfix-user-format))
+ (when host
+ (if (string-match tramp-ipv6-regexp host)
+ (concat tramp-prefix-ipv6-format host tramp-postfix-ipv6-format)
+ host))
+ tramp-postfix-host-format))
+
(defun cider-tramp-prefix (&optional buffer)
"Use the filename for BUFFER to determine a tramp prefix.
-Defaults to the current buffer.
-Return the tramp prefix, or nil if BUFFER is local."
+Defaults to the current buffer. Return the tramp prefix, or nil
+if BUFFER is local."
(let* ((buffer (or buffer (current-buffer)))
(name (or (buffer-file-name buffer)
(with-current-buffer buffer
default-directory))))
(when (tramp-tramp-file-p name)
(with-parsed-tramp-file-name name v
- ;; `tramp-make-tramp-file-name' was changed to take 6 mandatory
- ;; parameters in Emacs 26 instead of 4
- (if (version< emacs-version "26")
- (with-no-warnings
- (tramp-make-tramp-file-name v-method v-user v-host v-localname))
- (with-no-warnings
- (tramp-make-tramp-file-name v-method v-user v-domain v-host v-port v-localname)))))))
+ (with-no-warnings
+ (cider-make-tramp-prefix v-method v-user v-host))))))
(defun cider--client-tramp-filename (name &optional buffer)
"Return the tramp filename for path NAME relative to BUFFER.
@@ -147,6 +158,7 @@ If BUFFER has a tramp prefix, it will be added as a prefix to NAME.
If the resulting path is an existing tramp file, it returns the path,
otherwise, nil."
(let* ((buffer (or buffer (current-buffer)))
+ (name (replace-regexp-in-string "^file:" "" name))
(name (concat (cider-tramp-prefix buffer) name)))
(if (tramp-handle-file-exists-p name)
name)))
@@ -202,11 +214,19 @@ existing file ending with URL has been found."
(when-let* ((entry (match-string 3 url))
(file (cider--url-to-file (match-string 2 url)))
(path (cider--file-path file))
+ ;; It is used for targeting useless intermediate buffer.
+ ;; That buffer is made by (find-file path) below.
+ ;; It has the name which is the last part of the path.
+ (trash (replace-regexp-in-string "^/.+/" "" path))
(name (format "%s:%s" path entry)))
(or (find-buffer-visiting name)
(if (tramp-tramp-file-p path)
(progn
- ;; Use emacs built in archiving
+ ;; Use emacs built in archiving.
+ ;; This makes a list of files in archived Zip or Jar.
+ ;; That list buffer is useless after jumping to the
+ ;; buffer which has the real definition.
+ ;; It'll be removed by (kill-buffer trash) below.
(find-file path)
(goto-char (point-min))
;; Make sure the file path is followed by a newline to
@@ -215,6 +235,8 @@ existing file ending with URL has been found."
;; moves up to matching line
(forward-line -1)
(archive-extract)
+ ;; Remove useless buffer made by (find-file path) above.
+ (kill-buffer trash)
(current-buffer))
;; Use external zip program to just extract the single file
(with-current-buffer (generate-new-buffer
diff --git a/cider-compat.el b/cider-compat.el
index 816b8635..ec928dfd 100644
--- a/cider-compat.el
+++ b/cider-compat.el
@@ -1,7 +1,7 @@
;;; cider-compat.el --- Functions from newer Emacs versions for compatibility -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; This program is free software: you can redistribute it and/or modify
diff --git a/cider-debug.el b/cider-debug.el
index 7754fed5..54481d49 100644
--- a/cider-debug.el
+++ b/cider-debug.el
@@ -1,6 +1,6 @@
;;; cider-debug.el --- CIDER interaction with the cider.debug nREPL middleware -*- lexical-binding: t; -*-
-;; Copyright © 2015-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
diff --git a/cider-doc.el b/cider-doc.el
index 52a953a0..3c867ea0 100644
--- a/cider-doc.el
+++ b/cider-doc.el
@@ -1,6 +1,6 @@
;;; cider-doc.el --- CIDER documentation functionality -*- lexical-binding: t -*-
-;; Copyright © 2014-2017 Bozhidar Batsov, Jeff Valk and CIDER contributors
+;; Copyright © 2014-2018 Bozhidar Batsov, Jeff Valk and CIDER contributors
;; Author: Jeff Valk <jv@jeffvalk.com>
@@ -36,6 +36,7 @@
(require 'org-table)
(require 'button)
(require 'easymenu)
+(require 'cider-browse-spec)
;;; Variables
@@ -46,6 +47,11 @@
:group 'cider)
+(declare-function cider-apropos "cider-apropos")
+(declare-function cider-apropos-select "cider-apropos")
+(declare-function cider-apropos-documentation "cider-apropos")
+(declare-function cider-apropos-documentation-select "cider-apropos")
+
(defvar cider-doc-map
(let (cider-doc-map)
(define-prefix-command 'cider-doc-map)
@@ -461,9 +467,14 @@ Tables are marked to be ignored by line wrap."
(insert ".\n"))
(insert "\n")
(when spec
- (emit "Spec: " 'font-lock-function-name-face)
- (mapc (lambda (s) (insert s "\n")) spec)
- (insert "\n"))
+ (emit "Spec:" 'font-lock-function-name-face)
+ (insert (cider-browse-spec--pprint-indented spec))
+ (insert "\n\n")
+ (insert-text-button "Browse spec"
+ 'follow-link t
+ 'action (lambda (_)
+ (cider-browse-spec (format "%s/%s" ns name))))
+ (insert "\n\n"))
(if cider-docview-file
(progn
(insert (propertize (if class java-name clj-name)
diff --git a/cider-eldoc.el b/cider-eldoc.el
index 81926638..b055824d 100644
--- a/cider-eldoc.el
+++ b/cider-eldoc.el
@@ -1,7 +1,7 @@
;;; cider-eldoc.el --- eldoc support for Clojure -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
@@ -439,19 +439,19 @@ Only useful for interop forms. Clojure forms would be returned unchanged."
(defun cider--eldoc-add-datomic-query-inputs-to-arglists (arglists)
"Add the expected inputs of the datomic query to the ARGLISTS."
(if (cider-second-sexp-in-list)
- (let* ((query (cider-second-sexp-in-list))
- (query-inputs (nrepl-dict-get
- (cider-sync-request:eldoc-datomic-query query)
- "inputs")))
- (if query-inputs
- (thread-first
- (thread-last arglists
- (car)
- (remove "&")
- (remove "inputs"))
- (append (car query-inputs))
- (list))
- arglists))
+ (let* ((query (cider-second-sexp-in-list))
+ (query-inputs (nrepl-dict-get
+ (cider-sync-request:eldoc-datomic-query query)
+ "inputs")))
+ (if query-inputs
+ (thread-first
+ (thread-last arglists
+ (car)
+ (remove "&")
+ (remove "inputs"))
+ (append (car query-inputs))
+ (list))
+ arglists))
arglists))
(defun cider-eldoc ()
diff --git a/cider-grimoire.el b/cider-grimoire.el
index 959f99ea..c07614ba 100644
--- a/cider-grimoire.el
+++ b/cider-grimoire.el
@@ -1,6 +1,6 @@
;;; cider-grimoire.el --- Grimoire integration -*- lexical-binding: t -*-
-;; Copyright © 2014-2017 Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
;;
;; Author: Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/cider-inspector.el b/cider-inspector.el
index cf324446..c32d738d 100644
--- a/cider-inspector.el
+++ b/cider-inspector.el
@@ -1,7 +1,7 @@
;;; cider-inspector.el --- Object inspector -*- lexical-binding: t -*-
-;; Copyright © 2013-2017 Vital Reactor, LLC
-;; Copyright © 2014-2017 Bozhidar Batsov and CIDER contributors
+;; Copyright © 2013-2018 Vital Reactor, LLC
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
;; Author: Ian Eslick <ian@vitalreactor.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/cider-interaction.el b/cider-interaction.el
index c8ac4f54..962bcd1d 100644
--- a/cider-interaction.el
+++ b/cider-interaction.el
@@ -1,7 +1,7 @@
;;; cider-interaction.el --- IDE for Clojure -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
@@ -660,9 +660,9 @@ has started."
Returns the cons of the buffer itself and the location of VAR's definition
in the buffer."
(when-let* ((info (cider-var-info var))
- (file (nrepl-dict-get info "file"))
- (line (nrepl-dict-get info "line"))
- (buffer (cider-find-file file)))
+ (file (nrepl-dict-get info "file"))
+ (line (nrepl-dict-get info "line"))
+ (buffer (cider-find-file file)))
(with-current-buffer buffer
(save-excursion
(goto-char (point-min))
@@ -856,16 +856,16 @@ COMMENT-PREFIX is the comment prefix for the first line of output.
CONTINUED-PREFIX is the comment prefix to use for the remaining lines.
COMMENT-POSTFIX is the text to output after the last line."
(cl-flet ((multiline-comment-handler (buffer value)
- (with-current-buffer buffer
- (save-excursion
- (goto-char location)
- (let ((lines (split-string value "[\n]+" t)))
- ;; only the first line gets the normal comment-prefix
- (insert (concat comment-prefix (pop lines)))
- (dolist (elem lines)
- (insert (concat "\n" continued-prefix elem)))
- (unless (string= comment-postfix "")
- (insert comment-postfix)))))))
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char location)
+ (let ((lines (split-string value "[\n]+" t)))
+ ;; only the first line gets the normal comment-prefix
+ (insert (concat comment-prefix (pop lines)))
+ (dolist (elem lines)
+ (insert (concat "\n" continued-prefix elem)))
+ (unless (string= comment-postfix "")
+ (insert comment-postfix)))))))
(nrepl-make-response-handler buffer
'()
#'multiline-comment-handler
@@ -1236,6 +1236,37 @@ If invoked with OUTPUT-TO-CURRENT-BUFFER, output the result to current buffer."
(goto-char (cadr (cider-sexp-at-point 'bounds)))
(cider-eval-last-sexp output-to-current-buffer)))
+(defvar-local cider-previous-eval-context nil
+ "The previous evaluation context if any.
+
+That's set by commands like `cider-eval-last-sexp-in-context'.")
+
+(defun cider--eval-in-context (code)
+ "Evaluate CODE in user-provided evaluation context."
+ (let* ((code (string-trim-right code))
+ (eval-context (read-string
+ (format "Evaluation context (let-style) for `%s': " code)
+ cider-previous-eval-context))
+ (code (concat "(let [" eval-context "]\n " code ")")))
+ (cider-interactive-eval code)
+ (setq-local cider-previous-eval-context eval-context)))
+
+(defun cider-eval-last-sexp-in-context ()
+ "Evaluate the preceding sexp in user-supplied context.
+
+The context is just a let binding vector (without the brackets).
+The context is remembered between command invocations."
+ (interactive)
+ (cider--eval-in-context (cider-last-sexp)))
+
+(defun cider-eval-sexp-at-point-in-context ()
+ "Evaluate the preceding sexp in user-supplied context.
+
+The context is just a let binding vector (without the brackets).
+The context is remembered between command invocations."
+ (interactive)
+ (cider--eval-in-context (cider-sexp-at-point)))
+
(defun cider-eval-defun-to-comment (&optional insert-before)
"Evaluate the \"top-level\" form and insert result as comment.
@@ -1406,6 +1437,50 @@ command `cider-debug-defun-at-point'."
(concat "#dbg\n" (cider-defun-at-point)))
nil (cider-defun-at-point 'bounds))))
+(defun cider--calculate-opening-delimiters ()
+ "Walks up the list of expressions to collect all sexp opening delimiters.
+
+The result is a list of the delimiters.
+
+That function is used in `cider-eval-defun-to-point' so it can make an
+incomplete expression complete."
+ (interactive)
+ (let ((result nil))
+ (save-excursion
+ (condition-case nil
+ (while t
+ (backward-up-list)
+ (push (char-after) result))
+ (error result)))))
+
+(defun cider--matching-delimiter (delimiter)
+ "Get the matching (opening/closing) delimiter for DELIMITER."
+ (pcase delimiter
+ (?\( ?\))
+ (?\[ ?\])
+ (?\{ ?\})
+ (?\) ?\()
+ (?\] ?\[)
+ (?\} ?\{)))
+
+(defun cider--calculate-closing-delimiters ()
+ "Compute the list of closing delimiters to make the defun before point valid."
+ (mapcar #'cider--matching-delimiter (cider--calculate-opening-delimiters)))
+
+(defun cider-eval-defun-to-point ()
+ "Evaluate the current toplevel form up to point.
+
+It constructs an expression to eval in the following manner:
+
+- It find the code between the point and the start of the toplevel expression;
+- It balances this bit of code by closing all open expressions;
+- It evaluates the resulting code using `cider-interactive-eval'."
+ (interactive)
+ (let* ((beg-of-defun (save-excursion (beginning-of-defun) (point)))
+ (code (buffer-substring-no-properties beg-of-defun (point)))
+ (code (concat code (cider--calculate-closing-delimiters))))
+ (cider-interactive-eval code)))
+
(defun cider-pprint-eval-defun-at-point (&optional output-to-current-buffer)
"Evaluate the \"top-level\" form at point and pprint its value.
If invoked with OUTPUT-TO-CURRENT-BUFFER, insert as comment in the current
@@ -1458,12 +1533,18 @@ passing arguments."
(define-key map (kbd "n") #'cider-eval-ns-form)
(define-key map (kbd "v") #'cider-eval-sexp-at-point)
(define-key map (kbd ".") #'cider-read-and-eval-defun-at-point)
+ (define-key map (kbd "z") #'cider-eval-defun-to-point)
+ (define-key map (kbd "c") #'cider-eval-last-sexp-in-context)
+ (define-key map (kbd "b") #'cider-eval-sexp-at-point-in-context)
;; duplicates with C- for convenience
(define-key map (kbd "C-w") #'cider-eval-last-sexp-and-replace)
(define-key map (kbd "C-r") #'cider-eval-region)
(define-key map (kbd "C-n") #'cider-eval-ns-form)
(define-key map (kbd "C-v") #'cider-eval-sexp-at-point)
- (define-key map (kbd "C-.") #'cider-read-and-eval-defun-at-point)))
+ (define-key map (kbd "C-.") #'cider-read-and-eval-defun-at-point)
+ (define-key map (kbd "C-z") #'cider-eval-defun-to-point)
+ (define-key map (kbd "C-c") #'cider-eval-last-sexp-in-context)
+ (define-key map (kbd "C-b") #'cider-eval-sexp-at-point-in-context)))
;; Connection and REPL
@@ -1735,7 +1816,7 @@ refresh functions (defined in `cider-refresh-before-fn' and
"Load (eval) BUFFER's file in nREPL.
If no buffer is provided the command acts on the current buffer.
-If the buffer is for a cljc or cljx file, and both a Clojure and
+If the buffer is for a cljc file, and both a Clojure and
ClojureScript REPL exists for the project, it is evaluated in both REPLs."
(interactive)
(check-parens)
@@ -1769,7 +1850,7 @@ ClojureScript REPL exists for the project, it is evaluated in both REPLs."
(defun cider-load-file (filename)
"Load (eval) the Clojure file FILENAME in nREPL.
-If the file is a cljc or cljx file, and both a Clojure and ClojureScript
+If the file is a cljc file, and both a Clojure and ClojureScript
REPL exists for the project, it is evaluated in both REPLs.
The heavy lifting is done by `cider-load-buffer'."
@@ -1874,6 +1955,7 @@ of the buffer into a formatted string."
(defun cider-format-buffer ()
"Format the Clojure code in the current buffer."
(interactive)
+ (check-parens)
(cider-ensure-connected)
(cider--format-buffer #'cider-sync-request:format-code))
@@ -1883,6 +1965,7 @@ of the buffer into a formatted string."
(defun cider-format-edn-buffer ()
"Format the EDN data in the current buffer."
(interactive)
+ (check-parens)
(cider-ensure-connected)
(cider--format-buffer (lambda (edn)
(cider-sync-request:format-edn edn (cider--pretty-print-width)))))
@@ -1931,7 +2014,7 @@ START and END represent the region's boundaries."
(interactive)
(cider-ensure-connected)
(nrepl-sync-request:close (cider-current-connection))
- (message "Closed nREPL session"))
+ (message "Closed nREPL session"))
;;; quiting
(defun cider--close-buffer (buffer)
@@ -1983,6 +2066,8 @@ and all ancillary CIDER buffers."
(unless (cider-connected-p)
(cider-close-ancillary-buffers)))
+(declare-function cider-connect "cider")
+(declare-function cider-jack-in "cider")
(defun cider--restart-connection (conn)
"Restart the connection CONN."
(let ((project-dir (with-current-buffer conn nrepl-project-dir))
diff --git a/cider-macroexpansion.el b/cider-macroexpansion.el
index 6f0dab54..e0d42d7d 100644
--- a/cider-macroexpansion.el
+++ b/cider-macroexpansion.el
@@ -1,7 +1,7 @@
;;; cider-macroexpansion.el --- Macro expansion support -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
diff --git a/cider-mode.el b/cider-mode.el
index 690a8326..10471619 100644
--- a/cider-mode.el
+++ b/cider-mode.el
@@ -1,7 +1,7 @@
;;; cider-mode.el --- Minor mode for REPL interactions -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
@@ -33,6 +33,7 @@
(require 'clojure-mode)
(require 'cider-interaction)
+(require 'cider-profile)
(require 'cider-test)
(require 'cider-eldoc)
(require 'cider-resolve)
@@ -47,9 +48,9 @@
:package-version '(cider "0.10.0"))
(defun cider--modeline-info ()
- "Return info for the `cider-mode' modeline.
+ "Return info for the cider mode modeline.
-Info contains project name and host:port endpoint."
+Info contains the connection type, project name and host:port endpoint."
(if-let* ((current-connection (ignore-errors (cider-current-connection))))
(with-current-buffer current-connection
(concat
@@ -66,16 +67,15 @@ Info contains project name and host:port endpoint."
;;;###autoload
(defcustom cider-mode-line
'(:eval (format " cider[%s]" (cider--modeline-info)))
- "Mode line lighter for `cider-mode'.
+ "Mode line lighter for cider mode.
The value of this variable is a mode line template as in
-`mode-line-format'. See Info Node `(elisp)Mode Line Format' for
-details about mode line templates.
+`mode-line-format'. See Info Node `(elisp)Mode Line Format' for details
+about mode line templates.
-Customize this variable to change how `cider-mode' displays its
-status in the mode line. The default value displays the current connection.
-Set this variable to nil to disable the mode line
-entirely."
+Customize this variable to change how cider mode displays its status in the
+mode line. The default value displays the current connection. Set this
+variable to nil to disable the mode line entirely."
:group 'cider
:type 'sexp
:risky t
@@ -172,7 +172,10 @@ Clojure buffer and the REPL buffer."
(defun cider-find-and-clear-repl-output (&optional clear-repl)
"Find the current REPL buffer and clear it.
With a prefix argument CLEAR-REPL the command clears the entire REPL buffer.
-Returns to the buffer in which the command was invoked."
+Returns to the buffer in which the command was invoked.
+
+See also the related commands `cider-repl-clear-buffer' and
+`cider-repl-clear-output'."
(interactive "P")
(let ((origin-buffer (current-buffer)))
(switch-to-buffer (cider-current-repl-buffer))
@@ -186,19 +189,20 @@ Returns to the buffer in which the command was invoked."
(defconst cider-mode-menu
`("CIDER"
["Start a REPL" cider-jack-in
- :help "Starts an nREPL server (with lein, boot, or maven) and connects a REPL to it."]
+ :help "Starts an nREPL server (with Leiningen, Boot, or Gradle) and connects a REPL to it."]
["Connect to a REPL" cider-connect
:help "Connects to a REPL that's already running."]
+ ["Replicate connection" cider-replicate-connection
+ :help "Opens another connection based on a existing one. The new connection uses the same host and port as the base connection."]
["Quit" cider-quit :active cider-connections]
["Restart" cider-restart :active cider-connections]
- ("Clojurescript"
+ ("ClojureScript"
["Start a Clojure REPL, and a ClojureScript REPL" cider-jack-in-clojurescript
:help "Starts an nREPL server, connects a Clojure REPL to it, and then a ClojureScript REPL.
-Configure `cider-cljs-*-repl' to change the ClojureScript REPL to use for your build tool."]
- ["Create a ClojureScript REPL from a Clojure REPL" cider-create-sibling-cljs-repl]
- ["Form for launching a ClojureScript REPL via Leiningen" (customize-variable 'cider-cljs-lein-repl)]
- ["Form for launching a ClojureScript REPL via Boot" (customize-variable 'cider-cljs-boot-repl)]
- ["Form for launching a ClojureScript REPL via Gradle" (customize-variable 'cider-cljs-gradle-repl)])
+Configure `cider-cljs-repl-types' to change the ClojureScript REPL to use for your build tool."]
+ ["Connect to a ClojureScript REPL" cider-connect-clojurescript
+ :help "Connects to a ClojureScript REPL that's already running."]
+ ["Create a ClojureScript REPL from a Clojure REPL" cider-create-sibling-cljs-repl])
"--"
["Connection info" cider-display-connection-info
:active cider-connections]
@@ -225,8 +229,11 @@ Configure `cider-cljs-*-repl' to change the ClojureScript REPL to use for your b
(defconst cider-mode-eval-menu
'("CIDER Eval" :visible cider-connections
["Eval top-level sexp" cider-eval-defun-at-point]
+ ["Eval top-level sexp to point" cider-eval-defun-to-point]
["Eval current sexp" cider-eval-sexp-at-point]
+ ["Eval current sexp in context" cider-eval-sexp-at-point-in-context]
["Eval last sexp" cider-eval-last-sexp]
+ ["Eval last sexp in context" cider-eval-last-sexp-in-context]
["Eval selected region" cider-eval-region]
["Eval ns form" cider-eval-ns-form]
"--"
@@ -240,6 +247,9 @@ Configure `cider-cljs-*-repl' to change the ClojureScript REPL to use for your b
["Eval last sexp and pretty-print to REPL" cider-pprint-eval-last-sexp-to-repl]
["Eval last sexp and pretty-print to comment" cider-pprint-eval-last-sexp-to-comment]
["Insert last sexp in REPL" cider-insert-last-sexp-in-repl]
+ ["Insert top-level sexp in REPL" cider-insert-defun-in-repl]
+ ["Insert region in REPL" cider-insert-region-in-repl]
+ ["Insert ns form in REPL" cider-insert-ns-form-in-repl]
["Eval top-level sexp to comment" cider-eval-defun-to-comment]
["Eval top-level sexp and pretty-print to comment" cider-pprint-eval-defun-to-comment]
"--"
@@ -272,6 +282,14 @@ Configure `cider-cljs-*-repl' to change the ClojureScript REPL to use for your b
["Find resource" cider-find-resource]
["Find keyword" cider-find-keyword]
["Go back" cider-pop-back])
+ ("Browse"
+ ["Browse namespace" cider-browse-ns]
+ ["Browse all namespaces" cider-browse-ns-all]
+ ["Browse spec" cider-browse-spec]
+ ["Browse all specs" cider-browse-spec-all]
+ ["Browse REPL input history" cider-repl-history]
+ ["Browse classpath" cider-classpath]
+ ["Browse classpath entry" cider-open-classpath-entry])
("Macroexpand"
["Macroexpand-1" cider-macroexpand-1]
["Macroexpand-all" cider-macroexpand-all])
@@ -286,18 +304,15 @@ Configure `cider-cljs-*-repl' to change the ClojureScript REPL to use for your b
["List instrumented defs" cider-browse-instrumented-defs]
"--"
["Configure the Debugger" (customize-group 'cider-debug)])
- ("Browse"
- ["Browse namespace" cider-browse-ns]
- ["Browse all namespaces" cider-browse-ns-all]
- ["Browse spec" cider-browse-spec]
- ["Browse all specs" cider-browse-spec-all]
- ["Browse REPL input history" cider-repl-history]
- ["Browse classpath" cider-classpath]
- ["Browse classpath entry" cider-open-classpath-entry])
+ ,cider-profile-menu
("Misc"
+ ["Clojure Cheatsheet" cider-cheatsheet]
["Flush completion cache" cider-completion-flush-caches]))
"Menu for CIDER interactions.")
+(declare-function cider-macroexpand-1 "cider-macroexpansion")
+(declare-function cider-macroexpand-all "cider-macroexpansion")
+(declare-function cider-selector "cider-selector")
(defconst cider-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c C-d") 'cider-doc-map)
@@ -337,6 +352,7 @@ Configure `cider-cljs-*-repl' to change the ClojureScript REPL to use for your b
(define-key map (kbd "C-c M-s") #'cider-selector)
(define-key map (kbd "C-c M-r") #'cider-rotate-default-connection)
(define-key map (kbd "C-c M-d") #'cider-display-connection-info)
+ (define-key map (kbd "C-c C-=") #'cider-profile-map)
(define-key map (kbd "C-c C-x") #'cider-refresh)
(define-key map (kbd "C-c C-q") #'cider-quit)
(dolist (variable '(cider-mode-interactions-menu
@@ -357,13 +373,14 @@ Configure `cider-cljs-*-repl' to change the ClojureScript REPL to use for your b
"Menu for Clojure mode.
This is displayed in `clojure-mode' buffers, if `cider-mode' is not active."
`("CIDER" :visible (not cider-mode)
- ["Start a REPL" cider-jack-in
- :help "Starts an nREPL server (with lein, boot, or maven) and connects a REPL to it."]
- ["Connect to a REPL" cider-connect
+ ["Start a Clojure REPL" cider-jack-in
+ :help "Starts an nREPL server (with Leiningen, Boot, or Gradle) and connects a REPL to it."]
+ ["Connect to a Clojure REPL" cider-connect
:help "Connects to a REPL that's already running."]
+ ["Connect to a ClojureScript REPL" cider-connect-clojurescript
+ :help "Connects to a ClojureScript REPL that's already running."]
["Start a Clojure REPL, and a ClojureScript REPL" cider-jack-in-clojurescript
- :help "Starts an nREPL server, connects a Clojure REPL to it, and then a ClojureScript REPL.
- Configure `cider-cljs-lein-repl', `cider-cljs-boot-repl' and `cider-cljs-gradle-repl' to change the ClojureScript REPL to use."]
+ :help "Starts an nREPL server, connects a Clojure REPL to it, and then a ClojureScript REPL."]
"--"
["View manual online" cider-view-manual])))
diff --git a/cider-overlays.el b/cider-overlays.el
index 7cbed0bd..1a92b35f 100644
--- a/cider-overlays.el
+++ b/cider-overlays.el
@@ -1,6 +1,6 @@
;;; cider-overlays.el --- Managing CIDER overlays -*- lexical-binding: t; -*-
-;; Copyright © 2015-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
@@ -153,9 +153,9 @@ END is the position where the sexp ends, and defaults to point."
'before-string cider--fringe-overlay-good)))))
(cl-defun cider--make-result-overlay (value &rest props &key where duration (type 'result)
- (format (concat " " cider-eval-result-prefix "%s "))
- (prepend-face 'cider-result-overlay-face)
- &allow-other-keys)
+ (format (concat " " cider-eval-result-prefix "%s "))
+ (prepend-face 'cider-result-overlay-face)
+ &allow-other-keys)
"Place an overlay displaying VALUE at the end of line.
VALUE is used as the overlay's after-string property, meaning it is
displayed at the end of the overlay. The overlay itself is placed from
diff --git a/cider-popup.el b/cider-popup.el
index c3cf940a..411acebe 100644
--- a/cider-popup.el
+++ b/cider-popup.el
@@ -1,6 +1,6 @@
;;; cider-popup.el --- Creating and quitting popup buffers -*- lexical-binding: t; -*-
-;; Copyright © 2015-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
diff --git a/cider-profile.el b/cider-profile.el
new file mode 100644
index 00000000..0ccd1a63
--- /dev/null
+++ b/cider-profile.el
@@ -0,0 +1,207 @@
+;;; cider-profile.el --- CIDER support for profiling -*- lexical-binding: t; -*-
+
+;; Copyright © 2014-2018 Edwin Watkeys and CIDER contributors
+
+;; Author: Edwin Watkeys <edw@poseur.com>
+;; Juan E. Maya <jmayaalv@gmail.com>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides coarse-grained interactive profiling support.
+;; Based on earlier work by Edwin Watkeys (https://github.com/thunknyc/nrepl-profile).
+
+;;; Code:
+
+(require 'cider-client)
+
+(defconst cider-profile-buffer "*cider-profile*")
+
+(defvar cider-profile-map
+ (let ((map (define-prefix-command 'cider-profile-map)))
+ (define-key map (kbd "t") #'cider-profile-toggle)
+ (define-key map (kbd "c") #'cider-profile-clear)
+ (define-key map (kbd "S") #'cider-profile-summary)
+ (define-key map (kbd "s") #'cider-profile-var-summary)
+ (define-key map (kbd "n") #'cider-profile-ns-toggle)
+ (define-key map (kbd "v") #'cider-profile-var-profiled-p)
+ (define-key map (kbd "+") #'cider-profile-samples)
+ map)
+ "CIDER profiler keymap.")
+
+(defconst cider-profile-menu
+ '("Profile"
+ ["Toggle var profiling" cider-profile-toggle]
+ ["Toggle namespace profiling" cider-profile-ns-toggle]
+ "--"
+ ["Display var profiling status" cider-profile-var-profiled-p]
+ ["Display max sample count" cider-profile-samples]
+ ["Display summary" cider-profile-summary]
+ ["Clear data" cider-profile-clear])
+ "CIDER profiling submenu.")
+
+(defun cider-profile--make-response-handler (handler &optional buffer)
+ "Make a response handler using value handler HANDLER for connection BUFFER.
+
+Optional argument BUFFER defaults to current buffer."
+ (nrepl-make-response-handler
+ (or buffer (current-buffer)) handler nil nil nil))
+
+;;;###autoload
+(defun cider-profile-samples (&optional query)
+ "Displays current max-sample-count.
+If optional QUERY is specified, set max-sample-count and display new value."
+ (interactive "P")
+ (cider-ensure-op-supported "set-max-samples")
+ (cider-ensure-op-supported "get-max-samples")
+ (if (not (null query))
+ (cider-nrepl-send-request
+ (let ((max-samples (if (numberp query) query '())))
+ (message "query: %s" max-samples)
+ `("op" "set-max-samples" "max-samples" ,max-samples))
+ (cider-profile--make-response-handler
+ (lambda (_buffer value)
+ (let ((value (if (zerop (length value)) "unlimited" value)))
+ (message "max-sample-count is now %s" value)))))
+ (cider-nrepl-send-request
+ '("op" "get-max-samples")
+ (cider-profile--make-response-handler
+ (lambda (_buffer value)
+ (let ((value (if (zerop (length value)) "unlimited" value)))
+ (message "max-sample-count is now %s" value))))))
+ query)
+
+;;;###autoload
+(defun cider-profile-var-profiled-p (query)
+ "Displays the profiling status of var under point.
+Prompts for var if none under point or QUERY is present."
+ (interactive "P")
+ (cider-ensure-op-supported "is-var-profiled")
+ (cider-read-symbol-name
+ "Report profiling status for var: "
+ (lambda (sym)
+ (let ((ns (cider-current-ns)))
+ (cider-nrepl-send-request
+ `("op" "is-var-profiled"
+ "ns" ,ns
+ "sym" ,sym)
+ (cider-profile--make-response-handler
+ (lambda (_buffer value)
+ (pcase value
+ ("profiled" (message "Profiling is currently enabled for %s/%s" ns sym))
+ ("unprofiled" (message "Profiling is currently disabled for %s/%s" ns sym))
+ ("unbound" (message "%s/%s is unbound" ns sym)))))))))
+ query)
+
+;;;###autoload
+(defun cider-profile-ns-toggle (&optional query)
+ "Toggle profiling for the ns associated with optional QUERY.
+
+If optional argument QUERY is non-nil, prompt for ns. Otherwise use
+current ns."
+ (interactive "P")
+ (cider-ensure-op-supported "toggle-profile-ns")
+ (let ((ns (if query
+ (completing-read "Toggle profiling for ns: "
+ (cider-sync-request:ns-list))
+ (cider-current-ns))))
+ (cider-nrepl-send-request
+ `("op" "toggle-profile-ns"
+ "ns" ,ns)
+ (cider-profile--make-response-handler
+ (lambda (_buffer value)
+ (pcase value
+ ("profiled" (message "Profiling enabled for %s" ns))
+ ("unprofiled" (message "Profiling disabled for %s" ns)))))))
+ query)
+
+;;;###autoload
+(defun cider-profile-toggle (query)
+ "Toggle profiling for the given QUERY.
+Defaults to the symbol at point.
+With prefix arg or no symbol at point, prompts for a var."
+ (interactive "P")
+ (cider-ensure-op-supported "toggle-profile")
+ (cider-read-symbol-name
+ "Toggle profiling for var: "
+ (lambda (sym)
+ (let ((ns (cider-current-ns)))
+ (cider-nrepl-send-request
+ `("op" "toggle-profile"
+ "ns" ,ns
+ "sym" ,sym)
+ (cider-profile--make-response-handler
+ (lambda (_buffer value)
+ (pcase value
+ ("profiled" (message "Profiling enabled for %s/%s" ns sym))
+ ("unprofiled" (message "Profiling disabled for %s/%s" ns sym))
+ ("unbound" (message "%s/%s is unbound" ns sym)))))))))
+ query)
+
+(defun cider-profile-display-stats (stats-response)
+ "Displays the STATS-RESPONSE on `cider-profile-buffer`."
+ (let ((table (nrepl-dict-get stats-response "err")))
+ (if cider-profile-buffer
+ (let ((buffer (cider-make-popup-buffer cider-profile-buffer)))
+ (with-current-buffer buffer
+ (let ((inhibit-read-only t)) (insert table)))
+ (display-buffer buffer)
+ (let ((window (get-buffer-window buffer)))
+ (set-window-point window 0)
+ (select-window window)
+ (fit-window-to-buffer window)))
+ (cider-emit-interactive-eval-err-output table))))
+
+;;;###autoload
+(defun cider-profile-summary ()
+ "Display a summary of currently collected profile data."
+ (interactive)
+ (cider-ensure-op-supported "profile-summary")
+ (cider-profile-display-stats
+ (cider-nrepl-send-sync-request '("op" "profile-summary"))))
+
+;;;###autoload
+(defun cider-profile-var-summary (query)
+ "Display profile data for var under point QUERY.
+
+Defaults to the symbol at point. With prefix arg or no symbol at point,
+prompts for a var."
+ (interactive "P")
+ (cider-ensure-op-supported "profile-var-summary")
+ (cider-read-symbol-name
+ "Profile-summary for var: "
+ (lambda (sym)
+ (cider-profile-display-stats
+ (cider-nrepl-send-sync-request
+ `("op" "profile-var-summary"
+ "ns" ,(cider-current-ns)
+ "sym" ,sym)))))
+ query)
+
+;;;###autoload
+(defun cider-profile-clear ()
+ "Clear any collected profile data."
+ (interactive)
+ (cider-ensure-op-supported "clear-profile")
+ (cider-nrepl-send-request
+ '("op" "clear-profile")
+ (cider-profile--make-response-handler
+ (lambda (_buffer value)
+ (when (equal value "cleared")
+ (message "Cleared profile data"))))))
+
+(provide 'cider-profile)
+
+;;; cider-profile.el ends here
diff --git a/cider-repl-history.el b/cider-repl-history.el
index c1a5a387..c4d66dbc 100644
--- a/cider-repl-history.el
+++ b/cider-repl-history.el
@@ -676,8 +676,8 @@ text from the *cider-repl-history* buffer."
(interactive)
(cl-assert (eq major-mode 'cider-repl-history-mode))
(cider-repl-history-setup cider-repl-history-repl-window
- cider-repl-history-repl-buffer
- (current-buffer))
+ cider-repl-history-repl-buffer
+ (current-buffer))
(cider-repl-history-resize-window))
(defun cider-repl-history-occur (regexp)
@@ -687,9 +687,9 @@ text from the *cider-repl-history* buffer."
"Display command history entries matching" nil)))
(cl-assert (eq major-mode 'cider-repl-history-mode))
(cider-repl-history-setup cider-repl-history-repl-window
- cider-repl-history-repl-buffer
- (current-buffer)
- regexp)
+ cider-repl-history-repl-buffer
+ (current-buffer)
+ regexp)
(cider-repl-history-resize-window))
(put 'cider-repl-history-mode 'mode-class 'special)
diff --git a/cider-repl.el b/cider-repl.el
index ec412478..bb659215 100644
--- a/cider-repl.el
+++ b/cider-repl.el
@@ -1,7 +1,7 @@
;;; cider-repl.el --- REPL interactions -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
@@ -9,6 +9,7 @@
;; Artur Malabarba <bruce.connor.am@gmail.com>
;; Hugo Duncan <hugo@hugoduncan.org>
;; Steve Purcell <steve@sanityinc.com>
+;; Reid McKenzie <me@arrdem.com>
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -89,7 +90,7 @@ set to `display-only' the buffer will be displayed, but it will not become
focused. Otherwise the buffer is displayed and focused."
:type '(choice (const :tag "Create the buffer, but don't display it" nil)
(const :tag "Create and display the buffer, but don't focus it"
- display-only)
+ display-only)
(const :tag "Create, display, and focus the buffer" t))
:group 'cider-repl)
@@ -112,7 +113,7 @@ If this is set to nil, no re-centering takes place."
:package-version '(cider . "0.11.0"))
(defcustom cider-repl-use-pretty-printing nil
- "Control whether the results in REPL are pretty-printed or not.
+ "Control whether results in the REPL are pretty-printed or not.
The `cider-toggle-pretty-printing' command can be used to interactively
change the setting's value."
:type 'boolean
@@ -123,10 +124,18 @@ change the setting's value."
This sets the wrap point for pretty printing on the repl. If nil, it
defaults to the variable `fill-column'."
:type '(restricted-sexp :match-alternatives
- (integerp 'nil))
+ (integerp 'nil))
:group 'cider-repl
:package-version '(cider . "0.15.0"))
+(defcustom cider-repl-use-content-types t
+ "Control whether REPL results are presented using content-type information.
+The `cider-repl-toggle-content-types' command can be used to interactively
+change the setting's value."
+ :type 'boolean
+ :group 'cider-repl
+ :package-version '(cider . "0.17.0"))
+
(defcustom cider-repl-use-clojure-font-lock t
"Non-nil means to use Clojure mode font-locking for input and result.
Nil means that `cider-repl-input-face' and `cider-repl-result-face'
@@ -136,7 +145,9 @@ will be used."
:package-version '(cider . "0.10.0"))
(defcustom cider-repl-result-prefix ""
- "The prefix displayed in the REPL before a result value."
+ "The prefix displayed in the REPL before a result value.
+By default there's no prefix, but you can specify something
+like \"=>\" if want results to stand out more."
:type 'string
:group 'cider
:package-version '(cider . "0.5.0"))
@@ -149,6 +160,18 @@ you'd like to use the default Emacs behavior use
:type 'symbol
:group 'cider-repl)
+(defcustom cider-repl-print-length 100
+ "Initial value for *print-length* set during REPL start."
+ :type 'integer
+ :group 'cider
+ :package-version '(cider . "0.17.0"))
+
+(defcustom cider-repl-print-level nil
+ "Initial value for *print-level* set during REPL start."
+ :type 'integer
+ :group 'cider
+ :package-version '(cider . "0.17.0"))
+
(defcustom cider-repl-display-help-banner t
"When non-nil a bit of help text will be displayed on REPL start."
:type 'boolean
@@ -211,7 +234,7 @@ via `cider-current-connection'.")
(when (member "state" (nrepl-dict-get response "status"))
(nrepl-dbind-response response (repl-type changed-namespaces)
(when repl-type
- (setq cider-repl-type repl-type))
+ (cider-repl-set-type repl-type))
(unless (nrepl-dict-empty-p changed-namespaces)
(setq cider-repl-ns-cache (nrepl-dict-merge cider-repl-ns-cache changed-namespaces))
(dolist (b (buffer-list))
@@ -247,7 +270,7 @@ ENDPOINT is a plist as returned by `nrepl-connect'."
(with-current-buffer (get-buffer-create buff-name)
(unless (derived-mode-p 'cider-repl-mode)
(cider-repl-mode)
- (setq cider-repl-type "clj"))
+ (cider-repl-set-type "clj"))
(setq nrepl-err-handler #'cider-default-err-handler)
(cider-repl-reset-markers)
(add-hook 'nrepl-response-handler-functions #'cider-repl--state-handler nil 'local)
@@ -266,7 +289,7 @@ efficiency."
(let ((nrepl-sync-request-timeout nil))
(with-current-buffer buffer
(let* ((response (nrepl-send-sync-request
- (lax-plist-put (nrepl--eval-request "(str *ns*))")
+ (lax-plist-put (nrepl--eval-request "(str *ns*)")
"inhibit-cider-middleware" "true")
(cider-current-connection)))
(initial-ns (or (read (nrepl-dict-get response "value"))
@@ -284,6 +307,25 @@ efficiency."
"inhibit-cider-middleware" "true")
(cider-current-connection)))
+(defun cider-repl--build-config-expression ()
+ "Build the initial config expression."
+ (when (or cider-repl-print-length cider-repl-print-level)
+ (concat
+ "(do"
+ (when cider-repl-print-length (format " (set! *print-length* %d)" cider-repl-print-length))
+ (when cider-repl-print-level (format " (set! *print-level* %d)" cider-repl-print-level))
+ ")")))
+
+(defun cider-repl-set-config ()
+ "Set an inititial REPL configuration."
+ (interactive)
+ (when-let* ((config-expression (cider-repl--build-config-expression)))
+ (nrepl-send-sync-request
+ (lax-plist-put
+ (nrepl--eval-request config-expression)
+ "inhibit-cider-middleware" "true")
+ (cider-current-connection))))
+
(defun cider-repl-init (buffer &optional no-banner)
"Initialize the REPL in BUFFER.
BUFFER must be a REPL buffer with `cider-repl-mode' and a running
@@ -295,6 +337,7 @@ client process connection. Unless NO-BANNER is non-nil, insert a banner."
((pred identity) (pop-to-buffer buffer)))
(cider-repl-set-initial-ns buffer)
(cider-repl-require-repl-utils)
+ (cider-repl-set-config)
(unless no-banner
(cider-repl--insert-banner-and-prompt buffer))
buffer)
@@ -365,7 +408,7 @@ client process connection. Unless NO-BANNER is non-nil, insert a banner."
;; Above all else - don't panic! In case of an emergency - procure
;; some (hard) cider and enjoy it responsibly!
;;
-;; You can remove this message with the `cider-repl-clear-help-banner' command.
+;; You can remove this message with the <M-x cider-repl-clear-help-banner> command.
;; You can disable it from appearing on start by setting
;; `cider-repl-display-help-banner' to nil.
;; ======================================================================
@@ -583,7 +626,7 @@ When there is a possible unfinished ansi control sequence,
(unless (member root cider-repl--ns-roots)
(push root cider-repl--ns-roots)
(let ((roots (mapconcat
- ;; Replace _ or - with regexp patter to accommodate "raw" namespaces
+ ;; Replace _ or - with regexp pattern to accommodate "raw" namespaces
(lambda (r) (replace-regexp-in-string "[_-]+" "[_-]+" r))
cider-repl--ns-roots "\\|")))
(setq cider-repl--root-ns-regexp
@@ -767,61 +810,173 @@ the symbol."
t)))
(t t))))
+(defun cider-repl--display-image (buffer image &optional show-prefix bol string)
+ "Insert IMAGE into BUFFER at the current point.
+
+For compatibility with the rest of CIDER's REPL machinery, supports
+SHOW-PREFIX and BOL."
+ (with-current-buffer buffer
+ (save-excursion
+ (cider-save-marker cider-repl-output-start
+ (cider-save-marker cider-repl-output-end
+ (goto-char cider-repl-input-start-mark)
+ (when (and bol (not (bolp)))
+ (insert-before-markers "\n"))
+ (when show-prefix
+ (insert-before-markers
+ (propertize cider-repl-result-prefix 'font-lock-face 'font-lock-comment-face)))
+ (insert-image image string)
+ (set-marker cider-repl-input-start-mark (point) buffer)
+ (set-marker cider-repl-prompt-start-mark (point) buffer))))
+ (cider-repl--show-maximum-output))
+ t)
+
+(defcustom cider-repl-image-margin 10
+ "Specifies the margin to be applied to images displayed in the REPL.
+
+Either a single number of pixels - interpreted as a symmetric margin, or
+pair of numbers `(x . y)' encoding an arbitrary margin."
+ :type '(choice integer (vector integer integer))
+ :group 'cider-repl
+ :package-version '(cider . "0.17.0"))
+
+(defun cider-repl--image (data type datap)
+ "A helper for creating images with CIDER's image options.
+
+DATA is either the path to an image or its base64 coded data. TYPE
+is a symbol indicating the image type. DATAP indicates whether the image is
+the raw image data or a filename.
+
+Returns an image instance with a margin per `cider-repl-image-margin'."
+ (create-image data type datap
+ :margin cider-repl-image-margin))
+
+(defun cider-repl-handle-jpeg (_type buffer image &optional show-prefix bol)
+ "A handler for inserting a jpeg IMAGE into a repl BUFFER.
+Part of the default `cider-repl-content-type-handler-alist'."
+ (cider-repl--display-image buffer
+ (cider-repl--image image 'jpeg t)
+ show-prefix bol image))
+
+(defun cider-repl-handle-png (_type buffer image &optional show-prefix bol)
+ "A handler for inserting a png IMAGE into a repl BUFFER.
+Part of the default `cider-repl-content-type-handler-alist'."
+ (cider-repl--display-image buffer
+ (cider-repl--image image 'png t)
+ show-prefix bol image))
+
+(defun cider-repl-handle-external-body (type buffer _ &optional _show-prefix _bol)
+ "Handler for slurping external content into BUFFER.
+Handles an external-body TYPE by issuing a slurp request to fetch the content."
+ (if-let* ((args (cadr type))
+ (access-type (nrepl-dict-get args "access-type")))
+ (nrepl-send-request
+ (list "op" "slurp" "url" (nrepl-dict-get args "URL"))
+ (cider-repl-handler buffer)
+ (cider-current-connection)))
+ nil)
+
+(defvar cider-repl-content-type-handler-alist
+ `(("message/external-body" . ,#'cider-repl-handle-external-body)
+ ("image/jpeg" . ,#'cider-repl-handle-jpeg)
+ ("image/png" . ,#'cider-repl-handle-png))
+ "Association list from content-types to handlers.
+
+Handlers must be functions of two required and two optional arguments - the
+REPL buffer to insert into, the value of the given content type as a raw
+string, the REPL's show prefix as any and an `end-of-line' flag.
+
+The return value of the handler should be a flag, indicating whether or not
+the REPL is ready for a prompt to be displayed. Most handlers should return
+t, as the content-type response is (currently) an alternative to the
+value response. However for handlers which themselves issue subsequent
+nREPL ops, it may be convenient to prevent inserting a prompt.")
+
(defun cider-repl-handler (buffer)
"Make an nREPL evaluation handler for the REPL BUFFER."
- (nrepl-make-response-handler buffer
- (let (after-first-result-chunk)
- (lambda (buffer value)
- (cider-repl-emit-result buffer value (not after-first-result-chunk) t)
- (setq after-first-result-chunk t)))
- (lambda (buffer out)
- (cider-repl-emit-stdout buffer out))
- (lambda (buffer err)
- (cider-repl-emit-stderr buffer err))
- (lambda (buffer)
- (cider-repl-emit-prompt buffer))
- nrepl-err-handler
- (let (after-first-result-chunk)
- (lambda (buffer pprint-out)
- (cider-repl-emit-result buffer pprint-out (not after-first-result-chunk))
- (setq after-first-result-chunk t)))))
+ (let (after-first-result-chunk
+ (show-prompt t))
+ (nrepl-make-response-handler
+ buffer
+ (lambda (buffer value)
+ (cider-repl-emit-result buffer value (not after-first-result-chunk) t)
+ (setq after-first-result-chunk t))
+ (lambda (buffer out)
+ (cider-repl-emit-stdout buffer out))
+ (lambda (buffer err)
+ (cider-repl-emit-stderr buffer err))
+ (lambda (buffer)
+ (when show-prompt
+ (cider-repl-emit-prompt buffer)
+ (let ((win (get-buffer-window (current-buffer) t)))
+ (when win
+ (with-selected-window win
+ (set-window-point win cider-repl-input-start-mark))
+ (cider-repl--show-maximum-output)))))
+ nrepl-err-handler
+ (lambda (buffer pprint-out)
+ (cider-repl-emit-result buffer pprint-out (not after-first-result-chunk))
+ (setq after-first-result-chunk t))
+ (lambda (buffer value content-type)
+ (if-let* ((content-attrs (cadr content-type))
+ (content-type* (car content-type))
+ (handler (cdr (assoc content-type*
+ cider-repl-content-type-handler-alist))))
+ (setq after-first-result-chunk t
+ show-prompt (funcall handler content-type buffer value
+ (not after-first-result-chunk) t))
+ (progn (cider-repl-emit-result buffer value (not after-first-result-chunk) t)
+ (setq after-first-result-chunk t)))))))
+
+(defun cider--repl-request-plist (right-margin &optional pprint-fn)
+ "Plist to be appended to generic eval requests, as for the REPL.
+PPRINT-FN and RIGHT-MARGIN are as in `cider--nrepl-pprint-request-plist'."
+ (nconc (when cider-repl-use-pretty-printing
+ (cider--nrepl-pprint-request-plist right-margin pprint-fn))
+ (when cider-repl-use-content-types
+ (cider--nrepl-content-type-plist))))
(defun cider-repl--send-input (&optional newline)
"Go to the end of the input and send the current input.
If NEWLINE is true then add a newline at the end of the input."
(unless (cider-repl--in-input-area-p)
(error "No input at point"))
- (goto-char (point-max))
- (let ((end (point))) ; end of input, without the newline
- (cider-repl--add-to-input-history (buffer-substring cider-repl-input-start-mark end))
- (when newline
- (insert "\n")
- (cider-repl--show-maximum-output))
- (let ((inhibit-modification-hooks t))
- (add-text-properties cider-repl-input-start-mark
- (point)
- `(cider-old-input
- ,(cl-incf cider-repl-old-input-counter))))
- (unless cider-repl-use-clojure-font-lock
- (let ((overlay (make-overlay cider-repl-input-start-mark end)))
- ;; These properties are on an overlay so that they won't be taken
- ;; by kill/yank.
- (overlay-put overlay 'read-only t)
- (overlay-put overlay 'font-lock-face 'cider-repl-input-face))))
- (let ((input (cider-repl--current-input))
- (input-start (save-excursion (cider-repl-beginning-of-defun) (point))))
- (goto-char (point-max))
- (cider-repl--mark-input-start)
- (cider-repl--mark-output-start)
- (cider-nrepl-request:eval
- input
- (cider-repl-handler (current-buffer))
- (cider-current-ns)
- (line-number-at-pos input-start)
- (cider-column-number-at-pos input-start)
- (unless (or (not cider-repl-use-pretty-printing)
- (string-match-p "\\`[ \t\r\n]*\\'" input))
- (cider--nrepl-pprint-request-plist (cider--pretty-print-width))))))
+ (let ((input (cider-repl--current-input)))
+ (if (string-blank-p input)
+ ;; don't evaluate a blank string, but erase it and emit
+ ;; a fresh prompt to acknowledge to the user.
+ (progn
+ (cider-repl--replace-input "")
+ (cider-repl-emit-prompt (current-buffer)))
+ ;; otherwise evaluate the input
+ (goto-char (point-max))
+ (let ((end (point))) ; end of input, without the newline
+ (cider-repl--add-to-input-history input)
+ (when newline
+ (insert "\n")
+ (cider-repl--show-maximum-output))
+ (let ((inhibit-modification-hooks t))
+ (add-text-properties cider-repl-input-start-mark
+ (point)
+ `(cider-old-input
+ ,(cl-incf cider-repl-old-input-counter))))
+ (unless cider-repl-use-clojure-font-lock
+ (let ((overlay (make-overlay cider-repl-input-start-mark end)))
+ ;; These properties are on an overlay so that they won't be taken
+ ;; by kill/yank.
+ (overlay-put overlay 'read-only t)
+ (overlay-put overlay 'font-lock-face 'cider-repl-input-face))))
+ (let ((input-start (save-excursion (cider-repl-beginning-of-defun) (point))))
+ (goto-char (point-max))
+ (cider-repl--mark-input-start)
+ (cider-repl--mark-output-start)
+ (cider-nrepl-request:eval
+ input
+ (cider-repl-handler (current-buffer))
+ (cider-current-ns)
+ (line-number-at-pos input-start)
+ (cider-column-number-at-pos input-start)
+ (cider--repl-request-plist (cider--pretty-print-width)))))))
(defun cider-repl-return (&optional end-of-input)
"Evaluate the current input string, or insert a newline.
@@ -897,6 +1052,13 @@ text property `cider-old-input'."
fill-column
80))
+(defun cider-repl-toggle-content-types ()
+ "Toggle content-type rendering in the REPL."
+ (interactive)
+ (setq cider-repl-use-content-types (not cider-repl-use-content-types))
+ (message "Content-type support in REPL %s."
+ (if cider-repl-use-content-types "enabled" "disabled")))
+
(defun cider-repl-switch-to-other ()
"Switch between the Clojure and ClojureScript REPLs for the current project."
(interactive)
@@ -912,7 +1074,10 @@ text property `cider-old-input'."
(delete-region start end))
(defun cider-repl-clear-buffer ()
- "Delete the output generated by the Clojure process."
+ "Clear the currently visited REPL buffer completely.
+
+See also the related commands `cider-repl-clear-output' and
+`cider-find-and-clear-repl-output'."
(interactive)
(let ((inhibit-read-only t))
(cider-repl--clear-region (point-min) cider-repl-prompt-start-mark)
@@ -998,7 +1163,7 @@ With a prefix argument CLEAR-REPL it will clear the entire REPL buffer instead."
(defun cider-repl-set-ns (ns)
"Switch the namespace of the REPL buffer to NS.
-If called from a cljc or cljx buffer act on both the Clojure and
+If called from a cljc buffer act on both the Clojure and
ClojureScript REPL if there are more than one REPL present.
If invoked in a REPL buffer the command will prompt for the name of the
@@ -1016,6 +1181,18 @@ namespace to switch to."
(cider-repl-switch-ns-handler connection)))
:both))
+(defun cider-repl-set-type (&optional type)
+ "Set REPL TYPE to \"clj\" or \"cljs\"."
+ (interactive)
+ (let ((type (or type (completing-read
+ (format "Set REPL type (currently `%s') to: "
+ cider-repl-type)
+ '("clj" "cljs")))))
+ (setq cider-repl-type type)
+ (if (equal type "cljs")
+ (setq mode-name "REPL[cljs]")
+ (setq mode-name "REPL[clj]"))))
+
;;; Location References
@@ -1354,13 +1531,16 @@ constructs."
(declare-function cider-repl-history "cider-repl-history")
(declare-function cider-run "cider-interaction")
(declare-function cider-refresh "cider-interaction")
+(declare-function cider-version "cider")
+(declare-function cider-test-run-loaded-tests "cider-test")
+(declare-function cider-test-run-project-tests "cider-test")
(cider-repl-add-shortcut "clear-output" #'cider-repl-clear-output)
(cider-repl-add-shortcut "clear" #'cider-repl-clear-buffer)
(cider-repl-add-shortcut "clear-banners" #'cider-repl-clear-banners)
(cider-repl-add-shortcut "clear-help-banner" #'cider-repl-clear-help-banner)
(cider-repl-add-shortcut "ns" #'cider-repl-set-ns)
(cider-repl-add-shortcut "toggle-pretty" #'cider-repl-toggle-pretty-printing)
-(cider-repl-add-shortcut "browse-ns" (lambda () (cider-browse-ns (cider-current-ns))))
+(cider-repl-add-shortcut "browse-ns" (lambda () (interactive) (cider-browse-ns (cider-current-ns))))
(cider-repl-add-shortcut "classpath" #'cider-classpath)
(cider-repl-add-shortcut "history" #'cider-repl-history)
(cider-repl-add-shortcut "trace-ns" #'cider-toggle-trace-ns)
@@ -1370,6 +1550,9 @@ constructs."
(cider-repl-add-shortcut "test-ns" #'cider-test-run-ns-tests)
(cider-repl-add-shortcut "test-all" #'cider-test-run-loaded-tests)
(cider-repl-add-shortcut "test-project" #'cider-test-run-project-tests)
+(cider-repl-add-shortcut "test-ns-with-filters" #'cider-test-run-ns-tests-with-filters)
+(cider-repl-add-shortcut "test-all-with-filters" (lambda () (interactive) (cider-test-run-loaded-tests 'prompt-for-filters)))
+(cider-repl-add-shortcut "test-project-with-filters" (lambda () (interactive) (cider-test-run-project-tests 'prompt-for-filters)))
(cider-repl-add-shortcut "test-report" #'cider-test-show-report)
(cider-repl-add-shortcut "run" #'cider-run)
(cider-repl-add-shortcut "conn-info" #'cider-display-connection-info)
@@ -1411,7 +1594,7 @@ constructs."
(if (not (equal command ""))
(let ((command-func (gethash command cider-repl-shortcuts)))
(if command-func
- (call-interactively (gethash command cider-repl-shortcuts))
+ (call-interactively command-func)
(error "Unknown command %S. Available commands: %s"
command-func
(mapconcat 'identity (cider-repl--available-shortcuts) ", "))))
@@ -1425,7 +1608,6 @@ constructs."
(defvar cider-repl-mode-syntax-table
(copy-syntax-table clojure-mode-syntax-table))
-(declare-function cider-eval-region "cider-interaction")
(declare-function cider-eval-last-sexp "cider-interaction")
(declare-function cider-refresh "cider-interaction")
(declare-function cider-toggle-trace-ns "cider-interaction")
@@ -1435,6 +1617,9 @@ constructs."
(declare-function cider-find-ns "cider-interaction")
(declare-function cider-find-keyword "cider-interaction")
(declare-function cider-switch-to-last-clojure-buffer "cider-mode")
+(declare-function cider-macroexpand-1 "cider-macroexpansion")
+(declare-function cider-macroexpand-all "cider-macroexpansion")
+(declare-function cider-selector "cider-selector")
(defvar cider-repl-mode-map
(let ((map (make-sparse-keymap)))
@@ -1478,7 +1663,8 @@ constructs."
(define-key map (kbd "C-c M-t n") #'cider-toggle-trace-ns)
(define-key map (kbd "C-c C-x") #'cider-refresh)
(define-key map (kbd "C-x C-e") #'cider-eval-last-sexp)
- (define-key map (kbd "C-c C-r") #'cider-eval-region)
+ (define-key map (kbd "C-c C-r") 'clojure-refactor-map)
+ (define-key map (kbd "C-c C-v") 'cider-eval-commands-map)
(define-key map (string cider-repl-shortcut-dispatch-char) #'cider-repl-handle-shortcut)
(easy-menu-define cider-repl-mode-menu map
"Menu for CIDER's REPL mode"
@@ -1510,6 +1696,7 @@ constructs."
["Refresh loaded code" cider-refresh]
"--"
["Set REPL ns" cider-repl-set-ns]
+ ["Set REPL type" cider-repl-set-type]
["Toggle pretty printing" cider-repl-toggle-pretty-printing]
["Require REPL utils" cider-repl-require-repl-utils]
"--"
@@ -1536,6 +1723,8 @@ constructs."
["Quit" cider-quit]
["Restart" cider-restart]
"--"
+ ["Clojure Cheatsheet" cider-cheatsheet]
+ "--"
["A sip of CIDER" cider-drink-a-sip]
["View manual online" cider-view-manual]
["View refcard online" cider-view-refcard]
diff --git a/cider-resolve.el b/cider-resolve.el
index fa328aff..454663b8 100644
--- a/cider-resolve.el
+++ b/cider-resolve.el
@@ -1,6 +1,6 @@
;;; cider-resolve.el --- Resolve clojure symbols according to current nREPL connection
-;; Copyright © 2015-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
diff --git a/cider-scratch.el b/cider-scratch.el
index 1b6d12e5..2dded9fb 100644
--- a/cider-scratch.el
+++ b/cider-scratch.el
@@ -1,6 +1,6 @@
;;; cider-scratch.el --- *scratch* buffer for Clojure -*- lexical-binding: t -*-
-;; Copyright © 2014-2017 Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
diff --git a/cider-selector.el b/cider-selector.el
index ba85f703..dc6b4ea2 100644
--- a/cider-selector.el
+++ b/cider-selector.el
@@ -1,7 +1,7 @@
;;; cider-selector.el --- Buffer selection command inspired by SLIME's selector -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
diff --git a/cider-stacktrace.el b/cider-stacktrace.el
index 917c286c..c8ebb7ee 100644
--- a/cider-stacktrace.el
+++ b/cider-stacktrace.el
@@ -1,6 +1,6 @@
;;; cider-stacktrace.el --- Stacktrace navigator -*- lexical-binding: t -*-
-;; Copyright © 2014-2017 Jeff Valk, Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
;; Author: Jeff Valk <jv@jeffvalk.com>
@@ -574,9 +574,12 @@ Achieved by destructively manipulating the `cider-stacktrace-suppressed-errors'
;; Set `line-shift' to the number of lines from the beginning of defn.
(line-shift (- (or (button-get button 'line) 0)
(or (nrepl-dict-get info "line") 1)))
+ (file (or
+ (and (null var) (cider-resolve-java-class class))
+ (nrepl-dict-get info "file")
+ (button-get button 'file)))
;; give priority to `info` files as `info` returns full paths.
- (info (nrepl-dict-put info "file" (or (nrepl-dict-get info "file")
- (button-get button 'file)))))
+ (info (nrepl-dict-put info "file" file)))
(cider--jump-to-loc-from-info info t)
(forward-line line-shift)
(back-to-indentation)))
diff --git a/cider-test.el b/cider-test.el
index 524137d4..239124b0 100644
--- a/cider-test.el
+++ b/cider-test.el
@@ -1,6 +1,6 @@
;;; cider-test.el --- Test result viewer -*- lexical-binding: t -*-
-;; Copyright © 2014-2017 Jeff Valk, Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
;; Author: Jeff Valk <jv@jeffvalk.com>
@@ -37,6 +37,7 @@
(require 'cider-overlays)
(require 'button)
+(require 'cl-lib)
(require 'easymenu)
(require 'seq)
@@ -128,6 +129,7 @@ Add to this list to have CIDER recognize additional test defining macros."
;;; Report mode & key bindings
+;;
;; The primary mode of interacting with test results is the report buffer, which
;; allows navigation among tests, jumping to test definitions, expected/actual
;; diff-ing, and cause/stacktrace inspection for test errors.
@@ -139,6 +141,7 @@ Add to this list to have CIDER recognize additional test defining macros."
(define-key map (kbd "C-t") #'cider-test-run-test)
(define-key map (kbd "C-g") #'cider-test-rerun-test)
(define-key map (kbd "C-n") #'cider-test-run-ns-tests)
+ (define-key map (kbd "C-s") #'cider-test-run-ns-tests-with-filters)
(define-key map (kbd "C-l") #'cider-test-run-loaded-tests)
(define-key map (kbd "C-p") #'cider-test-run-project-tests)
(define-key map (kbd "C-b") #'cider-test-show-report)
@@ -147,6 +150,7 @@ Add to this list to have CIDER recognize additional test defining macros."
(define-key map (kbd "t") #'cider-test-run-test)
(define-key map (kbd "g") #'cider-test-rerun-test)
(define-key map (kbd "n") #'cider-test-run-ns-tests)
+ (define-key map (kbd "s") #'cider-test-run-ns-tests-with-filters)
(define-key map (kbd "l") #'cider-test-run-loaded-tests)
(define-key map (kbd "p") #'cider-test-run-project-tests)
(define-key map (kbd "b") #'cider-test-show-report)
@@ -156,8 +160,11 @@ Add to this list to have CIDER recognize additional test defining macros."
'("Test"
["Run test" cider-test-run-test]
["Run namespace tests" cider-test-run-ns-tests]
+ ["Run namespace tests with filters" cider-test-run-ns-tests-with-filters]
["Run all loaded tests" cider-test-run-loaded-tests]
+ ["Run all loaded tests with filters" (apply-partially cider-test-run-loaded-tests 'prompt-for-filters)]
["Run all project tests" cider-test-run-project-tests]
+ ["Run all project tests with filters" (apply-partially cider-test-run-project-tests 'prompt-for-filters)]
["Run tests after load-file" cider-auto-test-mode
:style toggle :selected cider-auto-test-mode]
"--"
@@ -184,6 +191,7 @@ Add to this list to have CIDER recognize additional test defining macros."
;; `f' for "run failed".
(define-key map "f" #'cider-test-rerun-failed-tests)
(define-key map "n" #'cider-test-run-ns-tests)
+ (define-key map "s" #'cider-test-run-ns-tests-with-filters)
(define-key map "l" #'cider-test-run-loaded-tests)
(define-key map "p" #'cider-test-run-project-tests)
;; `g' generally reloads the buffer. The closest thing we have to that is
@@ -200,8 +208,11 @@ Add to this list to have CIDER recognize additional test defining macros."
["Rerun current test" cider-test-run-test]
["Rerun failed/erring tests" cider-test-rerun-failed-tests]
["Run all ns tests" cider-test-run-ns-tests]
+ ["Run all ns tests with filters" cider-test-run-ns-tests-with-filters]
["Run all loaded tests" cider-test-run-loaded-tests]
+ ["Run all loaded tests with filters" (apply-partially cider-test-run-loaded-tests 'prompt-for-filters)]
["Run all project tests" cider-test-run-project-tests]
+ ["Run all project tests with filters" (apply-partially cider-test-run-project-tests 'prompt-for-filters)]
"--"
["Jump to test definition" cider-test-jump]
["Display test error" cider-test-stacktrace]
@@ -303,35 +314,48 @@ prompt and whether to use a new window. Similar to `cider-find-var'."
(defvar cider-test-ediff-buffers nil
"The expected/actual buffers used to display diff.")
+(defun cider-test--extract-from-actual (actual n)
+ "Extract form N from ACTUAL, ignoring outermost not.
+
+ACTUAL is a string like \"(not (= 3 4))\", of the sort returned by
+clojure.test.
+
+N = 1 => 3, N = 2 => 4, etc."
+ (with-temp-buffer
+ (insert actual)
+ (clojure-mode)
+ (goto-char (point-min))
+ (re-search-forward "(" nil t 2)
+ (clojure-forward-logical-sexp n)
+ (forward-whitespace 1)
+ (let ((beg (point)))
+ (clojure-forward-logical-sexp)
+ (buffer-substring beg (point)))))
+
(defun cider-test-ediff ()
"Show diff of the expected vs actual value for the test at point.
With the actual value, the outermost '(not ...)' s-expression is removed."
(interactive)
- (let ((expected (get-text-property (point) 'expected))
- (actual (get-text-property (point) 'actual)))
- (if (and expected actual)
- (let ((expected-buffer (generate-new-buffer " *expected*"))
- (actual-buffer (generate-new-buffer " *actual*")))
- (with-current-buffer expected-buffer
- (insert expected)
- (clojure-mode))
- (with-current-buffer actual-buffer
- (insert actual)
- (goto-char (point-min))
- (forward-char)
- (forward-sexp)
- (forward-whitespace 1)
- (let ((beg (point)))
- (forward-sexp)
- (let ((actual* (buffer-substring beg (point))))
- (erase-buffer)
- (insert actual*)))
- (clojure-mode))
- (apply 'ediff-buffers
- (setq cider-test-ediff-buffers
- (list (buffer-name expected-buffer)
- (buffer-name actual-buffer)))))
- (message "No test failure at point"))))
+ (let* ((expected-buffer (generate-new-buffer " *expected*"))
+ (actual-buffer (generate-new-buffer " *actual*"))
+ (diffs (get-text-property (point) 'diffs))
+ (actual* (get-text-property (point) 'actual))
+ (expected (cond (diffs (get-text-property (point) 'expected))
+ (actual* (cider-test--extract-from-actual actual* 1))))
+ (actual (cond (diffs (caar diffs))
+ (actual* (cider-test--extract-from-actual actual* 2)))))
+ (if (not (and expected actual))
+ (message "No test failure at point")
+ (with-current-buffer expected-buffer
+ (insert expected)
+ (clojure-mode))
+ (with-current-buffer actual-buffer
+ (insert actual)
+ (clojure-mode))
+ (apply #'ediff-buffers
+ (setq cider-test-ediff-buffers
+ (list (buffer-name expected-buffer)
+ (buffer-name actual-buffer)))))))
(defun cider-test-ediff-cleanup ()
"Cleanup expected/actual buffers used for diff."
@@ -374,36 +398,57 @@ With the actual value, the outermost '(not ...)' s-expression is removed."
(defun cider-test-render-assertion (buffer test)
"Emit into BUFFER report detail for the TEST assertion."
(with-current-buffer buffer
- (nrepl-dbind-response test (var context type message expected actual error gen-input)
- (cider-propertize-region (cider-intern-keys (cdr test))
- (let ((beg (point))
- (type-face (cider-test-type-simple-face type))
- (bg `(:background ,cider-test-items-background-color)))
- (cider-insert (capitalize type) type-face nil " in ")
- (cider-insert var 'font-lock-function-name-face t)
- (when context (cider-insert context 'font-lock-doc-face t))
- (when message (cider-insert message 'font-lock-doc-string-face t))
- (when expected
- (cider-insert "expected: " 'font-lock-comment-face nil
- (cider-font-lock-as-clojure expected)))
- (when actual
- (cider-insert " actual: " 'font-lock-comment-face nil
- (cider-font-lock-as-clojure actual)))
- (when error
- (cider-insert " error: " 'font-lock-comment-face nil)
- (insert-text-button error
- 'follow-link t
- 'action '(lambda (_button) (cider-test-stacktrace))
- 'help-echo "View causes and stacktrace")
- (insert "\n"))
- (when gen-input
- (cider-insert " input: " 'font-lock-comment-face nil
- (cider-font-lock-as-clojure gen-input)))
- (overlay-put (make-overlay beg (point)) 'font-lock-face bg))
- (insert "\n")))))
+ (nrepl-dbind-response test (var context type message expected actual diffs error gen-input)
+ (cl-flet ((insert-label (s)
+ (cider-insert (format "%8s: " s) 'font-lock-comment-face))
+ (insert-align-label (s)
+ (insert (format "%12s" s)))
+ (insert-rect (s)
+ (insert-rectangle (thread-first s
+ cider-font-lock-as-clojure
+ (split-string "\n")))
+ (beginning-of-line)))
+ (cider-propertize-region (cider-intern-keys (cdr test))
+ (let ((beg (point))
+ (type-face (cider-test-type-simple-face type))
+ (bg `(:background ,cider-test-items-background-color)))
+ (cider-insert (capitalize type) type-face nil " in ")
+ (cider-insert var 'font-lock-function-name-face t)
+ (when context (cider-insert context 'font-lock-doc-face t))
+ (when message (cider-insert message 'font-lock-doc-string-face t))
+ (when expected
+ (insert-label "expected")
+ (insert-rect expected)
+ (insert "\n"))
+ (if diffs
+ (dolist (d diffs)
+ (cl-destructuring-bind (actual (removed added)) d
+ (insert-label "actual")
+ (insert-rect actual)
+ (insert-label "diff")
+ (insert "- ")
+ (insert-rect removed)
+ (insert-align-label "+ ")
+ (insert-rect added)
+ (insert "\n")))
+ (when actual
+ (insert-label "actual")
+ (insert-rect actual)))
+ (when error
+ (insert-label "error")
+ (insert-text-button error
+ 'follow-link t
+ 'action '(lambda (_button) (cider-test-stacktrace))
+ 'help-echo "View causes and stacktrace")
+ (insert "\n"))
+ (when gen-input
+ (insert-label "input")
+ (insert (cider-font-lock-as-clojure gen-input)))
+ (overlay-put (make-overlay beg (point)) 'font-lock-face bg))
+ (insert "\n"))))))
(defun cider-test-non-passing (tests)
- "For a list of TESTS, each an nrepl-dict, return only those that did not pass."
+ "For a list of TESTS, each an `nrepl-dict`, return only those that did not pass."
(seq-filter (lambda (test)
(unless (equal (nrepl-dict-get test "type") "pass")
test))
@@ -477,6 +522,7 @@ The optional arg TEST denotes an individual test name."
test var fail error))))
;;; Test definition highlighting
+;;
;; On receipt of test results, failing/erring test definitions are highlighted.
;; Highlights are cleared on the next report run, and may be cleared manually
;; by the user.
@@ -490,11 +536,11 @@ The optional arg TEST denotes an individual test name."
(defun cider-test-highlight-problem (buffer test)
"Highlight the BUFFER test definition for the non-passing TEST."
(with-current-buffer buffer
- (nrepl-dbind-response test (type file line message expected actual)
- ;; we have to watch out for vars without proper location metadata
- ;; right now everything evaluated interactively lacks this data
- ;; TODO: Figure out what to do when the metadata is missing
- (when (and file line (not (cider--tooling-file-p file)))
+ ;; we don't need the file name here, as we always operate on the current
+ ;; buffer and the line data is correct even for vars that were
+ ;; defined interactively
+ (nrepl-dbind-response test (type line message expected actual)
+ (when line
(save-excursion
(goto-char (point-min))
(forward-line (1- line))
@@ -545,6 +591,7 @@ Or nil if not found."
;;; Test namespaces
+;;
;; Test namespace inference exists to enable DWIM test running functions: the
;; same "run-tests" function should be able to be used in a source file, and in
;; its corresponding test namespace. To provide this, we need to map the
@@ -573,7 +620,7 @@ This uses the Leiningen convention of appending '-test' to the namespace name."
(declare-function cider-emit-interactive-eval-output "cider-interaction")
(declare-function cider-emit-interactive-eval-err-output "cider-interaction")
-(defun cider-test-execute (ns &optional tests silent)
+(defun cider-test-execute (ns &optional tests silent prompt-for-filters)
"Run tests for NS, which may be a keyword, optionally specifying TESTS.
This tests a single NS, or multiple namespaces when using keywords `:project',
@@ -581,53 +628,66 @@ This tests a single NS, or multiple namespaces when using keywords `:project',
namespace is specified. Upon test completion, results are echoed and a test
report is optionally displayed. When test failures/errors occur, their sources
are highlighted.
-If SILENT is non-nil, suppress all messages other then test results."
+If SILENT is non-nil, suppress all messages other then test results.
+If PROMPT-FOR-FILTERS is non-nil, prompt the user for a test selector filters.
+The include/exclude selectors will be used to filter the tests before
+ running them."
(cider-test-clear-highlights)
- (cider-map-connections
- (lambda (conn)
- (unless silent
- (if (and tests (= (length tests) 1))
- ;; we generate a different message when running individual tests
- (cider-test-echo-running ns (car tests))
- (cider-test-echo-running ns)))
- (cider-nrepl-send-request
- `("op" ,(cond ((stringp ns) "test")
- ((eq :project ns) "test-all")
- ((eq :loaded ns) "test-all")
- ((eq :non-passing ns) "retest"))
- "ns" ,(when (stringp ns) ns)
- "tests" ,(when (stringp ns) tests)
- "load?" ,(when (or (stringp ns)
- (eq :project ns))
- "true"))
- (lambda (response)
- (nrepl-dbind-response response (summary results status out err)
- (cond ((member "namespace-not-found" status)
- (unless silent
- (message "No test namespace: %s" (cider-propertize ns 'ns))))
- (out (cider-emit-interactive-eval-output out))
- (err (cider-emit-interactive-eval-err-output err))
- (results
- (nrepl-dbind-response summary (error fail)
- (setq cider-test-last-summary summary)
- (setq cider-test-last-results results)
- (cider-test-highlight-problems results)
- (cider-test-echo-summary summary results)
- (if (or (not (zerop (+ error fail)))
- cider-test-show-report-on-success)
- (cider-test-render-report
- (cider-popup-buffer cider-test-report-buffer
- cider-auto-select-test-report-buffer)
- summary results)
- (when (get-buffer cider-test-report-buffer)
- (with-current-buffer cider-test-report-buffer
- (let ((inhibit-read-only t))
- (erase-buffer)))
- (cider-test-render-report
- cider-test-report-buffer
- summary results))))))))
- conn))
- :clj))
+ (let ((include-selectors
+ (when prompt-for-filters
+ (split-string
+ (cider-read-from-minibuffer "Test selectors to include (space separated): "))))
+ (exclude-selectors
+ (when prompt-for-filters
+ (split-string
+ (cider-read-from-minibuffer "Test selectors to exclude (space separated): ")))))
+ (cider-map-connections
+ (lambda (conn)
+ (unless silent
+ (if (and tests (= (length tests) 1))
+ ;; we generate a different message when running individual tests
+ (cider-test-echo-running ns (car tests))
+ (cider-test-echo-running ns)))
+ (cider-nrepl-send-request
+ `("op" ,(cond ((stringp ns) "test")
+ ((eq :project ns) "test-all")
+ ((eq :loaded ns) "test-all")
+ ((eq :non-passing ns) "retest"))
+ "includes" ,(when (listp include-selectors) include-selectors)
+ "excludes" ,(when (listp exclude-selectors) exclude-selectors)
+ "ns" ,(when (stringp ns) ns)
+ "tests" ,(when (stringp ns) tests)
+ "load?" ,(when (or (stringp ns) (eq :project ns)) "true"))
+ (lambda (response)
+ (nrepl-dbind-response response (summary results status out err)
+ (cond ((member "namespace-not-found" status)
+ (unless silent
+ (message "No test namespace: %s" (cider-propertize ns 'ns))))
+ (out (cider-emit-interactive-eval-output out))
+ (err (cider-emit-interactive-eval-err-output err))
+ (results
+ (nrepl-dbind-response summary (error fail)
+ (setq cider-test-last-summary summary)
+ (setq cider-test-last-results results)
+ (cider-test-highlight-problems results)
+ (cider-test-echo-summary summary results)
+ (if (or (not (zerop (+ error fail)))
+ cider-test-show-report-on-success)
+ (cider-test-render-report
+ (cider-popup-buffer
+ cider-test-report-buffer
+ cider-auto-select-test-report-buffer)
+ summary
+ results)
+ (when (get-buffer cider-test-report-buffer)
+ (with-current-buffer cider-test-report-buffer
+ (let ((inhibit-read-only t))
+ (erase-buffer)))
+ (cider-test-render-report
+ cider-test-report-buffer
+ summary results))))))))
+ conn))
+ :clj)))
(defun cider-test-rerun-failed-tests ()
"Rerun failed and erring tests from the last test run."
@@ -639,27 +699,40 @@ If SILENT is non-nil, suppress all messages other then test results."
(message "No prior failures to retest")))
(message "No prior results to retest")))
-(defun cider-test-run-loaded-tests ()
- "Run all tests defined in currently loaded namespaces."
- (interactive)
- (cider-test-execute :loaded))
+(defun cider-test-run-loaded-tests (prompt-for-filters)
+ "Run all tests defined in currently loaded namespaces.
-(defun cider-test-run-project-tests ()
- "Run all tests defined in all project namespaces, loading these as needed."
- (interactive)
- (cider-test-execute :project))
+If PROMPT-FOR-FILTERS is non-nil, prompt the user for a test selectors to filter the tests with."
+ (interactive "P")
+ (cider-test-execute :loaded nil nil prompt-for-filters))
+
+(defun cider-test-run-project-tests (prompt-for-filters)
+ "Run all tests defined in all project namespaces, loading these as needed.
-(defun cider-test-run-ns-tests (suppress-inference &optional silent)
+If PROMPT-FOR-FILTERS is non-nil, prompt the user for a test selectors to filter the tests with."
+ (interactive "P")
+ (cider-test-execute :project nil nil prompt-for-filters))
+
+(defun cider-test-run-ns-tests-with-filters (suppress-inference)
+ "Run tests filtered by selectors for the current Clojure namespace context.
+
+With a prefix arg SUPPRESS-INFERENCE it will try to run the tests in the
+current ns."
+ (interactive "P")
+ (cider-test-run-ns-tests suppress-inference nil 't))
+
+(defun cider-test-run-ns-tests (suppress-inference &optional silent prompt-for-filters)
"Run all tests for the current Clojure namespace context.
If SILENT is non-nil, suppress all messages other then test results.
With a prefix arg SUPPRESS-INFERENCE it will try to run the tests in the
-current ns."
+current ns. If PROMPT-FOR-FILTERS is non-nil, prompt the user for
+test selectors to filter the tests with."
(interactive "P")
(if-let* ((ns (if suppress-inference
(cider-current-ns t)
(funcall cider-test-infer-test-ns (cider-current-ns t)))))
- (cider-test-execute ns nil silent)
+ (cider-test-execute ns nil silent prompt-for-filters)
(if (eq major-mode 'cider-test-report-mode)
(when (y-or-n-p (concat "Test report does not define a namespace. "
"Rerun failed/erring tests?"))
@@ -688,15 +761,20 @@ is searched."
(let ((ns (get-text-property (point) 'ns))
(var (get-text-property (point) 'var)))
(if (and ns var)
+ ;; we're in a `cider-test-report-mode' buffer
+ ;; or on a highlighted failed/erred test definition
(progn
(cider-test-update-last-test ns var)
(cider-test-execute ns (list var)))
- (let ((ns (clojure-find-ns))
- (def (clojure-find-def)))
- (if (and ns (member (car def) cider-test-defining-forms))
+ ;; we're in a `clojure-mode' buffer
+ (let* ((ns (clojure-find-ns))
+ (def (clojure-find-def)) ; it's a list of the form (deftest something)
+ (deftype (car def))
+ (var (cadr def)))
+ (if (and ns (member deftype cider-test-defining-forms))
(progn
- (cider-test-update-last-test ns (cdr def))
- (cider-test-execute ns (cdr def)))
+ (cider-test-update-last-test ns (list var))
+ (cider-test-execute ns (list var)))
(message "No test at point"))))))
(defun cider-test-rerun-test ()
diff --git a/cider-util.el b/cider-util.el
index 3d348d89..fe7e275d 100644
--- a/cider-util.el
+++ b/cider-util.el
@@ -1,7 +1,7 @@
;; cider-util.el --- Common utility functions that don't belong anywhere else -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
@@ -31,12 +31,16 @@
;;; Code:
+;; Built-ins
+(require 'ansi-color)
+(require 'color)
(require 'seq)
-(require 'clojure-mode)
(require 'subr-x)
+
+;; clojure-mode and CIDER
(require 'cider-compat)
+(require 'clojure-mode)
(require 'nrepl-dict)
-(require 'ansi-color)
(defalias 'cider-pop-back 'pop-tag-mark)
@@ -83,12 +87,12 @@ which nREPL uses for temporary evaluation file names."
(let ((fname (file-name-nondirectory file-name)))
(string-match-p "^form-init" fname)))
-(defun cider--cljc-or-cljx-buffer-p (&optional buffer)
- "Return non-nil if the current buffer is visiting a cljc or cljx file.
+(defun cider--cljc-buffer-p (&optional buffer)
+ "Return non-nil if the current buffer is visiting a cljc file.
If BUFFER is provided act on that buffer instead."
(with-current-buffer (or buffer (current-buffer))
- (or (derived-mode-p 'clojurec-mode) (derived-mode-p 'clojurex-mode))))
+ (or (derived-mode-p 'clojurec-mode))))
;;; Thing at point
@@ -336,19 +340,12 @@ propertized (defaults to current buffer)."
;;; Colors
-(defun cider-scale-color (color scale)
- "For a COLOR hex string or name, adjust intensity of RGB components by SCALE."
- (let* ((rgb (color-values color))
- (scaled-rgb (mapcar (lambda (n)
- (format "%04x" (round (+ n (* scale 65535)))))
- rgb)))
- (apply #'concat "#" scaled-rgb)))
-
(defun cider-scale-background-color ()
"Scale the current background color to get a slighted muted version."
(let ((color (frame-parameter nil 'background-color))
- (dark (eq (frame-parameter nil 'background-mode) 'dark)))
- (cider-scale-color color (if dark 0.05 -0.05))))
+ (darkp (eq (frame-parameter nil 'background-mode) 'dark)))
+ (unless (equal "unspecified-bg" color)
+ (color-lighten-name color (if darkp 5 -5)))))
(autoload 'pkg-info-version-info "pkg-info.el")
@@ -611,6 +608,7 @@ through a stack of help buffers. Variables `help-back-label' and
"Don't wish it were easier. Wish you were better. -Jim Rohn"
"One chord is fine. Two chords is pushing it. Three chords and you're into jazz. -Lou Reed"
"We are all apprentices in a craft where no one ever becomes a master. -Ernest Hemingway"
+ "A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away. -Antoine de Saint-Exupery"
"Clojure isn't a language, it's a building material."
"Think big!"
"Think bold!"
@@ -645,6 +643,10 @@ through a stack of help buffers. Variables `help-back-label' and
"Oh, what a day... what a lovely day!"
"What a day! What cannot be accomplished on such a splendid day!"
"Home is where your REPL is."
+ "The worst day programming is better than the best day working."
+ "The only thing worse than a rebel without a cause is a REPL without a clause."
+ "In the absence of parentheses, chaos prevails."
+ "One REPL to rule them all, One REPL to find them, One REPL to bring them all, and in parentheses bind them!"
,(format "%s, I've a feeling we're not in Kansas anymore."
(cider-user-first-name))
,(format "%s, this could be the start of a beautiful program."
@@ -742,6 +744,34 @@ KIND can be the symbols `ns', `var', `emph', `fn', or a face name."
(t x)))
menu-list))
+(defcustom cider-jdk-src-paths '("/usr/lib/jvm/openjdk-8/src.zip")
+ "Used by `cider-stacktrace-navigate'.
+Zip/jar files work, but it's better to extract them and put the directory
+paths here. Clojure sources here:
+https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0/."
+ :group 'cider
+ :package-version '(cider . "0.17.0")
+ :type '(list string))
+
+(defun cider-resolve-java-class (class)
+ "Return a path to a Java source file that corresponds to CLASS.
+
+This will be a zip/jar path for archived sources and a normal
+file path otherwise."
+ (when class
+ (let ((file-name (concat (replace-regexp-in-string "\\." "/" class) ".java")))
+ (cl-find-if
+ 'file-exists-p
+ (mapcar
+ (lambda (d)
+ (cond ((file-directory-p d)
+ (expand-file-name file-name d))
+ ((and (file-exists-p d)
+ (member (file-name-extension d) '("jar" "zip")))
+ (format "zip:file:%s!/%s" d file-name))
+ (t (error "Unexpected archive: %s" d))))
+ cider-jdk-src-paths)))))
+
(provide 'cider-util)
;;; cider-util.el ends here
diff --git a/cider.el b/cider.el
index 87cdbb95..226058ca 100644
--- a/cider.el
+++ b/cider.el
@@ -1,7 +1,7 @@
;;; cider.el --- Clojure Interactive Development Environment that Rocks -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
@@ -11,7 +11,7 @@
;; Steve Purcell <steve@sanityinc.com>
;; Maintainer: Bozhidar Batsov <bozhidar@batsov.com>
;; URL: http://www.github.com/clojure-emacs/cider
-;; Version: 0.16.0
+;; Version: 0.17.0
;; Package-Requires: ((emacs "24.4") (clojure-mode "5.6.0") (pkg-info "0.4") (queue "0.1.1") (spinner "1.7") (seq "2.16"))
;; Keywords: languages, clojure, cider
@@ -60,7 +60,7 @@
:prefix "cider-"
:group 'applications
:link '(url-link :tag "GitHub" "https://github.com/clojure-emacs/cider")
- :link '(url-link :tag "Online Manual" "https://cider.readthedocs.org")
+ :link '(url-link :tag "Online Manual" "https://cider.readthedocs.io")
:link '(emacs-commentary-link :tag "Commentary" "cider"))
(defcustom cider-prompt-for-project-on-connect 'when-needed
@@ -90,12 +90,12 @@ project inference will take place."
(require 'seq)
-(defconst cider-version "0.16.0"
+(defconst cider-version "0.17.0"
"Fallback version used when it cannot be extracted automatically.
Normally it won't be used, unless `pkg-info' fails to extract the
version from the CIDER package or library.")
-(defconst cider-codename "Riga"
+(defconst cider-codename "Andalucía"
"Codename used to denote stable releases.")
(defcustom cider-lein-command
@@ -141,6 +141,56 @@ version from the CIDER package or library.")
:safe #'stringp
:package-version '(cider . "0.9.0"))
+(defcustom cider-clojure-cli-command
+ "clojure"
+ "The command used to execute clojure with tools.deps (requires Clojure 1.9+)."
+ :type 'string
+ :group 'cider
+ :package-version '(cider . "0.17.0"))
+
+(defcustom cider-clojure-cli-global-options
+ nil
+ "Command line options used to execute clojure with tools.deps."
+ :type 'string
+ :group 'cider
+ :safe #'stringp
+ :package-version '(cider . "0.17.0"))
+
+(defcustom cider-clojure-cli-parameters
+ "-e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init %s)'"
+ "Params passed to clojure to start an nREPL server via `cider-jack-in'.
+This is evaluated using `format', with the first argument being the Clojure
+vector of middleware variables as a string."
+ :type 'string
+ :group 'cider
+ :safe #'stringp
+ :package-version '(cider . "0.17.0"))
+
+(defcustom cider-shadow-cljs-command
+ "npx shadow-cljs"
+ "The command used to execute shadow-cljs.
+
+By default we favor the project-specific shadow-cljs over the system-wide."
+ :type 'string
+ :group 'cider
+ :package-version '(cider . "0.17.0"))
+
+(defcustom cider-shadow-cljs-global-options
+ ""
+ "Command line options used to execute shadow-cljs (e.g.: -v for verbose mode)."
+ :type 'string
+ :group 'cider
+ :safe #'stringp
+ :package-version '(cider . "0.17.0"))
+
+(defcustom cider-shadow-cljs-parameters
+ "server"
+ "Params passed to shadow-cljs to start an nREPL server via `cider-jack-in'."
+ :type 'string
+ :group 'cider
+ :safe #'stringp
+ :package-version '(cider . "0.17.0"))
+
(defcustom cider-gradle-command
"gradle"
"The command used to execute Gradle."
@@ -164,11 +214,12 @@ version from the CIDER package or library.")
:safe #'stringp
:package-version '(cider . "0.10.0"))
-(defcustom cider-default-repl-command
- "lein"
+(defcustom cider-default-repl-command "clojure-cli"
"The default command and parameters to use when connecting to nREPL.
This value will only be consulted when no identifying file types, i.e.
-project.clj for leiningen or build.boot for boot, could be found."
+project.clj for leiningen or build.boot for boot, could be found.
+
+As tools.deps is bundled with Clojure itself, it's the default REPL command."
:type 'string
:group 'cider
:safe #'stringp
@@ -185,6 +236,8 @@ cannot decide which of many build systems to use and will never override a
command when there is no ambiguity."
:type '(choice (const "lein")
(const "boot")
+ (const "clojure-cli")
+ (const "shadow-cljs")
(const "gradle")
(const :tag "Always ask" nil))
:group 'cider
@@ -226,14 +279,14 @@ This variable is used by `cider-connect'."
:package-version '(cider . "0.9.0"))
(defcustom cider-auto-mode t
- "When non-nil, automatically enable `cider-mode' for all Clojure buffers."
+ "When non-nil, automatically enable cider mode for all Clojure buffers."
:type 'boolean
:package-version '(cider . "0.9.0"))
(defcustom cider-inject-dependencies-at-jack-in nil
"When nil, do not inject repl dependencies (most likely nREPL middlewares) at `cider-jack-in' time."
:type 'boolean
- :safe #'stringp
+ :safe #'booleanp
:version '(cider . "0.11.0"))
(defcustom cider-offer-to-open-cljs-app-in-browser t
@@ -265,6 +318,8 @@ Sub-match 1 must be the project path.")
(pcase project-type
("lein" cider-lein-command)
("boot" cider-boot-command)
+ ("clojure-cli" cider-clojure-cli-command)
+ ("shadow-cljs" cider-shadow-cljs-command)
("gradle" cider-gradle-command)
(_ (user-error "Unsupported project type `%s'" project-type))))
@@ -273,9 +328,13 @@ Sub-match 1 must be the project path.")
Throws an error if PROJECT-TYPE is unknown. Known types are
\"lein\", \"boot\", and \"gradle\"."
(pcase project-type
- ("lein" (cider--lein-resolve-command))
- ("boot" (cider--boot-resolve-command))
- ("gradle" (cider--gradle-resolve-command))
+ ("lein" (cider--resolve-command cider-lein-command))
+ ("boot" (cider--resolve-command cider-boot-command))
+ ("clojure-cli" (cider--resolve-command cider-clojure-cli-command))
+ ;; here we have to account for the possibility that the command is either
+ ;; "npx shadow-cljs" or just "shadow-cljs"
+ ("shadow-cljs" (cider--resolve-command (car (split-string cider-shadow-cljs-command))))
+ ("gradle" (cider--resolve-command cider-gradle-command))
(_ (user-error "Unsupported project type `%s'" project-type))))
(defun cider-jack-in-global-options (project-type)
@@ -283,6 +342,8 @@ Throws an error if PROJECT-TYPE is unknown. Known types are
(pcase project-type
("lein" cider-lein-global-options)
("boot" cider-boot-global-options)
+ ("clojure-cli" cider-clojure-cli-global-options)
+ ("shadow-cljs" cider-shadow-cljs-global-options)
("gradle" cider-gradle-global-options)
(_ (user-error "Unsupported project type `%s'" project-type))))
@@ -291,6 +352,15 @@ Throws an error if PROJECT-TYPE is unknown. Known types are
(pcase project-type
("lein" cider-lein-parameters)
("boot" cider-boot-parameters)
+ ("clojure-cli" (format cider-clojure-cli-parameters
+ (concat
+ "["
+ (mapconcat
+ (apply-partially #'format "\"%s\"")
+ (cider-jack-in-normalized-nrepl-middlewares)
+ ", ")
+ "]")))
+ ("shadow-cljs" cider-shadow-cljs-parameters)
("gradle" cider-gradle-parameters)
(_ (user-error "Unsupported project type `%s'" project-type))))
@@ -328,17 +398,60 @@ specifying the artifact ID, and the second element the version number."
(string :tag "Version"))))
(defvar cider-jack-in-lein-plugins nil
- "List of Leiningen plugins where elements are lists of artifact name and version.")
+ "List of Leiningen plugins to be injected at jack-in.
+Each element is a list of artifact name and version, followed optionally by
+keyword arguments. The only keyword argument currently accepted is
+`:predicate', which should be given a function that takes the list (name,
+version, and keyword arguments) and returns non-nil to indicate that the
+plugin should actually be injected. (This is useful primarily for packages
+that extend CIDER, not for users. For example, a refactoring package might
+want to inject some middleware only when within a project context.)")
(put 'cider-jack-in-lein-plugins 'risky-local-variable t)
(cider-add-to-alist 'cider-jack-in-lein-plugins
"cider/cider-nrepl" (upcase cider-version))
+(defun cider-jack-in-normalized-lein-plugins ()
+ "Return a normalized list of Leiningen plugins to be injected.
+See `cider-jack-in-lein-plugins' for the format, except that the list
+returned by this function does not include keyword arguments."
+ (thread-last cider-jack-in-lein-plugins
+ (seq-filter
+ (lambda (spec)
+ (if-let* ((pred (plist-get (seq-drop spec 2) :predicate)))
+ (funcall pred spec)
+ t)))
+ (mapcar
+ (lambda (spec)
+ (seq-take spec 2)))))
+
(defvar cider-jack-in-nrepl-middlewares nil
"List of Clojure variable names.
-Each of these Clojure variables should hold a vector of nREPL middlewares.")
+Each of these Clojure variables should hold a vector of nREPL middlewares.
+Instead of a string, an element can be a list containing a string followed
+by optional keyword arguments. The only keyword argument currently
+accepted is `:predicate', which should be given a function that takes the
+list (string and keyword arguments) and returns non-nil to indicate that
+the middlewares should actually be injected.")
(put 'cider-jack-in-nrepl-middlewares 'risky-local-variable t)
(add-to-list 'cider-jack-in-nrepl-middlewares "cider.nrepl/cider-middleware")
+(defun cider-jack-in-normalized-nrepl-middlewares ()
+ "Return a normalized list of middleware variable names.
+See `cider-jack-in-nrepl-middlewares' for the format, except that the list
+returned by this function only contains strings."
+ (thread-last cider-jack-in-nrepl-middlewares
+ (seq-filter
+ (lambda (spec)
+ (or (not (listp spec))
+ (if-let* ((pred (plist-get (cdr spec) :predicate)))
+ (funcall pred spec)
+ t))))
+ (mapcar
+ (lambda (spec)
+ (if (listp spec)
+ (car spec)
+ spec)))))
+
(defun cider--list-as-boot-artifact (list)
"Return a boot artifact string described by the elements of LIST.
LIST should have the form (ARTIFACT-NAME ARTIFACT-VERSION). The returned
@@ -367,7 +480,7 @@ PLUGINS and MIDDLEWARES. PARAMS and MIDDLEWARES are passed on to
are passed on to `cider-boot-dependencies`."
(concat global-opts
(unless (seq-empty-p global-opts) " ")
- "-i \"(require 'cider.tasks)\" " ;; Note the white space at the end here
+ "-i \"(require 'cider.tasks)\" " ;; Note the space at the end here
(cider-boot-dependencies (append dependencies plugins))
(cider-boot-middleware-task params middlewares)))
@@ -385,7 +498,7 @@ string is quoted for passing as argument to an inferior shell."
(shell-quote-argument (format "[%s %S%s]" (car list) (cadr list) (cider--lein-artifact-exclusions exclusions))))
(defun cider-lein-jack-in-dependencies (global-opts params dependencies dependencies-exclusions lein-plugins)
- "Create lein jack-in dependencies.
+ "Create lein jack-in dependencies.
Does so by concatenating GLOBAL-OPTS, DEPENDENCIES, with DEPENDENCIES-EXCLUSIONS
removed, LEIN-PLUGINS, and finally PARAMS."
(concat
@@ -405,6 +518,33 @@ removed, LEIN-PLUGINS, and finally PARAMS."
" -- "
params))
+(defun cider-clojure-cli-jack-in-dependencies (global-opts params dependencies)
+ "Create Clojure tools.deps jack-in dependencies.
+Does so by concatenating GLOBAL-OPTS, DEPENDENCIES finally PARAMS."
+ (let ((dependencies (append dependencies cider-jack-in-lein-plugins)))
+ (concat
+ global-opts
+ (unless (seq-empty-p global-opts) " ")
+ "-Sdeps '{:deps {"
+ (mapconcat #'identity
+ (seq-map (lambda (dep) (format "%s {:mvn/version \"%s\"}" (car dep) (cadr dep))) dependencies)
+ " ")
+ "}}' "
+ params)))
+
+(defun cider-shadow-cljs-jack-in-dependencies (global-opts params dependencies)
+ "Create shadow-cljs jack-in deps.
+Does so by concatenating GLOBAL-OPTS, DEPENDENCIES finally PARAMS."
+ (let ((dependencies (append dependencies cider-jack-in-lein-plugins)))
+ (concat
+ global-opts
+ (unless (seq-empty-p global-opts) " ")
+ (mapconcat #'identity
+ (seq-map (lambda (dep) (format "-d %s:%s" (car dep) (cadr dep))) dependencies)
+ " ")
+ " "
+ params)))
+
(defun cider-add-clojure-dependencies-maybe (dependencies)
"Return DEPENDENCIES with an added Clojure dependency if requested.
@@ -437,14 +577,24 @@ dependencies."
(cider-add-clojure-dependencies-maybe
cider-jack-in-dependencies)
cider-jack-in-dependencies-exclusions
- cider-jack-in-lein-plugins))
+ (cider-jack-in-normalized-lein-plugins)))
("boot" (cider-boot-jack-in-dependencies
global-opts
params
(cider-add-clojure-dependencies-maybe
cider-jack-in-dependencies)
- cider-jack-in-lein-plugins
- cider-jack-in-nrepl-middlewares))
+ (cider-jack-in-normalized-lein-plugins)
+ (cider-jack-in-normalized-nrepl-middlewares)))
+ ("clojure-cli" (cider-clojure-cli-jack-in-dependencies
+ global-opts
+ params
+ (cider-add-clojure-dependencies-maybe
+ cider-jack-in-dependencies)))
+ ("shadow-cljs" (cider-shadow-cljs-jack-in-dependencies
+ global-opts
+ params
+ (cider-add-clojure-dependencies-maybe
+ cider-jack-in-dependencies)))
("gradle" (concat
global-opts
(unless (seq-empty-p global-opts) " ")
@@ -453,58 +603,165 @@ dependencies."
;;; ClojureScript REPL creation
-(defconst cider--cljs-repl-types
- '(("(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env))"
- "Rhino" "")
- ("(do (require 'figwheel-sidecar.repl-api) (figwheel-sidecar.repl-api/start-figwheel!) (figwheel-sidecar.repl-api/cljs-repl))"
- "Figwheel-sidecar" " (add figwheel-sidecar to your plugins)")
- ("(do (require 'cljs.repl.node) (cemerick.piggieback/cljs-repl (cljs.repl.node/repl-env)))"
- "Node" " (requires NodeJS to be installed)")
- ("(do (require 'weasel.repl.websocket) (cemerick.piggieback/cljs-repl (weasel.repl.websocket/repl-env :ip \"127.0.0.1\" :port 9001)))"
- "Weasel" " (see http://cider.readthedocs.io/en/latest/up_and_running/#browser-connected-clojurescript-repl)")
- ("(do (require 'adzerk.boot-cljs-repl) (adzerk.boot-cljs-repl/start-repl))"
- "Boot-cljs-repl" " (see https://github.com/adzerk-oss/boot-cljs-repl/blob/master/README.md")))
-
-(defcustom cider-cljs-lein-repl "(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env))"
- "Clojure form that returns a ClojureScript REPL environment.
-This is only used in lein projects. It is evaluated in a Clojure REPL and
-it should start a ClojureScript REPL."
- :type `(choice ,@(seq-map (lambda (x) `(const :tag ,(apply #'concat (cdr x)) ,(car x)))
- cider--cljs-repl-types)
- (string :tag "Custom"))
- :safe (lambda (x) (assoc x cider--cljs-repl-types))
- :package-version '(cider . "0.11.0")
- :group 'cider)
-
-(defcustom cider-cljs-boot-repl "(do (require 'adzerk.boot-cljs-repl) (adzerk.boot-cljs-repl/start-repl))"
- "Clojure form that returns a ClojureScript REPL environment.
-This is only used in boot projects. It is evaluated in a Clojure REPL and
-it should start a ClojureScript REPL."
- :type `(choice ,@(seq-map (lambda (x) `(const :tag ,(apply #'concat (cdr x)) ,(car x)))
- cider--cljs-repl-types)
- (string :tag "Custom"))
- :safe (lambda (x) (assoc x cider--cljs-repl-types))
- :package-version '(cider . "0.15.0")
- :group 'cider)
-(defcustom cider-cljs-gradle-repl "(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env))"
- "Clojure form that returns a ClojureScript REPL environment.
-This is only used in gradle projects. It is evaluated in a Clojure REPL and
-it should start a ClojureScript REPL."
- :type `(choice ,@(seq-map (lambda (x) `(const :tag ,(apply #'concat (cdr x)) ,(car x)))
- cider--cljs-repl-types)
- (string :tag "Custom"))
- :safe (lambda (x) (assoc x cider--cljs-repl-types))
- :package-version '(cider . "0.15.0")
- :group 'cider)
+(defcustom cider-check-cljs-repl-requirements t
+ "When non-nil will run the requirement checks for the different cljs repls.
-(defun cider-cljs-repl-form (project-type)
- "Return a Clojure form returning a ClojureScript REPL environment based on PROJECT-TYPE."
- (pcase project-type
- ("lein" cider-cljs-lein-repl)
- ("boot" cider-cljs-boot-repl)
- ("gradle" cider-cljs-gradle-repl)
- (_ (error "Unsupported project type `%s'" project-type))))
+Generally you should not disable this unless you run into some faulty check."
+ :type 'boolean
+ :safe #'booleanp
+ :version '(cider . "0.17.0"))
+
+(defun cider-verify-clojurescript-is-present ()
+ "Check whether ClojureScript is present."
+ (unless (cider-library-present-p "clojurescript")
+ (user-error "ClojureScript is not available. See http://cider.readthedocs.io/en/latest/clojurescript for details")))
+
+(defun cider-verify-piggieback-is-present ()
+ "Check whether the piggieback middleware is present."
+ (unless (cider-library-present-p "piggieback")
+ (user-error "Piggieback is not available. See http://cider.readthedocs.io/en/latest/clojurescript for details")))
+
+(defun cider-check-nashorn-requirements ()
+ "Check whether we can start a Nashorn ClojureScript REPL."
+ (cider-verify-piggieback-is-present)
+ (when (string-prefix-p "1.7" (cider--java-version))
+ (user-error "Nashorn is supported only on Java 8 or newer")))
+
+(defun cider-check-node-requirements ()
+ "Check whether we can start a Node ClojureScript REPL."
+ (cider-verify-piggieback-is-present)
+ (unless (executable-find "node")
+ (user-error "Node.js is not present on the exec-path. Make sure you've installed it and your exec-path is properly set")))
+
+(defun cider-check-figwheel-requirements ()
+ "Check whether we can start a Figwheel ClojureScript REPL."
+ (cider-verify-piggieback-is-present)
+ (unless (cider-library-present-p "figwheel-sidecar")
+ (user-error "Figwheel-sidecar is not available. Please check http://cider.readthedocs.io/en/latest/clojurescript")))
+
+(defun cider-check-weasel-requirements ()
+ "Check whether we can start a Weasel ClojureScript REPL."
+ (cider-verify-piggieback-is-present)
+ (unless (cider-library-present-p "weasel")
+ (user-error "Weasel in not available. Please check http://cider.readthedocs.io/en/latest/clojurescript/#browser-connected-clojurescript-repl")))
+
+(defun cider-check-boot-requirements ()
+ "Check whether we can start a Boot ClojureScript REPL."
+ (cider-verify-piggieback-is-present)
+ (unless (cider-library-present-p "boot-cljs-repl")
+ (user-error "The Boot ClojureScript REPL is not available. Please check https://github.com/adzerk-oss/boot-cljs-repl/blob/master/README.md")))
+
+(defun cider-check-shadow-cljs-requirements ()
+ "Check whether we can start a shadow-cljs REPL."
+ (unless (cider-library-present-p "shadow-cljs")
+ (user-error "The shadow-cljs ClojureScript REPL is not available")))
+
+(defun cider-shadow-cljs-init-form ()
+ "Generate the init form for a shadow-cljs REPL.
+
+We have to prompt the user to select a build, that's why
+this is a command, not just a string."
+ (let ((form "(do (require '[shadow.cljs.devtools.api :as shadow]) (shadow/watch :%s) (shadow/nrepl-select :%s))")
+ (build (string-remove-prefix ":" (read-from-minibuffer "Select shadow-cljs build: "))))
+ (format form build build)))
+
+(defun cider-custom-cljs-repl-init-form ()
+ "Prompt for a form that would start a ClojureScript REPL.
+
+The supplied string will be wrapped in a do form if needed."
+ (let ((form (read-from-minibuffer "Please, provide a form to start a ClojureScript REPL: ")))
+ ;; TODO: We should probably make this more robust (e.g. by using a regexp or
+ ;; parsing the form).
+ (if (string-prefix-p "(do" form)
+ form
+ (format "(do %s)" form))))
+
+(defvar cider-cljs-repl-types
+ '((nashorn "(cider.piggieback/cljs-repl (cljs.repl.nashorn/repl-env))"
+ cider-check-nashorn-requirements)
+ (figwheel "(do (require 'figwheel-sidecar.repl-api) (figwheel-sidecar.repl-api/start-figwheel!) (figwheel-sidecar.repl-api/cljs-repl))"
+ cider-check-figwheel-requirements)
+ (node "(do (require 'cljs.repl.node) (cider.piggieback/cljs-repl (cljs.repl.node/repl-env)))"
+ cider-check-node-requirements)
+ (weasel "(do (require 'weasel.repl.websocket) (cider.piggieback/cljs-repl (weasel.repl.websocket/repl-env :ip \"127.0.0.1\" :port 9001)))"
+ cider-check-weasel-requirements)
+ (boot "(do (require 'adzerk.boot-cljs-repl) (adzerk.boot-cljs-repl/start-repl))"
+ cider-check-boot-requirements)
+ (shadow cider-shadow-cljs-init-form cider-check-shadow-cljs-requirements)
+ (custom cider-custom-cljs-repl-init-form nil))
+ "A list of supported ClojureScript REPLs.
+
+For each one we have its name, the form we need to evaluate in a Clojure
+REPL to start the ClojureScript REPL and functions to very their requirements.
+
+The form should be either a string or a function producing a string.")
+
+(defun cider-register-cljs-repl-type (type init-form &optional requirements-fn)
+ "Register a new ClojureScript REPL type.
+
+Types are defined by the following:
+
+- TYPE - symbol identifier that will be used to refer to the REPL type
+- INIT-FORM - string or function (symbol) producing string
+- REQUIREMENTS-FN - function to check whether the REPL can be started.
+This param is optional.
+
+All this function does is modifying `cider-cljs-repl-types'.
+It's intended to be used in your Emacs config."
+ (unless (symbolp type)
+ (user-error "The REPL type must be a symbol"))
+ (unless (or (stringp init-form) (symbolp init-form))
+ (user-error "The init form must be a string or a symbol referring to a function"))
+ (unless (or (null requirements-fn) (symbolp requirements-fn))
+ (user-error "The requirements-fn must be a symbol referring to a function"))
+ (add-to-list 'cider-cljs-repl-types (list type init-form requirements-fn)))
+
+(defcustom cider-default-cljs-repl nil
+ "The default ClojureScript REPL to start.
+
+This affects commands like `cider-jack-in-clojurescript'. Generally it's
+intended to be set via .dir-locals.el for individual projects, as its
+relatively unlikely you'd like to use the same type of REPL in each project
+you're working on."
+ :type '(choice (const :tag "Nashorn" nashorn)
+ (const :tag "Figwheel" figwheel)
+ (const :tag "Node" node)
+ (const :tag "Weasel" weasel)
+ (const :tag "Boot" boot)
+ (const :tag "Shadow" shadow)
+ (const :tag "Custom" custom))
+ :group 'cider
+ :safe #'symbolp
+ :package-version '(cider . "0.17.0"))
+
+(make-obsolete-variable 'cider-cljs-lein-repl 'cider-default-cljs-repl "0.17")
+(make-obsolete-variable 'cider-cljs-boot-repl 'cider-default-cljs-repl "0.17")
+(make-obsolete-variable 'cider-cljs-gradle-repl 'cider-default-cljs-repl "0.17")
+
+(defun cider-select-cljs-repl ()
+ "Select the ClojureScript REPL to use with `cider-jack-in-clojurescript'."
+ (let ((repl-types (mapcar #'car cider-cljs-repl-types)))
+ (intern (completing-read "Select ClojureScript REPL type: " repl-types))))
+
+(defun cider-cljs-repl-form (repl-type)
+ "Get the cljs REPL form for REPL-TYPE."
+ (let ((repl-form (cadr (seq-find
+ (lambda (entry)
+ (eq (car entry) repl-type))
+ cider-cljs-repl-types))))
+ ;; repl-form can be either a string or a function producing a string
+ (if (symbolp repl-form)
+ (funcall repl-form)
+ repl-form)))
+
+(defun cider-verify-cljs-repl-requirements (repl-type)
+ "Verify that the requirements for REPL-TYPE are met."
+ (when-let* ((fun (nth 2 (seq-find
+ (lambda (entry)
+ (eq (car entry) repl-type))
+ cider-cljs-repl-types))))
+ (funcall fun)))
(defun cider--offer-to-open-app-in-browser (server-buffer)
"Look for a server address in SERVER-BUFFER and offer to open it."
@@ -513,51 +770,64 @@ it should start a ClojureScript REPL."
(save-excursion
(goto-char (point-min))
(when-let* ((url (and (search-forward-regexp "http://localhost:[0-9]+" nil 'noerror)
- (match-string 0))))
+ (match-string 0))))
(when (y-or-n-p (format "Visit ‘%s’ in a browser? " url))
(browse-url url)))))))
(defun cider-create-sibling-cljs-repl (client-buffer)
"Create a ClojureScript REPL with the same server as CLIENT-BUFFER.
The new buffer will correspond to the same project as CLIENT-BUFFER, which
-should be the regular Clojure REPL started by the server process filter."
+should be the regular Clojure REPL started by the server process filter.
+
+Normally this would prompt for the ClojureScript REPL to start (e.g. Node,
+Figwheel, etc), unless you've set `cider-default-cljs-repl'."
(interactive (list (cider-current-connection)))
+ ;; We can't start a ClojureScript REPL without ClojureScript
+ (when cider-check-cljs-repl-requirements
+ (cider-verify-clojurescript-is-present))
;; Load variables in .dir-locals.el into the server process buffer, so
- ;; cider-cljs-*-repl can be set for each project individually.
+ ;; cider-default-cljs-repl can be set for each project individually.
(hack-local-variables)
- (let* ((nrepl-repl-buffer-name-template "*cider-repl CLJS%s*")
- (nrepl-create-client-buffer-function #'cider-repl-create)
- (nrepl-use-this-as-repl-buffer 'new)
- (client-process-args (with-current-buffer client-buffer
- (unless (or nrepl-server-buffer nrepl-endpoint)
- (error "This is not a REPL buffer, is there a REPL active?"))
- (list (car nrepl-endpoint)
- (elt nrepl-endpoint 1)
- (when (buffer-live-p nrepl-server-buffer)
- (get-buffer-process nrepl-server-buffer)))))
- (cljs-proc (apply #'nrepl-start-client-process client-process-args))
- (cljs-buffer (process-buffer cljs-proc))
- (cljs-repl-form (cider-cljs-repl-form (cider-project-type))))
- (with-current-buffer cljs-buffer
- ;; The new connection has now been bumped to the top, but it's still a
- ;; Clojure REPL! Additionally, some ClojureScript REPLs can actually take
- ;; a while to start (some even depend on the user opening a browser).
- ;; Meanwhile, this REPL will gladly receive requests in place of the
- ;; original Clojure REPL. Our solution is to bump the original REPL back
- ;; up the list, so it takes priority on Clojure requests.
- (cider-make-connection-default client-buffer)
- (setq cider-repl-type "cljs")
- (pcase (assoc cljs-repl-form cider--cljs-repl-types)
- (`(,_ ,name ,info)
- (message "Starting a %s REPL%s" name (or info "")))
- (_ (message "Starting a custom ClojureScript REPL")))
- (cider-nrepl-send-request
- `("op" "eval"
- "ns" ,(cider-current-ns)
- "code" ,cljs-repl-form)
- (cider-repl-handler (current-buffer)))
- (when cider-offer-to-open-cljs-app-in-browser
- (cider--offer-to-open-app-in-browser nrepl-server-buffer)))))
+ (let* ((cljs-repl-type (or cider-default-cljs-repl
+ (cider-select-cljs-repl)))
+ (cljs-repl-form (cider-cljs-repl-form cljs-repl-type)))
+ (when cider-check-cljs-repl-requirements
+ (cider-verify-cljs-repl-requirements cljs-repl-type))
+ ;; if all the requirements are met we can finally proceed with starting
+ ;; the ClojureScript REPL for `cljs-repl-type'
+ (let* ((nrepl-repl-buffer-name-template "*cider-repl%s(cljs)*")
+ (nrepl-create-client-buffer-function #'cider-repl-create)
+ (nrepl-use-this-as-repl-buffer 'new)
+ (client-process-args (with-current-buffer client-buffer
+ (unless (or nrepl-server-buffer nrepl-endpoint)
+ (error "This is not a REPL buffer, is there a REPL active?"))
+ (list (car nrepl-endpoint)
+ (elt nrepl-endpoint 1)
+ (when (buffer-live-p nrepl-server-buffer)
+ (get-buffer-process nrepl-server-buffer)))))
+ (cljs-proc (apply #'nrepl-start-client-process client-process-args))
+ (cljs-buffer (process-buffer cljs-proc)))
+ (with-current-buffer cljs-buffer
+ ;; The new connection has now been bumped to the top, but it's still a
+ ;; Clojure REPL! Additionally, some ClojureScript REPLs can actually take
+ ;; a while to start (some even depend on the user opening a browser).
+ ;; Meanwhile, this REPL will gladly receive requests in place of the
+ ;; original Clojure REPL. Our solution is to bump the original REPL back
+ ;; up the list, so it takes priority on Clojure requests.
+ (cider-make-connection-default client-buffer)
+ (cider-repl-set-type "cljs")
+ (pcase cider-cljs-repl-types
+ (`(,name ,_ ,info)
+ (message "Starting a %s REPL%s" name (or info ""))))
+ ;; So far we have just another Clojure REPL. It's time to convert it
+ ;; to a ClojureScript REPL with a magic incantation.
+ (cider-nrepl-send-request
+ `("op" "eval"
+ "ns" ,(cider-current-ns)
+ "code" ,cljs-repl-form)
+ (cider-repl-handler (current-buffer)))
+ (when cider-offer-to-open-cljs-app-in-browser
+ (cider--offer-to-open-app-in-browser nrepl-server-buffer))))))
(defun cider--select-zombie-buffer (repl-buffers)
"Return a zombie buffer from REPL-BUFFERS, or nil if none exists."
@@ -623,7 +893,7 @@ own buffer."
(cider-inject-jack-in-dependencies command-global-opts params project-type)
params))
- (cmd (format "%s %s" command-resolved params)))
+ (cmd (format "%s %s" command params)))
(if (or project-dir cider-allow-jack-in-without-project)
(progn
(when (or project-dir
@@ -649,6 +919,9 @@ start the server."
(cider-jack-in prompt-project 'cljs-too))
;;;###autoload
+(defalias 'cider-jack-in-cljs #'cider-jack-in-clojurescript)
+
+;;;###autoload
(defun cider-connect (host port &optional project-dir)
"Connect to an nREPL server identified by HOST and PORT.
Create REPL buffer and start an nREPL client connection.
@@ -671,12 +944,28 @@ gets associated with it."
;; associate if we're in a project, prompt otherwise
((eq cider-prompt-for-project-on-connect 'when-needed) (cider-assoc-project-with-connection project-dir conn))
;; always prompt
- (t (cider-assoc-project-with-connection nil conn))))))))
+ (t (cider-assoc-project-with-connection nil conn)))))
+ conn)))
+
+;;;###autoload
+(defun cider-connect-clojurescript ()
+ "Connect to a ClojureScript REPL.
+
+It just delegates pretty much everything to `cider-connect' and just sets
+the appropriate REPL type in the end."
+ (interactive)
+ (when-let* ((conn (call-interactively #'cider-connect)))
+ (with-current-buffer conn
+ (cider-repl-set-type "cljs"))))
+
+;;;###autoload
+(defalias 'cider-connect-cljs #'cider-connect-clojurescript)
(defun cider-current-host ()
"Retrieve the current host."
(if (and (stringp buffer-file-name)
- (file-remote-p buffer-file-name))
+ (file-remote-p buffer-file-name)
+ (boundp 'tramp-current-host))
tramp-current-host
"localhost"))
@@ -780,6 +1069,8 @@ Use `cider-ps-running-nrepls-command' and `cider-ps-running-nrepl-path-regexp-li
(let* ((default-directory (clojure-project-dir (cider-current-dir)))
(build-files '(("lein" . "project.clj")
("boot" . "build.boot")
+ ("clojure-cli" . "deps.edn")
+ ("shadow-cljs" . "shadow-cljs.edn")
("gradle" . "build.gradle"))))
(delq nil
(mapcar (lambda (candidate)
@@ -788,8 +1079,8 @@ Use `cider-ps-running-nrepls-command' and `cider-ps-running-nrepl-path-regexp-li
build-files))))
(defun cider-project-type ()
- "Determine the type, either leiningen, boot or gradle, of the current project.
-If more than one project file types are present, check for a preferred
+ "Determine the type of the current project.
+When multiple project file markers are present, check for a preferred
build tool in `cider-preferred-build-tool', otherwise prompt the user to
choose."
(let* ((choices (cider--identify-buildtools-present))
@@ -806,34 +1097,14 @@ choose."
(t cider-default-repl-command))))
-;; TODO: Implement a check for `cider-lein-command' over tramp
-(defun cider--lein-resolve-command ()
- "Find `cider-lein-command' on `exec-path' if possible, or return nil.
-
-In case `default-directory' is non-local we assume the command is available."
- (when-let* ((command (or (and (file-remote-p default-directory) cider-lein-command)
- (executable-find cider-lein-command)
- (executable-find (concat cider-lein-command ".bat")))))
- (shell-quote-argument command)))
-
-;; TODO: Implement a check for `cider-boot-command' over tramp
-(defun cider--boot-resolve-command ()
- "Find `cider-boot-command' on `exec-path' if possible, or return nil.
-
-In case `default-directory' is non-local we assume the command is available."
- (when-let* ((command (or (and (file-remote-p default-directory) cider-boot-command)
- (executable-find cider-boot-command)
- (executable-find (concat cider-boot-command ".exe")))))
- (shell-quote-argument command)))
-
-;; TODO: Implement a check for `cider-gradle-command' over tramp
-(defun cider--gradle-resolve-command ()
- "Find `cider-gradle-command' on `exec-path' if possible, or return nil.
+;; TODO: Implement a check for command presence over tramp
+(defun cider--resolve-command (command)
+ "Find COMMAND on `exec-path' if possible, or return nil.
In case `default-directory' is non-local we assume the command is available."
- (when-let* ((command (or (and (file-remote-p default-directory) cider-gradle-command)
- (executable-find cider-gradle-command)
- (executable-find (concat cider-gradle-command ".exe")))))
+ (when-let* ((command (or (and (file-remote-p default-directory) command)
+ (executable-find command)
+ (executable-find (concat command ".bat")))))
(shell-quote-argument command)))
@@ -874,6 +1145,15 @@ message in the REPL area."
"CIDER's version (%s) does not match cider-nrepl's version (%s). Things will break!"
cider-version middleware-version))))
+(defcustom cider-redirect-server-output-to-repl t
+ "Controls whether nREPL server output would be redirected to the REPL.
+When non-nil the output would end up in both the nrepl-server buffer (when
+available) and the matching REPL buffer."
+ :type 'boolean
+ :group 'cider
+ :safe #'booleanp
+ :package-version '(cider . "0.17.0"))
+
(defun cider--subscribe-repl-to-server-out ()
"Subscribe to the nREPL server's *out*."
(cider-nrepl-send-request '("op" "out-subscribe")
@@ -893,7 +1173,8 @@ buffer."
(cider--check-required-nrepl-version)
(cider--check-clojure-version-supported)
(cider--check-middleware-compatibility)
- (cider--subscribe-repl-to-server-out)
+ (when cider-redirect-server-output-to-repl
+ (cider--subscribe-repl-to-server-out))
(when cider-auto-mode
(cider-enable-on-existing-clojure-buffers))
;; Middleware on cider-nrepl's side is deferred until first usage, but
@@ -917,7 +1198,8 @@ process buffer."
'(progn
(define-key clojure-mode-map (kbd "C-c M-j") #'cider-jack-in)
(define-key clojure-mode-map (kbd "C-c M-J") #'cider-jack-in-clojurescript)
- (define-key clojure-mode-map (kbd "C-c M-c") #'cider-connect)))
+ (define-key clojure-mode-map (kbd "C-c M-c") #'cider-connect)
+ (define-key clojure-mode-map (kbd "C-c M-C") #'cider-connect-clojurescript)))
(provide 'cider)
diff --git a/doc/additional_packages.md b/doc/additional_packages.md
index 07d995c4..c4e2d8d8 100644
--- a/doc/additional_packages.md
+++ b/doc/additional_packages.md
@@ -18,13 +18,6 @@ down the road.
**Make sure that the version of `clj-refactor` you've installed is compatible with
your CIDER version.**
-## clojure-cheatsheet
-
-[clojure-cheatsheet](https://github.com/clojure-emacs/clojure-cheatsheet) in an
-Emacs rendition of the web-based
-[official Clojure Cheatsheet](http://clojure.org/api/cheatsheet), that's easily
-searchable via Helm.
-
## helm-cider
[helm-cider](https://github.com/clojure-emacs/helm-cider) provides Helm
@@ -45,7 +38,12 @@ Flycheck checker for Clojure, using tools like
[core.typed](http://typedclojure.org/) and
[kibit](https://github.com/jonase/kibit).
-## inf-clojure
+## sayid
+
+[sayid](http://bpiel.github.io/sayid/) is a powerful alternative of CIDER's
+built-in basic tracing functionality.
+
+## Inf-clojure
This package provides basic interaction with a Clojure subprocess (REPL). It's
based on ideas from the popular inferior-lisp package.
@@ -105,14 +103,6 @@ RainbowDelimiters you can enable it in the REPL like this:
(add-hook 'cider-repl-mode-hook #'rainbow-delimiters-mode)
```
-## auto-complete
-
-[auto-complete](http://cx4a.org/software/auto-complete/) is a popular Emacs
-interactive auto-completion
-framework. [ac-cider](https://github.com/clojure-emacs/ac-cider) provides a
-completion source for auto-complete-mode, including, where CIDER provides it,
-pop-up documentation for completed symbols.
-
## eval-sexp-fu
[eval-sexp-fu](https://github.com/hchbaw/eval-sexp-fu.el) provides some visual
diff --git a/doc/cider-refcard.tex b/doc/cider-refcard.tex
index 7f09e249..6d877bd5 100644
--- a/doc/cider-refcard.tex
+++ b/doc/cider-refcard.tex
@@ -80,7 +80,7 @@
\item[C-c C-k] cider-load-buffer
\item[C-c C-l] cider-load-file
\item[C-c C-M-l] cider-load-all-files
- \item[C-c C-r] cider-eval-region
+ \item[C-c C-v] cider-eval-commands-map
\item[C-c C-n] cider-eval-ns-form
\item[C-x C-e] \ns{cider-eval-last-sexp}
\item[C-c C-w] \ns -and-replace
diff --git a/doc/clojurescript.md b/doc/clojurescript.md
new file mode 100644
index 00000000..17393e09
--- /dev/null
+++ b/doc/clojurescript.md
@@ -0,0 +1,215 @@
+## ClojureScript
+
+CIDER works with ClojureScript, but you should keep in mind that not all
+the functionality available with Clojure exists for ClojureScript (at least
+not yet). To give you a concrete example - things like running tests and
+the debugger are currently Clojure-only features.
+
+ClojureScript support relies on the [piggieback][] nREPL middleware
+being present in your REPL session. There's one exception to this,
+though - [shadow-cljs][]. It has its own nREPL middleware and doesn't rely
+on piggieback at all.
+
+To setup piggieback add the following dependencies to your project
+(`project.clj` in Leiningen based project or `build.boot` in Boot
+project):
+
+```clojure
+;; use whatever are the most recent versions here
+[cider/piggieback "0.3.2"]
+[org.clojure/clojure "1.9.0"]
+```
+
+as well as `piggieback` nREPL middleware:
+
+in `project.clj`:
+
+```clojure
+:repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]}
+```
+
+or in `build.boot`:
+
+```clojure
+(task-options!
+ repl {:middleware '[cider.piggieback/wrap-cljs-repl]})
+```
+
+There are many ClojureScript REPLs out there and it's often hard to wrap your
+head around them and the differences between them. You'd do well to read [this
+awesome article](https://lambdaisland.com/guides/clojure-repls/clojurescript-repls)
+before proceeding with the rest of the instructions listed here.
+
+Open a file in your project and issue <kbd>M-x</kbd>
+`cider-jack-in-clojurescript` <kbd>RET</kbd>. This will start up the nREPL
+server, and then create two REPL buffers for you, one in Clojure and one in
+ClojureScript. All usual CIDER commands will be automatically directed to the
+appropriate REPL, depending on whether you're visiting a `.clj` or a `.cljs`
+file.
+
+`cider-jack-in-clojurescript` will prompt you about the type of
+ClojureScript to start. Keep in mind that some of the REPLs will
+require some additional setup, before you can make use of them (e.g. you'll
+need to have Node.js installed to be able to start a node REPL).
+
+You can suppress the prompt the REPL to use by setting `cider-default-cljs-repl`.
+Here's an example that will make Nashorn the default:
+
+```el
+(setq cider-default-cljs-repl 'nashorn)
+```
+
+All supported ClojureScript REPLs are stored in
+`cider-cljs-repl-types`. If you need to extend it, you should use
+`cider-register-cljs-repl-type` in your Emacs configuration.
+
+```el
+(cider-register-cljs-repl-type 'super-cljs "(do (...))" optional-requirements-function)
+```
+
+You can also create a ClojureScript REPL with the command
+`cider-create-sibling-cljs-repl` in cases where you already have a
+Clojure REPL running.
+
+Continue reading for the additional setup needed for the various ClojureScript
+REPLs out there.
+
+### Browser-connected ClojureScript REPL
+
+Using Weasel, you can also have a browser-connected REPL.
+
+1. Add `[weasel "0.7.0"]` to your project's `:dependencies`.
+
+2. Issue <kbd>M-x</kbd> `cider-jack-in-clojurescript` <kbd>RET</kbd> and choose
+ the `Weasel` option when prompted about the ClojureScript REPL type you want
+ to use.
+
+3. Add this to your ClojureScript code:
+
+```clojure
+(ns my.cljs.core
+ (:require [weasel.repl :as repl]))
+(repl/connect "ws://localhost:9001")
+```
+
+4. Open a file in your project and issue <kbd>M-x</kbd> `cider-jack-in-clojurescript`.
+
+Provided that a Piggieback-enabled ClojureScript environment is active in your
+REPL session, code loading and evaluation will work seamlessly regardless of the
+presence of the `cider-nrepl` middleware. If the middleware is present then most
+other features of CIDER will also be enabled (including code completion,
+documentation lookup, the namespace browser, and macroexpansion).
+
+### Browser-connected ClojureScript REPL in Boot project
+
+1. Add this to your dependencies in `build.boot`:
+
+```clojure
+[adzerk/boot-cljs "X.Y.Z" :scope "test"]
+[adzerk/boot-cljs-repl "X.Y.Z" :scope "test"]
+[pandeiro/boot-http "X.Y.Z" :scope "test"]
+[weasel "0.7.0" :scope "test"]
+[cider/piggieback "0.3.2" :scope "test"]
+```
+
+and this at the end of `build.boot`:
+
+```clojure
+(require
+ '[adzerk.boot-cljs :refer [cljs]]
+ '[adzerk.boot-cljs-repl :refer [cljs-repl]]
+ '[pandeiro.boot-http :refer [serve]])
+
+(deftask dev []
+ (comp (serve)
+ (watch)
+ (cljs-repl) ; order is important!!
+ (cljs)))
+```
+
+2. Issue <kbd>M-x</kbd> `customize-variable` <kbd>RET</kbd> `cider-boot-parameters`
+ and insert `dev`.
+
+3. Open a file in your project and issue <kbd>M-x</kbd> `cider-jack-in-clojurescript`.
+
+5. Connect to the running server with your browser. The address is printed on the terminal, but it's probably `http://localhost:3000`.
+
+For more information visit [boot-cljs-repl](https://github.com/adzerk-oss/boot-cljs-repl).
+
+### Using the Figwheel REPL (Leiningen-only)
+
+You can also use [Figwheel](https://github.com/bhauman/lein-figwheel) with CIDER.
+
+1. Set up Figwheel as normal, but make sure `:cljsbuild` and `:figwheel` settings are
+ in the root of your Leiningen project definition.
+
+2. Add these to your dev `:dependencies`:
+
+```clojure
+[cider/piggieback "0.3.2"]
+[figwheel-sidecar "0.5.16"] ; use here whatever the current version of figwheel is
+```
+
+Keep in mind that figwheel 0.5.16 is the first to support piggieback
+0.3. If you're using an older figwheel you should stick to piggieback
+0.2.2 (which uses the old `com.cemerick/piggieback` package coordinates).
+
+3. Add this to your dev `:repl-options`:
+
+```clojure
+:nrepl-middleware [cider.piggieback/wrap-cljs-repl]
+```
+
+4. Start the REPL with `cider-jack-in-clojurescript` (<kbd>C-c M-J</kbd>)
+
+5. Open a browser to the Figwheel URL so that it can connect to your application.
+
+You now have two nREPL connections, one for Clojure and one for ClojureScript.
+CIDER will determine which to use based on the type of file you're editing.
+
+You should also check out
+[Figwheel's wiki](https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl).
+
+### Using shadow-cljs
+
+Provided you've configured your project correctly you can simply use
+`cider-jack-in-clojurescript` to use `shadow-cljs`.
+
+This will automatically start the shadow-cljs server and connect to it. You'll also
+be prompted for the build to use.
+
+Alternatively you can start the server manually with something like:
+
+```
+npx shadow-cljs server
+```
+
+And connect to it with `cider-connect`.
+
+[leiningen]: http://leiningen.org/
+[boot]: http://boot-clj.com/
+[piggieback]: https://github.com/clojure-emacs/piggieback
+[shadow-cljs]: https://github.com/thheller/shadow-cljs
+
+## Working with `.cljc` files
+
+Ordinarily, CIDER dispatches code from `clj` files to Clojure REPLs and `cljs`
+files to ClojureScript REPLs. However, `cljc` files have two possible connection
+targets. By default, CIDER tries to evaluate `cljc` files in all matching
+connection buffers, both `clj` and `cljs` (if present).
+
+Simply put - if you're evaluating the code `(+ 2 2)` in a `cljc` file and you
+have an active Clojure and and active ClojureScript REPL, then the code is going
+to be evaluated 2 times - once for each of them. This behavior might be a bit
+confusing, but that's what we came up with, when ruminating what was the most
+logical thing to do out-of-the-box.
+
+This can be modified with <kbd>M-x</kbd> `cider-toggle-connection-buffer`
+<kbd>RET</kbd>. Toggling this once will choose one of the connections as the
+primary, and successive calls to <kbd>M-x</kbd> `cider-toggle-connection-buffer`
+<kbd>RET</kbd> will alternate which connection to use. To restore evaluation to
+both connections, invoke `cider-toggle-connection-buffer` with a prefix argument
+(<kbd>C-u M-x</kbd> `cider-toggle-connection-buffer` <kbd>RET</kbd>).
+
+If there is only a Clojure connection, no toggling will happen and a message
+will inform you that there are no other connections to switch to.
diff --git a/doc/code_completion.md b/doc/code_completion.md
index 5973ea32..a42c08ef 100644
--- a/doc/code_completion.md
+++ b/doc/code_completion.md
@@ -1,6 +1,11 @@
CIDER provides intelligent code completion for both source buffers (powered by
`cider-mode`) and REPL buffers.
+Internally CIDER leverages
+[compliment](https://github.com/alexander-yakushev/compliment) for Clojure and
+[cljs-tooling](https://github.com/clojure-emacs/cljs-tooling) for ClojureScript.
+Improvements to the two libraries automatically translate to improvements in CIDER.
+
## Standard completion
Out-of-the box CIDER uses the standard Emacs tooling for code completion. When you
@@ -47,9 +52,6 @@ you can add this to your config:
(global-set-key (kbd "TAB") #'company-indent-or-complete-common)
```
-`company-indent-or-complete-common` is available only in `company-mode` 0.9+ (at
-the time of this writing it's still in development).
-
### Fuzzy candidate matching
By default `company-mode` will provide completion candidates with the assumption
@@ -90,12 +92,3 @@ dependencies that were loaded dynamically after the REPL has started (e.g. via
Boot). Executing `M-x cider-completion-flush-caches` (or going through the menu
`CIDER Interaction->Misc->Flush completion cache`) forces the completion backend
to re-read all classes it can find on the classpath.
-
-### Migrating from `auto-complete-mode`
-
-In case you have some `auto-complete-mode` configuration lying around and you
-want to switch to `company-mode` there are a few steps you have to take:
-
-* Disable `ac-cider-setup` or `ac-nrepl-setup` from running on CIDER hooks
-
-* Remove `cider-mode` and `cider-repl-mode` from the `ac-modes` list
diff --git a/doc/configuration.md b/doc/configuration.md
index c2b3477c..4cad2a1d 100644
--- a/doc/configuration.md
+++ b/doc/configuration.md
@@ -1,32 +1,43 @@
+In the spirit of Emacs almost every aspect of CIDER's behaviour
+is configurable. We've tried to come up with some reasonable
+defaults, but we've also tried to account for different people's
+preferences, so everyone could make CIDER as comfortable as
+possible for them.
+
+You can see every single customizable configuration option with the command
+<kbd>M-x customize-group RET cider</kbd>.
+
You can certainly use CIDER without configuring it any further,
but here are some ways other folks are adjusting their CIDER
experience.
## Basic configuration
-* Suppress auto-enabling of `cider-mode` in `clojure-mode` buffers, when starting
- CIDER:
+### Auto-enabling cider-mode in clojure-mode buffers
+
+By default CIDER will enable `cider-mode` in all `clojure-mode` buffers when the
+first CIDER connection is established. It will also add a `clojure-mode` hook to
+enable it on newly created `clojure-mode` buffers. The configuration snippet
+bellow allows you to override this (somewhat non-standard) behavior.
```el
+;; Suppress auto-enabling of `cider-mode` in `clojure-mode` buffers, when starting CIDER
(setq cider-auto-mode nil)
```
-By default CIDER will enable `cider-mode` in all `clojure-mode` buffers when the
-first CIDER connection is established. It will also add a `clojure-mode` hook to
-enable it on newly created `clojure-mode` buffers. The configuration snippet
-above allows you to override this (somewhat non-standard) behavior.
+### Prompt for confirmation of the symbol at point
-* By default, interactive commands that require a symbol (e.g. `cider-doc`) will
- prompt for the symbol, with the prompt defaulting to the symbol at point. You
- can set `cider-prompt-for-symbol` to `nil` to instead try the command with the
- symbol at point first, and only prompt if that fails (this used to be the
- default behavior in older CIDER releases).
+By default, interactive commands that require a symbol (e.g. `cider-doc`) will
+prompt for the symbol, with the prompt defaulting to the symbol at point. You
+can set `cider-prompt-for-symbol` to `nil` to instead try the command with the
+symbol at point first, and only prompt if that fails (this used to be the
+default behavior in older CIDER releases).
```el
(setq cider-prompt-for-symbol nil)
```
-* Log communication with the nREPL server:
+### Log communication with the nREPL server
```el
(setq nrepl-log-messages t)
@@ -37,7 +48,9 @@ conn-name*`. The communication log is invaluable for debugging CIDER issues, so
you're generally advised to enable logging when you need to debug something
nREPL related.
-* You can hide the `*nrepl-connection*` and `*nrepl-server*` buffers
+### Hide special nREPL buffers
+
+You can hide the `*nrepl-connection*` and `*nrepl-server*` buffers
from appearing in some buffer switching commands like
`switch-to-buffer`(<kbd>C-x b</kbd>) like this:
@@ -49,14 +62,18 @@ When using `switch-to-buffer`, pressing <kbd>SPC</kbd> after the command will
make the hidden buffers visible. They'll always be visible in
`list-buffers` (<kbd>C-x C-b</kbd>).
-* To prefer local resources to remote (tramp) ones when both are available:
+### Prefer local resources over remote ones
+
+To prefer local resources to remote (tramp) ones when both are available:
```el
(setq cider-prefer-local-resources t)
```
-* Prevent <kbd>C-c C-k</kbd> from prompting to save the file corresponding to
- the buffer being loaded, if it's modified:
+### Auto-save Clojure buffers on load
+
+Normally CIDER would prompt you to save a modified Clojure buffer on <kbd>C-c C-k</kbd> (`cider-load-buffer`).
+You can change this behaviour by adjusting `cider-save-file-on-load`:
```el
;; Don't prompt and don't save
@@ -65,7 +82,9 @@ make the hidden buffers visible. They'll always be visible in
(setq cider-save-file-on-load t)
```
-* Change the result prefix for interactive evaluation (by default it's `=> `):
+### Changing the result prefix for interactive evaluation
+
+Change the result prefix for interactive evaluation (by default it's `=> `):
```el
(setq cider-eval-result-prefix ";; => ")
@@ -73,25 +92,18 @@ make the hidden buffers visible. They'll always be visible in
To remove the prefix altogether just set it to an empty string(`""`).
-* CIDER can syntax highlight symbols that are known to be defined. By default,
- this is done on symbols from the `clojure.core` namespace as well as macros
- from any namespace. If you'd like CIDER to also colorize usages of functions
- and variables from any namespace, do:
+### Use a local copy of the JDK API documentation
-```el
-(setq cider-font-lock-dynamically '(macro core function var))
-```
-
-* If you are targeting the JVM and prefer a local copy of the JDK API
- documentation over Oracle's official copy (e.g., for
- [JavaSE 8](http://docs.oracle.com/javase/8/docs/api/)), per nREPL's
- [`javadoc-info` logic (accurate as of 29 Dec 2014)](http://docs.oracle.com/javase/8/docs/api/),
- you can arrange your project to include the **root** path of the local API doc
- (i.e., where the `index.html` is located) to be included on your classpath
- (i.e., where the doc HTML files can be located by
- `clojure.java.io/resource`). For example, for Leiningen, with the local API
- path being `/usr/share/doc/java/api/`, put the following line in
- `project.clj`:
+If you are targeting the JVM and prefer a local copy of the JDK API
+documentation over Oracle's official copy (e.g., for
+[JavaSE 8](http://docs.oracle.com/javase/8/docs/api/)), per nREPL's
+[`javadoc-info` logic (accurate as of 29 Dec 2014)](http://docs.oracle.com/javase/8/docs/api/),
+you can arrange your project to include the **root** path of the local API doc
+(i.e., where the `index.html` is located) to be included on your classpath
+(i.e., where the doc HTML files can be located by
+`clojure.java.io/resource`). For example, for Leiningen, with the local API
+path being `/usr/share/doc/java/api/`, put the following line in
+`project.clj`:
```clj
:dev {:resource-paths ["/usr/share/doc/java/api/"]}
@@ -105,38 +117,116 @@ To remove the prefix altogether just set it to an empty string(`""`).
More details can be found [here](https://github.com/clojure-emacs/cider/issues/930).
-* You can hide all nREPL middleware details from `cider-browse-ns*` and `cider-apropos*`
- commands by customizing the variable `cider-filter-regexps`. It should be a list of
- regexps matching the pattern of namespaces you want to filter out.
+### Use a local copy of the Java source code
+
+When an exception is thrown, e.g. when eval-ing `(. clojure.lang.RT foo)`, a
+stack trace pops up. Some places of the stack trace link to Clojure files,
+others to Java files. By default, you can click the Clojure file links to
+navigate there. If you configure `cider-jdk-src-paths`, you can also click the
+Java file links to navigate there.
+
+On Windows and macOS the JDK source code is bundled with the JDK. On Windows its
+typical location is `C:\Program Files\Java\{jdk-version}\src.zip`
+and on macOS its `/Library/Java/JavaVirtualMachines/{jdk-version}/Contents/Home/src.zip`.
+
+On Linux distributions usually the source code is distributed as a separate package.
+Here's how do get the JDK 8 source on Ubuntu:
+
+ sudo apt install openjdk-8-source
+
+The zip is installed to `/usr/lib/jvm/openjdk-8/src.zip`.
+
+You can download Clojure Java source code from
+[here](https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0/clojure-1.8.0-sources.jar).
+
+Extract both and configure e.g. like so:
+
+ (setq cider-jdk-src-paths '("~/java/clojure-1.8.0-sources"
+ "~/java/openjvm-8-src"))
+
+It's possible to use `jar` or `zip` files `cider-jdk-src-paths`, but extracting
+them is better since you get features like `ag` or `dired-jump`.
+
+### Filter out namespaces in certain namespace-related commands
- Its default value is `'("^cider.nrepl" "^refactor-nrepl" "^clojure.tools.nrepl")`,
- the most commonly used middleware collections/packages.
+You can hide all nREPL middleware details from `cider-browse-ns*` and `cider-apropos*`
+commands by customizing the variable `cider-filter-regexps`. It should be a list of
+regexps matching the pattern of namespaces you want to filter out.
- An important thing to note is that this list of regexps is passed on to the middleware
- without any pre-processing. So, the regexps have to be in Clojure format (with twice the number of backslashes)
- and not Emacs Lisp. For example, to achieve the above effect, you could also set `cider-filter-regexps` to `'(".*nrepl")`.
+Its default value is `'("^cider.nrepl" "^refactor-nrepl" "^clojure.tools.nrepl")`,
+the most commonly used middleware collections/packages.
- To customize `cider-filter-regexps`, you could use the Emacs customize UI,
- with <kbd>M-x</kbd> `customize-variable` <kbd>RET</kbd> `cider-filter-regexps`.
+An important thing to note is that this list of regexps is passed on to the middleware
+without any pre-processing. So, the regexps have to be in Clojure format (with twice the number of backslashes)
+and not Emacs Lisp. For example, to achieve the above effect, you could also set `cider-filter-regexps` to `'(".*nrepl")`.
- Or by including a similar snippet along with the other CIDER configuration.
+To customize `cider-filter-regexps`, you could use the Emacs customize UI,
+with <kbd>M-x</kbd> `customize-variable` <kbd>RET</kbd> `cider-filter-regexps`.
+
+Or by including a similar snippet along with the other CIDER configuration.
```el
(setq cider-filter-regexps '(".*nrepl"))
```
-* By default contents of CIDER's special buffers such as `*cider-test-report*`
- or `*cider-doc*` are line truncated. You can set
- `cider-special-mode-truncate-lines` to `nil` to make those buffers use word
- wrapping instead of line truncating.
+### Truncate long lines in special buffers
+
+By default contents of CIDER's special buffers such as `*cider-test-report*`
+or `*cider-doc*` are line truncated. You can set
+`cider-special-mode-truncate-lines` to `nil` to make those buffers use word
+wrapping instead of line truncating.
- This variable should be set before loading CIDER (which means before
- `require`-ing it or autoloading it).
+**This variable should be set before loading CIDER** (which means before
+`require`-ing it or autoloading it).
``` el
(setq cider-special-mode-truncate-lines nil)
```
+## Syntax highlighting
+
+### Dynamic syntax highlighting
+
+CIDER can syntax highlight symbols that are known to be defined. By default,
+this is done on symbols from the `clojure.core` namespace, as well as macros
+from any namespace. If you'd like CIDER to also colorize usages of functions
+and variables from any namespace, do:
+
+```el
+(setq cider-font-lock-dynamically '(macro core function var))
+```
+
+Here's how code looks without dynamic syntax highlighting.
+
+![Dynamic Font-lock Off](images/dynamic_font_lock_off.png)
+
+And here's how to the code looks when it's turned on.
+
+![Dynamic Font-lock On](images/dynamic_font_lock_on.png)
+
+### Syntax highlighting for reader conditionals
+
+By default CIDER will apply font-locking to unused reader conditional
+expressions depending on the buffer CIDER connection type.
+
+![Reader Conditionals](images/reader_conditionals.png)
+
+You can disable this behavior by adjusting `cider-font-lock-reader-conditionals`:
+
+```el
+(setq cider-font-lock-reader-conditionals nil)
+```
+
+### Customizing CIDER faces
+
+CIDER defines a few custom faces that you might want to adjust (although normally your color theme
+should take care of them):
+
+* `cider-deprecated-face` - used for syntax highlighting deprecated vars
+* `cider-instrumented-face` - used for syntax highlighting instrumented for debugging vars
+* `cider-traced-face` - used for syntax highlighting traced vars
+* `cider-reader-conditional-face` - used for syntax highlighting inactive reader conditional branches
+
## Configuring eldoc
* Enable `eldoc` in Clojure buffers:
@@ -246,13 +336,22 @@ are, however, ways to improve upon the standard completion if you wish to.
(require 'icomplete)
```
+You can learn more about `icomplete`
+[here](https://www.gnu.org/software/emacs/manual/html_node/emacs/Icomplete.html).
+
### ido
`ido` is also bundled with Emacs and offers more features than `icomplete`.
If you are using `ido`, be sure to use both `ido-everywhere`
-and [`ido-ubiquitous`](https://github.com/DarwinAwardWinner/ido-ubiquitous).
+and [`ido-completing-read+`](https://github.com/DarwinAwardWinner/ido-completing-read-plus).
You might also want to install [`ido-flex`](https://github.com/lewang/flx).
+### ivy (recommended)
+
+If you're fine with installing a third-party package for enhanced minibuffer
+completion you can't go wrong with the modern and versatile
+[ivy](http://oremacs.com/2015/04/16/ivy-mode/).
+
## Pretty-printing
You can configure the function used by CIDER for pretty-printing evaluation
diff --git a/doc/hacking_on_cider.md b/doc/hacking_on_cider.md
index 908e49ff..6e23fef4 100644
--- a/doc/hacking_on_cider.md
+++ b/doc/hacking_on_cider.md
@@ -71,10 +71,10 @@ $ make test
(Note: tests may not run correctly inside Emacs' `shell-mode` buffers. Running
them in a terminal is recommended.)
-You can also check for the presence of byte-compilation warnings in batch mode:
+You can also check for compliance with a variety of coding standards in batch mode (including docstrings and byte-compilation warnings):
```
-$ make test-bytecomp
+$ make lint
```
#### Running the tests in Travis CI
@@ -179,8 +179,8 @@ pretty much anything, though. (perhaps we should change this?) To run the
Clojure and ClojureScript tests you should specify some profile like this:
```
-$ lein with-profile +1.8,+test-clj test"
-$ lein with-profile +1.8,+test-cljs test"
+$ lein with-profile +1.8,+test-clj test
+$ lein with-profile +1.8,+test-cljs test
```
This will run all Clojure and ClojureScript tests against version 1.8 of both
diff --git a/doc/images/dynamic_font_lock_off.png b/doc/images/dynamic_font_lock_off.png
new file mode 100644
index 00000000..e67823d6
--- /dev/null
+++ b/doc/images/dynamic_font_lock_off.png
Binary files differ
diff --git a/doc/images/dynamic_font_lock_on.png b/doc/images/dynamic_font_lock_on.png
new file mode 100644
index 00000000..3ced2218
--- /dev/null
+++ b/doc/images/dynamic_font_lock_on.png
Binary files differ
diff --git a/doc/images/reader_conditionals.png b/doc/images/reader_conditionals.png
new file mode 100644
index 00000000..92670c4a
--- /dev/null
+++ b/doc/images/reader_conditionals.png
Binary files differ
diff --git a/doc/index.md b/doc/index.md
index 7d48f779..752aceda 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -74,7 +74,7 @@ CIDER packs plenty of features. Here are some of them (in no particular order):
* nREPL session management
* [Scratchpad](miscellaneous_features.md#using-a-scratchpad)
* [Minibuffer code evaluation](miscellaneous_features.md#evaluating-clojure-code-in-the-minibuffer)
-* Integration with [company-mode][] and [auto-complete-mode][]
+* Integration with [company-mode][]
* [Support for working with multiple simultaneous nREPL connections](managing_connections.md)
![CIDER Screenshot](images/cider-overview.png)
@@ -85,10 +85,9 @@ CIDER packs plenty of features. Here are some of them (in no particular order):
[Sly]: https://github.com/capitaomorte/sly
[Geiser]: https://github.com/jaor/geiser
[company-mode]: http://company-mode.github.io/
-[auto-complete-mode]: https://github.com/clojure-emacs/ac-cider
[leiningen]: http://leiningen.org/
[boot]: http://boot-clj.com/
-[piggieback]: https://github.com/cemerick/piggieback
+[piggieback]: https://github.com/clojure-emacs/piggieback
[vim-fireplace]: https://github.com/tpope/vim-fireplace
[CCW]: https://github.com/laurentpetit/ccw
[cider-nrepl]: https://github.com/clojure-emacs/cider-nrepl
diff --git a/doc/installation.md b/doc/installation.md
index 3cf6def7..79712459 100644
--- a/doc/installation.md
+++ b/doc/installation.md
@@ -34,7 +34,7 @@ Use the convenient plugin for defaults, either in your project's
A minimal `profiles.clj` for CIDER would be:
```clojure
-{:repl {:plugins [[cider/cider-nrepl "0.16.0"]]}}
+{:repl {:plugins [[cider/cider-nrepl "0.17.0"]]}}
```
**Be careful not to place this in the `:user` profile, as this way CIDER's
@@ -50,7 +50,7 @@ all of their projects using a `~/.boot/profile.boot` file like so:
(require 'boot.repl)
(swap! boot.repl/*default-dependencies*
- concat '[[cider/cider-nrepl "0.16.0"]])
+ concat '[[cider/cider-nrepl "0.17.0"]])
(swap! boot.repl/*default-middleware*
conj 'cider.nrepl/cider-middleware)
@@ -77,6 +77,6 @@ It goes without saying that your project should depend on `cider-nrepl`.
***
-`x.y.z` should match the version of CIDER you're currently using (say `0.16.0`).
+`x.y.z` should match the version of CIDER you're currently using (say `0.17.0`).
For snapshot releases of CIDER you should use the snapshot of the plugin as well
-(say `0.16.0-SNAPSHOT`).
+(say `0.17.0-SNAPSHOT`).
diff --git a/doc/interactive_programming.md b/doc/interactive_programming.md
index 815a6fd6..ba5ce55c 100644
--- a/doc/interactive_programming.md
+++ b/doc/interactive_programming.md
@@ -27,12 +27,13 @@ Here's a list of `cider-mode`'s keybindings:
`cider-eval-defun-at-point` |<kbd>C-M-x</kbd> <br/> <kbd>C-c C-c</kbd> | Evaluate the top level form under point and display the result in the echo area.
`cider-eval-sexp-at-point` |<kbd>C-c C-v v</kbd> | Evaluate the form around point.
`cider-eval-defun-at-point` |<kbd>C-u C-M-x</kbd> <br/> <kbd>C-u C-c C-c</kbd> | Debug the top level form under point and walk through its evaluation
+`cider-eval-defun-to-point` |<kbd>C-c C-v z</kbd> | Evaluate the preceding top-level form up to the point.
`cider-eval-region` |<kbd>C-c C-v r</kbd> | Evaluate the region and display the result in the echo area.
`cider-interrupt` |<kbd>C-c C-b</kbd> | Interrupt any pending evaluations.
`cider-macroexpand-1` |<kbd>C-c C-m</kbd> | Invoke `macroexpand-1` on the form at point and display the result in a macroexpansion buffer. If invoked with a prefix argument, `macroexpand` is used instead of `macroexpand-1`.
`cider-macroexpand-all` |<kbd>C-c M-m</kbd> | Invoke `clojure.walk/macroexpand-all` on the form at point and display the result in a macroexpansion buffer.
`cider-eval-ns-form` |<kbd>C-c C-v n</kbd> | Eval the ns form.
-`cider-repl-set-ns` |<kbd>C-c M-n</kbd> | Switch the namespace of the REPL buffer to the namespace of the current buffer.
+`cider-repl-set-ns` |<kbd>C-c M-n</kbd> | Switch the namespace of the REPL buffer to the namespace of the current buffer.
`cider-switch-to-repl-buffer` |<kbd>C-c C-z</kbd> | Switch to the relevant REPL buffer. Use a prefix argument to change the namespace of the REPL buffer to match the currently visited source file.
`cider-switch-to-repl-buffer` |<kbd>C-u C-u C-c C-z</kbd> | Switch to the REPL buffer based on a user prompt for a directory.
`cider-load-buffer-and-switch-to-repl-buffer` |<kbd>C-c M-z</kbd> | Load (eval) the current buffer and switch to the relevant REPL buffer. Use a prefix argument to change the namespace of the REPL buffer to match the currently visited source file.
diff --git a/doc/navigating_stacktraces.md b/doc/navigating_stacktraces.md
index e581225e..9e71f3fa 100644
--- a/doc/navigating_stacktraces.md
+++ b/doc/navigating_stacktraces.md
@@ -21,7 +21,7 @@ Command | Keyboard shortcut | D
`cider-stacktrace-toggle-repl` |<kbd>r</kbd> | Toggle display of REPL frames
`cider-stacktrace-toggle-tooling` |<kbd>t</kbd> | Toggle display of tooling frames (e.g. compiler, nREPL middleware)
`cider-stacktrace-toggle-duplicates` |<kbd>d</kbd> | Toggle display of duplicate frames
-`cider-stacktrace-show-only-project |<kbd>p</kbd> | Toggle display only project frames
+`cider-stacktrace-show-only-project` |<kbd>p</kbd> | Toggle display only project frames
`cider-stacktrace-toggle-all` |<kbd>a</kbd> | Toggle display of all frames
You can configure whether the error buffer with stacktraces should be automatically
diff --git a/doc/running_tests.md b/doc/running_tests.md
index 29cbcfba..7baf8509 100644
--- a/doc/running_tests.md
+++ b/doc/running_tests.md
@@ -14,11 +14,24 @@ namespace that were defined with `clojure.test/with-test`)
- in such cases you should use <kbd>C-u C-c C-t C-n</kbd>, which will simply run
whatever tests are present in the currently visited/active namespace.
+You can also press <kbd>C-c C-t C-s</kbd> to run a subset of the tests defined in
+the namespace filtered by test selectors. CIDER will ask you for those test selectors
+in the minibuffer. If you call this command with a prefix (<kbd>C-u C-c C-t C-s</kbd>)
+you can suppress the inference logic as for run tests for the namespace.
+
You can also run all loaded tests with <kbd>C-c C-t l</kbd> or <kbd>C-c C-t
C-l</kbd> and all tests within a project with <kbd>C-c C-t p</kbd> or <kbd>C-c
C-t C-p</kbd> (note that this will load **all** namespaces in your
-project). Using <kbd>C-c C-t t</kbd> or <kbd>C-c C-t C-t</kbd>, you can execute
-only the test a point.
+project). If you call these two with a prefix CIDER will ask for test selector filters
+and only run those tests in the project which match the selector inclusions/exclusions. Using
+<kbd>C-c C-t t</kbd> or <kbd>C-c C-t C-t</kbd>, you can execute only the
+test at point.
+
+Test selectors are originally a `leiningen` feature - see `lein help test` for some explanation.
+People use them to define subsets of tests usually run together for different purposes. For
+example you can mark some of your tests with the `^:smoke` metadata marker others with
+`^:integration`. This enables you to run these tests separately in your build pipeline.
+This feature in CIDER helps you to run these test subsets in your development environment.
All test commands are available in REPL buffers as well. There you can also use
<kbd>,</kbd> to invoke some of the testing commands.
@@ -30,6 +43,7 @@ Keyboard shortcut | Description
--------------------------------|-------------------------------
<kbd>g</kbd> | Run test at point.
<kbd>n</kbd> | Run tests for current namespace.
+<kbd>s</kbd> | Run tests for current namespace with selector filter.
<kbd>l</kbd> | Run tests for all loaded namespaces.
<kbd>p</kbd> | Run tests for all project namespaces. This loads the additional namespaces.
<kbd>f</kbd> | Re-run test failures/errors.
diff --git a/doc/troubleshooting.md b/doc/troubleshooting.md
index 982d8ddc..e29aead2 100644
--- a/doc/troubleshooting.md
+++ b/doc/troubleshooting.md
@@ -30,7 +30,22 @@ to see which command is associated with some keybinding)
At this point you'll be dropped in the debugger and you can step forward until
you find the problem.
-## REPL not starting
+## Profiling CIDER commands
+
+Emacs comes with a [built-in
+profiler](https://www.gnu.org/software/emacs/manual/html_node/elisp/Profiling.html). Using
+it is pretty simple:
+
+1. Start it with <kbd>M-x</kbd> `profiler-start`.
+2. Invoke some commands.
+3. Get the report with <kbd>M-x</kbd> `profiler-report`.
+
+If you intend to share the profiling results with someone it's a good idea to
+save the report buffer to a file with <kbd>C-x C-w</kbd>.
+
+## Commonly encountered problems (and how to solve them)
+
+### REPL not starting
Make sure that your CIDER version matches your `cider-nrepl` version. Check
the contents of the `*Messages*` buffer for CIDER-related errors. You should
@@ -38,20 +53,20 @@ also check the nREPL messages passed between CIDER and nREPL in
`*nrepl-messages*`. If you don't see anything useful there it's time to bring
out the big guns.
-### Debugging the REPL init
+#### Debugging the REPL init
To debug CIDER's REPL initialization it's a good idea to hook into one of its
entry points. Add a breakpoint to `cider-make-repl` (<kbd>C-u C-M-x</kbd>, while
in its body). Next time you start CIDER you'll be dropped in the debugger and
you can step forward until you find the problem.
-## Missing `*nrepl-messages*` buffer
+### Missing `*nrepl-messages*` buffer
nREPL message logging is not enabled by default. Set `nrepl-log-messages` to
`t` to activate it. Alternatively you can use <kbd>M-x</kbd> `nrepl-toggle-message-logging`
to enable/disable logging temporary within your current Emacs session.
-## `cider-debug` complains that it “failed to instrument ...”
+### `cider-debug` complains that it “failed to instrument ...”
In the REPL buffer, issue the following.
@@ -63,7 +78,7 @@ try to debug an expression (e.g., with <kbd>C-u
C-M-x</kbd>). [File an issue](https://github.com/clojure-emacs/cider-nrepl/issues/new)
and copy this information.
-## Debugging freezes & lock-ups
+### Debugging freezes & lock-ups
Sometimes a CIDER command might hang for a while (e.g. due to a bug or a
configuration issue). Such problems are super annoying, but are relatively easy
@@ -77,7 +92,7 @@ This will bring up a backtrace with the entire function stack, including
function arguments. So you should be able to figure out what's going on (or at
least what's being required).
-## Warning saying you have to use nREPL 0.2.12+
+### Warning saying you have to use nREPL 0.2.12+
CIDER currently requires at least nREPL 0.2.12 to work properly (there were some
nasty bugs in older version and no support for tracking where some var was
@@ -99,7 +114,7 @@ Note, that running `cider-jack-in` from outside the scope of a project will
result in the **older (0.2.6) nREPL dependency being used** (at least on Leiningen
2.5.1). This is likely a Leiningen bug.
-## Missing clojure-... function after CIDER update
+### Missing clojure-... function after CIDER update
Most likely you've updated CIDER, without updating `clojure-mode` as well.
@@ -107,7 +122,7 @@ CIDER depends on `clojure-mode` and you should always update them together, as
the latest CIDER version might depend on functionality present only in the latest
`clojure-mode` version.
-## I upgraded CIDER using `package.el` and it broke
+### I upgraded CIDER using `package.el` and it broke
The built-in package manager isn't perfect and sometimes it messes up. If you
just updated and encountered an error you should try the following before
@@ -115,12 +130,12 @@ opening an issue: Go into the `.emacs.d/elpa` directory, delete any folders
related to CIDER, restart Emacs and then re-install the missing packages. Note
that the order here matters.
-## I upgraded CIDER using `package.el` and nothing changed
+### I upgraded CIDER using `package.el` and nothing changed
Emacs doesn't load the new files, it only installs them on disk. To see the
effect of changes you have to restart Emacs.
-## CIDER complains of the `cider-nrepl` version
+### CIDER complains of the `cider-nrepl` version
This is a warning displayed on the REPL buffer when it starts, and usually looks like this:
@@ -129,19 +144,19 @@ This is a warning displayed on the REPL buffer when it starts, and usually looks
where `...` might be an actual version, like `0.10.0`, or it might be `not installed` or `nil`.
The solution to this depends on what you see and on what you're doing.
-### You see a number like `X.X.X`, and you're starting the REPL with `cider-connect`
+#### You see a number like `X.X.X`, and you're starting the REPL with `cider-connect`
Your project specifies the wrong version for the cider-nrepl middleware. See the
-[instructions](http://cider.readthedocs.org/en/latest/installation/#ciders-nrepl-middleware)
+[instructions](http://cider.readthedocs.io/en/latest/installation/#ciders-nrepl-middleware)
on the Installation section.
-### You see `not installed` or `nil`, and you're starting the REPL with `cider-connect`
+#### You see `not installed` or `nil`, and you're starting the REPL with `cider-connect`
To use `cider-connect` you need to add the cider-nrepl middleware to your project. See the
-[instructions](http://cider.readthedocs.org/en/latest/installation/#ciders-nrepl-middleware)
+[instructions](http://cider.readthedocs.io/en/latest/installation/#ciders-nrepl-middleware)
on the Installation section.
-### You see `not installed` or `nil`, and you're starting the REPL with `cider-jack-in`
+#### You see `not installed` or `nil`, and you're starting the REPL with `cider-jack-in`
- Do `C-h v cider-inject-dependencies-at-jack-in`, and check that this variable is non-nil.
- Make sure your project depends on at least Clojure `1.7.0`.
@@ -150,13 +165,29 @@ on the Installation section.
If the above doesn't work, you can try specifying the cider-nrepl middleware
manually, as per the
-[instructions](http://cider.readthedocs.org/en/latest/installation/#ciders-nrepl-middleware)
+[instructions](http://cider.readthedocs.io/en/latest/installation/#ciders-nrepl-middleware)
on the Installation section.
-### You see a number like `X.X.X`, and you're starting the REPL with `cider-jack-in`
+#### You see a number like `X.X.X`, and you're starting the REPL with `cider-jack-in`
This means you're manually adding the cider-nrepl middleware in your project,
but you shouldn't do that because `cider-jack-in` already does that for
you. Look into the following files, and ensure you've removed all references to
`cider-nrepl` and `tools.nrepl`: `project.clj`, `build.boot`,
`~/.lein/profiles.clj` and `~/.boot/profile.boot`.
+
+### I get some error related to refactor-nrepl on startup
+
+The package `clj-refactor` would normally inject its own middleware on
+`cider-jack-in`, just as CIDER itself would. Usually that's not a
+problem, as long as you're using compatible versions of CIDER and
+`clj-refactor`, but if you're getting some error probably that's not
+the case. You've got two options to solve this:
+
+* Use compatible versions of the two projects (e.g. their most recent
+ snapshots or most recent stable releases)
+* Disable the `clj-refactor` middleware injection:
+
+```el
+(setq cljr-inject-dependencies-at-jack-in nil)
+```
diff --git a/doc/up_and_running.md b/doc/up_and_running.md
index 1277638c..8098b3b3 100644
--- a/doc/up_and_running.md
+++ b/doc/up_and_running.md
@@ -76,142 +76,3 @@ helpful for identifying each host.
```el
(setq cider-known-endpoints '(("host-a" "10.10.10.1" "7888") ("host-b" "7888")))
```
-
-## ClojureScript usage
-
-ClojureScript support relies on the [piggieback][] nREPL middleware being
-present in your REPL session.
-
-Add the following dependencies to your project (`project.clj` in Leiningen based project
-or `built.boot` in Boot project):
-
-```clojure
-[com.cemerick/piggieback "0.2.1"]
-[org.clojure/clojure "1.7.0"]
-```
-
-as well as `piggieback` nREPL middleware:
-
-in `project.clj`:
-```clojure
-:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
-```
-
-or in `built.boot`:
-```clojure
-(task-options!
- repl {:middleware '[cemerick.piggieback/wrap-cljs-repl]})
-```
-
-Issue <kbd>M-x</kbd> `customize-variable` <kbd>RET</kbd> and either
-`cider-cljs-lein-repl`, `cider-cljs-boot-repl` or `cider-cljs-gradle-repl` if
-you'd like to change the REPL used (the default is `rhino` where possible).
-
-Open a file in your project and issue <kbd>M-x</kbd>
-`cider-jack-in-clojurescript` <kbd>RET</kbd>. This will start up the nREPL
-server, and then create two REPL buffers for you, one in Clojure and one in
-ClojureScript. All usual CIDER commands will be automatically directed to the
-appropriate REPL, depending on whether you're visiting a `.clj` or a `.cljs`
-file.
-
-### Browser-connected ClojureScript REPL
-
-Using Weasel, you can also have a browser-connected REPL.
-
-1. Add `[weasel "0.7.0"]` to your project's `:dependencies`.
-
-2. Issue <kbd>M-x</kbd> `customize-variable` <kbd>RET</kbd> plus either
- `cider-cljs-lein-repl`, `cider-cljs-boot-repl` or `cider-cljs-gradle-repl`
- and choose the `Weasel` option.
-
-3. Add this to your ClojureScript code:
-
-```clojure
-(ns my.cljs.core
- (:require [weasel.repl :as repl]))
-(repl/connect "ws://localhost:9001")
-```
-
-4. Open a file in your project and issue <kbd>M-x</kbd> `cider-jack-in-clojurescript`.
-
-Provided that a Piggieback-enabled ClojureScript environment is active in your
-REPL session, code loading and evaluation will work seamlessly regardless of the
-presence of the `cider-nrepl` middleware. If the middleware is present then most
-other features of CIDER will also be enabled (including code completion,
-documentation lookup, the namespace browser, and macroexpansion).
-
-### Browser-connected ClojureScript REPL in Boot project
-
-1. Add this to your dependencies in `build.boot`:
-
-```clojure
-[adzerk/boot-cljs "X.Y.Z" :scope "test"]
-[adzerk/boot-cljs-repl "X.Y.Z" :scope "test"]
-[pandeiro/boot-http "X.Y.Z" :scope "test"]
-[weasel "0.7.0" :scope "test"]
-[com.cemerick/piggieback "0.2.1" :scope "test"]
-```
-
-and this at the end of `build.boot`:
-
-```clojure
-(require
- '[adzerk.boot-cljs :refer [cljs]]
- '[adzerk.boot-cljs-repl :refer [cljs-repl]]
- '[pandeiro.boot-http :refer [serve]])
-
-(deftask dev []
- (comp (serve)
- (watch)
- (cljs-repl) ; order is important!!
- (cljs)))
-```
-
-2. Issue <kbd>M-x</kbd> `customize-variable` <kbd>RET</kbd> `cider-boot-parameters`
- and insert `dev`.
-
-3. Open a file in your project and issue <kbd>M-x</kbd> `cider-jack-in-clojurescript`.
-
-5. Connect to the running server with your browser. The address is printed on the terminal, but it's probably `http://localhost:3000`.
-
-For more information visit [boot-cljs-repl](https://github.com/adzerk-oss/boot-cljs-repl).
-
-### Using the Figwheel REPL (Leiningen-only)
-
-You can also use [Figwheel](https://github.com/bhauman/lein-figwheel) with CIDER.
-
-1. Set up Figwheel as normal, but make sure `:cljsbuild` and `:figwheel` settings are
- in the root of your Leiningen project definition.
-
-2. Add these to your dev `:dependencies`:
-
-```clojure
-[com.cemerick/piggieback "0.2.1"]
-[figwheel-sidecar "0.5.0-2"]
-```
-
-3. Add this to your dev `:repl-options`:
-
-```clojure
-:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]
-```
-
-4. Instruct CIDER to use Figwheel in your Emacs config:
-
-```el
-(setq cider-cljs-lein-repl "(do (use 'figwheel-sidecar.repl-api) (start-figwheel!) (cljs-repl))")
-```
-
-5. Start the REPL with `cider-jack-in-clojurescript` (<kbd>C-c M-J</kbd>)
-
-6. Open a browser to the Figwheel URL so that it can connect to your application.
-
-You now have two nREPL connections, one for Clojure and one for ClojureScript.
-CIDER will determine which to use based on the type of file you're editing.
-
-You should also check out
-[Figwheel's wiki](https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl).
-
-[leiningen]: http://leiningen.org/
-[boot]: http://boot-clj.com/
-[piggieback]: https://github.com/cemerick/piggieback
diff --git a/doc/using_the_repl.md b/doc/using_the_repl.md
index 06ff1d3b..f240b06d 100644
--- a/doc/using_the_repl.md
+++ b/doc/using_the_repl.md
@@ -13,7 +13,7 @@ Here's a list of the keybindings that are available in CIDER's REPL:
Keyboard shortcut | Description
-------------------------------------|------------------------------
-<kbd>RET</kbd> | Evaluate the current input in Clojure if it is complete. If incomplete, open a new line and indent. If invoked with a prefix argument is given then the input is evaluated without checking for completeness.
+<kbd>RET</kbd> | Evaluate the current input in Clojure if it is complete. If incomplete, open a new line and indent. If the current input is a blank string (containing only whitespace including newlines) then clear the input without evaluating and print a fresh prompt. If invoked with a prefix argument is given then the input is evaluated without checking for completeness.
<kbd>C-RET</kbd> | Close any unmatched parenthesis and then evaluate the current input in Clojure.
<kbd>C-j</kbd> | Open a new line and indent.
<kbd>C-c C-o</kbd> | Remove the output of the previous evaluation from the REPL buffer. With a prefix argument it will clear the entire REPL buffer, leaving only a prompt.
@@ -208,6 +208,22 @@ To make this behavior the default:
(setq cider-repl-use-pretty-printing t)
```
+#### Displaying images in the REPL
+
+Starting with CIDER 0.17 (Andalucía) expressions that evaluate to
+images will be rendered as images in the REPL. You can disable this
+behavior if you don't like it.
+
+```el
+(setq cider-repl-use-content-types nil)
+```
+
+Alternatively you can toggle this behaviour on and off using <kbd>M-x
+cider-repl-toggle-content-types</kbd>.
+
+Currently the feature doesn't work well with pretty-printing in the REPL,
+so you're advised not to enable both of them at the same time.
+
#### Limiting printed output in the REPL
Accidentally printing large objects can be detrimental to your
@@ -220,6 +236,38 @@ section of your Leiningen project's configuration.
:repl-options {:init (set! *print-length* 50)}
```
+or via `cider-repl-print-length` (set to 100 by default). In case both are
+present, CIDER's config will take precedence over what came from Lein.
+
+All of this applies to `*print-level*` as well. CIDER's configuration
+variable for it is named `cider-repl-print-level` (set to `nil` by default).
+
+#### Customizing the initial REPL namespace
+
+Normally the CIDER REPL will start with the `user` namespace.
+You can supply a default value for REPL sessions via the `repl-options` section
+of your Leiningen project's configuration.
+
+```clojure
+:repl-options {:init-ns 'my-ns}
+```
+
+#### Customizing newline interaction
+
+Ordinarily <kbd>Return</kbd> sends a form for evaluation meaning entering a
+newline requires a special chord: <kbd>C-j</kbd>. When entering forms that span
+multiple lines, it may be desirable to make evaluation require the special
+invocation and have entering a new-line be the default.
+
+The following customization of the `cider-repl-mode-map` will change these
+keybindings so that <kbd>Return</kbd> will introduce a new-line and
+<kbd>C-<return></kbd> will send the form off for evaluation.
+
+``` el
+(define-key cider-repl-mode-map (kbd "RET") #'cider-repl-newline-and-indent)
+(define-key cider-repl-mode-map (kbd "C-<return>") #'cider-repl-return)
+```
+
#### REPL history
* To make the REPL history wrap around when its end is reached:
diff --git a/mkdocs.yml b/mkdocs.yml
index 8d1cdff1..2e000976 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,12 +1,13 @@
site_name: "CIDER: The Clojure Interactive Development Environment that Rocks"
repo_url: https://github.com/clojure-emacs/cider
site_dir: html
-copyright: "Copyright (C) 2016-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors"
+copyright: "Copyright (C) 2016-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors"
docs_dir: doc
pages:
- Home: index.md
- Installation: installation.md
- Up and Running: up_and_running.md
+- ClojureScript: clojurescript.md
- Interactive Programming: interactive_programming.md
- Using the REPL: using_the_repl.md
- Code Completion: code_completion.md
diff --git a/nrepl-client.el b/nrepl-client.el
index 1bed8f72..38e0cb53 100644
--- a/nrepl-client.el
+++ b/nrepl-client.el
@@ -1,7 +1,7 @@
;;; nrepl-client.el --- Client for Clojure nREPL -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
@@ -9,6 +9,7 @@
;; Artur Malabarba <bruce.connor.am@gmail.com>
;; Hugo Duncan <hugo@hugoduncan.org>
;; Steve Purcell <steve@sanityinc.com>
+;; Reid McKenzie <me@arrdem.com>
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -38,7 +39,7 @@
;; The nREPL communication process can be broadly represented as follows:
;;
;; 1) The server process is started as an Emacs subprocess (usually by
-;; `cider-jack-in', which in turn fires up leiningen or boot). Note that
+;; `cider-jack-in', which in turn fires up leiningen or boot). Note that
;; if a connection was established using `cider-connect' there won't be
;; a server process.
;;
@@ -279,7 +280,8 @@ PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'."
"Read port from .nrepl-port, nrepl-port or target/repl-port files in directory DIR."
(or (nrepl--port-from-file (expand-file-name "repl-port" dir))
(nrepl--port-from-file (expand-file-name ".nrepl-port" dir))
- (nrepl--port-from-file (expand-file-name "target/repl-port" dir))))
+ (nrepl--port-from-file (expand-file-name "target/repl-port" dir))
+ (nrepl--port-from-file (expand-file-name ".shadow-cljs/nrepl.port" dir))))
(defun nrepl--port-from-file (file)
"Attempts to read port from a file named by FILE."
@@ -763,7 +765,8 @@ to the REPL."
(defun nrepl-make-response-handler (buffer value-handler stdout-handler
stderr-handler done-handler
&optional eval-error-handler
- pprint-out-handler)
+ pprint-out-handler
+ content-type-handler)
"Make a response handler for connection BUFFER.
A handler is a function that takes one argument - response received from
the server process. The response is an alist that contains at least 'id'
@@ -772,20 +775,35 @@ and 'session' keys. Other standard response keys are 'value', 'out', 'err',
The presence of a particular key determines the type of the response. For
example, if 'value' key is present, the response is of type 'value', if
-'out' key is present the response is 'stdout' etc. Depending on the type,
-the handler dispatches the appropriate value to one of the supplied
-handlers: VALUE-HANDLER, STDOUT-HANDLER, STDERR-HANDLER, DONE-HANDLER,
-EVAL-ERROR-HANDLER, and PPRINT-OUT-HANDLER. If the optional
-EVAL-ERROR-HANDLER is nil, the default `nrepl-err-handler' is used. If any
-of the other supplied handlers are nil nothing happens for the
-corresponding type of response."
+'out' key is present the response is 'stdout' etc.
+
+Depending on the type, the handler dispatches the appropriate value to one
+of the supplied handlers: VALUE-HANDLER, STDOUT-HANDLER, STDERR-HANDLER,
+DONE-HANDLER, EVAL-ERROR-HANDLER, PPRINT-OUT-HANDLER and
+CONTENT-TYPE-HANDLER.
+
+Handlers are functions of the buffer and the value they handle, except for
+the optional CONTENT-TYPE-HANDLER which should be a function of the buffer,
+content, the content-type to be handled as a list `(type attrs)'.
+
+If the optional EVAL-ERROR-HANDLER is nil, the default `nrepl-err-handler'
+is used. If any of the other supplied handlers are nil nothing happens for
+the corresponding type of response."
(lambda (response)
- (nrepl-dbind-response response (value ns out err status id pprint-out)
+ (nrepl-dbind-response response (content-type content-transfer-encoding body
+ value ns out err status id
+ pprint-out)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when (and ns (not (derived-mode-p 'clojure-mode)))
(cider-set-buffer-ns ns))))
- (cond (value
+ (cond ((and content-type content-type-handler)
+ (funcall content-type-handler buffer
+ (if (string= content-transfer-encoding "base64")
+ (base64-decode-string body)
+ body)
+ content-type))
+ (value
(when value-handler
(funcall value-handler buffer value)))
(out
@@ -974,13 +992,17 @@ Optional argument TOOLING Tooling is set to t if wanting the tooling session fro
"Perform :ls-sessions request for CONNECTION."
(nrepl-send-sync-request '("op" "ls-sessions") connection))
-(defun nrepl-sync-request:eval (input connection &optional ns)
+(defun nrepl-sync-request:eval (input connection &optional ns tooling)
"Send the INPUT to the nREPL server synchronously.
The request is dispatched via CONNECTION.
-If NS is non-nil, include it in the request."
+If NS is non-nil, include it in the request
+If TOOLING is non-nil the evaluation is done using the tooling nREPL
+session."
(nrepl-send-sync-request
(nrepl--eval-request input ns)
- connection))
+ connection
+ nil
+ tooling))
(defun nrepl-sessions (connection)
"Get a list of active sessions on the nREPL server using CONNECTION."
diff --git a/nrepl-dict.el b/nrepl-dict.el
index 6e1ba370..be143860 100644
--- a/nrepl-dict.el
+++ b/nrepl-dict.el
@@ -1,7 +1,7 @@
;;; nrepl-dict.el --- Dictionary functions for Clojure nREPL -*- lexical-binding: t -*-
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
-;; Copyright © 2013-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;;
;; Author: Tim King <kingtim@gmail.com>
;; Phil Hagelberg <technomancy@gmail.com>
diff --git a/test/cider-apropos-tests.el b/test/cider-apropos-tests.el
index 9bd0502f..5e2a6530 100644
--- a/test/cider-apropos-tests.el
+++ b/test/cider-apropos-tests.el
@@ -1,6 +1,6 @@
;;; cider-apropos-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-browse-ns-tests.el b/test/cider-browse-ns-tests.el
index 29c88da0..6967b4b4 100644
--- a/test/cider-browse-ns-tests.el
+++ b/test/cider-browse-ns-tests.el
@@ -1,6 +1,6 @@
;;; cider-browse-ns-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-classpath-tests.el b/test/cider-classpath-tests.el
index 76c5a8ba..98fdceb7 100644
--- a/test/cider-classpath-tests.el
+++ b/test/cider-classpath-tests.el
@@ -1,6 +1,6 @@
;;; cider-classpath-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-client-tests.el b/test/cider-client-tests.el
index 65603606..2231e4ce 100644
--- a/test/cider-client-tests.el
+++ b/test/cider-client-tests.el
@@ -1,6 +1,6 @@
;;; cider-client-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
@@ -99,9 +99,6 @@
(expect (cider-current-connection "clj") :to-equal b))
(with-temp-buffer
(clojurec-mode)
- (expect (cider-current-connection "clj") :to-equal b))
- (with-temp-buffer
- (clojurex-mode)
(expect (cider-current-connection "clj") :to-equal b))))))
(describe "when type argument is given"
@@ -235,6 +232,46 @@
:to-equal "stub")
(expect (cider-var-info "") :to-equal nil)))
+(describe "cider-toggle-buffer-connection"
+ (spy-on 'message :and-return-value nil)
+
+ (describe "when there are multiple connections"
+ (it "toggles between multiple buffers"
+ (with-connection-buffer "clj" clj-buffer
+ (with-connection-buffer "cljs" cljs-buffer
+ (with-temp-buffer
+ (setq major-mode 'clojurec-mode)
+ (expect (cider-connections)
+ :to-equal (list cljs-buffer clj-buffer))
+
+ (cider-toggle-buffer-connection)
+ (expect (cider-connections)
+ :to-equal (list clj-buffer))
+
+ (cider-toggle-buffer-connection)
+ (expect (cider-connections)
+ :to-equal (list cljs-buffer))
+
+ (cider-toggle-buffer-connection t)
+ (expect (cider-connections)
+ :to-equal (list cljs-buffer clj-buffer)))))))
+
+ (describe "when there is a single connection"
+ (it "reports a user error"
+ (with-connection-buffer "clj" clj-buffer
+ (with-temp-buffer
+ (setq major-mode 'clojurec-mode)
+ (expect (cider-connections)
+ :to-equal (list clj-buffer))
+
+ (expect (cider-toggle-buffer-connection) :to-throw 'user-error)
+
+ (expect (cider-connections)
+ :to-equal (list clj-buffer))
+
+ (expect (local-variable-p 'cider-connections)
+ :to-be nil))))))
+
(describe "cider-make-connection-default"
:var (connections)
diff --git a/test/cider-common-tests.el b/test/cider-common-tests.el
index 36cb246f..b222f3ba 100644
--- a/test/cider-common-tests.el
+++ b/test/cider-common-tests.el
@@ -1,6 +1,6 @@
;;; cider-common-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
@@ -64,3 +64,14 @@
(expect (cider--kw-to-symbol ":clj.core/str") :to-equal "clj.core/str")
(expect (cider--kw-to-symbol "::keyword") :to-equal "keyword")
(expect (cider--kw-to-symbol nil) :to-equal nil)))
+
+(describe "cider-make-tramp-prefix"
+ (it "returns tramp-prefix only"
+ ;;; The third parameter is a host. It must contains a port number.
+ (expect (cider-make-tramp-prefix "ssh" "cider-devs" "192.168.50.9#22")
+ :to-equal "/ssh:cider-devs@192.168.50.9#22:")
+ ;;; These two cases are for using ssh config alias.
+ (expect (cider-make-tramp-prefix "ssh" nil "test.cider.com")
+ :to-equal "/ssh:test.cider.com:")
+ (expect (cider-make-tramp-prefix "ssh" nil "test.local")
+ :to-equal "/ssh:test.local:")))
diff --git a/test/cider-debug-tests.el b/test/cider-debug-tests.el
index 0b66fee5..f93732b7 100644
--- a/test/cider-debug-tests.el
+++ b/test/cider-debug-tests.el
@@ -1,6 +1,6 @@
;;; cider-debug-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-eldoc-tests.el b/test/cider-eldoc-tests.el
index 0bdd083e..750483c6 100644
--- a/test/cider-eldoc-tests.el
+++ b/test/cider-eldoc-tests.el
@@ -1,6 +1,6 @@
;;; cider-eldoc-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-error-parsing-tests.el b/test/cider-error-parsing-tests.el
index d393e001..ce137f49 100644
--- a/test/cider-error-parsing-tests.el
+++ b/test/cider-error-parsing-tests.el
@@ -1,6 +1,6 @@
;;; cider-error-parsing-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-grimoire-tests.el b/test/cider-grimoire-tests.el
index 64ecb958..66c7f6ec 100644
--- a/test/cider-grimoire-tests.el
+++ b/test/cider-grimoire-tests.el
@@ -1,6 +1,6 @@
;;; cider-grimoire-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-interaction-tests.el b/test/cider-interaction-tests.el
index e59c2c0b..46ac0c75 100644
--- a/test/cider-interaction-tests.el
+++ b/test/cider-interaction-tests.el
@@ -1,6 +1,6 @@
;;; cider-interaction-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
@@ -102,3 +102,21 @@
(with-temp-buffer
(clojure-mode)
(expect (cider-interactive-eval "(+ 1)") :not :to-throw)))))
+
+(describe "cider--calculate-opening-delimiters"
+ (it "returns the right opening delimiters"
+ (with-temp-buffer
+ (clojure-mode)
+ (insert "(let [a 1] (let [b 2] (+ a b)))")
+ (backward-char 2)
+ (expect (cider--calculate-opening-delimiters) :to-equal '(40 40)))))
+
+(describe "cider--matching-delimiter"
+ (it "returns the right closing delimiter"
+ (expect (cider--matching-delimiter ?\() :to-equal ?\))
+ (expect (cider--matching-delimiter ?\{) :to-equal ?\})
+ (expect (cider--matching-delimiter ?\[) :to-equal ?\]))
+ (it "returns the right opening delimiter"
+ (expect (cider--matching-delimiter ?\)) :to-equal ?\()
+ (expect (cider--matching-delimiter ?\}) :to-equal ?\{)
+ (expect (cider--matching-delimiter ?\]) :to-equal ?\[)))
diff --git a/test/cider-overlay-tests.el b/test/cider-overlay-tests.el
index 3109c451..13b17be8 100644
--- a/test/cider-overlay-tests.el
+++ b/test/cider-overlay-tests.el
@@ -1,6 +1,6 @@
;;; cider-overlay-tests.el -*- lexical-binding: t; -*-
-;; Copyright © 2015-2017 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
diff --git a/test/cider-repl-tests.el b/test/cider-repl-tests.el
index b8d59a18..0a40ac0f 100644
--- a/test/cider-repl-tests.el
+++ b/test/cider-repl-tests.el
@@ -1,6 +1,6 @@
;;; cider-repl-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
@@ -142,3 +142,15 @@ PROPERTY shoudl be a symbol of either 'text, 'ansi-context or
(fill-column 80))
(expect (cider--pretty-print-width)
:to-equal fill-column))))
+
+(describe "cider-repl--build-config-expression"
+ (it "returns nil when all the config values are nil"
+ (let ((cider-repl-print-length nil)
+ (cider-repl-print-level nil))
+ (expect (cider-repl--build-config-expression) :to-equal nil)))
+ (it "returns an when any the config values are non-nil"
+ (let ((cider-repl-print-length 10)
+ (cider-repl-print-level 10))
+ (expect (cider-repl--build-config-expression)
+ :to-equal
+ "(do (set! *print-length* 10) (set! *print-level* 10))"))))
diff --git a/test/cider-selector-tests.el b/test/cider-selector-tests.el
index 9a2d680e..63eee4c9 100644
--- a/test/cider-selector-tests.el
+++ b/test/cider-selector-tests.el
@@ -1,6 +1,6 @@
;;; cider-selector-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-stacktrace-tests.el b/test/cider-stacktrace-tests.el
index 7a206e4a..91e4da15 100644
--- a/test/cider-stacktrace-tests.el
+++ b/test/cider-stacktrace-tests.el
@@ -1,6 +1,6 @@
;;; cider-stacktrace-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/cider-tests--no-auto.el b/test/cider-tests--no-auto.el
index 0b7db012..c27bd50b 100644
--- a/test/cider-tests--no-auto.el
+++ b/test/cider-tests--no-auto.el
@@ -1,6 +1,6 @@
;;; cider-tests--no-auto.el --- Non-automated tests -*- lexical-binding: t -*-
-;; Copyright © 2014-2017 Jeff Valk, Bozhidar Batsov and CIDER contributors
+;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
;; Author: Jeff Valk <jv@jeffvalk.com>
diff --git a/test/cider-tests.el b/test/cider-tests.el
index 91090173..179fcd71 100644
--- a/test/cider-tests.el
+++ b/test/cider-tests.el
@@ -1,6 +1,6 @@
;;; cider-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
@@ -134,7 +134,62 @@
:to-equal "-C -o -i \"(require 'cider.tasks)\" -d org.clojure/tools.nrepl\\:0.2.12 -d cider/cider-nrepl\\:0.11.0 cider.tasks/add-middleware -m cider.nrepl/cider-middleware repl -s wait"))
(it "can concat in a gradle project"
(expect (cider-inject-jack-in-dependencies "-m" "--no-daemon clojureRepl" "gradle")
- :to-equal "-m --no-daemon clojureRepl"))))
+ :to-equal "-m --no-daemon clojureRepl")))
+
+ (describe "when there are predicates"
+ :var (plugins-predicate middlewares-predicate)
+
+ (before-each
+ (fset 'plugins-predicate (lambda (&rest _) t))
+ (fset 'middlewares-predicate (lambda (&rest _) t))
+ (setq-local cider-jack-in-lein-plugins '(("refactor-nrepl" "2.0.0" :predicate plugins-predicate) ("cider/cider-nrepl" "0.11.0")))
+ (setq-local cider-jack-in-nrepl-middlewares '(("refactor-nrepl.middleware/wrap-refactor" :predicate middlewares-predicate) "cider.nrepl/cider-middleware" ("another/middleware"))))
+ (it "includes plugins whose predicates return true"
+ (expect (cider-jack-in-normalized-lein-plugins)
+ :to-equal '(("refactor-nrepl" "2.0.0") ("cider/cider-nrepl" "0.11.0"))))
+ (it "includes middlewares whose predicates return true"
+ (expect (cider-jack-in-normalized-nrepl-middlewares)
+ :to-equal '("refactor-nrepl.middleware/wrap-refactor" "cider.nrepl/cider-middleware" "another/middleware")))
+ (it "ignores plugins whose predicates return false"
+ (spy-on 'plugins-predicate :and-return-value nil)
+ (expect (cider-jack-in-normalized-lein-plugins)
+ :to-equal '(("cider/cider-nrepl" "0.11.0"))))
+ (it "ignores plugins whose predicates return false"
+ (spy-on 'middlewares-predicate :and-return-value nil)
+ (expect (cider-jack-in-normalized-nrepl-middlewares)
+ :to-equal '("cider.nrepl/cider-middleware" "another/middleware")))
+ (it "calls plugin predicates with the whole list entry"
+ (spy-on 'plugins-predicate)
+ (cider-jack-in-normalized-lein-plugins)
+ (expect 'plugins-predicate
+ :to-have-been-called-with '("refactor-nrepl" "2.0.0" :predicate plugins-predicate)))
+ (it "calls middleware predicates with the whole list entry"
+ (spy-on 'middlewares-predicate)
+ (cider-jack-in-normalized-nrepl-middlewares)
+ (expect 'middlewares-predicate
+ :to-have-been-called-with '("refactor-nrepl.middleware/wrap-refactor" :predicate middlewares-predicate)))
+ (it "only calls plugin predicates for their own entries"
+ (spy-on 'plugins-predicate)
+ (cider-jack-in-normalized-lein-plugins)
+ (expect 'plugins-predicate :to-have-been-called-times 1))
+ (it "only calls middleware predicates for their own entries"
+ (spy-on 'middlewares-predicate)
+ (cider-jack-in-normalized-nrepl-middlewares)
+ (expect 'middlewares-predicate :to-have-been-called-times 1)))
+
+ (describe "when the middleware and plugin lists have been normalized"
+ (before-each
+ (spy-on 'cider-jack-in-normalized-nrepl-middlewares
+ :and-return-value '("refactor-nrepl.middleware/wrap-refactor" "cider.nrepl/cider-middleware"))
+ (spy-on 'cider-jack-in-normalized-lein-plugins
+ :and-return-value '(("refactor-nrepl" "2.0.0") ("cider/cider-nrepl" "0.11.0")))
+ (setq-local cider-jack-in-dependencies-exclusions '()))
+ (it "uses them in a lein project"
+ (expect (cider-inject-jack-in-dependencies "" "repl :headless" "lein")
+ :to-equal "update-in :dependencies conj \\[org.clojure/tools.nrepl\\ \\\"0.2.12\\\"\\] -- update-in :plugins conj \\[refactor-nrepl\\ \\\"2.0.0\\\"\\] -- update-in :plugins conj \\[cider/cider-nrepl\\ \\\"0.11.0\\\"\\] -- repl :headless"))
+ (it "uses them in a boot project"
+ (expect (cider-inject-jack-in-dependencies "" "repl -s wait" "boot")
+ :to-equal "-i \"(require 'cider.tasks)\" -d org.clojure/tools.nrepl\\:0.2.12 -d refactor-nrepl\\:2.0.0 -d cider/cider-nrepl\\:0.11.0 cider.tasks/add-middleware -m refactor-nrepl.middleware/wrap-refactor -m cider.nrepl/cider-middleware repl -s wait"))))
(describe "cider-jack-in-auto-inject-clojure"
(it "injects `cider-minimum-clojure-version' when `cider-jack-in-auto-inject-clojure' is set to minimal"
diff --git a/test/cider-util-tests.el b/test/cider-util-tests.el
index 83d7a5f6..cd5042fc 100644
--- a/test/cider-util-tests.el
+++ b/test/cider-util-tests.el
@@ -1,6 +1,6 @@
;;; cider-util-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
@@ -184,11 +184,11 @@
;; :var (cider-version)
;; (it "returns the manual correct url for stable cider versions"
;; (setq cider-version "0.11.0")
-;; (expect (cider-manual-url) :to-equal "http://cider.readthedocs.org/en/stable/"))
+;; (expect (cider-manual-url) :to-equal "http://cider.readthedocs.io/en/stable/"))
;; (it "returns the manual correct url for snapshot cider versions"
;; (setq cider-version "0.11.0-snapshot")
-;; (expect (cider-manual-url) :to-equal "http://cider.readthedocs.org/en/latest/")))
+;; (expect (cider-manual-url) :to-equal "http://cider.readthedocs.io/en/latest/")))
(describe "cider-refcard-url"
:var (cider-version)
diff --git a/test/nrepl-bencode-tests.el b/test/nrepl-bencode-tests.el
index 827a76ed..4e704357 100644
--- a/test/nrepl-bencode-tests.el
+++ b/test/nrepl-bencode-tests.el
@@ -1,6 +1,6 @@
;;; nrepl-bencode-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/nrepl-client-tests.el b/test/nrepl-client-tests.el
index c8d4f0d7..5716e0a4 100644
--- a/test/nrepl-client-tests.el
+++ b/test/nrepl-client-tests.el
@@ -1,6 +1,6 @@
;;; nrepl-client-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/nrepl-dict-tests.el b/test/nrepl-dict-tests.el
index 8c8159ce..0011ff7c 100644
--- a/test/nrepl-dict-tests.el
+++ b/test/nrepl-dict-tests.el
@@ -1,6 +1,6 @@
;;; nrepl-dict-tests.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/test/scripts/cider-bytecomp-warnings.el b/test/scripts/cider-bytecomp-warnings.el
deleted file mode 100644
index cdc632d9..00000000
--- a/test/scripts/cider-bytecomp-warnings.el
+++ /dev/null
@@ -1,46 +0,0 @@
-;;; cider-bytecomp-warnings.el --- Check for byte-compilation problems
-
-;; Copyright © 2012-2017 Bozhidar Batsov and contributors
-;;
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;; This file is not part of GNU Emacs.
-
-;;; Commentary:
-
-;; This is a script to be loaded while visiting a CIDER source file. It will
-;; prepare all requirements and then byte-compile the file and signal an error
-;; on any warning. For example:
-;;
-;; emacs -Q --batch -l test/cider-bytecomp-warnings.el cider-mode.el
-
-;; This assumes that all CIDER dependencies are already on the package dir
-;; (probably from running `cask install').
-
-(setq load-prefer-newer t)
-(add-to-list 'load-path (expand-file-name "./"))
-(require 'package)
-(package-generate-autoloads 'cider default-directory)
-(package-initialize)
-(load-file "cider-autoloads.el")
-(setq byte-compile-error-on-warn t)
-
-;; Avoid spurious unused lexical arg warning from `condition-case'
-;; See: https://emacs.stackexchange.com/a/10058/10269
-(when (version< emacs-version "25.1")
- (setq byte-compile--use-old-handlers nil))
-
-(batch-byte-compile)
-
-;;; cider-bytecomp-warnings.el ends here
diff --git a/test/scripts/cider-checks.el b/test/scripts/cider-checks.el
deleted file mode 100644
index d7e29980..00000000
--- a/test/scripts/cider-checks.el
+++ /dev/null
@@ -1,33 +0,0 @@
-;; This is a script to be loaded from the root CIDER directory. It will prepare
-;; all requirements and then run `check-declare-directory' on
-;; `default-directory'. For example:
-;; emacs -Q --batch -l test/cider-checks.el
-
-;; This assumes that all CIDER dependencies are already on the package dir
-;; (probably from running `cask install').
-
-(add-to-list 'load-path (expand-file-name "./"))
-(require 'package)
-(require 'check-declare)
-(require 'seq)
-(package-initialize)
-
-;; disable some annoying (or non-applicable) checkdoc checks
-(setq checkdoc-package-keywords-flag nil)
-(setq checkdoc-arguments-in-order-flag nil)
-(setq checkdoc-verb-check-experimental-flag nil)
-
-(let ((files (seq-filter
- (lambda (el) (not (string-match-p "autoloads" el)))
- (directory-files default-directory t
- "\\`[^.].*\\.el\\'" t))))
- ;; `checkdoc-file' was introduced in Emacs 25
- (when (fboundp 'checkdoc-file)
- (dolist (file files)
- (checkdoc-file file))
- (when (get-buffer "*Warnings*")
- (message "Failing due to checkdoc warnings...")
- (kill-emacs 1)))
-
- (when (apply #'check-declare-files files)
- (kill-emacs 1)))
diff --git a/test/utils/cider-connection-test-utils.el b/test/utils/cider-connection-test-utils.el
index b51f090e..1ea36c95 100644
--- a/test/utils/cider-connection-test-utils.el
+++ b/test/utils/cider-connection-test-utils.el
@@ -1,6 +1,6 @@
;;; cider-connection-test-utils.el
-;; Copyright © 2012-2017 Tim King, Bozhidar Batsov
+;; Copyright © 2012-2018 Tim King, Bozhidar Batsov
;; Author: Tim King <kingtim@gmail.com>
;; Bozhidar Batsov <bozhidar@batsov.com>
diff --git a/travis-ci/install-gnutls.sh b/travis-ci/install-gnutls.sh
deleted file mode 100755
index bd3316b4..00000000
--- a/travis-ci/install-gnutls.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash -x
-
-# Setup a newer gnutls-cli on Travis CI
-# We need this as long as the Travis workers are Ubuntu 14.04
-# and the TLS cert chain on elpa.gnu.org is out-of-order
-
-# adjust these versions as needed
-export NETTLE_VERSION=3.4
-export GNUTLS_VERSION=3.5.16
-
-export WORKDIR=${HOME}/local/
-export LD_LIBRARY_PATH=${WORKDIR}/lib/
-export PKG_CONFIG_PATH=${WORKDIR}/lib/pkgconfig/
-
-# make sure workdir exists
-if [ ! -d ${WORKDIR} ]
-then
- mkdir $WORKDIR
-fi
-
-# exit if the cache is valid and up-to-date
-if [ -f ${WORKDIR}/bin/gnutls-cli ] && \
- [ -f ${WORKDIR}/nettle-${NETTLE_VERSION}.tar.gz ] && \
- [ -f ${WORKDIR}/gnutls-${GNUTLS_VERSION}.tar.xz ]
-then
- exit 0
-fi
-
-# delete cache and rebuild
-rm -rf $WORKDIR/bin $WORKDIR/lib $WORKDIR/share $WORKDIR/include
-rm -rf $WORKDIR/nettle* $WORKDIR/gnutls*
-
-cd $WORKDIR
-curl -O https://ftp.gnu.org/gnu/nettle/nettle-${NETTLE_VERSION}.tar.gz \
- && tar xfz nettle-${NETTLE_VERSION}.tar.gz \
- && cd nettle-${NETTLE_VERSION} \
- && ./configure --prefix=${WORKDIR} \
- && make -j4 install \
- && make distclean
-
-cd $WORKDIR
-curl -O https://www.gnupg.org/ftp/gcrypt/gnutls/v3.5/gnutls-${GNUTLS_VERSION}.tar.xz \
- && xz -d -k gnutls-${GNUTLS_VERSION}.tar.xz \
- && tar xf gnutls-${GNUTLS_VERSION}.tar \
- && cd gnutls-${GNUTLS_VERSION} \
- && ./configure --prefix=${WORKDIR} \
- --with-included-libtasn1 \
- --with-included-unistring \
- --without-p11-kit \
- && make -j4 install \
- && make distclean