LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-09-2012, 02:23 PM   #1
gregAstley
LQ Newbie
 
Registered: Aug 2012
Distribution: ubuntu 11.10
Posts: 27

Rep: Reputation: 4
Vim, vmap, send selected text as a function parameter


In brief, having written some functions to save typing I'm trying to set up a vmap[ping] that will allow me to select something I typed, and pass this selection to a function (since typing the function call on the command line, typing the parameters (with quotes), and escaping backslashes etc... counteracts most of the time saved by calling functions)

For (a simple) example, supposing I had the following function

Code:
    func Test(iStr)
    if a:iStr[0] =~ [a-zA-z]
        echo "hello"
    else
        echo "hello world"
    endif
    endfunc
I'd like to be able to visual select some text and then with some key mapping, F2 say, it will call Test(iStr) with the selection serving as the parameter iStr

I believe, that with more work (i.e. some way to specify that what I've selected should be inside Test()), the following

vmap <F2> :call Test()

is what I'm after. Thing is I've tried a number of variants (guesswork plus a little bit of dodgy inference from :help map) and I'm not getting anything useful


-----------------------------

As for an actual example of a function I want to call, the following (incomplete yet) function (and helper functions) would allow me to convert an expression of the form, say,

f_k^{(j)}g
to

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

In terms of a procedure I want to

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(...)

The code for SumOrSequence(...) is as follows:

Code:
    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
As regards the mapping bit, I know it looks like I haven't done too much work but assuming I have lots more digging ahead of me to find the answer myself (and I'm getting a bit frustrated with it right now!), can anyone help? (some of you may notice I posted this in stackoverflow too)


Update. Solved it, the following does the job (not perfectly, but good enough!)


Code:
    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()

Last edited by gregAstley; 10-09-2012 at 07:02 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
function parameter vbx_wx Programming 5 04-04-2010 02:34 PM
Compilation issue when Function is parameter in function call on LINUX sa20358 Linux - Software 2 07-24-2008 10:19 PM
what is function parameter? Jeon, Chang-Min Linux - Software 2 06-22-2006 06:53 PM
Bash function parameter Misel Programming 2 05-17-2003 11:51 AM
How to allow selected users to send a email to a particular IP xanthium Linux - Networking 2 11-05-2002 08:49 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration