在emacs中是否存在针对每个区域的应用命令?

时间:2015-08-02 01:24:12

标签: emacs elisp

我在orgmode文件中保存了一堆链接,比如说......

employeeDict[employee.ManagerId]

我可以通过将光标放在链接上并执行http://www.stackoverflow.com http://www.google.com http://www.github.com 来打开每一个,然后它会方便地弹出我的默认浏览器并在选项卡中打开该链接。

现在假设我有20个这样的链接。是否有方便的方法将这样的函数应用于选定区域内的每一行,而不记录显式宏?

我想象它看起来像......

C-c C-o

这仅适用于已定义的功能。我想象没有的方式就像...

Select region
M-x foreach-in-region
Keystrokes to apply to each line: C-c C-o

这是否存在?如果没有,我怎么会这么说?

3 个答案:

答案 0 :(得分:7)

您应该记录一行的宏,然后使用apply-macro-to-region-lines为区域中的所有行执行它。 C-x C-k r

或者,您可以使用多个游标在每一行上创建游标,并使用 C-c C-o 打开所有游标。如果您有机会,multiple-cursors会随着时间的推移改变您的使用模式。

答案 1 :(得分:5)

(defun do-lines (fun &optional start end)
  "Invoke function FUN on the text of each line from START to END."
  (interactive
   (let ((fn   (intern (completing-read "Function: " obarray 'functionp t))))
     (if (use-region-p)
         (list fn (region-beginning) (region-end))
       (list fn (point-min) (point-max)))))
  (save-excursion
    (goto-char start)
    (while (< (point) end)
      (funcall fun (buffer-substring (line-beginning-position) (line-end-position)))
      (forward-line 1))))

发表评论后更新

现在听起来你不想输入一个函数名但是点击一个键,并将绑定到该键的命令应用于区域(或缓冲区)中的每一行。

以下内容会做到这一点。但是,请注意命令通常具有特定行为。例如,如果您要点击键C-kkill-lines),那么它在每行杀死之后就已经向前移动了。因为do-lines不知道您将调用哪种函数(命令),所以它会在每次调用后前进到下一行。对于诸如kill-lines之类的命令,这将做错误的事情:它将最终推进两条线,而不是一条线,从而跳过线。 IOW,请注意do-lines的代码无法补偿它调用的特定函数可能与您期望的不一致。相反,它完成它所说的。

(defun do-lines (command &optional start end)
  "Invoke COMMAND on the text of each line from START to END."
  (interactive
   (let* ((key  (read-key-sequence-vector "Hit key sequence: "))
          (cmd  (lookup-key global-map key t)))
     (when (numberp cmd) (error "Not a valid key sequence"))
     (unless (commandp cmd) (error "Key `%s' is not defined" (key-description key)))
     (if (use-region-p)
         (list cmd (region-beginning) (region-end))
       (list cmd (point-min) (point-max)))))
  (setq start  (copy-marker start)
        end    (copy-marker end))
  (save-excursion
    (goto-char start)
    (while (< (point) end)
      (funcall command (buffer-substring (line-beginning-position) (line-end-position)))
      (forward-line 1))))

答案 2 :(得分:1)

在某些情况下,您可以在C-x z之后使用Emacs Repeating,后面再加上一个`z'。我试图注释区域中的所有行,并且在我的用例中效果很好。

命令C-x z(重复)提供了另一种重复Emacs的方法 命令很多次

要多次重复该命令,请输入其他z:每个z再重复一次该命令