2010-08-31 78 views
3

因此,我一直在this web site that creates random themes for Emacs上玩。我一直保存結果.el文件並在啓動Emacs時加載它們。通過評估以inspiration-爲前綴的elisp表達式,可以開始每個顏色主題。評估Emacs中的隨機elisp函數

不幸的是,我不知道elisp。有人可以幫助我弄清楚,我可能會寫一個函數來查看「靈感」前綴函數是否可用,並隨機評估其中一個函數?

回答

6

我喜歡逐步建立這些問題的解決方案。如果您只想嘗試我的答案,請跳至末尾的defun代碼塊。我去*scratch*緩衝區,在lisp-interaction-mode嘗試這些代碼片斷。在表達式之後您可以鍵入C-j,Emacs將運行它並將結果插入緩衝區。

apropos函數搜索符合某些模式的符號,包括正則表達式。因此,我們可以找到以「inspiration-」像這樣所有符號:

(apropos "^inspiration-\*" t) 

但是結果對於其他一些信息的每個符號的列表。我們可以丟棄,只是把符號名稱,這是第一位的,使用first功能:

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

他們有些是沒有的功能,讓我們刪除任何失敗的functionp測試:

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

現在讓我們隨機選擇其中之一。我正在從let切換到let*,因爲let*允許我在相同的初始化中引用較早的定義,例如,定義functions時使用symbols

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

現在,讓我們把它轉換成一個新的口齒不清功能(讓我們不要有名字開始與inspiration-)。我將其標記爲interactive,以便除了在其他elisp代碼中使用它之外,還可以通過M-x use-random-inspiration運行它。另一個大的變化是使用funcall實際運行隨機選擇的功能:

(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)))) 

所以添加到您的$HOME/.emacs文件,並嘗試一下。

編輯:當哈羅德打我衝避免中肯緩衝彈出

(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

哈羅德 - 謝謝你。這正是我需要的。我發現了「mapatoms」,並開始嘗試用這種方法來構建某些東西,但不知道elisp,這是鋪平道路的一條緩慢道路。這更直接。 – qrest 2010-08-31 07:55:10

+0

原來我遇到的唯一問題是apropos函數會在* Apropos *緩衝區中創建一個自己的新窗口。我沒有辦法壓制它,但你能嗎? – qrest 2010-08-31 16:09:42

+0

花了我一會兒才弄清楚apropos窗口彈出。我已經添加了一個標記爲EDIT的修復程序。原來它是一個2部分的修復。首先,我們需要將彈出窗口變量設置爲零,以便屏幕不會分裂成一半。這使得彈出窗口占據了窗口。然後我們可以立即殺死* Apropos *緩衝區,回到我們所在的緩衝區。 – 2010-09-03 05:39:39

4

我工作的一個答案。但是,他的回答讓我思考。我之前並不知道靈感主題生成器,我非常喜歡這個主意!所以,儘管這不是你要求的,但讀者仍然可能會很感興趣。它從Inspiration站點中選擇一個隨機主題,將其下載到緩衝區中,對其進行評估,並在刪除緩衝區後執行結果函數。

基本上,它是隨機的顏色主題。我還沒有計算出光照和黑暗的隨機編號方案,但如果這樣做,這可以很容易地變成一對random-darkrandom-light函數。然後你可以觸發基於下載的日出和日落時間爲您的緯度和經度... =)

(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

這是不是一個真正的答案,但找到的靈感主題發生器之後,我真想一個不錯的方式來調整它們...

所以我做了這個... http://jasonm23.github.com/