OVH Cloud OVH Cloud

Modification de la modeline

23 réponses
Avatar
Jérémy JUST
Bonjour,

Sous XEmacs, je voudrais gagner un peu de place dans la modeline. J'ai
déjà trouvé comment retirer le « Xemacs: » avec

(setf (cdar modeline-buffer-identification) "%N")
; au lieu de "XEmacs%N:"


Maintenant, je voudrais réduire le nombre d'espaces (et tirets) un peu
partout. Les bouts de code que j'ai trouvés dans les news réécrivent
entièrement la liste modeline-format, et ça ne me plaît pas trop (ce
serait pour y remettre les valeurs par défaut, la plupart du temps).

Mon idée est plutôt de parcourir modeline-format et de retirer ou
modifier ce qui ne me convient pas. Mais mes trop vagues notions de Lisp
ne m'ont pas mené bien loin. Voilà mes essais:

; La chaîne " " est ce que renvoie (elt modeline-format 4).
; Mais ce code semble ne rien faire.
(setq modeline-format
(mapcar (lambda (x) (if (equal x " ") "A" x)) modeline-format))


; Avec une regexp, j'essaie de supprimer tous les espaces
; Pas plus de succès
(setq modeline-format
(mapcar (lambda (x) (cond (string-match "\\s" x)
(replace-match "")))
modeline-format))


; Alors que le code suivant modifie bien la modeline immédiatement
(setq modeline-format (reverse modeline-format))


Voilà.
Je suis preneur de suggestions.

--
Jérémy JUST <jeremy_just@netcourrier.com>

10 réponses

1 2 3
Avatar
Olve
; La chaîne " " est ce que renvoie (elt modeline-format 4).
; Mais ce code semble ne rien faire.
(setq modeline-format
(mapcar (lambda (x) (if (equal x " ") "A" x)) modeline-format))



Bizarre ... Problème d'encodages ? Pourtant l'espace est toujours
encodé pareil .... string-equal doit faire l'affaire ?
Et

(setq modeline-format
(mapcar (lambda (x) (if (equal x (elt modeline-format 4)) "A" x))
modeline-format))

?? -- modeline-format est local, la valeur que tu donnes de
(elt modeline-format 4) n'est peut etre pas la bonne. Ou alors tu
modifies la modeline-format d'un autre buffer ?? --

; Avec une regexp, j'essaie de supprimer tous les espaces
; Pas plus de succès
(setq modeline-format
(mapcar (lambda (x) (cond (string-match "s" x)
(replace-match "")))
modeline-format))



ben c'est quoi ce délire ???? :-)
Là à mon avis, il faut au moins douze heures de repos :-)

(replace-match "") remplace dans le buffer la derniere partie delimitee par
match-data :-) Il manque aussi un niveau de parentheses ... Et pourquoi pas
un bon vieux if ? Bon cond c'est plus lisp, ok.

Mais

(mapcar (lambda (x) (cond ((string-match "s" x) ""))
(t x)))
modeline-format)

doit déjà fonctionner mieux !

Non testé, non xemacsé d'ailleurs.
J'espère que j'ai pas trop dit d'aneries :-)
Amitiés,
Olivier
Avatar
Jérémy JUST
On Wed, 04 Aug 2004 23:28:56 +0200
Olve wrote:

string-equal doit faire l'affaire ?



Avec string-equal, j'ai un problème de syntaxe

(setq modeline-format
(mapcar (lambda (x) (if (string-equal x " ") "A" x))
modeline-format))

donne:

Wrong type argument: stringp, (#<extent [detached) help-echo keymap
0x40639e68 from no buffer> . modeline-modified)


