在 emacs-lisp 中包装带引号的函数
我使用 cscope emacs 扩展(并且发现它非常有用)。 不幸的是,仅搜索当前目录及以下目录的默认行为对我来说是不够的,因此我使用 cscope-set-initial-directory 到我选择的目录。 不幸的是,这对我来说也不够,因为我有多个不同的项目,每个项目都有自己的“初始”目录。
我已经为我在 emacs 中最常使用的三个 cscope 方法设置了热键,
(global-set-key [f9] 'cscope-find-this-text-string)
(global-set-key [f8] 'cscope-find-global-definition)
(global-set-key [f7] 'cscope-find-this-symbol)
我认为以某种方式用一个函数包装这些调用以在给定路径上运行 cscope-set-initial-directory (通过查看生成的缓冲区文件名是什么)。 但我还没有成功!
(global-set-key [f9] (lambda () (interactive) (cscope-set-initial-directory "blah") 'cscope-find-this-text-string))
不起作用。 我还尝试向两个 cscope-hooks 添加钩子,但在我的正常使用模式中,这两个钩子似乎都没有被调用。 我什至不介意每次切换缓冲区时运行一次,但我也没有在任何地方看到它的钩子:/。
有人可以帮忙吗? :)
I use the cscope emacs extension (and find it quite useful). Unfortunately, it's default behaviour of only searching the current directory and below is insufficient for me, so I use the cscope-set-initial-directory to the directory of my choice. Unfortunately this has become insufficient for me as well because I have multiple different projects each with their own "initial" directory.
I have set up hot keys for the three cscope methods I use the most in emacs
(global-set-key [f9] 'cscope-find-this-text-string)
(global-set-key [f8] 'cscope-find-global-definition)
(global-set-key [f7] 'cscope-find-this-symbol)
I figured it would be pretty easy to somehow wrap those calls with a function to run cscope-set-initial-directory on a given path (generated by looking at what the buffer-file-name is). But I have as-yet been unsuccessful!
(global-set-key [f9] (lambda () (interactive) (cscope-set-initial-directory "blah") 'cscope-find-this-text-string))
doesn't work. I've also tried adding hooks to the two cscope-hooks, but neither of those seem to ever get called during my normal usage patterns. I wouldn't even mind running it once every time I switch buffers, but I didn't see a hook for that anywhere either :/.
Can someone help? :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
免责声明:我尚未安装 cscope,因此无法对此进行测试。
基本想法是您想要提示输入一个目录:这就是对 Interactive 的调用。 然后设置目录:let 语句会为您完成此操作。 然后,您调用所需的原始例程,并通过使用“call-interactively”调用它,您会收到提示。
您可以类似地包装其他两个例程。
一旦这对您有用,您可以通过自定义根区域的提示来获得更奇特的效果,以拥有自己的历史变量,并在三个例程之间共享。
关于您最初的解决方案,这是一个很好的尝试。 大多数人没有意识到需要通过“交互式”将功能转变为命令。 引用名称对您不起作用的原因是,引用只是告诉解释器将符号视为符号,而不对其进行任何操作。 要调用该例程,您通常会这样做:
不幸的是,对于像上面这样的直接调用,您必须提供一个参数(要搜索的字符串)。 因此,您可以添加一些代码来提示输入字符串,或者使用命令的内置代码来进行提示。 这就是“
call-interactively
”的用途,它调用命令并调用其“”interactive
表单来进行提示。此外,将击键绑定到命令名称(而不是裸露的 lambda)通常是个好主意,原因有两个:首先,如果您曾经执行过
Ch k
(Mxdescribe-key
code>),你会得到一个有意义的命令名称,其次,如果/当你修改函数时,你可以这样做而不必破坏绑定。Disclaimer: I've not installed cscope so cannot test this.
The basic idea being you want to prompt for a directory to start from: that's the call to interactive. Then you set the directory: the let statement does that for you. Then you call the original routine you wanted, and by calling it with
'call-interactively
you get prompted.You'd wrap the other two routines similarly.
Once that's working for you, you can get fancier by customizing prompt for a root area to have its own history variable that's shared across the three routines.
Regarding your initial solution, that was a good try. Most don't realize the need for
'interactive
to turn the function into a command. The reason the quoted name doesn't work for you is that the quote simply tells the interpreter to treat the symbol as a symbol and not do to anything with it. To call the routine, you'd generally do:Unfortunately, with a direct call like the one just above, you have to provide an argument (the string to search for). So, you can either add some code to prompt for the string, or use the command's built-in code to do the prompting. That's what the '
call-interactively
is used for, it calls the command and invokes its'interactive
form which does the prompting.Also, it's generally a good idea to bind keystrokes to names of commands, as opposed to bare lambdas, for two reasons: first, if you ever do
C-h k
(M-x describe-key
), you get a meaningful command name, and second, if/when you modify the function, you can do so without having to muck with the binding as well.