9

How can I get electric-pair-mode to not pair quotation marks (single or double)? I still want it to pair everything else (brackets, braces, etc.), just not quotes.

Ben
  • 587
  • 4
  • 11
  • Have you tried customizing `electric-pair-inhibit-predicate`? – elethan Aug 12 '16 at 18:26
  • @elethan where do I find this `electric-pair-inhibit-predicate` variable? It's unknown to my emacs 24.3.1 – ggll Dec 15 '17 at 18:17
  • @ggll I am using Emacs 25.1.1 and for me it is in `elec-pair.el`. – elethan Dec 16 '17 at 17:12
  • In source of `electric-pair-mode`, `electric-pair-pairs` and `electric-pair-text-pairs` is used for customization, but `electric-pair-text-syntax-table` takes precedence. A hook that locally sets these variables should be enough to get this to work. I'll check if that's the case later and post an answer. –  Dec 20 '17 at 12:10

4 Answers4

10

Add the following to your emacs init file:

(setq electric-pair-inhibit-predicate
      (lambda (c)
        (if (char-equal c ?\") t (electric-pair-default-inhibit c))))

Reference from my blog post: https://www.topbug.net/blog/2016/09/29/emacs-disable-certain-pairs-for-electric-pair-mode/

xuhdev
  • 1,839
  • 13
  • 26
  • 1
    This does not work for me. Double quotes are still paired. – Ben Oct 06 '17 at 14:14
  • @Ben Which emacs version do you have. Please add that information to your question. Please, try the code from this answer with `emacs -Q` (emacs started with command line option `-Q`). Perhaps some other package interferes. The code works for me with GNU Emacs 25.3.1 (x86_64-unknown-cygwin, GTK+ Version 3.22.20) of 2017-09-11. – Tobias Dec 15 '17 at 07:57
  • I'm adding an answer because I can't yet comment. @xuhdev has the answer right but for reasons I don't really understand in my system when I evaluate: (setq electric-pair-inhibit-predicate (lambda (c) (if (char-equal c ?\") t (electric-pair-default-inhibit c)))) I get (lambda (c) (if (char-equal c 34) t (electric-pair-default-inhibit c))). So try M-x customize-variable, choose electric-pair-inhibit-predicate, and then choose from the value-menu function and in the box write: (lambda (c) (if (char-equal c ?\") t (electric-pair-default-inhibit c))) This way it works for my configurations at emac – D. Dimakakos Dec 18 '17 at 14:04
  • Please don't post a pseudo answer in lieu of a comment. When you gain a bit of "reputation" points you will be able to comment. If you're wondering why `?\"` ends up printed as `34`, it's because the `"` character is the same as the integer `34`. In Emacs, characters are positive integers of a certain range. – Drew Dec 18 '17 at 17:42
  • This must be an electric.el version problem. I am using `GNU Emacs 24.3.1 (x86_64-redhat-linux-gnu) of 2016-01-13`. – Ben Dec 21 '17 at 15:17
  • Just confirmed that this answer _does_ work in 25.3.1. This answer will become more correct as older versions of emacs become obsolete, so I will mark it as accepted. – Ben Dec 29 '17 at 16:02
2

It appears you cannot. The various customizations only allow you to add pairs.

If you're willing to use a different package to do your pairing, you can try smartparens. You can set quotation marks to not pair as follows:

(sp-pair "'" nil :actions :rem)
(sp-pair "\"" nil :actions :rem)
zck
  • 8,984
  • 2
  • 31
  • 65
  • Note that smartparens lacks some subtle features from electric-pair that aren't immediately obvious. If you can get over that (or mod them in yourself) it may be worth switching anyway. Smartparents has other useful features and is a lot more flexible. – JCC Sep 12 '16 at 22:22
  • Could you mention a subtle electric-pair feature missing from smartparens, @JackCC? – Omar Sep 30 '16 at 07:23
  • It's been a while since I switched, so these might be wrong, but off the top of my head: if you have a closing brace immediately following the cursor (or with whitespace between it), typing the opening brace in `electric-pair` will respect the existing closing brace. In `smartparens`, a new closing brace is always created unless you are in strict mode (which has other strong side-effects). For example: `|)` -> `(|)` in `electric-pair` versus `|)` -> `(|))` in smartparens. The pipe symbol `|` represents the cursor. – JCC Sep 30 '16 at 10:36
  • Likewise, if you are in `electric-pair` and you have a closing brace four lines down with only whitespace between your cursor and the closing brace and you type that closing brace, it will replace the brace below, causing it to become flush with the cursor. That doesn't happen in `smartparens` unless you're in strict mode. This is a nice shortcut when editing something like lisp (or even something like Python, honestly) because it reduces the cognitive overhead of formatting s-expressions. It can make balancing braces more confusing though. – JCC Sep 30 '16 at 10:38
  • I believe `electric-pair` also inherits its pairs from the syntax table of the current mode, whereas in `smartparens` you have to explicitly program in every pair. I could be wrong about that one though. – JCC Sep 30 '16 at 10:42
  • Can I use `electric-pair` and `smartparens ` together? – alper Jun 28 '20 at 13:29
2

Update: @xuhdev's answer is preferable as it doesn't interfere with Emacs' code.

Might be worth a feature request having that customizable. For the moment, it looks trivial to modify the code in question.

Afterwards load your own variant of electric-pair-post-self-insert-function

Open elec-pair.el and copy from there

(defun electric-pair-post-self-insert-function ()
[ ... ] )

Then look into the body for any

(memq syntax '(?\( ?\) ?\" ?\$))

and delete the ?\" from there, i.e.

(memq syntax '(?\( ?\) ?\$))

but not delete ?\" at other places(!)

and reload i.e. evaluate the changed function.

To reload at next session put it into some file "my-changed-stuff.el" and load this from your init-file.

Andreas Röhler
  • 1,894
  • 10
  • 10
1

I think it could be simpler, based on @xuhdev's answer:

(setq electric-pair-inhibit-predicate (lambda (c) (char-equal c ?\")))

The doc says

The function is called with a single char (the opening char just inserted). If it returns non-nil, then ‘electric-pair-mode’ will not insert a matching closer.

So the lambda only needs to return a boolean.

Jason
  • 161
  • 4