如何让 Emacs 解包代码块?

如何让 Emacs 解包代码块?

How to get Emacs to unwrap a block of code?

假设我在 emacs 缓冲区中有一行如下所示:

1
2
foo -option1 value1 -option2 value2 -option3 value3 \\
    -option4 value4 ...

我希望它看起来像这样:

1
2
3
4
5
foo -option1 value1 \\
    -option2 value2 \\
    -option3 value3 \\
    -option4 value4 \\
    ...

我希望每个选项/值对位于单独的一行。我还希望那些后续行根据模式适当缩进,而不是添加固定数量的空白。我希望代码在当前块上工作,在第一个非空行或不包含选项/值对的行处停止,尽管我可以满足于它在选定区域上工作。

有人知道 elisp 函数可以做到这一点吗?


没有人拥有我想要的东西,所以我决定清理我的 elisp 手册并自己做。这似乎工作得很好,尽管输出并不是我所要求的。在这个版本中,第一个选项单独出现在一行,而不是像我原来的问题那样留在第一行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(defun tcl-multiline-options ()
 "spread option/value pairs across multiple lines with continuation characters"
  (interactive)
  (save-excursion
    (tcl-join-continuations)
    (beginning-of-line)
    (while (re-search-forward" -[^ ]+ +"  (line-end-position) t)
      (goto-char (match-beginning 0))
      (insert" \\\\\
")
      (goto-char (+(match-end 0) 3))
      (indent-according-to-mode)
      (forward-sexp))))

(defun tcl-join-continuations ()
 "join multiple continuation lines into a single physical line"
  (interactive)
  (while (progn (end-of-line) (char-equal (char-before) ?\\\\))
    (forward-line 1))
  (while (save-excursion (end-of-line 0) (char-equal (char-before) ?\\\\))
    (end-of-line 0)
    (delete-char -1)
    (delete-char 1)
    (fixup-whitespace)))

在这种情况下,我会使用宏。您可以使用 C-x ( 开始录制宏,并使用 C-x 停止录制)。当你想重播宏类型 C-x e.

在这种情况下,我会输入 C-a C-x ( C-s v a l u e C-f C-f \\\\ RET SPC SPC SPC SPC C-x )

这将记录一个搜索"值"的宏,向前移动 2,插入斜杠和换行符,最后将新行隔开以对齐。然后你可以重复这个宏几次。

编辑:我刚刚意识到,您的文字可能不像"value1"那样容易搜索。您还可以搜索空格并循环点击。例如,在第一场比赛后按 C-s 几次以跳过某些比赛。

注意:由于您的示例是"临时"的,因此该解决方案也是如此。当您需要临时解决方案时,通常会使用宏。使宏应用更一致的一种方法是将原始语句全部放在一行上(也可以通过宏或手动完成)。

编辑:感谢您对 ( 与 C-( 的评论,你是对的,我的错误!


您的模式可能已经支持此功能。在 C 模式和 Makefile 模式下,至少, M-q (fill-paragraph) 将在填充列中插入续行并换行。

你在什么模式下编辑这个?


就个人而言,我一直都在做这样的事情。

但我不会编写函数来执行此操作,除非我会这样做
一年中的每一天。

您可以使用查询替换轻松做到这一点,如下所示:

m-x (查询-替换" -option""^Q^J -option")

我说 ^Q^J 因为这是你要输入的内容来引用换行符并将其放入
字符串。

然后只需按 'y' 替换要替换的字符串,然后按 'n' 跳过奇怪的
你会发现的角落案例。

另一个主力函数是 query-replace-regexp,它可以做
正则表达式的替换。

还有 grep-query-replace,它将通过解析执行查询替换
grep 命令的输出。这很有用,因为您可以搜索
对于 100 个文件中的"foo",然后在每次出现时执行查询替换
从一个文件跳到另一个文件。


推荐阅读