emacs autoload 集裝箱

火星人 @ 2014-03-12 , reply:0


  

「它看起來像個函數!」

首先,什麼是 autoload?

實際上,它就是個函數。

所謂「實際」,是指在實際使用的時候,你是區分不出來 autoload 和普通函數的區別的。

autoload 在 emacs 中也是一種類型,和符號、數字、字元串、函數是同等級別的對象,它和函數的區別類似於函數原型和函數的區別——沒有實際的定義,只有簡單說明, 調用的時候才載入相關定義。

autoload 對象需要用 autoload 函數生成,類似下面這種:

(autoload 'fn "file" "docstring" interactive type)

參數包含: fn (沒有名稱你敢怎麼調用) file (具體定義實際存儲的位置) docstring (使用說明) interactive (如果非 nil 表示可以通過交互方式調用) type (類型:函數、宏、鍵圖)

使用 autoload 有什麼好處?簡單的說就是節約資源,包括廣大人民群眾喜聞樂見的縮短 emacs 啟動時間……當然作為一個實誠人,我必須說,效果不明顯。

更有意義的就是在載入方面,因為載入 autoload 的時候,是把該 autoload 所在文件一起讀取,所以理論上,你可以一個 require 也不用寫,全用 autoload !某種程度上,這也是一種抽象,你不用再為載入哪個文件犯愁,比如有些該載入的文件沒有載入——其實也沒什麼問題,無非是報錯,然後除錯——相信自己,這不算什麼,尤其是比起不該載入的文件被載入這種情況,起碼它還會報錯不是?

如果你足夠細心,會發現很多 emacs 內置的 elisp 文件,你並不需要顯式的 require/load ,用到的時候就載入了,很是神奇。打開這些文件,可以看到裡面有一些 「;;;###autoload」 樣子奇怪的東東(autoload magic cookies)。

我曾經也認為,在函數定義前面添上 magic cookies 就萬事大吉了。其實完全不是這麼回事,理論上還需要調用 update-directory-autoloads 之類的函數,根據 magic cookies 生成 autoload 定義文件,然後再讀取該文件。

關鍵的問題是 emacs 內置的 update-directory-autoloads 並不好用,參數很古怪,完全讓人無所適從。甚至在 emacs 24 之前,要通過指定外部變數 generated-autoload-file 來確定輸出文件……你根本無法理解,函數和函數之間的差距咋就這麼大呢!

其實這些也不是沒有人能夠忍受,如果你是個 M 的話;關鍵的問題在於,它生成的 autoload 定義,位置參數只是一個文件名!

然後怎麼找到這個文件呢?很簡單,這個文件要在 load-path 裡面,如果你把自己收集整理的函數放在一個文件夾中的話,那麼你要把這個文件夾加入 load-path ……當然這也不是什麼問題,然後你要給文件起一個名字,比如你把一些函數放在 xxx.el 裡面,然後會發生什麼事情呢?

假設 emacs 自帶了一個 xxx.el(a) 文件,在 load-path 中,它裡面定義了一個 autoload 函數 y;而你自己的 xxx.el(b) 文件也加入 load-path,那麼當你調用 y 的時候,它會到你自己的 xxx.el(b) 文件中查找,然後就悲劇了。

這有點類似於 lisp-1 中的變數捕獲,所以我給它起了一個好聽的名字:文件捕獲。為了避免這個有著好聽名字的問題,我給自己的文件起些不太好聽的名字,類似 +xxx.el 這樣,人生真是寂寞啊……

所以,如果能夠在 autoload 中指定文件位置的話,就可以避免像這樣淪落為一個寂寞的二逼青年,為了成為一名正義的二逼青年,我弄了這麼個東東,主要特點:

1.不再依賴於 load-path ,你可以自己指定位置,生成的 autoload 定義是這樣的(保存在loaddefs文件中的定義)

(autoload 'calc-column (expand-file-name "_autoload/column" *init-dir*) "Not documented.\n\n(fn fn)" t nil)

可以看到,路徑的位置是一個表達式,使用相對位置來定位,執行上面定義,得到定義為(讀取loaddefs文件后得到的定義)

(autoload "d:/apps/emacs/init.emacs/_autoload/column" "Not documented.

(fn fn)" t nil)

2.loaddefs 文件中使用列表來保存數據,比較文藝;而 emacs 自帶的版本,文件名和時間的信息保存在註釋中。但是從另一個方面來說,原來版本的 loaddefs 可以直接 load,而現在的這個需要有一個專用的函數來載入,這點比較二逼。

3.使用簡單

(loaddefs-update 文件夾 基準文件夾)

其中文件夾放置函數定義,然後生成 autoload 定義,裡面使用的文件參數是相對於基準文件夾的路徑

當然,問題也必須有,主要是文件IO方面的問題,emacs 在這方面弱智的讓人心碎。目前來說,可能你要在目標文件夾中自己創建一個 _loaddefs 文件,運行完 loaddefs-update 之後可能還需要手動保存……

另外,生成的 autoload 表達式和原版的可能不完全一樣,但是並不影響使用。山寨的,你懂的

文件下載地址





[火星人 via ] emacs autoload 集裝箱已經有112次圍觀

http://www.coctec.com/docs/linux/show-post-65030.html