Skip to content

Commit

Permalink
Improvements to shell.c (contributed by Guo Yu)
Browse files Browse the repository at this point in the history
 - Make the full screen window top most (by Guo Yu)

 - Make it compile without warnings (Guo Yu added const everywhere,
   I removed assignments in conditional expressions)

 - Replace make file with batch script that automatically builds
   both the shell-x86.dll and shell-x64.dll binaries (by me)
  • Loading branch information
xolox committed Nov 11, 2011
1 parent 942e75a commit d51681b
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 44 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -95,7 +95,7 @@ Vim has a limited ability to call external libraries using the Vim script functi

Since then I switched to Linux and didn't look back, which meant the DLL sat in my `~/.vim/etc/` waiting to be revived. Now that I've published my [easytags.vim][easytags] plug-in and put a lot of effort into making it Windows compatible, the `execute()` function from the DLL would be very useful to run [Exuberant Ctags][ctags] in the background without stealing Vim's focus by opening a command prompt window. This is why I've decided to release the DLL. Because I switched to Linux I've also added an autoload script that wraps the DLL on Windows and calls out to external programs such as `wmctrl`, `gnome-open`, `kde-open`, and others on UNIX.

Before I go ahead and bundle the DLL files with my [easytags.vim][easytags] plug-in I need to make sure they're compatible with as many Windows Vim installations out there as possible, e.g. XP/Vista/7, different service packs, 32/64 bits, etc. I've uploaded a [ZIP archive including two compiled DLL files][download] to the [Vim scripts page][vim_scripts_entry] for this plug-in (build using the latest Windows SDK but targeting Windows XP x86/x64 DEBUG, should also work on Vista/7) and the source code is available in the [GitHub repository](http://github.com/xolox/vim-shell) (see the `NMAKE` [makefile](http://github.com/xolox/vim-shell/blob/master/dll/Makefile) for compile instructions).
Before I go ahead and bundle the DLL files with my [easytags.vim][easytags] plug-in I need to make sure they're compatible with as many Windows Vim installations out there as possible, e.g. XP/Vista/7, different service packs, 32/64 bits, etc. I've uploaded a [ZIP archive including two compiled DLL files][download] to the [Vim scripts page][vim_scripts_entry] for this plug-in (build using the latest Windows SDK but targeting Windows XP x86/x64 RELEASE, should also work on Vista/7) and the source code is available in the [GitHub repository](http://github.com/xolox/vim-shell) (there's also a [Batch script](http://github.com/xolox/vim-shell/blob/master/dll/Makefile) with compile instructions).

## Other full-screen implementations

Expand Down
6 changes: 3 additions & 3 deletions autoload/xolox/shell.vim
@@ -1,9 +1,9 @@
" Vim auto-load script
" Author: Peter Odding <peter@peterodding.com>
" Last Change: October 29, 2011
" Last Change: November 11, 2011
" URL: http://peterodding.com/code/vim/shell/

let g:xolox#shell#version = '0.9.20'
let g:xolox#shell#version = '0.9.21'

if !exists('s:fullscreen_enabled')
let s:enoimpl = "%s() hasn't been implemented on your platform! %s"
Expand Down Expand Up @@ -340,7 +340,7 @@ if xolox#misc#os#is_win()

function! s:has_dll() " {{{2
try
return s:library_call('libversion', '') == '0.2'
return s:library_call('libversion', '') == '0.3'
catch
return 0
endtry
Expand Down
6 changes: 3 additions & 3 deletions doc/shell.txt
Expand Up @@ -201,9 +201,9 @@ need to make sure they're compatible with as many Windows Vim installations
out there as possible, e.g. XP/Vista/7, different service packs, 32/64 bits,
etc. I've uploaded a ZIP archive including two compiled DLL files [8] to the
Vim scripts page [9] for this plug-in (build using the latest Windows SDK but
targeting Windows XP x86/x64 DEBUG, should also work on Vista/7) and the
source code is available in the GitHub repository [10] (see the
'NMAKE'makefile [11] for compile instructions).
targeting Windows XP x86/x64 RELEASE, should also work on Vista/7) and the
source code is available in the GitHub repository [10] (there's also a Batch
script [11] with compile instructions).

===============================================================================
*shell-other-full-screen-implementations*
Expand Down
12 changes: 0 additions & 12 deletions misc/shell/Makefile

This file was deleted.

12 changes: 12 additions & 0 deletions misc/shell/make.cmd
@@ -0,0 +1,12 @@
:: This Windows batch script compiles the Windows DLL for the
:: shell.vim plug-in for the x86 and x64 processor architectures.

:: Build shell-x86.dll.
CALL SETENV /Release /x86 /xp
CL /nologo /Wall /LD shell.c /link /out:shell-x86.dll shell32.lib user32.lib
DEL shell.exp shell.lib shell.obj

:: Build shell-x64.dll.
CALL SETENV /Release /x64 /xp
CL /nologo /Wall /LD shell.c /link /out:shell-x64.dll shell32.lib user32.lib
DEL shell.exp shell.lib shell.obj
Binary file modified misc/shell/shell-x64.dll
Binary file not shown.
Binary file modified misc/shell/shell-x86.dll
Binary file not shown.
67 changes: 42 additions & 25 deletions misc/shell/shell.c
Expand Up @@ -26,8 +26,9 @@
*/

#define _WIN32_WINNT 0x0500 /* GetConsoleWindow() */
#define WIN32_LEAN_AND_MEAN /* but keep it simple */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ctype.h>
#include <shellapi.h> /* ShellExecute? */

/* Dynamic strings are returned using a static buffer to avoid memory leaks */
Expand All @@ -36,9 +37,9 @@ static char buffer[1024 * 10];
#undef MessageBox
#define MessageBox(message) MessageBoxA(NULL, message, "Vim Library", 0)

static char *GetError(void) /* {{{1 */
static const char *GetError(void) /* {{{1 */
{
int i;
size_t i;

FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, buffer, sizeof buffer, NULL);
Expand All @@ -50,19 +51,19 @@ static char *GetError(void) /* {{{1 */
return buffer;
}

