summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2019-01-10 08:39:18 -0700
committerSean Whitton <spwhitton@spwhitton.name>2019-01-10 08:39:18 -0700
commit99a77b2d8bd9e9721ff52b8a817ba50b74dd3fe8 (patch)
tree772f5355d5939a61d6a2fddbfb4b70c355495d13
parent52096bd8c3c3834efe11ba0e8d3d7efaa85c5fa4 (diff)
parent1ccef7b2b7a063aa42416d1518e8e7228d90a78d (diff)
Merge tag '5.10.0'
-rw-r--r--CHANGELOG.md18
-rw-r--r--CONTRIBUTING.md15
-rw-r--r--README.md17
-rw-r--r--clojure-mode.el213
-rw-r--r--test/clojure-mode-font-lock-test.el5
-rw-r--r--test/clojure-mode-indentation-test.el37
-rw-r--r--test/clojure-mode-sexp-test.el10
7 files changed, 215 insertions, 100 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ecea94e..7835474 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,24 @@
## master (unreleased)
+## 5.10.0 (2019-01-05)
+
+### New features
+
+* Recognize Gradle projects using the new Kotlin DSL (`build.gradle.kts`).
+* [#481](https://github.com/clojure-emacs/clojure-mode/issues/481): Support vertical alignment even in the presence of blank lines, with the new `clojure-align-separator` user option.
+* [#483](https://github.com/clojure-emacs/clojure-mode/issues/483): Support alignment for reader conditionals, with the new `clojure-align-reader-conditionals` user option.
+* [#497](https://github.com/clojure-emacs/clojure-mode/pull/497): Indent "let", "when" and "while" as function form if not at start of a symbol.
+
+### Bugs fixed
+
+* [#489](https://github.com/clojure-emacs/clojure-mode/issues/489): Inserting parens before comment form doesn't move point.
+* [#500](https://github.com/clojure-emacs/clojure-mode/pull/500): Fix project.el integration.
+
+### Changes
+
+* Change the accepted values of `clojure-indent-style` from keywords to symbols.
+
## 5.9.1 (2018-08-27)
* [#485](https://github.com/clojure-emacs/clojure-mode/issues/485): Fix a regression in `end-f-defun`.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1c925af..bb46c29 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -34,7 +34,18 @@ clojure-mode (version 2.1.1)
* [Squash related commits together][5].
* Open a [pull request][4] that relates to *only* one subject with a clear title
and description in grammatically correct, complete sentences.
-* When applicable, attach ERT unit tests.
+* When applicable, attach ERT unit tests. See below for instructions on running the tests.
+
+## Development setup
+
+1. Fork and clone the repository.
+1. Install [Cask][7].
+1. Run `cask install` in the repository folder.
+1. Run tests with `make test`.
+
+**Note:** macOS users should make sure that the `emacs` command resolves the version of Emacs they've installed
+manually (e.g. via `homebrew`), instead of the ancient Emacs 22 that comes bundled with macOS.
+See [this article][8] for more details.
[1]: https://github.com/clojure-emacs/clojure-mode/issues
[2]: http://gun.io/blog/how-to-github-fork-branch-and-pull-request
@@ -42,3 +53,5 @@ and description in grammatically correct, complete sentences.
[4]: https://help.github.com/articles/using-pull-requests
[5]: http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html
[6]: https://github.com/clojure-emacs/clojure-mode/blob/master/CHANGELOG.md
+[7]: https://github.com/cask/cask
+[8]: https://emacsredux.com/blog/2015/05/09/emacs-on-os-x/
diff --git a/README.md b/README.md
index c82d8fc..4e3fa4e 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ want multi-line docstrings to be indented at all (which is pretty common in most
The indentation of function forms is configured by the variable
`clojure-indent-style`. It takes three possible values:
-- `:always-align` (the default)
+- `always-align` (the default)
```clj
(some-function
@@ -93,7 +93,7 @@ The indentation of function forms is configured by the variable
2)
```
-- `:always-indent`
+- `always-indent`
```clj
(some-function
@@ -105,7 +105,7 @@ The indentation of function forms is configured by the variable
2)
```
-- `:align-arguments`
+- `align-arguments`
```clj
(some-function
@@ -117,6 +117,9 @@ The indentation of function forms is configured by the variable
2)
```
+**Note:** Prior to clojure-mode 5.10 the configuration options for `clojure-indent-style` used to be
+keywords, but now they are symbols. Keywords will still be supported at least until clojure-mode 6.
+
#### Indentation of macro forms
The indentation of special forms and macros with bodies is controlled via
@@ -362,8 +365,8 @@ enable it like this:
## REPL Interaction
-One of the fundamental aspects of Lisps in general and Clojure in
-particular is the notion of interactive programming - building your
+One of the fundamental aspects of Lisps in general, and Clojure in
+particular, is the notion of interactive programming - building your
programs by continuously changing the state of the running Lisp
program (as opposed to doing something more traditional like making a
change and re-running the program afterwards to see the changes in
@@ -376,7 +379,9 @@ running Clojure process and evaluating code interactively.
### Basic REPL
-Install [inf-clojure][] for basic interaction with a REPL process.
+[inf-clojure][] provides basic interaction with a Clojure REPL process.
+It's very similar in nature and supported functionality to `inferior-lisp-mode`
+for Common Lisp.
### CIDER
diff --git a/clojure-mode.el b/clojure-mode.el
index 37b1abb..7940b80 100644
--- a/clojure-mode.el
+++ b/clojure-mode.el
@@ -10,7 +10,7 @@
;; Artur Malabarba <bruce.connor.am@gmail.com>
;; URL: http://github.com/clojure-emacs/clojure-mode
;; Keywords: languages clojure clojurescript lisp
-;; Version: 5.9.1
+;; Version: 5.10.0
;; Package-Requires: ((emacs "25.1"))
;; This file is not part of GNU Emacs.
@@ -69,6 +69,8 @@
(require 'newcomment)
(require 'align)
(require 'subr-x)
+(require 'lisp-mnt)
+(require 'project)
(declare-function lisp-fill-paragraph "lisp-mode" (&optional justify))
@@ -79,7 +81,7 @@
:link '(url-link :tag "GitHub" "https://github.com/clojure-emacs/clojure-mode")
:link '(emacs-commentary-link :tag "Commentary" "clojure-mode"))
-(defconst clojure-mode-version "5.8.2"
+(defconst clojure-mode-version (lm-version)
"The current version of `clojure-mode'.")
(defface clojure-keyword-face
@@ -92,7 +94,7 @@
"Face used to font-lock Clojure character literals."
:package-version '(clojure-mode . "3.0.0"))
-(defcustom clojure-indent-style :always-align
+(defcustom clojure-indent-style 'always-align
"Indentation style to use for function forms and macro forms.
There are two cases of interest configured by this variable.
@@ -110,7 +112,7 @@ already use special indentation rules.
The possible values for this variable are keywords indicating how
to indent function forms.
- `:always-align' - Follow the same rules as `lisp-mode'. All
+ `always-align' - Follow the same rules as `lisp-mode'. All
args are vertically aligned with the first arg in case (A),
and vertically aligned with the function name in case (B).
For instance:
@@ -120,30 +122,27 @@ to indent function forms.
merge
some-coll)
- `:always-indent' - All args are indented like a macro body.
+ `always-indent' - All args are indented like a macro body.
(reduce merge
some-coll)
(reduce
merge
some-coll)
- `:align-arguments' - Case (A) is indented like `lisp', and
+ `align-arguments' - Case (A) is indented like `lisp', and
case (B) is indented like a macro body.
(reduce merge
some-coll)
(reduce
merge
some-coll)"
- :safe #'keywordp
- :type '(choice (const :tag "Same as `lisp-mode'" :always-align)
- (const :tag "Indent like a macro body" :always-indent)
+ :safe #'symbolp
+ :type '(choice (const :tag "Same as `lisp-mode'" 'always-align)
+ (const :tag "Indent like a macro body" 'always-indent)
(const :tag "Indent like a macro body unless first arg is on the same line"
- :align-arguments))
+ 'align-arguments))
:package-version '(clojure-mode . "5.2.0"))
-(define-obsolete-variable-alias 'clojure-defun-style-default-indent
- 'clojure-indent-style "5.2.0")
-
(defcustom clojure-use-backtracking-indent t
"When non-nil, enable context sensitive indentation."
:type 'boolean
@@ -179,11 +178,12 @@ For example, \[ is allowed in :db/id[:db.part/user]."
(cl-every 'characterp value))))
(defcustom clojure-build-tool-files
- '("project.clj" ; Leiningen
- "build.boot" ; Boot
- "build.gradle" ; Gradle
- "deps.edn" ; Clojure CLI (a.k.a. tools.deps)
- "shadow-cljs.edn" ; shadow-cljs
+ '("project.clj" ; Leiningen
+ "build.boot" ; Boot
+ "build.gradle" ; Gradle
+ "build.gradle.kts" ; Gradle
+ "deps.edn" ; Clojure CLI (a.k.a. tools.deps)
+ "shadow-cljs.edn" ; shadow-cljs
)
"A list of files, which identify a Clojure project's root.
Out-of-the box `clojure-mode' understands lein, boot, gradle,
@@ -439,7 +439,7 @@ ENDP and DELIM."
(t)))))
(defconst clojure--collection-tag-regexp "#\\(::[a-zA-Z0-9._-]*\\|:?\\([a-zA-Z0-9._-]+/\\)?[a-zA-Z0-9._-]+\\)"
- "Collection reader macro tag regexp.
+ "Collection reader macro tag regexp.
It is intended to check for allowed strings that can come before a
collection literal (e.g. '[]' or '{}'), as reader macro tags.
This includes #fully.qualified/my-ns[:kw val] and #::my-ns{:kw
@@ -880,12 +880,12 @@ any number of matches of `clojure--sym-forbidden-rest-chars'."))
(2 'clojure-keyword-face))
;; type-hints: #^oneword
- (,(concat "\\(#^\\)\\(" clojure--sym-regexp "?\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
+ (,(concat "\\(#?\\^\\)\\(" clojure--sym-regexp "?\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
(1 'default)
(2 font-lock-type-face)
(3 'default)
(4 'default))
- (,(concat "\\(#^\\)\\(" clojure--sym-regexp "\\)")
+ (,(concat "\\(#?\\^\\)\\(" clojure--sym-regexp "\\)")
(1 'default)
(2 font-lock-type-face))
@@ -1090,6 +1090,22 @@ will align the values like this:
:safe #'booleanp
:type 'boolean)
+(defconst clojure--align-separator-newline-regexp "^ *$")
+
+(defcustom clojure-align-separator clojure--align-separator-newline-regexp
+ "The separator that will be passed to `align-region' when performing vertical alignment."
+ :package-version '(clojure-mode . "5.10")
+ :type `(choice (const :tag "Make blank lines prevent vertical alignment from happening."
+ ,clojure--align-separator-newline-regexp)
+ (other :tag "Allow blank lines to happen within a vertically-aligned expression."
+ 'entire)))
+
+(defcustom clojure-align-reader-conditionals nil
+ "Whether to align reader conditionals, as if they were maps."
+ :package-version '(clojure-mode . "5.10")
+ :safe #'booleanp
+ :type 'boolean)
+
(defcustom clojure-align-binding-forms
'("let" "when-let" "when-some" "if-let" "if-some" "binding" "loop"
"doseq" "for" "with-open" "with-local-vars" "with-redefs")
@@ -1104,6 +1120,10 @@ will align the values like this:
:safe #'listp
:type '(repeat string))
+(defvar clojure--beginning-of-reader-conditional-regexp
+ "#\\?@(\\|#\\?("
+ "Regexp denoting the beginning of a reader conditional.")
+
(defun clojure--position-for-alignment ()
"Non-nil if the sexp around point should be automatically aligned.
This function expects to be called immediately after an
@@ -1118,32 +1138,36 @@ For instance, in a map literal point is left immediately before
the first key; while, in a let-binding, point is left inside the
binding vector and immediately before the first binding
construct."
- ;; Are we in a map?
- (or (and (eq (char-before) ?{)
- (not (eq (char-before (1- (point))) ?\#)))
- ;; Are we in a cond form?
- (let* ((fun (car (member (thing-at-point 'symbol) clojure-align-cond-forms)))
- (method (and fun (clojure--get-indent-method fun)))
- ;; The number of special arguments in the cond form is
- ;; the number of sexps we skip before aligning.
- (skip (cond ((numberp method) method)
- ((null method) 0)
- ((sequencep method) (elt method 0)))))
- (when (and fun (numberp skip))
- (clojure-forward-logical-sexp skip)
- (comment-forward (point-max))
- fun)) ; Return non-nil (the var name).
- ;; Are we in a let-like form?
- (when (member (thing-at-point 'symbol)
- clojure-align-binding-forms)
- ;; Position inside the binding vector.
- (clojure-forward-logical-sexp)
- (backward-sexp)
- (when (eq (char-after) ?\[)
- (forward-char 1)
- (comment-forward (point-max))
- ;; Return non-nil.
- t))))
+ (let ((point (point)))
+ ;; Are we in a map?
+ (or (and (eq (char-before) ?{)
+ (not (eq (char-before (1- point)) ?\#)))
+ ;; Are we in a reader conditional?
+ (and clojure-align-reader-conditionals
+ (looking-back clojure--beginning-of-reader-conditional-regexp (- (point) 4)))
+ ;; Are we in a cond form?
+ (let* ((fun (car (member (thing-at-point 'symbol) clojure-align-cond-forms)))
+ (method (and fun (clojure--get-indent-method fun)))
+ ;; The number of special arguments in the cond form is
+ ;; the number of sexps we skip before aligning.
+ (skip (cond ((numberp method) method)
+ ((null method) 0)
+ ((sequencep method) (elt method 0)))))
+ (when (and fun (numberp skip))
+ (clojure-forward-logical-sexp skip)
+ (comment-forward (point-max))
+ fun)) ; Return non-nil (the var name).
+ ;; Are we in a let-like form?
+ (when (member (thing-at-point 'symbol)
+ clojure-align-binding-forms)
+ ;; Position inside the binding vector.
+ (clojure-forward-logical-sexp)
+ (backward-sexp)
+ (when (eq (char-after) ?\[)
+ (forward-char 1)
+ (comment-forward (point-max))
+ ;; Return non-nil.
+ t)))))
(defun clojure--find-sexp-to-align (end)
"Non-nil if there's a sexp ahead to be aligned before END.
@@ -1152,10 +1176,14 @@ Place point as in `clojure--position-for-alignment'."
(let ((found))
(while (and (not found)
(search-forward-regexp
- (concat "{\\|(" (regexp-opt
- (append clojure-align-binding-forms
- clojure-align-cond-forms)
- 'symbols))
+ (concat (when clojure-align-reader-conditionals
+ (concat clojure--beginning-of-reader-conditional-regexp
+ "\\|"))
+ "{\\|("
+ (regexp-opt
+ (append clojure-align-binding-forms
+ clojure-align-cond-forms)
+ 'symbols))
end 'noerror))
(let ((ppss (syntax-ppss)))
@@ -1217,9 +1245,9 @@ When called from lisp code align everything between BEG and END."
(cl-incf count)))
(dotimes (_ count)
(align-region (point) sexp-end nil
- '((clojure-align (regexp . clojure--search-whitespace-after-next-sexp)
+ `((clojure-align (regexp . clojure--search-whitespace-after-next-sexp)
(group . 1)
- (separate . "^ *$")
+ (separate . ,clojure-align-separator)
(repeat . t)))
nil))
;; Reindent after aligning because of #360.
@@ -1276,7 +1304,10 @@ symbol properties."
'clojure-indent-function)
(get (intern-soft (match-string 1 function-name))
'clojure-backtracking-indent)))
- (when (string-match (rx (or "let" "when" "while") (syntax symbol))
+ ;; indent symbols starting with if, when, ...
+ ;; such as if-let, when-let, ...
+ ;; like if, when, ...
+ (when (string-match (rx string-start (or "if" "when" "let" "while") (syntax symbol))
function-name)
(clojure--get-indent-method (substring (match-string 0 function-name) 0 -1)))))
@@ -1336,6 +1367,10 @@ spec."
(let ((function (thing-at-point 'symbol)))
(clojure--get-indent-method function))))
+(defun clojure--keyword-to-symbol (keyword)
+ "Convert KEYWORD to symbol."
+ (intern (substring (symbol-name keyword) 1)))
+
(defun clojure--normal-indent (last-sexp indent-mode)
"Return the normal indentation column for a sexp.
Point should be after the open paren of the _enclosing_ sexp, and
@@ -1361,19 +1396,22 @@ accepted by `clojure-indent-style'."
;; Here we have reached the start of the enclosing sexp (point is now at
;; the function name), so the behaviour depends on INDENT-MODE and on
;; whether there's also an argument on this line (case A or B).
- (let ((case-a ; The meaning of case-a is explained in `clojure-indent-style'.
+ (let ((indent-mode (if (keywordp indent-mode)
+ ;; needed for backwards compatibility
+ ;; as before clojure-mode 5.10 indent-mode was a keyword
+ (clojure--keyword-to-symbol indent-mode)
+ indent-mode))
+ (case-a ; The meaning of case-a is explained in `clojure-indent-style'.
(and last-sexp-start
(< last-sexp-start (line-end-position)))))
(cond
- ;; For compatibility with the old `clojure-defun-style-default-indent', any
- ;; value other than these 3 is equivalent to `always-body'.
- ((not (memq indent-mode '(:always-align :align-arguments nil)))
+ ((eq indent-mode 'always-indent)
(+ (current-column) lisp-body-indent -1))
;; There's an arg after the function name, so align with it.
(case-a (goto-char last-sexp-start)
(current-column))
;; Not same line.
- ((eq indent-mode :align-arguments)
+ ((eq indent-mode 'align-arguments)
(+ (current-column) lisp-body-indent -1))
;; Finally, just align with the function name.
(t (current-column)))))))
@@ -1445,7 +1483,7 @@ This function also returns nil meaning don't specify the indentation."
(+ lisp-body-indent containing-form-column))
;; Further non-special args, align with the arg above.
((> pos (1+ method))
- (clojure--normal-indent last-sexp :always-align))
+ (clojure--normal-indent last-sexp 'always-align))
;; Special arg. Rigidly indent with a large indentation.
(t
(+ (* 2 lisp-body-indent) containing-form-column)))))
@@ -1459,8 +1497,8 @@ This function also returns nil meaning don't specify the indentation."
(cond
;; Preserve useful alignment of :require (and friends) in `ns' forms.
((and function (string-match "^:" function))
- (clojure--normal-indent last-sexp :always-align))
- ;; This is should be identical to the :defn above.
+ (clojure--normal-indent last-sexp 'always-align))
+ ;; This should be identical to the :defn above.
((and function
(string-match "\\`\\(?:\\S +/\\)?\\(def[a-z]*\\|with-\\)"
function)
@@ -1689,6 +1727,10 @@ Return nil if not inside a project."
(when (> (length choices) 0)
(car (sort choices #'file-in-directory-p)))))
+;; project.el integration
+(cl-defmethod project-roots ((project (head clojure)))
+ (list (cdr project)))
+
(defun clojure-project-relative-path (path)
"Denormalize PATH by making it relative to the project root."
(file-relative-name path (clojure-project-dir)))
@@ -1949,8 +1991,7 @@ This will skip over sexps that don't represent objects, so that ^hints and
"Return truthy if the first form matches FIRST-FORM."
(condition-case nil
(save-excursion
- (end-of-defun)
- (clojure-backward-logical-sexp 1)
+ (beginning-of-defun)
(forward-char 1)
(clojure-forward-logical-sexp 1)
(clojure-backward-logical-sexp 1)
@@ -1980,7 +2021,7 @@ change this heuristic it needs to be bullet-proof and desired. While
testing, give an easy way to turn this new behavior off."
:type 'boolean
:safe #'booleanp
- :package-version '(clojure-mode . "5.8.3"))
+ :package-version '(clojure-mode . "5.9.0"))
(defun clojure-find-first (pred coll)
"Find first element of COLL for which PRED return truthy."
@@ -2001,21 +2042,24 @@ many times."
(let ((beginning-of-defun-function nil))
(if (and clojure-toplevel-inside-comment-form
(clojure-top-level-form-p "comment"))
- (save-match-data
- (let ((original-position (point))
- clojure-comment-start clojure-comment-end)
- (end-of-defun)
- (setq clojure-comment-end (point))
- (clojure-backward-logical-sexp 1) ;; beginning of comment form
- (setq clojure-comment-start (point))
- (forward-char 1) ;; skip paren so we start at comment
- (clojure-forward-logical-sexp) ;; skip past the comment form itself
- (if-let ((sexp-start (clojure-find-first (lambda (beg-pos)
- (< beg-pos original-position))
- (clojure-sexp-starts-until-position
- clojure-comment-end))))
- (progn (goto-char sexp-start) t)
- (beginning-of-defun n))))
+ (condition-case nil
+ (save-match-data
+ (let ((original-position (point))
+ clojure-comment-start clojure-comment-end)
+ (beginning-of-defun)
+ (setq clojure-comment-start (point))
+ (end-of-defun)
+ (setq clojure-comment-end (point))
+ (beginning-of-defun)
+ (forward-char 1) ;; skip paren so we start at comment
+ (clojure-forward-logical-sexp) ;; skip past the comment form itself
+ (if-let ((sexp-start (clojure-find-first (lambda (beg-pos)
+ (< beg-pos original-position))
+ (clojure-sexp-starts-until-position
+ clojure-comment-end))))
+ (progn (goto-char sexp-start) t)
+ (beginning-of-defun n))))
+ (scan-error (beginning-of-defun n)))
(beginning-of-defun n))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2591,11 +2635,12 @@ lists up."
;;;###autoload
(defun clojure-let-backward-slurp-sexp (&optional n)
"Slurp the s-expression before the let form into the let form.
-With a numberic prefix argument slurp the previous N s-expression into the let form."
+With a numberic prefix argument slurp the previous N s-expression
+into the let form."
(interactive "p")
- (unless n (setq n 1))
- (dotimes (k n)
- (save-excursion (clojure--let-backward-slurp-sexp-internal))))
+ (let ((n (or n 1)))
+ (dotimes (_ n)
+ (save-excursion (clojure--let-backward-slurp-sexp-internal)))))
(defun clojure--let-forward-slurp-sexp-internal ()
"Slurp the next s-expression after the let form into the let form."
diff --git a/test/clojure-mode-font-lock-test.el b/test/clojure-mode-font-lock-test.el
index 69f5bf6..f97c30f 100644
--- a/test/clojure-mode-font-lock-test.el
+++ b/test/clojure-mode-font-lock-test.el
@@ -347,9 +347,10 @@ POS."
;; type-hint
(should (eq (clojure-test-face-at 1 2 "#^ve/yCom|pLex.stu-ff") 'default))
- (should (eq (clojure-test-face-at 3 4 "#^ve/yCom|pLex.stu-ff")
- 'font-lock-type-face))
+ (should (eq (clojure-test-face-at 3 4 "#^ve/yCom|pLex.stu-ff") 'font-lock-type-face))
(should (eq (clojure-test-face-at 5 21 "#^ve/yCom|pLex.stu-ff") 'default))
+ (should (eq (clojure-test-face-at 2 3 "^ve/yCom|pLex.stu-ff") 'font-lock-type-face))
+ (should (eq (clojure-test-face-at 5 20 "^ve/yCom|pLex.stu-ff") 'default))
(should (eq (clojure-test-face-at 3 4 " (ve/yCom|pLex.stu-ff)")
'font-lock-type-face))
diff --git a/test/clojure-mode-indentation-test.el b/test/clojure-mode-indentation-test.el
index 71e4ab5..7c71f11 100644
--- a/test/clojure-mode-indentation-test.el
+++ b/test/clojure-mode-indentation-test.el
@@ -58,7 +58,7 @@ values of customisable variables."
(let ((fname (intern (format "indentation/%s" description))))
`(ert-deftest ,fname ()
(let* ((after ,after)
- (clojure-indent-style :always-align)
+ (clojure-indent-style 'always-align)
(expected-cursor-pos (1+ (s-index-of "|" after)))
(expected-state (delete ?| after))
,@var-bindings)
@@ -238,7 +238,7 @@ values of customisable variables."
(declare (indent 1))
(when (stringp style)
(setq forms (cons style forms))
- (setq style :always-align))
+ (setq style '(quote always-align)))
`(ert-deftest ,(intern (format "test-backtracking-%s" name)) ()
(progn
,@(mapcar (lambda (form)
@@ -421,7 +421,9 @@ values of customisable variables."
(def-full-indent-test let-when-while-forms
"(let-alist [x 1]\n ())"
"(while-alist [x 1]\n ())"
- "(when-alist [x 1]\n ())")
+ "(when-alist [x 1]\n ())"
+ "(if-alist [x 1]\n ())"
+ "(indents-like-fn-when-let-while-if-are-not-the-start [x 1]\n ())")
(defun indent-cond (indent-point state)
(goto-char (elt state 1))
@@ -461,7 +463,7 @@ x
3))")
(def-full-indent-test align-arguments
- :align-arguments
+ 'align-arguments
"(some-function
10
1
@@ -471,7 +473,7 @@ x
2)")
(def-full-indent-test always-indent
- :always-indent
+ 'always-indent
"(some-function
10
1
@@ -485,7 +487,8 @@ x
"Verify that all FORMs correspond to a properly indented sexps."
(declare (indent defun))
`(ert-deftest ,(intern (format "test-align-%s" name)) ()
- (let ((clojure-align-forms-automatically t))
+ (let ((clojure-align-forms-automatically t)
+ (clojure-align-reader-conditionals t))
,@(mapcar (lambda (form)
`(with-temp-buffer
(clojure-mode)
@@ -596,6 +599,28 @@ x
:b {:a :a,
:aa :a}}")
+(def-full-align-test reader-conditional
+ "#?(:clj 2
+ :cljs 2)")
+
+(def-full-align-test reader-conditional-splicing
+ "#?@(:clj [2]
+ :cljs [2])")
+
+(ert-deftest reader-conditional-alignment-disabled-by-default ()
+ (let ((content "#?(:clj 2\n :cljs 2)"))
+ (with-temp-buffer
+ (clojure-mode)
+ (insert content)
+ (call-interactively #'clojure-align)
+ (should (string= (buffer-string) content)))
+ (with-temp-buffer
+ (clojure-mode)
+ (setq-local clojure-align-reader-conditionals t)
+ (insert content)
+ (call-interactively #'clojure-align)
+ (should-not (string= (buffer-string) content)))))
+
(ert-deftest clojure-align-remove-extra-commas ()
(with-temp-buffer
(clojure-mode)
diff --git a/test/clojure-mode-sexp-test.el b/test/clojure-mode-sexp-test.el
index 40f861c..a15a319 100644
--- a/test/clojure-mode-sexp-test.el
+++ b/test/clojure-mode-sexp-test.el
@@ -65,7 +65,15 @@ and point left there."
(wrong))"
(let ((clojure-toplevel-inside-comment-form t))
(beginning-of-defun))
- (should (looking-at-p "[[:space:]]*(right)"))))
+ (should (looking-at-p "[[:space:]]*(right)")))
+ (clojure-buffer-with-text
+ "
+(formA)
+|
+(formB)"
+ (let ((clojure-toplevel-inside-comment-form t))
+ (beginning-of-defun)
+ (should (looking-at-p "(formA)")))))
(ert-deftest test-clojure-end-of-defun-function ()
(clojure-buffer-with-text