Temporary Syntax Tables Revisited

The other day, I wrote about Xah Lee’s post on temporary syntax tables and the with-syntax-table macro. Subsequently, Lee discovered a nasty side effect that he wrote about on the G+ Emacs Community site. The problem was that his code

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

modified the original standard syntax table for all buffers.

The problem is (standard-syntax-table) doesn’t copy the standard syntax table; it just returns a pointer to the standard syntax table object. This is the same thing that happens if you assign a list to a variable:

(setq x '(1 2 3))
(setq y x)
(setf (car y) 5)
(message "x is %s" x)

returns

x is (5 2 3)

because x and y refer to the same object.

What we need to do is first make a copy of the standard syntax table. Happily, the copy-syntax-table function does just that1 so if we evaluate

(with-syntax-table (copy-syntax-table)
  (modify-syntax-entry ?‹ "(›")
  (describe-syntax))

the ‹ is described as an open bracket but if we open a new fundamental buffer and call describe-syntax it is described as punctuation, as expected.

Lee solved this problem by creating a new syntax table with make-syntax-table and added his definitions to it. You might think that Lee’s solution is incorrect because the other syntax definitions will be missing from his new table but it is correct because make-syntax-table will create a table that inherits from the standard syntax table (or whatever table you specify).

Footnotes:

1

copy-syntax-table copies standard syntax table by default but you can specify a table explicitly if you want to start with some other table.

This entry was posted in Programming and tagged . Bookmark the permalink.