純粋なvimに近づく正規表現は
\v\c\s*\zs(\s{-}(((sqrt|log|sin|cos|tan|exp)?\(.{-}\))|(-?[0-9,.]+(e-?[0-9]+)?)|([-+*/%^]+)))+(\s*\=?)?\s*
制限があります:部分式(関数の引数を含む)は解析されません。これを行うには、適切な文法パーサーを使用する必要があります。純粋なvim1でこれを行うことはお勧めしません。
オペレーターマッピング
これをテキストオブジェクトのように使用できるようにするには、$MYVIMRCで次のようなものを使用します。
func! DetectExpr(flag)
let regex = '\v\c\s*\zs(\s{-}(((sqrt|log|sin|cos|tan|exp)?\(.{-}\))|(-?[0-9,.]+(e-?[0-9]+)?)|([-+*/%^]+)))+(\s*\=?)?\s*'
return searchpos(regex, a:flag . 'ncW', line('.'))
endf
func! PositionLessThanEqual(a, b)
"echo 'a: ' . string(a:a)
"echo 'b: ' . string(a:b)
if (a:a[0] == a:b[0])
return (a:a[1] <= a:b[1]) ? 1 : 0
else
return (a:a[0] <= a:b[0]) ? 1 : 0
endif
endf
func! SelectExpr(mustthrow)
let cpos = getpos(".")
let cpos = [cpos[1], cpos[2]] " use only [lnum,col] elements
let begin = DetectExpr('b')
if ( ((begin[0] == 0) && (begin[1] == 0))
\ || !PositionLessThanEqual(begin, cpos) )
if (a:mustthrow)
throw "Cursor not inside a valid expression"
else
"echoerr "not satisfied: " . string(begin) . " < " . string(cpos)
endif
return 0
endif
"echo "satisfied: " . string(begin) . " < " . string(cpos)
call setpos('.', [0, begin[0], begin[1], 0])
let end = DetectExpr('e')
if ( ((end[0] == 0) || (end[1] == 0))
\ || !PositionLessThanEqual(cpos, end) )
call setpos('.', [0, cpos[0], cpos[1], 0])
if (a:mustthrow)
throw "Cursor not inside a valid expression"
else
"echoerr "not satisfied: " . string(begin) . " < " . string(cpos) . " < " . string(end)
endif
return 0
endif
"echo "satisfied: " . string(begin) . " < " . string(cpos) . " < " . string(end)
norm! v
call setpos('.', [0, end[0], end[1], 0])
return 1
endf
silent! unmap X
silent! unmap <M-.>
xnoremap <silent>X :<C-u>call SelectExpr(0)<CR>
onoremap <silent>X :<C-u>call SelectExpr(0)<CR>
これで、カーソル位置の前後(または後)の最も近い式を操作できます。
- vX -[v]通常はe[X]pressionを選択します
- dX -[d]現在のe[X]pressionを選択
- yX -[y] ank current e [X] pression
"a
yX --id。登録するためにa
トリックとして、以下を使用して、OPから正確なアスキーアートに到達します(デモの目的でvirtualeditを使用)。
挿入モードマッピング
チャットへの応答:
" if you want trailing spaces/equal sign to be eaten:
imap <M-.> <C-o>:let @e=""<CR><C-o>"edX<C-r>=substitute(@e, '^\v(.{-})(\s*\=?)?\s*$', '\=string(eval(submatch(1)))', '')<CR>
" but I'm assuming you wanted them preserved:
imap <M-.> <C-o>:let @e=""<CR><C-o>"edX<C-r>=substitute(@e, '^\v(.{-})(\s*\=?\s*)?$', '\=string(eval(submatch(1))) . submatch(2)', '')<CR>
挿入モード中にヒットAlt-.すると、現在の式がその評価に置き換えられます。カーソルは、挿入モードの結果の最後に移動します。
200 + 3 This is my text -300 +2 + (9*3)
This is text 0.25 + 2.000 + sqrt(15/1.5)
Alt-.インサートを3回押し込んでテスト:
203 This is my text -271
This is text 5.412278
楽しみのために:アスキーアート
vXoyoEsc`<jPvXr-r|e.
自分で簡単にテストするには:
:let @q="vXoyo\x1b`<jPvXr-r|e.a*\x1b"
:set virtualedit=all
今、あなたは@qどこでもできます、そしてそれは最も近い表現をアスキー-装飾します:)
200 + 3 = 203 -300 +2 + (9*3) =
|-------|*
|-------------------|*
200 + 3 = 203 -300 +2 + (9*3)
|-----------------|*
|-------|*
This is text 0,25 + 2.000 + sqrt(15/1.5)
|-------------------------|*
1このような解析を行うためにVimのPython統合を使用することを検討してください