AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Intellisense-like autoreplacement with multiple suggestions
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
SoLong&Thx4AllTheFish



Joined: 27 May 2007
Posts: 4999

PostPosted: Sat Jan 16, 2010 1:57 pm    Post subject: Reply with quote

To follow up on the post above a very quick & dirty hack just to see it if works (can't test atm)

- take the latest script posted above
- look at line 264 or so where the sendplay line is (blue) and insert the red one above
Code:
Sending:=SubStr(Sending, InStr(Sending, "|") - 1)
SendPlay, {BS %len%}{Raw}%sending% ; First do the backspaces, Then send word (Raw because we want the string exactly as in wordlist.txt)

- now create a wordlist.txt with the words like so
Quote:
abdomen|Xray Abdomen
abdomen|Ultrasound Abdomen
e.g. typeword, actual words after a |

Edit1+2: typos in code above said substring which should have been substr and of course should substring from | char not until the | char Embarassed
_________________
AHK Wiki FAQ
TF : Text files & strings lib, TF Forum


Last edited by SoLong&Thx4AllTheFish on Sat Jan 16, 2010 2:29 pm; edited 3 times in total
Back to top
View user's profile Send private message
kakarukeys



Joined: 28 Sep 2009
Posts: 86

PostPosted: Sat Jan 16, 2010 2:10 pm    Post subject: Reply with quote

Very Happy I'm waiting for some more details from him, before suggesting a tweak.

I'm not sure what his software does: autocompletion as in TypingAid? or handles database query and returns information about the medical terms (in which case the listbox you just showed is more suitable)

Any here's my tweak (idea only):

put
"Abdomen<CT >"
in wordlist.txt

During Sendinput, the program should send ^{LEFT} for < and ^{RIGHT} for >. Yours is more reliable.
_________________
TypingAid autocompletion program made with AHK.
Back to top
View user's profile Send private message
stressbaby



Joined: 17 Aug 2009
Posts: 131

PostPosted: Sat Jan 16, 2010 2:59 pm    Post subject: Reply with quote

Many thanks, guys.

In the program, the lab or xray order is entered in one module, and then once completed, the report is returned through another module. Now there is a set of order names, and if the completed report is put back into the EMR with an EXACT MATCH of the order name, it will mark it as completed. However, if the names don't match exactly, the order will not get marked as completed. (There is a .fl cross reference file, but there is no way to get all of the different spelling variations into the cross reference file). So anyway, "CT Abdomen" won't be marked as completed if the staff titles it "CT Adbomen" or "CAT SCAT Abdomen" or whatever.

Now I can query the EMR order name table using ODBC drivers and generate Wordlist.txt or Collection.txt and I expect there might end up being 300-500 different order names in the end...but not that many. There is no need to query the table every time, just once to write the .txt file. Ideally, this script would trigger when the staff is entering the results back into the system. When they start typing in that particular text box, the script will filter the list and direct them to an exact title match.

Kollektor by Boskoop is pretty close. I would want to remove the "Delete List" button! I'm going to the office today to try this out on the actual module. Written in German...oh boy...

Kakarukeys, at first glance, the tweak you suggest probably won't work because Abdomen<CT> would have to be added to the Wordlist.txt file and as I said, I'm going to try to generate that automatically from the table of order names using the ODBC drivers. If I'm able to do that, then I can share out the program to other users and they can generate their own Wordlist.txt that matches their own list of order names.

I welcome other suggestions, but I want to thank hugov and kakarukeys for their help already.
Back to top
View user's profile Send private message
SoLong&Thx4AllTheFish



Joined: 27 May 2007
Posts: 4999

PostPosted: Sat Jan 16, 2010 3:38 pm    Post subject: Reply with quote

@stressbaby if you need help with the kollektor script feel free to PM me I've been studying that script for ages to figure out how it worked, it was the script that got me interested in AHK in the first place (autoit 2 user for many years before that)
_________________
AHK Wiki FAQ
TF : Text files & strings lib, TF Forum
Back to top
View user's profile Send private message
stressbaby



Joined: 17 Aug 2009
Posts: 131

PostPosted: Sat Jan 16, 2010 7:11 pm    Post subject: Thanks Reply with quote

We're OT here, but a quick thanks to kakurakeys and hugov. The Kollektor actually worked just as I had hoped. I appreciate your replies.
Back to top
View user's profile Send private message
maniac



Joined: 28 Aug 2009
Posts: 267

PostPosted: Tue Jan 19, 2010 8:06 pm    Post subject: Reply with quote

OK, first phase of my consolidation is done. I have completely merged the 2 separate versions I've been maintaining into one file and parameterized them via a Preferences.ini file. We can add gui support for the preferences later if we want.

Next step is to merge in KakaruKeys' changes, add in more parameters, and add in support for a 2 press version.

Let me know if you have any comments/suggestions so far.

Code:
;  Intellitype: typing aid
;  Press 1 to 0 keys to autocomplete the word upon suggestion
;  (0 will match suggestion 10)
;                                  - Jordi S
;                               Heavily modified by:
;                               Maniac
;___________________________________________

; Press 1 to 0 keys to autocomplete the word upon suggestion
; (0 will match suggestion 10)
;_______________________________________

;    CONFIGURATIONS

#NoEnv
SetBatchLines, 20ms
ListLines Off

OnExit, SaveScript

;read in the preferences file
ReadPreferences()

ListVars
Pause

;setup code
keyagain=
key=
clearword=1

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)
}
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
      Setenv, Word,
      WinWaitActive, %ETitle%
      Continue
    }   
   
   ;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)   
   WinGetActiveTitle, ATitle
   WinGet, A_id2, ID, %ATitle%
   IfNotEqual, A_id, %A_id2%
   {
      Gosub,clearallvars
      Setenv, Word, %chr%
      Continue
   }
   
   ifequal, OldCaretY,
        OldCaretY = %A_CaretY%
   ifnotequal, OldCaretY, %A_CaretY%
   {
      ; add the word if switching lines
      AddWordToList(Word)
      Gosub,clearallvars
      Setenv, Word, %chr%
      Continue         
   }

   OldCaretY=%A_CaretY%
   
      ;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)
               Gosub, clearallvars
               Setenv, Word, %chr%
               Continue
            } else {
                     Setenv, Word, %word%%chr%
                  }
         } else {
                  AddWordToList(Word)
                  Gosub, clearallvars     
                }
   
   ;Wait till minimum letters
   IF ( StrLen(Word) < wlen )
   {
      ToolTip,
      Continue
   }
   
   ;Match part-word with command
   Num =
   Match =
   singlematch = 0
   number = 0
   StringLeft, baseword, Word, %wlen%
   baseword := ConvertWordToAscii(baseword,1)
   Loop
   {
      IfEqual, zword%baseword%%a_index%,, Break
      IfEqual, number, 10
         Break
      if ( SubStr(zword%baseword%%a_index%, 1, StrLen(Word)) = Word )
      {
         number ++
         singlematch := zword%baseword%%a_index%
         match .= Mod(number,10) . ". " . singlematch . "`n"
         singlematch%number% = %singlematch%
           
         Continue           
      }
   }
   
   ;If no match then clear Tip
   IfEqual, Match,
   {
      clearword=0
      Gosub,clearallvars
      Continue
   }
   
   ;Show matched command
   StringTrimRight, match, match, 1        ; Get rid of the last linefeed
   WinGetActiveTitle, ATitle
   WinGetPos, , PosY, , SizeY, %ATitle%
   ToolTipSizeY := (number * 12)
   ToolTipPosY := A_CaretY+14
   if ((ToolTipSizeY + ToolTipPosY) > (PosY + SizeY))
       ToolTipPosY := (A_CaretY - 14 - ToolTipSizeY)
   IfNotEqual, Word,,ToolTip, %match%, %A_CaretX%, %ToolTipPosY%
   ; +14 Move tooltip down a little so as not to hide the caret.
}

