From 66910f84422f0a4e89f1880730fe889d34c690f8 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 3 Jan 2022 11:32:00 -0500 Subject: [PATCH] Make it possible to get uniform indentation While Emacs and clojure-mode have good support for "lisp-style" indentation, and provided fine-grained customization via indent-specs, some prefer "dumb" indentation where every single form gets the same level of indent, regardless of whether it's a macro, whether there are arguments on the same line as the function name, etc. Currently this is not possible without redefining certain functions because of hard-coded values that handle specific cases, namely the indent-spec case, and the keyword invocation case (`(:require ...)`). This introduces two new defcustoms, one allows completely disabling the indent-spec handling, so the first hard-coded case is skipped, the second allows specifically customizing the second case. This should allow "tonsky style" formatting with ``` (setq clojure-indent-style 'always-indent clojure-indent-keyword-style 'always-indent clojure-enable-indent-specs nil) ``` --- clojure-mode.el | 60 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/clojure-mode.el b/clojure-mode.el index 0c782b49..a879c1d2 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -100,6 +100,8 @@ (defcustom clojure-indent-style 'always-align "Indentation style to use for function forms and macro forms. +For forms that start with a keyword see `clojure-indent-keyword-style'. + There are two cases of interest configured by this variable. - Case (A) is when at least one function argument is on the same @@ -147,6 +149,51 @@ to indent function forms. 'align-arguments)) :package-version '(clojure-mode . "5.2.0")) +(defcustom clojure-indent-keyword-style 'always-align + "Indentation style to use for forms that start with a keyword. +For function/macro forms, see `clojure-indent-style'. +There are two cases of interest configured by this variable. + +- Case (A) is when at least one argument following the keyword is + on the same line as the keyword. +- Case (B) is the opposite (no arguments are on the same line as + the keyword). + +The possible values for this variable are keywords indicating how +to indent keyword invocation forms. + + `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: + (:require [foo.bar] + [bar.baz]) + (:require + [foo.bar] + [bar.baz]) + + `always-indent' - All args are indented like a macro body. + (:require [foo.bar] + [bar.baz]) + (:x + location + 0) + + `align-arguments' - Case (A) is indented like `lisp', and + case (B) is indented like a macro body. + (:require [foo.bar] + [bar.baz]) + (:x + location + 0) + " + :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)) + :package-version '(clojure-mode . "5.14.0")) + (defcustom clojure-use-backtracking-indent t "When non-nil, enable context sensitive indentation." :type 'boolean @@ -1517,7 +1564,8 @@ This function also returns nil meaning don't specify the indentation." (1+ (current-column)) ;; Function or macro call. (forward-char 1) - (let ((method (clojure--find-indent-spec)) + (let ((method (and clojure-enable-indent-specs + (clojure--find-indent-spec))) (last-sexp calculate-lisp-indent-last-sexp) (containing-form-column (1- (current-column)))) (pcase method @@ -1554,7 +1602,7 @@ 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)) + (clojure--normal-indent last-sexp clojure-indent-keyword-style)) ;; This should be identical to the :defn above. ((and function (string-match "\\`\\(?:\\S +/\\)?\\(def[a-z]*\\|with-\\)" @@ -1633,6 +1681,14 @@ Requires the macro's NAME and a VALUE." (put-clojure-indent x 'defun)) value)) +(defcustom clojure-enable-indent-specs t + "Honor indent specs, either set via metadata on the +function/macro, or via `define-clojure-indent'. Set this to `nil' +to get uniform formatting of all forms." + :type 'boolean + :safe #'booleanp + :package-version '(clojure-mode . "5.14.0")) + (defcustom clojure-defun-indents nil "List of additional symbols with defun-style indentation in Clojure.