简体   繁体   English

如何将参数传递给Elisp函数?

[英]How to pass arguments to Elisp function?

I have this keymap to flush empty lines like this: 我有这个键盘映射来刷新像这样的空行:

(global-set-key (kbd "M-T") (lambda () (interactive) (flush-lines "^[[:space:]]*$")))

But this doesn't work over a region. 但这在某个地区不起作用。 Unrelated lines out of the region are getting merged. 区域之外无关的行将被合并。 But when I select a region and manually try Mx flush-lines RET ^[[:space:]]*$ RET, it works as expected. 但是,当我选择一个区域并手动尝试使用Mx刷新线RET ^ [[:space:]] * $ RET时,它可以按预期工作。 What am I doing wrong ? 我究竟做错了什么 ?

A function can be called interactively or non-interactively (this is in fact a little bit more complex, but that's a good enough approximation). 可以交互式或非交互式地调用一个函数(实际上稍微复杂一点,但这足够好了)。 The interactive calling mode is used to bind some function arguments from the current environment, or by interacting with the user. 交互式调用模式用于绑定当前环境中的某些函数自变量或与用户进行交互。 The non-interactive mode is the normal calling mode when you write in Emacs Lisp. 当您使用Emacs Lisp编写时,非交互模式是正常的调用模式。

Typically, the interactive behaviour is declared using an (interactive ...) form after the docstring, but in the particular case of flush-lines , the behaviour is partly automated by an interactive spec, and partly hardcoded (for the region part). 通常,交互式行为是在文档字符串之后使用(interactive ...)形式声明的,但是在flush-lines的特定情况下,该行为部分由interactive规范自动实现,并且部分由硬编码(对于区域部分)组成。 You can ask Emacs whether the current code is executed interactively by calling called-interactively-p , but as the doc say, it is encouraged to have another optional argument that indicates whether the call is interactive. 您可以通过调用call called-interactively-p来询问Emacs当前代码是否以交互方式执行,但是正如文档所说,鼓励使用另一个可选参数来指示调用是否是交互式的。

The function signature is: 函数签名为:

(flush-lines REGEXP &optional RSTART REND INTERACTIVE)

RSTART and REND are the starting and ending position of the current region, as integers. RSTARTREND是当前区域的开始和结束位置,以整数表示。 They can also be nil . 他们也可以是nil The last parameter indicates whether the call is interactive. 最后一个参数指示呼叫是否是交互式的。

When you call flush-lines from your anonymous function, you are calling it non-interactively, which means you need to pass arguments explicitly to the functions. 当您从匿名函数调用flush-lines ,您是在非交互方式下调用它,这意味着您需要将参数显式传递给函数。

For this function, you can simply call it as follows: 对于此功能,您可以简单地按如下方式调用它:

(flush-lines "^[[:space:]]*$" nil nil t)

This makes the function behaves as-if called interactively, in which case the region is computed automatically since the start and end argument are nil. 这使得该函数的行为就像是被交互调用一样,在这种情况下,由于start和end参数为nil,因此会自动计算区域。

In the general case, what you would do is have your own (interactive "r") declaration, and add two parameters to the anonymous function. 在一般情况下,您要做的是拥有自己的(interactive "r")声明,并向匿名函数添加两个参数。 For example, in the *scratch* buffer, you can evalue this expression: 例如,在*scratch*缓冲区中,您可以对以下表达式求值:

(call-interactively
  (lambda (beg end)
    (interactive "r")
    (list beg end)))

Then, the result is a list of cursor positions, that represents your region. 然后,结果是代表您所在地区的光标位置列表。 In your case you would call (flush-lines "^[[:space:]]*$" beg end) , for example. 例如,在您的情况下,您将调用(flush-lines "^[[:space:]]*$" beg end)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM