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
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.)
Note: 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
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.)
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!
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
LikeLike
Thanks! Corrected.
LikeLike
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.
LikeLike
You may need to add a pause (Sleep, 100) after the first SendInput command. Depending upon the situation, the script may outrun the copy. See this discussion “Using the Sleep Command with Clipboard Routines.”
LikeLike
[…] night, I received the following comment from Thom Blake about last week’s blog “Auto-Capitalize the First Letter of Sentences” prompting this Quick Tip about adding the Sleep command at critical points in certain types […]
LikeLike
[…] doing research for last week’s blog, I came across an alternative technique for capitalizing the first letter in a sentence. It uses a […]
LikeLike
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.
LikeLike
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
LikeLike
I’m not familiar with Microsoft Teams but perhaps you can isolate the Hotstrings to prevent firing in that program by using the #If directive. I discuss the techniques in my book AutoHotkey Hotkey Techniques.
LikeLike
I was able to fix it by removing:
Loop, 26
Hotstring(“:C?*:`n” . Chr(A_Index + 96),”`n” . Chr(A_Index + 64))
..for the caps on new line. I’m gonna miss it but I Teams more than any app for work.
LikeLike
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.
LikeLike
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.
LikeLike
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.
LikeLike
Try this:
LikeLike
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.
LikeLike
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.
LikeLike
[…] Recent comment on my blog “Auto-Capitalize the First Letter of Sentences“: […]
LikeLike
[…] Hotkeys, you can switch to alphabetic characters using techniques similar to those found in “Auto-Capitalize the First Letter of Sentences” for Hotstrings using Chr(A_Index + 64) to convert to the letter […]
LikeLike
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
LikeLike
I had this issue too and had to stop using it. 😦
LikeLike
I simply commented out the newline portion Heath and haven’t had a single problem since!
You lose that specific functionality of course but the other pieces are worth it to me!
LikeLiked by 1 person
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.
LikeLike
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))
LikeLike
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?
LikeLike
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?
LikeLike