AutoHotkey Windows Clipboard Techniques for Swapping Letters (Beginning Hotkeys Part 9)

Delving into Windows Clipboard Hotkey Tricks for Switching Mistyped Letters in Any Document or Text Editor…Plus, a Discussion of the “Standard AutoHotkey Windows Clipboard Routine”

Note: January 29, 2017—Over time, I’ve come to realize that AutoHotkey scripts should employ a number of different “best practices” in Clipboard manipulation routines. The code includes ClipboardAll,  ClipWait 0, and IfErrorLevel.  This blog discusses those techniques in detail. I now refer to this AutoHotkey Clipboard setup as “the standard AutoHotkey Clipboard routine.”

I’m taking yet another diversion from the Hotkey command to dig into something just as important (if not more so) when discussing Hotkeys—the action code contained in and initiated by the keyboard combination. Highlighting Hotkeys without looking into the embedded routines is like studying eggshells without learning the nature of the egg. While the various techniques for implementing Hotkeys are significant, looking at the specific AutoHotkey action routine inside may be even more crucial.

*         *          *

 

AutoHotkey Library Deal
AutoHotkey Library Deal

This Hotkey blog builds upon the discussions in the previous parts of this series. If you find any of the information too confusing, then reviewing earlier blogs may be worthwhile. Plus, you can find the entire series in the e-book AutoHotkey Hotkey Techniques available in the EPUB, Amazon MOBI, and PDF (for printing and reading) formats.

 

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

*          *          *

Swapping Letters with the Windows Clipboard

I start with a simple AutoHotkey action which swaps two misplaced letters in any text document or editing window. For example, maybe you typed “from” rather than “form”—or vice versa. It’s a common problem which requires the swapping of two letters in the middle of the word.

The obvious solution is highlighting the two characters by dragging the mouse cursor over the characters, then retyping the letters. This takes at least three actions: dragging the mouse with the left button down, then the two replacement keystrokes. (Half the time I type the same characters exactly the same as before.) What if we write a short Hotkey script which swaps the two letters?

We begin with a simple AutoHotkey solution but continue adding features which make the Hotkey routine more robust while simplifying the activating action.

This blog introduces AutoHotkey tricks for using the Windows Clipboard (while saving its original contents), checking for Clipboard errors, and using the Send command to select text inside any word processor, e-mail program, or Web editing field.

Using the Windows Clipboard with AutoHotkey

One of the most common AutoHotkey methods for manipulating text is by utilizing the Windows Clipboard. The convenience of the Windows Clipboard is in its ability to copy (CTRL+C) anything selected from any source (document, Web page, e-mail, etc.), then save it in temporary memory. Once saved, the Clipboard contents can be manipulated in a number of ways. The cleverly named built-in AutoHotkey variable Clipboard always contains the current contents of the Windows Clipboard. Many AutoHotkey Hotkey routines access the Windows Clipboard for its unique power and flexibility.

As an example, I build on an AutoHotkey script which takes advantage of the Windows Clipboard to transpose two mistyped letters. Later, as part of the explored techniques, highlighting with the mouse cursor gets replace by the AutoHotkey Send command for selecting (highlighting) text. No need to hold the left mouse button and drag.

Swapping Transposed Letters

The first time I talked about swapping letters in a word processor or text editor was in Chapter Five, “A Tip for Mild Dyslexia, Swapping Letters,” of Digging Deeper into AutoHotkey. Written early in my AutoHotkey explorations, this snippet offers a barebones look at the Hotkey:

!R::
  SendInput, ^c
  Sleep, 100
  Clipboard := SubStr(Clipboard,2,1) . SubStr(Clipboard,1,1)
  SendInput, ^V
Return

When the key combination ALT+R (!R) is activated, any selected (highlighted) text is copied (CTRL+C) to the Windows Clipboard with the Send command (SendInput, ^c). AutoHotkey then pauses 100 microseconds (Sleep, 100), swaps the two characters using the SubStr() function, then replaces/pastes (SendInput, ^V) the pre-selected text in the document with the Clipboard contents.

The SubStr() function swaps the two characters by placing the period/dot ( . ) concatenate operator (adds text together) between the second character (SubStr(Clipboard,2,1)) and the first character (SubStr(Clipboard,1,1))—reversing the original order.

Honestly, this Hotkey is about the same amount of work as doing the letter swap by hand—highlight the letters, then activate the two key combination—but it’s a good starting point. While this script is simple, works well, and demonstrates the basic use of the Windows Clipboard, it presents a number of common AutoHotkey issues which should be addressed.

  1. If the Windows Clipboard already contains data—which you might want to use later—the Hotkey wipes out that content when it sends the Clipboard copy shortcut (CTRL+C).
  2. When AutoHotkey stores to the Clipboard there is a time lag (however slight). If the script doesn’t pause, then it could outrun the copy process before saving the proper Clipboard content. Adding the pause (Sleep, 100) ensures time for the Clipboard copy, but let’s find a better way.
  3. The script requires the pre-selection of the two transposed letters with the mouse or cursor keys. Without a selection prior to the Hotkey activation, either no result or the wrong result occurs.

