3

I've came across this comment in an evil-surround issue, which stated this code:

;; use non-spaced pairs when surrounding with an opening brace
(evil-add-to-alist
 'evil-surround-pairs-alist
 ?\( '("(" . ")")
 ?\[ '("[" . "]")
 ?\{ '("{" . "}")
 ?\) '("( " . " )")
 ?\] '("[ " . " ]")
 ?\} '("{ " . " }"))

And it actually works. but what are those strange ?\ symbols? What are they doing? What do they mean?

3

Emacs represents characters with the ?a syntax (or ?\X for special characters, where X is one of them).

(characterp "a")                        ; => nil
(characterp ?a)                         ; => t

They evaluate to integers:

(integerp ?a)                           ; => t

They are not single-character strings, so the following will throw an error:

(string-equal "a" ?a)                   ; => (throws an error)

You can convert them to strings using:

(char-to-string ?a)                     ; => "a", note: semi-obsolete

or just a plain old:

(string ?a)                             ; => "a"

So now you have:

(string-equal "a" (string ?a))          ; => t

And for your special characters like parentheses and braces:

(list (string-equal "(" (string ?\())
      (string-equal "[" (string ?\[))
      (string-equal "{" (string ?\{)))  ; => (t t t)
  • Dan, could the evil-surround author have chosen to implement the evil-surround-pairs-alist variable with string (e.g. "(") leads instead of integer (e.g. ?\() leads? Why didn't he just use the string format? – ninrod Feb 2 '17 at 17:06
  • @ninrod: in principle, yes: keys in an alist can be strings. But characters will be a faster lookup because you can test for equality with eq (so (eq ?a ?a) evaluates to t), whereas string equality is slower to evaluate. In effect, an alist with character keys can use assq, but one with string keys needs the slower assoc. Whether or not you'd ever notice the speed difference depends on a) the list length, and b) how often you run the function. It's also likely that he's querying the characters around point with char-before and char-after, and wants to skip conversion. – Dan Feb 2 '17 at 17:10
  • (minor) ?\ can be used for any character, not just special characters. So you can (but you need not) use ?\g instead of ?g. – Drew Feb 2 '17 at 18:20
  • 2
    @Drew: almost, but not quite, I think. For example, ?a is the character representation of lowercase "a" while ?\a is the character representation of C-g, and ?t represents lowercase "t" and ?\t represents the tab character. So both (eq ?a ?\a) and (eq ?t ?\t) evaluate to nil. However, it does work for some other characters: (eq ?z ?\z) evaluates to t. – Dan Feb 2 '17 at 18:57
  • 1
    @Dan: Ah yes, right you are. It is true for characters for which there is not some other escape sequence defined. That is, as long as it is not one of the se: \a, \b, \t, \n, \v, \r, \e, \s, \\ , and \d. The relevant manual page is (elisp)Basic Char Syntax. – Drew Feb 2 '17 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.