Как относиться к подчеркиванию как к части слова?

34

Я использую evilрежим Emacs + .

Когда я поместить курсор на e(в нормальном состоянии) в куске текста , таких как abc_def_ghi, ciw(изменение внутреннего слова) изменяет только defчасть строки, в то время как Вим бы изменить весь abc_def_ghi.

Как я могу заставить evilтрактовать подчеркивание как Vim (то есть как часть слова)?

казах
источник

Ответы:

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 .

Дэн
источник
Это работает как шарм. Для того, чтобы изменить все движения ( w, awи т.д.), вы можете сделать то же самое со следующими функциями тоже: evil-forward-word-begin, evil-forward-word-end, evil-backward-word-begin, evil-backward-word-end, evil-a-word, evil-inner-word. Примечание: вам нужно изменить underscore-as-wordна разные, уникальные (произвольные) значения.
Ситактиф
(modify-syntax-entry ?_ "w")не работает для меня по какой-то причине. Делать это в интерактивном режиме тоже не получалось. Любая идея, почему или как я могу отладить это? Я на Spacemacs в случае, если это актуально.
Хелдер С Рибейро
1
Это объясняет мою проблему. По-видимому, вы должны явно обратиться к целевой таблице синтаксиса. В моем случае я использовал (modify-syntax-entry ?_ "w" rust-mode-syntax-table), тогда это сработало.
Хелдер С Рибейро
Каковы непреднамеренные последствия изменения записи синтаксиса?
июня
FTR: superword-modeне влияет на движение в evil-mode. Так что это не является составляющей для изменения таблиц синтаксиса.
Привет, Ангел,
28

Следующий фрагмент заставит Зло рассматривать символ 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.

Erik
источник
14

В spacemacs FAQ предлагает следующий язык конкретного решения:

;; 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. С зла на, он работает со всеми командами слов , связанных с ( w, e, *, #и т.д.)

В целом, это будет сделано для всех основных режимов:

(add-hook 'after-change-major-mode-hook
          (lambda ()
            (modify-syntax-entry ?_ "w")))
ejoubaud
источник
2
Используете 'prog-mode-hookли вы возможность охватить каждый язык?
BallpointBen
2

В Emacs 24 введен superword-modeвторостепенный режим, который обрабатывает подчеркивание как часть слов. evil-modeуважает этот параметр.

Вот документация:

(superword-mode &optional ARG)

Переключение движения и редактирования суперслов (режим Superword). С префиксным аргументом ARGвключите режим Superword, если ARGон положительный, и отключите его в противном случае. Если ARGвызывается из Lisp, включите режим, если опущен или ноль.

Режим Superword является локальным режимом буфера. Включение этого параметра изменяет определение слов таким образом, что символы символов рассматриваются как части слов: например, in superword-mode, "this_is_a_symbol"считается одним словом.

BallpointBen
источник
Если вы используете evil-mode, к сожалению, при superword-modeвключении возникает ошибка . Когда вызывается, это вызывает некоторое ошибочное поведение evil-forward-word-begin: github.com/emacs-evil/evil/issues/721
modulitos
0

Мне действительно очень нравится это поведение, так как я мог бы просто захотеть отредактировать часть слова и оставить остальные части без изменений. Если я хочу , чтобы перейти на целое слово , я всегда могу использовать E, Wили B, варианты в верхнем регистре. Это дает мне более детальный контроль.

xji
источник