我经常将由换行符或换行符分隔的项目粘贴到 Emacs 缓冲区中,导致每个项目位于不同的行上,如下所示:
one
two
three
four
很多时候我实际上想要一个逗号分隔值的列表,如下所示:
"one", "two", "three", "four"
如果能够实现从行到列表的一键转换,那就太好了。我想我可以使用正则表达式来转换它,但这似乎是一种常用的操作,可能已经有内置的 Emacs 函数。有人可以推荐一个吗?
M-q 会将换行符替换为空格(在相当短的短单词列表中),但不会添加引号和逗号。或者,也许多次M-^,直到它们都在同一条线上。除此之外 - 没有想到任何内置的东西。
显然,键盘宏是一个很好的选择。
但是,一种不会创建许多撤消步骤的更快方法是这样的:
(defun lines-to-cslist (start end &optional arg)
(interactive "r\nP")
(let ((insertion
(mapconcat
(lambda (x) (format "\"%s\"" x))
(split-string (buffer-substring start end)) ", ")))
(delete-region start end)
(insert insertion)
(when arg (forward-char (length insertion)))))
编辑:我do看到你正在寻找一个函数......但由于唯一的答案就是简单地编写你自己的函数(即不存在内置函数),我想我应该插话一下正则表达式 会是 ,因为其他人可能会偶然发现这一点,并欣赏编写函数并将其放入
.emacs
的替代方法。
这是两个步骤,但只是因为您希望引用您的文字:
粘贴在 Emacs
*scratch*
缓冲区中(添加 five six
以显示它可以在每行处理多个单词,如果感兴趣的话):
one
two
three
four
five six
首先,将单个
word
替换为"word"
:
M-x replace-regexp RET \(.*\) RET "\1" RET
产生:
"one"
"two"
"three"
"four"
"five six"
现在,将每个回车符(在 Emacs 中为
C-q C-j
)替换为 ,
:
M-x replace-regexp RET C-q C-j RET , RET
产生:
"one", "two", "three", "four", "five six"
我今天在工作中为此写了一个解决方案。以下是从行转换为 csv 以及从 csv 转换为行的函数,并带有用户可指定的分隔符。该函数作用于当前突出显示的区域。
(defun lines-to-csv (separator)
"Converts the current region lines to a single line, CSV value, separated by the provided separator string."
(interactive "sEnter separator character: ")
(setq current-region-string (buffer-substring-no-properties (region-beginning) (region-end)))
(insert
(mapconcat 'identity
(split-string current-region-string "\n")
separator)))
(defun csv-to-lines (separator)
"Converts the current region line, as a csv string, to a set of independent lines, splitting the string based on the provided separator."
(interactive "sEnter separator character: ")
(setq current-region-string (buffer-substring-no-properties (region-beginning) (region-end)))
(insert
(mapconcat 'identity
(split-string current-region-string separator)
"\n")))
要使用此功能,请突出显示要编辑的区域,然后执行 M-x 并指定要使用的分隔符。
我通常使用宏来完成此类任务。
M-X kmacro-start-macro
和M-x kmacro-end-or-call-macro
,然后您可以重复执行。
我的 ~/.emacs 中有这些定义:
(defun join-line-after ()
"Join this line to next and fix up whitespace at join."
(interactive)
(end-of-line)
(forward-char)
(join-line))
(global-set-key "\C-j" 'join-line-after)
因此,要将行列表变成一行,我将光标放在第一个元素之前并继续点击
C-j
。如果需要添加或删除逗号,我通常会根据上下文在之前或之后使用正则表达式替换来完成此操作。