From ebb543ca396a5a761fcbaf2f694b86959945b7ad Mon Sep 17 00:00:00 2001 From: Gewerd-Strauss <80548781+Gewerd-Strauss@users.noreply.github.com> Date: Tue, 6 Jul 2021 12:47:47 +0200 Subject: [PATCH 1/5] Split tooltip as it runs off screen for me Since I have so many commands nowadays, my list keeps running beyond the visible edge of the screen. This patch will split the "command"-tooltip at the midway point and display both parts separately to both sides of the active gui --- GUI/GUI.ahk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GUI/GUI.ahk b/GUI/GUI.ahk index fb04a22..b5bc430 100644 --- a/GUI/GUI.ahk +++ b/GUI/GUI.ahk @@ -208,5 +208,7 @@ gui_commandlibrary: tooltiptextpadded .= "`n" } Sort, tooltiptextpadded - ToolTip %tooltiptextpadded%, 3, 3, 1 + tooltip,% Substr(tooltiptextpadded,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))),A_ScreenWidth,3,3 + ToolTip % Substr(tooltiptextpadded,1,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))), 3, 3, 1 + ; for reasons I don't quite understand myself, if you swap around the two tooltips, the left one disappears shortly after the command is issued for the first time. return From aeec96335abf2827d733df22ee98d2cb508a0e19 Mon Sep 17 00:00:00 2001 From: Gewerd-Strauss <80548781+Gewerd-Strauss@users.noreply.github.com> Date: Tue, 6 Jul 2021 12:51:14 +0200 Subject: [PATCH 2/5] Update GUI.ahk --- GUI/GUI.ahk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GUI/GUI.ahk b/GUI/GUI.ahk index b5bc430..5132cef 100644 --- a/GUI/GUI.ahk +++ b/GUI/GUI.ahk @@ -208,6 +208,8 @@ gui_commandlibrary: tooltiptextpadded .= "`n" } Sort, tooltiptextpadded + ;ToolTip %tooltiptextpadded%, 3, 3, 1 ; reactivate this line and deactivate the two tooltips below if you don't want/have to split your commands. + ; This is done because I have so many nowadays that they don't fit on the screen anymore if sorted into one gui. tooltip,% Substr(tooltiptextpadded,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))),A_ScreenWidth,3,3 ToolTip % Substr(tooltiptextpadded,1,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))), 3, 3, 1 ; for reasons I don't quite understand myself, if you swap around the two tooltips, the left one disappears shortly after the command is issued for the first time. From 5cfc17cc8dc42ad5bf7838847798f8dbb0905bab Mon Sep 17 00:00:00 2001 From: Gewerd-Strauss <80548781+Gewerd-Strauss@users.noreply.github.com> Date: Tue, 6 Jul 2021 13:22:14 +0200 Subject: [PATCH 3/5] added personal adaptions * enter a function for pasting variable contents * force focus back to gui edit field if gui is open * moved gui to the top of the screen, instead of the center * add Ctrl+Backspace full-word deletion --- GUI/GUI.ahk | 420 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 348 insertions(+), 72 deletions(-) diff --git a/GUI/GUI.ahk b/GUI/GUI.ahk index 5132cef..250ea92 100644 --- a/GUI/GUI.ahk +++ b/GUI/GUI.ahk @@ -1,5 +1,5 @@ -; Created by Asger Juul Brunshøj - +; Created by Asger Juul Brunshj +#SingleInstance,Force ; Note: Save with encoding UTF-8 with BOM if possible. ; I had issues with special characters like in ¯\_(ツ)_/¯ that wouldn't work otherwise. ; Notepad will save UTF-8 files with BOM automatically (even though it does not say so). @@ -31,69 +31,111 @@ gui_autoexecute: ; Initialize search_urls as a variable set to zero search_urls := 0 + + ; Set Gui-Margins for subsequent guis in this + vMarginX:=6 + vMarginY:=6 return ;------------------------------------------------------------------------------- -; LAUNCH GUI +; LAUNCH GUI ;------------------------------------------------------------------------------- -CapsLock & Space:: +CapsLock & Space:: ;; Open Gui gui_spawn: +WinGetActiveTitle,sPreviousActiveWindow +tooltip, % sPreviousActiveWindow if gui_state != closed - { + { ; If the GUI is already open, close it. - gui_destroy() - return - } + gui_destroy() + if WinExist(sPreviousActiveWindow) + { + WinActivate, sPreviousActiveWindow + } + return + } - gui_state = main +gui_state = main - Gui, Margin, 16, 16 - Gui, Color, 1d1f21, 282a2e - Gui, +AlwaysOnTop -SysMenu +ToolWindow -caption +Border - Gui, Font, s11, Segoe UI - Gui, Add, Text, %gui_control_options% vgui_main_title, ¯\_(ツ)_/¯ - Gui, Font, s10, Segoe UI - Gui, Add, Edit, %gui_control_options% vPedersen gFindus - Gui, Show,, myGUI - return +Gui, Margin, 6, 6 +Gui, Color, 1d1f21, 282a2e +Gui, +AlwaysOnTop -SysMenu +ToolWindow -caption +Border +Gui, Font, s8, Segoe UI +Gui, Add, Text, %gui_control_options% vgui_main_title, ¯\_(ツ)_/¯ +;Gui, Add, Text, , ¯\_(ツ)_/¯ +Gui, Font, s10, Segoe UI +Gui, Add, Edit, %gui_control_options% vPedersen gFindus +Hotkey, ^Backspace, DeleteWord_Host,On +Gui, Show ,y0, Host +SetTimer, ForceOnTop_Host,250 +return ;------------------------------------------------------------------------------- ; GUI FUNCTIONS AND SUBROUTINES ;------------------------------------------------------------------------------- -; Automatically triggered on Escape key: +; Automatically triggered on Escape key: GuiEscape: - gui_destroy() - return +gui_destroy() +Hotkey, ^Backspace, DeleteWord_Host,Off +gui, destroy +SetCapsLockState,Off +search_url:=[] +REPLACEME:="" +tooltip, +tooltip,,,,2 +;click +if WinExist(sPreviousActiveWindow) + WinActivate, sPreviousActiveWindow +return ; The callback function when the text changes in the input field. Findus: - Gui, Submit, NoHide - #Include %A_ScriptDir%\GUI\UserCommands.ahk - return +Gui, Submit, NoHide +#Include %A_ScriptDir%\GUI\UserCommands.ahk +return + +ForceOnTop_Host: +;if WinExist("Host") + ;WinActivate +;else + ;SetTimer, ForceOnTop_Host, Off +return +DeleteWord_Host: +SendInput, ^+{Left}{BS} +return ; ; gui_destroy: Destroy the GUI after use. ; #WinActivateForce gui_destroy() { - global gui_state - global gui_search_title - - gui_state = closed + global gui_state + global gui_search_title + Hotkey, ^Backspace, DeleteWord_Host,Off + Pedersen= + gui_state = closed ; Forget search title variable so the next search does not re-use it ; in case the next search does not set its own: - gui_search_title = - + gui_search_title = + ; Clear the tooltip - Gosub, gui_tooltip_clear - + Gosub, gui_tooltip_clear + ; Hide GUI - Gui, Destroy - + Gui, Destroy + + ; reset CapsLock state + SetCapsLockState,Off ; Bring focus back to another window found on the desktop - WinActivate + WinActivate + tooltip,,,,1 + tooltip,,,,2 + tooltip,,,,3 + tooltip,,,,4 + } +; gui_change_title: Sets the title of the GUI box. gui_change_title(message,color = "") { ; If parameter color is omitted, the message is assumed to be an error ; message, and given the color red. @@ -115,40 +157,69 @@ gui_change_title(message,color = "") { ; gui_search_add_elements: Add GUI controls to allow typing of a search query. ; gui_search_add_elements: - Gui, Add, Text, %gui_control_options% %cYellow%, %gui_search_title% - Gui, Add, Edit, %gui_control_options% %cYellow% vgui_SearchEdit -WantReturn - Gui, Add, Button, x-10 y-10 w1 h1 +default ggui_SearchEnter ; hidden button - GuiControl, Disable, Pedersen - Gui, Show, AutoSize - return +gui_search_add_elements_default: +Gui, Add, Text, %gui_control_options% %cYellow%, %gui_search_title% +Gui, Add, Edit, %gui_control_options% %cYellow% vgui_SearchEdit -WantReturn +Gui, Add, Button, x-10 y-10 w1 h1 +default ggui_SearchEnter ; hidden button +GuiControl, Disable, Pedersen +Gui, Show, AutoSize, +return -gui_search(url) { - global - if gui_state != search - { - gui_state = search - ; if gui_state is "main", then we are coming from the main window and - ; GUI elements for the search field have not yet been added. - Gosub, gui_search_add_elements - } - ; Assign the url to a variable. - ; The variables will have names search_url1, search_url2, ... +gui_search(url:=0,filequery:="0",file:="REPLACEME") { ;; I think the function just merges and indexes all urls in UserCommands.ahk ? + global + backup_default:=false + if gui_state != search + { + gui_state = search + Gosub, gui_search_add_elements + } + search_urls := search_urls + 1 + search_url%search_urls% := url ;; what does this do? +} - search_urls := search_urls + 1 - search_url%search_urls% := url +gui_search_default(url,Defaulturl) { ;; I thi nk the function just merges and indexes all urls in UserCommands.ahk ? + global + backup_default:=true + DefaultURL_g:=Defaulturl + if gui_state != search + { + gui_state = search + Gosub, gui_search_add_elements + } + search_urls := search_urls + 1 + search_url%search_urls% := url ;; what does this do? } -gui_SearchEnter: - Gui, Submit - gui_destroy() - query_safe := uriEncode(gui_SearchEdit) - Loop, %search_urls% - { - StringReplace, search_final_url, search_url%A_Index%, REPLACEME, %query_safe% - run %search_final_url% - } - search_urls := 0 + +gui_SearchEnter: ;; Function assembles the search string to execute. Since only the search term is replaced, it can just be "run" as a normal command. +Gui, Submit +gui_destroy() +Hotkey, ^Backspace, DeleteWord_Host,Off +tooltip +loop, %search_urls% +{ + ;MsgBox, %search_url%%A_Index% +} +query_safe := uriEncode(gui_SearchEdit) +Loop, %search_urls% +{ + StringReplace, search_final_url, search_url%A_Index%, REPLACEME, %query_safe% + ;MsgBox, % search_final_url + if !query_safe ; nothing has been specified as search query, the string is empty + { + if backup_default + run, %DefaultURL_g%,,,RunPID + else + run, %search_final_url%,,,RunPID + } + else + run %search_final_url%,,,RunPID +} + search_urls := 0 ;; reset search_urls + sleep, 200 + click + WinActivate, ahk_pid, %RunPID% return ;------------------------------------------------------------------------------- @@ -206,11 +277,216 @@ gui_commandlibrary: } tooltiptextpadded .= line tooltiptextpadded .= "`n" - } - Sort, tooltiptextpadded - ;ToolTip %tooltiptextpadded%, 3, 3, 1 ; reactivate this line and deactivate the two tooltips below if you don't want/have to split your commands. - ; This is done because I have so many nowadays that they don't fit on the screen anymore if sorted into one gui. - tooltip,% Substr(tooltiptextpadded,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))),A_ScreenWidth,3,3 - ToolTip % Substr(tooltiptextpadded,1,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))), 3, 3, 1 - ; for reasons I don't quite understand myself, if you swap around the two tooltips, the left one disappears shortly after the command is issued for the first time. - return +} +Sort, tooltiptextpadded +tooltip,% Substr(tooltiptextpadded,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))),A_ScreenWidth,3,3 +ToolTip % Substr(tooltiptextpadded,1,Instr(tooltiptextpadded,"`n",,,Ceil((StrSplit(tooltiptextpadded,"`n").length())/2))), 3, 3, 1 +return + + + ;Clip() - Send and Retrieve Text Using the Clipboard + ;by berban - updated February 18, 2019 + ;https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62156 + + ;modified by Gewerd Strauss + +fClip(Text="", Reselect="",Restore:=1,DefaultMethod:=1) +{ + ;m(DefaultMethod) + if !DefaultMethod + { + BlockInput,On + if InStr(Text,"&|") ;; check if needle contains cursor-pos. The needle must be &|, without brackets + { + move := StrLen(Text) - RegExMatch(Text, "[&|]") + Text := RegExReplace(Text, "[&|]") + sleep, 20 + MoveCursor:=true + } + Else + { + MoveCursor:=false + move:=1 ;; offset the left-moves for the edgecase that this is not guarded by movecursor + } + Static BackUpClip, Stored, LastClip + If (A_ThisLabel = A_ThisFunc) + { + If (Clipboard == LastClip) + Clipboard := BackUpClip + BackUpClip := LastClip := Stored := "" + } + Else + { + If !Stored + { + Stored := True + BackUpClip := ClipboardAll ; ClipboardAll must be on its own line + } + Else + SetTimer, %A_ThisFunc%, Off + LongCopy := A_TickCount, Clipboard := "", LongCopy -= A_TickCount ; LongCopy gauges the amount of time it takes to empty the clipboard which can predict how long the subsequent clipwait will need + If (Text = "") ; No text is pasted, hence we pull it. + { + SendInput, ^c + ClipWait, LongCopy ? 0.6 : 0.2, True + } + Else + { + Clipboard := LastClip := Text + ClipWait, 10 + SendInput, ^v + ;MsgBox, mc:%MoveCursor% + if MoveCursor + { + if WinActive("E-Mail – ") and Winactive("— Mozilla Firefox") + { + WinActivate + sleep, 20 + BlockInput,On + WinActivate, "E-Mail – " + if !ReSelect and (ReSelect = False) + SendInput, % "{Left " move-1 "}" + else if (Reselect="") + SendInput, % "{Left " move-1 "}" + } + else + if !ReSelect and (ReSelect = False) + SendInput, % "{Left " move-2 "}" + else if (Reselect="") + { + SendInput, % "{Left " move-2 "}" + } + } + } + SetTimer, %A_ThisFunc%, -700 + Sleep 200 ; Short sleep in case Clip() is followed by more keystrokes such as {Enter} + If (Text = "") ; we are pulling, not pasting + { + SetTimer, %A_ThisFunc%, Off + { + f_unstickKeys() + if !Restore + { + BlockInput, Off + return LastClip := Clipboard + } + LastClip := Clipboard + ClipWait, LongCopy ? 0.6 : 0.2, True + BlockInput,Off + Return LastClip + } + } + Else If ReSelect and ((ReSelect = True) or (StrLen(Text) < 3000)) + { + SetTimer, %A_ThisFunc%, Off + SendInput, % "{Shift Down}{Left " StrLen(StrReplace(Text, "`r")) "}{Shift Up}" + } + } + f_unstickKeys() + BlockInput, Off + Return + + } + else + { + if InStr(Text,"&|") ;; check if needle contains cursor-pos. The needle must be &|, without brackets + { + move := StrLen(Text) - RegExMatch(Text, "[&|]") + Text := RegExReplace(Text, "[&|]") + sleep, 20 + MoveCursor:=true + } + Else + { + MoveCursor:=false + move:=1 ;; offset the left-moves for the edgecase that this is not guarded by movecursor + } + If (A_ThisLabel = A_ThisFunc) { + If (Clipboard == LastClip) + Clipboard := BackUpClip + BackUpClip := LastClip := Stored := "" + } Else { + If !Stored { + Stored := True + BackUpClip := ClipboardAll ; ClipboardAll must be on its own line + } Else + SetTimer, %A_ThisFunc%, Off + LongCopy := A_TickCount, Clipboard := "", LongCopy -= A_TickCount ; LongCopy gauges the amount of time it takes to empty the clipboard which can predict how long the subsequent clipwait will need + If (Text = "") { + SendInput, ^c + ClipWait, LongCopy ? 0.6 : 0.2, True + } Else { + Clipboard := LastClip := Text + ClipWait, 10 + SendInput, ^v + } + SetTimer, %A_ThisFunc%, -700 + Sleep 20 ; Short sleep in case Clip() is followed by more keystrokes such as {Enter} + If (Text = "") + Return LastClip := Clipboard + Else If ReSelect and ((ReSelect = True) or (StrLen(Text) < 3000)) + SendInput, % "{Shift Down}{Left " StrLen(StrReplace(Text, "`r")) "}{Shift Up}" + if Move and !ReSelect{ + SendInput, % "{Left " move-2 "}" + } + } + Return + + } + fClip: + f_unstickKeys() + BlockInput,Off + Return fClip() +} + + +f_unstickKeys() +{ + BlockInput, On + SendInput, {Ctrl Up} + SendInput, {V Up} + SendInput, {Shift Up} + SendInput, {Alt Up} + BlockInput, Off +} + + +/* original by berban https://github.com/berban/Clip/blob/master/Clip.ahk + ; Clip() - Send and Retrieve Text Using the Clipboard +; by berban - updated February 18, 2019 +; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=62156 + Clip(Text="", Reselect="") + { + Static BackUpClip, Stored, LastClip + If (A_ThisLabel = A_ThisFunc) { + If (Clipboard == LastClip) + Clipboard := BackUpClip + BackUpClip := LastClip := Stored := "" + } Else { + If !Stored { + Stored := True + BackUpClip := ClipboardAll ; ClipboardAll must be on its own line + } Else + SetTimer, %A_ThisFunc%, Off + LongCopy := A_TickCount, Clipboard := "", LongCopy -= A_TickCount ; LongCopy gauges the amount of time it takes to empty the clipboard which can predict how long the subsequent clipwait will need + If (Text = "") { + SendInput, ^c + ClipWait, LongCopy ? 0.6 : 0.2, True + } Else { + Clipboard := LastClip := Text + ClipWait, 10 + SendInput, ^v + } + SetTimer, %A_ThisFunc%, -700 + Sleep 20 ; Short sleep in case Clip() is followed by more keystrokes such as {Enter} + If (Text = "") + Return LastClip := Clipboard + Else If ReSelect and ((ReSelect = True) or (StrLen(Text) < 3000)) + SendInput, % "{Shift Down}{Left " StrLen(StrReplace(Text, "`r")) "}{Shift Up}" + } + Return + Clip: + Return Clip() + } +*/ + From f074d11dd23349064564186654162076e0bfc13a Mon Sep 17 00:00:00 2001 From: Gewerd-Strauss <80548781+Gewerd-Strauss@users.noreply.github.com> Date: Tue, 6 Jul 2021 13:30:20 +0200 Subject: [PATCH 4/5] Update GUI.ahk removed overlooked test code --- GUI/GUI.ahk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/GUI/GUI.ahk b/GUI/GUI.ahk index 250ea92..76187a2 100644 --- a/GUI/GUI.ahk +++ b/GUI/GUI.ahk @@ -96,10 +96,10 @@ return ForceOnTop_Host: -;if WinExist("Host") - ;WinActivate -;else - ;SetTimer, ForceOnTop_Host, Off +if WinExist("Host") + WinActivate +else + SetTimer, ForceOnTop_Host, Off return DeleteWord_Host: SendInput, ^+{Left}{BS} From 2a4d9320b987bf450f6993ca3029859f96fd74db Mon Sep 17 00:00:00 2001 From: Gewerd-Strauss <80548781+Gewerd-Strauss@users.noreply.github.com> Date: Tue, 6 Jul 2021 13:38:26 +0200 Subject: [PATCH 5/5] Update README.md Added documentation on extended, branch-specific functionality. --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index e64b59b..caa8798 100644 --- a/README.md +++ b/README.md @@ -110,3 +110,15 @@ The url is now passed as a parameter instead: gui_search("https://www.youtube.com/results?search_query=REPLACEME") Additionally, the tooltip was revived for Windows 10 and improved with the help of Github user schmimae. + + +--- END of original documentation +In this branch by Gewerd Strauss, the following changes have been made: + +1. The gui is located at the very top of the screen, central, instead of the middle of the screen. +2. Ctrl+Backspace will delete full words within the gui +3. The tooltip created when typing "?" in the gui is split into two halves to be displayed separately, as my personal version of this wonderful script is running out of screen height for displaying command tooltips. Can be easily changed by deactivating the two responsible lines and reactivating the original line above. + + + +Thank you to the original creator, plul, for creating this amazing utility script. I use it in way too many situations to count.