AutoHotkey Tip of the Week: Auto-Capitalize the First Letter of Sentences

Some People Don’t Find It Easy to Shift to Uppercase While Capitalizing Words—AutoHotkey Allows Us to Stop Reaching for the Shift Key—at Least for New Sentences!

I received the following question from a reader:

Hello,

Is there a script to auto-capitalize the first word of a sentence. Or after a period?

Thanks.

*          *          *

Not everyone received an A in typing class—I didn’t. Plus, many people for a variety of reasons may find navigating a keyboard difficult. Where using the Shift key may be a simple inconvenience for some, people who are not blessed with full functioning fingers and/or hands encounter an arduous task. Even capitalizing the word “I” (“i think i will go”) can present a challenge. The primary goal of AutoHotkey is to make your Windows life easier.

You’ll find a number of ways to build an auto-capitalize script—the simplest involves setting up about 100 Hotstrings. A more complicated solution uses Regular Expressions (RegEx).

Add Hotstrings for Each Case

Library Benefits

In reply to the above question, I offered some sample Hotstrings for capitalizing the first word after a period:

:C?*:. a::. A
:C?*:. b::. B
:C?*:. c::. C

The C option (located between the first two colons) forces the Hotstring to look for only the lowercase letter. The asterisk * option immediately activates the Hotstring—no end character required. The question mark ? option allows the Hotstring to fire as part of another word—a common occurrence at the end of a sentence since space almost never appears between the last word in a sentence and the period (e.g. This is the end of a sentence. After…).

We only need to create 26 of these Hotstrings—one for each letter of the alphabet. You might find this the easiest solution.

Of course, we should also add Hotstrings for sentences ending in question marks ( ? ) and exclamation points ( ! ). That’s 52 more! Note: The exclamation points ( ! ) requires the raw R option since the character acts as a Hotkey modifier:

:CR?*:! a::! A
:CR?*:! b::! B
:CR?*:! c::! C

If we want to capitalize the first word in a new paragraph (no preceding punctuation), we can add another set of Hotstrings that capitalize the first letter after the newline character ( `n )—another 26 Hotstrings:

:C*:`na::`nA
:C*:`nb::`nB
:C*:`nc::`nC

Setting up over 100 Hotstrings one-by-one gets tedious. (Of course, you only need to do this once.) Fortunately, the recent addition of the Hotstring() function makes it easy.

Adding Hotstrings with the Hotstring() Function

The Hotstring() function alleviated most of the need for complex routines creating dynamic Hotstrings. Now, we can set up Hotstrings anytime without hardwiring the code into a script. (The InstantHotstrings.ahk script uses the Hotstring() function as its backbone for creating, testing, and saving Hotstrings.)

Beginning AutoHotkey Hotstrings 200pxNote: I uncovered some dynamic Hotstring functions written years ago that work well. However, the Hotstring() function supplanted many of their benefits—with the exception of more complex Regular Expressions (RegEx) Hotstrings. One of the first solutions I found for the sentence-capitalization problem used one of these functions but I didn’t find it necessary any better or more robust than the Hotstring() function code I offer here. Yet, I see other important reasons for adding at least one of these dynamic RegEx Hotstring functions to your AutoHotkey toolbox. More on that next time.

The following Loop commands set up Hotstrings that capitalize the first word in a sentence following a period, a question mark,  or an exclamation point (with one space), plus the new paragraph mark ( `n ) (with no space):

Loop, 26 
	Hotstring(":C?*:. " . Chr(A_Index + 96),". " . Chr(A_Index + 64))
Loop, 26 
	Hotstring(":CR?*:! " . Chr(A_Index + 96),"! " . Chr(A_Index + 64))
Loop, 26 
	Hotstring(":C?*:? " . Chr(A_Index + 96),"? " . Chr(A_Index + 64))
Loop, 26 
	Hotstring(":C?*:`n" . Chr(A_Index + 96),"`n" . Chr(A_Index + 64))
Return

That’s all there is to it!

These AutoHotkey Loops create Hotstrings identical to the original hardcoded Hotstrings shown above. However, unlike the Hotstring double-colon format, you can run this code to set up the auto-capitalize app at any time—preferably in the auto-execute section of the script.

