emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Buffer-local variables affect general-purpose functions


From: Stefan Monnier
Subject: Re: Buffer-local variables affect general-purpose functions
Date: Thu, 27 Mar 2014 10:17:23 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

>   M-x find-file-literally RET some-file RET
>   M-x set-variable RET case-fold-search RET t RET
>   M-: (chars-equal ?à ?À) RET

> This produces nil, although the characters should compare equal under
> case-fold-search.  Why?  Because we are in a unibyte buffer, where
> values between 128 and 255 are interpreted as eight-bit raw bytes, not
> as Latin characters, and raw bytes don't have lower/upper-case pairs.

I agree with Paul on this one: this should be fixed to disregard
unibyte setting.  `char-equal' compares chars, not bytes (use `eq'
for bytes).
It's an old backward compatibility hack that should go.

> Another example, from the same sequence of commands above, is the fact
> that setting case-fold-search for the buffer affects comparison of
> characters that don't belong to the buffer, merely because that buffer
> happens to be current at the moment of comparison.

IIUC this is the kind of problem you really want to talk about in this
thread, and yes, it's a problem.  Usually case-fold-search is let-bound
rather than set buffer-locally, but we have similar problems with
syntax-tables, case-tables, etc...

> The question is: do we want to do something about that?

Not sure.  It's hard to find all occurrences of this problem.
And I don't think we can find a "general" solution: each case might be
best solved in a different way.  Furthermore the right solution will
sometimes (often?) be to throw away the current functionality and
replace it with something different.

But we can definitely try to solve it on a case-by-case basis.

> Yet another example is 'downcase' and 'upcase' functions -- they use
> case tables local to the current buffer, even when the functions they
> are applied to characters and strings not from the buffer.

The solution here is simple: throw away buffer-local case-tables.
AFAICT, set-case-table is used at only one place: in with-case-table.

   % grep set-case-table **/*.el    
   emacs-lisp/cl-lib.el:;; (gv-define-simple-setter current-case-table 
set-case-table)
   subr.el:      (progn (set-case-table ,table)
   subr.el:      (set-case-table ,old-case-table))))))

So the only use of set-case-table is in with-case-table.

   % grep with-case-table **/*.el
   emacs-lisp/lisp-mode.el:                       "eval-and-compile" 
"eval-when-compile" "with-case-table"
   leim/quail/sisheng.el:  (with-case-table (standard-case-table)
   mail/smtpmail.el:                   (with-case-table ascii-case-table ;Why?
   subr.el:(defmacro with-case-table (table &rest body)

And the only uses of with-case-table are in lisp/leim/quail/sisheng.el
(where it sets the standard case table, so it should have no effect) and
in lisp/mail/smtpmail.el (where it uses ascii-case-table but should only
apply it to ASCII text, so it could just as well use the standard case
table).

And then we can use the Unicode 'case tables' as recently discussed.
Patch for that welcome on trunk.

> This could produce subtle bugs, and is certainly confusing and
> unexpected, at least by some.

Agreed.


        Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]