From 30505fab277f871287c759278e17c1911edbfd5d Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Fri, 25 Nov 2022 16:28:46 -0700 Subject: upgrade vendored copy of Paredit to version 25 --- .emacs.d/initlibs/paredit.el | 155 +++++++++++++++++++++++++++++++------------ 1 file changed, 112 insertions(+), 43 deletions(-) diff --git a/.emacs.d/initlibs/paredit.el b/.emacs.d/initlibs/paredit.el index 737acc9f..563dbdfb 100644 --- a/.emacs.d/initlibs/paredit.el +++ b/.emacs.d/initlibs/paredit.el @@ -1,9 +1,9 @@ ;;; paredit.el --- minor mode for editing parentheses -*- Mode: Emacs-Lisp -*- -;; Copyright (C) 2005--2014 Taylor R. Campbell +;; Copyright (C) 2005--2022 Taylor R. Campbell -;; Author: Taylor R. Campbell -;; Version: 24 +;; Author: Taylor R. Campbell +;; Version: 25 ;; Created: 2005-07-31 ;; Keywords: lisp @@ -20,17 +20,11 @@ ;; You should have received a copy of the GNU General Public License ;; along with paredit. If not, see . -;;; The currently released version of paredit is available at -;;; . +;;; Paredit - https://paredit.org ;;; -;;; The latest beta version of paredit is available at -;;; . -;;; -;;; The Git repository for paredit is available at -;;; -;;; -;;; Release notes are available at -;;; . +;;; Latest release: https://paredit.org/paredit.el +;;; Current development version: https://paredit.org/paredit-beta.el +;;; Release notes: https://paredit.org/NEWS ;;; Install paredit by placing `paredit.el' in `/path/to/elisp', a ;;; directory of your choice, and adding to your .emacs file: @@ -43,7 +37,7 @@ ;;; Start Paredit Mode on the fly with `M-x enable-paredit-mode RET', ;;; or always enable it in a major mode `M' (e.g., `lisp') with: ;;; -;;; (add-hook M-mode-hook 'enable-paredit-mode) +;;; (add-hook 'M-mode-hook 'enable-paredit-mode) ;;; ;;; Customize paredit using `eval-after-load': ;;; @@ -53,7 +47,7 @@ ;;; 'paredit-dwim))) ;;; ;;; Send questions, bug reports, comments, feature suggestions, &c., -;;; via email to the author's surname at mumble.net. +;;; via email to the author's surname at paredit.org. ;;; ;;; Paredit should run in GNU Emacs 21 or later and XEmacs 21.5.28 or ;;; later. @@ -105,6 +99,16 @@ ;;; ;;; (foo (bar | baz) quux) C- (foo (bar | baz quux)) ;;; +;;; Note: Paredit Mode is not compatible with Electric Indent Mode. +;;; Use one or the other, not both. If you want RET to auto-indent and +;;; C-j to just insert newline in Paredit Mode, simply rebind the keys +;;; with the following fragment in your .emacs file: +;;; +;;; (eval-after-load 'paredit +;;; '(progn +;;; (define-key paredit-mode-map (kbd "RET") 'paredit-newline) +;;; (define-key paredit-mode-map (kbd "C-j") nil))) +;;; ;;; Some paredit commands automatically reindent code. When they do, ;;; they try to indent as locally as possible, to avoid interfering ;;; with any indentation you might have manually written. Only the @@ -118,7 +122,7 @@ ;;; This assumes Unix-style LF line endings. -(defconst paredit-version 24) +(defconst paredit-version 25) (defconst paredit-beta-p nil) (eval-and-compile @@ -188,11 +192,14 @@ If point was on indentation, it stays in indentation." ;;;; Minor Mode Definition +(defvar paredit-lighter " Paredit" + "Mode line lighter Paredit Mode.") + (defvar paredit-mode-map (make-sparse-keymap) "Keymap for the paredit minor mode.") (defvar paredit-override-check-parens-function - (lambda (condition) condition nil) + (lambda (condition) (declare ignore condition) nil) "Function to tell whether unbalanced text should inhibit Paredit Mode.") ;;;###autoload @@ -204,7 +211,7 @@ Paredit behaves badly if parentheses are unbalanced, so exercise caution when forcing Paredit Mode to be enabled, and consider fixing unbalanced parentheses instead. \\" - :lighter " Paredit" + :lighter paredit-lighter ;; Setting `paredit-mode' to false here aborts enabling Paredit Mode. (if (and paredit-mode (not current-prefix-arg)) @@ -320,11 +327,13 @@ Paredit behaves badly if parentheses are unbalanced, so exercise ("|(defun hello-world ...)" ";;; |\n(defun hello-world ...)")) - ("C-j" paredit-newline + (() paredit-newline ("(let ((n (frobbotz))) |(display (+ n 1)\nport))" ,(concat "(let ((n (frobbotz)))" "\n |(display (+ n 1)" "\n port))"))) + ("RET" paredit-RET) + ("C-j" paredit-C-j) "Deleting & Killing" (("C-d" ,@paredit-forward-delete-keys) @@ -764,17 +773,16 @@ If such a comment exists, delete the comment (including all leading "List of predicates for whether to put space by delimiter at point. Each predicate is a function that is is applied to two arguments, ENDP and DELIMITER, and that returns a boolean saying whether to put a - space next to the delimiter -- before the delimiter if ENDP is false, - after the delimiter if ENDP is true. + space next to the delimiter -- before/after the delimiter if ENDP is + false/true, respectively. If any predicate returns false, no space is inserted: every predicate has veto power. -Each predicate may assume that the point is not at the beginning of the - buffer, if ENDP is false, or at the end of the buffer, if ENDP is - true; and that the point is not preceded, if ENDP is false, or - followed, if ENDP is true, by a word or symbol constituent, a quote, - or the delimiter matching DELIMITER. -Each predicate should examine only text before the point, if ENDP is - false, or only text after the point, if ENDP is true.") +Each predicate may assume that the point is not at the beginning/end of + the buffer, and that the point is preceded/followed by a word + constituent, symbol constituent, string quote, or delimiter matching + DELIMITER, if ENDP is false/true, respectively. +Each predicate should examine only text before/after the point if ENDP is + false/true, respectively.") (defun paredit-space-for-delimiter-p (endp delimiter) ;; If at the buffer limit, don't insert a space. If there is a word, @@ -957,7 +965,7 @@ If not in a string, act as `paredit-doublequote'; if not prefix argument ;; -- then delete the backslash to avoid a dangling escape. (let ((delete-p t)) (unwind-protect - (let ((char (read-char "Character to escape: "))) + (let ((char (read-char "Character to escape: " t))) (if (not (eq char ?\^?)) (progn (message "Character to escape: %c" char) (insert char) @@ -991,6 +999,43 @@ If in a comment and if followed by invalid structure, call ;; Indent the following S-expression, but don't signal an ;; error if there's only a closing delimiter after the point. (paredit-ignore-sexp-errors (indent-sexp))))) + +(defun paredit-electric-indent-mode-p () + "True if Electric Indent Mode is on, false if not. +Electric Indent Mode is generally not compatible with paredit and + users are advised to disable it, since paredit does essentially + everything it tries to do better. +However, to mitigate the negative user experience of combining + Electric Indent Mode with paredit, the default key bindings for + RET and C-j in paredit are exchanged depending on whether + Electric Indent Mode is enabled." + (and (boundp 'electric-indent-mode) + electric-indent-mode)) + +(defun paredit-RET () + "Default key binding for RET in Paredit Mode. +Normally, inserts a newline, like traditional Emacs RET. +With Electric Indent Mode enabled, inserts a newline and indents + the new line, as well as any subexpressions of it on subsequent + lines." + (interactive) + (if (paredit-electric-indent-mode-p) + (let ((electric-indent-mode nil)) + (paredit-newline)) + (newline))) + +(defun paredit-C-j () + "Default key binding for C-j in Paredit Mode. +Normally, inserts a newline and indents + the new line, as well as any subexpressions of it on subsequent + lines. +With Electric Indent Mode enabled, inserts a newline, like + traditional Emacs RET." + (interactive) + (if (paredit-electric-indent-mode-p) + (let ((electric-indent-mode nil)) + (newline)) + (paredit-newline))) (defun paredit-reindent-defun (&optional argument) "Reindent the definition that the point is on. @@ -999,7 +1044,9 @@ If the point is in a string or a comment, fill the paragraph instead, (interactive "P") (if (or (paredit-in-string-p) (paredit-in-comment-p)) - (lisp-fill-paragraph argument) + (if (memq fill-paragraph-function '(t nil)) + (lisp-fill-paragraph argument) + (funcall fill-paragraph-function argument)) (paredit-preserving-column (save-excursion (end-of-defun) @@ -1101,6 +1148,15 @@ If a list begins on the line after the point but ends on a different (defalias 'paredit-initialize-comment-dwim 'comment-normalize-vars) (comment-normalize-vars)) +(defvar paredit-comment-prefix-toplevel ";;; " + "String of prefix for top-level comments aligned at the left margin.") + +(defvar paredit-comment-prefix-code ";; " + "String of prefix for comments indented at the same depth as code.") + +(defvar paredit-comment-prefix-margin ";" + "String of prefix for comments on the same line as code in the margin.") + (defun paredit-comment-dwim (&optional argument) "Call the Lisp comment command you want (Do What I Mean). This is like `comment-dwim', but it is specialized for Lisp editing. @@ -1162,13 +1218,13 @@ This is expected to be called only in `paredit-comment-dwim'; do not (and indent (zerop indent)))) ;; Top-level comment (if code-after-p (save-excursion (newline))) - (insert ";;; ")) + (insert paredit-comment-prefix-toplevel)) ((or code-after-p (not code-before-p)) ;; Code comment (if code-before-p (newline-and-indent) (lisp-indent-line)) - (insert ";; ") + (insert paredit-comment-prefix-code) (if code-after-p (save-excursion (newline) @@ -1177,7 +1233,7 @@ This is expected to be called only in `paredit-comment-dwim'; do not (t ;; Margin comment (indent-to comment-column 1) ; 1 -> force one leading space - (insert ?\; ))))) + (insert paredit-comment-prefix-margin))))) ;;;; Character Deletion @@ -2131,17 +2187,22 @@ If the point is on an S-expression, such as a string or a symbol, not between them, that S-expression is considered to follow the point." (interactive "P") (save-excursion - (cond ((paredit-in-string-p) - (goto-char (car (paredit-string-start+end-points)))) - ((paredit-in-char-p) - (backward-sexp)) - ((paredit-in-comment-p) - (error "No S-expression to raise in comment."))) ;; Select the S-expressions we want to raise in a buffer substring. - (let* ((n (prefix-numeric-value argument)) - (bound (scan-sexps (point) n)) + (let* ((bound + (if (and (not argument) (paredit-region-active-p)) + (progn (if (< (mark) (point)) + (paredit-check-region (mark) (point)) + (paredit-check-region (point) (mark))) + (mark)) + (cond ((paredit-in-string-p) + (goto-char (car (paredit-string-start+end-points)))) + ((paredit-in-char-p) + (backward-sexp)) + ((paredit-in-comment-p) + (error "No S-expression to raise in comment."))) + (scan-sexps (point) (prefix-numeric-value argument)))) (sexps - (if (< n 0) + (if (< bound (point)) (buffer-substring bound (paredit-point-at-sexp-end)) (buffer-substring (paredit-point-at-sexp-start) bound)))) ;; Move up to the list we're raising those S-expressions out of and @@ -2150,7 +2211,15 @@ If the point is on an S-expression, such as a string or a symbol, not (delete-region (point) (scan-sexps (point) 1)) (let* ((indent-start (point)) (indent-end (save-excursion (insert sexps) (point)))) - (indent-region indent-start indent-end nil))))) + ;; If the expression spans multiple lines, its indentation is + ;; probably broken, so reindent it -- but don't reindent + ;; anything that we didn't touch outside the expression. + ;; + ;; XXX What if the *column* of the starting point was preserved + ;; too? Should we avoid reindenting in that case? + (if (not (eq (save-excursion (goto-char indent-start) (point-at-eol)) + (save-excursion (goto-char indent-end) (point-at-eol)))) + (indent-region indent-start indent-end nil)))))) ;;; The effects of convolution on the surrounding whitespace are pretty ;;; random. If you have better suggestions, please let me know. -- cgit v1.2.3