Jak traktować podkreślenie jako część słowa?

34

Używam eviltrybu Emacs + .

Kiedy ustawić kursor na e(w stanie normalnym) w fragmencie tekstu, takie jak abc_def_ghi, ciw(zmiana wewnętrznej słowa) zmienia jedynie defczęść napisu, a Vim będzie zmienić cały abc_def_ghi.

Jak zmusić się evildo traktowania podkreślenia tak, jak robi to Vim (tj. Jako część słowa)?

Kossak
źródło

Odpowiedzi:

26

Najprostsze obejście: użyj, ciWaby wybrać słowo rozdzielone spacjami.

Większy problem dotyczy wartości _znaku w tabeli składni . Problem polega na tym _, że domyślnie jest on składnikiem symbolu w tabeli składni i chcesz go traktować jako składnik słowa.

Jeśli używasz emacsa 24.4, możesz spróbować włączyć superword-mode. Nie próbowałem tego sam, więc twój przebieg może się różnić.

Alternatywą jest po prostu samodzielna modyfikacja tabeli składni i poinformowanie Emacsa, że ​​ma traktować _znak jako składnik słowa, tak jak poniżej:

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

Po wykonaniu tej czynności ciwdziała tak, jak chcesz, tak, że wybierze wszystko abc_def_ghizamiast tylko def.

Jednak robienie tego w ten sposób może być przesadą, szczególnie jeśli chcesz, _aby liczyć się tylko jako część słowa dla obiektu tekstowego. Zamiast tego możesz doradzić evil-inner-wordw następujący sposób:

(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)))

Teraz _jest nadal składnikiem symbolu dla wszystkiego oprócz obiektu tekstowego z wewnętrznym słowem, więc ciwzrobi dokładnie to, co chcesz, bez dotykania funkcjonalności czegokolwiek innego.

Możesz przeczytać więcej o modyfikowaniu tabel składniowych w węźle EmacsWiki .

Dan
źródło
To działa jak urok. Aby zmienić wszystkie ruchy ( w, awetc.), można zrobić to samo z następujących funkcji TOO: evil-forward-word-begin, evil-forward-word-end, evil-backward-word-begin, evil-backward-word-end, evil-a-word, evil-inner-word. Uwaga: musisz zmienić underscore-as-wordna różne, unikalne (arbitralne) wartości.
sitaktif
(modify-syntax-entry ?_ "w")z jakiegoś powodu nie działało dla mnie. Robienie tego interaktywnie też nie działało. Masz pomysł, dlaczego lub jak mogę to debugować? Jestem na Spacemacs, na wypadek, gdyby było to istotne.
Helder S Ribeiro
1
To wyjaśnia mój problem. Najwyraźniej musisz wyraźnie odnieść się do docelowej tabeli składni. W moim przypadku użyłem (modify-syntax-entry ?_ "w" rust-mode-syntax-table), a potem zadziałało.
Helder S Ribeiro
Jakie są niezamierzone skutki modyfikacji wpisu składni?
luntain
FTR: superword-modenie wpływa na ruch w evil-mode. Nie jest to więc element modyfikujący tabele składniowe.
Cześć Anioł
28

Poniższy fragment sprawi, że Zło będzie traktować symbol Emacsa jak słowo.

(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))

Ma to tę zaletę, że zmienia się w zależności od języka:

foo-bar

jest jednym symbolem w, lisp-modeale dwoma symbolami (oddzielonymi przez -) w c-mode.

Erik
źródło
14

W spacemacs FAQ proponuje następujące rozwiązania specyficzne dla języka:

;; 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")))

Działa również w regularnych emacach. Ze złem na, to działa na wszystkich poleceń związanych słowo-( w, e, *, #, etc)

Mówiąc bardziej ogólnie, zrobi to dla wszystkich głównych trybów:

(add-hook 'after-change-major-mode-hook
          (lambda ()
            (modify-syntax-entry ?_ "w")))
ejoubaud
źródło
2
Czy używasz 'prog-mode-hookopcji obejmującej każdy język?
BallpointBen
2

Wprowadzono Emacsa 24 superword-mode, mniejszy tryb, który traktuje podkreślenia jako część słów. evil-modeszanuje to ustawienie.

Oto dokumentacja:

(superword-mode &optional ARG)

Przełącz ruch superwordu i edycję (tryb Superword). Za pomocą argumentu przedrostka ARGwłącz tryb Superword, jeśli ARGjest dodatni, i wyłącz go w przeciwnym razie. W przypadku wywołania z Lisp włącz tryb, jeśli ARGjest pominięty lub zero.

Tryb Superword to lokalny tryb buforowania lokalnego bufora. Włączenie go zmienia definicję słów, tak że znaki symboli są traktowane jako części słów: np. In superword-mode, "this_is_a_symbol"liczy się jako jedno słowo.

BallpointBen
źródło
Jeśli używasz evil-mode, niestety jest błąd, kiedy superword-modejest włączony. Powoduje pewne nieprawidłowe zachowanie, gdy evil-forward-word-beginjest nazywany: github.com/emacs-evil/evil/issues/721
modulitos
0

Właściwie to bardzo podoba mi się to zachowanie, ponieważ mógłbym chcieć po prostu edytować część słowa i zachować pozostałe części nienaruszone. Jeśli chcę przejrzeć całe słowo, zawsze mogę użyć E, Wlub B, wielkich wariantów. To daje mi bardziej szczegółową kontrolę.

Xji
źródło