; 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,
               {
                  IfNotEqual, OldCaretY, %A_CaretY%   
                  {
                     ToolTip,
                  }
               }
            }
         }
   Return
   
; Key definitions for autocomplete (0 to 9)
#MaxThreadsPerHotkey 1
$1::
$2::
$3::
$4::
$5::
$6::
$7::
$8::
$9::
$0::
CheckWord(A_ThisHotkey)
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
   
   StringRight, Key, Key, 1 ;Grab just the number pushed, trim off the "$"
   
   IfEqual, Key, 0
   {
      WordIndex = 10
   } else {
            WordIndex = %Key%
         } 
   
   clearword=1

   ; If active window has different window ID from before the input, blank word
   ; (well, assign the number pressed to the word)
   WinGetActiveTitle, ATitle
   WinGet, A_id2, ID, %ATitle%
   IfNotEqual, A_id, %A_id2%
   {
      SendInput,%key%
      Gosub,clearallvars
      Return
   }
     
   IfNotEqual, OldCaretY, %A_CaretY% ;Make sure we are still on the same line
      {
         SendInput,%key%
         Gosub,clearallvars
         Return
      }

   ifequal, Word,        ; only continue if word is not empty
   {
      SendInput,%key%
      Setenv, Word, %key%
      clearword=0
      Gosub,clearallvars
      Return
   }
         
   ifequal, singlematch%WordIndex%,   ; only continue singlematch is not empty
      {
         SendInput,%key%
         Setenv, Word, %word%%key%
         clearword=0
         Gosub,clearallvars
         Return
      }

   Local sending
   Local len
   Local ClipboardSave
   ; SEND THE WORD!
   sending := singlematch%WordIndex%
   StringLen, len, Word
   ; Update Typed Count
   UpdateWordCount(sending)   
   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
}

