Emacs Lisp 中的无效函数

Invalid function in Emacs Lisp

我正在 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))

当我定义函数、绑定它和 运行 时,我得到 "Invalid function" 并且它指向那条线。我是 运行宁 Linux 薄荷

使用 C-h f progn 按顺序计算多个表达式。

您目前正在尝试调用名为 (kill-ring-save (region-beginning) (region-end)) 的函数 并向其传递参数 (start-process-shell-command ...)

自然地,Emacs 会告诉您 (kill-ring-save (region-beginning) (region-end)) 不是函数的名称。

另外phils的回答:

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)))