Hatena::ブログ(Diary)

hchbaw記

2013-02-12

zshでvimのEasyMotionっぽいEmacsのace-jump-modeもどきをしたい。

まれに zsh でも https://github.com/Lokaltog/vim-easymotionhttps://github.com/winterTTr/ace-jump-mode を使いたくなるのです、というわけでやってみました。

こんな感じです。

https://github.com/hchbaw/zce.zsh/raw/readme/zce.zsh.gif

アニメーションgifです。

ソースコードはこちらから。

https://github.com/hchbaw/zce.zsh

使い方です。

source すると `zce` というラインエディタ用コマンドを使うことができるようになりますので、bindkey して下さい。

% . ./zce.zsh
% bindkey "^Xz" zce

設定です。

zstyle 経由でいくつか設定することができます。それぞれデフォルトの値です。

:zce:* keys
ターゲット文字に使用される文字列です。

デフォルトは `setopt braceccl; echo ${(j..)$(print {a-z} {A-Z})}` の結果です。

:zce:* fg
ターゲット文字の装飾です。

デフォルトは 'fg=196,bold' です。

:zce:* bg
関数実行中のエディットバッファの装飾です。

デフォルトは 'fg=black,bold' です。

:zce:* prompt-char
検索する文字の入力のプロンプトです。

デフォルトは '%{\e[1;32m%}Search for character:%{\e[0m%} ' です。

:zce:* prompt-key
ターゲット文字の入力のプロンプトです。

デフォルトは '%{\e[1;32m%}Target key:%{\e[0m%} '


オプションで zcompile できるようにもしています。もし少しでもシェルの起動をはやくしたい向きには、autoload と組み合わせて試してみて下さい。

% Z=~/c/experiment/zsh/zce.zsh/zce.zsh; ($SHELL -c ". $Z && zce-zcompile $Z ~/.zsh/zfunc")
** zcompiling zce in ~/.zsh/zfunc for a little faster startups...
+ mkdir -p ~/.zsh/zfunc
* writing code ~/.zsh/zfunc/zce
* re-compiling ~/.zsh/zfunc/zce.zwc: succeeded
** All done.
** Please update your .zshrc to load the zcompiled file like this,
-- >8 --
## zce.zsh stuff.
# source ~/c/experiment/zsh/zce.zsh/zce.zsh
autoload -w ~/.zsh/zfunc/zce; zle -N zce
# bindkey "^Xz" zce
-- 8< --

vim では EasyMotion 、Emacs では ace-jump-mode を使わしてもらっています。

ただ、 char-mode しか使っていないので、まだ zce.zsh にはその機能はありません、ごめんなさい m(__)m

特に EasyMotion はそのほとんどの機能を使っていなくって、そうじゃないだろうっていわれちゃいそうだけれども、

function! Myeasymotionacejump()
  call EasyMotion#F(0, -1)
endfunction