; This is to blank all vars related to matches, tooltip and (optionally) word
clearallvars:
      Ifequal,clearword,1
      {
         Setenv,word,   
         OldCaretY=
      }
      ToolTip
      ; Clear all singlematches
      Loop, 10
      {
         singlematch%a_index% =
      }
      sending =
      key=
      match=
      clearword=1
      Return

AddWordToList(AddWord)
{
   global
   Local CharTerminateList
   Local Base
   Local AddWordInList
   Local CountWord
   Local pos

   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, wordlistdone, 0 ;If we are still reading the wordlist file and we come across ;LEARNEDWORDS; set the LearnedWordsCount flag
      {
         IfEqual, AddWord, `;LEARNEDWORDS`;
            LearnedWordsCount=0
      }
      addword =
      Return
   }
   
   ifequal, wordlistdone, 1
   {
         if addword contains 1,2,3,4,5,6,7,8,9,0,%ForceNewWordCharacters%
            Return
   }
   IF ( StrLen(addword) <= wlen ) ; don't add the word if it's not longer than the minimum length
   {
      addword =
      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)
               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)
            } else {
                     UpdateWordCount(addword) ;Increment the word count if it's already in the list
                  }
         }
   
   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)
{
; 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%,
   {
      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
}

ReadPreferences()
{
   global ETitle
   global TerminatingCharacters
   global ForceNewWordCharacters
   global Wlen
   FileRead, Settings, %A_ScriptDir%\Preferences.ini   
   Loop, Parse, Settings, `n, `r
   {
      If ( SubStr(A_LoopField,1,1) != ";" )
      {
         StringGetPos, Pos, A_LoopField, =
         StringLeft, Line, A_LoopField, %Pos%
         StringReplace, Line, Line, %A_SPACE%,,All
         StringTrimLeft, Value, A_LoopField, (Pos+1)
         IfEqual, Line, Title
         {
            ETitle = %Value%
            Continue
         }
     
         IfEqual, Line, TerminatingCharacters
         {
            TerminatingCharacters = %Value%
            Continue
         }
   
         IfEqual, Line, ForceNewWordCharacters
         {
            ForceNewWordCharacters = %Value%
            Continue
         }
     
         IfEqual, Line, Length
         {
            Wlen = %Value%
            Continue
         }
      }
   }

   IfEqual, Wlen,
      Wlen = 3
   
   IfEqual, TerminatingCharacters,
      TerminatingCharacters = {enter}{space}{bs}{esc}{tab}{Home}{End}{PgUp}{PgDn}{Up}{Down}{Left}{Right}.;`,:¿?¡!'"()]{}{}}{{}
     
   Return
}
   
SaveScript:
; Close the tooltip if it's open
ToolTip,
; Add all the standard words to the tempwordlist
FileRead, ParseWords, %A_ScriptDir%\Wordlist.txt
LearnedwordsPos := InStr(ParseWords, "`;LEARNEDWORDS`;",true,1) ;Check for Learned Words
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.
{
   TempWordList .= "`;LEARNEDWORDS`;`r`n"
   Loop, Parse, SortWordList, `,
   {
      StringTrimLeft, AppendWord, A_LoopField, InStr(A_LoopField,"z") ;Strip (Number,"z") from beginning
      TempWordList .= AppendWord . "`r`n"
   }
   StringTrimRight, TempWordList, TempWordList, 2
   
   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


Preferences.ini:
Code:
;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.
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
Back to top
View user's profile Send private message
SoLong&Thx4AllTheFish



Joined: 27 May 2007
Posts: 4999

PostPosted: Tue Jan 19, 2010 8:34 pm    Post subject: Reply with quote

May I suggest you brush up your knowledge of the INI format and use the Iniread and write functions of AHK rather then your workaround? Also have the ReadPreferences() create the INI if it doesn't exist yet on the first run using a simple fileappend:

Code:
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
)
IfNotExist, settings.ini
      FileAppend, %INI%, settings.ini

_________________
AHK Wiki FAQ
TF : Text files & strings lib, TF Forum
Back to top
View user's profile Send private message
maniac



Joined: 28 Aug 2009
Posts: 267

PostPosted: Tue Jan 19, 2010 9:50 pm    Post subject: Reply with quote

hugov wrote:
May I suggest you brush up your knowledge of the INI format and use the Iniread and write functions of AHK rather then your workaround? Also have the ReadPreferences() create the INI if it doesn't exist yet on the first run using a simple fileappend:

Oh, there's a standard for the ini format? Didn't even know that... guess it makes sense though Smile. Thanks I'll make the changes to conform to that.
Back to top
View user's profile Send private message
Guest






PostPosted: Wed Jan 20, 2010 2:28 am    Post subject: Reply with quote

Hey guys, does this have arrow up, down feature?
Back to top
kakarukeys



Joined: 28 Sep 2009
Posts: 86

PostPosted: Wed Jan 20, 2010 3:27 am    Post subject: Reply with quote

Great. I'll test it.

Two strange bugs I have been working on:

1. When the script is running, user can't type áéíóú on a Spanish Keyboard (physical keyboard, not keyboard layout).

2. The script can't read from wordlist.txt in Vista 64bit !?

Anonymous wrote:
Hey guys, does this have arrow up, down feature?


Hi, it looks like a popular feature, so I will add it to my personal project, BlitzType. The next beta will be released some time in the beginning of February.
_________________
TypingAid autocompletion program made with AHK.
Back to top
View user's profile Send private message
SoLong&Thx4AllTheFish



Joined: 27 May 2007
Posts: 4999

PostPosted: Wed Jan 20, 2010 8:24 am    Post subject: Reply with quote

Quote:
Hi, it looks like a popular feature
Its just the same guest asking it again again in various threads.
_________________
AHK Wiki FAQ
TF : Text files & strings lib, TF Forum
Back to top
View user's profile Send private message
Guest






PostPosted: Wed Jan 20, 2010 8:48 am    Post subject: Reply with quote

I'm not asking in various threads. I'm asking in the SAME thread. And no, that doesn't answer my question. And so, I'm gonna ask again in the future.
Back to top
SoLong&Thx4AllTheFish



Joined: 27 May 2007
Posts: 4999

PostPosted: Wed Jan 20, 2010 8:52 am    Post subject: Reply with quote

I'm quite sure (without looking) you have requested the same up/down feature in similar threads. But we'll never know for sure because of the guest ID, why not choose a nick makes it so much easier to talk to someone Smile And its easy to try yourself if it has the new feature by simply trying, why ask all the time.
_________________
AHK Wiki FAQ
TF : Text files & strings lib, TF Forum
Back to top
View user's profile Send private message
SoLong&Thx4AllTheFish



Joined: 27 May 2007
Posts: 4999

PostPosted: Wed Jan 20, 2010 10:48 am    Post subject: Reply with quote

Just a quick hack to add tab + enter completion while tooltip is active, will either complete first or use the selected item in the list, no guis where harmed in the process Smile so you can use the vertical arrow keys on the keyboard now.
Code:
; ALPHA version: TAB COMPLETION AND UP/DOWN FEATURE PRESS TAB or ENTER to select after UP/DOWN
;  Intellitype: typing aid
;  Press 1 to 0 keys to autocomplete the word upon suggestion
;  (0 will match suggestion 10)
;                                  - Jordi S
;                               Heavily modified by:
;                               Maniac
;___________________________________________

;    CONFIGURATIONS

#NoEnv
SetBatchLines, 20ms
ListLines Off

OnExit, SaveScript

; Editor Window Recognition
; (make it blank to make the script seek all windows)
ETitle =

;Minimum word length to make a guess
WLen = 3
keyagain=
key=
clearword=1
;Gosub,clearallvars   ; clean vars from start

; Press 1 to 0 keys to autocomplete the word upon suggestion
; (0 will match suggestion 10)
;_______________________________________

CoordMode, ToolTip, Relative
AutoTrim, Off

WordListDone = 0

;reads list of words from file
FileRead, ParseWords, %A_ScriptDir%\Wordlist.txt
Loop, Parse, ParseWords, `n, `r
{
   AddWordToList(A_LoopField)
}
ParseWords =

SetTimer, Winchanged, 100

GoSub, ReverseWordNums
WordlistDone = 1

Loop
{
   ;Editor window check
    WinGetActiveTitle, ATitle
    WinGet, A_id, ID, %ATitle%
    IfNotInString, ATitle, %ETitle%
    {
      ToolTip
      Setenv, Word,
      WinWaitActive, %ETitle%
      Continue
  }
   
   ;Get one key at a time
   Input, chr, L1 V,{enter}{space}.;`,:¿?¡!'"()]{}{}}{tab}{Up}{Dn}{bs}{{}{esc}{Home}{End}{PgUp}{PdDn}{Left}{Right}
   EndKey = %errorlevel%
   ; If active window has different window ID from before the input, blank word
   ; (well, assign the number pressed to the word)   
   WinGetActiveTitle, ATitle
   WinGet, A_id2, ID, %ATitle%
   IfNotEqual, A_id, %A_id2%
   {
      Gosub,clearallvars
      Setenv, Word, %chr%
      Continue
   }
   
   ifequal, OldCaretY,
        OldCaretY = %A_CaretY%
   ifnotequal, OldCaretY, %A_CaretY%
   {
      ; add the word if switching lines
      AddWordToList(Word)
         Gosub,clearallvars
         Setenv, Word, %chr%
         Continue
         
   }

   OldCaretY=%A_CaretY%
   
      ;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
         {
            Setenv, Word, %word%%chr%
         } else {
                  ;addword = %Word%
                  ;Gosub, addwordtolist
                  AddWordToList(Word)
                  Gosub, clearallvars     
                }
   
   ;Wait till minimum letters
   IF ( StrLen(Word) < wlen )
   {
      ToolTip,
      Continue
   }
   
   ;Match part-word with command
   Num =
   Match =
   singlematch = 0
   number = 0
   StringLeft, baseword, Word, %wlen%
   baseword := ConvertWordToAscii(baseword,1)
   Loop
   {
      IfEqual, zword%baseword%%a_index%,, Break
      IfEqual, number, 10
         Break
      if ( SubStr(zword%baseword%%a_index%, 1, StrLen(Word)) = Word )
      {
         number ++
         singlematch := zword%baseword%%a_index%
         match .= Mod(number,10) . ". " . singlematch . "`n"
         singlematch%number% = %singlematch%
           
         Continue           
      }
   }
   
   ;If no match then clear Tip
   IfEqual, Match,
   {
      clearword=0
      Gosub,clearallvars
      Continue
   }
   
   ;Show matched command
   StringTrimRight, match, match, 1        ; Get rid of the last linefeed
   WinGetActiveTitle, ATitle
   WinGetPos, , PosY, , SizeY, %ATitle%
   ToolTipSizeY := (number * 12)
   ToolTipPosY := A_CaretY+14
   if ((ToolTipSizeY + ToolTipPosY) > (PosY + SizeY))
       ToolTipPosY := (A_CaretY - 14 - ToolTipSizeY)
   IfNotEqual, Word,,ToolTip, %match%, %A_CaretX%, %ToolTipPosY%
   ; +14 Move tooltip down a little so as not to hide the caret.
}

