2015-10-26 46 views
0

我的evil-commentary作者,完整的源不到200線可以在回購找到。無限循環當字節編譯

基本上,我有這樣的事情。

(evil-define-operator evil-commentary (beg end type) 
    "Comment or uncomment region that {motion} moves over." 
    :move-point nil 
    (interactive "<R>") 
    (let ((comment-function 
     (cdr (assoc major-mode 
        evil-commentary-comment-function-for-mode-alist)))) 
    (if comment-function (funcall comment-function beg end) 
     (comment-or-uncomment-region beg end)))) 


(defun evil-commentary-comment-for-org (beg end) 
    "Comment function for `org-mode'." 
    (interactive "r") 
    (if (and (fboundp 'org-in-src-block-p) 
      (org-in-src-block-p)) 
     (evil-commentary-do-in-org-src-block beg end 
     (call-interactively 'evil-commentary)) 
    (comment-or-uncomment-region beg end))) 

的想法是,evil-commentary將調用evil-commentary-comment-for-org在組織文件,如果我們在一個src塊,evil-commentary-comment-for-org將在src-edit緩衝區再次調用evil-commentary(現在有不同的major-mode

安裝工作得很好,但是當我編譯代碼時,我得到一個無限循環evil-commentary - >evil-commentary-comment-for-org - >evil-commentary ...與Variable binding depth exceeds max-specpdl-size錯誤...

我發現,它會如果我在加載org之後編譯代碼,則工作,但不是我想要的,因爲evil-commentary將在用戶編譯舊版本org後停止工作,然後升級它。 (中package.el中的一個缺陷)

謝謝!

+0

在看到Angus的回答之前,我認爲你在字節編譯期間看到了一個inf-loop。試着更準確地描述你看到的症狀。 – Stefan

回答

1

的問題是在this line,它擴展爲:

(org-babel-do-in-edit-buffer 
    (call-interactively 'evil-commentary)) 

如果您還沒有加載org,字節編譯器不知道org-babel-do-in-edit-buffer是一個宏觀的,不能展開。所以它只是編譯一個叫做org-babel-do-in-edit-buffer的函數(至今還未知)。

當執行到該行,函數的參數首先評估(如在任何其他函數調用),並有你有你的無限循環。

嘗試需要一個orgeval-when-compile內。

+0

謝謝,@angus。這就說得通了。我解釋了爲什麼我不想要求'org'的原因是,如果用戶在更新'org'之前安裝'evil-comment',那麼他將會遇到問題。我想知道我是否可以使用'declare-function'並以某種方式聲明它是一個宏(即不計算參數) –

+0

我不這麼認爲。無論如何,用'(eval ...)'環繞那個'org-babel-do ...'的調用,但這很醜陋。我想知道是否沒有任何鉤子告訴Emacs在另一個升級時重新編譯你的軟件包(我真的不太瞭解包裝)。 – angus

+0

是的,很遺憾,我們目前還沒有真正的解決方案。如果我找不到其他解決方案,我會堅持用'(eval ...)'的方式。再次感謝! –