としてしか使っていない…(^^;;

2013-01-10

`flet' is an obsolete macro (as of 24.3); use either `cl-flet' or `cl-letf'.

;; -*- lexical-binding: t -*-

で、書かれているelispがオフィシャルに入って来たりしているんですね、Emacs浦島太郎な状態です。

それの流れなのかどうなのかおっついていけていないんだけれども、起動時等に表題のようなメッセージが出力されるようになってしまいました。

(emacs-version)
;;⇒"GNU Emacs 24.3.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.4.2)
;; of 2012-12-24 on dex, modified by Debian"

ちょっと確認というわけで、以下のようなコード。これがパスするようになりました。

(expectations
  (defun grok () (grok-raw))
  (defun grok-raw () "want override")
  (defun my-grok-raw () "take over")

  (desc "semantics")
  (expect '("want override" . "take over")
    (cl-flet ((grok-raw () (my-grok-raw)))
      (cons (funcall 'grok-raw)
            (funcall #'grok-raw))))
  (expect '("take over" . "take over")
    (cl-letf (((symbol-function 'grok-raw) #'my-grok-raw))
      (cons (funcall 'grok-raw)
            (funcall #'grok-raw))))
  (expect '("take over" . "take over")
    (flet ((grok-raw () (my-grok-raw)))
      (cons (funcall 'grok-raw)
            (funcall #'grok-raw))))

  (desc "overriding")
  (expect "want override"
    (cl-flet ((grok-raw () (my-grok-raw)))
      (grok)))
  (expect "take over"
    (cl-letf (((symbol-function 'grok-raw) #'my-grok-raw))
      (grok)))
  (expect "take over"
    (flet ((grok-raw () (my-grok-raw)))
      (grok))))

これでゆくと、'cl-'プレフィックスが付いている方はcl-なだけに、Common Lispそっくりに動いてくれるようになっていて、プレフィックス無しの'flet'に関しては後方互換な方にたおしてくれています。

たすかります〜。

(ということは、'flet'を含め、今まであったやつに関してはきっとしばらくは後方互換を保つ感じにしてくれているんじゃないかしらんと、勝手に自分の都合のよい方へ解釈しておこう(^^;

2012-11-30

zshでコマンドラインの文字列に対してvimの*/*,*?*,*n*,*N*等をしたい

https://github.com/zsh-users/zaw zaw.zshを公開して下さっているnakamurayさんありがとうございます!マッチした部分をハイライトするコード等々、とっても参考にさして頂きました。<(__)>

できたのがこちらです。

https://github.com/hchbaw/en.zsh

git://github.com/hchbaw/en.zsh.git

以下のような感じです。

https://github.com/hchbaw/en.zsh/raw/readme/en.zsh.gif

アニメーションgifです。

注意点です。

vicmd キーマップの /,?,n,N を上書きするので特に注意して下さい。


edit-command-line だと overkill だと思っていて、どうにかしたかったということで作ってみました。あんまり頻繁には使わないかもしれないとも思いました…(^^;;

そんな感じで、

パーっと書いたのでまだまだ色々決め打ちな部分とかがあるんですけれども、ちょってずつ整理してゆきたいなと思っています。

zaw.zshで候補に対してvimの*/*,*?*,*n*等をしたい

上のやつのzaw.zsh版で作業中という感じで、いろいろ変な所があるかもしれません、ごめんなさいm(__)m

こちらは候補を検索していて、エディットバッファを見ていません。

こんな感じです。

https://raw.github.com/gist/4175072/20371a63c96640bb2e9b2fee53b14aa08377e1d5/zaw.zsh.gif

随分かえちゃっているので、もうちょっと整理したらば本家へ出さしてもらおうかしらんと考えています。もし両方使いたい向きには、今の所、en.zshがvicmdキーマップを上書きしちゃうので、先にzaw.zshを読み込んで下さい。

差分はこの辺です。

https://github.com/hchbaw/zaw/compare/master...tb;keymap

プルリクエストで使っている以外のブランチは何もいわずに巻きもどしたりけしたりします、御注意下さい。<(__)>


さて、

自分ではanything.elでは、全然anything-isearch使っていないんです…多分、normalモードが無いというのが自分の中での要因の一つだと思っていて、normalモードがあれば話が変ってくるかしらん、という感じがしたので書いてみています。

絞り込んだ状態でながめていたいような時には、使う機会が有るかもしれないな〜と思います。

2012-11-09

textobj-motionmotion.vimのevil.el版を作ってみました。

textobj-motionmotion.vim というのは昨日のやつです。

(http://d.hatena.ne.jp/hchbaw/20121108/1352382527)

位置を返すのみのオぺーレータを二回連続して実行するという、Vim Scriptの時も一旦思いついたんだけれども、どうしてもうまく実装できなかったやりようでやってみました。

evil.elではオぺレータの、作用する範囲等の事柄を知るには、evil-define-operatorを基点に、evil-read-motion -> evil-keypress-parser -> read-event -> key-binding。それと、evil-define-interactive-codeをパラパラ〜っと眺めてみてなんとなくわかった気になりました(^^;

Vim Scriptで、key-bindingみたいな機能がどっかにあるんじゃなかろうかと思っていたんだけれども、残念ながらあたしには見付けられませんでした…

;; evil.el version of textobj-motionmotion.vim
;; https://github.com/hchbaw/textobj-motionmotion.vim
;; Thanks very much the authors of evil.el -- extensible vi layer!

(evil-define-operator evil-textobj-motionmotion-operator (beg end)
  (interactive "<r>")
  (cons beg end))

(defun evil-motionmotion-range (interim)
  (let ((pos (point)))
    (pcase-let
        ((`((,b . _) . (_ . ,e))
           (cons
            #1=(call-interactively 'evil-textobj-motionmotion-operator)
            (progn
              (funcall interim pos)
              #1#))))
      (evil-range b (goto-char e)))))

(evil-define-text-object evil-a-motionmotion (count &optional beg end type)
  (evil-motionmotion-range 'ignore))

(evil-define-text-object evil-i-motionmotion (count &optional beg end type)
  (evil-motionmotion-range 'goto-char))

(define-key evil-outer-text-objects-map "m" 'evil-a-motionmotion)
(define-key evil-inner-text-objects-map "m" 'evil-i-motionmotion)

見事に上手いこといった〜、こわいくらい(^^;;

gistはコチラ

https://gist.github.com/4044079

git://gist.github.com/4044079.git

追記 (2011-11-13)

更新しました。

`end'を使うのは、テキストオブジェクトっぽいモーションのみにしました。`evil-this-motion'を見ちゃっているんだけれども、他によい方法が考えつきませんでした。

また更新しました。ひだり向きに移動した時の動きがおかしかったので修正しました。`orig'を見ちゃっているんだけれども、他によい方法が(ry

`orig'を見るのやめにしました。

最近ではこれのexclusive/inclusiveがいまいちしっくりこない気もしています…

2012-11-08

textobj-motionmotion というのを作ってみました。

作ってみました、発端は、zshのラインエディタでは以下のことができません、というところなのだけれども、あとevil.elだと普通にできます。

man zsh-betaexpn*

とここまで入力した時に、'<Esc>dvTa'と打つと

man zsh-beta

となります。モーションが*o_v*等を考慮しないのでしょうがないのだけれども、そのような事はzshのラインエディタでは上手くいきません、というのが発端です。

これって任意のモーション二つをテキストオブジェクトとして扱うことができるようになれば、'<Esc>dimTal'等のような感じで代用できるんじゃないかなと思いました。

というわけで、Vimには一体どんなモーションがあるのだろうかしらんと思ってVim Script書いてみました。「よっこいしょー!」って聞こえて来そうなコードになっちゃっているけれども、最初なので許して。

注意点です。

マッピングされたコマンドはサポートされていませんし、自分が把握できている範囲だけでもいろいろと不十分です。ごめんなさいm(__)m

数時間使ってみた所、ビルトインのやつだけでもテキストオブジェクトをサポートしないと自分でもさっぱり使わないっていう感じがしてきております…

これじゃあと思ってビルトインのテキストオブジェクトはサポートしたつもりです。

使い方です。

デフォルトのキーマッピングが'am'と'im'です。実行すると、後続のモーション二つを入力待ちになります。モーションの入力がおわると、二つのモーションでカーソルが動いた範囲がオぺレータが作用するテキストになります。

例えば、(*)にカーソルがあるとして、

./runtime/doc/m*otion.txt

が、'vamF/;'で、

./runtime/doc/m*otion.txt
         ^^^^^

が選択されます。iの方は、'vimF/2;'で同じのが選択されます。

'a'と'i'では二番目のモーションが実行される時のカーソル位置が異なります。

'a' では二番目のモーションは、カーソル位置が一回目のモーションで移動した位置で実行されます。

'i' では二番目のモーションは、カーソル位置が一回目のモーションで移動した位置ではなく、オぺレータの入力時のカーソル位置で実行されます。(一つ目のモーションの実行の前に保存しておいて、実行後にsetposで戻しています。)

この辺は自分の勝手な趣味なんだろうけれども、テキストオブジェクト等で、'a'は突き進む感じがしていて、'i'はふんばっているような印象なので、そんなようなテイストが反映されています…伝わりづらい感じだけれども!

ソースコードはこちら、

https://github.com/hchbaw/textobj-motionmotion.vim

git://github.com/hchbaw/textobj-motionmotion.vim.git

ドキュメントはこちら、

http://hchbaw.github.com/experiment/vim/textobj-motionmotion.html

vim.orgへはこちら、

http://www.vim.org/scripts/script.php?script_id=4304

vim.orgへ初投稿しちゃった!もっとこなれてからにするものなのかな〜ともちょっと思ったんだけれどもごめんなさいやっちゃった、どうぞよろしくおねがいいたします。<(__)>