From madore@news.ens.fr
Path: eleves!not-for-mail
From: madore@news.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.editeurs.emacs,ens.forum.alt.bavardage.insultes
Subject: CONNERIE DE MERDE DE XEMACS
Date: 8 Mar 1999 02:09:52 GMT
Lines: 93
Sender: madore@clipper.ens.fr
Message-ID: <7bvbhg$59e$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 920858992 5422 129.199.129.1 (8 Mar 1999 02:09:52 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 8 Mar 1999 02:09:52 GMT
X-Newsreader: Flrn (0.3.1 - 12/98)
Xref: eleves ens.forum.informatique.editeurs.emacs:93 ens.forum.alt.bavardage.insultes:456

Je savais bien qu'XEmacs était de la merde, mais là ils se sont
vraiment surpassés.

Normalement, faire une config pour Emacs et XEmacs où les touches
backspace et delete marchent correctement devrait être à peu près
trivial.  L'éditeur lit soit des caractères soit des keysyms X suivant
qu'il tourne dans un terminal ou dans une fenêtre X ; ces entrées sont
converties en événements, puis ces événements passent par un certain
nombre de tables de remapping (essentiellement, pour convertir des
choses comme "\033[3~" en [delete], c'est-à-dire pour identifier des
successions d'événements caractères et des événements X ; la
principale table est la function-key-map) avant de passer par la
dernière table, la global-map, qui les convertit en fonctions.

Mon Plan Pour Une Config Qui Marche En Faisant The Right Thing était
donc (à peu de choses près) d'utiliser la function-key-map pour
transformer "\177" en [backspace] et "\033[3~" en [delete], puis la
global-map pour binder 'backward-delete-char à [backspace] et
'delete-char à [delete].  Ainsi, sous X, l'éditeur reçoit des keysyms
BackSpace et Delete et les transforme en événements [backspace] et
[delete] qui font ce qu'il faut, et dans un xterm (ou un quelconque
tty), il reçoit les séquences de caractères, et les tranforme en
[backspace] ou [delete] comme il faut.

[Quelques précisions pas très importantes.  D'abord, il faut aussi
transformer [kp-delete] en [delete] dans le function-key-map
(kp-delete et l'événement généré sous X par le delete du pavé
numérique) ; bien entendu, il ne faut pas mettre d'entrée dans la
global-map à kp-delete ; or XEmacs le fait : encore une preuve de sa
nacszitude, mais là ce n'est rien par rapport à ce qui va suivre,
parce qu'on peut toujours l'enlever.  Une autre chose c'est que
contrairement à ce que je dis plus haut je projetais, parce que je
crois que c'est mieux, de convertir [backspace] en \177 et non \177 en
[backspace].  Mais ça ne change rien pour la suite.]

Or ma config merveilleuse elle marche sous Emacs dans tout les cas et
sous XEmacs en mode X.  Mais sous XEmacs dans un terminal, le
backspace efface à droite au lieu d'effacer à gauche.  Mystère...
Pourquoi ce comportement ?  Je constate qu'à un très bas niveau le
caractère \177 est transformé en [delete] (ce qui fait que comme
j'affecte la fonction 'delete-char à [delete], il efface à droite -
même si function-key-map essaye de remapper \177 en [backspace], parce
que function-key-map est ignoré pour les événements qui ont une entrée
dans le global-map).

J'ai passé énormément de temps (regardez l'heure de ce message) à
chercher d'où provenait cette traduction de bas niveau.  Elle ne
provenait pas de la function-key-map ni de la key-translation-map, ni
même de la keyboard-translate-table (une table de très bas niveau).
En désespoir de cause je suis allé voir dans le source C...

...et c'était bien là qu'était le problème.  Dans events.c on trouve :

void
character_to_event (Emchar c, struct Lisp_Event *event, struct console *con,
		    int use_console_meta_flag)
{
  /* ... */
  else if (c == 127)
    k = QKdelete;
  /* ... */
}

Autrement dit, le caractère 127 produit *directement* l'événement
[delete].  Sans aucune possibilité de le remapper.  Et, bien entendu,
le keysym Delete produit aussi l'événement [delete].  Sans aucune
possibilité de le remapper.  Conséquence : le caractère 127 et le
keysym Delete *doivent* avoir le même effet.  Or on veut que l'un
efface à gauche et l'autre à droite.  Donc ce n'est pas possible.
Donc XEmacs est irrémédiablement buggué.

(Un peu plus haut dans les sources on voit que le code transformait de
même \010 en [backspace], mais que ça a été mis en #if 0, avec un
commentaire expliquant que c'était « too controversial ».)

Je trouve vraiment que le connard qui a écrit ce code mériterait
d'être recouvert de miel et enterré à côté d'une fourmilière.

En tout cas, il me reste deux possibilités :

* patcher le source.  C'est assez évident, et ça devrait marcher.
Mais encore faut-il faire accepter ce patch.  Qui est responsable
d'XEmacs que je l'engueule un grand coup ?

* écrire un hack immonde pour détecter si on est sous X ou non : si on
n'est pas sous X, je remappe \177=[delete] en [backspace] et \033[3~
en [true-delete], et c'est [true-delete] que j'affecte à delete-char.

(Si je me débrouille bien, le hack devrait marcher à la fois sur un
XEmacs patché et sur un XEmacs non patché - ainsi que sur un bête
Emacs, d'ailleurs.)

Qu'en pensez-vous ?

