From 994168240aa3d81cb42cef2f049fec5739f9d850 Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Sun, 15 Mar 2015 00:17:05 -0700 Subject: [PATCH] Support indenting backquote substitutions in cl-indent * lisp/emacs-lisp/cl-indent.el (lisp-indent-backquote-substitution-mode): New user option. (common-lisp-indent-function-1, common-lisp-loop-part-indentation) (common-lisp-indent-function): Support normally indenting backquote substitutions. (extended-loop-p): Rename to `lisp-extended-loop-p'. --- lisp/ChangeLog | 9 ++++++ lisp/emacs-lisp/cl-indent.el | 62 +++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a9cf1b0f88f..fb2291c534c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,12 @@ +2015-03-15 Daniel Colascione + + * emacs-lisp/cl-indent.el + (lisp-indent-backquote-substitution-mode): New user option. + (common-lisp-indent-function-1, common-lisp-loop-part-indentation) + (common-lisp-indent-function): Support normally indenting + backquote substitutions. + (extended-loop-p): Rename to `lisp-extended-loop-p'. + 2015-03-14 Michael R. Mauger * progmodes/sql.el: Version 3.5 diff --git a/lisp/emacs-lisp/cl-indent.el b/lisp/emacs-lisp/cl-indent.el index 1bcfb6df2cf..5e75406cf22 100644 --- a/lisp/emacs-lisp/cl-indent.el +++ b/lisp/emacs-lisp/cl-indent.el @@ -138,6 +138,19 @@ If non-nil, alignment is done with the first parameter :type 'boolean :group 'lisp-indent) +(defcustom lisp-indent-backquote-substitution-mode t + "How to indent substitutions in backquotes. +If `t', the default, indent substituted forms normally. +If `nil', do not apply special indentation rule to substituted +forms. If `corrected', subtract the `,' or `,@' from the form +column, indenting as if this character sequence were not present. +In any case, do not backtrack beyond a backquote substitution. + +Until Emacs 25.1, the `nil' behavior was hard-wired." + :version "25.1" + :type '(choice (const corrected) (const nil) (const t)) + :group 'lisp-indent) + (defvar lisp-indent-defun-method '(4 &lambda &body) "Defun-like indentation method. @@ -145,7 +158,7 @@ This applies when the value of the `common-lisp-indent-function' property is set to `defun'.") -(defun extended-loop-p (loop-start) +(defun lisp-extended-loop-p (loop-start) "True if an extended loop form starts at LOOP-START." (condition-case () (save-excursion @@ -170,11 +183,22 @@ the standard lisp indent package." "Compute the indentation of loop form constituents." (let* ((loop-indentation (save-excursion (goto-char (elt state 1)) - (current-column)))) + (current-column)))) + (when (and (eq lisp-indent-backquote-substitution-mode 'corrected)) + (save-excursion + (goto-char (elt state 1)) + (incf loop-indentation + (cond ((eq (char-before) ?,) -1) + ((and (eq (char-before) ?@) + (progn (backward-char) + (eq (char-before) ?,))) + -2) + (t 0))))) + (goto-char indent-point) (beginning-of-line) (list - (cond ((not (extended-loop-p (elt state 1))) + (cond ((not (lisp-extended-loop-p (elt state 1))) (+ loop-indentation lisp-simple-loop-indentation)) ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)") (+ loop-indentation lisp-loop-keyword-indentation)) @@ -264,9 +288,15 @@ at `common-lisp-indent-function' and, if set, use its value instead." ;; FIXME: why do we need to special-case loop? (if (save-excursion (goto-char (elt state 1)) - (looking-at (if (derived-mode-p 'emacs-lisp-mode) - "(\\(cl-\\)?[Ll][Oo][Oo][Pp]" - "([Ll][Oo][Oo][Pp]"))) + (and (looking-at (if (derived-mode-p 'emacs-lisp-mode) + "(\\(cl-\\)?loop" + "([Ll][Oo][Oo][Pp]")) + (or lisp-indent-backquote-substitution-mode + (not + (or (and (eq (char-before) ?@) + (progn (backward-char) + (eq (char-before) ?,))) + (eq (char-before) ?,)))))) (common-lisp-loop-part-indentation indent-point state) (common-lisp-indent-function-1 indent-point state))) @@ -373,11 +403,21 @@ instead." (not (eq (char-after (- containing-sexp 2)) ?\#))) ;; No indentation for "'(...)" elements (setq calculated (1+ sexp-column))) - ((or (eq (char-after (1- containing-sexp)) ?\,) - (and (eq (char-after (1- containing-sexp)) ?\@) - (eq (char-after (- containing-sexp 2)) ?\,))) - ;; ",(...)" or ",@(...)" - (setq calculated normal-indent)) + ((when + (or (eq (char-after (1- containing-sexp)) ?\,) + (and (eq (char-after (1- containing-sexp)) ?\@) + (eq (char-after (- containing-sexp 2)) ?\,))) + ;; ",(...)" or ",@(...)" + (when (eq lisp-indent-backquote-substitution-mode + 'corrected) + (incf sexp-column -1) + (when (eq (char-after (1- containing-sexp)) ?\@) + (incf sexp-column -1))) + (cond (lisp-indent-backquote-substitution-mode + (setf tentative-calculated normal-indent) + (setq depth lisp-indent-maximum-backtracking) + nil) + (t (setq calculated normal-indent))))) ((eq (char-after (1- containing-sexp)) ?\#) ;; "#(...)" (setq calculated (1+ sexp-column))) -- 2.39.2