美文网首页Emacs/VimEmacs LispEmacs
Emacs上下文引起的Elisp宏展开及编译问题

Emacs上下文引起的Elisp宏展开及编译问题

作者: 齐格Insight | 来源:发表于2016-08-14 09:19 被阅读134次

    问题

    在开发leanote-emacs这个包的时候,我定义了一个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中定义的一个宏。我发现,如果我将leanote的安装放在spacemacs的启动安装包里时。当emacs启动完成后,我执行M-x leanote-spaceline-status打开leanote的modeline的status时会报如下错误:

    (invalid-function spaceline-define-segment)
    

    我感到很困惑,为什么说是invalid-function无效的函数?可它明明是一个宏呀!

    定位

    不过,令我感觉奇怪的是,当我的emacs启动完成后(注:我emacs是安装了spaceline这个包的),我再手工安装leanote-emacs时不会报这个错。我将两次安装时leanote.el编译后的leanote.elc文件打开看,发现它们不一样,如下:


    报错时leanote.elc文件
    正确的结果

    原因

    emacs是有上下文的(如一些变量及包),当编译leanote.el这个文件的时候,上下文不一样,最后导致的编译结果会不一样。第一次将leanote放在spacemacs启动安装里时,因为这个时候spaceline这个feature还没有载入到emacs的上下文中。因此,编译leanote.el文件时,编译器并不知道spaceline-define-segment它是一个宏,因此,它就不会对其进行宏展开,只认为它是一个普通的函数。第二次,当我手工进行安装的时候,这个时候上下文中已经存在spaceline这个包,也就是spaceline-define-segment这个宏的声明已经在emacs的上下文中。所以,编译器会将这个宏进行展开,而不会将它视为一个函数对待。

    相关文章

      网友评论

        本文标题:Emacs上下文引起的Elisp宏展开及编译问题

        本文链接:https://www.haomeiwen.com/subject/gbsysttx.html