; 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,
               {
                  IfNotEqual, OldCaretY, %A_CaretY%   
                  {
                     ToolTip,
                  }
               }
            }
         }
   Return
   
; Key definitions for autocomplete (0 to 9)
#MaxThreadsPerHotkey 1
$Enter::
$Up::
$Down::
$Tab::
$1::
$2::
$3::
$4::
$5::
$6::
$7::
$8::
$9::
$0::
CheckWord(A_ThisHotkey)
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
   StringRight, Key, Key, 1 ;Grab just the number pushed, trim off the "$"
   If (Key = "r") ; enter
       {
   IfEqual, Match,
      {
       Send {Enter}   
       Return
      }
      Key = 1
      If InStr(match, ">") ; get selected
          Key:=SubStr(match, InStr(match, ">") + 2, 1)
       }
   If (Key = "b") ; tab was pressed
       {
   IfEqual, Match,
      {
       Send {Tab}   
       Return
      }
      Key = 1
      If InStr(match, ">") ; get selected
          Key:=SubStr(match, InStr(match, ">") + 2, 1)
       }
   If (Key = "n") ; Down was pressed
       {
   IfEqual, Match,
      {
       Send {Down}   
       Return
      }
   ToolTipSizeY := (number * 12)
   ToolTipPosY := A_CaretY+14
   if ((ToolTipSizeY + ToolTipPosY) > (PosY + SizeY))
       ToolTipPosY := (A_CaretY - 14 - ToolTipSizeY)
   StringReplace, match, match, > %UpDownCounter%, %UpDownCounter%
   UpDownCounter++
   If (UpDownCounter > 9)
      UpDownCounter = 0
   StringReplace, match, match, %UpDownCounter%, > %UpDownCounter%
   IfNotEqual, Word,,ToolTip, %match%, %A_CaretX%, %ToolTipPosY%
   Return
       }
   If (Key = "p") ; Up was pressed
       {
   IfEqual, Match,
      {
       Send {Up}   
       Return
      }   
   ToolTipSizeY := (number * 12)
   ToolTipPosY := A_CaretY+14
   if ((ToolTipSizeY + ToolTipPosY) > (PosY + SizeY))
       ToolTipPosY := (A_CaretY - 14 - ToolTipSizeY)
   StringReplace, match, match, > %UpDownCounter%, %UpDownCounter%
   If (UpDownCounter = "")
         UpDownCounter=1
   UpDownCounter--
   If (UpDownCounter < 0)
      UpDownCounter = 9
   StringReplace, match, match, %UpDownCounter%, > %UpDownCounter%
   IfNotEqual, Word,,ToolTip, %match%, %A_CaretX%, %ToolTipPosY%
   Return
       }
   IfEqual, Key, 0
   {
      WordIndex = 10
   } else {
            WordIndex = %Key%
         }
   
   clearword=1

   ; If active window has different window ID from before the input, blank word
   ; (well, assign the number pressed to the word)
   WinGetActiveTitle, ATitle
   WinGet, A_id2, ID, %ATitle%
   IfNotEqual, A_id, %A_id2%
   {
      SendInput,%key%
      Gosub,clearallvars
      Return
   }
     
   IfNotEqual, OldCaretY, %A_CaretY% ;Make sure we are still on the same line
      {
         SendInput,%key%
         Gosub,clearallvars
         Return
      }

   ifequal, Word,        ; only continue if word is not empty
   {
      SendInput,%key%
      Setenv, Word, %key%
      clearword=0
      Gosub,clearallvars
      Return
   }
         
   ifequal, singlematch%WordIndex%,   ; only continue singlematch is not empty
      {
         SendInput,%key%
         Setenv, Word, %word%%key%
         clearword=0
         Gosub,clearallvars
         Return
      }

   Local sending
   Local len
   Local ClipboardSave
   ; SEND THE WORD!
   if key =0
      key = 10
   sending := singlematch%WordIndex%
   StringLen, len, Word
   ; Update Typed Count
   UpdateWordCount(sending)   
   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
}

