The script below helps move between gvim and a bash-shell on Windows
using the commands Ctrl-Z and fg.
#!/c/opt/perl64/bin/perl
BEGIN {(*STDERR = *STDOUT) || die;}
=head
Switch between gVim and Bash on Windows via Ctrl-Z and fg
---------------------------------------------------------
This script helps move between gvim and a bash-shell on
Windows using the commands Ctrl-Z and fg.
My work-flow involves spending almost all my time in gvim on Windows.
Although I have some tools to help me remain in gvim while performing
tasks outside of gvim, I occasionally have to move to a bash shell.
Although there are situations -- such as those involving gvim with no
file open (issue: implementation does not look for the correct gVim
title) or multiple gvim or bash windows (issue: implementation does no
+t
offer choice among multiple windows) -- where the implementation is no
+t
fully effective, it is satisfactory for my needs.
Usage:
-----
A) The following gVim mappings:
nnoremap <c-z> :silent !perl c:\opt\bin\czfg.pl 0 % %:p:h %:p:t<c
+r>
nnoremap <s-z> :silent !perl c:\opt\bin\czfg.pl 0 % %:p:h %:p:t r
+egister<cr>
assume that this script is located at c:\opt\bin\czfg.pl
B) Before this script can be used, both gVim and bash windows must exi
+st.
C) The first time this script is used to switch between gVim and bash,
it must be from gVim, and the command to be issued -- as per the ab
+ove
mapping -- is the normal mode command <Shift-Z>. Doing so will
not only switch focus to the bash window but also define an alias f
+g
to get back to gVim from bash.
D) Subsequent switches between gVim and bash would be via <Ctrl-Z> and
+ fg.
Non-perl Alternatives:
---------------------
1) In Windows 7, the bash and gVim windows can be pinned to the task-
bar, say, as the first and second applications respectively. Then
the <Win-1> and <Win-2> activate either the bash or the gVim window
+.
If multiple bash or gVim windows are present, use <Ctrl-Win-1> and
<Ctrl-Win-2>.
2) The console ConEmu is getting better at supporting 256 colors for
console vim, but wasn't quite there as of November 3, 2013:
https://groups.google.com/d/msg/conemu_ml/nThX05Kal0E/AEOkK3Px6dYJ
=cut
use diagnostics;
use warnings;
use strict;
$| = 1;
#-----------------------------------------------------
use Win32;
use Win32::GuiTest qw(
SetForegroundWindow
GetChildWindows
GetWindowText
SendKeys
SetFocus
ShowWindow
SW_RESTORE
EnableWindow
);
defined $ARGV[ 0 ] or exit;
my $win_id = $ARGV[ 0 ];
my $buf_str = $ARGV[ 1 ];
my $win_str_p = $ARGV[ 2 ];
my $win_str_f = $ARGV[ 3 ];
my $register = $ARGV[ 4 ];
# if called via fg in bash, go back to gVim and exit
if( ! $buf_str )
{
SetFocus( $win_id );
ShowWindow( $win_id, SW_RESTORE );
EnableWindow( $win_id, 1 );
SetForegroundWindow( $win_id );
exit;
}
# if here, script has been called from gVim
# gVim window name has path within brackets
$win_str_p = "($win_str_p)";
# For use in pattern matching, escape '\', '(' and ')'.
$win_str_p =~ s,\\,\\\\,g;
$win_str_p =~ s,\(,\\(,;
$win_str_p =~ s,\),\\),;
# clean up buffer paths that are relative to local directory
$buf_str =~ s,^\.,,;
$buf_str =~ s,^\\,,;
$buf_str =~ s,^/,,;
# For files in local directory, don't use path component for gVim wind
+ow name
( $buf_str !~ /\\/ ) and ( $buf_str !~ /\// ) and $win_str_p = '';
my $go_back_to = '';
my $go_to = '';
# undocumented feature: user can specify target of fg command
$win_id and $go_back_to = $win_id;
# Get id of gVim and bash windows by iterating through all windows
for my $a_window ( GetChildWindows(0) )
{
my $foo = GetWindowText($a_window);
# get first match to gVim window title
if( ( ! $go_back_to ) and
( $foo =~ m/gvim/i ) and
( $foo =~ m/$win_str_f/i ) and
( $foo =~ m/$win_str_p/i ) ) # empty string will match
{
$go_back_to = $a_window;
}
# get first match to bash window title
if( ( ! $go_to ) and
( $foo eq 'bash' ) ) # reset any messed up title via: echo -n
+e "\033]0;bash\007"
{
$go_to = $a_window;
}
}
# bring the bash window forward
SetFocus( $go_to );
ShowWindow( $go_to, SW_RESTORE );
EnableWindow( $go_to, 1 );
SetForegroundWindow( $go_to );
# Done unless user has requested that the alias fg be created
$register and ( $register eq 'register' ) or exit;
# If here, need to build and issue the command to create the alias fg
# Assuming script is not in path, get full path to script
my $script = Cwd::abs_path( $0 ); # didn't work: File::Spec->rel2abs(
+$0 );
# Convert '\' to '/' for use in bash
$script =~ s,\\,/,g; # weird: have seen Cwd::abs_path use both '\' and
+ '/'
# create the alias fg
SendKeys("alias fg=\'$script $go_back_to\'\n");
__END__