There are simple solutions for each of these problems which you should implement in your AutoHotkey scripts.

Tip for Saving Contents of the Windows Clipboard

As a rule, you don’t want to lose the contents of your Windows Clipboard merely because you used a Hotkey. When added to any Windows Clipboard snippet, there are a couple of lines of AutoHotkey code which save and restore the original Clipboard contents:

!R::
 OldClipboard := ClipboardAll
  SendInput, ^c
  Sleep, 100
  Clipboard := SubStr(Clipboard,2,1) . SubStr(Clipboard,1,1)
  SendInput, ^V
 Clipboard := OldClipboard
Return

In the first line of code, AutoHotkey saves the contents of the Windows Clipboard to the variable OldClipboard. The ClipboardAll form of the built-in variable captures everything contained in Windows Clipboard—including graphics and files. The Clipboard form of the variable only captures text.

After running the main code in the Hotkey, the routine restores the original Clipboard contents by setting the Clipboard variable to the previously saved content (Clipboard := OldClipboard). By including these two lines in AutoHotkey Clipboard scripts, activating one of these Hotkey no longer affects the Clipboard’s initial contents.

Waiting for the Clipboard

Anyone who has used a simplified AutoHotkey Clipboard Hotkey has most likely experience the problem of Clipboard loading lag. While the data loads into the Clipboard, the AutoHotkey script continues on to the next lines of code. This often causes the routine to outrun the Clipboard copy command causing the Hotkey to either not work or return unexpected results. We often fix the problem by adding a pause (Sleep, 100), as shown above, but that can be hit or miss—especially if a particularly long Clipboard load time occurs. The ClipWait command may be the solution, however, it comes with a couple of important quirks.

Using the ClipWait Command

First, the ClipWait command only works with an empty Windows Clipboard. The command pauses the script until data appears in the Clipboard. A common novice error is to use the ClipWait command when the Clipboard already contains other data. It’s important to clear the Clipboard by setting it equal to nothing:

!R::
 OldClipboard := ClipboardAll
  Clipboard =     ;clears the Clipboard
  SendInput, ^c
  ClipWait 0      ;pause for Clipboard data
  Clipboard := SubStr(Clipboard,2,1) . SubStr(Clipboard,1,1)
  SendInput, ^V
 Clipboard := OldClipboard
Return

The Windows Clipboard is emptied by setting the Clipboard variable to no value (Clipboard = ). Now that the Clipboard is free of content, the ClipWait command pauses until data appears in it. It’s important to include the number of seconds to wait. Otherwise, it will wait indefinitely—a problem if you forget to select any text. (By adding 0  (ClipWait 0) as the time interval, the timeout defaults to 0.5 seconds.)

Using ErrorLevel for Hotkey Misfires

If I forget to preselect the two letters, then, when activating the Hotkey, nothing gets copied into Windows Clipboard. If the ClipWait command simply timeouts, I may not even realize what happened.

This can be fixed by adding an ErrorLevel message for those times when nothing moves into the Windows Clipboard. The message informs me that I forgot to select the letters:

!R::
 OldClipboard := ClipboardAll
  Clipboard = ;clears the Clipboard
  SendInput, ^c
  ClipWait 0 ;pause for Clipboard data
  If ErrorLevel
   {
    MsgBox, No text selected!
   }
  Clipboard := SubStr(Clipboard,2,1) . SubStr(Clipboard,1,1)
  SendInput, ^V
  Clipboard := OldClipboard
Return

Whenever the ClipWait command times out without data moving into the Windows Clipboard, ErrorLevel is set to 1 (true). Otherwise, the value is set to 0 (false). This will happen whenever I don’t pre-select (highlight) the two letters targeted for swapping. By adding the ErrorLevel trap, the routine uses the MsgBox command to notify me if I forget to make a selection.

Eliminating the Requirement for Pre-Selected Text

Rather than checking for errors when no text is pre-selected, wouldn’t it be better if all we had to do was place the cursor without any type of pre-selection? This is where clever use of the Send command makes it even easier to swap two letters. Simply place the cursor between the two letters and hit ALT+R:

!R::
 OldClipboard := ClipboardAll
  Clipboard = ;clears the Clipboard
  SendInput {Left}+{Right 2}
  SendInput, ^x
  ClipWait 0 ;pause for Clipboard data
  If ErrorLevel
  {
    MsgBox, No text selected!
  }
  SwappedLetters := SubStr(Clipboard,2) . SubStr(Clipboard,1,1)
  SendInput, %SwappedLetters%
  SendInput {Left}
 Clipboard := OldClipboard
