Adding Action to AutoHotKey HotStrings, Plus a Trick for Creating IF Conditional Hotstring Text Replacements (Part 3, Beginning Hotstrings)

How to Add Action to AutoHotKey Hotstrings; Solving an AutoCorrect Problem with IF-ELSE Conditions

*          *          *

New to AutoHotkey? See “Introduction to AutoHotkey: A Review and Guide for Beginners.”

*          *          *

Beginning AutoHotkey Hotstrings 200pxAs a convenience for people who want to get this entire series (plus more) in one place, I have now published the e-book Beginning AutoHotkey Hotstrings which is available on the ComputorEdge E-Books site (in three formats—EPUB for mobile devices, MOBI for Kindle, and PDF for printing and computer) and through Amazon. Regardless of whether you’re interested in the book or not, it’s worth your time to peruse some of the blogs linked at “Beginning AutoHotkey Hotstring Techniques” found under the “AutoHotkey Topics and Series” tab in the top menu bar. They just might inspire your next AutoHotkey script.

*          *          *

As I mentioned in the update from last time (see “Using the C Option for the Word AutoHotkey”), my solution for the Hotstring (.ahk) which should not expand to the word .AutoHotKey didn’t quite work out as planned. The problem was that the dot (.) which preceded the ahk reset the Hotstring leaving the active string as only the ::ahk::AutoHotKey line of code. Every time I wanted to type MyScriptFile.ahk I would get MyScriptFile.AutoHotKey. In most cases, the approach of placing the higher priority Hotstring line of code first in the script would likely work out. After all, typing .ahk on its own (space before the dot) did nothing and took priority over the ahk (no dot) text expansion to the word AutoHotKey which appeared second in the script.

In retrospect, I should have picked a different Hotstring for the word AutoHotKey and saved myself the hassle. But, then again, I never would have come up with the following fix. There may be other times when under special conditions you need to ensure that a Hotstring does not fire. This approach might give you some insight into a way to do it.

Note: I first developed this Hotstring technique to deal with special cases where the letter combination ht should not be automatically AutoCorrected to th at the beginning of certain words (e.g. http and HTML)—as discussed in a previous blog. These routines check the two letters (the swapped th) preceding the Hotstring before making the substitution. These snippets are scheduled for discussion in a future blog. (To fully understand the nature of this problem, you may need to review the previous two blogs on Hotstrings.)

Hotstrings Running AutoHotKey Routines

In the previous blogs, we have concentrated on modifying direct replacement Hotstrings with the available options which are placed between the first two colons. Now, we get a little more advanced by adding snippets of code to run when the Hotstring is activated.

To run an AutoHotKey routine with a Hotstring, the lines of code must appear on the first line after the initial Hotstring definition:

::dmml::
  MsgBox, Don't make me laugh!
Return
Pop-up Message Box
Hotstring pops up a message box.

When loaded, this Hotstring displays the message “Don’t make me laugh!” (as shown at right) whenever the activating string dmml is typed. In the same manner as other Hotstrings, the original dmml is automatically deleted. (To prevent this automatic backspacing, use the B0 option.)

The Return command is not always required at the end of the snippet, but it is usually a good idea. As is the case with the auto-execute section of the script, the lines of code in the Hotstring will continue to execute until a Return command, a HotKey definition, or another Hotstring definition is encountered. Without the Return command at the end, any Label subroutine immediately following will start running. As a rule, use Return at the end of all of your snippets unless you have a specific reason to leave it open.

The power of the action Hotstring is in its ability to change with conditions. As a practical example of an action Hotstring, you may want to add the following date inserter into one of your regular scripts.

:C*:Anow:: 
  FormatTime, CurrentDateTime,, MMMM d, yyyy 
  SendInput %CurrentDateTime%
Return

Whenever the activating keys Anow (capital A required) are typed, the current date is instantly inserted into any Windows word processing program or text editing field in a Web page (e.g. October 5, 2015). The code between the first Hotstring line and the Return is executed in the same way as any other AutoHotKey subroutine. As with a regular Hotstring, the activating text is deleted through automatic backspacing.

Tip: When an activating Hotstring might appear in another word (e.g. anow in nanowatt) it is a good idea to include a capital letter in the string (Anow) and the C option in the Hotstring. That way accidental activation at the wrong time is unlikely.

In this case, the FormatTime command sets the format for the current date. The current time and date is the default value used by the FormatTime command. Then, the  SendInput command is used to replace Anow in the text. The Send or SendInput command is an alternative method for replacing text when using the subroutine form of a Hotstring. (SendInput is generally preferred over the Send command since it buffers keyboard and mouse activity while working. This reduces the risk of errors caused by continued typing during Hotstring action.)

