Thanks maniac, and HugoV, appreciate your comments.
Agree that my initial version is qwerty-centric and keyboard-layout-insensitive, so:
Code:
SplashImage, , , Q: Qwerty Layout`nC: Colemak Layout`nD: Dvorak Layout
Input, Layout, L1
ChooseString = asdfgqwert1234567890 ; still the default!
if (Layout="c")
ChooseString = arstdqwfpg1234567890
if (Layout="d")
ChooseString = aoeuidhtns1234567890
SplashImage, off
cs := ChooseString
allows the Colemak-friendlier:

I hadn't known of the Colemak layout, and may try to learn it as a project. It seems that one of its design principles (that minimizing finger travel distance is desirable) is used by allowing custom hotkey combinations in the script. It would also allow immediate selection of up to 20 choices without needing repeated arrow-key strokes. It feels very natural to me. But I understand that many people may find it easier to type numbers. Personally, I can never hit the number keys without making mistakes, especially 5 - 6 - 7 (now I've gone from being qwerty-centric to being a number-hater, it's hard to be politically correct), and I don't think I'm the only person in that boat.
maniac, hope you try this revised version and see some merit in the hotkey combination option. Needs to be run with LoopAndChangeLines_2p13.ahk (in my previous post).
Code:
/*
Revised to allow for immediate choice of 3 different keyboard layouts (with qwerty the default)
Assign name for revised file, and original file
Run this script, it does the rest
Two modifications to the basic (great) TypingAid script
1:
I'm a touch typist who's clumsy at finding numbers
And I'm lazy, I hate to remove my fingers from the home row
This modification allows choosing words from the tooltip
by using the custom combination of <key> & <letter or number>
(while holding down <key> hit <letter or number>
Key options:
Space - text followed by space
N (NoSpace) - text without space after
; , . - text with that punctuation after
M (as in ctrl-m command) or Enter - text with carriage return after
, & . while tooltip displayed: Toggles whether space inserted after words and punctuation, default is Yes, insert. Changes default for _subsequent_ choices, not the current one.
Letter - number options:
asdfg qwert corresponds to 1 - 0 if <key> is held down
1234567890 will choose 11 - 20 if <key> is held down
Maybe someone knows a way to do this easier than creating a
hidden window when the tooltip shows content
( create gui window hidden99 by function g99c() )
and making the custom combinations conditional #ifwinexist hidden99
==> I don't think this change will be at all useful to one-finger typists, but I think it will be VERY helpful to touch typists. (It is to me!) Also, still allows choosing by numbers without holding down <key>.
2:
In addition, I've added a SpecialStringCheck() function.
It looks at the chosen string before sending it to be entered.
This allows:
+ insert multi-line strings ( | is replaced with string `n )
+ insert everything after chosen character (in this first revision I chose semicolon)
- <not yet done> can make this a remarkable front end that does more than insert text, by creating rules, for example assigning character which will start branch "run the following text as ahk code" instead of "insert text"
To avoid interfering with the original TypingAid, this (demonstration and bugs-included) Mod writes its own small wordlist.mod.txt and preferences.mod.ini
This script run in the same directory as
original file (eg TypingAid v2.13.ahk)
will create and load
revised file (eg TypingAid v2.13tooltip.ahk, tooltip because I also have a listbox mod
After assigning names,
The modTA include file (currently line 9) creates "RevisedFile" by looping through the "OriginalFile" line by line, creating place-sensitive additions and replacements to the original file, plus one line at the end for an include file. This include file contains the window-sensitive custom combination hotkeys and revised functions
*/
OriginalFile = TA_2p13ori.ahk
IfNotExist, %OriginalFile%
InputBox, OriginalFile, , Type Name of File to modify`, located within script directory:,,,,,,,,%OriginalFile%
IfNotExist, %OriginalFile%
MsgBox,,, Error`, try again, 2
RevisedFile = TA_2p13ModToolTip.ahk
IncludeFile = %RevisedFile%.include.txt
ofile := OriginalFile
rfile := RevisedFile
ifil := IncludeFile
FileDelete, % rfile
FileDelete, % ifil
;#Include modTA.011_2p13a.ahk ; original to modify ori
;#Include modTA.011_2p13aa.ahk ; simplify the sendvalue commands, works
;#Include modTA.011_2p13aaa.ahk ; try to allow any sendmethod
#Include LoopAndChangeLines_2p13.ahk ; SendFullMod(sending, StrLen(Word))
/*
This Include File does place-sensitive additions and replacements within the original TypingAid v2.13, including adding 1 line for an include file at the end of the Modified TypingAid.
TMod11.txt is created below, the code is not place-sensitive and doesn't replace existing TypingAid code
This modification allows:
- custom combination hotkeys starting with ; or , or .
- choosing among the first 10 items by ;/,/. & letter chosen by the left hand
- choosing among the last 10 items by ;/,/. & Number 1 - 0
- ; just adds selection, while ,/. will add selection plus punctuation.
*/
SplashImage, , , Q: Qwerty Layout`nC: Colemak Layout`nD: Dvorak Layout
Input, Layout, L1
ChooseString = asdfgqwert1234567890
if (Layout="c")
ChooseString = arstdqwfpg1234567890
if (Layout="d")
ChooseString = aoeuidhtns1234567890
SplashImage, off
cs := ChooseString
; FirstChar of combination hotkey determines action after item is chosen:
; Space -> space
; n -> No Space m Carriage return (like the old control m)
; ; or , or . -> that punctuation added
FileAppend, #IfWinExist`, hidden99`n, % ifil
loop, 20
{
i := A_Index
hk2 := SubStr(cs, i, 1)
FileAppend, ```; & %hk2%::`nCheckWord(`"$%i%`")`ng99d()`nreturn`n, % ifil
FileAppend, `. & %hk2%::`nCheckWord(`"$%i%`")`ng99d()`nreturn`n, % ifil
FileAppend, `, & %hk2%::`nCheckWord(`"$%i%`")`ng99d()`nreturn`n, % ifil
FileAppend, space & %hk2%::`nCheckWord(`"$%i%`")`ng99d()`nreturn`n, % ifil
FileAppend, enter & %hk2%::`nCheckWord(`"$%i%`")`ng99d()`nreturn`n, % ifil
FileAppend, m & %hk2%::`nCheckWord(`"$%i%`")`ng99d()`nreturn`n, % ifil
FileAppend, n & %hk2%::`nCheckWord(`"$%i%`")`ng99d()`nreturn`n, % ifil
}
FileAppend, `;::`ng99d()`nsend`, ```;`nreturn`n, % ifil
FileAppend, `,::`ng99d()`nsend`, ```,`nreturn`n, % ifil
FileAppend, `.::`ng99d()`nsend`, ```.`nreturn`n, % ifil
FileAppend, space::`ng99d()`nsend`, {space}`nreturn`n, % ifil
FileAppend, enter::`ng99d()`nsend`, {enter}`nreturn`n, % ifil
FileAppend, m::`ng99d()`nsend`, m`nreturn`n, % ifil
FileAppend, n::`ng99d()`nsend`, n`nreturn`n, % ifil
FileAppend, `, & `.::`ngosub`, ToggleDefSpace`nreturn`n, % ifil
FileAppend, #IfWinExist`n`n, % ifil
FileAppend,
(
g99c()
{
gui, 99:add, Text, ,
gui, 99:show, hide, hidden99
}
g99d()
{
gui, 99:destroy
}
ToggleDefSpace:
if (DefSpace=" ")
DefSpace=
else
DefSpace:= a_space
return
), % ifil
FileAppend,
(
AddToMatchListMod(position,value)
{
global
Local prefix
IfGreater, position, 20
{
prefix =
} else {
pickletters = %cs%
IfLessOrEqual, position, 10
prefix := Mod(position,10) . substr(pickletters
,Mod(position,20), 1) . ". "
else
prefix := " " . substr(pickletters
,Mod(position,20), 1) . ". "
}
IfEqual, ArrowKeyMethod, Off
{
match .= prefix . value . "``n"
} else {
IfEqual, MatchPos, `%Position`%
{
match .= ">" . prefix . value . "``n"
} Else {
match .= " " . prefix . value . "``n"
}
}
}
), % ifil
FileAppend,
(
SpecialStringCheck(byref sending)
{
global
IfInString, sending, ```;
{
sending2 := SubStr(sending, InStr(sending, ";", False ,0)+1)
sending := sending2
}
IfInString, sending, ..
{
;sending2 := SubStr(sending, 1, InStr(sending, "..", False ,0)) . "``n"
sending2 := SubStr(sending, 3)
sending := sending2
;Return
}
IfInString, sending, |
{
;sending2 := SubStr(sending, 1, InStr(sending, "|", False ,0)-1) . "``n"
StringReplace, sending2, sending, |, ``n, All
AddSpace =
sending := sending2
Return
}
sending2 := sending
}
), % ifil
FileAppend,
(
Esc::ExitApp
^!r::Reload
), % ifil
FileAppend, ; this will be SendFullMod(x,y)
(
SendFullMod(SendValue,BackSpaceLen)
{
global SendMethod, addSpace, DefSpace
global A_id
SpecialStringCheck(SendValue)
StringLeft, hkFirstChar, a_thishotkey, 1
`; override | as last character sending NewLine before punctuation
punc:="`;,."
stringright, stringlastchar, SendValue, 1
ifinstring, punc, `%hkFirstChar`%
{
stringright, stringlastchar, SendValue, 1
if (stringlastchar="``n") {
stringtrimright, sendvalue, sendvalue, 1
LastAdd = ``n
}
}
if (hkFirstChar = ".") or (hkFirstChar = ",") or (hkFirstChar = ";")
FirstAdd := hkFirstChar
if (hkFirstChar = "s" ) or (hkFirstChar = "$" )
sleep, 1
; space allows default - space
;sending = {Shift Up}{Shift Down}{Shift Up}{BS `%BackSpaceLen`%}{Raw}`%SendValue`%
if (hkFirstChar = "e" ) or (hkFirstChar = "m")
{
AddSpace=
LastAdd = ``n
}
if (hkFirstChar = "n" )
AddSpace=
sending = {Shift Up}{Shift Down}{Shift Up}{BS `%BackSpaceLen`%}{Raw}`%SendValue`%`%FirstAdd`%`%LastAdd`%`%AddSpace`%
AddSpace := DefSpace
IfEqual, SendMethod, 1
{
; Shift key hits are here to account for an occassional bug which misses the first keys in SendPlay
`; sending is previously assigned sending = {Shift Up}{Shift Down}{Shift Up}{BS `%BackSpaceLen`%}{Raw}`%SendValue`%
SendPlay, `%sending`% ; First do the backspaces, Then send word (Raw because we want the string exactly as in wordlist.txt)
Return
}
`; don't know yet how to integrate these sending = {BS `%BackSpaceLen`%}{Raw}`%SendValue`%
IfEqual, SendMethod, 2
{
SendInput, `%sending`% ; First do the backspaces, Then send word (Raw because we want the string exactly as in wordlist.txt)
Return
}
IfEqual, SendMethod, 3
{
SendEvent, `%sending`% ; First do the backspaces, Then send word (Raw because we want the string exactly as in wordlist.txt)
Return
}
ClipboardSave := ClipboardAll
Clipboard =
Clipboard := SendValue
ClipWait, 0
sending = {BS `%BackSpaceLen`%}^v
IfEqual, SendMethod, 1C
{
sending := "{Shift Up}{Shift Down}{Shift Up}" . sending
SendPlay, `%sending`% ; First do the backspaces, Then send word via clipboard
} else {
IfEqual, SendMethod, 2C
{
SendInput, `%sending`% ; First do the backspaces, Then send word via clipboard
} else {
IfEqual, SendMethod, 3C
{
SendEvent, `%sending`% ; First do the backspaces, Then send word via clipboard
} Else {
sending = {BS `%BackSpaceLen`%}{Ctrl Down}v{Ctrl Up}
ControlGetFocus, ActiveControl, ahk_id `%A_id`%
IfNotEqual, ActiveControl,
ControlSend, `%ActiveControl`%, `%sending`%, ahk_id `%A_id`%
}
}
}
Clipboard := ClipboardSave
Return
}
), % ifil
IfNotExist, wordlist.mod.txt
{
contents=
(
..Two periods are automatically eliminated.
..This means you can put in choices (menus, if you will)
..Based on plain text
..This is fun|For girls and boys|Of all ages|
..Try ;Hey Hey AutoHotKey is the Greatest
..TryThis ;He ain't heavy|He's my brother|He is heavy!|
[heay
[heab
[heck
/headaches headachier ;hi there
h;e is here
h;h-triggered words ;Starting with this little gem
He is a nut.
He is a filbert.
He is a pecan.
He is a peanut.
He is a nut.
He is a peanut.
He is a nut.
He is a nut|
He is a nut, a nutty nut|
He is a nutcase.
abaci
aback
abacus
abacuses
abaft
abalone
abalones
abandon
abandoned
abandonedly
abandonee
abandoner
abandoners
abandoning
abandonment
abandonments
abandons
abase
abased
abasedly
abasement
abaser
abasers
abases
abash
abashed
abashedly
abashes
abashing
abashment
abashments
abasing
abatable
abate
abated
abatement
abatements
abater
abaters
abates
abating
abatis
abatises
abator
abattoir
abattoirs
abbacies
abbacy
abbatial
abbe ;A semicolon is interpreted as: don't type what goes before.
abbes ;Is it the first semicolon; or the last semicolon.
;LEARNEDWORDS;
)
FileAppend, %contents%, wordlist.mod.txt
}
IfNotExist, Preferences.mod.ini
{
contents=
(
[IncludePrograms]
IncludeProgramExecutables=
IncludeProgramTitles=
ExcludeProgramExecutables=
ExcludeProgramTitles=
;
[Settings]
Length=2
NumPresses=1
ToolTipOffset=14
ToolTipLineHeight=13
LearnMode=Off
LearnCount=5
LearnLength=5
ArrowKeyMethod=First
DisabledAutoCompleteKeys=
DetectMouseClickMove=On
SendMethod=1
MaxMatches=20
TerminatingCharacters={enter}{space}{bs}{esc}{tab}{Home}{End}{PgUp}{PdDn}{Up}{Dn}{Left}{Right}???!()$
ForceNewWordCharacters=
;
;
[HelperWindow]
HelperWindowProgramExecutables=
HelperWindowProgramTitles=
XY=200,277
)
FileAppend, %contents%, Preferences.mod.ini
}
MsgBox,,, You have modified TypingAid`nAnd Now %rfile% will be loaded`nEscape will exit it, 2
run % rfile
ExitApp
The Hotkey command would be a much more straightforward way to activate or deactivate the custom hotkey combinations, thanks for pointing that out.
As far as your thoughts about the SpecialStringCheck() function, I understand. I tend to get carried away with possibilities, and keeping your script focused on single word completion WILL keep your script focused. That's something I'm not too good at.
Multiword and paragraph entry may better be the province of scripts like Kollektor++.
Anyway, I hope you'll consider custom hotkey combinations as an option, if you think it adds some ease-of-use for some people. I understand that it may be low priority or omitted. And I really appreciate how much work and thought you and your contributors have put into this script.