ユーザー定義のモーションでマクロを中断させる方法 #979

Open
machakann opened this Issue Nov 15, 2016 · 4 comments

Projects

None yet

3 participants

@machakann

質問・報告の内容

例えば、組み込みの f コマンドだとマクロの中で f{char} して {char} が見つからないときにマクロをその時点で止めます。これと同じ動作をユーザー定義のモーション、すなわち :call Motion()<CR> のように定義するモーションで実現したいのですが方法を調べてもわかりませんでした。

:echoerr でエラーを発生させると止まりますがもう少し平和的な方法があるとうれしいです。なにかよい方法があればご教授願いたいです。

@h-east
Member
h-east commented Nov 15, 2016

@machakann サンプルコードを貼っていただくと嬉しいかもです。

@machakann

すいません、非常にあいまいな質問で申し訳ないのですが、

function! Motion() abort
  normal! f,
endfunction

nnoremap F, :<C-u>call Motion()<CR>

このようなマップを定義したとして、次のようなバッファーの1行目にカーソルを置きます。

a,
b,
c

qq0f,xjq2@q と入力すると3行目で f, は失敗して最後の文字削除 x は働きません。

a
b
c

しかし、 qq0F,xjq2@q と入力するとモーション F, が失敗したとならないので最後の x も働きます。

a
b

そこで、 F, にもキーマクロを中断する方法がないだろうかとお聞きしたいのです。イメージとしては

function! Motion() abort
  let originalpos = getpos('.')
  normal! f,
  if getpos('.') == originalpos
    " 何らかのコマンドでキーマクロを中断
  endif
endfunction

のような方法でできるものがあるのではないかと想像しました。

@mattn
Member
mattn commented Nov 15, 2016

expr call を使ってみてはどうでしょうか?

function! Motion() abort
  return "f,"
endfunction

nnoremap <expr> <plug>(my-motion) Motion()
map F, <plug>(my-motion)
@machakann

例の場合であれば、確かに <expr> マッピングで希望の動作になるのですが、実際にキーマッピングを定義する場合はもう少し複雑だったりするので必ずしも expr call に還元するのは難しい、と思ってしまいます。

特に、 <expr> マッピングの中だと :normal コマンドが使えないので、モーションが複雑化すると実現したい動作を作るのが厳しくなります。明示的に Ex コマンドか Normal コマンドか関数で実現できるとありがたいです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment