How to create a map with a possibly undefined variable as part of it

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

How to create a map with a possibly undefined variable as part of it

Dave Roberts
Sorry if this is right in front of my eyes in eval.txt or map.txt...
I know I can do this in a function but am trying to do it in a map.

(WinXP GVIM 7 from last weeks CVS sources)

I want to create a map to copy the current file ("%") to a directory
that's in a global variable (g:copydir) so I tried:
nmap <Leader>cp    :if exists("g:copydir") | exe "!cp -i \"%\"
".g:copydir | else | echo "g:copydir not set" | endif

This caused an error if g:copydir didn't exist because according to
eval.txt (under :if) 'The commands still need to be parsed to find the
"endif".'

OK so I tried to create it if it doesn't exist then remove it when done:
nmap <Leader>cp    :if !exists("g:copydir") | let copydirnotexist=1 |
let g:copydir='' | echo 'g:copydir not set' | else | let
copydirnotexist=0 | exe "!cp -i \"%\" ".g:copydir | endif | if
copydirnotexist > 0 | unlet g:copydir | endif | unlet copydirnotexist

(or if you'd rather)
nmap <Leader>cp    :if !exists("g:copydir") |
                             \ let copydirnotexist=1 |
                             \ let g:copydir='' |
                             \ echo 'g:copydir not set' |
                           \ else |
                             \ let copydirnotexist=0 |
                             \ exe "!cp -i \"%\" ".g:copydir |
                           \ endif |
                           \ if copydirnotexist |
                             \ unlet g:copydir |
                           \ endif |
                           \ unlet copydirnotexist

If I take the single line version and cut from the first 'IF' (so I have
the whole expression but not the "nmap <Leader>cp") and paste to the
command line it works.

If I cut the whole line (including the mapping) it says:
E581: :else without :if

What am I missing?

Thanks,

- Dave
Reply | Threaded
Open this post in threaded view
|

RE: How to create a map with a possibly undefined variable as part of it

Halim, Salman
The simplest thing to do in my experience is something like this:

function! CopyFile()
  if exists( 'g:copydir' )
    execute '!cp -I "%" ' . g:copydir
  else
    echohl WarningMsg
    echo "g:copydir not set"
    echohl None
  endif
Endfunction
nmap <Leader>cp :call CopyFile()<CR>

Basically, I put complex commands in a function and just have a mapping
that calls the function.

Look at the help for echohl to change the highlight of the echo in the
else to resemble an error or a warning...

Salman.

> -----Original Message-----
> From: Dave Roberts [mailto:[hidden email]]
> Sent: Thursday, August 18, 2005 12:11 PM
> To: Vim
> Subject: How to create a map with a possibly undefined
> variable as part of it
>
> Sorry if this is right in front of my eyes in eval.txt or map.txt...
> I know I can do this in a function but am trying to do it in a map.
>
> (WinXP GVIM 7 from last weeks CVS sources)
>
> I want to create a map to copy the current file ("%") to a
> directory that's in a global variable (g:copydir) so I tried:
> nmap <Leader>cp    :if exists("g:copydir") | exe "!cp -i \"%\"
> ".g:copydir | else | echo "g:copydir not set" | endif
>
> This caused an error if g:copydir didn't exist because
> according to eval.txt (under :if) 'The commands still need to
> be parsed to find the "endif".'
>
> OK so I tried to create it if it doesn't exist then remove it
> when done:
> nmap <Leader>cp    :if !exists("g:copydir") | let copydirnotexist=1 |
> let g:copydir='' | echo 'g:copydir not set' | else | let
> copydirnotexist=0 | exe "!cp -i \"%\" ".g:copydir | endif |
> if copydirnotexist > 0 | unlet g:copydir | endif | unlet
> copydirnotexist
>
> (or if you'd rather)
> nmap <Leader>cp    :if !exists("g:copydir") |
>                              \ let copydirnotexist=1 |
>                              \ let g:copydir='' |
>                              \ echo 'g:copydir not set' |
>                            \ else |
>                              \ let copydirnotexist=0 |
>                              \ exe "!cp -i \"%\" ".g:copydir |
>                            \ endif |
>                            \ if copydirnotexist |
>                              \ unlet g:copydir |
>                            \ endif |
>                            \ unlet copydirnotexist
>
> If I take the single line version and cut from the first 'IF'
> (so I have the whole expression but not the "nmap
> <Leader>cp") and paste to the command line it works.
>
> If I cut the whole line (including the mapping) it says:
> E581: :else without :if
>
> What am I missing?
>
> Thanks,
>
> - Dave
>
Reply | Threaded
Open this post in threaded view
|

Re: How to create a map with a possibly undefined variable as part of it

Dave Roberts
Halim, Salman wrote:

>The simplest thing to do in my experience is something like this:
>
>function! CopyFile()
>  if exists( 'g:copydir' )
>    execute '!cp -I "%" ' . g:copydir
>  else
>    echohl WarningMsg
>    echo "g:copydir not set"
>    echohl None
>  endif
>Endfunction
>nmap <Leader>cp :call CopyFile()<CR>
>
>Basically, I put complex commands in a function and just have a mapping
>that calls the function.
>
>Look at the help for echohl to change the highlight of the echo in the
>else to resemble an error or a warning...
>
>Salman.
>  
>

That's more or less what I ended up with (you added the warning message
coloring) but I was curious as to why I could, at the command line use
that whole command just fine but if I tried to map the same line I got a
message that the ELSE had no IF to go with it?!?

Thanks,

- Dave
Reply | Threaded
Open this post in threaded view
|

Re: How to create a map with a possibly undefined variable as part of it

A.J.Mechelynck
----- Original Message -----
From: "Dave Roberts" <[hidden email]>
To: "Vim" <[hidden email]>
Sent: Thursday, August 18, 2005 7:39 PM
Subject: Re: How to create a map with a possibly undefined variable as part
of it


> Halim, Salman wrote:
>
>>The simplest thing to do in my experience is something like this:
>>
>>function! CopyFile()
>>  if exists( 'g:copydir' )
>>    execute '!cp -I "%" ' . g:copydir
>>  else
>>    echohl WarningMsg
>>    echo "g:copydir not set"
>>    echohl None
>>  endif
>>Endfunction
>>nmap <Leader>cp :call CopyFile()<CR>
>>
>>Basically, I put complex commands in a function and just have a mapping
>>that calls the function.
>>
>>Look at the help for echohl to change the highlight of the echo in the
>>else to resemble an error or a warning...
>>
>>Salman.
>>
>
> That's more or less what I ended up with (you added the warning message
> coloring) but I was curious as to why I could, at the command line use
> that whole command just fine but if I tried to map the same line I got a
> message that the ELSE had no IF to go with it?!?
>
> Thanks,
>
> - Dave

I think you got hit by what is described at ":help map_bar".

Try wrapping the whole {rhs} in an ":exec" statement.

Best regards,
Tony.


Reply | Threaded
Open this post in threaded view
|

Re: How to create a map with a possibly undefined variable as part of it

Dave Roberts
Tony Mechelynck wrote:

> ----- Original Message ----- From: "Dave Roberts" <[hidden email]>
> To: "Vim" <[hidden email]>
> Sent: Thursday, August 18, 2005 7:39 PM
> Subject: Re: How to create a map with a possibly undefined variable as
> part of it
>
>
>> Halim, Salman wrote:
>>
>>> The simplest thing to do in my experience is something like this:
>>>
>>> function! CopyFile()
>>>  if exists( 'g:copydir' )
>>>    execute '!cp -I "%" ' . g:copydir
>>>  else
>>>    echohl WarningMsg
>>>    echo "g:copydir not set"
>>>    echohl None
>>>  endif
>>> Endfunction
>>> nmap <Leader>cp :call CopyFile()<CR>
>>>
>>> Basically, I put complex commands in a function and just have a mapping
>>> that calls the function.
>>>
>>> Look at the help for echohl to change the highlight of the echo in the
>>> else to resemble an error or a warning...
>>>
>>> Salman.
>>>
>>
>> That's more or less what I ended up with (you added the warning
>> message coloring) but I was curious as to why I could, at the command
>> line use that whole command just fine but if I tried to map the same
>> line I got a message that the ELSE had no IF to go with it?!?
>>
>> Thanks,
>>
>> - Dave
>
>
> I think you got hit by what is described at ":help map_bar".
>
> Try wrapping the whole {rhs} in an ":exec" statement.
>
> Best regards,
> Tony.
>
>

