如何将下划线视为单词的一部分?


34

我使用Emacs + evil模式。

当我将光标放在e(正常状态)诸如,的大块文本中abc_def_ghiciw(更改内部字词)仅更改def字符串的一部分,而Vim会更改整个字符串abc_def_ghi

evil该如何像Vim一样强迫下划线(即作为单词的一部分)?

Answers:


26

最简单的解决方法:用于ciW选择以空格分隔的单词。

更大的问题与语法表中_字符的值有关。问题是,默认情况下是语法表中的符号组成部分,您希望将其视为单词组成部分。_

如果您使用的是emacs 24.4,则可以尝试启用superword-mode。我自己还没有尝试过,所以您的里程可能会有所不同。

一种替代方法是简单地自己修改语法表,并告诉Emacs您希望它将_字符视为单词组成部分,如下所示:

(modify-syntax-entry ?_ "w")

完成此操作后,ciw将按您希望的方式工作,这样它将选择全部abc_def_ghi而不是def

但是,以这种方式执行此操作可能会过大,尤其是如果您只希望将_算作文本对象单词的一部分。相反,您可以建议evil-inner-word如下:

(defadvice evil-inner-word (around underscore-as-word activate)
  (let ((table (copy-syntax-table (syntax-table))))
    (modify-syntax-entry ?_ "w" table)
    (with-syntax-table table
      ad-do-it)))

现在,除了内字文本对象之外_它仍然是所有内容的符号组成,因此将精确地执行您想要的操作,而不会影响其他功能。ciw

您可以在EmacsWiki节点上阅读有关修改语法表的更多信息。


这就像一个魅力。要改变所有的动作(waw等等),你可以做同样具有以下功能太:evil-forward-word-beginevil-forward-word-endevil-backward-word-beginevil-backward-word-endevil-a-wordevil-inner-word。注意:您需要更改underscore-as-word为不同的唯一(任意)值。
sitaktif

(modify-syntax-entry ?_ "w")由于某种原因对我不起作用。以交互方式进行操作也不起作用。知道为什么或如何调试吗?我在Spacemacs上使用,以防万一。
Helder S Ribeiro '18

1
解释了我的问题。显然,您必须明确引用目标语法表。就我而言,我使用(modify-syntax-entry ?_ "w" rust-mode-syntax-table),然后它起作用了。
Helder S Ribeiro '18

修改语法条目的意外影响是什么?
午餐

FTR:superword-mode不影响的移动evil-mode。因此,它不是修改语法表的组成部分。
Hi-Angel

28

以下代码片段将使Evil将Emacs 符号视为一个单词。

(with-eval-after-load 'evil
    (defalias #'forward-evil-word #'forward-evil-symbol)
    ;; make evil-search-word look for symbol rather than word boundaries
    (setq-default evil-symbol-word-search t))

这样做的好处是,它会根据语言而变化:

foo-bar

是中的一个符号,lisp-mode但中的两个符号(以分隔-c-mode


14

spacemacs常见问题提供了以下语言的具体的解决方案:

;; For python
(add-hook 'python-mode-hook #'(lambda () (modify-syntax-entry ?_ "w")))
;; For ruby
(add-hook 'ruby-mode-hook #'(lambda () (modify-syntax-entry ?_ "w")))
;; For Javascript
(add-hook 'js2-mode-hook #'(lambda () (modify-syntax-entry ?_ "w")))

它也可以在常规emacs中使用。与邪恶的,它适用于所有字相关的命令(we*#,等)

更一般而言,这将在所有主要模式下执行:

(add-hook 'after-change-major-mode-hook
          (lambda ()
            (modify-syntax-entry ?_ "w")))

2
是否正在使用'prog-mode-hook一种覆盖所有语言的选项?
BallpointBen

2

引入superword-mode了Emacs 24 ,这是将下划线视为单词一部分的次要模式。evil-mode尊重此设置。

这里是文档:

(superword-mode &optional ARG)

切换超级字词的移动和编辑(超级字词模式)。使用前缀参数ARG,如果ARG为正,则启用超级字模式,否则,将其禁用。如果从Lisp调用,则启用该模式(如果ARG省略或为nil)。

超字模式是局部于缓冲区的次要模式。启用它会更改单词的定义,以便将符号字符视为单词的一部分:例如,中的superword-mode"this_is_a_symbol"算作一个单词。


evil-mode不幸的是,如果您使用,superword-mode则启用时会出现错误。当evil-forward-word-begin被调用时,它会导致一些不稳定的行为:github.com/emacs-evil/evil/issues/721
moduloss

0

我实际上很喜欢这种行为,因为我可能只想编辑单词的一部分,而其他部分保持完整。如果我想整个的话,我可以随时使用走了过来EW或者B,大写字母变体。这给了我更细粒度的控制。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.