¿Cómo tratar el guión bajo como parte de la palabra?

34

Yo uso el evilmodo Emacs + .

Cuando coloco el cursor sobre e(en estado normal) en un fragmento de texto como abc_def_ghi, ciw(cambiar palabra interna) cambia solo la defparte de la cadena, mientras que Vim cambiaría la totalidad abc_def_ghi.

¿Cómo puedo obligar evila tratar el guión bajo como lo hace Vim (es decir, como parte de la palabra)?

Kossak
fuente

Respuestas:

26

La solución más simple: usar ciWpara seleccionar una palabra delimitada por espacios en blanco.

El problema más grande tiene que ver con el valor del _personaje en la tabla de sintaxis . El problema es que _, por defecto, es un componente de símbolo en la tabla de sintaxis, y desea tratarlo como un componente de palabra.

Si está utilizando emacs 24.4, puede intentar habilitarlo superword-mode. No lo he probado yo mismo, por lo que su kilometraje puede variar.

Una alternativa es simplemente modificar la tabla de sintaxis usted mismo y decirle a Emacs que desea que trate el _carácter como un componente de la palabra, así:

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

Después de hacer eso, ciwfunciona como lo desea, de modo que seleccionará todo en abc_def_ghilugar de solo def.

Sin embargo, hacerlo de esta manera puede ser excesivo, especialmente si solo desea _que cuente como parte de la palabra para el objeto de texto. En cambio, puede aconsejar evil-inner-wordlo siguiente:

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

Ahora, _sigue siendo un símbolo constituyente de todo, excepto del objeto de texto de la palabra interna, por ciwlo que hará exactamente lo que desee sin tocar la funcionalidad de nada más.

Puede leer más sobre cómo modificar tablas de sintaxis en el nodo EmacsWiki .

Dan
fuente
Esto funciona como un encanto. Para modificar todos los movimientos ( w, aw, etc.), se puede hacer lo mismo con las siguientes funciones también: evil-forward-word-begin, evil-forward-word-end, evil-backward-word-begin, evil-backward-word-end, evil-a-word, evil-inner-word. Nota: debe cambiar underscore-as-worda valores diferentes, únicos (arbitrarios).
sitaktif
(modify-syntax-entry ?_ "w")no funcionó para mí por alguna razón. Hacerlo interactivamente tampoco funcionó. ¿Alguna idea de por qué o cómo puedo depurar esto? Estoy en Spacemacs en caso de que sea relevante.
Helder S Ribeiro
1
Esto explica mi problema. Aparentemente, debe referirse explícitamente a la tabla de sintaxis de destino. En mi caso lo usé (modify-syntax-entry ?_ "w" rust-mode-syntax-table), luego funcionó.
Helder S Ribeiro
¿Cuáles son los efectos no deseados de modificar la entrada de sintaxis?
luntain
FTR: superword-modeno afecta el movimiento en evil-mode. Por lo tanto, no es un componente para modificar tablas de sintaxis.
Hi-Angel
28

El siguiente fragmento hará que Evil trate un símbolo de Emacs como una palabra.

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

Esto tiene la ventaja de que cambia según el idioma:

foo-bar

es un símbolo en lisp-modepero dos símbolos (separados por -) en c-mode.

Erik
fuente
14

Las preguntas frecuentes de spacemacs ofrecen la siguiente solución específica del idioma:

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

También funciona en emacs regulares. Con el mal encendido, funciona con todos los comandos relacionados con la palabra-( w, e, *, #, etc)

De manera más general, esto lo hará para todos los modos principales:

(add-hook 'after-change-major-mode-hook
          (lambda ()
            (modify-syntax-entry ?_ "w")))
ejoubaud
fuente
2
¿Está usando 'prog-mode-hookuna opción para cubrir todos los idiomas?
BallpointBen
2

Emacs 24 introdujo superword-mode, un modo menor que trata los guiones bajos como parte de las palabras. evil-moderespeta esta configuración.

Aquí está la documentación:

(superword-mode &optional ARG)

Alternar el movimiento y la edición de superpalabras (modo Superword). Con un argumento prefijo ARG, habilite el modo Superword si ARGes positivo, y desactívelo de lo contrario. Si se llama desde Lisp, habilite el modo si ARGse omite o es nulo.

El modo Superword es un modo menor local de búfer. Habilitarlo cambia la definición de las palabras de tal manera que los caracteres de símbolos se tratan como partes de las palabras: por ejemplo, en superword-mode, "this_is_a_symbol"cuenta como una palabra.

BallpointBen
fuente
Si está utilizando evil-mode, desafortunadamente, hay un error cuando superword-modeestá habilitado. Causa un comportamiento errático cuando evil-forward-word-beginse llama: github.com/emacs-evil/evil/issues/721
modulitos
0

De hecho, me gusta bastante este comportamiento, ya que es posible que solo desee editar una parte de la palabra y mantener las otras partes intactas. Si quiero repasar toda la palabra, siempre puedo usar E, Wo Blas variantes en mayúscula. Esto me da más control de grano fino.

xji
fuente