Emacs Lisp: with-syntax-table Leaking Bug

By Xah Lee. Date: . Last updated: .

There seems to be a bug with with-syntax-table

Here's how to reproduce.

open a new buffer, then Alt+x fundamental-mode.

eval the following one-by-one by Alt+x eval-last-sexp.

(string (char-syntax ?\«))
;; "."

(with-syntax-table (standard-syntax-table)
  (modify-syntax-entry ?\« "(»")
  (modify-syntax-entry ?\» ")«")
  )

(string (char-syntax ?\«))
;; "("

Expected result of last expression is ".", but it actually returns "("

This means, with-syntax-table leaked.

The elisp manual reads:

Macro: with-syntax-table table body…

    This macro executes body using table as the current syntax table. It returns the value of the last form in body, after restoring the old current syntax table.

    Since each buffer has its own current syntax table, we should make that more precise: with-syntax-table temporarily alters the current syntax table of whichever buffer is current at the time the macro execution starts. Other buffers are not affected.

not a bug

actually, it's not a bug. You need to make a copy of the syntax table, like this:

(copy-syntax-table (standard-syntax-table))

The with-syntax-table simply makes a syntax table current. You still have to make sure you are not modifying the standard-syntax-table.

Syntax Tables (ELISP Manual)