如何可视地向后选择计算? [英] How do I visual select a calculation backwards?
问题描述
我想直观地向后选择计算p.e.
I would like to visual select backwards a calculation p.e.
200 + 3 This is my text -300 +2 + (9*3)
|-------------|*
This is text 0,25 + 2.000 + sqrt(15/1.5)
|-------------------------|*
原因是我将在插入模式下使用它. 编写完计算后,我想选择计算(使用地图),然后将计算结果输入文本中.
The reason is that I will use it in insert mode. After writing a calculation I want to select the calculation (using a map) and put the results of the calculation in the text.
正则表达式必须执行的操作是:
-从光标(请参见上例中的*
)向后选择以开始计算
(包括\/-+*:.,^
).
-计算只能从log/sqrt/abs/round/ceil/floor/sin/cos/tan或正数或负数开始
-计算也可以从行的开头开始,但永远不会返回到
上一行
What the regex must do is:
- select from the cursor (see *
in above example) backwards to the start of the calculation
(including \/-+*:.,^
).
- the calculation can start only with log/sqrt/abs/round/ceil/floor/sin/cos/tan or with a positive or negative number
- the calculation can also start at the beginning of the line but it never goes back to
a previous line
我尝试了各种方法,但是找不到正确的正则表达式.
我注意到,向后搜索与向前搜索不同.
I tried in all ways but could not find the correct regex.
I noted that backward searching is different then forward searching.
有人可以帮助我吗?
修改
忘记了,如果有一个并且光标前面有'=',或者光标和'='之间只有空格,那么它还必须包括.
它不能包含其他"="符号.
Edit
Forgot to mention that it must include also the '=' if there is one and if the '=' is before the cursor or if there is only space between the cursor and '='.
It must not include other '=' signs.
200 + 3 = 203 -300 +2 + (9*3) =
|-------------------|<SPACES>*
200 + 3 = 203 -300 +2 + (9*3)
|-----------------|<SPACES>*
*
=光标所在的位置
推荐答案
在纯vim中紧靠的正则表达式是
A regex that comes close in pure vim is
\v\c\s*\zs(\s{-}(((sqrt|log|sin|cos|tan|exp)?\(.{-}\))|(-?[0-9,.]+(e-?[0-9]+)?)|([-+*/%^]+)))+(\s*\=?)?\s*
有局限性:不解析子表达式(包括函数参数).您需要使用适当的语法解析器来执行此操作,并且我不建议您在纯vim 1
There are limitations: subexpressions (including function arguments) aren't parsed. You'd need to use a proper grammar parser to do that, and I don't recommend doing that in pure vim1
要启用类似于文本对象的功能,请在$ MYVIMRC中使用以下功能:
To enable using this a bit like text-objects, use something like this in your $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>
现在,您可以对光标位置附近(或之后)的最接近表达式进行运算:
Now you can operator on the nearest expression around (or after) the cursor position:
- v X -[v]通常选择e [X]压缩
- d X -[d]删除当前e [X]压缩
- y X -[y]当前当前e [X]压缩
-
"a
y X -ID.注册a
- vX - [v]isually select e[X]pression
- dX - [d]elete current e[X]pression
- yX - [y]ank current e[X]pression
"a
yX - id. to registera
作为一个技巧,请使用以下内容从OP中获得确切的ascii艺术(出于演示目的,使用 virtualedit ):
As a trick, use the following to arrive at the exact ascii art from the OP (using virtualedit for the purpose of the demo):
响应聊天:
" 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-.,当前表达式将替换为其求值.在插入模式下,光标结束于结果的末尾.
allows you to hit Alt-. during insert mode and the current expression gets replaced with it's evaluation. The cursor ends up at the end of the result in insert mode.
200 + 3 This is my text -300 +2 + (9*3)
This is text 0.25 + 2.000 + sqrt(15/1.5)
通过在插入中按 Alt-. 3次进行测试:
Tested by pressing Alt-. in insert 3 times:
203 This is my text -271
This is text 5.412278
为了娱乐:ASCII艺术
v X o y o Esc ` < j P v X r - r | e .
要自己轻松进行测试,请执行以下操作:
For Fun: ascii art
vXoyoEsc`<jPvXr-r|e.
To easily test it yourself:
:let @q="vXoyo\x1b`<jPvXr-r|e.a*\x1b"
:set virtualedit=all
现在,您可以在任何地方 @ q ,它会自动修饰最接近的表达式:)
Now you can @q anywhere and it will ascii-decorate the nearest expression :)
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集成来进行此类解析
1 consider using Vim's python integration to do such parsing
这篇关于如何可视地向后选择计算?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!