Skip to content

Commit

Permalink
feat(lisp): insert space before opening paren after slurping
Browse files Browse the repository at this point in the history
This prevents some weirdly formatted code like (foo)(bar)
becomnig (foo(bar)) instead of (foo (bar))

Fixes Fuco1#781
  • Loading branch information
Fuco1 committed Jun 29, 2024
1 parent 36f2e80 commit 0fe32ac
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
12 changes: 12 additions & 0 deletions smartparens-config.el
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,21 @@ ID, ACTION, CONTEXT."
;; do not consider punctuation
(not (looking-at "[?.,;!]"))))))))

(defun sp-lisp-insert-space-after-slurp (_id action _context)
(-let (((&plist :ok-orig :next-thing) sp-handler-context))
(when (and (eq action 'slurp-forward)
(sp-get ok-orig (/= :beg-in :end-in)))
(save-excursion
(sp-get ok-orig (goto-char :end-in))
(skip-syntax-backward " ")
(unless (looking-at-p (rx (or whitespace eol)))
(insert " "))))))

;; emacs is lisp hacking environment, so we set up some most common
;; lisp modes too
(sp-with-modes sp-lisp-modes
(sp-local-pair "(" nil :post-handlers '(:add sp-lisp-insert-space-after-slurp))
(sp-local-pair "[" nil :post-handlers '(:add sp-lisp-insert-space-after-slurp))
;; disable ', it's the quote character!
(sp-local-pair "'" nil :actions nil))

Expand Down
12 changes: 9 additions & 3 deletions smartparens.el
Original file line number Diff line number Diff line change
Expand Up @@ -7362,7 +7362,12 @@ Examples:
(let ((n (abs (prefix-numeric-value arg)))
(enc (sp-get-enclosing-sexp))
(in-comment (sp-point-in-comment))
next-thing ok)
next-thing ok
;; At some places we mutate the value of `ok'
;; destructively (updating the end). The original value
;; is useful in the handlers for manipulating the
;; surroundings, so we copy it here.
ok-orig)
(when enc
(save-excursion
(if (sp--raw-argument-p arg)
Expand All @@ -7387,6 +7392,7 @@ Examples:
(goto-char (sp-get next-thing :end-suf))
(setq ok next-thing)
(setq next-thing (sp-get-thing nil)))
(setq ok-orig (copy-sequence ok))
;; do not allow slurping into a different context from
;; inside a comment
(if (and in-comment
Expand Down Expand Up @@ -7427,14 +7433,14 @@ Examples:
(insert " "))))
(sp--run-hook-with-args
(sp-get enc :op) :pre-handlers 'slurp-forward
(list :arg arg :enc enc :ok ok :next-thing next-thing))
(list :arg arg :enc enc :ok ok :ok-orig ok-orig :next-thing next-thing))
(sp-get ok (insert :cl :suffix))
(sp--indent-region (sp-get ok :beg-prf) (point))
;; HACK: update the "enc" data structure if ok==enc
(when (= (sp-get enc :beg) (sp-get ok :beg)) (plist-put enc :end (point)))
(sp--run-hook-with-args
(sp-get enc :op) :post-handlers 'slurp-forward
(list :arg arg :enc enc :ok ok :next-thing next-thing)))
(list :arg arg :enc enc :ok ok :ok-orig ok-orig :next-thing next-thing)))
(setq n (1- n)))
(sp-message :cant-slurp)
(setq n -1))))))))
Expand Down
51 changes: 51 additions & 0 deletions test/smartparens-elisp-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,54 @@ punctuation was considered invalid."
(sp-backward-delete-char)
(sp-backward-delete-char)
(sp-buffer-equals ";; `a-symbol-name'? I|")))

(prog1 "#781"
(ert-deftest sp-test-slurp-insert-space-for-style--next-sexp-paren-no-space ()
(sp-test-with-temp-elisp-buffer "(foo|)(bar)"
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| (bar))")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(foo|) (bar)")
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| (bar))")))

(ert-deftest sp-test-slurp-insert-space-for-style--next-sexp-paren-space ()
(sp-test-with-temp-elisp-buffer "(foo|) (bar)"
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| (bar))")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(foo|) (bar)")
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| (bar))")))

(ert-deftest sp-test-slurp-insert-space-for-style--next-sexp-symbol-no-space ()
(sp-test-with-temp-elisp-buffer "(foo|)bar"
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| bar)")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(foo|) bar")
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| bar)")))

(ert-deftest sp-test-slurp-insert-space-for-style--next-sexp-symbol-space ()
(sp-test-with-temp-elisp-buffer "(foo|) bar"
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| bar)")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(foo|) bar")
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo| bar)")))

(ert-deftest sp-test-slurp-insert-space-for-style--no-extra-space-from-empty-sexp ()
(sp-test-with-temp-elisp-buffer "(|)foo"
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(|foo)")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(|)foo")))

(ert-deftest sp-test-slurp-insert-space-for-style--next-on-new-line ()
(sp-test-with-temp-elisp-buffer "(foo|)\n(bar)"
(call-interactively 'sp-forward-slurp-sexp)
(sp-buffer-equals "(foo|\n (bar))")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(foo|)\n(bar)"))))

0 comments on commit 0fe32ac

Please sign in to comment.