Che*_*eso 6 emacs elisp defadvice advising-functions
我想要做的是智能地为compile函数的字符串参数预先设置缓冲区本地默认值.
现在compile.el默认使用"make"作为命令.我可以通过设置来设置它compile-command.我甚至可以将变量缓冲区本地化.如果我想要相同的静态值,那就行.
但我想compile-command根据缓冲区的内容,缓冲区的名称,文件的包含目录的内容(如果有的话)以及月亮的相位来智能地选择.基本上我想控制默认值,然后允许交互式用户覆盖该预设值.
我希望通过以前的建议来做到这一点.但这并不像我预期的那样有效.
阅读advice.el文件,我明白了
假设一个函数/宏/子/特殊形式有N条前建议,M条左右的建议和K条后建议.假设没有任何建议受到保护,其建议的定义将如下所示(正文形式索引对应于该通知类中相应建议的位置):
([macro] lambda <arglist>
[ [<advised-docstring>] [(interactive ...)] ]
(let (ad-return-value)
{<before-0-body-form>}*
....
{<before-N-1-body-form>}*
{<around-0-body-form>}*
{<around-1-body-form>}*
....
{<around-M-1-body-form>}*
(setq ad-return-value
<apply original definition to <arglist>>)
{<other-around-M-1-body-form>}*
....
{<other-around-1-body-form>}*
{<other-around-0-body-form>}*
{<after-0-body-form>}*
....
{<after-K-1-body-form>}*
ad-return-value))
Run Code Online (Sandbox Code Playgroud)
这对我说的是,当建议的函数是交互式的时,`call-interactively'在调用before建议或任何建议之前调用交互式表单.
而且,当我添加建议时compile,我观察到的行为证实了这一点.处理交互式表单后将调用该通知.交互式表单建议用于编译的字符串,在我的建议有机会猜测它应该是什么之前,并预先设置它.
所以...
compile-command为任何缓冲区动态预设?想法赞赏.
一种选择是compile-command在模式挂钩中设置变量,例如
(add-hook 'c++-mode-hook 'my-c++-set-compile-command)
(defun my-c++-set-compile-command ()
(setq (make-local-variable 'compile-command) (format "gmake %s" (buffer-file-name))))
Run Code Online (Sandbox Code Playgroud)
我有时会添加专门的命令来调整当前的编译行(打开/关闭调试标志,优化标志等),然后将这些命令绑定到迷你缓冲区中的方便按键.
关于在interactive表单之前添加建议,您需要提供具有您想要的交互式表单的建议(在之前或之前).来自advice.el库,一个例子:
;;(defadvice switch-to-buffer (around confirm-non-existing-buffers activate)
;; "Switch to non-existing buffers only upon confirmation."
;; (interactive "BSwitch to buffer: ")
;; (if (or (get-buffer (ad-get-arg 0))
;; (y-or-n-p (format "`%s' does not exist, create? " (ad-get-arg 0))))
;; ad-do-it))
Run Code Online (Sandbox Code Playgroud)
小智 5
compile-command不必是字符串.编译函数可以避免它,因此它可以是一个函数,它返回一个特定于缓冲区的字符串,或者取决于一天中的时间等等:
(setq compile-command (lambda () (if (eq phase-of-moon 'waning)
"make -DWANING=1"
"make -DWANING=0")))
Run Code Online (Sandbox Code Playgroud)
此外,虽然可能对您的特定需求没有用,但您始终可以在文件变量部分中定义compile-command:
/* -*- compile-command: "make -DFOO"; -*- */
Run Code Online (Sandbox Code Playgroud)
要么
// Local Variables:
// compile-command: "make -DSOMETHING_SPECIAL"
// End:
Run Code Online (Sandbox Code Playgroud)
compile-command实际上用作手册中文件变量的示例.
啊,你知道我做了什么吗?我使用了倾斜策略。
我已将 C-xC-e 全局设置为compile。我没有使用建议,而是定义了一个包装 的函数compile,然后将 C-xC-e 绑定到该。在包装器中,我对编译命令进行了猜测。
(defun cheeso-invoke-compile-interactively ()
"fn to wrap the `compile' function. This simply
checks to see if `compile-command' has been previously guessed, and
if not, invokes `cheeso-guess-compile-command' to set the value.
Then it invokes the `compile' function, interactively."
(interactive)
(cond
((not (boundp 'cheeso-local-compile-command-has-been-set))
(cheeso-guess-compile-command)
(set (make-local-variable 'cheeso-local-compile-command-has-been-set) t)))
;; local compile command has now been set
(call-interactively 'compile))
Run Code Online (Sandbox Code Playgroud)
猜测函数是这样的:
(defun cheeso-guess-compile-command ()
"set `compile-command' intelligently depending on the
current buffer, or the contents of the current directory."
(interactive)
(set (make-local-variable 'compile-command)
(cond
((or (file-expand-wildcards "*.csproj" t)
(file-expand-wildcards "*.vcproj" t)
(file-expand-wildcards "*.vbproj" t)
(file-expand-wildcards "*.shfbproj" t)
(file-expand-wildcards "*.sln" t))
"msbuild ")
;; sometimes, not sure why, the buffer-file-name is
;; not set. Can use it only if set.
(buffer-file-name
(let ((filename (file-name-nondirectory buffer-file-name)))
(cond
;; editing a .wxs (WIX Soluition) file
((string-equal (substring buffer-file-name -4) ".wxs")
(concat "nmake "
;; (substring buffer-file-name 0 -4) ;; includes full path
(file-name-sans-extension filename)
".msi" ))
;; a javascript file - run jslint
((string-equal (substring buffer-file-name -3) ".js")
(concat (getenv "windir")
"\\system32\\cscript.exe c:\\cheeso\\bin\\jslint-for-wsh.js "
filename))
;; something else - do a typical .exe build
(t
(concat "nmake "
(file-name-sans-extension filename)
".exe")))))
(t
"nmake "))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
768 次 |
| 最近记录: |