A Technique for Creating Conditional IF-ELSE Hotstrings

Beginner's Guide to AutoHotkeyThe object in this blog is to build an action Hotstring which differentiates between typing ahk and .ahk (a dot plus ahk). The problem with the previous solution was the dot caused the Hotstring to reset forcing filenames such as AHKScripFile.ahk to expand to AHKScripFile.AutoHotKey. In order for the HotString to prevent this, it needs to check the character before the ahk to determine whether or not it is a dot. The following solution uses a number of techniques which appear in my AutoHotKey e-books starting with A Beginner’s Guide to AutoHotKey.

This Hotstring snippet gets relatively long for a beginning routine, but there are numerous AutoHotKey learning points worth investigating. I’ll take it one step at a time explaining the function and importance of each line as the routine is built.

Selecting Text for Clipboard Manipulation

Selected Text
Text with the blue background is selected text for copying or deleting.

When using any computer system, a common method for copying and moving text (or objects) is selecting it by first clicking the left mouse button on one side of the text and dragging the mouse to the other end before releasing the button. The text is then highlighted, as shown at the right. Once highlighted, the text can be copied to the Windows clipboard for later pasting (inserting) into the same or other documents.

Using the Windows clipboard to move and/or manipulate text is a technique commonly employed in AutoHotKey scripts. In fact the built-in variable name for the Windows clipboard contents is simply Clipboard. However, just as when using a mouse and keyboard, the text or object must first be selected (highlighted) on screen. Then those same keyboard hotkeys, copy (CTRL+C), delete (CTRL+X), and paste (CTRL+V) are executed with AutoHotKey commands.

The first step in our problem is selecting the target text which must include ahk plus any preceding character, as shown by the image above. This is done with the following SendInput command:

:B0C:ahk::
  SendInput {Backspace}{Shift down}{Left 4}{Shift up} 
Return

Notice that the no backspace B0 option is used along with the C option. Since we don’t yet know if we want to delete the string, the no backspace option prevents the automatic deletion of the activating string. The C option forces the Hotstring to only respond to ahk (all lowercase letters), thus causing it to ignore AHK in all caps.

The SendInput command simulates keyboard action. In this case, as with normal Windows operation, text is selected by using the SHIFT key and the cursor arrows. But before selecting text, the last activating character (space or punctuation) needs to be removed. SendInput {Backspace} deletes the last character typed. (Don’t worry. We’ll add that character back once we make any necessary changes.)

{Shift down} tells Windows to press and hold the SHIFT key down. {Left 4}  forces the cursor to move four characters to the left. (This is the same keyboard action you would use when selecting (highlighting) characters on your Windows computer screen.) {Shift up} completes the selection—leaving the selected text highlighted. Now we are ready to copy the selected text to the Windows clipboard:

:B0C:ahk::
 SendInput {Backspace}{Shift down}{Left 4}{Shift up}
 SendInput ^c
Return

The keyboard combination for copying selected text to the Windows clipboard is CTRL+C. In AutoHotKey that combination is activated with SendInput ^c. The caret ^ represents the Control key (CTRL) in AutoHotKey.

The primary issue which arises when AutoHotKey is used to copy to the clipboard is the possibility of a slight delay before the clipboard actually receives the data. While it only takes microseconds, sometimes the script will move on to the next step too soon. To prevent this the ClipWait command is added. ClipWait pauses the script until the Windows clipboard contains data. However, before the ClipWait command will work, the Windows clipboard must be empty. The AutoHotKey variable Clipboard is used to empty the Windows Clipboard by setting it equal to nothing:

:B0C:ahk::
 SendInput {Backspace}{Shift down}{Left 4}{Shift up}
 Clipboard :=       ;the Windows Clipboard is set to nothing
 SendInput ^c
 ClipWait 0         ;script pauses until the Clipboard filled
Return

Adding the 0 to the ClipWait command forces it to timeout after 500 microseconds.

The problem with clearing the Windows clipboard is that it may contain something you’ll need later. You don’t always want the clipboard cleared every time you execute a special HotKey or Hotstring feature which uses the Clipboard variable. As a standard part of most of your clipboard routines you should save the original content of the Windows clipboard in the beginning of the routine, then restore it to the clipboard at the end:

:B0C:ahk::
 OldClip := Clipboard   ;capture original clipboard contents
 Clipboard := 
 SendInput {Backspace}{Shift down}{Left 4}{Shift up} 
 SendInput ^c
 ClipWait 0
;
; conditional code inserted here
;
 Clipboard := OldClip   ;restore old clipboard contents
Return