Même avec le « XEmacs Lisp Ref Manual » je ne suis pas capable de
corriger (oui, je veux jouer à celui qui arrive à écrire deux lignes de
Lisp, mais je n'y connais strictement rien).


(setq modeline-format
(mapcar (lambda (x) (if (equal x (elt modeline-format 4)) "A"
x))
modeline-format))



Rien.


Ou alors tu modifies la modeline-format d'un autre buffer ??



Je n'ai pas l'impression. C'est pour vérifier ça que j'avais fait mon
test avec `reverse' dans mon premier post.


ben c'est quoi ce délire ???? :-)



Merci pour l'honnêteté! :)
C'est dommage, je pensais être devenu un virtuose du Lisp en quelques
dizaines de minutes!


(replace-match "") remplace dans le buffer la derniere partie
delimitee par match-data :-)



Oups! J'avions dû mal lire la doc.


(mapcar (lambda (x) (cond ((string-match "s" x) ""))
(t x)))
modeline-format)
doit déjà fonctionner mieux !



J'ai essayé ça:
(setq modeline-format
(mapcar (lambda (x) (cond ((string-match "s" x) "")
(t x)))
modeline-format))

Et...

Invalid regexp: "Premature end of regular expression"

D'autre part, si je comprends bien le code que tu me proposes, je vais
(enfin, si ça marche) remplacer tout élément qui contient un espace par
la chaîne vide.
C'est un peu violent.


Bon, merci pour ton aide!
Je vais prendre les douze heures de repos que tu suggérais (mais j'en
laisserai la moitié pour la nuit suivante).

--
Jérémy JUST
Avatar
drkm
Olve writes:

Ben oui il manque un espace, excuses moi !!!
"s +" : c'est à dire toute expression composée de caratères
dont la syntaxe est celle du caractère qui suit le "s",
c'est à dire l'espace. Le + est pour dire : répété
autant de fois que nécessaire, mais au moins une.



Puisque tu ne te sers que du retour booléen de `string-match()', le
'+' est d'ailleurs totalement inutile.

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
Avatar
Olve
"s +" : c'est à dire toute expression composée de caratères
dont la syntaxe est celle du caractère qui suit le "s",
c'est à dire l'espace. Le + est pour dire : répété
autant de fois que nécessaire, mais au moins une.



Puisque tu ne te sers que du retour booléen de `string-match()', le
'+' est d'ailleurs totalement inutile.



Oh, gasp, tu as raison. Le mieux serait d'ecrire

(setq modeline-format
(mapcar (lambda (x) (cond ((and (stringp x)
(posix-string-match "s +" x))
(substring x (max 0 (- (match-end 0) 1))))
(t x)))
modeline-format))

;; J'ai laisse un espace quand meme. Celui du "(- (match-end 0) 1)" (le 1).
Ca roule ?
Amities,
Olivier
Avatar
Jérémy JUST
On Thu, 05 Aug 2004 11:20:58 +0200
Olve wrote:

(setq modeline-format
(mapcar (lambda (x) (if (string-equal x " ") "A" x))
modeline-format))
Wrong type argument: stringp, [...]


Oh, c'est juste qu'il attend deux chaines de caracteres :-(



Quel âne je suis, j'avais oublié qu'on parcourait une liste qui ne
contient pas que des chaînes!


Mais c'est rare de voir quelqu'un qui écrit comme cela ne pas
connaitre la syntaxe de la primitive incontournable qu'est cond.



À force d'essayer de comprendre du Lisp, j'ai retenu le nom des
fonctions idiomatiques... mais pas leur syntaxes!
Bon, OK, je le note: cond, ça marche comme un switch.


"s +" : c'est à dire toute expression composée de caratères
dont la syntaxe est celle du caractère qui suit le "s",



Oups, j'avais fait un gros contre-sens sur le "s": je pensais que
comme en Perl, ça correspondait à la famille des espaces (espace,
tabulation...).
Merci pour cette correction!


Voici un code qui fonctionne et tesé en plus :



Pour la postérité, je poste le code auquel j'ai abouti, qui fait ce
que je veux:

; Pour supprimer les espaces en trop dans la modeline
(setq-default modeline-format
(mapcar (lambda (x) (cond ((and (stringp x)
(string-match "s +" x))
(replace-match " " t t x))
((and (stringp x)
(string-match "-+" x))
(replace-match "-" t t x))
(t x)))
modeline-format))


J'utilise setq-default plutôt que setq, pour que ça concerne tous les
buffers.
Je suis revenu à replace-match, mais avec les bons arguments pour
remplacer dans la chaîne, cette fois! Ça permet de remplacer les
caractères surnuméraires, et non toute la chaîne qui les contient.


Désolé pour les ratés



Au contraire, ça m'a permis de comprendre plein de choses!
Merci beaucoup pour toutes ces explications; c'était très clair!

--
Jérémy JUST
Avatar
Pascal Bourguignon
Jérémy JUST writes:
À force d'essayer de comprendre du Lisp, j'ai retenu le nom des
fonctions idiomatiques... mais pas leur syntaxes!
Bon, OK, je le note: cond, ça marche comme un switch.



Tu ferais mieux de lire un manuel de référence.
C-h i m elisp RET par exemple.

Ou la doc:
C-h f cond RET

cond, ça marche comme une séquence de if. C'est case qui marche (à peu
près comme un switch). Et case, c'est avec (require 'cl)...


--
__Pascal Bourguignon__ http://www.informatimago.com/

Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
Avatar
Jérémy JUST
On Fri, 06 Aug 2004 00:37:26 +0200
Olve wrote:

Oui. Ceci étant, il faut utiliser posix-string-match,



Si tu le dis... je modifie.


bien qu'en général les deux fonctions (avec et sans posix)
fonctionnent pareillement.



Sur une regexp aussi simple, je vois mal comment il pourrait y avoir
des comportements différents (à part sur la gloutonnerie du +)!
J'ai jeté un oeil sur la doc du langage de regexp du Lisp: je
comprends mieux pourquoi je n'y comprends rien. En plus de l'abondance
en slash, les différences cachées avec Perl me perdent complètement.


Entre setq-default et setq, le fait est que ce qu'il faudrait vraiment
faire, c'est appliquer ce code a chaque changement de la modeline,
c'est a dire qu'il faudrait une fonction modify-modeline-format et un
crochet :-)



J'avais pensé à ça, puis, n'arrivant pas à l'écrire, je me suis
rabattu sur un crochet pour le cperl-mode (c'est dans celui-là que j'ai
mes problèmes de place)... Puis j'ai trouvé le setq-default, qui m'a
satisfait...
Pour l'instant, je le garde!


Encore merci pour ton aide.

--
Jérémy JUST
Avatar
drkm
Olve writes:

Oh, gasp, tu as raison. Le mieux serait d'ecrire

(setq modeline-format
(mapcar (lambda (x) (cond ((and (stringp x)
(posix-string-match "s +" x))
(substring x (max 0 (- (match-end 0) 1))))
(t x)))
modeline-format))

;; J'ai laisse un espace quand meme. Celui du "(- (match-end 0) 1)" (le 1).
Ca roule ?



J'ai l'impression que ce que veut le PO est un « remplacement
récursif », c'est à dire que chaque suite de plusieures espaces (ou
"-") soit remplacée. Que pensez-vous de :

(defun my-replace-modeline-format (x &optional start)
""
(unless start
(setq start 0))
(cond ((and (stringp x)
(string-match "(s s +|--+)" x start))
(let ((replacement (substring (match-string 0 x) 0 1)))
(my-replace-modeline-format (replace-match replacement t t x)
(1+ start))))
(t x)))

(setq-default modeline-format
(mapcar 'my-replace-modeline-format modeline-format))

?

Notez que le remplacement n'est fait que pour les sous-chaînes de
deux ou plus occurences d'une espace (ou d'un "-"). Remplacer " " par
" " (ou "-" par "-") n'a pas beaucoup d'intérêt ;-)

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
Avatar
Olve
J'ai l'impression que ce que veut le PO est un « remplacement
récursif », c'est à dire que chaque suite de plusieures espaces (ou
"-") soit remplacée. Que pensez-vous de :

(defun my-replace-modeline-format (x &optional start)
""
(unless start
(setq start 0))
(cond ((and (stringp x)
(string-match "(s s +|--+)" x start))
(let ((replacement (substring (match-string 0 x) 0 1)))
(my-replace-modeline-format (replace-match replacement t t x)
(1+ start))))
(t x)))

(setq-default modeline-format
(mapcar 'my-replace-modeline-format modeline-format))

?



Oui, c'est cool. Sauf que j'aurais appele start compteur, mais c'est tout :-)
Amities,
Olivier
Avatar
drkm
Olve writes:

(defun my-replace-modeline-format (x &optional start)
""
(unless start
(setq start 0))
(cond ((and (stringp x)
(string-match "(s s +|--+)" x start))
(let ((replacement (substring (match-string 0 x) 0 1)))
(my-replace-modeline-format (replace-match replacement t t x)
(1+ start))))
(t x)))
(setq-default modeline-format
(mapcar 'my-replace-modeline-format modeline-format))



Oui, c'est cool. Sauf que j'aurais appele start compteur, mais c'est
tout :-)



Tu pinailles, là ;-) Mais cela m'a fait découvrir une petite erreur.
Il faut remplacer :

(1+ start))))

par :

(1+ (match-beginning 0)))))

Si je suis d'accord pour `X', je maintiens par contre le `START'.
Ce n'est pas un compteur (ce que pouvait laisser supposer la petite
erreur), mais bien une position de départ dana la chaîne. Et plus
important, c'est le nom qu'utilisent les fonctions de correspondance
de modèles, comme `string-match()'.

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
1 2 3