#!/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 not offer choice among multiple windows) -- where the implementation is not fully effective, it is satisfactory for my needs. Usage: ----- A) The following gVim mappings: nnoremap :silent !perl c:\opt\bin\czfg.pl 0 % %:p:h %:p:t nnoremap :silent !perl c:\opt\bin\czfg.pl 0 % %:p:h %:p:t register 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 exist. 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 above mapping -- is the normal mode command . Doing so will not only switch focus to the bash window but also define an alias fg to get back to gVim from bash. D) Subsequent switches between gVim and bash would be via 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 and activate either the bash or the gVim window. If multiple bash or gVim windows are present, use and . 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 window 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 -ne "\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__