OVH Cloud OVH Cloud

Problème spécial

24 réponses
Avatar
Ph. Ivaldi
Re,

J'utilise two-mode-mode pour faire un mode hybride latex/asymptote:
quand le curseur se trouve entre les balises \begin{asy} et \end{asy}
tout le buffer bascule en asy-mode et hors des balises il est en mode
LaTeX-mode.
Ça fonctionne très bien sauf que...

En mode asy-mode tout texte entre apostrophes ou guillemets (") est
coloré en rouge (c'est une chaîne quoi).

Si j'édite ce bête code:
8<------8<------8<------8<------8<------8<------8<------8<------8<------
\documentclass{article}
\begin{document}
s'il Il n'y a pas de solution c'est qu'il n'y a pas de problème.
\begin{asy}
draw(unitcircle);
\end{asy}
\end{document}
8<------8<------8<------8<------8<------8<------8<------8<------8<------

comme le nombre d'apostrophes avant l'environnement asy est impair,
tout l'environnement asy devient rouge.

Auriez une idée pour contourner ce problème ?
J'étudie TOUTE proposition, de la plus farfelue à la plus sérieuse.
--
Merci de votre attention,
Philippe Ivaldi.
http://piprim.tuxfamily.org/

10 réponses

1 2 3
Avatar
Ph. Ivaldi
Le 06 juillet 2007, Olivier écrivit :

Maintenant, ça ne fonctionne que dès que le end{asy}
apparait, c'est comme cela que je l'ai codé, mais on peut
faire dès que le begin{asy} apparait.



Ce n'est pas un problème. Chez moi ça ne fonctionne tout simplement pas...
Tout l'environnement asy devient rouge.

Tu es en lazy-lock, ton fichier est très gros ou ce genre de choses ?



Non pas de lazy-lock et le même exemple que toi.
J'ai aussi testé avec emacs-snapshot -q et emacs -q ; rien à faire !

De toutes façons, la coloration asy, ou du moins celle que je
redefinis doit prendre le pas sur toute autre.



Je comprends parfaitement ton code et le paramètre "t" à
`font-lock-add-keywords' devrait faire passer ta coloration au-dessus
des autres... Ben non... :-(
J'ai même mis un mouchard '(message "pass")' dans
`asy-locate-asy-environment' pour être sûr que ça passe par là.

Je n'ai pas de fichier asy-keywords.el, j'ai créé les variables
manquantes à la main :-p



Tu peux le trouver là:
http://piprim.tuxfamily.org/home/pi/emacs.d/site-lisp/asy-keywords.el
(il est généré à chaque mise à jour d'Asymptote pour avoir les nouveaux
mots clef).

Dépité, j'essaye aussi sur gnu.emacs.help...
Peut-être qu'il y aura d'autres idée.
--
Amicalement,
Philippe Ivaldi.
http://piprim.tuxfamily.org/
Avatar
Olivier
Ph. Ivaldi wrote:
[...]

Ce n'est pas un problème. Chez moi ça ne fonctionne tout simplement pas...
Tout l'environnement asy devient rouge.


[...]
De toutes façons, la coloration asy, ou du moins celle que je
redefinis doit prendre le pas sur toute autre.



Je comprends parfaitement ton code et le paramètre "t" à
`font-lock-add-keywords' devrait faire passer ta coloration au-dessus
des autres... Ben non... :-(



Si, si, ça marche -- un peu et mal, mais ça marche :-p
Le rouge est probablement ta couleur par défaut (???),
je ne suis pas sur de la couleur que donne l'allocation
de asy-dummy-face -- Là, il utilise font-lock-warning-face
à mon avis (c'est le rouge vif) :-(



Au lieu de (defface asy-dummy-face),
tu peux essayer (make-face 'asy-dummy-face) qui met
tous les attributs à nil, ou faire suivre
le defface d'un (face-spec-reset-face 'asy-dummy-face).
Mais cela devrait revenir
à la default-face qui est celle qui à tous les attributs
à nil.

On obtient la face par defaut en faisant
(face-default-spec nil)
ou plus précisément en cas de customization, avec
(face-user-default-spec nil)
Chez moi, tout cela est nil.

Voila mes deux sous avant depart !
A.O.
Avatar
Ph. Ivaldi
Le 07 juillet 2007, Olivier écrivit :

Si, si, ça marche -- un peu et mal, mais ça marche :-p



c'est pas du juste !

Le rouge est probablement ta couleur par défaut (???),



:-) c'est un blague ? :-)

je ne suis pas sur de la couleur que donne l'allocation
de asy-dummy-face -- Là, il utilise font-lock-warning-face
à mon avis (c'est le rouge vif) :-(



ftp://download.tuxfamily.org/piprim/emacs/probleme-asy.mpeg

Je fais une dernière tentative en regardant comment est codé font-lock+:
http://www.emacswiki.org/cgi-bin/wiki/font-lock+.el

--
Amicalement,
Philippe Ivaldi.
http://piprim.tuxfamily.org/
Avatar
Olivier
Bon, ça y est, j'ai compris comment fonctionne
asy-mode et ... faut tout changer pour la couleur ---

Bon, voyons si nous sommes d'accord :
-- le mode d'un buffer est une variable
du buffer et non une propriete d'une partie
du texte. Ce pourquoi je dis toujours qu'emacs
n'est pas fait pour gérer plusieurs modes.
-- en conséquence, font-lock réagit au mode
mais s'occupe du buffer en entier et de la portion
en asy-mode.
-- solutions :
(1) -- (j'aime pas) dans font-lock, mettre
des matchers qui reconnaissent la présence
d'un begin{asy} non fermé avant eux --
(2) -- (j'aime) en introduisant le end{asy}
on met la propriete 'asy-mode a toute
la portion entre les deux balises.
Et on reconnait les keywords avec
la text-property (celle-ci et pas d'autres).
Oui, cela demande de reécrire les matchers, mais
cela me semble viable à long terme.

Voila.
Amities,
Olivier
Avatar
Ph. Ivaldi
Le 08 juillet 2007, Olivier écrivit :

Bon, ça y est, j'ai compris comment fonctionne
asy-mode et ... faut tout changer pour la couleur ---

Bon, voyons si nous sommes d'accord :
-- le mode d'un buffer est une variable
du buffer et non une propriete d'une partie
du texte. Ce pourquoi je dis toujours qu'emacs
n'est pas fait pour gérer plusieurs modes.



On est d'accord.

-- en conséquence, font-lock réagit au mode
mais s'occupe du buffer en entier



Oui c'est bien le problème.
Ce qui serait robuste c'est qu'il ne s'occupe que du texte entre les
balises begin{asy} et end{asy}.
Autrement dit, que les appels à parse-partial-sexp ne s'effectuent
qu'entre ces balises.
Pour cela il est sûrement possible d'utiliser la variable
font-lock-extend-region-functions mais je n'y suis pas arrivé.

et de la portion
en asy-mode.



Du coup oui puisqu'elle est dans le buffer.

-- solutions :
(1) -- (j'aime pas) dans font-lock, mettre
des matchers qui reconnaissent la présence
d'un begin{asy} non fermé avant eux --



J'aime pas trop nom plus...

(2) -- (j'aime) en introduisant le end{asy}
on met la propriete 'asy-mode a toute
la portion entre les deux balises.
Et on reconnait les keywords avec
la text-property (celle-ci et pas d'autres).
Oui, cela demande de reécrire les matchers, mais
cela me semble viable à long terme.



Je ne sais pas exactement comment marche la reconnaissance des mots
clefs basé sur la "text-property" mais la reconnaissance des "strings"
et commentaires ne sera-t-elle pas toujours active ?

Il va falloir aussi récupérer toutes les reconnaissances de objc-mode.

Tu sais comment procéder ?

Autres solutions:

* radicale mais imparfaite:

Dans la bascule asy-mode/latex-mode on met un
(setq font-lock-keywords-only x) (x=t en asy-mode x=nil en latex-mode)

La coloration des strings et comments est désactivée !
Si je ne trouve pas d'autre solution avant demain c'est celle là que
j'adopterai...

* Sinon, la fonction clef qui s'occupe de la coloration en asy-mode est
font-lock-fontify-syntactically-region

J'essaie actuellement de la comprendre et de la modifier pour lui faire
sauter une guillemet dans certain cas mais j'ai des difficulté avec
parse-partial-sexp qui est loin d'être simple...

Grand merci pour ton aide!
--
Philippe Ivaldi.
http://piprim.tuxfamily.org/

PS: j'ai des problème de connexion quand il pleut, et là il pleut...
Il est possible que je puisse pas répondre rapidement.
Avatar
Olivier
Ph. Ivaldi wrote:
[...]
* Sinon, la fonction clef qui s'occupe de la coloration en asy-mode est
font-lock-fontify-syntactically-region



Ah oui, ça peut être pas mal.
Alors voila :
-----------------------------------------------------------------
(defface asy-environment-face
`((t
(:underline t :inverse-video t)))
"Face used to highlighting the keywords 'begin{asy}' and
'end{asy}' within lasy-mode."
:group 'asymptote)

(font-lock-add-keywords
'asy-mode
'(("\begin{asy}.*" . 'asy-environment-face)
("\end{asy}" . 'asy-environment-face)))

(defadvice font-lock-unfontify-region
(around asy-font-lock-unfontify-region (start end))
(if (eq major-mode 'asy-mode)
(let*((be (or (save-excursion
(goto-char start)
(search-forward "begin{asy}" end t)
(- (point) 11))
start))
(en (or (save-excursion
(goto-char be)
(search-forward "end{asy}" end t)
(point))
end)))
;(print (list be en))
(save-restriction
(narrow-to-region be en)
(setq start be end en)
ad-do-it
(widen)))
ad-do-it))

(ad-activate 'font-lock-unfontify-region)

(defadvice font-lock-fontify-syntactically-region
(around asy-font-lock-fontify-syntactically-region (start end
&optional loudly))
(if (eq major-mode 'asy-mode)
(let*((be (or (save-excursion
(goto-char start)
(search-forward "begin{asy}" end t)
(- (point) 11))
start))
(en (or (save-excursion
(goto-char be)
(search-forward "end{asy}" end t)
(point))
end)))
;(print (list be en))
(save-restriction
(narrow-to-region be en)
(setq start be end en)
ad-do-it
(widen)))
ad-do-it))

(ad-activate 'font-lock-fontify-syntactically-region)
--------------------------------------------------------------------

Ca marche pas mal, mais il y reste un probleme qui me chagrine :
--(1) quand on est en lasy-mode dans l'environnement asy
et qu'on demande [swicj lasy-mode] du menu, ça fait bip
la premiere fois et pas la seconde et je ne sais pas pourquoi :-(

Mais tu connais mieux le code ensuite, tu dois pouvoir trouver
plus facilement que moi ce qui peche.

Hope that fonctionne !
Amities,
Olivier
Avatar
Ph. Ivaldi
Le 08 juillet 2007, Olivier écrivit :

[code]

Ca marche pas mal, mais il y reste un probleme qui me chagrine :
--(1) quand on est en lasy-mode dans l'environnement asy
et qu'on demande [swicj lasy-mode] du menu, ça fait bip
la premiere fois et pas la seconde et je ne sais pas pourquoi :-(

Mais tu connais mieux le code ensuite, tu dois pouvoir trouver
plus facilement que moi ce qui peche.



Effectivement, je regarderai ça...

Hope that fonctionne !



Malheureusement non... Voilà ce que ça donne:
ftp://download.tuxfamily.org/piprim/emacs/probleme-asy.mpeg

Mais ta méthode me semble prometteuse !
Je vais voir ce qui cloche.

Au lieu de chercher begin{asy} (on ne sait pas s'il est avant ou après
ce qu'il est en train de "fontifier") il faut peut-être utiliser ça
8<------8<------8<------8<------8<------8<------8<------8<------8<------
(defun lasy-mode-at-point (pos)
"Return t if POS is in asy environment."
(save-excursion
(save-match-data
(goto-char pos)
(let ((basy (search-backward "begin{asy}" (point-min) t 1))
(easy (search-forward "end{asy}" (point-max) t 1)))
(and basy easy (> pos basy) (< pos easy))))))
8<------8<------8<------8<------8<------8<------8<------8<------8<------

Hier soir je n'avais plus de connexion (ça fait 4 jours que Fr-Telecom
doit passer), et j'en étais là:

8<------8<------8<------8<------8<------8<------8<------8<------8<------
(defun lasy-mode-p ()
(and (boundp two-mode-bool) two-mode-bool))

(setq-default font-lock-syntactic-face-function
(lambda (state)
(if (nth 3 state)
(if (lasy-mode-p)
(and (eq """ (char-after (nth 8 state)))
font-lock-string-face)
font-lock-string-face)
font-lock-comment-face)))
8<------8<------8<------8<------8<------8<------8<------8<------8<------

Évidement il ne faut pas utiliser setq-default...
Ça désactive la coloration des strings en lasy-mode.
Il suffit en plus de voir si le nombre de guillemet est impair avant
l'environnement asy lorsque qu'on passe de latex-mode à asy-mode et de
désactiver la coloration des strings seulement dans ce cas...
C'est pas génial mais c'est un moindre mal.

J'étudie tout ça encore aujourd'hui... après basta !
--
Philippe Ivaldi.
http://piprim.tuxfamily.org/
Avatar
Ph. Ivaldi
Le 09 juillet 2007, Ph. Ivaldi écrivit :

et j'en étais là:

8<----8<------8<------8<------8<------8<------8<------8<------
(defun lasy-mode-p ()
(and (boundp two-mode-bool) two-mode-bool))

(setq-default font-lock-syntactic-face-function
(lambda (state)
(if (nth 3 state)
(if (lasy-mode-p)
(and (eq """ (char-after (nth 8 state)))
font-lock-string-face)
font-lock-string-face)
font-lock-comment-face)))
8<-----8<------8<------8<------8<------8<------8<------8<------



C'est mal codé, à revoir ! mais l'idée est là...
--
Philippe Ivaldi.
http://piprim.tuxfamily.org/
Avatar
Olivier
Bon, je ne vais pas faire dans la finesse, voici un code qui doit
tourner, l'autre etait plein de fautes :-(

Ses faiblesses :
-- lasy-mode-at-point est trop fort pour ce que l'on fait,
on peut gagner du temps, tant pis, c'est plus joli ainsi.
-- les definitions de be et en pourrait etre plus efficace, ca,
ya pas a dire !
-- le condition-case autour du add-do-it est assez bourrin, j'en
conviens, mais narrow-to-region est tres incomplet.
Il pourrait meme etre necessaire de le mettre dans la partie
unfontify si jamais la premiere ligne n'etait pas
debut-de-ligne-begin{asy}-quedalle.

Son avantage supposé : il tourne souvent :-)
A.O.
-------------------------------------------------------------------------
(defun lasy-mode-at-point (pos)
"Return t if POS is in asy environment."
(save-excursion
(save-match-data
(goto-char pos)
(let ((basy (search-backward "begin{asy}" (point-min) t 1))
(easy (search-forward "end{asy}" (point-max) t 1)))
(and basy easy (> pos basy) (< pos easy))))))

(defadvice font-lock-unfontify-region
(around asy-font-lock-unfontify-region (beg end))
(if (eq major-mode 'asy-mode)
(let*((be (if (lasy-mode-at-point beg)
beg
(or (save-excursion
(goto-char beg)
(if (search-forward "begin{asy}" end t)
(- (point) 11) nil))
beg)))
(en (or (save-excursion
(goto-char be)
(if (search-forward "end{asy}" end t)
(point) nil))
end)))
;(print (list be en))
(save-restriction
;(print "In font-lock-unfontify-region")
(narrow-to-region be en)
(setq beg be end en)
;(print (list "beg = " beg " myown = " be " end = " end " myown = "
en))
ad-do-it
(widen)
;(print "Out of font-lock-unfontify-region")
))
ad-do-it))

(ad-activate 'font-lock-unfontify-region)

(defadvice font-lock-fontify-syntactically-region
(around asy-font-lock-fontify-syntactically-region (start end
&optional loudly))
(if (eq major-mode 'asy-mode)
(let*((be (if (lasy-mode-at-point start)
start
(or (save-excursion
(goto-char start)
(if (search-forward "begin{asy}" end t)
(- (point) 11) nil))
start)))
(en (or (save-excursion
(goto-char be)
(if (search-forward "end{asy}" end t)
(point) nil))
end)))
;(print (list "start = " start " myown = " be " end = " end " myown " en))
(save-restriction
;(print "In font-lock-fontify-syntactically-region")
(narrow-to-region be en)
(setq start be end en)
(condition-case nil
ad-do-it
(error nil))
(widen)
;(print "Out of font-lock-fontify-syntactically-region")
))
ad-do-it))

(ad-activate 'font-lock-fontify-syntactically-region)
--------------------------------------------------------------------------
Avatar
Ph. Ivaldi
Le 09 juillet 2007, Olivier écrivit :

Bon, je ne vais pas faire dans la finesse,



On est pas obligé hein... :-)

voici un code qui doit
tourner,

Ses faiblesses :
-- lasy-mode-at-point est trop fort pour ce que l'on fait,
on peut gagner du temps, tant pis, c'est plus joli ainsi.
-- les definitions de be et en pourrait etre plus efficace, ca,
ya pas a dire !
-- le condition-case autour du add-do-it est assez bourrin, j'en
conviens, mais narrow-to-region est tres incomplet.
Il pourrait meme etre necessaire de le mettre dans la partie
unfontify si jamais la premiere ligne n'etait pas
debut-de-ligne-begin{asy}-quedalle.



Je regarderai en détail si je peux mieux faire...
J'étais plus ou moins en train de faire ce que tu proposes (en encore
moins fin !).

Son avantage supposé : il tourne souvent :-)



Comme on dirait par chez nous « putain, ÇA MARCHE con ! » (faut
l'entendre avec l'accent...)

Mais qui a dit qu'Emacs n'était pas fait pour les multi-modes ? :-)

Peut-être que cette fonctionnalité intéresserait les auteurs de
two-mode-mode...

Je ne sais pas comment te remercier !

Mille mercis, je n'y serais jamais arrivé seul.
--
Philippe Ivaldi.
http://piprim.tuxfamily.org/
1 2 3