smartparens icon indicating copy to clipboard operation
smartparens copied to clipboard

Strict mode - cannot disable pair matching with custom predicate

Open arichiardi opened this issue 2 years ago • 2 comments

Hi there, I am working with web-mode and Javascript and I have the following issue.

Expected behavior

It should allow me to write => (JS inline function)

Actual behavior

Every time I try to write =>, smartparens complains with We can not insert unbalanced closing delimiter in strict mode.

Steps to reproduce the problem

Enable web-mode and (require 'smartparens-javascript) and (smartparens-strict-mode) Try = followed by a >.

Backtraces if necessary (M-x toggle-debug-on-error)

None


I have actually tried the following:

with a predicate like:

(defun ar-emacs--point-after-equal-p (id action context)
  "Return t if point is after \\=, nil otherwise.  This predicate
is only tested on \"insert\" action."
  (when (eq action 'insert)
    (save-excursion
      (= (preceding-char) ?=))))

First using:

(sp-local-pair 'web-mode "<" nil :skip-match 'ar-emacs--point-after-equal-p)

Then

(sp-local-pair 'web-mode "<" nil :unless ('ar-emacs--point-after-equal-p))

In both cases I was not able to make it work.


Environment & version information

  • smartparens version: master aka 63695c6
  • Active major-mode: web-mode
  • Smartparens strict mode: t
  • Emacs version (M-x emacs-version): GNU Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.29, cairo version 1.17.4) of 2021-06-08
  • Starterkit/Distribution: Vanilla
  • OS: gnu/linux

arichiardi avatar Aug 31 '21 20:08 arichiardi

You almost got it. The action you need to disable is navigate not insert because the > does not insert the opening <. With this code I kind of got it working. The skip predicate unfortunately has different API so you need two functions instead of just one.

(defun ar-emacs--point-after-equal-p (id action _context)
  "Return t if point is after \\=, nil otherwise.  This predicate
is only tested on \"insert\" action."
  (when (eq action 'navigate)
    (save-excursion
      (backward-char 1)
      (equal (preceding-char) ?=))))

(defun ar-emacs--point-after-equal-skip-p (ms mb _me)
  "Return t if point is after \\=, nil otherwise.  This predicate
is only tested on  \"insert\" action."
  (and
   (equal ms ">")
   (save-excursion
     (goto-char mb)
     (sp--looking-back-p "=" 1))))


(sp-local-pair 'web-mode "<" ">"
               :unless '(ar-emacs--point-after-equal-p)
               :skip-match 'ar-emacs--point-after-equal-skip-p)

The whole configuration API is so clunky, I don't like it very much :/

Fuco1 avatar Sep 04 '21 12:09 Fuco1

Nice! Thanks it seems like it is working indeed.

arichiardi avatar Sep 04 '21 15:09 arichiardi