for loop

バッファローカルにEvilを有効にする/momonga.vim #6

目標

Emacs Evil (Extensible VI Layer) をバッファローカルに有効にする

動機

Amazon.co.jp: 実践Vim 思考のスピードで編集しよう!: Drew Neil, 新丈径: 本を読んでvimのキーバインドや文字列操作に対する考えかたの有効性も理解して、vimを使いつつ、過去のmomonga.vimにも参加して.vimrcを弄ったりしたものの、エディタというか作業のベースがEmacsになってしまっていて、これはVimに置き換えもできないと感じていた

一方で以前から Evil: EmacsをVimのごとく使う – 導入編 – 貳佰伍拾陸夜日記 を読んで使ってみたいと気にはしていたのだけど(evil-mode t)を実行するとEmacs上の全てのバッファで有効になってしまうので導入に踏み切れないでいた。種々のアプリはEmacs上での動作を基本としているのでVimキーバインドはプログラミングするバッファのみで有効になって欲しい

で、momonga.vim#6がドワンゴでやる、ということだったので会場に対する興味もありつつこれを期にやってしまおうと企ててみた

結果

evil-local-modeという関数が用意されてて、完全に確認不足

経過

ちょっと頑張ってみないと、と思っていたevilをローカルバッファのみで有効にする、という処理が公式に用意されていて何をしに来たのか良くわからない状態に。 とりあえずこんな感じで該当のファイルをオープンしたタイミングで設定を有効にできるはず。

1
2
3
4
5
6
7
8
9
10
11
(require 'evil)
(evil-mode 0)

(defmacro add-evil-mode (hook-name)
  `(add-hook ',hook-name '(lambda () (evil-local-mode t))))

(add-evil-mode sh-mode-hook)
(add-evil-mode clojure-mode-hook)
(add-evil-mode ruby-mode-hook)
(add-evil-mode lisp-interaction-mode-hook)
(add-evil-mode emacs-lisp-mode-hook)

ついでにevil-local-modeを有効にしたり、C-gでEvilでの処理をキャンセルしてnormal-stateに戻るようなキーバインド設定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  (defun toggle-evil-local-mode () (interactive)
    (if evil-local-mode
      (evil-local-mode 0)
      (evil-local-mode 1)))
  
  (defun evil-escape-or-quit (&optional prompt)
    (interactive)
    (cond
      ((or (evil-normal-state-p) (evil-insert-state-p) (evil-visual-state-p)
           (evil-replace-state-p) (evil-visual-state-p)) [escape])
    (t (kbd "C-g"))))
  
  (define-key key-translation-map     (kbd "C-g")     'evil-escape-or-quit)
  (define-key evil-operator-state-map (kbd "C-g")     'evil-escape-or-quit)
  (define-key evil-normal-state-map   [escape]        'keyboard-quit)
  (global-set-key                     (kbd "C-c C-z") 'toggle-evil-local-mode)

とりあえず、この辺を設定しておいて少しずつEvilを使っていくようにしようと思う。

課題

evil-mode-lineがevil-local-modeの場合は効いてなさそうなのをなんとかしたい。。。
clever-f.vim相当の機能が欲しい

感想とか

会場について特にドワンゴだから、といったような特殊な感じはなかったんじゃないかと。。
うたってみたの実演があったけど、(闇のVimの)勉強会では普通のことのようだし。
前回同様ゆるくもくもくできたけど、前回朝から晩までだったのに比べればだいぶ短期集中だったかな。

余り色々の人とお話はできなかったけれど@pogin503さんにElispのことを教わったりした。Vimはあまり使ってないとのことだったのでVimについて知りたければ入門viより実践Vimを読むべきと押し付けたりした。

あとは、周りのVimmerのコイツ何してるの、という視線もないまま空気と化して一人もくもくとEmacsをいじっていた私を見かねて主催の@supermomongaさんがEvil回りの話を振ってくれたのだけど、期待に応えられず。

もってきてもらった課題はVimユーザとしてはEvilを使ってる状況でC-[でkeyboard-quit相当の処理をしたい場面があるのだけど思った通りに動かないといったもの。 例えば下記の設定はEscapeキーには効くけど、C-[には効かない。

(define-key minibuffer-inactive-mode-map [escape] 'keyboard-quit)

EscapeもC-[もESCとして認識されてるみたいなのだけど、どうもそれぞれ別個に機能としてのESCと紐付いてるみたいで、かつC-[のキーバインドを変更する方法は見付けられなかった。keycodeを検出するxevを動かすために@supermomongaさんのMacにXを捩じ込んだりもしたけど、keycode指定も上手くいかなかくて悔しい思いをした。

ちなみに後で試してみたところ強引に下記のようにC-[をC-gにtranslateしてしまえばkeyboard-quitを実行することは可能だった。

(keyboard-translate ?\e ?\a)

参考 GNU Emacs Lispリファレンスマニュアル: Character Type

ということで進捗としては何しにわざわざ勉強会に行ったのか、といった感じになってしまったけれどこういう機会がないとなかなかEvilに向き会えなかったので良い切っ掛けだったと思う。
今回のことでEmacs上でVimに近いキーバインドを使って作業できる状況を作れるようにはなってきたのだけどvimscriptで実装されてるあの機能が欲しい、となったりしそうなのが若干不安。そこまでEvilが手に馴染めばそれはそれで良い兆候なのだろうけど。