Loading Hotstrings into the InstantHotstring.ahk Script from Any AutoHotkey (.ahk) File

Reading Data from Saved .AHK Files Makes Loading Hotstrings into the InstantHotstring.ahk Script Easy

In the blog, “Use the FileSelectFile Command to Save Instant Hotstrings to an AutoHotkey File.” I discussed how to save a set of newly created InstantHotstring.ahk Hotstrings in .ahk files. The other half of the file storage problem involves reading those saved (or any other) Hotstring data files back into that same app. Using the tools already built into the script made writing the file loading code remarkably easy. The subroutine LoadHotstrings calls on the previously written subroutines SetOptions and AddHotstring. This saves replicating of code originally used in those subroutines.

Loading Hotstring Files into the InstantHotstring.ahk Script

Library BenefitsI designed the LoadHotstrings subroutine to scan any .ahk file looking for lines of code in the AutoHotkey Hotstring format. This subroutine:

This approach to loading the Hotstrings from a file simulates the same steps you would take when adding a new Hotstring by hand directly to the InstantHotstring app—although it skips a couple of steps which would slow down the process with pop-up messages.

InstantHotstring Load
The InstantHotstring.ahk script uses the FileSelectFile command to locate a saved .ahk file, then read its contents into a variable. Next, AutoHotkey Loops through the variable matching and loading any Hotstrings. This works for any file containing AutoHotkey Hotstrings.

Watching Hotstrings Load

You can watch each Hotstring flash by as AutoHotkey loads the parsed code into the InstantHotstring.ahk app—rendering the changes in the GUI controls. If the file contains a large number of Hotstrings, the process runs a little slow. In fact, when a Hotstring file only contains a few lines, the loading time does not cause a problem, but when filling the app with the 1033 Hotstring EmojiInsert.ahk file, in one test, it took two minutes 15 seconds. This is not desirable.

Changing and redrawing the GUI window while loading the Hotstrings from a file consumes a great deal of computer time. We can speed up the process by hiding the GUI while loading the Hotstring but then we don’t get feedback during the loading process. (Is it working or not?)  We can add a Progress GUI control to track the loading process, although, even rendering that control can eat up a little time. (In the next blog, I optimize the loading process by hiding the GUI and adding an informational Progress GUI control.)

The LoadHotstrings Label Subroutine

Here I offer the entire LoadHotstrings subroutine (without the code I plan for speeding up the loading process). But, rather than discussing the entire subroutine line-by-line, I plan to hit the high points. Many commands and functions found here I’ve discussed extensively either in other blogs (linked where appropriate) or my books (found at ComputorEdgeBook.com):

LoadHotstrings:

Gui, Hotstring:+OwnDialogs
If (InStr(FileExist("\Hotstrings"), "D") = 0)
  FileCreateDir, Hotstrings

FileSelectFile, OpenFile , , %A_ScriptDir%\Hotstrings\, , *.ahk
If ErrorLevel
  Return

; Variable to tell the script that activated strings come from a file.
LoadHotstrings := 1

; Use *P65001 to read UTF-8 file *P1200 for UTF-16
FileRead, AddHotstring, *P65001 %OpenFile%

Loop, Parse, AddHotstring, `n
{
  If (A_Loopfield ~= "^:.*?:.+?::[^\s]") ; Check for valid Hotstring
  {
    HotString := StrSplit(A_LoopField, ":",,5)
    GuiControl, , Edit1, % HotString[3]
; Removes comments on same line
    HotText := StrSplit(HotString[5], A_Space . ";") 
; Trim spaces from right side of text
    GuiControl, , Edit2, % RTrim(HotText[1]," `r") 
    GoSub SetOptions
    GoSub CapsCheck
    GoSub AddHotstring
  }
}

LoadHotstrings := 0

Return

You can find this subroutine in context at the Free AutoHotkey Scripts page in the InstantHotstring.ahk script.

Make Sure the File or Folder Exists

You only need the following code to check for the Hotstrings folder—just in case you accidentally (or deliberately) deleted it:

If (InStr(FileExist("\Hotstrings"), "D") = 0)
  FileCreateDir, Hotstrings

However, after recreating the folder and opening it with the FileSelectFile command, no files will appear in the listing pane. You will need to navigate to the proper location.

Note: In reality, you probably don’t need this bit of code. Anytime you load or reload the script, it checks for the existence of the sample Hotstring file. If not found, AutoHotkey recreates it—which includes the Hotstring folder. The snippet above would only take effect if you deleted the folder in the middle of a session.

If you plan to maintain your Hotstring files elsewhere, then you should alter the code in both the save subroutine and the load subroutine to reflect that change.

Disable Key Portions of Other Subroutines

You’ll find pieces of the AddHotstring subroutine which could halt the loading of Hotstrings—mostly due to pop-up messages which highlight areas of concern. While appropriate when setting individual Hotstring by hand, the MsgBox windows quickly become tedious when loading hundreds (or thousands) of Hotstrings. By creating a variable which tells the script that the incoming Hotstrings originate from a file:

; Variable tells script the activated strings come from a file.
LoadHotstrings := 1

we can add conditionals for skipping those parts of the code which slowdown the loading process:

If (LoadHotstrings = 0)  ; Not from file
{
  .
  .
  .
}

You find this type of conditional in the AddHotstring subroutine.