Return

As demonstrated in an earlier blog, the Send command can be used to select text in a document or edit field. This eliminates the needs to pre-select text with the mouse, although the cursor still must be placed between the two characters for swapping. In this case, the SendInput command moves the cursor one space to the left ({Left}) before holding down the SHIFT key (+) and highlighting two characters to the right (+{Right 2}).

Note: The primary modifier keys (^ for CTRL, ! for ALT, + for SHIFT, and # for the WIN key) serve the same purpose in the Send command as they do in any Hotkey combination. They each behave as if the modifying key is held down while the next character is pressed. Therefore, Send, +{Right 2} holds down the SHIFT key while moving the cursor key two characters to the right—thus selecting the two letters.

Tip: Be careful when using capital letters with the Send command. The command Send, !A is the same as Send, !+a. The SHIFT key is assumed when sending an uppercase letter, therefore it’s usually safer to use lowercase letters with the Send command.

The SendInput command then cuts (CTRL+X) the characters and sends them to the Windows Clipboard. I used CTRL+X (cut) as an alternative to CTRL+C (copy) merely for demonstration purposes. The difference is slight since the later SendInput will replace the selected text. I tend to stick with the copy shortcut rather than cut since an error when using copy (CTRL+C) will likely leave the original text untouched rather than deleting it.

Tip: In most cases, I use SendInput rather than Send because it is faster and more robust. Per the online documentation, “SendInput and SendPlay use the same syntax as Send but are generally faster and more reliable. In addition, they buffer any physical keyboard or mouse activity during the send, which prevents the user’s keystrokes from being interspersed with those being sent.”

Using the Send command to select the target letters speeds up the Hotkey procedure while eliminating possible inaccuracies. Just locate the cursor between the mistyped characters and hit the Hotkey combination.

Mouse selection can be cumbersome and at times inaccurate. For example, if three characters are accidentally selected rather than two then the results will be distorted. Plus, by guaranteeing selection with the Send command, the ErrorLevel trap may no longer be needed since characters will always get selected for copying to the Clipboard—unless the cursor is placed inside an empty file or non-editable page.

Note: Even with the advantages of selecting (highlighting) text with the Send command, there are times when pre-selecting text with the mouse is preferable—as will be demonstrated in the word swapping Hotkey to be discussed in the next blog.

On Altering the Clipboard Contents

Rather than altering the data within the Windows Clipboard, this routine saves the swapped letters to the variable SwappedLetters. With regards to performance, I don’t know that it make much difference, but rather than using CTRL+V to paste the results (SendInput, ^V), the Send command inserts the contents of the new variable (SendInput, %SwappedLetters%) directly into the document. The most obvious advantage to this technique is that the content of the Clipboard remains untouched—possibly for other use.

The last Send command (SendInput {Left}) moves the cursor left—back to the starting location between the two swapped characters. Hit ALT+R again and characters toggle back to their original order.

Format for Standard AutoHotkey Windows Clipboard Procedures

Our letter swapping letters Hotkey routine has grown considerably since the version from the Digging Deeper book. Yet each change significantly adds to the efficiency and robustness of the Hotkey routine. If you want to ensure that you include these tips in all your Windows Clipboard Hotkeys then, you may want to add them to another AutoHotkey Hotkey (CTRL+ALT+F) for inserting the needed lines of code:

^!F::
var =
(
[Enter Hotkey combination here]`:`:
 OldClipboard := ClipboardAll
 Clipboard = ;clears the Clipboard
[Add Clipboard Selection/Copy code here]
ClipWait 0 ;pause for Clipboard data
 If ErrorLevel
 {
 MsgBox, Error message for non-selection
 }
[Add Clipboard Paste/Replacement code here]
Clipboard := OldClipboard
Return
)
SendInput, %Var%
Return

Press the CTRL+ALT+F key combination and the above format is entered into your working script ready for your new Hotkey. Note that the colon character (:) needs to be escaped with the backtick (`:). Otherwise, AutoHotkey thinks you’re trying to set up another Hotkey.

Or, if you prefer to set up a slightly simpler Hotstring for entering the format (cbf for Clipboard Format):

:*:cbf::
(
[Enter Hotkey combination here]`:`:
 OldClipboard := ClipboardAll
 Clipboard = ;clears the Clipboard
[Add Clipboard Selection/Copy code here]
ClipWait 0 ;pause for Clipboard data
 If ErrorLevel
 {
 MsgBox, Error message for non-selection
 }
[Add Clipboard Paste/Replacement code here]
Clipboard := OldClipboard
Return
)

Open any text editor and type “cbf” and the structure for the Windows Clipboard Hotkey gets inserted. Fill in the details to complete the script.

Next time, we’ll take a look at adding a couple of new tricks with similar Clipboard techniques for swapping words.

 

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