2012-10-09 34 views
2

简而言之,写了一些功能来保存输入我试图设置一个vmap [ping],这将允许我选择我输入的内容,并将此选项传递给一个函数(因为在命令行上键入函数调用,键入参数(带引号)和转义反斜杠等......抵消通过调用函数节省的大部分时间)Vim vmap,发送选定的文本作为参数功能

对于(一个简单的)示例,假设我有以下功能

func Test(iStr) 
if a:iStr[0] =~ [a-zA-z] 
    echo "hello" 
else 
    echo "hello world" 
endif 
endfunc 

我希望能够可视化选择一些文本,然后用一些按键映射,F2说,它会调用测试(ISTR)与选择作为参数iStr

我相信,与更多的工作(即一些方法来指定我所选择的应该是内部测试()),以下

vmap <F2> :call Test() 

是我后。事情是我已经尝试了一些变体(猜测加上一些有趣的推理:help map),我没有得到任何有用的东西。更新,我一直在使用一个辅助函数的Test2()只

call Test(<C-W>) 

为它的身体试图...我总觉得我需要我的光标(以某种方式)下抢字的保持,那么我做了 - 因为我可以从内部的Test2


传递到测试(......)至于功能我要打电话,以下(但不完全)函数(和辅助功能)的实际例子允许我转换表格的形式,比方说,

f_k^{(j)}g 

f_1^{(j)}g, f_2^{(j)}g, \dots, f_{n-1}^{(j)}g, f_n^{(j)}g 

在我想要一个程序方面

a) type the repeated term in vim 
b) visually select it 
c) hit some mapping key that will call SumOrSequence(iExpression, iIndex) 
d) provide "k" as a parameter 
e) press enter 
f) see the change made by SumOrSequence(...) 

为SumOrSequence(...)的代码如下:

func SumOrSequence(iExpression, iIndex) 
"need to check validity of these - maybe set a default 
let default = Interrogate("do with defaults? yes [y] (2,1,n,0,\",\"), yes but specify last term [d[a-Z]], no [n]") 
if default == "y" 
    let leftTerms = 2 
    let rightTerms = 1 
    let lastTermIndex = "n" 
    let firstTermIndex = 0 
    let operator = "," 
    let dotType = "\\dots" 
elseif default =~ 'd[a-zA-Z]' 
    let leftTerms = 2 
    let rightTerms = 1 
    let lastTermIndex = default[1] 
    let firstTermIndex = 0 
    let operator = Interrogate("what separates terms? add [+], subtract [-], times [*], comma [,], ampersand [&]?") 
    let dotType = "\\cdots" 
else "so n or anything else 
    let leftTerms = InterrogateNumber("how many terms before dots? ") 
    let rightTerms = InterrogateNumber("how many terms after dots? ") 
    let lastTermIndex = Interrogate("what is last term index?") 
    let firstTermIndex = Interrogate("what is first term index?") 
    let operator = Interrogate("what separates terms? add [+], subtract [-], times [*], comma [,], ampersand [&]?") "need to check only any of these provided 
    let dotType = "\\cdots" 
endif 
if operator == "," 
    let dotType = "\\dots" 
endif 
if operator == "*" 
    let operator = "\\times" 
endif 
let leftCount = 0 
let oExpression = "" 
while leftCount < leftTerms 
    if leftCount > 0 
     let oExpression .= operator . " " 
    endif 
    let oExpression .= ReplaceIndex(a:iExpression, a:iIndex, leftCount,1) 
    let leftCount += 1 
endwhile 
let oExpression .= operator . " " . dotType . " " 
let rightCount = rightTerms-1 
while rightCount > 0 
    "here we are going to be counting backwards from some number denoting number of terms - may need to know if we actually have a number! 
    echo "decrement: " . HandleDecrement(lastTermIndex, rightCount) 
    let oExpression .= operator . " " . ReplaceIndex(a:iExpression, a:iIndex, HandleDecrement(lastTermIndex, rightCount),1) 
    let rightCount -= 1 
endwhile 
let oExpression .= operator . " " . ReplaceIndex(a:iExpression, a:iIndex, lastTermIndex,0) 
echo oExpression 
endfunc 

func ReplaceIndex(iExpression, iIndex, iReplacement, iInsertBraces) 
"the game we play here is to search for iIndex in such form that it is not part of any other string 
"We should expect this to be the case if the character to the left or right of the index is not in [A-z] (or just to the right if a greek char) 
let oExpression = "" 
let strEndPosition = strlen(a:iExpression) - 1 
let currPosition = 0 
let indexLen = strlen(a:iIndex) 
while currPosition <= strEndPosition 
    let indexCounter = 0 
    let foundIndex = 1 
    while indexCounter < indexLen 
     if a:iExpression[currPosition + indexCounter] == a:iIndex[indexCounter] 
      if a:iExpression[currPosition + indexLen] =~ '[a-zA-Z]' 
       let foundIndex = 0 
       let indexCounter = indexLen 
      elseif a:iExpression[currPosition -1] =~ '[a-zA-Z]' && a:iExpression[currPosition] != "\\" 
       let foundIndex = 0 
       let indexCounter = indexLen 
      else 
       let indexCounter+=1 
      endif 
     else 
      let indexCounter = indexLen 
      let foundIndex = 0 
     endif 
    endwhile 
    if foundIndex == 0 
     let oExpression .= a:iExpression[currPosition] 
     let currPosition+=1 
    else 
     if a:iInsertBraces == 1 
      let oExpression .= "{" . a:iReplacement . "}" 
     else 
      let oExpression .= a:iReplacement 
     endif 
     let currPosition+=indexLen 
    endif 
