Emacs 多个“互动”选项
我编写了一个小函数,使用逗号作为项目分隔符来反转标记区域中的项目。功能代码为:Emacs 多个“互动”选项,emacs,elisp,Emacs,Elisp,我编写了一个小函数,使用逗号作为项目分隔符来反转标记区域中的项目。功能代码为: (取消反向列表(结束) 在位反转列表,其中逗号“,”是列表项分隔符 (交互式“r”) (如果(区域-active-p) (let((区域列表(反向(拆分字符串(区域作为字符串)”,“”))) (结束) (区域列表do中s的循环(程序 (插入(chomp s)) (插入“,”)) (删除字符-2)) (消息“错误:未选择区域!”) 其中,chomp从字符串中去除前导/尾随空格,区域作为字符串将区域作为字符串生成 该功
(取消反向列表(结束)
在位反转列表,其中逗号“,”是列表项分隔符
(交互式“r”)
(如果(区域-active-p)
(let((区域列表(反向(拆分字符串(区域作为字符串)”,“”)))
(结束)
(区域列表do中s的循环(程序
(插入(chomp s))
(插入“,”))
(删除字符-2))
(消息“错误:未选择区域!”)
其中,chomp
从字符串中去除前导/尾随空格,区域作为字符串
将区域作为字符串生成
该功能非常有用,但是如果能够动态选择分离器,那就太好了。我要寻找的行为是:
- 如果在没有通用参数的情况下调用,请使用逗号作为项目分隔符
- 如果使用通用参数(
)调用,请用户输入一个(可能是多字符)分隔符字符串C-u
埃莱马基尔 因为
r
始终是前两个参数。如果使用C-u传递参数。然后,您可能需要将参数作为分隔符传递给第三个参数。但是如果没有第一个和第二个参数,就不能通过第三个参数。(我不确定,我也是初学者)
我希望您使用r
和s
选项来实现它。尽管您始终需要提供分隔符参数
例如:
(defun reverse-list (beg end &optional sepeartor )
(interactive "r
ssepeartor:")
(princ beg)
(princ "*")
(princ end)
(princ sepeartor))
您可以使用p
来读取。如果没有前缀参数,则为nil
,如果有前缀参数,则为non-nil
,因此您可以对此进行测试,并决定是否将分隔符设置为,“
或使用读取字符串
提示用户输入分隔符
此外,我还要对您的代码发表以下评论:
beg
和end
实际上是区域的开始和结束。如果以非交互方式调用,这些可能不匹配(或者甚至可能没有区域),在这种情况下,您的函数将出错(因为它删除beg
和end
之间的缓冲区,但插入区域的反转)。因此,您需要调用(缓冲区子字符串beg end)
,而不是(区域作为字符串)
kill region
来删除区域,这将删除的文本复制到kill环。这真的是你想做的吗?这可能会让用户感到惊讶。最好调用delete region
,除非您确实想保存删除的文本
insert
之前,您不能确保该点位于正确的位置。在交互式使用中,您可以不受影响,但对于非交互式使用,点可以在任何地方,所以您应该显式地移动它。当然,也可以使用保存游览
“,”
,然后不得不删除它,这似乎很不雅观。最好不要在一开始就插入它
(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))))))
确实是一个更好的解决方案!感谢您的详细评论,我正在学习elisp,因此这非常有帮助!不过有一条评论:起初我没有使用手动错误消息,但后来根本没有发生错误。另外,当我在没有活动区域的情况下使用您的函数时,当前行中截至
点的内容会反转。。。也许这是我的emacs配置中的一个bug?在添加我的错误处理代码时,您的函数工作得很好。在Emacs中,该区域即使当前未处于活动状态(即突出显示),也会继续存在。请参阅手册中的“”。通常,最好编写命令,以便它们在该区域上运行,即使该区域当前未处于活动状态。毕竟,用户可能已经关闭了瞬态标记模式
,但仍然希望使用您的命令。+1,重构很好。两个小错误:1nreverse
比reverse
更可取,因为split string
返回一个新列表,因此不需要复制它。2.loop
宏的do
子句已经在隐式progn
中包装了后续表单,因此不需要progn
。
(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))))))