3

簡単に言えば、入力を節約する関数をいくつか書いたので、入力したものを選択してこの選択を関数に渡すことができるようにする vmap[ping] をセットアップしようとしています (コマンド ラインで関数呼び出しを入力するため、パラメーターを (引用符で) 入力し、バックスラッシュをエスケープするなど... 関数を呼び出すことで節約されるほとんどの時間を打ち消します)

(単純な)例として、次の関数があるとします

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

いくつかのテキストを視覚的に選択できるようにしたいと思います。次に、いくつかのキー マッピングを使用して、F2 と言うと、パラメーター iStr として機能する選択で Test(iStr) を呼び出します。

より多くの作業 (つまり、選択したものを Test() 内に配置する必要があることを指定する方法) を使用すると、次のようになると思います。

vmap <F2> :call Test()

私が求めているものです。問題は、私がいくつかの変種を試したということです (当て推量と :help map からのちょっとした危険な推論) が、何も役に立ちません。更新、ヘルパー関数 Test2() を使用してみました

call Test(<C-W>) 

その本体として...どういうわけか、カーソルの下の単語を(どういうわけか)つかむ必要があると思います.Test2内からTest(...)にそれを渡すことができるので、完了です


呼び出したい関数の実際の例として、次の (まだ不完全な) 関数 (およびヘルパー関数) を使用すると、次のような形式の式を変換できます。

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

マッピングビットに関しては、私はあまり仕事をしていないように見えますが、自分で答えを見つけるためにもっと掘り下げる必要があると仮定すると、誰か助けてもらえますか?


アップデート。わかりました、不器用な方法で動作するものがあります。つまり、次のヘルパー関数を定義した場合です。

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(...) から取得したものに置き換えることができます

改善に感謝しますが、すべての意図と目的のために、これは解決されています:]

4

2 に答える 2

2

次のようなヘルパー関数を使用できます。

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

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

選択範囲に対して動作するカスタム コマンドを登録できるもあり:com -rangeますが、インターフェイスは行指向です。

于 2012-10-10T11:44:46.030 に答える
2

選択レジスタを使用して、視覚的に選択したもので関数を呼び出します。

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

通常モードでカーソルの下の単語をつかみたい場合は、これを使用できます。これは、選択レジスタにヤンクしてから値を使用します。(代わりに任意の名前付きレジスタにヤンクすることができます。たとえば、and を含むaレジスタです。)"ay@a

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

ところで、これらは Test 関数では機能しませんが、呼び出すだけでも機能しないようですか?

: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
于 2012-10-10T16:21:22.757 に答える