The content of the Windows clipboard is saved in the new variable OldClip (OldClip := Clipboard) before emptying the clipboard (Clipboard := ). Then, at the end of the routine, the old content is restored to the clipboard (Clipboard := OldClip).

Now it’s time to add the conditional code which checks for a dot (.) at the beginning of the string stored in the clipboard. Remember that the last four characters were selected before copying them in order to capture any character preceding the ahk string. When that first character is a dot, the Hotstring should remain untouched. The IF command sets up the conditional:

:B0C:ahk::
 OldClip := Clipboard
 Clipboard :=
 SendInput {Backspace}{Shift down}{Left 4}{Shift up}
 SendInput ^c
 ClipWait 0
 If (Clipboard = ".ahk")   ;If clipboard contains ".ahk"
     SendInput {Shift down}{Right 4}{Shift up}  ;deselect text
 Clipboard := OldClip
Return

The first condition checked is when the first character is a dot (.ahk). In this case, the Hotstring only needs deselecting which is the reverse of the selection process used in the beginning of the routine (SendInput {Shift down}{Right 4}{Shift up}). Through AutoHotKey, the SHIFT key is pressed and held, the right cursor arrow is pressed four times, then the SHIFT key is released. This effectively returns the text to its original state—except for the ending keystroke. The activation space or punctuation is missing.

Note: When there is only one command line following an IF, ELSE, or ELSE IF statement, the enclosing curly brackets {} are not needed. However, if more than one command line follows, the curly brackets are mandatory. In this example there is only one command line following each IF, ELSE, or ELSE IF statement.

The activating character in a Hotstring is saved in the built-in variable A_EndChar. By adding that character, all returns to as it was before the Hotstring activation:

:B0C:ahk::
 OldClip := Clipboard
 Clipboard := 
 SendInput {Backspace}{Shift down}{Left 4}{Shift up}  SendInput ^c
 ClipWait 0
 If (Clipboard = ".ahk")
   SendInput {Shift down}{Right 4}{Shift up}
 SendInput %A_EndChar%   ;adds back activating character
 Clipboard := OldClip
Return

The activating character is added back with the SendInput command by placing the variable A_EndChar inside percent signs (%A_EndChar%) for evaluation. (There are other practical uses for the Hotstring variable A_EndChar in AutoCorrect scripts which will be addressed in future blogs.)

The current routine deals with the situation where we want nothing to change, but to insert the word AutoHotKey when there is no preceding dot an Else statement is needed. Since the dot will not be removed in any case, before replacing the three letters ahk, the cursor must first be move one character to the right. This deselects the first character and saves the it from the text replacement action. Then the remaining ahk is expanded to AutoHotKey:

:B0C:ahk::
 SendInput {Backspace}{Shift down}{Left 4}{Shift up}
 OldClip := Clipboard
 Clipboard := 
 SendInput ^c
 ClipWait 0
 If (Clipboard = ".ahk")
   SendInput {Shift down}{Right 4}{Shift up}
 Else
   SendInput {Shift down}{Right}{Shift up}AutoHotKey
 SendInput %A_EndChar%
 Clipboard := OldClip
Return

The only problem I found with this routine was that whenever ahk is used at the beginning of a page (no possible preceding character), the cursor movement to the right actually uncovers the first a, yielding results such as aAutoHotKey. The solution is to add an Else If conditional which combines the Else command with the If command. This only takes affect when there is no character or symbol preceding the ahk activating string:

:B0C:ahk::
 SendInput {Backspace}{Shift down}{Left 4}{Shift up}
 OldClip := Clipboard
 Clipboard := 
 SendInput ^c
 ClipWait 0
 If (Clipboard = ".ahk")
   SendInput {Shift down}{Right 4}{Shift up}
 Else If (Clipboard = "ahk")
   SendInput AutoHotKey
 Else
   SendInput {Shift down}{Right}{Shift up}AutoHotKey
 SendInput %A_EndChar%
 Clipboard := OldClip
Return 

If the Windows clipboard only contains the three characters ahk (no preceding character), then it is replaced with AutoHotKey. This is the final Hotstring routine—at least until another issue crops up.

This one Hotstring covers quite a bit of territory for a beginning level topic. However, many of these techniques are used on a regular basis in other AutoHotKey applications. This is the same approach that I used to fix the http and HTML problem which cropped up after I implemented the automatic correction of the two letters ht to th whenever I started a word with ht (in a previous blog). I’m saving that discussion for a later date.

Next time, I’ll go into how to add a pop-up menus to your AutoCorrect script for selecting the correct correction.

*         *          *

Find Jack’s AutoHotkey e-Books at ComputorEdgeBooks.com.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s