Subject: Re: bug#62536: 30.0.50; Can we add """ ... """ electric pair in elixir, just like python

From: João Távora <[email-masked]>
Date: Wed, 05 Apr 2023 15:33:05 +0100

Wilhelm Kirschbaum <[email-masked]> writes:

>>> And in electric-layout-rules you _can_, I think, identify
>>> triple quotes using a function as described in the last
>>> paragraph of its docstring.
>>>
>> Yes, I tested this earlier and it does work.
>>
>
> Even though it works, it does not play nice with the custom psif,
> because the layout rules seems to trigger before the hook.

There could yet be a snag here, which I didn't anticipate, which is that
rules in electric-layout-rules do not trigger if inside strings or
comments, and that is hardcoded.

Let's assume we got rid of the snag or had some mechanism to override
it:

    diff --git a/lisp/electric.el b/lisp/electric.el
    index bac3f5a2b3c..cef5326852c 100644
    --- a/lisp/electric.el
    +++ b/lisp/electric.el
    @@ -409,9 +409,7 @@ electric-layout-post-self-insert-function-1
                                     (goto-char pos)
                                     (funcall probe last-command-event))))
                              (when res (throw 'done res))))))))))
    -    (when (and rule
    -               ;; Not in a string or comment.
    -               (not (nth 8 (save-excursion (syntax-ppss pos)))))
    +    (when rule
           (goto-char pos)
           (when (functionp rule) (setq rule (funcall rule)))
           (dolist (sym (if (symbolp rule) (list rule) rule))

Then, the following simple patch seems to have good results in my tests.

   (defun joaot/looking-back-at-exactly-three-quotes-p ()
     (looking-back "\\(\\`\\|[^\"]\\)\"\"\"" (- (point) 4)))
    
   (defun joaot/triple-quotes ()
     (when (and (eq ?\" last-command-event)
                (joaot/looking-back-at-exactly-three-quotes-p))
       (save-excursion (insert "\"\"\"" ))))
    
   (defun joaot/layout-after-triple-quotes (inserted)
     (when (and (eq inserted ?\") (joaot/looking-back-at-exactly-three-quotes-p))
       '(after-stay after)))
    
   (defun joaot/setup-elixir-electricity ()
     (electric-layout-local-mode 1)
     (electric-pair-local-mode 1)
     (electric-indent-local-mode 1)
     (add-hook 'post-self-insert-hook 'joaot/super-quotes-and-newlines -05 t)
     (setq-local electric-layout-rules
                 (list #'joaot/layout-after-triple-quotes)))
    
   (add-hook 'elixir-ts-mode-hook 'joaot/setup-elixir-electricity)

João