(Since we assume that any Hotstrings found in .ahk files already contain proper formatting, skipping these checks in the AddHotstring subroutine does not present a problem.)

Make Sure You Can Read Special Characters

By default, the FileRead command reads files in the ANSI format. That means you can lose any special characters such as emojis in the loading process. By adding the *P65001 option, we ensure that AutoHotkey retains special formatting in the Hotstrings.

; Use *P65001 to read UTF-8 file *P1200 for UTF-16
FileRead, AddHotstring, *P65001 %OpenFile%

In the blog “Use the FileSelectFile Command to Save Instant Hotstrings to an AutoHotkey File,” we made a point of saving the Hotstring files in UTF-8 format to prevent loss of special formatting.

Use RegExMatch() Function to Find Strings

AutoHotkey RegExThe process of identifying Hotstring code lines in files presents another opportunity to take advantage of the power of Regular Expressions (RegEx). In this case, the script uses the abbreviated RegExMatch() function (~=) to only processes lines matching the AutoHotkey Hotstring format:

; Check for valid Hotstring
If (A_Loopfield ~= "^:.*?:.+?::[^\s]")

The above RegEx “^:.*?:.+?::[^\s]” looks for a match at the beginning of a line ^ when a colon :, followed by zero * or more characters .*?, another colon :, followed one + or more characters .+? (ensures at least one character in the Hotstring portion of the format), then a double-colon :: occurs. The [^\s] at the end ensures that the first character in the Replacement Text is not a blank space—as you might find in a continuation long replacement Hotstring. (You could also use [\S] to denote not a blank space.) This RegEx matches the format of any one-line AutoHotkey Hotstring.

We parse the Hotstring line and enter its parts into the InstantHotstring.ahk app.

(To learn the many ways to use Regular Expressions (RegEx), see my book, A Beginner’s Guide to Using Regular Expressions in AutoHotkey.)

Parse and Load the Hotstring into the InstantHotstring.ahk App

In various places in the InstantHotstring.ahk script, we use the StrSplit() function to parse the Hotstring code into its component parts:

HotString := StrSplit(A_LoopField, ":",,5)

When using the colon as the delimiting character, the StrSplit() function returns an array of variables containing the key Hotstring data.

AutoHotkey places the contents of the third array element into the matching Hotstring field in the GUI:

GuiControl, , Edit1, % HotString[3]

The Replacement Text part of the Hotstring requires a little more work.

Removing Comments from Replacement Text

Since some Hotstrings may contain at the end of the line operationally invisible comments preceded by a semicolon (;), the script must excise these before activating the Hotstring.

As an example of unwanted text, some of the Hotstrings in the EmojiInsert.ahk file use hidden comments as category markers which will not appear when routinely running the file under AutoHotkey:

:*:!cheese::🧀            ; food, dairy

However, without further parsing, the comments become part of the Hotstring when activated by the InstantHotstring.ahk script. First, we must re-parse the HotString[5] string using A_Space . “;” to separate the comments from the Replacement Text:

; Removes comments on same line
HotText := StrSplit(HotString[5], A_Space . ";")

Next, we insert the text into the Replacement Text field in the InstantHotstring.ahk GUI while trimming any remaining blank spaces from the right end of the string with the RTrim() function:

; Trim spaces from right side of text
GuiControl, , Edit2, % RTrim(HotText[1]," `r")

Since only comments preceded by a space and a semi-colon can appear on the same line as the Hotstring, this last step ensures clean Replacement Text for use in the Hotstring() function. (Note: Multi-line continuation Hotstrings will not load into the InstantHotstring app.)

Set Hotstring Options

Drawing upon any embedded Hotstring options, the SetOptions subroutine checks the respective CheckBox controls in the GUI:

GoSub SetOptions

This simulates the manual selection of options in the InstantHotstring.ahk script.

Activate Each Hotstring

After loading each valid Hotstring into the InstantHotstring GUI controls, the LoadHotstrings subroutine runs the AddHotstring subroutine—activating each with the Hotstring() function:

GoSub AddHotstring

This performs the same action as when the user clicks the Set Hotstring button in the GUI window—except for a couple of validating checks which would stop the loading action with a pop-up MsgBox.

Slow Loading Hotstring

As I mentioned toward the beginning of this blog, This Hotstring loading subroutine flashes each Hotstring in the GUI window as it loads the file. For large Hotstring files, this process can take a few minutes. I’ve made changes to hide the GUI while loading and implemented a Progress GUI control to track the results. Next time.

Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)

jack

This post was proofread by Grammarly
(Any other mistakes are all mine.)

(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)

3 thoughts on “Loading Hotstrings into the InstantHotstring.ahk Script from Any AutoHotkey (.ahk) File

  1. […] Last time, I discussed the problem of slow data loading speeds when adding a large Hotstring file to the InstantHotstring.ahk app. I selected the EmojiInsert.ahk file (1036 Hotstrings) as a test file and watched as AutoHotkey carefully render each flashing Hotstring in the GUI window. I have since implemented techniques for hiding the GUI window and adding a Progress GUI control, but in the process, I needed a technique for measuring and comparing the load times for the various setups. (In the next blog, I plan to review the drag reducing steps I took to slash Hotstring loading time.) As a timer, I implemented the method found in the AutoHotkey online documentation for measuring the elapsed time in an AutoHotkey script: […]

    Like

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 )

Facebook photo

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

Connecting to %s