Emacs中python-mode函数的defadvice

5
在Python模式下,有一个名为py-execute-region的函数,它可以将代码的高亮区域发送到Python缓冲区进行评估。评估完成后,光标位于Python缓冲区中,但我希望它仍留在脚本缓冲区中,以便我可以继续编写更多的代码。我编写了一个简单的advising函数:
(defadvice py-execute-region                                                
   (after py-execute-region-other-window activate)                          
   """ After execution, return cursor to script buffer """                  
   (other-window 1)                                                         
) 

但这根本没有任何作用。我尝试过其他变体,比如使用“around”而不是“after”;将变量设置为脚本缓冲区名称,然后弹出到该缓冲区并进行类似的操作。但都没有成功!我想知道这个机制是否对某些人来说很明显...谢谢!

4个回答

9
在这种情况下,解决方案似乎是:
(custom-set-variables
 '(py-shell-switch-buffers-on-execute nil))

2
使用around-advice将函数包装在对save-window-excursion的调用中,该调用将在命令完成后恢复先前的窗口配置。
(defadvice py-execute-region
   (around preserve-window-configuration activate)
   "After execution, return cursor to script buffer"
   (save-window-excursion ad-do-it))

请注意,如果Python缓冲区尚未显示,则在命令完成后仍将隐藏。为了解决这个问题,您可以在最后添加另一个建议,调用switch-to-buffer-other-window:

(defadvice py-execute-region
   (after show-pybuf-other-window activate)
   "After execution, show the python buffer in another window."
   (switch-to-buffer-other-window "[PYTHON BUFFER NAME]"))

另外,请确保在elisp中不要使用"""三引号""",我认为它们无法正常工作。

谢谢!但这也不管用…… save-window-excursion听起来像我想要的,但它似乎没有做任何事情,而第二个则翻转了Python和脚本缓冲区的位置(尽管它确实将光标放在了脚本缓冲区最初所在的窗口中)。我最初尝试了一个类似于pop-to-buffer的东西,而不是switch-to-buffer-other-window,它也将Python缓冲区放入了脚本窗口中! - hatmatrix
如果你在save-window-excursion中运行一个命令,那么在它完成后,你的窗口配置应该与你之前运行命令时相同。确保你没有启用任何其他干扰的旧建议。 - Ryan C. Thompson
谢谢 - 是的,我的窗口配置没有改变,但光标最终停留在Python缓冲区中...我认为我理解了这个概念,但是为什么这个或其他尝试都不起作用,这让我感到困惑... - hatmatrix
从M-x describe-function save-window-excursion:“还会恢复所选窗口的选择。还会恢复当前缓冲区。”因此,save-window-excursion 应该 是您想要的。我尝试了(save-window-excursion (other-window 1)),它做到了我期望的,即把我放回到原来的位置。 - Ryan C. Thompson
是的...我已经尝试了你提供的所有建议,加载了新的emacs实例,但它们似乎都不起作用...我使用了插入函数来代替other-window,并且我指定的文本出现在正确的(脚本)缓冲区中,但光标总是停留在python缓冲区。我还尝试将py-execute-region包装在一个名为my-py-execute-region的函数中(我将其绑定到C-c|),该函数使用save-window-excursion、other-window和所有其他在此处列出的替代方法,但仍然无法解决问题。感谢你提醒我三重引号的问题-但似乎没有任何作用!困惑... - hatmatrix
请编辑您的原始答案并添加一些您尝试过的内容。如果您发布代码,我们可以帮助您调试它。——请在原始答案下方添加一个水平线。 - Ryan C. Thompson

1

我实际上没有尝试过这个,但是对于find-file,我做了类似的事情,在那里我需要在调用other-window之前调用interactive。我实际上并不真正了解Emacs Lisp,但这可能会起作用。

(defadvice py-execute-region                                                
   (after py-execute-region-other-window activate)                          
   (interactive)
   (other-window 1)                                                         
)

1

你那里的代码对我来说很好用。它应该会自动激活,所以不需要单独激活。但是,你需要取消激活并重新激活建议才能使更改生效:

1)定义并激活建议

2)它不能做你想要的事情,所以改变建议

3)取消激活:(ad-deactivate 'py-execute-region)

4)重新激活:(ad-activate 'py-execute-region)

第4步应该会捕捉到你在第2步中所做的更改。或者,你可以在第2步中更改代码,然后只需重新评估第4步中的代码(假设设置了激活标志)。


谢谢!...但对我来说仍然不起作用。如果我用(other-window 1)(insert "x")替换defadvice的主体,它会将“x”放入脚本缓冲区,但光标仍然在Python缓冲区中...非常令人困惑。 - hatmatrix
同一个函数中是否还有其他激活的建议?此时,我会启动一个纯净的emacs(emacs -q),加载Python模式,定义并激活您的建议,然后查看它是否仍无法正常工作。可能存在一些奇怪的交互作用。 - Joe Casadonte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接