分享一段简单的代码,它的作用是:
会把光标所在org-link的路径作为默认值显示在mini buffer,修改后回车就会重命名文件,并且更新org文件中所有指向这一文件的链接。
比较简单,有需要的同学可以自取,有bug可以在这里或者在gist下面留言。
好久不写elisp了,需要时不时热热身啊
(defun et/rename-org-link-file (path)
(interactive
(list
(let* ((link (org-element-context))
(old-path (org-element-property :path link)))
(read-string "PATH: " old-path nil old-path))))
(let ((old-path (org-element-property :path (org-element-context))))
(mkdir (file-name-directory path) t)
(rename-file old-path path)
(save-excursion
(goto-char (point-min))
(while (search-forward old-path nil t)
(replace-match path)))
(message (format "Rename %s to %s" old-path path)))
)
Edit 1: 当目标文件夹不存在时mkdir
2 个赞
这段代码比较令我不爽的是:org-element-context被重复调用了两次,一次是在interactive form里用于生成默认值,一次是在函数主体内。但是没有办法,因为好像不能把interactive放到let里?
这个好。经常是先改文件名,再去改链接名。但怎么用上呢
加到你的配置里(或者直接eval一下先试试再决定要不要加到配置里),然后M-x 找到这个命令就可以调用了,确保你的光标停留在org-link上
因为我的使用情形比较简单,遇到复杂情形可能不工作,如果有遇到可以在这里反馈。
哦。我改链接时是用默认的C-c C-l命令,我以为是搞成advice,链接修改后去改文件名
SPQR
2021 年4 月 3 日 17:21
7
应该写一个:around
advice就行了,比较一下调用org-link
(应该是C-c C-l的默认绑定?)前后的org-link路径值,然后如果两个值不一致就调用et/rename-org-link-file
,应该是可行的
还要考虑是否是文件类链接,考虑是重新指向其他文件还是重命名文件。不知还有没有其他的,似乎有点麻烦
SPQR
2021 年4 月 4 日 03:55
9
org-insert-link
里面是用正则匹配把link和description提取出来
仔细看了下好像并不是,这个正则会把link type也匹配了。。
((org-in-regexp org-link-bracket-re 1)
;; We do have a link at point, and we are going to edit it.
(setq remove (list (match-beginning 0) (match-end 0)))
(setq desc (when (match-end 2) (match-string-no-properties 2)))
(setq link (read-string "Link: "
(org-link-unescape
(match-string-no-properties 1)))))
SPQR
2021 年4 月 4 日 10:06
10
基于楼主的版本增加了对原文件是否存在的检查和link type的检查
(defun et/rename-org-link-file (path)
(interactive
(list
(let* ((link (org-element-context))
(old-path (org-element-property :path link)))
(read-string "PATH: " old-path nil old-path))))
(let* ((link (org-element-context))
(old-path (org-element-property :path link))
(ltype (org-element-property :type link)))
(if (and (file-exists-p old-path)
(member ltype '("file" "docview" "attachment")))
(progn (mkdir (file-name-directory path) t)
(rename-file old-path path)
(save-excursion
(goto-char (point-min))
(while (search-forward old-path nil t)
(replace-match path)))
(message (format "Rename %s to %s" old-path path)))
(message (format "!!!File type not valid or dose not exist!!! %s %s" ltype old-path)))))
3 个赞