evil-surround有这个功能吗?

我想把一个用中文引号括住的词(“example”)快速转化为用英文引号括住(“example”), 查了一下,evil-surround有很多类似的功能,但我没有找到与我需求一致的功能。

不知道能否增强一下surround,或者自己写lisp实现?这个轮子应该已经有了吧

1 个赞

正则也很方便:

:%s/[“”]/"/g

严格一点:

:%s/“\([^”]*\)”/"\1"/g

还可以限定作用范围,避免误伤

1 个赞

另外补充一下,我们用中文输入法打打出来的 “”‘’ 这几对其实是英文符号(中文称之为“弯角引号”),在 emacs 官方手册里常见,我估计论坛里大部分人都不知道: https://en.wikipedia.org/wiki/Quotation_mark

customize-variable evil-surround-pairs-alist

添加 pairs 之后好像还要定义 text object,这是作者留下的坑 https://github.com/timcharper/evil-surround/issues/20#issuecomment-18413089

回帖有个提交可以参考,spacemacs 也有实现 https://github.com/syl20bnr/spacemacs/blob/c788da709bb1c74344f5ab1b6f18cfdf6b930df8/layers/%2Bdistributions/spacemacs-bootstrap/funcs.el#L81

2 个赞

你要的功能是cs“"吧,第一个是中文引号,第二个是英文引号

哈,并没有所谓的“中文引号”

cs“" 不如 csm", m 表示 quotation mark,不用切换输入法,也不用区分左右:

(setq-default evil-surround-pairs-alist (cons '(?m . ("“" . "”"))
                                         evil-surround-pairs-alist))
2 个赞

推销一下 embraceevil-embrace

5 个赞

还没自己定制过~目前处于模仿阶段:joy:

没有中文的引号是什么意思?一直没想明白呢?

看了下,好像是更灵活了

我们用中文输入法打出的 “”‘’ 其实英文符号,这些引号在 emacs 官方手册中常见。真正的中文引号是的。

有现成的代码拷来即用:

;; @from https://github.com/syl20bnr/spacemacs/blob/c788da7/layers/%2Bdistributions/spacemacs-bootstrap/funcs.el#L81-L107

(defmacro spacemacs|define-text-object (key name start end)
  "Define a text object and a surround pair.
START and END are strings (not regular expressions) that define
the boundaries of the text object."
  `(progn
     (spacemacs|define-text-object-regexp ,key ,name
                                          ,(regexp-quote start)
                                          ,(regexp-quote end))
     (with-eval-after-load 'evil-surround
       (push (cons (string-to-char ,key)
                   (if ,end
                       (cons ,start ,end)
                     ,start))
             evil-surround-pairs-alist))))

(defmacro spacemacs|define-text-object-regexp (key name start-regexp end-regexp)
  "Define a text object.
START-REGEXP and END-REGEXP are the boundaries of the text object."
  (let ((inner-name (make-symbol (concat "evil-inner-" name)))
        (outer-name (make-symbol (concat "evil-outer-" name))))
    `(progn
       (evil-define-text-object ,inner-name (count &optional beg end type)
         (evil-select-paren ,start-regexp ,end-regexp beg end type count nil))
       (evil-define-text-object ,outer-name (count &optional beg end type)
         (evil-select-paren ,start-regexp ,end-regexp beg end type count t))
       (define-key evil-inner-text-objects-map ,key (quote ,inner-name))
       (define-key evil-outer-text-objects-map ,key (quote ,outer-name)))))

;; 如果已经在用 spacemacs, 只要下边一句就可以了
(spacemacs|define-text-object "m" "quotation-mark" "“" "”")

然后按 csm" 就有效果了。@ziyuanjun

3 个赞

给你32个赞

我现在这样做:

(spacemacs|define-text-object "q" "quotation-mark" "“" "”");; csq"实现中文引号的快速替换
(spacemacs|define-text-object "b" "brackets-mark" "(" ")");; csb(实现中文括号的快速替换

可以实现: “引号”—>“引号” 、(括号)—>(括号)

弱弱地问一下反过来又该如何写呢? “引号”<—“引号” 、(括号)<—(括号)

前面#11 楼的回复末尾漏掉一行:

(setq-default evil-surround-pairs-alist evil-surround-pairs-alist)

有了这一行,Sm 就可以给选中的内容加上引号了。

按你的设置,反向替换是 cs"qcs)b

1 个赞

我试了一下,不行啊!

  1. cs)b替换后还是英文括号
  2. cs"q对文字没有改动,而且最后一个q开始了宏定义

  • 检查你当前 buffer 的 evil-surround-pairs-alist,是不是有你新加的符号
  • 看前面回复,漏掉的配置要补上,setq-default 更新默认值
  • q 开启宏定义可能是你快捷键设置不合理,导致冲突

感谢回答,应该是漏掉了漏掉了setq-default那句配置。

另外,我发现了一个问题: 对于有嵌套的情况如(“example”),光标在引号内的单词上时,按cs)会报这样一个错误: No surrounding delimiters found 如果光标恰好在引号上面,则会报错: Search failed. This means there is unmatched expression somewhere or we are at the beginning/end of file.

报错因为你的 evil-surround-pairs-alist 中没有 () 键对应的 pair。

配置完了,关机重启拔电池,再观察 evil-surround-pairs-alist 内容是否正确。

evil-surround-pairs-alist 中有键对应的 pair。 我按你的方式把键改成了"r", 试了几次,有时候能有用有时候又不行。

不知道什么原因,我再试试吧