【问题标题】:Invalid function in Emacs LispEmacs Lisp 中的无效函数
【发布时间】:2015-01-15 07:08:08
【问题描述】:

我正在 Emacs Lisp 中创建一个函数,如果没有活动区域,它将大声读取整个缓冲区。否则,它会读取活动区域。

(defun speak-my-text () "Speaks text in buffer."
  (interactive)
(if (equal mark-active t)
   (
    (kill-ring-save (point-min) (point-max))
      (start-process-shell-command "speakbuffvar" nil 
        "bash -c \"killall espeak;xsel --clipboard|espeak -s 290\"")
           )
  (
    (kill-ring-save (region-beginning) (region-end))
      (start-process-shell-command "speakbuffvar" nil 
        "bash -c \"killall espeak;xsel --clipboard|espeak -s 290\"")
           )))

(global-set-key (kbd "C-z") 'speak-my-text)

else 子句的第一行有问题:

(kill-ring-save (region-beginning) (region-end))

当我定义函数、绑定它并运行时,我得到“无效函数”并且它指向那条线。我正在运行 Linux Mint。

【问题讨论】:

标签: linux emacs elisp


【解决方案1】:

使用C-h f progn 依次计算多个表达式。

您当前正尝试调用一个名为 (kill-ring-save (region-beginning) (region-end)) 的函数并将参数传递给它 (start-process-shell-command ...)

当然,Emacs 是在告诉你(kill-ring-save (region-beginning) (region-end)) 不是函数的名称。

【讨论】:

    【解决方案2】:

    除了菲尔斯的回答:

    mark-active 在这种情况下不可靠,因为它可能是 如果一个区域没有扩展,也非零。

    函数region-active-p 可以使用,但取决于 活跃的transient-mark-mode,这可能是无关的——在大多数情况下 顺便说一句,它是有用且足够的。

    这是一个如何检查大于的有效区域的示例 零和超过transient-mark-mode 问题:

    (defun ar-region-active-p ()
      "Check for and existing region of some extend.
    
    Don't mix up that question with transient-mark-mode "
      (interactive)
      (and (ignore-errors (region-beginning))(region-end) (< (region-beginning)(region-end))))
    

    基于此,您的命令可能会略有不同:

    (defun my-command-on-region ()
      "If a region of some extend exists, use on it.
    
    Otherwise use whole buffer.
    
    Doesn't require `transient-mark-mode' being active"
      (interactive)
      (let ((beg (or (and (ignore-errors (region-beginning))(region-end) (< (region-beginning)(region-end))(region-beginning))
             (point-min)))
       (end (or (and (ignore-errors (region-beginning))(region-end) (< (region-beginning)(region-end))(region-end))
             (point-max))))
        (DO-SOMETHING beg end)))
    

    【讨论】:

    • 非常感谢备用 if 设置和指向 progn 的指针。
    • 虽然这个答案有一些很好的建议,但它并没有解决错误的原因。 @phils 已正确确定实际原因。重要的是要记住,在 lisp 中,未引用列表中的第一个元素应该是一个函数。在您的代码中,您有一个列表,其中第一个元素是 (kill-ring-save (region-begin) (region-end))。为了使其正确执行,它需要返回一个函数 - 或者至少是一个解析为函数的符号。一般来说,在 lisp 语言中,你不能只使用 () 来嵌套表达式,你需要 prog 之类的东西。
    • @TimX 除了 phils 的答案 - 已编辑,以明确这一点。
    • TimX:在elisp中,第一个元素必须是函数符号或lambda表达式;它不能是任意表达式返回一个函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多