static char *Success(char *result) /* {{{1 */
static const char *Success(const char *result) /* {{{1 */
{
/* printf("OK\n"); */
return result;
}

static char *Failure(char *result) /* {{{1 */
static const char *Failure(const char *result) /* {{{1 */
{
/* if (result && strlen(result)) MessageBox(result); */
return result;
}

static char *execute(char *command, int wait) /* {{{1 */
static const char *execute(char *command, int wait) /* {{{1 */
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
Expand All @@ -84,81 +85,96 @@ static char *execute(char *command, int wait) /* {{{1 */
}

__declspec(dllexport)
char *execute_synchronous(char *command) /* {{{1 */
const char *execute_synchronous(char *command) /* {{{1 */
{
return execute(command, 1);
}

__declspec(dllexport)
char *execute_asynchronous(char *command) /* {{{1 */
const char *execute_asynchronous(char *command) /* {{{1 */
{
return execute(command, 0);
}

__declspec(dllexport)
char *libversion(char *ignored) /* {{{1 */
const char *libversion(const char *ignored) /* {{{1 */
{
(void)ignored;
return Success("0.2");
return Success("0.3");
}

__declspec(dllexport)
char *openurl(char *path) /* {{{1 */
const char *openurl(const char *path) /* {{{1 */
{
ShellExecute(NULL, "open", path, NULL, NULL, SW_SHOWNORMAL);
return Success(NULL);
}

__declspec(dllexport)
char *fullscreen(long enable) /* {{{1 */
const char *fullscreen(long enable) /* {{{1 */
{
HWND window;
LONG styles;
LONG exStyle;
HMONITOR monitor;
MONITORINFO info = { sizeof info };

if (!(window = GetForegroundWindow()))
window = GetForegroundWindow();
if (!window)
return Failure("Could not get handle to foreground window!");

if (!(styles = GetWindowLong(window, GWL_STYLE)))
styles = GetWindowLong(window, GWL_STYLE);
if (!styles)
return Failure("Could not query window styles!");

if (enable) styles ^= WS_CAPTION | WS_THICKFRAME;
else styles |= WS_CAPTION | WS_THICKFRAME;
exStyle = GetWindowLong(window, GWL_EXSTYLE);
if (!exStyle)
return Failure("Could not query window ex style!");

if (enable) {
styles ^= WS_CAPTION | WS_THICKFRAME;
exStyle |= WS_EX_TOPMOST;
} else {
styles |= WS_CAPTION | WS_THICKFRAME;
exStyle &= ~WS_EX_TOPMOST;
}

if (!SetWindowLong(window, GWL_STYLE, styles))
return Failure("Could not apply window styles!");

if (!SetWindowLong(window, GWL_EXSTYLE, exStyle))
return Failure("Could not apply window ex style!");

if (enable) {
if (!(monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST)))
monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST);
if (!monitor)
return Failure("Could not get handle to monitor!");
if (!GetMonitorInfo(monitor, &info))
return Failure("Could not get monitor information!");
if (!SetWindowPos(window, HWND_TOP,
if (!SetWindowPos(window, HWND_TOPMOST,
info.rcMonitor.left,
info.rcMonitor.top,
info.rcMonitor.right - info.rcMonitor.left,
info.rcMonitor.bottom - info.rcMonitor.top,
SWP_SHOWWINDOW))
return Failure("Could not resize window!");
} else if (!SetWindowPos(window, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED))
} else if (!SetWindowPos(window, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED))
return Failure("Could not restore window!");

return Success(NULL);
}

__declspec(dllexport)
char *console(char *command) /* {{{1 */
const char *console(char *command) /* {{{1 */
{
/* TODO: The quest to embedding a command prompt in Vim :)
* This doesn't quite work and I'm afraid it never will.
*/

HWND gvim, console;
LONG styles;

if (!(gvim = GetForegroundWindow()))
gvim = GetForegroundWindow();
if (!gvim)
return Failure("Could not get handle to foreground window");

// destroy old console?
Expand All @@ -169,7 +185,8 @@ char *console(char *command) /* {{{1 */
return Failure("Could not allocate console");

// get handle to console window
if (!(console = GetConsoleWindow()))
console = GetConsoleWindow();
if (!console)
return Failure("Could not get handle to console window");

// embed console inside foreground window
Expand Down

0 comments on commit d51681b

Please sign in to comment.