diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2019-01-10 08:39:18 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2019-01-10 08:39:18 -0700 |
commit | 99a77b2d8bd9e9721ff52b8a817ba50b74dd3fe8 (patch) | |
tree | 772f5355d5939a61d6a2fddbfb4b70c355495d13 | |
parent | 52096bd8c3c3834efe11ba0e8d3d7efaa85c5fa4 (diff) | |
parent | 1ccef7b2b7a063aa42416d1518e8e7228d90a78d (diff) |
Merge tag '5.10.0'
-rw-r--r-- | CHANGELOG.md | 18 | ||||
-rw-r--r-- | CONTRIBUTING.md | 15 | ||||
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | clojure-mode.el | 213 | ||||
-rw-r--r-- | test/clojure-mode-font-lock-test.el | 5 | ||||
-rw-r--r-- | test/clojure-mode-indentation-test.el | 37 | ||||
-rw-r--r-- | test/clojure-mode-sexp-test.el | 10 |
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/ @@ -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 |