2010-08-31 6 views
3

Donc, je me suis amusé avec this web site that creates random themes for Emacs. J'ai sauvegardé les fichiers .el résultants et les ai chargés au démarrage d'Emacs. Chaque thème de couleur peut être démarré en évaluant une expression elisp préfixée par inspiration-.Évaluation d'une fonction aléatoire elisp dans Emacs

Malheureusement, je ne sais pas elisp. Quelqu'un peut-il m'aider à comprendre comment je pourrais écrire une fonction qui regarde quelles fonctions préfixées "inspiration-" sont disponibles, et évaluer aléatoirement l'une d'entre elles?

Répondre

6

J'aime construire une solution à ces problèmes de manière incrémentielle. Si vous voulez juste essayer ma réponse, passez au bloc de code defun à la fin. Je vais dans le tampon *scratch*, dans lisp-interaction-mode pour essayer ces extraits de code. Vous pouvez taper C-j après une expression et Emacs l'exécutera et insérera les résultats dans le tampon.

La fonction apropos recherche les symboles correspondant à certains modèles, y compris les expressions régulières. Ainsi, nous pouvons trouver tous les symboles commençant par comme « inspiration- » si:

(apropos "^inspiration-\*" t) 

Mais ce résultat a une liste pour chaque symbole avec d'autres informations. Nous pouvons jeter cela et juste prendre le nom du symbole, qui vient en premier, en utilisant la fonction first:

(mapcar #'first (apropos "^inspiration-\*" t)) 

Certains d'entre eux ne sont pas des fonctions, donc retirons toutes celles qui échouent au test functionp:

(let ((symbols (mapcar #'first (apropos "^inspiration-\*" t)))) 
    (remove-if-not #'functionp symbols)) 

Maintenant, choisissons au hasard l'un d'entre eux. Je passe de let à let* car let* me permet de faire référence à des définitions antérieures dans la même initialisation, par ex. en utilisant symbols lors de la définition functions.

(let* ((symbols (mapcar #'first (apropos "^inspiration-\*" t))) 
     (functions (remove-if-not #'functionp symbols)) 
     (number (random (length functions)))) 
    (nth number functions)) 

Maintenant, nous allons transformer en une nouvelle fonction Lisp (et il ne faut pas avoir le début du nom avec inspiration-). Je vais le marquer comme interactive de sorte que vous pouvez l'exécuter via M-x use-random-inspiration en plus de l'utiliser dans un autre code elisp. L'autre grand changement est d'utiliser funcall pour exécuter réellement la fonction choisie au hasard:

(defun use-random-inspiration() 
    (interactive) 
    (let* ((symbols (mapcar #'first (apropos "^inspiration-\*" t))) 
     (functions (remove-if-not #'functionp symbols)) 
     (number (random (length functions)))) 
    (funcall (nth number functions)))) 

ajouter Pour que votre fichier $HOME/.emacs et l'essayer.

EDIT: Évitez la mémoire tampon Apropos pop-up

(defun use-random-inspiration() 
    (interactive) 
    (let* ((pop-up-windows nil) 
     (symbols (mapcar #'first (apropos "^inspiration-\*" t))) 
     (functions (remove-if-not #'functionp symbols)) 
     (number (random (length functions)))) 
    (funcall (nth number functions))) 
    (kill-buffer (get-buffer "*Apropos*"))) 
+0

Harold - je vous remercie. C'est exactement ce dont j'avais besoin. J'ai trouvé des "mapatoms" et j'ai commencé à essayer de construire quelque chose avec ça mais je ne savais pas que c'était une route lente à paver. C'est beaucoup plus simple. – qrest

+0

Il s'avère que le seul problème que j'ai est que la fonction apropos ouvre une nouvelle fenêtre dans le tampon * Apropos *. Je ne vois pas un moyen de le supprimer, mais pouvez-vous? – qrest

+0

M'a pris un moment pour comprendre que la fenêtre pop-up à propos. J'ai ajouté un correctif pour cela marqué comme un EDIT. Il s'avère que c'est un correctif en 2 parties. Tout d'abord, nous devons définir la variable pop-up-windows à zéro afin que l'écran ne soit pas divisé en deux. Cela fait que la fenêtre pop-up prend le contrôle de la fenêtre. Ensuite, nous pouvons tuer le tampon * Apropos * tout de suite pour retourner au tampon dans lequel nous étions. –

4

je travaillais sur une réponse à cela quand Harold m'a battu au poinçon. Mais, sa réponse m'a fait réfléchir. Je ne connaissais pas le générateur de thème Inspiration avant et j'aime vraiment l'idée! Donc, même si ce n'est pas ce que vous avez demandé, cela peut être intéressant pour les gens qui lisent cette question. Il sélectionne un thème aléatoire sur le site Inspiration, le télécharge dans un tampon, l'évalue et exécute la fonction résultante après avoir supprimé le tampon. Fondamentalement, ce sont des thèmes de couleurs aléatoires à la pression. Je n'ai pas encore trouvé le schéma de numérotation aléatoire pour la lumière et l'obscurité, mais si je le fais, cela pourrait facilement être transformé en une paire de fonctions random-dark et random-light.Que vous pouvez alors déclencher basé sur le lever du soleil et téléchargé coucher du soleil pour votre latitude et ... = LON)

(defun random-inspiration() 
    "Downloads a random Inspiration theme and evaluates it." 
    (interactive) 
    (let* ((num (number-to-string (random 1000000))) 
     (buffer (url-retrieve-synchronously 
        (concat "http://inspiration.sweyla.com/code/emacs/inspiration" 
          num 
          ".el")))) 
    (save-excursion 
     (set-buffer buffer) 
     (goto-char (point-min)) 
     (re-search-forward "^$" nil 'move) 
     (eval-region (point) (point-max)) 
     (kill-buffer (current-buffer)) 
     (funcall (intern-soft (concat "inspiration-" num)))))) 
0

Ce n'est pas vraiment une réponse, mais après avoir trouvé le générateur de thème d'inspiration, je voulais vraiment une belle façon de les modifier ...

Je fait cela ... http://jasonm23.github.com/

Questions connexes