Skip to content

Commit

Permalink
feat(barf): move the point with the barfed delimiter
Browse files Browse the repository at this point in the history
Fix #918
  • Loading branch information
Fuco1 committed Jan 18, 2023
1 parent 6cd739a commit 219da72
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 12 deletions.
1 change: 1 addition & 0 deletions smartparens-ruby.el
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ ID, ACTION, CONTEXT."
ID, ACTION, CONTEXT."
(-let (((&plist :arg arg :enc enc) sp-handler-context))
(when (equal action 'barf-backward)
(goto-char (sp-get enc :beg))
(sp-ruby-delete-indentation 1)
(indent-according-to-mode)
(save-excursion
Expand Down
38 changes: 33 additions & 5 deletions smartparens.el
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,14 @@ position (before or after the region).
:group 'smartparens)

;; navigation & manip custom
(defcustom sp-barf-move-point-with-delimiter t
"If non-nil, move point when it would end outside the sexp after barf.

This way, a barf operation can be immediately followed by an
opposite slurp to undo it."
:type 'boolean
:group 'smartparens)

(defcustom sp-navigate-consider-sgml-tags '(
html-mode
)
Expand Down Expand Up @@ -7386,6 +7394,11 @@ closing delimiter of the list.

If the current list is empty, do nothing.

If the setting `sp-barf-move-point-with-delimiter' is non-nil,
move the point together with the closing delimiter if the point
would end up outside of the enclosing sexp. This way the barf
can be always followed by a slurp to undo the change.

Examples: (prefix arg in comment)

(foo bar| baz) -> (foo bar|) baz ;; nil (defaults to 1)
Expand All @@ -7398,7 +7411,8 @@ Examples: (prefix arg in comment)
(interactive "P")
(let* ((raw (sp--raw-argument-p arg))
(old-arg arg)
(arg (prefix-numeric-value arg)))
(arg (prefix-numeric-value arg))
(new-cl-position nil))
(if (> arg 0)
(if (sp-point-in-blank-sexp)
(sp-message :blank-sexp)
Expand All @@ -7425,8 +7439,12 @@ Examples: (prefix arg in comment)
(sp-do-move-cl (point))
(sp--keep-indentation
(sp--indent-region :beg :end))
(setq new-cl-position (- (point) :cl-l))
(sp--run-hook-with-args :op :post-handlers 'barf-forward
(list :arg arg :enc enc))))))
(list :arg arg :enc enc)))))
(when (and sp-barf-move-point-with-delimiter
(< new-cl-position (point)))
(goto-char new-cl-position)))
(sp-backward-barf-sexp (sp--negate-argument old-arg)))))

(defun sp-backward-barf-sexp (&optional arg)
Expand All @@ -7445,7 +7463,8 @@ Examples:
(interactive "P")
(let* ((raw (sp--raw-argument-p arg))
(old-arg arg)
(arg (prefix-numeric-value arg)))
(arg (prefix-numeric-value arg))
(new-cl-position nil))
(if (> arg 0)
(if (sp-point-in-blank-sexp)
(sp-message :blank-sexp)
Expand All @@ -7469,10 +7488,19 @@ Examples:
(sp--run-hook-with-args :op :pre-handlers 'barf-backward
(list :arg arg :enc enc)))
(sp-get (sp-get-enclosing-sexp)
(sp-do-move-op (point))
;; make sure that we end up on the same place, since
;; sp-do-move-op might move the point to the start of
;; the previous sexp (the one barfed out)
(save-excursion (sp-do-move-op (point)))
;; skip the opening to end up inside the sexp
(forward-char (+ :op-l :prefix-l))
(sp--indent-region :beg :end)
(setq new-cl-position (point))
(sp--run-hook-with-args :op :post-handlers 'barf-backward
(list :arg arg :enc enc))))))
(list :arg arg :enc enc)))))
(when (and sp-barf-move-point-with-delimiter
(> new-cl-position (point)))
(goto-char new-cl-position)))
(sp-forward-barf-sexp (sp--negate-argument old-arg)))))

;; TODO: get rid of the macro anyway, it's stupid!
Expand Down
57 changes: 57 additions & 0 deletions test/smartparens-barf-test.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
(require 'smartparens)

(ert-deftest sp-test-sp-forward-barf-sexp-634 ()
(let ((sp-barf-move-point-with-delimiter nil))
(sp-test-with-temp-elisp-buffer "(let ((a 4)\n ;; (fail)\n |(+ 1)\n ))\n"
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(let ((a 4))\n ;; (fail)\n (+ 1)\n )\n")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(let ((a 4)))\n;; (fail)\n|(+ 1)\n\n"))))

(ert-deftest sp-test-sp-forward-barf-918-move-point-with-closing-enabled ()
(let ((sp-barf-move-point-with-delimiter t))
(sp-test-with-temp-elisp-buffer "(hello world\n\n | what\n is this)"
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(hello world\n\n | what\n is) this")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(hello world\n\n | what)\nis this")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(hello world|)\n\nwhat\nis this"))))

(ert-deftest sp-test-sp-forward-barf-918-move-point-with-closing-disabled ()
(let ((sp-barf-move-point-with-delimiter nil))
(sp-test-with-temp-elisp-buffer "(hello world\n\n | what\n is this)"
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(hello world\n\n | what\n is) this")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(hello world\n\n | what)\nis this")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(hello world)\n\n|what\nis this"))))

(ert-deftest sp-test-sp-backward-barf-918-move-point-with-opening-enabled ()
(let ((sp-barf-move-point-with-delimiter t))
(sp-test-with-temp-elisp-buffer "(hello world\n\n | what\n is this)"
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello (world\n\n | what\n is this)")
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello world\n\n(|what\n is this)")
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello world\n\nwhat\n(|is this)"))))

(ert-deftest sp-test-sp-backward-barf-918-move-point-with-opening-enabled-with-prefix ()
(let ((sp-barf-move-point-with-delimiter t))
(sp-test-with-temp-elisp-buffer ",@(hello world\n\n | what\n is this)"
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello ,@(world\n\n | what\n is this)")
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello world\n\n,@(|what\n is this)")
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello world\n\nwhat\n,@(|is this)"))))

(ert-deftest sp-test-sp-backward-barf-918-move-point-with-opening-disabled ()
(let ((sp-barf-move-point-with-delimiter nil))
(sp-test-with-temp-elisp-buffer "(hello world\n\n | what\n is this)"
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello (world\n\n | what\n is this)")
(call-interactively 'sp-backward-barf-sexp)
(sp-buffer-equals "hello world\n\n|(what\n is this)"))))
7 changes: 0 additions & 7 deletions test/smartparens-commands-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -1023,10 +1023,3 @@ This is the behavior of `paredit-convolute-sexp'."
(sp-buffer-equals "(foo)
(progn
|(bar))"))))

(ert-deftest sp-test-sp-forward-barf-sexp-634 ()
(sp-test-with-temp-elisp-buffer "(let ((a 4)\n ;; (fail)\n |(+ 1)\n ))\n"
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(let ((a 4))\n ;; (fail)\n (+ 1)\n )\n")
(call-interactively 'sp-forward-barf-sexp)
(sp-buffer-equals "(let ((a 4)))\n;; (fail)\n|(+ 1)\n\n")))

0 comments on commit 219da72

Please sign in to comment.