; clipboard_to_pwsh.ahk ; ===================== ; Clipboard-driven hotkey suite for Windows. Executes clipboard content via a ; persistent background PowerShell server, opens URLs, browses paths, tiles ; terminals, and more. ; ; Requirements: ; - AutoHotkey v2.0+ ; - PowerShell 7 (pwsh) ; - profile_hotkey_server.ps1 and profile_hotkey_launcher.ps1 in the same ; directory as this script (or under %USERPROFILE%\Scripts\autohotkey\) ; - clip_watcher.ps1 for Win+Shift+C clipboard editing feature ; ; Paths are derived from %USERPROFILE% — no hardcoded user paths. ; ; Hotkeys: ; Win+Shift+Enter — Execute clipboard via PowerShell server ; Win+Shift+C — Edit clipboard in Sublime with auto-sync back ; Win+Shift+/ — Toggle server window visibility ; Win+Shift+U — Open clipboard as URL in default browser ; Win+Shift+B — Open clipboard path in Explorer ; Win+Shift+R — Copy rules.txt to clipboard ; Win+Shift+P — Run clipboard as Python script (probe) ; Win+Shift+D — Set probe working directory ; Win+Shift+A — Tile all terminal windows ; Win+Ctrl+Shift+A — Tile with priority dialog #Requires AutoHotkey v2.0 #SingleInstance Force Persistent ; Self-elevate to admin so we can move elevated windows (tiling, etc.) if !A_IsAdmin { try Run("*RunAs " A_ScriptFullPath) ExitApp } global gUserProfile := EnvGet("USERPROFILE") ; Win+Shift+Enter: Execute clipboard/selection via persistent background PowerShell. ; The server process (profile_hotkey_server.ps1) stays running with full $PROFILE loaded. ; AHK communicates via temp files — no new process spawned per command. ; ; Detection logic: ; - Starts with "context" → inspect command (helpers available) ; - Starts with "outline" → inspect command (helpers available) ; - Starts with "snap" → inspect command (helpers available) ; - Starts with "#-#" → batch payload (helpers available) ; - Anything else → raw pwsh passthrough (full profile available) ; ; Win+Shift+C: Write clipboard to clip.txt, open in Sublime with file-watcher ; that syncs saves back to clipboard. ; ; Win+Shift+/: Toggle server window — hide / show+focus (handles buried windows) ; Toggle server window visibility (handles buried/unfocused windows) #+/:: { DetectHiddenWindows(true) hwnd := WinExist("AHK_HOTKEY_SERVER") DetectHiddenWindows(false) if (!hwnd) { ToolTip("Server window not found") SetTimer(() => ToolTip(), -1500) return } isVisible := DllCall("IsWindowVisible", "Ptr", hwnd) isFocused := (WinExist("A") = hwnd) if (isVisible && isFocused) { WinHide(hwnd) ToolTip("Server window hidden") } else { WinShow(hwnd) WinActivate(hwnd) ToolTip("Server window shown") } SetTimer(() => ToolTip(), -1500) } ; Win+Shift+C: Clipboard → clip.txt → Sublime (with auto-sync back to clipboard) #+c:: { clipFile := gUserProfile "\pocket\clip.txt" watcherScript := gUserProfile "\Scripts\autohotkey\clip_watcher.ps1" clip := A_Clipboard if (clip = "") { ToolTip("Clipboard is empty") SetTimer(() => ToolTip(), -1000) return } ; Write clipboard to file (overwrite) try FileDelete(clipFile) FileAppend(clip, clipFile, "UTF-8") ; Kill any existing watcher before starting a new one try RunWait('pwsh -NoProfile -NoLogo -Command "Get-Process pwsh | Where-Object { $_.CommandLine -like \"*clip_watcher*\" } | Stop-Process -Force -ErrorAction SilentlyContinue"',, "Hide") ; Start file watcher (hidden, stays alive while Sublime has the file open) Run('pwsh -NoProfile -NoLogo -WindowStyle Hidden -File "' watcherScript '" "' clipFile '"',, "Hide") ; Open in Sublime Run('"C:\Program Files\Sublime Text\sublime_text.exe" "' clipFile '"') ToolTip("Clipboard → clip.txt (watching for saves)") SetTimer(() => ToolTip(), -2000) } ; Probe working directory (default) global gProbeDir := gUserProfile "\temp" ; Win+Shift+D: Set probe working directory via input dialog #+d:: { global gProbeDir ib := InputBox("Set the working directory for probe (Win+Shift+P):", "Probe Directory", "w500 h120", gProbeDir) if (ib.Result = "Cancel") return dir := Trim(ib.Value, " `t`r`n") if (dir = "" || !DirExist(dir)) { ToolTip("Directory not found: " dir) SetTimer(() => ToolTip(), -2000) return } gProbeDir := dir ToolTip("Probe directory: " gProbeDir) SetTimer(() => ToolTip(), -2000) } ; Win+Shift+P: Run clipboard as Python script (probe) #+p:: { global gProbeDir clip := A_Clipboard if (clip = "") { ToolTip("Clipboard is empty") SetTimer(() => ToolTip(), -1000) return } ; Write clipboard to a temp .py file tmpPy := A_Temp "\ahk_probe.py" try FileDelete(tmpPy) FileAppend(clip, tmpPy, "UTF-8") ; Build the PowerShell command to run it psScript := "Set-Location '" gProbeDir "'; python '" tmpPy "'" SendToServer(psScript, "raw", "probe") } ; URI encode for search queries UriEncode(str) { encoded := "" loop parse, str { ch := A_LoopField if RegExMatch(ch, "[A-Za-z0-9\-_.~]") encoded .= ch else encoded .= Format("%{:02X}", Ord(ch)) } return encoded } ; Comm directory global gCommDir := A_Temp "\ahk_pwsh" global gTriggerFile := gCommDir "\trigger.txt" global gScriptFile := gCommDir "\cmd.ps1" global gOutFile := gCommDir "\output.txt" global gStatusFile := gCommDir "\status.txt" global gPidFile := gCommDir "\server.pid" global gServerPath := gUserProfile "\Scripts\autohotkey\profile_hotkey_server.ps1" ; Ensure comm directory exists DirCreate(gCommDir) ; Launch server on startup if not already running EnsureServer() EnsureServer() { global gPidFile, gServerPath if FileExist(gPidFile) { try { pid := Trim(FileRead(gPidFile, "UTF-8"), " `t`r`n") if (pid != "") { if ProcessExist(Integer(pid)) { return } } } } launcherPath := gUserProfile "\Scripts\autohotkey\profile_hotkey_launcher.ps1" Run("pwsh -NoProfile -NoLogo -File `"" launcherPath "`"") ToolTip("Starting hotkey server...") timeout := 10000 elapsed := 0 while (!FileExist(gPidFile) && elapsed < timeout) { Sleep(200) elapsed += 200 } Sleep(500) try WinHide("AHK_HOTKEY_SERVER") if FileExist(gPidFile) { ToolTip("Hotkey server started") SetTimer(() => ToolTip(), -1500) } else { ToolTip("Server failed to start") SetTimer(() => ToolTip(), -3000) } } SendToServer(psScript, mode, label) { global gTriggerFile, gScriptFile, gOutFile, gStatusFile EnsureServer() try FileDelete(gOutFile) try FileDelete(gStatusFile) try FileDelete(gScriptFile) try FileDelete(gTriggerFile) FileAppend(psScript, gScriptFile, "UTF-8") FileAppend(mode, gTriggerFile, "UTF-8") ToolTip(label "...") timeout := 30000 elapsed := 0 while (FileExist(gTriggerFile) && elapsed < timeout) { Sleep(50) elapsed += 50 } if (elapsed >= timeout) { ToolTip(label " — timed out after 30s") SetTimer(() => ToolTip(), -3000) return } status := "FAIL" output := "" try status := Trim(FileRead(gStatusFile, "UTF-8"), " `t`r`n") try output := Trim(FileRead(gOutFile, "UTF-8"), " `t`r`n") if (status = "OK") { summary := output if (StrLen(summary) > 80) summary := SubStr(summary, 1, 80) "..." ToolTip(label (summary != "" ? ": " summary : "")) SetTimer(() => ToolTip(), -2500) } else { ToolTip(label " — error (see window)") SetTimer(() => ToolTip(), -3000) errorDisplay := StrReplace(output, "`"", "\`"") Run("pwsh -NoProfile -NoLogo -NoExit -Command `"Write-Host `'" errorDisplay "`' -ForegroundColor Red`"") } } ; Win+Shift+U: Open clipboard as URL in Chrome #+u:: { clip := Trim(A_Clipboard, " `t`r`n") if (clip = "") { ToolTip("Clipboard is empty") SetTimer(() => ToolTip(), -1000) return } ; If it doesn't look like a URL, try prepending https:// url := clip if !RegExMatch(url, "i)^https?://") { ; If it looks like a domain (has a dot, no spaces), add https:// if (RegExMatch(url, "^[^\s]+\.[^\s]+$")) url := "https://" url else { ; Treat as Google search url := "https://www.google.com/search?q=" UriEncode(url) } } Run(url) ToolTip("Opened in browser") SetTimer(() => ToolTip(), -1500) } ; Win+Shift+B: Open clipboard path in Explorer #+b:: { clip := Trim(A_Clipboard, " `t`r`n`"") if (clip = "") { ToolTip("Clipboard is empty") SetTimer(() => ToolTip(), -1000) return } ; If it's a file, select it in Explorer; if it's a directory, open it if DirExist(clip) { Run('explorer.exe "' clip '"') ToolTip("Opened folder") } else if FileExist(clip) { Run('explorer.exe /select,"' clip '"') ToolTip("Revealed file") } else { ; Try as a partial path relative to user profile expanded := gUserProfile "\" clip if DirExist(expanded) { Run('explorer.exe "' expanded '"') ToolTip("Opened folder") } else if FileExist(expanded) { Run('explorer.exe /select,"' expanded '"') ToolTip("Revealed file") } else { ToolTip("Path not found: " clip) } } SetTimer(() => ToolTip(), -2000) } ; Win+Shift+R: Copy rules.txt to clipboard #+r:: { rulesPath := gUserProfile "\pocket\rules.txt" if !FileExist(rulesPath) { ToolTip("rules.txt not found") SetTimer(() => ToolTip(), -2000) return } try { content := FileRead(rulesPath, "UTF-8") A_Clipboard := content lineCount := StrSplit(content, "`n").Length ToolTip("rules.txt copied (" lineCount " lines)") SetTimer(() => ToolTip(), -2000) } catch as err { ToolTip("Failed to read rules.txt: " err.Message) SetTimer(() => ToolTip(), -3000) } } ; Win+Shift+A: Arrange all Windows Terminal windows in an optimal grid #+a:: { Run('powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File "' gUserProfile '\Scripts\tile_terminals.ps1"',, "Hide") ToolTip("Arranging terminals...") SetTimer(() => ToolTip(), -1500) } ; Win+Ctrl+Shift+A: Arrange with priority dialog ^#+a:: { Run('powershell -ExecutionPolicy Bypass -File "' gUserProfile '\Scripts\tile_terminals.ps1" -Tailored') } #+Enter:: { clip := A_Clipboard if (clip = "") { ToolTip("Clipboard is empty") SetTimer(() => ToolTip(), -1000) return } trimmed := Trim(clip, " `t`r`n") lower := StrLower(trimmed) if RegExMatch(lower, "^context\b") { mode := "inspect" label := "context" } else if RegExMatch(lower, "^outline\b") { mode := "inspect" label := "outline" } else if RegExMatch(lower, "^snap\b") { mode := "inspect" label := "snap" } else if RegExMatch(trimmed, "^#-#") { mode := "batch" label := "batch" } else if RegExMatch(trimmed, "m)^!\s") { ; Claude-style "! command" lines — strip "!" prefix from all lines, run as raw pwsh mode := "raw" label := "pwsh" trimmed := RegExReplace(trimmed, "m)^\!\s?", "") } else { mode := "raw" label := "pwsh" } if (mode = "batch") { psScript := "batch" } else { psScript := trimmed } SendToServer(psScript, mode, label) }