使用printf和替换更改视觉选择

时间:2015-08-21 04:21:17

标签: vim

我一直致力于在Vim中实现一个简单的实用程序,它允许我在视觉上选择一些文本,计算结果,然后用结果替换原始文本。但是,我遇到了一个问题:似乎某种方式将substituteprintf结合使用会改变我的视觉选择。 这是代码:

vnoremap <leader>C y<ESC>:call setreg( '"', printf( '%f', eval( substitute( substitute( getreg( '"' ), '\n', '', 'g' ), '\(\d\+\.\=\d*\)\s*\^\s*\(\d\+\.\=\d*\)', 'pow( \1, \2 )', 'g' ) ) ), getregtype( '"' ) )<CR>gvp

现在,它的很长,但我正在努力解决这个问题。基本上,它采用视觉选择的文本,猛拉它,然后设置"寄存器以包含评估的响应,然后重新选择最后的视觉选择,然后粘贴它,用结果替换视觉选择。

举个例子,假设我有这一行:a = 32 - 2。视觉选择32 - 2,然后点击<leader>C。该行最终为a = 30.0000002 - 2

问题出在最后一次替换的最后一位:'\(\d\+\.\=\d*\)\s*\^\s*\(\d\+\.\=\d*\)' bit没有最后\.\=\d*,代码运行正常(假设指数/索引不是浮点数)。如果没有printf,它就可以正常工作,因为没有浮点数。使用printf 最后一位,只替换第一个字符,但输出正确。

我需要使用printf,因为这允许我使用浮点数。我还需要做替换,因为它允许我使用指数。

发生了什么,我该如何解决?它没有做,因为只需在printf中使用该代码就可以改变视觉区域。我只是遗漏了一些非常明显的东西吗?

1 个答案:

答案 0 :(得分:1)

显然,未命名的寄存器不会在模式更改后存活。但是,根据手册:

  

写入“”寄存器写入寄存器“0。

事实上,将gvp更改为gv"0p会使您的宏工作。但是,我建议使用更安全的版本:

function! s:expr_eval()                                            
    let old_expr = @"
    let reg_type = getregtype('"')
    let expr = substitute(old_expr, '\n', '', 'g')
    let expr = substitute(expr, '\v(\d+%(\.\d*)?)\s*\^\s*(\d+%(\.\d*)?)', 'pow(\1, \2)', 'g')
    try
        let expr = printf('%f', eval(expr))
    catch
        let expr = old_expr
    endtry
    call setreg('"', expr, reg_type)
endfunction

vnoremap <silent> <leader>C  y:<C-u>call <SID>expr_eval()<CR>gv"0p