I’ve put this routine—plus the two following techniques—into the new AutoSentenceCap.ahk script.

Two More Capitalization Techniques

1. Capitalize the word “I”

Since we always capitalize the word “I”, this script should include:

:C:i::I

If AutoHotkey detects a lone lowercase “i”, it converts it to an uppercase “I” whenever I follow it with an end character (EndChar).

2. Capitalize the first word in a document (or any other word)

The new paragraph capitalization only works for letters following the newline character ( `n ). It doesn’t work for the first paragraph in a document—no newline. We need an easy way to switch that first letter—after typing it—to uppercase (or, for that matter, capitalize any word).

I wrote a Hotkey routine that transforms the first letter of any word appearing just before the text cursor into uppercase. I commandeered the CapsLock key for the Hotkey since I had blocked years ago due to its annoying behavior (as discussed in “Chapter Eight: Using Extra Mouse Buttons and the Wasted Insert Key” in the free book AutoHotkey Tricks You Ought to Do with Windows).

The following routine capitalizes any word appearing before the cursor location. The cursor may sit on any portion of the target word, but not on the next word:

CapsLock::
  OldClipboard := ClipboardAll
  Clipboard := ""     ; Clears the Clipboard
  SendInput ^+{left}  ; Selects word to the left
  Sleep, 100
  SendInput ^c        ; Copy text
  ClipWait 0 ;pause for Clipboard data
  If ErrorLevel
  {
    MsgBox, No text selected!
  }
  StringUpper, Clipboard, Clipboard, T  ; Cap first char (Title)
  Sleep, 100
  SendInput %Clipboard%
  Clipboard := OldClipboard
Return

hotkeycover200

March 15, 2020 Update: Added the Sleep commands in response to the comment at the end of this blog from Thom Blake. See this discussion “Quick Tip: Using the Sleep Command with Clipboard Routines.”

This routine uses the “Standard Clipboard Routine”, discussed in Chapter Nine: “AutoHotkey Windows Clipboard Techniques for Swapping Letters” of the book AutoHotkey Hotkey Techniques to create a Hotkey for capitalizing the first letter of any word when you press the CapsLock key with the cursor located inside it.

Note: See the discussion of the SendInput %Clipboard% command versus the SendInput ^v command in the blog “Quick Tip: The Best Way to Paste with the AutoHotkey Send Command—including the comments from readers at the end of the blog.

Now, when I hit the CapsLock key with the text cursor in or at the end of the word, it automatically capitalizes that word in any document or text editing field.

Find the new AutoSentenceCap.ahk script at the Free AutoHotkey Scripts page.

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.)

Find my AutoHotkey books at ComputorEdge E-Books!

Buy Jack a Cappuccino!

If you found a blog particularly useful, show your appreciation by buying Jack a cup of coffee! Or, if you prefer something for yourself, check out his books.

$4.95


Peruse my AutoHotkey books at ComputorEdge E-Books!

25 thoughts on “AutoHotkey Tip of the Week: Auto-Capitalize the First Letter of Sentences

  1. Hi, thank you, it’s indeed great tip, which made my day 😀

    I’ve spotted typo in your code:

    Loop, 26
    Hotstring(“:C?*:`n” . Chr(A_Index + 96),”`ns” . Chr(A_Index + 64))

    Corrected version:

    Loop, 26
    Hotstring(“:C?*:`n” . Chr(A_Index + 96),”`n” . Chr(A_Index + 64))

    Happy coding, Jack

    Like

  2. Jack

    Great script but I seem to have a problem with the capitalize a word function. It only works intermittently. Message box says No text selected when clearly there is.

    Like

  3. Your CapsLock script is an amazing idea. Love it. I use AHK to capitalize the first letter of my name. Unfortunately when I’ll type my email address or webpage, I don’t want the capitalization. So a light change in your script and I can reverse it and have all in lower case.

    Like

  4. Hey, just wanted to say this script is great! However, I may not be able to use it anymore, because it always SENDS the first letter it capitalizes as a message in Microsoft Teams. I thought maybe I was typing to fast, but I waited 10 seconds and it still does the same thing. Please help! Here is a screenshot: https://i.imgur.com/23cEZ5H.png

    Like

  5. The CapsLock routine is handy. I prefer it with a modifier key. Some people (I am one) use SHIFT to release CapsLock. Therefore, I use ^CAPSLOCK as the hotkey, and it works.

    Like

  6. This routine can be handy, though the main issue is that, in AHK, “if more than one hotstring matches something you type, only the one listed first in the script will take effect”. Actually, I’m not sure about that, as it appears that using the asterisk as a hotstring option takes precedence. In any case, this does seem to have the effect that other hotstrings that could otherwise be used cannot be used if they also match the code provided here. I have lots of those types of hotstrings, which I use on new lines and after punctuation. I have been unable to find any solutions to this, since AHK does not accommodate sequential firing.

    Like

    • A short demo:

      :T:tn::Thanks
      :C*?:`nt::`nT

      Run this script. Type “Tn” on a new line. It works to type “Thanks”. Now type “tn” on a new line. The first line in the script is now skipped. You see only “Tn” in response.

      Like

      • Let me disagree with you. I’ve followed your example:

        #InputLevel 1
        :T:tn::Thanks
        #InputLevel 0
        :C*?:`nt::`nT

        General solution: you can write your own “triggerstring recognizer”. Solution which will work analogue to so called “hotstring recognizer” which is working in a shade of AutoHotkey interpreter. This isn’t too hard. Just InputHook() and circular buffer.

        Like

      • Let me disagree with you, @mikeyww. Following your example:

        #InputLevel 1
        :T:tn::Thanks
        #InputLevel 0
        :C*?:`nt::`nT

        It works to me.

        Referring to your main thought: “if more than one hotstring matches something you type, only the one listed first in the script will take effect”. Nope, see above.

        But to have more general solution, you can write “triggerstring recognizer” (analogue to “hotstring recognizer” working in a shade of AutoHotkey interpreter) and InputHook(). I’d suggest circular buffer as well.

        Like

  7. Hello Jack, I am a little too new to AHK to understand why this is happening but I have noticed that the newline portion of this code sometimes auto sends Microsoft Teams chats if you send a message and immediately start typing another!

    I will dedicate some time to fixing it on my own, but thought I should let you know for the time being

    Like

  8. I have issues with this and I want it to work so bad! Here is an example of the output when I type 3 sentences.

    The dog is blue. THe dog ran fast. -AHK
    —The dog is blue. The dog ran fast. -No AHK
    I have a dog.. SH name is Tommy. -AHK
    —I have a dog. His name is tommy. -No AHK
    Whats up?h iTS is the best script. -AHK
    —What’s up? This is the best script. -No AHK

    I have removed the newline code already, but this issue only happens when I type normal. If I type really slow, then it will usually work right.
    Any tips?

    I have a dog. THe dog is blue.. eT dog runs fast. The dog is red. iHs name is blue. uBt he is grey.
    I have a dog. The dog is blue. The dog runs fast. The dog is red. His name is blue. But he is grey.

    Like

  9. Regarding issue within Teams text messenger (aka communicator), I believe the same behavior is observed within Signal text messenger. Workaround:

    Loop, 26
    Hotstring(“:CB0?*:`n” . Chr(A_Index + 96), “{BackSpace}” . Chr(A_Index + 64))

    Like

    • I have this issue too. So the fix is adding that to the rest of them like this:

      AutoCap:

      Loop, 26
      Hotstring(“:C?*:. ” . Chr(A_Index + 96),”. ” . Chr(A_Index + 64))
      Loop, 26
      Hotstring(“:CR?*:! ” . Chr(A_Index + 96),”! ” . Chr(A_Index + 64))
      Loop, 26
      Hotstring(“:C?*:? ” . Chr(A_Index + 96),”? ” . Chr(A_Index + 64))
      Loop, 26
      Hotstring(“:CB0?*:`n” . Chr(A_Index + 96), “{BackSpace}” . Chr(A_Index + 64))

      …or removing those and just adding your Hostring?

      Like

  10. Hi,
    Thanks for this, great tool.
    I do exprience an issue with Microsoft teams though, it seems to only capitalize letter after .!? But it does not capitalize the first word you type into teams, is there a commandline you can add that as well?

    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