問(wèn)題
在開(kāi)發(fā)leanote-emacs這個(gè)包的時(shí)候,我定義了一個(gè)spaceline的segement,代碼如下:
(defun leanote-spaceline-status ()
"Install spaceline status, need spaceline 2.x version."
(interactive)
(require 'spaceline)
(spaceline-define-segment leanote-status-seg
"show the leanote status"
(when leanote-mode
(powerline-raw
(s-trim (leanote-status)))))
(spaceline-spacemacs-theme 'leanote-status-seg)
(spaceline-compile))
其中spaceline-define-segment是在spaceline中定義的一個(gè)宏。我發(fā)現(xiàn),如果我將leanote的安裝放在spacemacs的啟動(dòng)安裝包里時(shí)。當(dāng)emacs啟動(dòng)完成后,我執(zhí)行M-x leanote-spaceline-status打開(kāi)leanote的modeline的status時(shí)會(huì)報(bào)如下錯(cuò)誤:
(invalid-function spaceline-define-segment)
我感到很困惑,為什么說(shuō)是invalid-function無(wú)效的函數(shù)?可它明明是一個(gè)宏呀!
定位
不過(guò),令我感覺(jué)奇怪的是,當(dāng)我的emacs啟動(dòng)完成后(注:我emacs是安裝了spaceline這個(gè)包的),我再手工安裝leanote-emacs時(shí)不會(huì)報(bào)這個(gè)錯(cuò)。我將兩次安裝時(shí)leanote.el編譯后的leanote.elc文件打開(kāi)看,發(fā)現(xiàn)它們不一樣,如下:


原因
emacs是有上下文的(如一些變量及包),當(dāng)編譯leanote.el這個(gè)文件的時(shí)候,上下文不一樣,最后導(dǎo)致的編譯結(jié)果會(huì)不一樣。第一次將leanote放在spacemacs啟動(dòng)安裝里時(shí),因?yàn)檫@個(gè)時(shí)候spaceline這個(gè)feature還沒(méi)有載入到emacs的上下文中。因此,編譯leanote.el文件時(shí),編譯器并不知道spaceline-define-segment它是一個(gè)宏,因此,它就不會(huì)對(duì)其進(jìn)行宏展開(kāi),只認(rèn)為它是一個(gè)普通的函數(shù)。第二次,當(dāng)我手工進(jìn)行安裝的時(shí)候,這個(gè)時(shí)候上下文中已經(jīng)存在spaceline這個(gè)包,也就是spaceline-define-segment這個(gè)宏的聲明已經(jīng)在emacs的上下文中。所以,編譯器會(huì)將這個(gè)宏進(jìn)行展開(kāi),而不會(huì)將它視為一個(gè)函數(shù)對(duì)待。