7

我经常将由换行符或换行符分隔的项目粘贴到 Emacs 缓冲区中,导致每个项目位于不同的行上,如下所示:

one
two
three
four

很多时候,我实际上想要一个逗号分隔值的列表,如下所示:

"one", "two", "three", "four"

能够进行从行到列表的一键式转换会很棒。我想我可以使用正则表达式对其进行转换,但它似乎是一种可能已经具有内置 Emacs 函数的常用操作。有人可以推荐一个吗?

4

4 回答 4

6

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)))))
于 2013-07-29T11:49:29.027 回答
6

编辑:确实看到你正在寻找一个函数......但由于唯一的答案就是简单地编写你自己的(即不存在内置函数),我想我会加入正则表达式的内容,因为其他人可能会偶然发现这一点并欣赏替代编写函数并将其放入.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"
于 2014-04-13T00:10:54.127 回答
5

我今天在工作中为此写了一个解决方案。下面是从行转换为 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")))

要使用它,请突出显示要编辑的区域,然后执行 Mx 并指定要使用的分隔符。

于 2014-10-17T20:56:04.390 回答
1

我通常使用宏来完成这类任务。M-X kmacro-start-macroM-x kmacro-end-or-call-macro,然后您可以重复执行此操作。

于 2014-10-18T07:03:07.050 回答