; This is to blank all vars related to matches, tooltip and (optionally) word
clearallvars:
      Ifequal,clearword,1
      {
         Setenv,word,   
         OldCaretY=
      }
      ToolTip
      ; Clear all singlematches
      Loop, 10
      {
         singlematch%a_index% =
      }
      sending =
      key=
      match=
      clearword=1
      UpDownCounter=
      Return

AddWordToList(AddWord)
{
   global
   Local CharTerminateList
   Local Base
   Local AddWordInList
   Local CountWord
   Local pos

   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, wordlistdone, 0 ;If we are still reading the wordlist file and we come across ;LEARNEDWORDS; set the LearnedWordsCount flag
      {
         IfEqual, AddWord, `;LEARNEDWORDS`;
            LearnedWordsCount=0
      }
      addword =
      Return
   }
   ifequal, wordlistdone, 1 ;if we are not reading the wordlist file, use the following characters in the terminate list
         CharTerminateList = 1,2,3,4,5,6,7,8,9,0
   else CharTerminateList =
   if addword contains %CharTerminateList% ;if one of the chars in the word is in the terminate list, don't add it
   {
      addword =
      CharTerminateList =
      Return
   }
   CharTerminateList =
   IF ( StrLen(addword) <= wlen ) ; don't add the word if it's not longer than the minimum length
   {
      addword =
      Return
   }

   Base := ConvertWordToAscii(SubStr(addword,1,wlen),1)
   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
   {
      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 = %LearnedWords%,%addword%
                  }
            zCount%CountWord% := LearnedWordsCount++    ;increment the count and store the Weight of the LearnedWord in reverse order (will be inverted later)
         }
      } else {    ; If this is an on-the-fly learned word
               CountWord := ConvertWordToAscii(addWord,0)
               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 = %LearnedWords%,%addword%
                     }
            }
      ; Increment the counter for each hash
      zbasenum%Base%++       
      pos := zbasenum%Base%
      ; Set the hashed value to the word
      zword%Base%%pos% = %addword%
      pos =
   } Else {
            IfEqual, WordListDone, 1   ;if we've already typed the word and we've loaded the wordlist increment the count
            {
               UpdateWordCount(addword)
            }
         }
   
   Return
}
   
; 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)
{
; 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%,
   {
      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
}
   
SaveScript:
; Add all the standard words to the tempwordlist
FileRead, ParseWords, %A_ScriptDir%\Wordlist.txt
LearnedwordsPos := InStr(ParseWords, "`;LEARNEDWORDS`;",true,1) ;Check for Learned Words
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.
{
   TempWordList .= "`;LEARNEDWORDS`;`r`n"
   Loop, Parse, SortWordList, `,
   {
      StringTrimLeft, AppendWord, A_LoopField, InStr(A_LoopField,"z") ;Strip (Number,"z") from beginning
      TempWordList .= AppendWord . "`r`n"
   }
   StringTrimRight, TempWordList, TempWordList, 2
   
   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

_________________
AHK Wiki FAQ
TF : Text files & strings lib, TF Forum
Back to top
View user's profile Send private message
maniac



Joined: 28 Aug 2009
Posts: 267

PostPosted: Wed Jan 20, 2010 11:52 am    Post subject: Reply with quote

LOL, so simple. Seriously I can't believe I didn't think of that, thanks hugov I'll incorporate that in.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
Page 7 of 10

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group