我编写了一个小函数,使用逗号作为项目分隔符来反转标记区域中的项目。功能代码是:
(defun reverse-list (beg end)
"Reverses a list in-place, where comma ',' is the list item separator."
(interactive "r")
(if (region-active-p)
(let ((region-list (reverse (split-string (region-as-string) ","))))
(kill-region beg end)
(loop for s in region-list do (progn
(insert (chomp s))
(insert ", ")))
(delete-char -2))
(message "Error: No region selected!")))
其中chomp
从字符串中删除前导/尾随空格,region-as-string
将该区域作为字符串。
该功能非常有用,但是能够动态选择分隔符会很棒。我正在寻找的行为是:
C-u
)调用,则要求用户输入(可能是多字符)分隔符字符串我试图实现这一目标,但没有成功。如果你能提供帮助会很棒!
提前致谢,
elemakil
答案 0 :(得分:7)
您可以使用interactive code P
阅读"raw" prefix argument。如果没有前缀参数,则为nil
,如果有前缀参数,则为nil
,因此您可以对此进行测试,并决定是将分隔符设置为","
还是使用read-string
提示用户输入。
另外,我会对您的代码发表以下评论:
只有交互式调用您的函数才有效,因此beg
和end
实际上是区域的开头和结尾。如果以非交互方式调用,这些可能不匹配(或者甚至可能没有区域),在这种情况下,您的函数将出错(因为它会删除beg
和end
之间的缓冲区,但会插入逆转该地区)。因此,您需要致电(buffer-substring beg end)
,而不是(region-as-string)
。
[已编辑,请参阅注释]在区域处于非活动状态时引发错误并不是一个好主意。在Emacs中,即使处于非活动状态(即不再突出显示),该区域仍然存在。或者用户可能已关闭transient-mark-mode
,因此根本没有活动区域。在这两种情况下,用户可能仍希望运行您的命令。
最多可以在区域处于活动状态时更改命令的行为(例如,参见comment-dwim
)。
您可以通过调用kill-region
来删除该区域,delete-region
会将删除的文本复制到kill-ring。这真的是你想要做的吗?它可能会让用户感到惊讶。除非您实际上是要保存已删除的文本,否则最好拨打insert
。
在开始调用save-excursion
之前,您无法确保该点位于正确的位置。在交互式使用中,你可以使用它,但对于非交互式使用点可以在任何地方,所以你应该明确地移动它。当然也可以使用", "
。
插入额外的(defun reverse-list (beg end read-separator)
"Reverse the region in-place, treating it as a list of items
separated by commas. With a prefix argument, prompt for the
separator."
(interactive "r\nP")
(save-excursion
(let* ((separator (if read-separator (read-string "Separator: ") ","))
(region-list (nreverse (split-string (buffer-substring beg end) separator)))
(separator (concat separator " ")))
(goto-char beg)
(delete-region beg end)
(loop for s in region-list
for sep = "" then separator
do (insert sep) (insert (chomp s))))))
然后必须删除它似乎非常不优雅。最好不要首先插入它。
以下是修正以上所有内容的修订代码:
{{1}}
答案 1 :(得分:-1)
r -- Region: point and mark as 2 numeric args, smallest first. Does no I/O.
因为r
始终是前两个参数。如果使用 C-u 传递参数。然后,您可能需要将参数作为分隔符传递给第三个参数。但是如果没有第一个和第二个参数,你就无法传递第三个参数。 (我不确定。我也是初学者)
我的目的是使用r
和s
选项来实现它。虽然您总是需要提供分隔符参数。
示例:
(defun reverse-list (beg end &optional sepeartor )
(interactive "r
ssepeartor:")
(princ beg)
(princ "*")
(princ end)
(princ sepeartor))