アンダースコアを単語の一部として扱う方法は?


34

Emacs + evilモードを使用します。

e(通常の状態で)カーソルを(通常の状態で)などのテキストチャンクに配置するとabc_def_ghiciw(内部単語の変更)defは文字列の一部のみを変更し、Vimは全体を変更しますabc_def_ghi

evilVimと同じように(つまり、単語の一部として)アンダースコアを強制的に処理するにはどうすればよいですか?

回答:


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ノードの構文テーブルの変更に関する詳細を読むことができます


これは魅力のように機能します。すべての動き(変更するにはwawなど)を、あなたも以下の機能と同じ操作を行うことができますevil-forward-word-beginevil-forward-word-endevil-backward-word-beginevil-backward-word-endevil-a-wordevil-inner-word。注:underscore-as-word異なる一意の(任意の)値に変更する必要があります。
シタクティフ

(modify-syntax-entry ?_ "w")何らかの理由で私のために働いていませんでした。インタラクティブに実行しても機能しませんでした。これをデバッグする理由または方法はありますか?関連する場合に備えて、Spacemacsを使用しています。
ヘルダーSリベイロ

1
これは私の問題を説明しています。どうやら、ターゲット構文テーブルを明示的に参照する必要があります。私の場合、私はを使用し(modify-syntax-entry ?_ "w" rust-mode-syntax-table)、それが機能しました。
ヘルダーSリベイロ

構文エントリを変更すると、意図しない影響は何ですか?
-luntain

FTR:のsuperword-mode動きには影響しませんevil-mode。したがって、構文テーブルを変更する構成要素ではありません。
Hi-Angel

28

次のスニペットは、Evilが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

は1つのシンボルですlisp-modeが、では2つのシンボル(で区切られています-)ですc-mode


14

spacemacsよくある質問は以下の言語固有のソリューションを提供しています:

;; 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でも機能します。上の悪では、それはすべての単語に関連するコマンドで動作します(we*#、など)

より一般的には、これはすべての主要なモードでそれを行います:

(add-hook 'after-change-major-mode-hook
          (lambda ()
            (modify-syntax-entry ?_ "w")))

2
'prog-mode-hookすべての言語をカバーするオプションを使用していますか?
BallpointBen

2

Emacs 24が導入されました。これsuperword-modeは、アンダースコアを単語の一部として扱うマイナーモードです。evil-modeこの設定を尊重します。

ドキュメントは次のとおりです。

(superword-mode &optional ARG)

スーパーワードの移動と編集を切り替えます(スーパーワードモード)。プレフィクス引数を使用して、正のARG場合ARGはスーパーワードモードを有効にし、そうでない場合は無効にします。Lispから呼び出された場合、モードif ARGが省略されているかnilを有効にします。

スーパーワードモードは、バッファローカルマイナーモードです。これを有効にすると、記号文字が単語の一部として扱われるように単語の定義が変更されます。たとえば、in superword-mode"this_is_a_symbol"1つの単語としてカウントされます。


を使用している場合evil-mode、残念ながら、superword-modeisが有効になっているときにバグがあります。evil-forward-word-begin呼び出されたときに、いくつかの不安定な動作を引き起こします:github.com/emacs-evil/evil/issues/721
modulitos

0

単語の一部を編集し、他の部分はそのままにしたいので、実際にこの動作がとても好きです。私は全体の単語の上に行きたい場合は、私はいつも使用することができEWまたはB、大文字のバリアントを。これにより、よりきめ細かな制御が可能になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.