Wie wird der Unterstrich als Teil des Wortes behandelt?

34

Ich benutze den Emacs + evilModus.

Wenn ich die Cursorposition auf e(im Normalzustand) in einem Stück Text , wie beispielsweise abc_def_ghi, ciw(ändern inneres Wort) ändert nur den defTeil der Zeichenfolge, während der gesamte Vim ändern würde abc_def_ghi.

Wie kann ich erzwingen evil, den Unterstrich wie Vim zu behandeln (dh als Teil des Wortes)?

Kossak
quelle

Antworten:

26

Die einfachste Lösung: Verwenden ciWSie diese Option, um ein durch Leerzeichen getrenntes Wort auszuwählen.

Das größere Problem hat mit dem Wert des _Zeichens in der Syntaxtabelle zu tun . Das Problem ist, dass _es sich standardmäßig um einen Symbolbestandteil in der Syntaxtabelle handelt und Sie diesen als Wortbestandteil behandeln möchten.

Wenn Sie Emacs 24.4 verwenden, können Sie versuchen, es zu aktivieren superword-mode. Ich habe es nicht selbst ausprobiert, daher kann Ihr Kilometerstand variieren.

Eine Alternative besteht einfach darin, die Syntaxtabelle selbst zu ändern und Emacs mitzuteilen, dass das _Zeichen wie folgt als Wortbestandteil behandelt werden soll:

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

Nachdem Sie dies getan haben, ciwfunktioniert es so, wie Sie es möchten, sodass es nicht nur, abc_def_ghisondern alles auswählt def.

Wenn Sie dies jedoch auf diese Weise tun, ist dies möglicherweise zu viel des Guten, insbesondere wenn Sie nur möchten _, dass das Wort als Teil des Textobjekts gezählt wird. Stattdessen können Sie evil-inner-wordFolgendes raten :

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

Ist jetzt _immer noch ein Symbolbestandteil für alles außer für das Textobjekt mit dem inneren Wort, ciwwird also genau das tun, was Sie wollen, ohne die Funktionalität von irgendetwas anderem zu berühren.

Weitere Informationen zum Ändern von Syntaxtabellen finden Sie im EmacsWiki-Knoten .

Dan
quelle
Das wirkt wie ein Zauber. Zu ändern , alle Bewegungen ( w, awusw.), können Sie das gleiche mit den folgenden Funktionen auch tun: evil-forward-word-begin, evil-forward-word-end, evil-backward-word-begin, evil-backward-word-end, evil-a-word, evil-inner-word. Hinweis: Sie müssen underscore-as-wordin verschiedene, eindeutige (willkürliche) Werte wechseln .
Sitaktif
(modify-syntax-entry ?_ "w")hat aus irgendeinem Grund nicht für mich gearbeitet. Es interaktiv zu machen hat auch nicht funktioniert. Irgendeine Idee warum oder wie ich das debuggen kann? Ich bin auf Spacemacs, falls das relevant ist.
Helder S Ribeiro
1
Das erklärt mein Problem. Anscheinend müssen Sie explizit auf die Zielsyntaxtabelle verweisen. In meinem Fall habe ich (modify-syntax-entry ?_ "w" rust-mode-syntax-table)dann geklappt.
Helder S Ribeiro
Was sind die unbeabsichtigten Auswirkungen einer Änderung des Syntaxeintrags?
Luntain
FTR: superword-modebeeinflusst nicht die Bewegung in evil-mode. Das Ändern von Syntaxtabellen ist also kein Bestandteil.
Hi-Angel
28

Das folgende Snippet lässt Evil ein Emacs- Symbol als Wort behandeln.

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

Dies hat den Vorteil, dass es sich je nach Sprache ändert:

foo-bar

ist ein Symbol in, lisp-modeaber zwei Symbole (getrennt durch -) in c-mode.

Erik
quelle
14

Die FAQ zu spacemacs bietet die folgende sprachspezifische Lösung:

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

Es funktioniert auch in normalen Emacs. Mit dem Bösen auf, es funktioniert mit allen Wortbezogenen Befehlen ( w, e, *, #usw.)

Im Allgemeinen funktioniert dies für alle Hauptmodi:

(add-hook 'after-change-major-mode-hook
          (lambda ()
            (modify-syntax-entry ?_ "w")))
Ejoubaud
quelle
2
Wird 'prog-mode-hookeine Option verwendet, um jede Sprache abzudecken?
BallpointBen
2

Emacs 24 wurde eingeführt superword-mode, ein Nebenmodus, der Unterstriche als Teil von Wörtern behandelt. evil-moderespektiert diese Einstellung.

Hier ist die Dokumentation:

(superword-mode &optional ARG)

Superword-Bewegung und -Bearbeitung umschalten (Superword-Modus). ARGAktivieren Sie mit einem Präfix-Argument den Superword-Modus, wenn dies ARGpositiv ist, und deaktivieren Sie ihn ansonsten. Wenn Sie von Lisp aus aufgerufen werden, aktivieren Sie den Modus, wenn er ARGweggelassen wird oder nicht.

Der Superword-Modus ist ein Buffer-Local-Minor-Modus. Aktivieren es ändert die Definition von Wörtern , so dass Symbole Zeichen als Teile von Wörtern behandelt werden: zB in superword-mode, "this_is_a_symbol"zählt als ein Wort.

BallpointBen
quelle
Wenn Sie verwenden evil-mode, gibt es leider einen Fehler, wenn superword-modeaktiviert ist. Es verursacht ein unberechenbares Verhalten, wenn github.com/emacs-evil/evil/issues/721evil-forward-word-begin
modulitos
0

Eigentlich mag ich dieses Verhalten sehr, da ich vielleicht nur einen Teil des Wortes bearbeiten und die anderen Teile intakt halten möchte. Wenn ich das ganze Wort übergehen will , kann ich immer gebrauchen E, Woder BVarianten der Groß. Dies gibt mir eine feinkörnigere Kontrolle.

xji
quelle