Skip to content

Commit

Permalink
feat(show): make the preference rules for inside highlighting consistent
Browse files Browse the repository at this point in the history
Fixes #289
  • Loading branch information
Fuco1 committed Apr 3, 2024
1 parent 0ff3486 commit 3ed34cb
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 75 deletions.
20 changes: 13 additions & 7 deletions smartparens.el
Original file line number Diff line number Diff line change
Expand Up @@ -9524,7 +9524,11 @@ After the next command the pair will automatically disappear."

(defcustom sp-show-pair-from-inside nil
"If non-nil, highlight the enclosing pair if immediately after
the opening delimiter or before the closing delimiter."
the opening delimiter or before the closing delimiter.

This option does not disable highlighting of pairs from outside
the expression. If a pair can be highlighted from the outside,
it is preferred to the one highlighted from the inside."
:type 'boolean
:group 'show-smartparens)

Expand Down Expand Up @@ -9699,26 +9703,28 @@ matching paren in the echo area if not visible on screen."
(let* ((pair-list (sp--get-allowed-pair-list))
(opening (sp--get-opening-regexp pair-list))
(closing (sp--get-closing-regexp pair-list))
(allowed (and sp-show-pair-from-inside (sp--get-allowed-regexp))))
(allowed (sp--get-allowed-regexp pair-list))
(stringlike (sp--get-stringlike-regexp)))
(cond
;; if we are in a situation "()|", we should highlight the
;; regular pair and not the string pair "from inside"
((and (not (sp--evil-normal-state-p))
(not (sp--evil-motion-state-p))
(not (sp--evil-visual-state-p))
(sp--looking-back (if sp-show-pair-from-inside allowed closing)))
(sp--looking-back (if sp-show-pair-from-inside allowed closing))
(not (looking-at opening)))
(scan-and-place-overlays (match-string 0) :back))
((or (and (or (sp--evil-normal-state-p)
(sp--evil-motion-state-p)
(sp--evil-visual-state-p))
(sp--looking-at (sp--get-allowed-regexp)))
(sp--looking-at (if sp-show-pair-from-inside allowed opening))
(looking-at (sp--get-stringlike-regexp))
(looking-at allowed))
(looking-at (if sp-show-pair-from-inside allowed opening))
(looking-at stringlike)
(and (memq major-mode sp-navigate-consider-sgml-tags)
(looking-at "<")))
(scan-and-place-overlays (match-string 0)))
((or (sp--looking-back (if sp-show-pair-from-inside allowed closing))
(sp--looking-back (sp--get-stringlike-regexp))
(sp--looking-back stringlike)
(and (memq major-mode sp-navigate-consider-sgml-tags)
(sp--looking-back ">")))
(scan-and-place-overlays (match-string 0) :back))
Expand Down
161 changes: 93 additions & 68 deletions test/smartparens-show-mode-test.el
Original file line number Diff line number Diff line change
@@ -1,81 +1,106 @@
(require 'smartparens)
(require 'evil)

(defmacro sp-test--show-pairs (initial init-form &rest forms)
(declare (indent 2))
`(let ((sp-pairs
'((t .
((:open "\"" :close "\"" :actions (insert wrap autoskip navigate))
(:open "'" :close "'" :actions (insert wrap autoskip navigate))
(:open "$" :close "$" :actions (insert wrap autoskip navigate))
(:open "(" :close ")" :actions (insert wrap autoskip navigate))
(:open "[" :close "]" :actions (insert wrap autoskip navigate))
(:open "{" :close "}" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil))
(unwind-protect
(sp-test-with-temp-buffer ,initial
,init-form
(show-smartparens-mode 1)
(smartparens-mode 1)
(shut-up (sp-show--pair-function))
,@forms)
(sp-show--pair-delete-overlays))))

(defun sp-test--show-pairs-assert (result)
(let ((op-beg (plist-get result :op-beg))
(op-len (or (plist-get result :op-len) 1))
(cl-beg (plist-get result :cl-beg))
(cl-len (or (plist-get result :cl-len) 1))
(op (nth 0 sp-show-pair-overlays))
(cl (nth 2 sp-show-pair-overlays)))
(if (and (not op-beg) (not cl-beg))
(should (eq sp-show-pair-overlays nil))
(if (not op-beg)
(should (null op))
(should (not (null op)))
(should (= (overlay-start op) op-beg))
(should (= (overlay-end op) (+ op-beg op-len))))
(if (not cl-beg)
(should (null cl))
(should (not (null cl)))
(should (= (overlay-start cl) cl-beg))
(should (= (overlay-end cl) (+ cl-beg cl-len)))))))

(ert-deftest sp-test-show-mode-point-at-nonpairable-stringlike-delimiter-textmode ()
(let ((sp-pairs '((t . ((:open "\"" :close "\"" :actions (insert wrap autoskip navigate))
(:open "'" :close "'" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil))
(unwind-protect
(sp-test-with-temp-buffer "\"asdasd'| asdasd asd\""
(text-mode)
(show-smartparens-mode 1)
(sp-show--pair-function)
(should (eq sp-show-pair-overlays nil)))
(sp-show--pair-delete-overlays))))
(sp-test--show-pairs "\"asdasd'| asdasd asd\"" (text-mode)
(sp-test--show-pairs-assert nil)))

(ert-deftest sp-test-show-mode-point-at-beg-of-sexp ()
(let ((sp-pairs '((t . ((:open "(" :close ")" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil))
(unwind-protect
(sp-test-with-temp-elisp-buffer "|(foo bar)"
(show-smartparens-mode 1)
(sp-show--pair-function)
(should (not (eq sp-show-pair-overlays nil))))
(sp-show--pair-delete-overlays))))
(sp-ert-deftest sp-test-show-mode-point-elisp
:let ((sp-show-pair-from-inside nil))
(sp-test--show-pairs "|(foo bar)" (emacs-lisp-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 9)))
(sp-test--show-pairs "(foo bar)|" (emacs-lisp-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 9)))

(ert-deftest sp-test-show-mode-point-at-end-of-sexp ()
(let ((sp-pairs '((t . ((:open "(" :close ")" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil))
(unwind-protect
(sp-test-with-temp-elisp-buffer "(foo bar)|"
(show-smartparens-mode 1)
(sp-show--pair-function)
(should (not (eq sp-show-pair-overlays nil))))
(sp-show--pair-delete-overlays))))
(sp-test--show-pairs "(|foo bar)" (emacs-lisp-mode)
(sp-test--show-pairs-assert nil))
(sp-test--show-pairs "(foo bar|)" (emacs-lisp-mode)
(sp-test--show-pairs-assert nil))

(ert-deftest sp-test-show-mode-point-at-beg-in-of-sexp-from-inside-t ()
(let ((sp-pairs '((t . ((:open "(" :close ")" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil)
(sp-show-pair-from-inside t))
(unwind-protect
(sp-test-with-temp-elisp-buffer "(|foo bar)"
(show-smartparens-mode 1)
(sp-show--pair-function)
(should (not (eq sp-show-pair-overlays nil))))
(sp-show--pair-delete-overlays))))
(sp-test--show-pairs "\"()|\"" (emacs-lisp-mode)
(sp-test--show-pairs-assert (list :op-beg 2 :cl-beg 3)))
(sp-test--show-pairs "\"()\"|" (emacs-lisp-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 4))))

(ert-deftest sp-test-show-mode-point-at-end-in-sexp-from-inside-t ()
(let ((sp-pairs '((t . ((:open "(" :close ")" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil)
(sp-show-pair-from-inside t))
(unwind-protect
(sp-test-with-temp-elisp-buffer "(foo bar|)"
(show-smartparens-mode 1)
(sp-show--pair-function)
(should (not (eq sp-show-pair-overlays nil))))
(sp-show--pair-delete-overlays))))
(sp-ert-deftest sp-test-show-mode-point-elisp-from-inside-t
:let ((sp-show-pair-from-inside t))
(sp-test--show-pairs "(|foo bar)" (emacs-lisp-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 9)))
(sp-test--show-pairs "(foo bar|)" (emacs-lisp-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 9))))

(ert-deftest sp-test-show-mode-point-at-beg-in-of-sexp-from-inside-nil ()
(let ((sp-pairs '((t . ((:open "(" :close ")" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil)
(sp-show-pair-from-inside nil))
(unwind-protect
(sp-test-with-temp-elisp-buffer "(|foo bar)"
(show-smartparens-mode 1)
(sp-show--pair-function)
(should (eq sp-show-pair-overlays nil)))
(sp-show--pair-delete-overlays))))
(sp-ert-deftest sp-test-show-mode-latex-multiple-nested-sexps
(sp-test--show-pairs "|$({})$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 6)))
(sp-test--show-pairs "$|({})$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 2 :cl-beg 5)))
(sp-test--show-pairs "$(|{})$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 3 :cl-beg 4)))
(sp-test--show-pairs "$({|})$" (latex-mode)
(sp-test--show-pairs-assert nil))
(sp-test--show-pairs "$({}|)$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 3 :cl-beg 4)))
(sp-test--show-pairs "$({})|$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 2 :cl-beg 5)))
(sp-test--show-pairs "$({})$|" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 6))))

(ert-deftest sp-test-show-mode-point-at-end-in-sexp-from-inside-nil ()
(let ((sp-pairs '((t . ((:open "(" :close ")" :actions (insert wrap autoskip navigate))))))
(sp-show-pair-overlays nil)
(sp-show-pair-from-inside nil))
(unwind-protect
(sp-test-with-temp-elisp-buffer "(foo bar|)"
(show-smartparens-mode 1)
(sp-show--pair-function)
(should (eq sp-show-pair-overlays nil)))
(sp-show--pair-delete-overlays))))
(sp-ert-deftest sp-test-show-mode-latex-multiple-nested-sexps-from-inside-t
:let ((sp-show-pair-from-inside t))
(sp-test--show-pairs "|$({})$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 6)))
(sp-test--show-pairs "$|({})$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 2 :cl-beg 5)))
(sp-test--show-pairs "$(|{})$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 3 :cl-beg 4)))
(sp-test--show-pairs "$({|})$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 3 :cl-beg 4)))
(sp-test--show-pairs "$({}|)$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 3 :cl-beg 4)))
(sp-test--show-pairs "$({})|$" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 2 :cl-beg 5)))
(sp-test--show-pairs "$({})$|" (latex-mode)
(sp-test--show-pairs-assert (list :op-beg 1 :cl-beg 6))))

(ert-deftest sp-test-show-mode-point-at-end-in-sexp-evil ()
(let ((sp-pairs '((t . ((:open "(" :close ")" :actions (insert wrap autoskip navigate))))))
Expand Down

0 comments on commit 3ed34cb

Please sign in to comment.