Code: Select all
#SingleInstance, Force
; A version of Hotstring Helper that will support block multi-line replacements.
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=114688
; Needs AHK v1.1
; Please get a copy of AutoHotkey.exe and rename it to match the name of this
; script file, so that the .exe and the .ahk have the same name, in the same folder.
; DO NOT COMPILE, or the Append command won't work.
; By Kunkel321, Version 3-22-2023
!#h:: ; Activation key combo (not string) is Alt+Win+h.
AutoTrim On ; Retain any leading and trailing whitespace on the clipboard.
ClipboardOld = %ClipboardAll% ; Save and put back later.
Clipboard = ; Must start off blank for detection to work.
Send ^c ; Copy selected text.
ClipWait 0.3 ; Wait for clipboard to contain text.
Clipboard := Trim(Clipboard) ; Because MS Word keeps leaving spaces.
; If white space present in selected text, probably not an Autocorrect entry.
If (InStr(Clipboard, " ") || InStr(Clipboard, "`n"))
{
;=======Change=options=for=multi=word=entry=options=and=trigger=strings=as=desired==============
myDefaultOpts := "" ; PreEnter these hotstring options; "*" = end char not needed, etc.
myPrefix := ";" ; Optional character that you want suggested at the beginning of each hotstring.
addFirstLetters := 5 ; Add first letter of this many words. (5 recommended; 0 = don't use feature.)
tooSmallLen := 2 ; Only first letters from words longer than this. (Moot if addFirstLetters = 0)
mySuffix := "" ; An empty string "" means don't use feature.
;===========================================================one=more=below=======================
If (addFirstLetters > 0)
{
LBLhotstring := "Edit trigger string as needed"
initials := "" ; Initials will be the first letter of each word as a hotstring suggestion.
HotStrSug := StrReplace(Clipboard, "`n"," ") ; Unwrap, but only for hotstr suggestion.
Loop, Parse, HotStrSug, %A_Space%
{
lenW := Strlen(A_LoopField)
If (lenW > tooSmallLen) ; Check length of each word, ignore if 2 letters.
initials :=initials . SubStr(A_LoopField, "1", "1")
lenHS := StrLen(initials)
If (lenHS = addFirstLetters) ; stop looping if hotstring is 5 chars long.
break
}
StringLower, initials, initials
defaultHotStr := myPrefix . initials . mySuffix ; Append preferred prefix or suffix, as defined above, to initials.
}
else
{
LBLhotstring := "Add a trigger string"
defaultHotStr := myPrefix . mySuffix ; Use prefix and/or suffix as needed, but no initials.
}
}
else
{
LBLhotstring := "Add misspelled word"
defaultHotStr = %Clipboard% ; No spaces found so assume it's a mispelling autocorrect entry: No options, no pre/suffix.
;===============Change=options=autocorrect=words=as=desired======================================
myDefaultOpts := "" ; PreEnter these autocorrect options; "T" = raw text mode, etc.
;================================================================================================
}
WinGetPos, X, Y, W, H, A ; "A" to get the active window's position on screen.
X := X + (W * 0.05) ; Use these with GUI Show, below.
Y := Y + (H * 0.2)
Gui, hh:Destroy ; Prevents duplicates of the GUI form.
Gui, hh:-MinimizeBox +alwaysOnTop ToolWindow
Gui, hh:Font, s11
Gui, hh:Add, Text, y3, Add Hotstring (don't include colons)
Gui, hh:Add, Text, ys+25 xs w30 Section, Options
Gui, hh:Add, Text, x+20 w200, %LBLhotstring%
Gui, hh:Add, Edit, ys+20 xm+10 w30 h24 vOpts Section, %myDefaultOpts%
Gui, hh:Add, Edit, x+28 w215 vHotStr, %defaultHotStr%
Gui, hh:Add, Text, xm Section, Enter Replacement Text
Gui, hh:Font, s8
Gui, hh:Add, Button, ys-2 x+10 h10 -Tabstop vBtsize gTogSize, make bigger
Gui, hh:Add, Button, ys-2 x+2 h10 -Tabstop gBtsymb vTogSymb, show ¶
Gui, hh:Font, s11
Gui, hh:Add, Edit, +Wrap ys+20 xs w295 h100 vRepStr, %Clipboard%
Gui, hh:Add, Button, Section y212 x14 vBtappend, Append
Gui, hh:Add, Button, y212 x+5 vBtvalidate, Validate
Gui, hh:Add, Button, y212 x+5 vBtspell, Spell ; "Spell Check" took too much space.
Gui, hh:Add, Button, y212 x+5 vBtopen, Open
Gui, hh:Add, Button, y212 x+5 vBtcancel, Cancel
Gui, hh:Show, x%X% y%Y% h250 w322, Hotstring Helper - Multi Line ; If GUI title gets chaned, change below #IfWinActive too.
Return
TogSize: ; "make bigger" button activates this.
GuiControlGet, Btsize
If (Btsize = "make bigger") ; This is the default state of the button.
{
GuiControl, move, RepStr, w400 h400 ; Make replacement string box bigger.
GuiControl, move, Btappend, y512 ; Move the buttons down.
GuiControl, move, Btvalidate, y512
GuiControl, move, Btspell, y512
GuiControl, move, Btopen, y512
GuiControl, move, Btcancel, y512
guicontrol,,Btsize, make small ; Change button to say 'make small'
Gui, Show, h551 w428 ; Make the whole GUI form bigger.
}
else ; Button says 'make small' so...
{
GuiControl, move, RepStr, w295 h100 ; Make box small again.
GuiControl, move, Btappend, y212 ; Move buttons back up.
GuiControl, move, Btvalidate, y212
GuiControl, move, Btspell, y212
GuiControl, move, Btopen, y212
GuiControl, move, Btcancel, y212
guicontrol,,Btsize, make bigger ; Change button text back.
Gui, Show, h250 w322 ; Make GUI smaller again.
}
return
Btsymb:
Gui, Submit, NoHide
GuiControlGet, TogSymb
If (TogSymb = "show ¶")
{
RepStr := StrReplace(StrReplace(RepStr,"`r`n","`n"),"`n","¶`n") ; Pilcrow for Enter
RepStr := StrReplace(RepStr, A_Space,"•") ; middle dot for Space
RepStr := StrReplace(RepStr, A_Tab," ? ") ; space arrow space for Tab
GuiControl,, RepStr, %RepStr%
GuiControl, +Readonly, RepStr,
GuiControl,, TogSymb, hide ¶
GuiControl, Disable, Btappend
}
else
{
RepStr := StrReplace(RepStr,"¶`n","`n")
RepStr := StrReplace(RepStr, "•",A_Space)
RepStr := StrReplace(RepStr," ? ",A_Tab)
GuiControl, -Readonly, RepStr,
GuiControl,, RepStr, %RepStr%
GuiControl,, TogSymb, show ¶
GuiControl, Enable, Btappend
}
Return
#IfWinActive, Hotstring Helper - Multi Line ; Allows window-specific behavior.=======
$Enter:: ; When Enter is pressed, but only in this GUI. "$" prevents accidental Enter key loop.
GuiControlGet, hhControl, hh:Focus ; Determine which part of GUI is active.
GuiControlGet, TogSymb ; Get current text of button
; MsgBox hhControl is |%hhControl%|`n`nTogSymb is |%TogSymb%|
if (TogSymb = "show ¶") ; Do nothing if symbol button returns this text.
{
;MsgBox togSymp is 'show' so just return
return
}
Else if (hhControl = "Edit1") || (hhControl = "Edit2") ; Edit1 is Opts box, Edit2 is the Hotstring box
{
Gosub, hhButtonAppend ; Opts box or HotStr box is active, so press Append button.
return
}
else ; Replacement text box must be active, so...
{
send {Enter} ; Just normal typing; Enter yields Enter key press.
Return
}
Esc::
Gui, hh:Destroy
Clipboard = %ClipboardOld% ; Restore previous contents of clipboard.
return
#IfWinActive ; Turn off window-specific behavior.======================
hhButtonValidate: ; If either of these buttons are pressed.
hhButtonAppend:
Gui, hh:Submit, NoHide
FileRead, ThisFile, %A_ScriptName% ; Save these contents to variable 'ThisFile'.
If (Opts = "") ; If options box is empty, skip rexex check.
validOpts = Okay.
else
{
; Make sure hotstring options are valid.
NeedleRegEx := "(\*|B0|\?|SI|C|K[0-9]{1,3}|SE|X|SP|O|R|T)" ; These are in the AHK docs!!!
WithNeedlesRemoved := RegExReplace(Opts, NeedleRegEx, "") ; Remove all valid options from var.
If(WithNeedlesRemoved = "") ; If they were all removed...
validOpts = Okay.
else ; Some characters from the Options box were not recognized.
{
OptTips = ; Just a block text assignement to var.
(
Don't include the colons.
..from AHK v1 docs...
* ending char not needed
? trigger inside other words
B0 no backspacing
SI send input mode
C case-sensitive
K(n) set key delay
SE send event mode
X execute command
SP send play mode
O omit end char
R send raw
T super raw
)
validOpts = Invalid Hotsring Options found.`n---> %WithNeedlesRemoved%`n`n`tTips:`n%OptTips%
}
}
; Make sure hotstring box is not empty.
validHot := "" ; Reset to empty each time.
If (HotStr = "") || (HotStr = myPrefix) || (HotStr = mySuffix) || inStr(HotStr, ":") ; || means 'or'
validHot = Hotstring box should not be empty.`n-Don't include colons.
else ; No colons, and not empty. Good. Now check for duplicates.
{
Loop, parse, ThisFile, `n, `r ; Check line-by-line.
{
If instr(A_LoopField, ":" . HotStr . "::") ; If line contains HotStr...
{
validHot = DUPLICATE FOUND`nAt Line %A_Index%:`n %A_LoopField%
break
}
}
If (validHot = "") ; If variable didn't get set in loop, then no duplicates found
validHot = Okay.
}
; Make sure replacement string box is not empty.
If (RepStr = "") || (SubStr(RepStr, "1", "1")==":") ; If Replacement box empty, or first char is ":"
validRep = Replacement string box should not be empty.`n-Don't include the colons.
else
validRep = Okay.
; Concatenate the three above validity checks.
CombinedValidMsg = OPTIONS BOX `n-%validOpts%`n`nHOTSTRING BOX `n-%validHot%`n`nREPLACEMENT BOX `n-%validRep%
; Both buttons lead here, so which was pressed?
if (A_ThisLabel = "hhButtonValidate")
{
MsgBox , 4096, VALIDATION, %CombinedValidMsg%
return
}
if (A_ThisLabel = "hhButtonAppend")
{
Clipboard = %ClipboardOld% ; Restore previous contents of clipboard.
; Check for mult-line replacment and wrap in parenths if needed.
If inStr(RepStr,"`n")
WholeStr := ":" . Opts . ":" . HotStr . "::`n(`n" . RepStr . "`n)"
Else
WholeStr := ":" . Opts . ":" . HotStr . "::" . RepStr
;~ MsgBox , 4096, PREVIEW, %WholeStr%
If (validOpts = "Okay.") && (validHot = "Okay.") && (validRep = "Okay.") ; if all valid
{
Gui, hh:Submit, Hide
FileAppend, `n%WholeStr%, %A_ScriptFullPath% ; 'n makes sure it goes on a new line.
Reload
Return
}
else ; The three validity checks weren't all okay, so...
{
MsgBox , 4100, VALIDATION, %CombinedValidMsg%`n`n####################`nContinue Anyway?
IfMsgBox Yes
{
Gui, hh:Submit, Hide
FileAppend, `n%WholeStr%, %A_ScriptFullPath% ; 'n makes sure it goes on a new line.
Reload
Return
}
else
return
}
}
hhButtonSpell: ; Spell button goes here.
Gui, hh:Submit, NoHide
If (RepStr = "")
MsgBox Replacement Text not found.
else
{
googleSugg := GoogleAutoCorrect(RepStr) ; Calls below function
If (RepStr = googleSugg)
MsgBox No suggestions found.
Else
{
MsgBox 4100, Google Suggestion, %googleSugg%`n`n######################`nChange Replacement Text?
IfMsgBox Yes
GuiControl, Text, Edit3, %googleSugg%
else
return
}
}
return
GoogleAutoCorrect(Word) ; Uses Google's "Did you mean..." feature.
{ ; function by TheDewd ;https://www.autohotkey.com/boards/viewtopic.php?f=6&t=83164
ReqURL := "https://www.google.com/search?q=" Word
objReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
objReq.Open("GET", ReqURL)
objReq.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)")
objReq.Send()
HTML := objReq.ResponseText
; MsgBox HTML is |%HTML%| ; It returns with a whole page of html code.
; These regexes filter though the html to get the google suggestion.
RegExMatch(HTML, "value=""(.*?)""", A)
; MsgBox A1 is %A1%
RegExMatch(HTML, ";spell=1.*?>(.*?)<\/a>", B)
; MsgBox B1 is %B1%
return (B1 ? B1 : A1)
}
; The other buttons.
hhButtonOpen: ; Open this file and go to the bottom so you can see your Hotstrings.
Gui, hh:Destroy
Clipboard = %ClipboardOld% ; Restore previous contents of clipboard.
Edit
WinWaitActive, %A_ScriptName% ; Wait for the script to be open in text editor.
sleep, 250
Send, {Ctrl Down}{End}{Ctrl Up}{Home} ; Navigate to the bottom.
return
hhButtonCancel:
Gui, hh:Destroy
Clipboard = %ClipboardOld% ; Restore previous contents of clipboard.
Exit
return
;==========================
; HotStrings appended (added)
; by the script will be down there.
; Newest ones at the bottom.
;=========================
::;ottff::
(
one
two
three
four
five
)
::;tatat::This and that and the other.
::spesial::special