请教,org-mode里可不可以单独设置每个链接的打开方式?像html-a标签的target属性一样

如何在当前window打开org里的文件链接? 中的设置我的org文件都是在当前buffer打开的,这样通过动态改变org文件内容的办法把org-mode当成一个应用来用

这样做下去情况就是我的org文件中的链接越来越多,这样其实也正常,现在我们随便打开一个新闻网站什么的,一个页面都会包含几十或几百个链接在里面。但html里的链接a标签可以针对每个链接单独设置是在当前页面打开还是在新页面打开。

对于org-mode里的链接我也有这个需求,想设成默认在当前buffer窗口打开,但部分链接可单独设置为在其它窗口打开。这个该如何设置呢?

印象中可以的,有个变量可以定制,你这两种情况用什么特征来区别?

Edit:

变量 org-file-apps 用于控制如何打开 file:path 这样的本地路径;

http/https 类型的链接,由 browse-url-browser-function 变量控制的;

使用情况就是在org文件中作代码阅读笔记,方便在org中跳转到源文件的指定位置,解析源文件生成了一些链接,比如

** file://D:/t/mode/demo.php::@header
…………
** file://D:/t/mode/demo.php::@body
…………
** file://D:/t/mode/demo.php::@footer
…………

一个窗口打开org文件,点击org标题上的链接,另一窗口跳转到源码指定位置,特征就是这个链接是位于org文件的标题行上,带有::指定跳转位置,没有这个特征的就可以是在当前窗口打开了

目前想到2种方法:

  1. 通过 org-open-at-point-functions 变量定制一个函数
  2. 通过 org-file-apps 变量定制;

下面是我之前用 pdf-tools 的时候,用来跳到 pdf 指定页的,供参考下:

(defun whatacold/org-pdf-app (file-path link-without-schema)
  "Open pdf file using pdf-tools and go to the specified page."
  (let* ((page (if (not (string-match "\\.pdf::\\([0-9]+\\)\\'"
                                      link-without-schema))
                   1
                 (string-to-number (match-string 1 link-without-schema)))))
    (find-file-other-window file-path)
    (pdf-view-goto-page page)))

(setq org-file-apps
      '((auto-mode . emacs)
        ("\\.pdf\\(::[0-9]+\\)?\\'" . whatacold/org-pdf-app)
        ("\\.mkv" . "vlc \"%s\"")))
1 个赞

我是在org的链接里 直接运行elisp 的,现在是写成这个样子解决的

[[elisp:(progn (other-window 1)(org-open-file "D:/t/mode/demo.php" 0 nil "@header"))][@header]]

写成 file://D:/t/mode/demo.php::@header时,鼠标点击或回车最后调用的应该也是org-open-file这个方法

不是可以用自定义链接类型么

org-open-file的第4个参数是搜索词,搜索文件指定内容所在行跳转到指定位置,而不仅只是指定行号. 自定义链接类型不清楚怎么加搜索词

加搜索词是什么意思

就是file://D:/t/mode/demo.php::@header这个是在文件中搜索@header这个字符,跳转到这个字符所在的位置

自定义链接类型后也是可以做到的啊

比如我现在用的是这样的

(defun org-wiki-open (path _)
  "定义回车打开链接"
  (eye/open-git-file-v2 path))

(defun eye--org-wiki-completion (&optional arg)
  "定义complete,支持用C-c C-l的方式自动插入链接"
  (let* ((file-list (eye--get-dir-file-list (concat locale-notebook-dir "/org")))
	 sel-name)
    (setq sel-name (ivy-read "Select wiki note: " file-list))
    (setq sel-name (file-name-base sel-name))
    ;; (insert (format "[[wiki:%s]]" sel-name))
    (format "wiki:%s" sel-name)
    ))

(org-link-set-parameters "wiki"
			 :face '(:foreground "orange" :underline t)
			 :follow #'org-wiki-open
			 :complete 'eye--org-wiki-completion)

在 follow指定的函数中,path就是链接中的路径,例如链接 [[wiki:test-file.org]],org-wiki-open中解析这个path后想做什么事情都可以,完全可以自定义一个格式,[[wiki:test-file.org::@header]] 解析到::@时,就在打开文件后再搜索跳到那个位置,甚至可以传给swiper自动弹出提示选择。

我上面的 eye/open-git-file-v2 函数中,是通过git 查找文件,并弹出ivy选择。


(defun eye/open-git-file-v2 (&optional filename)
  (interactive)
  (let* ((default-directory (concat locale-notebook-dir "/org"))
		 (current-filename (file-name-base (buffer-name)))
		 temp-path)
    (shell-command "git ls-tree -r HEAD --name-only > list_files")
    (setq temp-path
	  (ivy-read "select:"
				(s-split "\n" (get-string-from-file "list_files"))
				:initial-input filename
				))
    (delete-file "list_files")
    (when (file-exists-p temp-path)
      (find-file temp-path)
      )))
1 个赞

自定义链接类型确实是个好办法,避免链接里的elisp代码写太多。