A simple vim script programming question (Calling external command)

85 views
Skip to first unread message

Neo

unread,
Sep 13, 2007, 1:16:20 AM9/13/07
to vim_use
hi,

I used VIM a lot but this is my first time to modify VIM script. The
problem is because I am using Cygwin on Windows and the path
difference between these two creates some problem.

The script I am going to modify is the perforce.vim script, which can
be found in vim.sourceforge.net.

I just want to change the "format" of the "filename" it passed to each
function from "/cygdrive/c/..../" to "C:\...", since the command only
recognize the later format.

The following is what I have:

let s:os_type = system( 'uname -o' )

then, I want to check the os_type in the following function, if it is
"Cygwin", it will change the variable "filename" by using external
command "cygpath -w". But I don't know how to assembly this external
command with option and the variable "filename", then get it back to
another variable.

function s:P4ShellCommandCurrentBuffer( sCmd )
let filename = expand( "%:p" )
return s:P4ShellCommand( a:sCmd . " " . filename )
endfunction

Thanks,
Neo

Gary Johnson

unread,
Sep 13, 2007, 3:18:29 AM9/13/07
to vim...@googlegroups.com
On 2007-09-13, Neo <neo...@gmail.com> wrote:
> hi,
>
> I used VIM a lot but this is my first time to modify VIM script. The
> problem is because I am using Cygwin on Windows and the path
> difference between these two creates some problem.

Indeed.

> The script I am going to modify is the perforce.vim script, which can
> be found in vim.sourceforge.net.
>
> I just want to change the "format" of the "filename" it passed to each
> function from "/cygdrive/c/..../" to "C:\...", since the command only
> recognize the later format.
>
> The following is what I have:
>
> let s:os_type = system( 'uname -o' )
>
> then, I want to check the os_type in the following function, if it is
> "Cygwin", it will change the variable "filename" by using external
> command "cygpath -w". But I don't know how to assembly this external
> command with option and the variable "filename", then get it back to
> another variable.
>
> function s:P4ShellCommandCurrentBuffer( sCmd )
> let filename = expand( "%:p" )
> return s:P4ShellCommand( a:sCmd . " " . filename )
> endfunction

The following segment, borrowed with modifications from Doug Potts's
ccase.vim, will convert from a Cygwin path to a Windows path. (This
may put a newline at the end of winpath--I didn't check that.)

if &shellxquote == '"'
let winpath = system("cygpath -w '" . filename . "'")
else
let winpath = system('cygpath -w "' . filename . '"')
endif

Is that what you were looking for?

HTH,
Gary

thomas

unread,
Sep 13, 2007, 3:37:19 AM9/13/07
to vim_use

> then, I want to check the os_type in the following function, if it is
> "Cygwin", it will change the variable "filename" by using external
> command "cygpath -w".

Another solution to prevent most of these problems would be to
temporarily change the working directory to fnamemodify(filename,
':p:h') if feasible.

let cwd = getcwd()
exec 'lcd '. escape(fnamemodify(filename, ':p:h'), '#%')
try
let filename = fnamemodify(filename, ':t')
+++
finally
exec 'lcd '. escape(cwd, '#%')
endtry

Or so.


Hari Krishna Dara

unread,
Sep 13, 2007, 11:27:11 AM9/13/07
to vim_use

Have you considered using cygwin version of p4.exe and setting AltRoots
to include the cygwin version of the ClientRoot in your client
specifications? If your ClientRoot is c:/xyz, then you would include
/cygdrive/c/xyz in the AltRoots.

Another alternative is to continue using windows p4.exe (for better
performance), but mount your dev directory as /xyz, something like this:

mount c:/xyz /xyz

When you access your workspace from Vim, you should remember to use /xyz
instead of /cygdrive/c/xyz.

One issue with the alternative approach is that often people name their
ClientRoot as "dev" as in c:/dev and mounting it as /dev will collide
with that of the device file paths. There are only a small set of device
files that matter on cygwin, most important being /dev/null and if I
recollect correctly, cygwin ends up creating a file called "null" in
your c:/dev directory and everything would still work just fine. You
still have to unset PWD before invoking windows p4, as I noticed that it
is sensitive to this environment variable.

PS: I used the alternate configuration that I is suggested above for
more than 5 yrs. previously and never noticed any issues with commands
misbehaving, but that is just my experience.

PS2: On vim.sf.net, you would find an alternative perforce plugin
maintained by me, that is a lot more powerful than the one you are
trying to use, so you might want to give it a try. In my plugin, if
cygwin environment is detected, I automatically clear the PWD variable
as part of running every p4 command

--
HTH,
Hari

>
> Thanks,
> Neo
>
>
> >
>

Neo

unread,
Sep 13, 2007, 1:23:14 PM9/13/07
to vim_use
Hari,

I tried your scripts. But vim crashes once I opened a new file.

I used the latest version of your scripts (4.1) and the genutils
(2.4). Also, I clean-up my .vim directory. The vim I used on Cygwin is
7.1.

Is there anything I missed?

Thanks,
Neo

Neo

unread,
Sep 13, 2007, 1:41:26 PM9/13/07
to vim_use

Gary,

I tried your approach it can convert the path from unix to windows.
But, it seems that I missed the "'" of the filename, which I used
passed to p4 command finally.

Is there a way to append a " ' " at each end of the filename?

Thanks,
Neo

>
> HTH,
> Gary

Gary Johnson

unread,
Sep 13, 2007, 2:25:28 PM9/13/07
to vim...@googlegroups.com

The 's are not really part of the file name, are they? I assume you
mean that your file name contains spaces and therefore must be
quoted for your p4 to recognize the name as one string.

You could put ' at each end of the file name with this command,

let filename = "'".filename."'"

but I'm not sure that's the right solution.

I find proper quoting of file names with spaces to be difficult,
especially when interfacing between Windows and Cygwin commands and
environments. That's one reason I gave up using gvim for Windows
with Cygwin. I now use gvim for Windows when editing in a Windows
environment and use vim for Cygwin when editing in a Cygwin
environment.

Putting proper quotes around command arguments should be handled by
the 'shellxquote' and/or 'shellquote' options. That's why the code
segment above has that "if". It sounds like you may not have those
set properly for your 'shell'. Take a look at the help for those
two options. Something else to try would be use "echo" as your
command instead of p4 so that you can see what the arguments to p4
look like.

Regards,
Gary

Neo

unread,
Sep 13, 2007, 6:12:18 PM9/13/07
to vim_use

Gary,

Could you show me how to remove the "newline" at the end of this
"filename" ?

Thanks,
Neo

Gary Johnson

unread,
Sep 13, 2007, 7:46:04 PM9/13/07
to vim...@googlegroups.com
On 2007-09-13, Neo <neo...@gmail.com> wrote:

> Could you show me how to remove the "newline" at the end of this
> "filename" ?

Sure.

let filename = substitute(filename, "\n", "", "")

That will delete the first newline from filename.

Here's an example from my ~/.vimrc where I determine the current OS:

let os = substitute(system('uname'), "\n", "", "")

That particular ~/.vimrc is always read by a version of vim built
for some flavor of Unix: Linux, SunOS or HP-UX.

Regards,
Gary

Reply all
Reply to author
Forward
0 new messages