Fuco1 / smartparens

Minor mode for Emacs that deals with parens pairs and tries to be smart about it.
GNU General Public License v3.0
1.84k stars 194 forks source link

Slow text insertion in latex-mode (and others) #1141

Open haji-ali opened 1 year ago

haji-ali commented 1 year ago

Actual behavior

I've had slow text insertion for a while in my emacs setup and I finally traced it back to smartparens. For example, with smartparens-latex loaded, inserting any text is super slow in some documents when smartparens-mode is on

Steps to reproduce the problem

Make sure smartparens-latex is loaded and smartparens-mode is on and simply insert any text almost anywhere in a large latex document.

Profiler

Here's a profiler output

``` 853 100% - sp--post-self-insert-hook-handler 451 52% - sp--all-pairs-to-insert 451 52% - sp--do-action-p 365 42% + sp-in-math-p 84 9% - my/enable-exmath-paren 40 4% + texmathp 2 0% + sp-point-in-string 402 47% - sp-insert-pair 402 47% - sp--pair-to-insert 402 47% - sp--all-pairs-to-insert 402 47% - sp--do-action-p 343 40% + sp-in-math-p 59 6% - my/enable-exmath-paren 39 4% + texmathp ```

Reason and Solution

The reason for the slow behavior is that many latex specific parentheses call sp-in-math-p which calls texmathp which can be slow in certain cases.

A simple solution that I implemented is to change the order in which sp--all-pairs-to-insert checks valid parentheses so that only matching pairs are action-checked. A possible implementation follows:

(defun sp--all-pairs-to-insert (&optional looking-fn action)
  "Return all pairs that can be inserted at point.
..."
  (setq looking-fn (or looking-fn 'sp--looking-back-p))
  (setq action (or action 'insert))
  (-if-let (trigs
            (--filter (and
                       (plist-get it :trigger)
                       (funcall looking-fn (sp--strict-regexp-quote (plist-get it :trigger)))
                       (sp--do-action-p (plist-get it :open) action))
                      sp-local-pairs))
      (cons :trigger trigs)
    (cons :open
          (--filter (and
                     (funcall looking-fn (sp--strict-regexp-quote (plist-get it :open)))
                     (sp--do-action-p (plist-get it :open) action))
                    sp-local-pairs))))

This already improves the performance of smartparen considerably (For example texmathp is called only once per insertion) and more performance can be gained by making sp--strict-regexp-quote faster by caching the regular-expression instead of reconstructing on the fly in sp--strict-regexp-quote.

I am happy to do a pull-request if this solution is suitable. Similar changes are also worth doing in sp--pair-to-wrap.

Environment & version information