Since I learnt about posh-git and posh-hg and moved from cmd to Powershell, I’ve felt the need to improve my terminal experience on Windows. Let’s face it, the built in terminals have been absolute rubbish for ages.
So I did the following:
- Added a sexier prompt that wrote the current user name and directory on one line and prompted on the next with a $.
- Added posh-hg and posh-git.
- Started using Console for better font support and transparency.
- Grabbed the elevate application, saved it in my %PATH% and renamed it to sudo :)
Here’s what I came up with:
Next I wanted to get something that felt more ‘built-in’.
One of my fondest console experiences wasn’t with a terminal that shipped with an OS, but one that came as part of a game. The consoles I used in the Quake games have a special place in my heart. Everyone remembers the first time they typed ‘impulse 9’ or ‘noclip’. You got to the console in Quake by hitting the tilde (`) key and it dropped down from the top of the screen, filling the top portion of it. It would be pretty cool if I could get something similar.
Fortunately, real-life friend Mike Lomas caught me tweeting about this and found this article written by xiao of xster.net. The article pretty much sums up how to achieve this using an application named AutoHotkey. AutoHotkey offers quite a powerful scripting language which can be used to interact with windows when a key combination is pressed.
Unfortunately, the script there wouldn’t quite fulfil my needs. The reason for this was that with my dual monitor setup, I prefer the primary screen to be on the right, and I like the console on the left. I don’t know if it’s just me, but the window would continually pop up in the top left of the right-hand screen. I tried altering the built in settings in Console and the underlying Powershell window. I tried altering the script by adding calls to AutoHotkey’s built in functions. It just wouldn’t go where I wanted.
Finally, I got somewhere by invoking some WinAPI functions from the AutoHotkey script.
-
#`::
-
-
DetectHiddenWindows, On
-
-
IfWinNotExist ahk_class Console_2_Main
-
{
-
Run Console2\Console.exe
-
WinWaitActive ahk_class Console_2_Main
-
SetWindowLocation(-1280, 0)
-
WinActivate ahk_class Console_2_Main
-
-
WinShow ahk_class ConsoleWindowClass
-
WinGet, hwnd, ID, ahk_class ConsoleWindowClass
-
SetWindowStyle(hwnd)
-
WinHide ahk_class ConsoleWindowClass
-
-
return
-
}
-
-
DetectHiddenWindows, Off
-
-
IfWinActive ahk_class Console_2_Main
-
{
-
WinMinimize ahk_class Console_2_Main
-
WinHide ahk_class Console_2_Main
-
}
-
else
-
{
-
WinShow ahk_class Console_2_Main
-
SetWindowLocation(-1280, 0)
-
WinActivate ahk_class Console_2_Main
-
}
-
-
SetWindowLocation(x, y)
-
{
-
WinGet, hwnd, ID, ahk_class Console_2_Main
-
VarSetCapacity(wp, 44, 0)
-
DllCall("GetWindowPlacement", "ptr", hwnd, "ptr", &wp)
-
NumPut(44, wp, 0, "uint")
-
NumPut(1, wp, 4, "uint")
-
NumPut(3, wp, 8, "uint")
-
NumPut(x, wp, 20, "int")
-
NumPut(y, wp, 24, "int")
-
NumPut(x, wp, 28, "int")
-
NumPut(y, wp, 32, "int")
-
DllCall("SetWindowPlacement", "ptr", hwnd, "ptr", &wp)
-
}
-
-
SetWindowStyle(hwnd)
-
{
-
ws := DllCall("GetWindowLong", "ptr", hwnd, "int", -20)
-
ws := ws &~ 0x40000
-
DllCall("SetWindowLong", "ptr", hwnd, "int", -20, "int", ws)
-
}
As you can see, there are similarities to the script in the article. The tricky bits are the calls to the Windows API, which are wrapped in the functions SetWindowLocation and SetWindowStyle. Basically, SetWindowLocation can be used to give Console’s main window a negative X co-ordinate. However, even though Console has settings to stop the console appearing in the taskbar, using SetWindowPlacement appeared to kind of screw it up. That’s where SetWindowStyle comes in, which removes a window from the taskbar. Very hacky I know. However, I have to admit as a developer who’s spent most of their time in a managed garbage collected world, low-level bit-flipping has a certain charm to it.
The script above gives the following behaviour:
- When a console is not running, a new instance is fired up and placed in the correct location.
- When a console is running but not active, it’s activated, positioned in the correct place and has focus.
- When a console is running and active, it’s hidden from view and the last window that had focus gets the focus.
- The console window does not appear in the taskbar.
I’ve never written an AutoHotkey script before, so as you might have guessed, I make no guarantees about the suitability of this script – it was put together during a lunchtime of hacking around. It does however give me Quake style console I was after.