Gemini 2.5 - TrueCrimeAudit/ClautoHotkey GitHub Wiki
Snippet Manager Test
The new Gemini 2.5 just one shot this snippet manager. I am a little shocked, because even the best flagship models still have some issue with this prompt and sometimes more simple prompts. I did use my standard system prompt for AHK v2 that just helps with the basics like I do with all new models.
There's a little bit of everything in this example to test the LLMs AHK v2 writing abilities. The requirements for this example use some simple patterns. I also look for anything extra that I think wasn't required but showed some level of complexity.
Required:
- Initiates class properly (LLMs struggle with appending "new " to classes)
- Creating a static map
- Escaping strings
- Variable scoping
- Previous window context
- Control storage
Extras:
- Fat arrow function
The Prompt
Create an AutoHotkey v2 script for a Snippet Manager tool with the following features:
- Store a collection of predefined text snippets (like greetings, closings, reminders)
- Display them in a listbox GUI
- Allow copying the selected snippet to clipboard
- Option to send the snippet directly to the previous active window
- Show temporary tooltips for user feedback
Additional Requirements:
- Store snippets in a static Map
- Track the previously active window
- Have a clean, resizable GUI
- Display tooltips that automatically disappear
Include these specific snippets: "Greeting", "Closing", "Reminder", and "Follow-up" with appropriate text content for each.
Make sure to follow AutoHotkey v2 best practices with proper event binding, control management, and variable scoping.
The Code
#Requires AutoHotkey v2.1-alpha.16
#SingleInstance Force
SnippetManagerGui() ; Initialize the class
class SnippetManagerGui {
; --- Static Configuration ---
static SNIPPETS := Map(
"Greeting", "Hello [Name],`n`nHope you are having a great week!`n",
"Closing", "Best regards,`n`n[Your Name]",
"Reminder", "Just a friendly reminder about the meeting scheduled for [Date] at [Time].",
"Follow-up", "Following up on our previous conversation regarding [Topic]. Do you have any updates?`n"
)
static TOOLTIP_DURATION := 2000 ; Milliseconds
; --- Properties ---
gui := ""
controls := Map()
lastActiveWin := 0
tooltipTimer := 0
; --- Constructor ---
__New() {
this.InitializeGui()
this.SetupControls()
this.PopulateListbox()
this.SetupEventHandlers()
this.SetupHotkeys() ; Optional: Add a hotkey to show/hide
OutputDebug("Snippet Manager Initialized.")
}
; --- Initialization Methods ---
InitializeGui() {
this.gui := Gui("+Resize", "Snippet Manager")
this.gui.SetFont("s10", "Segoe UI")
this.gui.OnEvent("Close", this.Hide.Bind(this))
this.gui.OnEvent("Escape", this.Hide.Bind(this))
; Capture the previously active window when this GUI gets focus
this.gui.OnEvent("Context", this.GuiContext.Bind(this))
}
SetupControls() {
this.controls["listbox"] := this.gui.AddListBox("w250 h300 vSelectedSnippetName")
this.controls["copyBtn"] := this.gui.AddButton("w120 yp x+m", "&Copy")
this.controls["sendBtn"] := this.gui.AddButton("w120 yp", "&Send")
this.controls["status"] := this.gui.AddText("w250 y+10", "Select a snippet.") ; Simple status/info text
}
PopulateListbox() {
snippetNames := Array()
for name in SnippetManagerGui.SNIPPETS.Keys() {
snippetNames.Push(name)
}
this.controls["listbox"].Add(snippetNames)
}
SetupEventHandlers() {
this.controls["copyBtn"].OnEvent("Click", this.CopySnippet.Bind(this))
this.controls["sendBtn"].OnEvent("Click", this.SendSnippet.Bind(this))
; Allow double-click in listbox to send
this.controls["listbox"].OnEvent("DoubleClick", this.SendSnippet.Bind(this))
; Update status text on selection change
this.controls["listbox"].OnEvent("Change", (*) => {
this.controls["status"].Value := "Selected: " this.controls["listbox"].Text
})
}
SetupHotkeys() {
; Example: Win+Shift+S to toggle the GUI
Hotkey("#+s", this.Toggle.Bind(this))
}
; --- Event Handlers ---
GuiContext(guiObj, EventInfo, wParam, lParam) {
; WM_ACTIVATE (0x0006) is often sent during context changes.
; wParam low word indicates activation state, lParam is the HWND being activated/deactivated.
; However, Gui OnEvent("Context")'s wParam seems more reliable for the *previous* HWND.
if (wParam != 0 && wParam != this.gui.Hwnd) {
; Check if the window handle is valid before storing
if WinExist("ahk_id " wParam) {
this.lastActiveWin := wParam
OutputDebug("SnippetManager: Captured last active window: " this.lastActiveWin " (" WinGetTitle("ahk_id " wParam) ")")
} else {
OutputDebug("SnippetManager: GuiContext received invalid previous HWND: " wParam)
}
}
return 0 ; Allow default processing
}
CopySnippet(*) {
snippetName := ""
snippetContent := this.HandleSelection(&snippetName)
if (snippetContent != "") {
A_Clipboard := snippetContent
this.ShowTooltip("'" snippetName "' copied to clipboard.")
OutputDebug("Copied snippet: " snippetName)
}
}
SendSnippet(*) {
snippetName := ""
snippetContent := this.HandleSelection(&snippetName)
if (snippetContent = "") {
return ; HandleSelection already showed tooltip if needed
}
if (!this.lastActiveWin || !WinExist("ahk_id " this.lastActiveWin)) {
this.ShowTooltip("Error: Previous window not found or invalid.")
OutputDebug("Send error: Invalid lastActiveWin: " this.lastActiveWin)
return
}
try {
OutputDebug("Attempting to send to HWND: " this.lastActiveWin " (" WinGetTitle("ahk_id " this.lastActiveWin) ")")
WinActivate("ahk_id " this.lastActiveWin)
if WinWaitActive("ahk_id " this.lastActiveWin, , 0.5) { ; Wait max 0.5 sec
Sleep(100) ; Small delay for focus to settle
SendInput(snippetContent)
this.ShowTooltip("'" snippetName "' sent.")
OutputDebug("Sent snippet: " snippetName " to HWND: " this.lastActiveWin)
} else {
this.ShowTooltip("Error: Could not activate previous window.")
OutputDebug("Send error: Failed to activate HWND: " this.lastActiveWin)
}
} catch Error as e {
this.ShowTooltip("Error sending snippet: " e.Message)
OutputDebug("Send exception: " e.Message)
}
}
; --- Utility Methods ---
HandleSelection(&snippetNameRef) {
selectedName := this.controls["listbox"].Text ; .Text gets the selected item's text
if (selectedName = "") {
this.ShowTooltip("Please select a snippet first.")
snippetNameRef := ""
return ""
}
if (!SnippetManagerGui.SNIPPETS.Has(selectedName)) {
this.ShowTooltip("Error: Snippet key not found.")
OutputDebug("Selection Error: Key '" selectedName "' not in SNIPPETS map.")
snippetNameRef := selectedName
return ""
}
snippetNameRef := selectedName
return SnippetManagerGui.SNIPPETS[selectedName]
}
ShowTooltip(text) {
; Disable previous timer if it exists
if (this.tooltipTimer) {
SetTimer(this.tooltipTimer, 0) ; Disable the timer
this.tooltipTimer := 0
}
ToolTip(text)
; Create a new timer - use negative period for one-time execution
this.tooltipTimer := SetTimer(this.ClearTooltip.Bind(this), -SnippetManagerGui.TOOLTIP_DURATION)
}
ClearTooltip() {
ToolTip() ; Clear the tooltip
this.tooltipTimer := 0 ; Reset timer reference
}
Show() {
; It's often good practice to capture the *current* active window
; right before showing, as GuiContext might not trigger if already shown.
; However, relying on GuiContext is cleaner if it works reliably.
; Let's stick with GuiContext for now.
this.gui.Show()
OutputDebug("Snippet Manager Shown.")
}
Hide(*) {
this.gui.Hide()
OutputDebug("Snippet Manager Hidden.")
}
Toggle(*) {
if WinExist("ahk_id " this.gui.Hwnd) {
this.Hide()
} else {
this.Show()
}
}
}