如何在Emacs缓冲区中同时打开多个URL?

问题描述 投票:0回答:1

我使用Emacs编辑器连同org-mode和evil-mode主要是用于文字处理和文档。经常会有一个主题,几个不同的网站URL所属。

举个例子。我有一个关于如何安装Emacs的文本片段。

*** install emacs

emacs - I want to try org-mode. What's the shortest path from zero to typing? - Stack Overflow
https://stackoverflow.com/questions/4940680/i-want-to-try-org-mode-whats-the-shortest-path-from-zero-to-typing

Index of /gnu/emacs/windows/emacs-26
http://ftp.gnu.org/gnu/emacs/windows/emacs-26/emacs-26.3-x86_64.zip

Installation target:
file://C:\Lupo_Pensuite\MyApps\emacs

How to
file://C:\Lupo_Pensuite\MyDocs\howto.txt

是否可以选择区域,所有的URL都在我的默认网络浏览器中打开?而文件链接是在Windows资源管理器内打开的?而文本文件是用相关的编辑器打开的?

或者更好的是:emacs知道a.m.文本片段实际上是一个org模式的章节。不管光标在该章中的哪个位置,像M-x open-all-links-in-chapter这样的操作都是......打开当前章中所有提到的链接。

Prio 1: emacsorg-modeevil-mode中是否已经有类似的东西存在?

Prio 2: 有没有你知道的 elisp 函数可以实现这个用例?

环境:Windows 10下的Cygwin,emacorg模式下的evil-mode。Windows 10下的Cygwin,emacs 26.3,org-mode 9.1.9。

url emacs org-mode evil-mode
1个回答
1
投票

警告:不经意间使用了以下内容 可以 让你的机器屈服。我将在最后添加一些更具体的警告,但要小心!

下面代码的基本思想是解析一个Org模式文件的缓冲区,以获得缓冲区的解析树:通过以下方式完成。org-element-parse-buffer. 然后我们可以使用 org-element-map 来行走解析树,并选择 只是 节点 link我们对每一个都应用了一个函数。我们应用的函数。get-link,通过链接节点的内容,提取类型和路径,并返回这两个内容的列表。这是目前的情况。

(defun get-link (x)
  (let* ((link (cadr x))
         (type (plist-get link :type))
         (path (plist-get link :path)))
   (if (or (string= type "http") (string= type "https"))
     (list type path))))

(defun visit-all-http-links ()
  (interactive)
  (let* ((parse-tree (org-element-parse-buffer))
         (links (org-element-map parse-tree 'link #'get-link)))
    links))

注意,我只保留了 httphttps 链接:你可能想要添加额外的类型。

这已经很好地实现了你想要的东西。事实上,如果你用上面的两个函数加载文件,你可以在下面的Org模式示例文件上尝试。

* foo
** foo 1
http://www.google.com
https://redhat.com
* bar
** bar 2
[[https://gnome.org][Gnome]] is a FLOSS project. So is Fedora: https://fedoraproject.org.


* Code
#+begin_src emacs-lisp :results value verbatim :wrap example
(visit-all-http-links)
#+end_src

#+RESULTS:
#+begin_example
(("http" "//www.google.com") ("https" "//redhat.com") ("https" "//gnome.org") ("https" "//fedoraproject.com"))
#+end_example

并评估源块 C-c C-c,你得到的结果显示。

现在我们需要做的是将每个 (TYPE PATH) 对,然后访问它--这是代码的最终版本。


(defun get-link (x)
  "Assuming x is a LINK node in an Org mode parse tree,
   return a list consisting of its type (e.g. \"http\")
   and its path."
  (let* ((link (cadr x))
         (type (plist-get link :type))
         (path (plist-get link :path)))
   (if (or (string= type "http") (string= type "https"))
     (list type path))))

(defun format-url (x)
  "Take a (TYPE PATH) list and return a proper URL. Note
   the following works for http- and https-type links, but
   might need modification for other types."
  (format "%s:%s" (nth 0 x) (nth 1 x)))

(defun visit-all-http-links ()
  (interactive)
  (let* ((parse-tree (org-element-parse-buffer))
         (links (org-element-map parse-tree 'link #'get-link)))
    (mapcar #'browse-url (mapcar #'format-url links))))

我们添加了一个函数 format-url ,做到这一点。("http" "//example.com") --> "http://example.com" 并将其映射到链接列表上,产生一个新的URLS列表。然后我们将函数 browse-url emacs提供的),然后我们看着浏览器将它们全部打开。

警告:如果你的文件中有成百上千的链接,那么你会在浏览器中创建成百上千的标签。

  • 如果你的文件中有成百上千的链接 那么你将会在浏览器中创建成百上千的标签页 你是 SURE 你的机器能承受得了吗?

  • 如果你的链接指向大的对象,那就会给你的系统带来另一种内存压力。你是否 SURE 你的机器能承受吗?

  • 如果你的Org模式缓冲区很大,那么 org-element-parse-buffer 可以采取 的时间来处理它。此外,虽然有缓存机制,但由于bug,默认情况下并没有启用,所以每次执行函数时都要解析缓冲区的 再一次 从头开始。

  • 每次执行该函数时,你都会打开 新产品 浏览器中的标签。

针对评论中的问题进行了编辑。

Q1:"visit-all-http-links可以打开文件中的所有URL。我原来的问题是,是否可以只打开当前org-mode章节中被发现的URL。"

A1:只做一个区域有点难,但也是可以的,如果你保证这个区域是语法正确的org模式(比如标题及其内容的集合)。你只需要把区域写到一个临时缓冲区,然后在临时缓冲区上做我所做的事情,而不是原来的区域.下面是使用修改后的代码。visit-url 问题2中的函数。

(defun visit-all-http-links-in-region (beg end)
  (interactive "r")
  (let ((s (buffer-substring beg end)))
    (with-temp-buffer
      (set-buffer (current-buffer))
      (insert s)
      (let* ((parse-tree (org-element-parse-buffer))
             (links (org-element-map parse-tree 'link #'get-link)))
        (mapcar #'visit-url (mapcar #'format-url links))))))

(defun visit-all-http-links ()
  (interactive)
  (visit-all-http-links-in-region (point-min) (point-max)))

非常小的测试.

Q2:"每次我用你的函数执行你的例子URLs时,URLs都以不同的顺序被打开--是否可以按照在org文件中找到的那个顺序打开URLs?"

A2:链接是按照它们在文件中出现的顺序确定地找到的。但是当你调用 browse-url所有的赌注都被取消了,因为URL现在属于浏览器,它将尝试在一个单独的标签页中打开它所收到的每个URL,并且 另起炉灶 - 换句话说是异步的。你可以尝试在调用之间引入一个延迟,但不能保证。

(defun visit-url(url)
   (browse-url)
   (sit-for 1 t))

然后使用 visit-url 而不是 browse-urlvisit-all-urls.

© www.soinside.com 2019 - 2024. All rights reserved.