想问一下,用 insert-button 添加本地文件链接,action 失效问题

同样的lisp,放在 Scratch 中就能正常实现功能。

而放在配置文件中调用,就会出现:

Symbol’s value as variable is void: link

的错误提示。

不知道是什么原因,还是 lisp 写法的问题???

(defun blove/make-config-link (link)
  (insert-button link
				 'action (lambda (_) (find-file link))
				 'follow-link t
				 )
  (insert "\n")
  )

(defun blove/buffer-config-links ()
  (interactive)
  (let ((buf (get-buffer-create "*Blove Config Links*"))
		)
	(with-current-buffer buf
	  (erase-buffer)
	  (mapcar (lambda (item) (blove/make-config-link (expand-file-name item))) recentf-list)
	  )
  (pop-to-buffer buf t))
  )

你依赖了 rencetf-list 变量,而在加载的时候没法保证你的配置是先于 recentf 运行 还是后于它。要么用 autoload 要么用 with-eval-after-load.

而在 *Scratch* 里可以的工作原因是 rencetf 已经加载完毕,自然这个变量也就是 non-nil

1 个赞

你的 lambda 里的 link 需要 lexical-binding 才有定义,需要开启它,而 scratch 里从 27.1 开始默认开启了: https://github.com/emacs-mirror/emacs/blob/emacs-27.1/etc/NEWS#L319 一般建议所有地方(包括配置文件)都开启 lexical-binding。

1 个赞

非常感谢! :+1:
根据你的提示,给配置文件开头添加了:

;; -*- lexical-binding: t; -*-

就实现了预期的功能。

根据道友的提示,给配置文件开头添加了:

;; -*- lexical-binding: t; -*-

能够实现预期的功能了。

感谢提供思路!
而且通过您的叙述,了解到emacs加载的更多相关内容! :+1:

修整一下,只显示文件名,而不显示路径。点击打开文件。

修改后的完整代码

;; -*- lexical-binding: t; -*-

(defun blove/make-config-link (label link)
  (interactive)
  (insert-button label
				 'action (lambda (_) (find-file link))
				 'follow-link t
				 )
  (insert "\n")
  )
(defun blove/open-recentf-in-buffer ()
  (interactive)
  (let ((buf (get-buffer-create "*Recentf Buffer*")))
	(with-current-buffer buf
	  (erase-buffer)
	  (mapcar (lambda (item)
				(setq label (concat "\uf30c" " " (nth (- (length (split-string item "/")) 1) (split-string item "/")) " " "ﰺ"))
				(blove/make-config-link label item))
			  recentf-list)
	  )
	(pop-to-buffer buf t))
  )