Como tratar o sublinhado como parte da palavra?

34

Eu uso o evilmodo Emacs + .

Quando eu posicionar o cursor no e(no estado normal) em um pedaço de texto, como abc_def_ghi, ciw(a mudança palavra interior) altera apenas o defparte da corda, enquanto Vim mudaria toda abc_def_ghi.

Como forçar evila tratar o sublinhado como o Vim (como parte da palavra)?

Kossak
fonte

Respostas:

26

A solução mais simples: use ciWpara selecionar uma palavra delimitada por espaços em branco.

A questão maior tem a ver com o valor do _caractere na tabela de sintaxe . O problema é que _, por padrão, um constituinte de símbolo na tabela de sintaxe e você deseja tratá-lo como um constituinte de palavra.

Se você estiver usando o emacs 24.4, tente ativar superword-mode. Eu mesmo não tentei, então sua milhagem pode variar.

Uma alternativa é simplesmente modificar a tabela de sintaxe e dizer ao Emacs que você deseja que ele trate o _caractere como um constituinte de palavras, da seguinte forma:

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

Depois de fazer isso, ciwfunciona como você deseja, de modo que ele seleciona tudo abc_def_ghie não apenas def.

Fazer dessa maneira, no entanto, pode ser um exagero, especialmente se você quiser que a _contagem seja parte da palavra para o objeto de texto. Em vez disso, você pode aconselhar da evil-inner-wordseguinte maneira:

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

Agora, _ainda é um constituinte de símbolo para tudo, exceto para o objeto de texto com palavras internas, portanto ciw, fará exatamente o que você deseja sem tocar na funcionalidade de qualquer outra coisa.

Você pode ler mais sobre como modificar tabelas de sintaxe no nó EmacsWiki .

Dan
fonte
Isso funciona como um encanto. Para alterar todos os movimentos ( w, aw, etc.), você pode fazer o mesmo com as seguintes funções também: evil-forward-word-begin, evil-forward-word-end, evil-backward-word-begin, evil-backward-word-end, evil-a-word, evil-inner-word. Nota: você precisa mudar underscore-as-wordpara valores diferentes e únicos (arbitrários).
sitaktif
(modify-syntax-entry ?_ "w")não funcionou para mim por algum motivo. Fazer isso interativamente também não funcionou. Alguma idéia de por que ou como eu posso depurar isso? Estou no Spacemacs, caso isso seja relevante.
Helder S Ribeiro
1
Isso explica o meu problema. Aparentemente, você deve consultar a tabela de sintaxe de destino explicitamente. No meu caso eu usei (modify-syntax-entry ?_ "w" rust-mode-syntax-table), então funcionou.
Helder S Ribeiro
Quais são os efeitos não intencionais da modificação da entrada de sintaxe?
luntain 28/02
FTR: superword-modenão afeta o movimento evil-mode. Portanto, não é um componente para modificar tabelas de sintaxe.
Hi-Angel
28

O trecho a seguir fará com que o Evil trate um símbolo do Emacs como uma palavra.

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

Isso tem a vantagem de mudar de acordo com o idioma:

foo-bar

é um símbolo em, lisp-modemas dois símbolos (separados por -) em c-mode.

Erik
fonte
14

As perguntas frequentes sobre o spacemacs oferecem a seguinte solução específica de 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")))

Também funciona em emacs regulares. Com o mal diante, ele funciona com todos os comandos relacionados com a palavra ( w, e, *, #, etc)

De maneira mais geral, isso será feito para todos os principais modos:

(add-hook 'after-change-major-mode-hook
          (lambda ()
            (modify-syntax-entry ?_ "w")))
ejoubaud
fonte
2
Está usando 'prog-mode-hookuma opção para cobrir todos os idiomas?
precisa
2

Introduzido o Emacs 24 superword-mode, um modo secundário que trata os sublinhados como parte das palavras. evil-moderespeita esta configuração.

Aqui está a documentação:

(superword-mode &optional ARG)

Alterne o movimento e a edição de superword (modo Superword). Com um argumento de prefixo ARG, ative o modo Superword, se ARGpositivo, e desative-o caso contrário. Se chamado do Lisp, ative o modo se ARGfor omitido ou nulo.

O modo Superword é um modo secundário local de buffer. A ativação altera a definição de palavras, de modo que os caracteres dos símbolos sejam tratados como partes de palavras: por exemplo, in superword-mode, "this_is_a_symbol"conta como uma palavra.

BallpointBen
fonte
Se você estiver usando evil-mode, infelizmente, há um erro quando superword-modeestá ativado. Isso causa algum comportamento irregular quando evil-forward-word-beginé chamado: github.com/emacs-evil/evil/issues/721
modulitos
0

Na verdade, eu gosto bastante desse comportamento, pois talvez eu queira editar uma parte da palavra e manter as outras partes intactas. Se eu quiser passar por cima de toda a palavra que eu sempre pode usar E, Wou B, a maiúscula variantes. Isso me dá um controle mais refinado.

xji
fonte