emacs中是否存在apply-function-to-region-lines?

dol*_*ola 8 emacs macros elisp function

我的很多工作都涉及搜索和删除不必要的代码行.所以我创建一个宏,然后选择所有行(C-x h),然后运行命令(apply-macro-to-region-lines).我设法保存该命令并将其放在我的.emacs文件中; 我打电话给它cut_it_now.但是现在我的函数不再是一个宏了,所以我再也不能使用这个(apply-macro-to-region-lines)函数了.你知道在(apply-function-to-region-lines)某处实现了吗?

非常感谢,

d

phi*_*ils 5

请注意apply-macro-to-region-lines只要该宏定义为向量或字符串,您仍然可以使用从代码生成的宏。使用自定义apply-named-macro-to-region-lines[2],您可以选择要交互使用的宏。

Emacs有两种从键盘宏生成代码的方式,具体取决于命名宏的方法。

如果使用kmacro-name-last-macro(绑定到C-xC-kn),那么Emacs 将从宏中生成一个函数,该函数对于此特定目的不是直接有用的[1]。

如果您使用name-last-kbd-macro宏命名,它将作为矢量或字符串生成。

无论哪种情况,都可以insert-kbd-macro用来获取代码。

实际上,矢量/字符串格式是默认格式,因此您可以绕过命名步骤并立即询问代码(RET在名称提示符下键入以指示最新定义的宏),然后手动编辑所插入的默认名称。码。

[1]:向量形式的确确实只是嵌入在函数定义中,因此您应该能够从代码中提取该形式,以便以向量格式手动重新定义宏函数。

[2]:最初写此回复时,我忘记了这是一个自定义函数。对于那个很抱歉。

(defun apply-named-macro-to-region-lines (top bottom)
  "Apply named keyboard macro to all lines in the region."
  (interactive "r")
  (let ((macro (intern
                (completing-read "kbd macro (name): "
                                 obarray
                                 (lambda (elt)
                                   (and (fboundp elt)
                                        (or (stringp (symbol-function elt))
                                            (vectorp (symbol-function elt))
                                            (get elt 'kmacro))))
                                 t))))
    (apply-macro-to-region-lines top bottom macro)))
Run Code Online (Sandbox Code Playgroud)


zev*_*zev 5

以下函数应该执行您想要的操作:

(defun apply-function-to-region-lines (fn)
  (interactive "aFunction to apply to lines in region: ")
  (save-excursion
    (goto-char (region-end))
    (let ((end-marker (copy-marker (point-marker)))
          next-line-marker)
      (goto-char (region-beginning))
      (if (not (bolp))
          (forward-line 1))
      (setq next-line-marker (point-marker))
      (while (< next-line-marker end-marker)
        (let ((start nil)
              (end nil))
          (goto-char next-line-marker)
          (save-excursion
            (setq start (point))
            (forward-line 1)
            (set-marker next-line-marker (point))
            (setq end (point)))
          (save-excursion
            (let ((mark-active nil))
              (narrow-to-region start end)
              (funcall fn)
              (widen)))))
      (set-marker end-marker nil)
      (set-marker next-line-marker nil))))
Run Code Online (Sandbox Code Playgroud)

因此,如果您想要对缓冲区中的行应用以下函数:

(defun test()
  (insert "> "))
Run Code Online (Sandbox Code Playgroud)

并且,如果您的缓冲区包含以下内容:

Line 1: blah, blah
Line 2: blah, blah
Line 3: blah, blah
Line 4: blah, blah
Run Code Online (Sandbox Code Playgroud)

如果您选择仅包含第 2 行和第 3 行的区域,输入“Mx apply-function-to-region-lines”,并在提示时输入“test”作为函数名称,您将在缓冲区中得到以下结果:

Line 1: blah, blah
> Line 2: blah, blah
> Line 3: blah, blah
Line 4: blah, blah
Run Code Online (Sandbox Code Playgroud)


san*_*inc 3

我同意@Lindydancer 的回答,并且我还想补充一点,可能有一种更简单的方法来实现您的目标。例如内置函数delete-matching-lines。:-)