【«已解决»| 求助】 更优雅地退出交互函数

(defun 例子 ()
  (interactive)
  ...

  (if (条件)
      (progn (函数-1)
             (signal 'quit nil)))
  ...
  (其他函数))

如果满足 条件,在完成该分枝上的函数后,且在不执行 其他函数的情况下,退出 例子这个交互函数。

目前上述写法,可行但不优雅。大家有什么想法么?

不知道怎么样算优雅,这种情况我一般都用 catch, throw, 似乎更不优雅?

楼主的版本,会在 Mini buffer 显示 quit, 想办法去掉这个提示。

最开始楼主也是想用 catch, throw

(defun 例子 ()
  (interactive)
  ...
  (catch 'early-exit
    (if (条件)
        (progn (函数-1)
               (throw 'early-exit "尊敬的用户,您已提前退出函数。"))))
  ...
  (其他函数))

虽然也能实现退出功能,但出现下面的提示:

command-execute: Wrong type argument: listp, "尊敬的用户,您已提前退出函数。"

看来是没能领会正确使用 catch, throw 的方法。

catch 需要包住所有代码才行,你写的还是会执行 “其他函数”。

这个错误无法理解,按理是没有问题的。应该是其他代码的问题。

首先,其他函数应该放在catch里吧,不然throw了catch完还是会执行。

另外,那个error是command-execute的吧,你贴的代码看不出来哪里出问题了。


直接把其他函数放到else里不行吗……

是哦,这不就是 if else 的逻辑吗,我人都傻了…

感谢两位 @Kinney@misaki 帮助

问题函数源自楼主的这个 PR: https://github.com/Kungsgeten/org-brain/pull/345/files

(defun org-brain-visualize (entry &optional nofocus nohistory wander)
  ...)

只是想在搜索之前,添加一个判断。

(list
      (org-brain-choose-entry
       "Entry: "
   ...))

如果该判断成立,则不执行下面的函数,正常跳出 org-brain-visualize

catch 需要包住所有代码才行,你写的还是会执行 “其他函数”。

稍后我再试试不同位置包裹所有代码。

直接把其他函数放到else里不行吗

不行,还是会执行下面的交互函数

(let ((result (catch 'k
		(throw 'k (+ 1 1))
		(message "Unreachable!"))))
  (message "Result is %d" result))

必须包住所有可能会被跳过执行的代码。

catch类似一个带label的block(也有时髦人叫escape continuation),throw会立刻返回一个值(作为这个block的返回值)不再执行剩余代码

最终的解决方案是由 Kungsgeten 重写了一个包裹函数

把原来要执行的交互函数,放在了新包裹函数中若干判断的最后一个。

直接把其他函数放到else里不行吗

直接改原来的函数,让 if-else 一个分枝极其不对称。而且这个条件执行在 (interactive ...) 里面,会把原函数复杂化。

还是没能用上 catch throw,以后有机会再研究。

多谢 @misaki @Kinney@cireu 帮助。

举一反三, 下面这个函数可以批量设置 Org-headline 的优先级。

只要把想处理的 Org-headlines 标记上,然后呼叫这个函数,就可以批量处理。

(defun my/org-priority (&optional action show)
  (interactive "P")
  (if (and (org-region-active-p) org-loop-over-headlines-in-active-region)
      (let ((cl (if (eq org-loop-over-headlines-in-active-region 'start-level)
		    'region-start-level 'region))
	    org-loop-over-headlines-in-active-region)
	(org-map-entries
	 (lambda () (org-priority))
	 nil cl
	 (when (org-invisible-p) (org-end-of-subtree nil t))))
    (call-interactively #'org-priority)))

python js elisp的try catch 我都是拿来当高级goto用的,

反正不是严肃的事情, 怎么方便怎么来(逃