I tried:

nmap <Leader>cp    :exe "if !exists('g:copydir') | let copydirnotexist=1
| let g:copydir='' | echo 'g:copydir not set' | else | let
copydirnotexist=0 | exe '!cp -i \"%\" '.g:copydir | endif | if
copydirnotexist > 0 | unlet g:copydir | endif | unlet copydirnotexist"

But that didn't work either.

I should have mentioned in the original email that I, besides what I
showed, I also tried wrapping the rhs in an :exec as well as the whole line.

Thanks though,

- Dave
Reply | Threaded
Open this post in threaded view
|

Re: How to create a map with a possibly undefined variable as part of it

Bill McCarthy
In reply to this post by Dave Roberts
On Thu 18-Aug-05 11:10am -0500, Dave Roberts wrote:


> Sorry if this is right in front of my eyes in eval.txt or map.txt...
> I know I can do this in a function but am trying to do it in a map.
>
> (WinXP GVIM 7 from last weeks CVS sources)
>
> I want to create a map to copy the current file ("%") to a directory
> that's in a global variable (g:copydir) so I tried:
> nmap <Leader>cp    :if exists("g:copydir") | exe "!cp -i \"%\"
> ".g:copydir | else | echo "g:copydir not set" | endif
>
> This caused an error if g:copydir didn't exist because according to
> eval.txt (under :if) 'The commands still need to be parsed to find the
> "endif".'

Was that map line on one line?  It works fine here if I
escape the bars and end it with a <CR>.

You could put this in your _vimrc file as such:

    nmap <Leader>cp :if exists("g:copydir")
            \\| exe "!cp -i \"%\"" . g:copydir
        \\| else
            \\| echo "g:copydir not set"
        \\| endif<CR>

--
Best regards,
Bill