hugov wrote:
Looks nice
two comments + one feature
a) it doesn't seem to run the first time but does the second, probably because it doesn't read the INI?
b) the up/down is nice

but I liked my version slightly better for two reason b1: I could cycle through the list b2: when I pressed UP the first time it jumped to the last item in the list which would be the fastest way the select the last item in the list (apart from pressing 0)
New feature suggestion

Because the up/down arrow solves the problem of getting number 13 for example you can increase the number of items shown above 10, the only adaptation needed would be
- configurable number of items
- stop adding digits after first 10 :
Quote:
1 abalone
2 abalones
3 abandon
4 abandoned
5 abandonedly
6 abandonee
7 abandoner
8 abandoners
9 abandoning
0 abandonment
abandonments
abandons
abashedly
abashing
If you'd do that the UP to go to the LAST item would make sense

I'm I driving you insane yet

a. Fixed, I forgot to default the LearnMode option if none is used yet
b. Oops! I forgot to mention, PageUp/PageDn work in the list. PgDn brings you to the end and vice-versa. I decided to not use Home/End as those keys are too necessary when programming.
If you still think it should wrap, let me know. I emulated SciTE4AutoHotkey's autocomplete functionality.
Good idea on increasing the number of words, I'll look into that. It should still be limited for performance (tooltip draw) reasons but maybe I could make it a parameter.
Thanks for all the advice
edit:
OK, max items is now 20, min is 10. Defined via MaxMatches parameter in INI file. I tried 30 but got too much slowdown when drawing the tooltip.
Hitting PgUp will bring you up 10 items, stopping at the first.
Hitting PgDn will bring you down 10 items, stopping at the last.
Hitting Up on the first item will bring you to the last item.
Hitting Down in the last item will bring you to the first item.
Let me know what you think.
Code:
; TypingAid
; Press 1 to 0 keys to autocomplete the word upon suggestion
; Or use the Up/Down keys to select an item
; (0 will match suggestion 10)
; Credits:
; -Jordi S
; -Maniac
; -hugov
; -kakarukeys
; -Asaptrad
;___________________________________________
; Press 1 to 0 keys to autocomplete the word upon suggestion
;___________________________________________
; CONFIGURATIONS
#NoEnv
SetBatchLines, 20ms
ListLines Off
OnExit, SaveScript
;read in the preferences file
ReadPreferences()
;setup code
clearword=1
MouseX = 0
MouseY = 0
Helper_id =
CoordMode, Mouse, Relative
CoordMode, ToolTip, Relative
AutoTrim, Off
SetTimer, Winchanged, 100
;mark the wordlist as not done
WordListDone = 0
;reads list of words from file
FileRead, ParseWords, %A_ScriptDir%\Wordlist.txt
Loop, Parse, ParseWords, `n, `r
{
AddWordToList(A_LoopField,0)
}
ParseWords =
;reverse the numbers of the word counts in memory
GoSub, ReverseWordNums
;mark the wordlist as completed
WordlistDone = 1
Loop
{
;Editor window check
WinGetActiveTitle, ATitle
WinGet, A_id, ID, %ATitle%
IfNotInString, ATitle, %ETitle%
{
ToolTip
Word=
WinWaitActive, %ETitle%
ATitle =
Continue
}
ATitle =
;Get one key at a time
Input, chr, L1 V, %TerminatingCharacters%
EndKey = %errorlevel%
; If active window has different window ID from before the input, blank word
; (well, assign the number pressed to the word)
WinGet, A_id2, ID, A
IfNotEqual, A_id, %A_id2%
{
Gosub,clearallvars
Word = %chr%
Continue
}
ifequal, OldCaretY,
OldCaretY := HCaretY()
if ( OldCaretY != HCaretY() )
{
; add the word if switching lines
AddWordToList(Word,0)
Gosub,clearallvars
Word = %chr%
Continue
}
OldCaretY := HCaretY()
;Backspace clears last letter
ifequal, EndKey, Endkey:BackSpace
{
StringLen, len, Word
IfNotEqual, len, 0
{
ifequal, len, 1
{
Gosub,clearallvars
} else {
StringTrimRight, Word, Word, 1
}
}
} else ifequal, EndKey, Max
{
if chr in %ForceNewWordCharacters%
{
AddWordToList(Word,0)
Gosub, clearallvars
Word = %chr%
Continue
} else {
Word .= chr
}
} else {
AddWordToList(Word,0)
Gosub, clearallvars
}
;Wait till minimum letters
IF ( StrLen(Word) < wlen )
{
ToolTip,
Continue
}
IfNotEqual, MatchPos,
{
IfEqual, ArrowKeyMethod, LastWord
{
OldMatch := singlematch%MatchPos%
} else {
IfEqual, ArrowKeyMethod, LastPosition
{
OldMatch = %MatchPos%
} else {
OldMatch =
}
}
} else {
OldMatch =
}
;Match part-word with command
Num =
number = 0
StringLeft, baseword, Word, %wlen%
baseword := ConvertWordToAscii(baseword,1)
Loop
{
IfEqual, zword%baseword%%a_index%,, Break
IfEqual, number, %MaxMatches%
Break
if ( SubStr(zword%baseword%%a_index%, 1, StrLen(Word)) = Word )
{
number ++
singlematch := zword%baseword%%a_index%
singlematch%number% = %singlematch%
Continue
}
}
;If no match then clear Tip
IfEqual, number, 0
{
clearword=0
Gosub,clearallvars
Continue
}
IfEqual, OldMatch,
{
IfEqual, ArrowKeyMethod, Off
{
MatchPos =
} else {
MatchPos = 1
}
} Else {
IfEqual, ArrowKeyMethod, Off
{
MatchPos =
} else {
IfEqual, ArrowKeyMethod, LastPosition
{
IfGreater, OldMatch, %Number%
{
MatchPos = %Number%
} else {
MatchPos = %OldMatch%
}
} else {
IfEqual, ArrowKeyMethod, LastWord
{
Pos =
Loop, %Number%
{
if ( OldMatch == singlematch%A_Index% )
{
Pos = %A_Index%
Break
}
}
IfEqual, pos,
{
MatchPos = 1
} Else {
MatchPos = %Pos%
}
} else {
MatchPos = 1
}
}
}
}
OldMatch =
RebuildMatchList()
ShowToolTip()
}
RebuildMatchList()
{
global
match =
Loop, %Number%
{
AddToMatchList(A_Index,singlematch%A_Index%)
}
StringTrimRight, match, match, 1 ; Get rid of the last linefeed
Return
}
AddToMatchList(position,value)
{
global
Local prefix
IfGreater, position, 10
{
prefix =
} else {
prefix := Mod(position,10) . ". "
}
IfEqual, ArrowKeyMethod, Off
{
match .= prefix . value . "`n"
} else {
IfEqual, MatchPos, %Position%
{
match .= ">" . prefix . value . "`n"
} Else {
match .= " " . prefix . value . "`n"
}
}
}
;Show matched values
ShowToolTip()
{
global ToolTipOffset
global Word
global Match
WinGetPos, , PosY, , SizeY, A
ToolTipSizeY := (number * 12)
ToolTipPosY := HCaretY()+ToolTipOffset
; + ToolTipOffset Move tooltip down a little so as not to hide the caret.
if ((ToolTipSizeY + ToolTipPosY) > (PosY + SizeY))
ToolTipPosY := (HCaretY() - ToolTipOffset - ToolTipSizeY)
IfNotEqual, Word,
ToolTip, %match%, HCaretX(), %ToolTipPosY%
}
; Timed function to detect change of focus (and remove tooltip when changing active window)
Winchanged:
WinGetActiveTitle, ATitle
WinGet, A_id3, ID, %ATitle%
IfNotEqual, A_id, %A_id3%
{
ToolTip ,
} else {
; If we are in the correct window, and OldCaretY is set, clear the tooltip if not in the same line
IfInString, ATitle, %ETitle%
{
IfNotEqual, OldCaretY,
{
if ( OldCaretY != HCaretY() )
{
ToolTip,
}
}
}
}
ATitle =
A_Id3 =
Return
; Update last click position in case Caret is not detectable
~LButton::
MouseGetPos, MouseX, MouseY
Return
; Key definitions for autocomplete (0 to 9)
#MaxThreadsPerHotkey 1
$1::
$2::
$3::
$4::
$5::
$6::
$7::
$8::
$9::
$0::
CheckWord(A_ThisHotkey)
Return
$^Enter::
$^Space::
$Tab::
$Up::
$Down::
$PgUp::
$PgDn::
EvaluateUpDown(A_ThisHotKey)
Return
^+h::
CreateHelperWindow()
Return
^+c::
AddSelectedWordToList()
Return
; If hotkey was pressed, check wether there's a match going on and send it, otherwise send the number(s) typed
CheckWord(Key)
{
global
Local ATitle
Local A_id2
Local WordIndex
Local KeyAgain
StringRight, Key, Key, 1 ;Grab just the number pushed, trim off the "$"
IfEqual, Key, 0
{
WordIndex = 10
} else {
WordIndex = %Key%
}
clearword=1
IfEqual, NumPresses, 2
Suspend, On
; If active window has different window ID from before the input, blank word
; (well, assign the number pressed to the word)
if ( ReturnWinActive() = )
{
SendInput,%key%
Gosub,clearallvars
IfEqual, NumPresses, 2
Suspend, Off
Return
}
if ReturnLineWrong() ;Make sure we are still on the same line
{
SendInput,%key%
Gosub,clearallvars
IfEqual, NumPresses, 2
Suspend, Off
Return
}
ifequal, Word, ; only continue if word is not empty
{
SendInput,%key%
Word = %key%
clearword=0
Gosub,clearallvars
IfEqual, NumPresses, 2
Suspend, Off
Return
}
ifequal, singlematch%WordIndex%, ; only continue singlematch is not empty
{
SendInput,%key%
Word .= key
clearword=0
Gosub,clearallvars
IfEqual, NumPresses, 2
Suspend, Off
Return
}
IfEqual, NumPresses, 2
{
Input, keyagain, L1 I T0.5, 1234567890
; If there is a timeout, abort replacement, send key and return
IfEqual, ErrorLevel, Timeout
{
SendInput, %key%
Word .= key
clearword=0
Gosub,clearallvars
Suspend, off
Return
}
; Make sure it's an EndKey, otherwise abort replacement, send key and return
IfNotInString, ErrorLevel, EndKey:
{
SendInput, %key%%keyagain%
Word .= key . keyagain
clearword=0
Gosub, clearallvars
Suspend, off
Return
}
; If the 2nd key is NOT the same 1st trigger key, abort replacement and send keys
IfNotInString, ErrorLevel, %key%
{
StringTrimLeft, keyagain, ErrorLevel, 7
SendInput, %key%%keyagain%
Word .= key . keyagain
clearword=0
Gosub, clearallvars
Suspend, Off
Return
}
}
SendWord(WordIndex)
IfEqual, NumPresses, 2
Suspend, Off
Return
}
SendWord(WordIndex)
{
global
Local sending
Local len
;Local ClipboardSave
;Send the word
sending := singlematch%WordIndex%
StringLen, len, Word
; Update Typed Count
UpdateWordCount(sending,0)
SendPlay, {BS %len%}{Raw}%sending% ; First do the backspaces, Then send word (Raw because we want the string exactly as in wordlist.txt)
; below works but uses clipboard
;ClipboardSave:=ClipboardAll
;Clipboard = %sending%
;SendPlay, {BS %len%}^v ; First do the backspaces, Then send word (Raw because we want the string exactly as in wordlist.txt)
;Clipboard = %ClipboardSave%
Gosub clearallvars
Return
}
;If a hotkey related to the up/down arrows was pressed
EvaluateUpDown(Key)
{
global
IfEqual, ArrowKeyMethod, Off
{
SendKey(Key)
Return
}
IfEqual, Match,
{
SendKey(Key)
Return
}
if ( ReturnWinActive() = )
{
SendKey(Key)
Gosub, ClearAllVars
Return
}
if ReturnLineWrong()
{
SendKey(Key)
GoSub, ClearAllVars
Return
}
IfEqual, Word, ; only continue if word is not empty
{
SendKey(Key)
ClearWord = 0
GoSub, ClearAllVars
Return
}
if ( ( Key = "$^Enter" ) || ( Key = "$Tab" ) || ( Key = "$^Space" ) )
{
IfEqual, singlematch%MatchPos%, ;only continue if singlematch is not empty
{
SendKey(Key)
MatchPos = %Number%
RebuildMatchList()
ShowToolTip()
Return
}
SendWord(MatchPos)
Return
}
IfEqual, Key, $Up
{
MatchPos--
} else {
IfEqual, Key, $Down
{
MatchPos++
} else {
IfEqual, Key, $PgUp
{
MatchPos-=10
IfLess, MatchPos, 1
MatchPos = 1
} else {
IfEqual, Key, $PgDn
{
MatchPos+=10
IfGreater, MatchPos, %Number%
MatchPos = %Number%
}
}
}
}
IfLess, MatchPos, 1
{
MatchPos = %Number%
} else {
IfGreater, MatchPos, %Number%
{
MatchPos = 1
}
}
RebuildMatchList()
ShowToolTip()
Return
}
SendKey(Key)
{
IfEqual, Key, $^Enter
{
Key = ^{Enter}
} else {
IfEqual, Key, $^Space
{
Key = ^{Space}
} else {
Key := "{" . SubStr(Key, 2) . "}"
}
}
SendInput, %Key%
Return
}
ReturnWinActive()
{
global A_id
WinGet, A_id2, ID, A
Return, ( A_id = A_id2 )
}
ReturnLineWrong()
{
global OldCaretY
Return, ( OldCaretY != HCaretY() )
}
;Create helper window for showing tooltip
CreateHelperWindow()
{
Global Helper_id
Gui, Add, Text,,Tooltip appears here
Gui, Show
WinGet, Helper_id, ID,,Tooltip appears here
WinSet, AlwaysOnTop, On, ahk_id %Helper_id%
return
}
; function to grab the X position of the caret for the tooltip
HCaretX()
{
global MouseX
global Helper_id
WinGetPos, HelperX,,,, ahk_id %Helper_id%
WinGetPos, X,,,, A
if HelperX !=
{
if X !=
{
return HelperX - X
}
}
if A_CaretX < 14
{
if MouseX != 0
{
return MouseX
}
}
return A_CaretX
}
; function to grab the Y position of the caret for the tooltip
HCaretY()
{
global MouseY
global Helper_id
WinGetPos,,HelperY,,, ahk_id %Helper_id%
WinGetPos,, Y,,, A
if HelperY !=
{
if Y !=
{
return HelperY - Y
}
}
if A_CaretX < 14
{
if MouseY != 0
{
return MouseY + 20
}
}
return A_CaretY
}
AddSelectedWordToList()
{
ClipboardSave := ClipboardAll
Clipboard =
Sleep, 100
SendInput, ^c
ClipWait, 0
IfNotEqual, Clipboard,
{
AddWordToList(Clipboard,1)
}
Clipboard = %ClipboardSave%
}
AddWordToList(AddWord,ForceCountNewOnly)
{
;AddWord = Word to add to the list
;ForceCountNewOnly = force this word to be permanently learned even if learnmode is off
global
Local CharTerminateList
Local Base
Local AddWordInList
Local CountWord
Local pos
Local LearnModeTemp
IfEqual, LearnMode, On
{
LearnModeTemp = 1
} else {
IfEqual, ForceCountNewOnly, 1
LearnModeTemp = 1
}
Ifequal, Addword, ;If we have no word to add, skip out.
Return
if ( Substr(addword,1,1) = ";" ) ;If first char is ";", clear word and skip out.
{
IfEqual, LearnMode, On ;Check LearnMode here as we only do this if the wordlist is not done
{
IfEqual, wordlistdone, 0 ;If we are still reading the wordlist file and we come across ;LEARNEDWORDS; set the LearnedWordsCount flag
{
IfEqual, AddWord, `;LEARNEDWORDS`;
LearnedWordsCount=0
}
}
Return
}
IF ( StrLen(addword) <= wlen ) ; don't add the word if it's not longer than the minimum length
{
Return
}
ifequal, wordlistdone, 1
{
IfNotEqual, LearnModeTemp, 1
{
Return
} else {
if addword contains 1,2,3,4,5,6,7,8,9,0,%ForceNewWordCharacters%
Return
}
}
Base := ConvertWordToAscii(SubStr(addword,1,wlen),1)
IfEqual, WordListDone, 0 ;if this is read from the wordlist
{
IfNotEqual,LearnedWordsCount, ;if this is a stored learned word
{
CountWord := ConvertWordToAscii(addword,0)
IfEqual, LearnedWords, ;if we haven't learned any words yet, set the LearnedWords list to the new word
{
LearnedWords = %addword%
} else { ;otherwise append the learned word to the list
LearnedWords .= "," . addword
}
zCount%CountWord% := LearnedWordsCount++ ;increment the count and store the Weight of the LearnedWord in reverse order (will be inverted later)
}
IncrementCounterAndAddWord(Base,AddWord)
} else { ; If this is an on-the-fly learned word
AddWordInList =
Loop ;Check to see if the word is already in the list, case sensitive
{
IfEqual, zword%base%%a_index%,, Break
if ( zword%base%%a_index% == AddWord )
{
AddWordInList = 1
Break
}
Continue
}
IfEqual, AddWordInList, ; if the word is not in the list
{
CountWord := ConvertWordToAscii(addWord,0)
IfEqual, ForceCountNewOnly, 1
{
zCount%CountWord% = 5 ;set the count to 5 so it gets written to the file
} else {
zCount%CountWord% = 1 ;set the count to one as it's the first time we typed it
}
IfEqual, LearnedWords, ;if we haven't learned any words yet, set the LearnedWords list to the new word
{
LearnedWords = %addword%
} else { ;otherwise append the learned word to the list
LearnedWords .= "," . addword
}
IncrementCounterAndAddWord(Base,AddWord)
IfEqual, LearnMode, On
{
IfEqual, ForceCountNewOnly, 1
UpdateWordCount(addword,1) ;resort the necessary words if it's a forced added word
}
} else {
IfEqual, ForceCountNewOnly, 1
{
CountWord := ConvertWordToAscii(addWord,0)
IF ( zCount%CountWord% < 5 )
zCount%CountWord% = 5
UpdateWordCount(addWord,1)Icon
} else {
IfEqual, LearnMode, On
{
UpdateWordCount(addword,0) ;Increment the word count if it's already in the list and we aren't forcing it on
}
}
}
}
Return
}
IncrementCounterAndAddWord(Base,AddWord)
{
global
local pos
; Increment the counter for each hash
zbasenum%Base%++
pos := zbasenum%Base%
; Set the hashed value to the word
zword%Base%%pos% = %addword%
}
; This sub will reverse the read numbers since now we know the total number of words
ReverseWordNums:
LearnedWordsCount+=4
Loop,parse,LearnedWords, `,
{
AsciiWord := ConvertWordToAscii(A_LoopField,0)
zCount%AsciiWord% := LearnedWordsCount - zCount%AsciiWord%
}
AsciiWord =
LearnedWordsCount =
Return
UpdateWordCount(word,SortOnly)
{
;Word = Word to increment count for
;SortOnly = Only sort the words, don't increment the count
; If the Count for the word already exists - ie if it's a learned word, increment it, else don't.
local CountWord := ConvertWordToAscii(word,0)
IfNotEqual, zCount%CountWord%,
{
IfNotEqual, SortOnly, 1 ;don't increment the count if we only want to sort the words
zCount%CountWord%++
local WordBase
StringLeft, WordBase, word, %wlen% ;find the pseudohash for the word
WordBase := ConvertWordToAscii(WordBase,1)
Local ConvertWord =
Local LowIndex =
Local WordList =
Loop
{
ifequal, zword%WordBase%%A_Index%, ;Break the loop if no more words to read for the hash
Break
CountWord := zword%WordBase%%A_Index% ;Set CountWord to the current Word position
ConvertWord := ConvertWordToAscii(CountWord,0) ; Find the Ascii equivalent of the word
IfNotEqual, zCount%ConvertWord%, ;If there's no count for this word do nothing
{
IfEqual, LowIndex,
LowIndex = %A_Index% ;If this is the first word we've found with a count set this as our starting position
WordList .= "," . zCount%ConvertWord% . "z" . CountWord ;prefix all words with (zCount"z")
}
}
ifnotequal, Wordlist, ;If we have no words to process, don't
{
StringTrimLeft, WordList, WordList, 1
Sort, WordList, N R D, ;Sort the wordlist by order of
LowIndex-- ;A_Index starts at 1 so this value needs to be decremented
Local IndexPos =
Loop, Parse, WordList, `,
{
IndexPos := LowIndex + A_Index ;Set the current word we are processing to the starting pos plus word position
StringTrimLeft, CountWord, A_LoopField, InStr(A_LoopField,"z") ;Strip (Number,"z") from beginning
zword%WordBase%%IndexPos% = %CountWord% ; update the word in the list
}
}
}
Return
}
ConvertWordToAscii(Base,Caps)
{
; Return the word in Ascii numbers padded to length 3 per character
; Capitalize the string if NoCaps is not set
IfEqual, Caps, 1
StringUpper, Base, Base
Loop, Parse, Base
{
New .= SubStr("00" . Asc(A_LoopField),-2)
}
Return New
}
; This is to blank all vars related to matches, tooltip and (optionally) word
clearallvars:
Ifequal,clearword,1
{
word =
OldCaretY=
}
ToolTip
; Clear all singlematches
Loop, 10
{
singlematch%a_index% =
}
sending =
key=
match=
MatchPos=
clearword=1
Return
ReadPreferences()
{
global
Local Prefs
Local INI
Prefs = %A_ScriptDir%\Preferences.ini
DftTerminatingCharacters = {enter}{space}{bs}{esc}{tab}{Home}{End}{PgUp}{PgDn}{Up}{Down}{Left}{Right}.;`,¿?¡!'"()]{}{}}{{}:
If FileExist(Prefs)
{
IniRead, ETitle, %Prefs%, Settings, Title, %A_Space%
IniRead, TerminatingCharacters, %Prefs%, Settings, TerminatingCharacters, %DftTerminatingCharacters%
IniRead, ForceNewWordCharacters, %Prefs%, Settings, ForceNewWordCharacters, %A_Space%
IniRead, Wlen, %Prefs%, Settings, Length, 3
IniRead, NumPresses, %Prefs%, Settings, NumPresses, 1
IniRead, LearnMode, %Prefs%, Settings, LearnMode, Off
IniRead, ToolTipOffset, %Prefs%, Settings, ToolTipOffset, 14
IniRead, ArrowKeyMethod, %Prefs%, Settings, ArrowKeyMethod, First
IniRead, MaxMatches, %Prefs%, Settings, MaxMatches, 10
} else {
INI=
(
;Title is a string of text to find in the title of the window you want TypingAid enabled for. If you leave
;it blank it will work in all windows.
[Settings]
Title=
;
;TerminatingCharacters is a list of EndKey characters which will signal the script that you are done typing a word.
;A list of keys may be found here:
; http://www.autohotkey.com/docs/KeyList.htm
;Certain characters (such as `% or , ) require an escape character in front, see here:
; http://www.autohotkey.com/docs/commands/_EscapeChar.htm
;For more detail on how to format the list of characters please see the EndKeys section (paragraphs 2,3,4) of:
; http://www.autohotkey.com/docs/commands/Input.htm
TerminatingCharacters={enter}{space}{bs}{esc}{tab}{Home}{End}{PgUp}{PgDn}{Up}{Down}{Left}{Right}.;`,:¿?¡!'"()]{}{}}{{}
;
;ForceNewWordCharacters is a comma separated list of characters which force the script to start a new word whenever
;one of those characters is typed. Any words which begin with one of these characters will never be learned (even
;if learning is enabled). If you were typing a word when you hit one of these characters that word will be learned
;if learning is enabled.
ForceNewWordCharacters=
;
;Length is the minimum number of characters required to show the list of words. The higher this number the better performance will be.
Length=3
;
;NumPresses is the number of times the hotkey must be pushed for the word to be selected, either 1 or 2.
NumPresses=1
;
;LearnMode defines whether or not the script should learn new words as you type them, either On or Off
LearnMode=On
;
;ToolTipOffset is the number of pixels below the top of the Caret (Cursor) to display the tooltip
ToolTipOffset=14
;
;ArrowKeyMethod is the way the arrow keys are handled in the drop down. Off means you can only use the number keys
;First resets the selected word to the beginning whenever you type a new character
;LastWord keeps the last word selected if still in the last, else resets to the beginning
;LastPosition keeps the last cursor position
ArrowKeyMethod=First
;
;MaxMatches is the number of words to show in the dropdown. Valid range is from 10 to 20. If ArrowKeyMethod=Off
;this will be forced to 10
MaxMatches=10
)
FileAppend, %INI%, %Prefs%
}
IfEqual, TerminatingCharacters,
TerminatingCharacters = DftTerminatingCharacters
IfEqual, Wlen,
Wlen = 3
IfEqual, NumPresses,
NumPresses = 1
IfEqual, LearnMode,
LearnMode = Off
IfEqual, ToolTipOffset,
ToolTipOffset = 14
IfEqual, ArrowKeyMethod,
{
ArrowKeyMethod = First
} else {
IfEqual, ArrowKeyMethod, Off ;force MaxMatches to 10 if we aren't using arrow keys
MaxMatches=10
}
IfLess, MaxMatches, 10
{
MaxMatches=10
} else {
IfGreater, MaxMatches, 20
MaxMatches = 20
}
Return
}
SaveScript:
; Close the tooltip if it's open
ToolTip,
IfNotEqual, LearnedWords,
{
; Add all the standard words to the tempwordlist
FileRead, ParseWords, %A_ScriptDir%\Wordlist.txt
IfEqual, LearnMode, On
{
LearnedwordsPos := InStr(ParseWords, "`;LEARNEDWORDS`;",true,1) ;Check for Learned Words
} else {
LearnedwordsPos = 0 ;force all words to be re-written if we aren't learning
}
IfNotEqual, LearnedwordsPos, 0
{
TempWordList := SubStr(ParseWords, 1, LearnedwordsPos - 1) ;Grab all non-learned words out of list
} else {
TempWordList := ParseWords
}
ParseWords =
; Parse the learned words and store them in a new list by count if their total count is greater than 5.
; Prefix the word with the count and "z" for sorting
Loop, Parse, LearnedWords, `,
{
SortWord := ConvertWordToAscii(A_LoopField,0)
IfGreaterOrEqual, zCount%SortWord%, 5
{
SortWordList .= "," . zCount%SortWord% . "z" . A_LoopField
}
}
StringTrimLeft, SortWordList, SortWordList, 1 ;remove extra starting comma
Sort, SortWordList, N R D, ; Sort numerically, comma delimiter
IfNotEqual, SortWordList, ; If SortWordList exists write to the file, otherwise don't.
{
Loop
{
StringRight, LastChar, TempWordList, 1
IF ( ( LastChar = "`r") || ( LastChar = "`n" ) )
{
StringTrimRight, TempWordList, TempWordList, 1
} else {
Break
}
}
IfEqual, LearnMode, On
TempWordList .= "`r`n`;LEARNEDWORDS`;" ;only append ;LEARNEDWORDS; if we are in learning mode
Loop, Parse, SortWordList, `,
{
StringTrimLeft, AppendWord, A_LoopField, InStr(A_LoopField,"z") ;Strip (Number,"z") from beginning
TempWordList .= "`r`n" . AppendWord
}
FileDelete, %A_ScriptDir%\Temp_Wordlist.txt
FileAppend, %TempWordList%, %A_ScriptDir%\Temp_Wordlist.txt ;Only update the file if we have learned words
FileCopy, %A_ScriptDir%\Temp_Wordlist.txt, %A_ScriptDir%\Wordlist.txt, 1
FileDelete, %A_ScriptDir%\Temp_Wordlist.txt
}
}
ExitApp