summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/lisp-mode.el70
1 files changed, 70 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index b0f823e0103..ca464984613 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -102,6 +102,7 @@
()
(setq shared-lisp-mode-map (make-sparse-keymap))
(define-key shared-lisp-mode-map "\e\C-q" 'indent-sexp)
+ (define-key shared-lisp-mode-map "\M-q" 'lisp-fill-paragraph)
(define-key shared-lisp-mode-map "\177" 'backward-delete-char-untabify)
(define-key shared-lisp-mode-map "\t" 'lisp-indent-line))
@@ -593,6 +594,75 @@ ENDPOS is encountered."
(indent-sexp endmark)
(set-marker endmark nil))))
+;;;; Lisp paragraph filling commands.
+
+(defun lisp-fill-paragraph (&optional justify)
+ "Like \\[fill-paragraph], but handle Emacs Lisp comments.
+If any of the current line is a comment, fill the comment or the
+paragraph of it that point is in, preserving the comment's indentation
+and initial semicolons."
+ (interactive "P")
+ (let (
+ ;; Non-nil if the current line contains a comment.
+ has-comment
+
+ ;; If has-comment, the appropriate fill-prefix for the comment.
+ comment-fill-prefix
+ )
+
+ ;; Figure out what kind of comment we are looking at.
+ (save-excursion
+ (beginning-of-line)
+ (cond
+
+ ;; A line with nothing but a comment on it?
+ ((looking-at "[ \t]*;[; \t]*")
+ (setq has-comment t
+ comment-fill-prefix (buffer-substring (match-beginning 0)
+ (match-end 0))))
+
+ ;; A line with some code, followed by a comment? Remember that the
+ ;; semi which starts the comment shouldn't be part of a string or
+ ;; character.
+ ((progn
+ (while (not (looking-at ";\\|$"))
+ (skip-chars-forward "^;\n\"\\\\?")
+ (cond
+ ((eq (char-after (point)) ?\\) (forward-char 2))
+ ((memq (char-after (point)) '(?\" ??)) (forward-sexp 1))))
+ (looking-at ";+[\t ]*"))
+ (setq has-comment t)
+ (setq comment-fill-prefix
+ (concat (make-string (current-column) ? )
+ (buffer-substring (match-beginning 0) (match-end 0)))))))
+
+ (if (not has-comment)
+ (fill-paragraph justify)
+
+ ;; Narrow to include only the comment, and then fill the region.
+ (save-restriction
+ (narrow-to-region
+ ;; Find the first line we should include in the region to fill.
+ (save-excursion
+ (while (and (zerop (forward-line -1))
+ (looking-at "^[ \t]*;")))
+ ;; We may have gone to far. Go forward again.
+ (or (looking-at "^[ \t]*;")
+ (forward-line 1))
+ (point))
+ ;; Find the beginning of the first line past the region to fill.
+ (save-excursion
+ (while (progn (forward-line 1)
+ (looking-at "^[ \t]*;")))
+ (point)))
+
+ ;; Lines with only semicolons on them can be paragraph boundaries.
+ (let ((paragraph-start (concat paragraph-start "\\|^[ \t;]*$"))
+ (paragraph-separate (concat paragraph-start "\\|^[ \t;]*$"))
+ (fill-prefix comment-fill-prefix))
+ (fill-paragraph justify))))))
+
+
(defun indent-code-rigidly (start end arg &optional nochange-regexp)
"Indent all lines of code, starting in the region, sideways by ARG columns.
Does not affect lines starting inside comments or strings, assuming that