From 5615023023aea50683f5725284fb9bc6cbbd64ec Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 24 Nov 2022 19:05:29 +0000 Subject: Work around Electric Indent Mode brokenness in newline keys. --- NEWS | 1 + paredit.el | 41 ++++++++++++++++++++++++++++++++++++++++- test.el | 32 +++++++++++++++++++++++++------- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 765f903..efc6c4e 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,7 @@ The latest version of this file is available at *** Reading character in Backslash escape now inherits input method. *** M-r (paredit-raise-sexp) no longer reindents single-line sexps. *** Various bug fixes and additions to test suite. +*** Worked around brokenness induced by Electric Indent Mode. ** Version 24 diff --git a/paredit.el b/paredit.el index b67b1bd..be45288 100644 --- a/paredit.el +++ b/paredit.el @@ -337,11 +337,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) @@ -1007,6 +1009,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. diff --git a/test.el b/test.el index bd8ae37..8e6ebe9 100644 --- a/test.el +++ b/test.el @@ -220,13 +220,31 @@ Four arguments: the paredit command, the text of the buffer (paredit-test 'paredit-wrap-sexp '(("(foo |bar baz)" "(foo (|bar baz))")))) -(paredit-test 'paredit-newline - '(("\"foo|bar\"" "\"foo\n|bar\"") - ("(frob grovel ;full |(lexical)\n mumble)" - "(frob grovel ;full\n |(lexical)\n mumble)") - ("(frob grovel ;full (|lexical)\n mumble)" - "(frob grovel ;full (\n ;|lexical)\n mumble)") - ("#\\|(" "#\\(\n|"))) +(let ((plain-newline-tests + '(("\"foo|bar\"" "\"foo\n|bar\"") + ("(frob grovel ;full |(lexical)\n mumble)" + "(frob grovel ;full \n|(lexical)\n mumble)") + ("(frob grovel ;full (|lexical)\n mumble)" + "(frob grovel ;full (\n|lexical)\n mumble)") + ("#\\|(" "#\\\n|("))) + (indented-newline-tests + '(("\"foo|bar\"" "\"foo\n|bar\"") + ("(frob grovel ;full |(lexical)\n mumble)" + "(frob grovel ;full\n |(lexical)\n mumble)") + ("(frob grovel ;full (|lexical)\n mumble)" + "(frob grovel ;full (\n ;|lexical)\n mumble)") + ("#\\|(" "#\\(\n|")))) + (if (boundp 'electric-indent-mode) + (progn + (let ((electric-indent-mode t)) + (paredit-test 'paredit-RET indented-newline-tests) + (paredit-test 'paredit-C-j plain-newline-tests)) + (let ((electric-indent-mode nil)) + (paredit-test 'paredit-RET plain-newline-tests) + (paredit-test 'paredit-C-j indented-newline-tests))) + (paredit-test 'paredit-RET plain-newline-tests) + (paredit-test 'paredit-C-j indented-newline-tests)) + (paredit-test 'paredit-newline indented-newline-tests)) (paredit-test 'paredit-reindent-defun ;++ Test filling paragraphs in comments and strings. -- cgit v1.2.1