endwhile 
    echo "oExpression: " . oExpression 
return oExpression 
endfunc 

func HandleIncrement(iExpression, iIncrement) 
"and what about negative numbers for iExpression!??? not handling these yet :[ 
let oExpression = "" 
if !(a:iExpression[0] =~ '[0-9]') || a:iExpression < 10 && strlen(a:iExpression) > 1 
    let oExpression = a:iExpression . " + " . a:iIncrement 
else 
    let oExpression = a:iExpression + a:iIncrement 
endif 
echo oExpression 
return oExpression 
endfunc 

func HandleDecrement(iExpression, iIncrement) 
"TODO and what about negative numbers for iExpression!??? not handling these yet :[ 
let oExpression = "" 
if !(a:iExpression[0] =~ '[0-9]') || a:iExpression < 10 && strlen(a:iExpression) > 1 
    let oExpression = a:iExpression . " - " . a:iIncrement 
else 
    let oExpression = a:iExpression - a:iIncrement 
endif 
echo oExpression 
return oExpression 
endfunc 


func Interrogate(iQuestion) 
    call inputsave() 
    let answer = input(a:iQuestion) 
    call inputrestore() 
    return answer 
endfunc 

func InterrogateNumber(iQuestion) 
    call inputsave() 
    let answer = input(a:iQuestion) 
    call inputrestore() 
    "TODO what if negative number?? 
    if !(answer[0] =~ '[0-9]') 
     let answer = InterrogateNumber(a:iQuestion . " you didn't enter a numerical value ") 
    endif 
    return answer 
endfunc 

至于映射位,我知道看起来我没有做太多的工作,但假设我有更多的东西在挖掘我自己找到答案,任何人都可以帮忙吗?


更新。好吧,我有事情,在一个笨拙的方式排序的工作,也就是说,如果我定义以下helperfunction:

func SumOrSequenceHelper() 
    let oIndex = Interrogate("index variable? ") 
    "go to last thing visually selected (I think!), yank it (putting it in the " register), then fetch it via oParam. Then pass this off to SumOrSequence 
    execute "normal! gvy" 
    let oExpression = getreg('"') 
    call SumOrSequence(oExpression, oIndex) 
endfunc 

vnoremap <F6> :call SumOrSequenceHelper() 

那么一切都很好,我可以做一个执行命令来替换我与我的选择从SumOrSequence获得(...)

将是任何改善,但为这一个解决所有意图和目的感激:]

回答

1

你可以使用一个辅助函数是这样的:

func! GetSelectedText() 
    normal gv"xy 
    let result = getreg("x") 
    normal gv 
    return result 
endfunc 

vnoremap <F6> :call MyFunc(GetSelectedText())<cr> 

还有:com -range,它可以注册一个对选择进行操作的自定义命令,但界面是面向行的。

+0

您的解决方案比我的雨衣...感谢的! (我无法投票这一个尚未)如此确定我怎么会使用com -range的想法,但看看com的帮助和尝试:com我看到该范围不是一个定义的命令 – HexedAgain

+0

有一个例子一个范围命令在这里: http://www.adp-gmbh.ch/vim/user_commands.html(在底部) – zah

+0

这是伟大的 - 我只知道到目前为止的缩写和映射;通过(简短)命令(易于输入参数(无引号))执行正是我想要的! – HexedAgain

1

使用选择寄存器来调用与视觉选择的任何功能。

vnoremap <F6> :call Test(@*)<CR> 

如果你只是想光标在普通模式下,你可以使用这个,这猛拉到选择寄存器下抢字保存,则使用的值。 (你可以抽出任意命名寄存器来代替,例如在a寄存器与"ay@a

noremap <S-F6> "*yaw:call Test(@*)<CR> 

通过这些不与你的测试功能的工作方式,而只是调用它不似乎也有效?

:call Test("fred") 
Error detected while processing function Test: 
line 1: 
E121: Undefined variable: a 
E15: Invalid expression: a:iStr[0] =~ [a-zA-z] 

他们用这个测试功能工作:

function Test(iStr) 
    echo a:iStr 
endfunction 
+0

感谢您的建议 - 我知道我的问题的答案可能很简单,我只是不知道语法!至于测试功能,我忘了在[a-zA-Z]上键入单引号 – HexedAgain

相关问题