aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/emacs-lisp/lisp-mode.el48
1 files changed, 44 insertions, 4 deletions
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 89d5659f300..54d916887cd 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -594,6 +594,7 @@ font-lock keywords will not be case sensitive."
594 ;; I believe that newcomment's auto-fill code properly deals with it -stef 594 ;; I believe that newcomment's auto-fill code properly deals with it -stef
595 ;;(set (make-local-variable 'adaptive-fill-mode) nil) 595 ;;(set (make-local-variable 'adaptive-fill-mode) nil)
596 (setq-local indent-line-function 'lisp-indent-line) 596 (setq-local indent-line-function 'lisp-indent-line)
597 (setq-local indent-region-function 'lisp-indent-region)
597 (setq-local outline-regexp ";;;\\(;* [^ \t\n]\\|###autoload\\)\\|(") 598 (setq-local outline-regexp ";;;\\(;* [^ \t\n]\\|###autoload\\)\\|(")
598 (setq-local outline-level 'lisp-outline-level) 599 (setq-local outline-level 'lisp-outline-level)
599 (setq-local add-log-current-defun-function #'lisp-current-defun-name) 600 (setq-local add-log-current-defun-function #'lisp-current-defun-name)
@@ -748,12 +749,51 @@ function is `common-lisp-indent-function'."
748 :type 'function 749 :type 'function
749 :group 'lisp) 750 :group 'lisp)
750 751
751(defun lisp-indent-line () 752(defun lisp-ppss (&optional pos)
753 "Return Parse-Partial-Sexp State at POS, defaulting to point.
754Like to `syntax-ppss' but includes the character address of the
755last complete sexp in the innermost containing list at position
7562 (counting from 0). This is important for lisp indentation."
757 (unless pos (setq pos (point)))
758 (let ((pss (syntax-ppss pos)))
759 (if (nth 9 pss)
760 (parse-partial-sexp (car (last (nth 9 pss))) pos)
761 pss)))
762
763(defun lisp-indent-region (start end)
764 "Indent region as Lisp code, efficiently."
765 (save-excursion
766 (setq end (copy-marker end))
767 (goto-char start)
768 ;; The default `indent-region-line-by-line' doesn't hold a running
769 ;; parse state, which forces each indent call to reparse from the
770 ;; beginning. That has O(n^2) complexity.
771 (let* ((parse-state (lisp-ppss start))
772 (last-syntax-point start)
773 (pr (unless (minibufferp)
774 (make-progress-reporter "Indenting region..." (point) end))))
775 (while (< (point) end)
776 (unless (and (bolp) (eolp))
777 (lisp-indent-line parse-state))
778 (forward-line 1)
779 (let ((last-sexp (nth 2 parse-state)))
780 (setq parse-state (parse-partial-sexp last-syntax-point (point)
781 nil nil parse-state))
782 ;; It's important to preserve last sexp location for
783 ;; `calculate-lisp-indent'.
784 (unless (nth 2 parse-state)
785 (setf (nth 2 parse-state) last-sexp))
786 (setq last-syntax-point (point)))
787 (and pr (progress-reporter-update pr (point))))
788 (and pr (progress-reporter-done pr))
789 (move-marker end nil))))
790
791(defun lisp-indent-line (&optional parse-state)
752 "Indent current line as Lisp code." 792 "Indent current line as Lisp code."
753 (interactive) 793 (interactive)
754 (let ((indent (calculate-lisp-indent)) 794 (let ((pos (- (point-max) (point)))
755 (pos (- (point-max) (point)))) 795 (indent (progn (beginning-of-line)
756 (beginning-of-line) 796 (calculate-lisp-indent (or parse-state (lisp-ppss))))))
757 (skip-chars-forward " \t") 797 (skip-chars-forward " \t")
758 (if (or (null indent) (looking-at "\\s<\\s<\\s<")) 798 (if (or (null indent) (looking-at "\\s<\\s<\\s<"))
759 ;; Don't alter indentation of a ;;; comment line 799 ;; Don't alter indentation of a ;;; comment line