TypingAid v2.22.0 - Word AutoCompletion Utility

Post your working scripts, libraries and tools for AHK v1.1 and older
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

TypingAid v2.22.0 - Word AutoCompletion Utility

18 Dec 2014, 11:03

Archived thread from old AHK forums.

TypingAid is a simple, compact, and handy auto-completion utility.

It is customizable enough to be useful for regular typing and for programming.

Download:
TypingAid v2.22.0 Precompiled Executable
TypingAid v2.22.0 AHK Script

As of version 2.19.7.0, the script is no longer compatible with AHK Basic. Please get the newest version from http://www.ahkscript.org.

English Wordlists:
1200 English Words Weighted By Frequency
2000 Common English Words
2000 Common English Words (Alternative)
3600 English Words
Large English Wordlist (Unfiltered, may contain curse words, etc)
Large English Wordlist by rommmcek
Large English Wordlist (words with only 4+ letters) by rommmcek
350,000+ English words (extracted from Project Gutenberg), found here
235,000+ English words (extracted from /usr/share/dict/words), found here
100,000 English Words Weighted by Frequency (based on Google Books)
333,333 English Words Weighted by Frequency (based on Google Web Trillion Word Corpus, by Norvig)
550,000+ English Words Weighted by Frequency (based on British National Corpus)

Non-English Wordlists
Large French Wordlist by rommmcek
Large German Wordlist by rommmcek
Large Italian Wordlist by rommmcek
Romanian Wordlist (282,000+ words) Thanks to Ochisor. Extracted from here.
Large Spanish Wordlist by jamesw77bp
Large Spanish Wordlist by rommmcek

AHK Keyword Wordlist:
Wordlist AHK.txt (Thanks tidbit.)
Wordlist AHK with parameter descriptions by rommmcek
Wordlist AHK with parameter descriptions and comments by rommmcek
Wordlist AHK with parameters autocompleted by rommmcek

Screenshots:
Image
Image

Change Log

Features:
As you type your word, up to 10 (or as defined in Settings) matches will appear in a drop-down dialog, numbered 1 - 0 (10th). To choose the match you want just hit the associated number on your keyboard (numpad does not work). Alternatively you can select an item from the drop-down using the Up/Down arrows or the mouse. You can define a fixed position for the drop-down dialog to appear by hitting Ctrl-Shift-H to open a small helper window, or by specifying a list of programs in the preferences file. Please note that in Firefox, Thunderbird, and certain other programs you will probably need to open the helper window due to issues detecting the caret position.

Words should be stored in a file named 'Wordlist.txt' which should be located in the script directory. These words may be commented out by prefixing with a semicolon or simply removed or added. Words may include terminating characters (such as space), but you must select the word before typing the terminating character.

In addition to being able to use the number keys to select a word, you can select words from the drop-down via the Up/Down arrows. Hitting Up on the first item will bring you to the last and hitting Down on the last item will bring you to the first. Hitting Page Up will bring you up 10 items, or to the first item. Hitting Page Down will bring you down 10 items, or to the last item. You can hit Tab, Right Arrow, Ctrl-Space, or Ctrl-Enter to autocomplete the selected word. This feature can be disabled or have some of its behavior modified via Settings.

The script will learn words as you type them if "Learn new words as you type" is set to On in Settings. If you type a word more than 5 times (or as defined in "Minimum length of word to learn") in a single session the word will be permanently added to the list of learned words. Learned words will always appear below predefined words, but will be ranked and ordered among other learned words based on the frequency you type them. You can permanently learn a word by highlighting a word and hitting Ctrl-Shift-C (this works even if "Learn new words as you type" is set to Off). You may use Ctrl-Shift-Del to remove the currently selected Learned Word.
Learned words are stored in the WordlistLearned.db sqlite3 database. Learned words are backed up in WordlistLearned.txt. To modify the list of Learned words manually, delete the WordlistLearned.db database, then manually edit the WordlistLearned.txt file. On the next launch of the script, the WordlistLearned.db database will be rebuilt.

Word descriptions can be added to 'Wordlist.txt' that will appear in the wordlist next to the word. These descriptions should be in the form of <word>|d|<description>, e.g., Tylenol|d|Pain Reliever. This could be used for things like definitions, translation aids, or function arguments. When Fixed Width fonts are used in the wordlist, the description columns will be tabbed evenly so they line up.

Word replacements can be added to 'Wordlist.txt' that will appear in the wordlist next to the word. These replacements should be in the form of <word>|r|<description>, e.g., fire|r|fuego. When the word is chosen, it will be backspaced out and replaced with the new word. If Case Correction is off, the first letter will be changed to match the case of the word being replaced. This could be used for spelling replacements, text expansion, or translation aids. Multiple replacements can be defined for a word (put each on a separate line).

A description and a replacement can both be added to the same word.

When Settings are changed, the script will automatically create a file named Preferences.ini in the script directory. This file allows for sharing settings between users. Users are encouraged to only edit settings by using the Settings window.
To allow for distribution of standardized preferences, a Defaults.ini may be distributed with the same format as Preferences.ini. If the Defaults.ini is present, this will override the hardcoded defaults in the script. A user may override the Defaults.ini by changing settings in the Settings window.

Customizable features include:
  • Enable or disable learning mode.
  • Number of characters a word needs to have in order to be learned.
  • Number of times you must type a word before it is permanently learned.
  • List of strings which will prevent any word which contains one of these strings from being learned.
  • Number of times you must press a number hotkey to select the associated word.
  • Change whether single or double clicking is required to autocomplete a word with the mouse.
  • Disable certain keys for autocompleting a word selected via the arrow keys.
  • Change the method used to send the word to the screen.
  • Change whether the script simply completes or actually replaces the word (capitalization change based on the wordlist file).
  • Enable or disable the resetting of the Wordlist Box on a mouseclick.
  • Change whether a space should be automatically added after the autocompleted word or not.
  • Number of items to show in the list at once.
  • Number of characters before the list of words appears.
  • Choose whether to display learned words before words in Wordlist.txt.
  • Enable, disable, or customize the arrow key's functionality.
  • Change whether the typed word should appear in the word list or not.
  • Number of pixels below the caret to display the Wordlist Box.
  • Wordlist Box Default Font of fixed (Courier New) or variable (Tahoma) width.
  • Wordlist Box Font Size.
  • Wordlist Box Opacity setting to set the transparency of the List Box.
  • Wordlist Box Character Width to override the computed character width.
  • Wordlist Box Default Font override.
  • Wordlist Box Max Width
  • List of programs for which you want %g_ScriptTitle% enabled.
  • List of programs for which you do not want %g_ScriptTitle% enabled.
  • List of programs for which you want the Helper Window to automatically open.
  • List of characters which terminate a word.
  • List of characters which terminate a word and start a new word.
  • List of characters which end a word, add that character to the word, and force the word to be learned.
Unicode Support:
Full support for UTF-8 character set.

Known Issues

Workarounds

Future Features

Credits:
Maniac
Jordi S
HugoV
kakarukeys
Asaptrad
j4hangir
Theclaw
rommmcek
jamesw77bp



Original Thread
Last edited by Maniac on 25 Aug 2016, 07:06, edited 11 times in total.
zotune
Posts: 85
Joined: 17 Nov 2014, 17:57

Re: TypingAid v2.19.9 - Word AutoCompletion Utility

30 Jan 2015, 06:55

Love this script. Is there any way to make this work with IP-addresses such as 10.211.110.21? I think it registers . (dot) as end of a word.

Thank you for your wonderful work.
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.19.9 - Word AutoCompletion Utility

30 Jan 2015, 07:14

It does register a . as the end of the word (you can disable that, but I wouldn't recommend it).

If you only need to learn a specific (and small) set of IP addresses, you can do the following:
1. Set "Length" to 2 in preferences.ini (make sure the script is not running when you do this). This will cause the wordlist to pop up when you've only typed 2 letters (if your IP addresses all begin with 3 characters, you can skip this step).
2. Type out the IP address, highlight it, and then hit Ctrl-Shift-C. This should learn the word.
3. Type out the first octal of the IP address, and then you should be able to autocomplete it (don't hit the .!)

If #2 doesn't work, just manually add the IP address to your wordlist.
zotune
Posts: 85
Joined: 17 Nov 2014, 17:57

Re: TypingAid v2.19.9 - Word AutoCompletion Utility

30 Jan 2015, 07:17

Thanks for the quick reply. It doesn't seem to work with numbers for me (for some reason).
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.19.9 - Word AutoCompletion Utility

30 Jan 2015, 08:45

OK, I see the issue. I specifically added checks which suppressed the ability to learn/read any words without alpha characters. I've added this back when reading from Wordlist.txt or hitting ctrl-shift-c.

This will be in the next release, but you can grab my development branch if you want. It has a bunch of other changes though (including a whole rewrite of the database backend).
Go here:
https://github.com/ManiacDC/TypingAid/tree/SQLite
Hit "Download Zip" on the right.
zotune
Posts: 85
Joined: 17 Nov 2014, 17:57

Re: TypingAid v2.19.9 - Word AutoCompletion Utility

30 Jan 2015, 10:04

Okay, thanks :) I will add it when it's available (I need to edit parts of the scripts anyhow).
bonami
Posts: 3
Joined: 31 Mar 2015, 22:23

Re: TypingAid v2.19.9 - Word AutoCompletion Utility

01 Apr 2015, 04:12

Do I have to run it as a serparate ahk? I tried to include it from my script, but it tried to undefine my hotkeys.
Then, how to call this script from mine?
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.19.9 - Word AutoCompletion Utility

01 Apr 2015, 05:47

You'll need to run it standalone, unless you plan on really tweaking the contents of this script. Thanks!
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.20.0 - Word AutoCompletion Utility

09 Apr 2015, 07:24

2.20.0 has been released!

*2.20.0 4/9/2015
** Added a Settings window (thanks to HugoV for doing much of the coding).
** Changed the learned words to use an SQLite3 database backend. This should help with future enhancements
** Changing settings no longer requires a script restart
** Added Active/Inactive Notification Area icons
** Added working Pause functionality
** Detecting Window switches now uses Windows Event Hooks, rather than a timer
** Added weighting based on number of characters left to type
** Changed license to GPLv3 for compatibility with AhkDBA SQLite3 interface
** Added the ability to learn words with no alpha characters when hitting Ctrl-Shift-C, or to read them in from Wordlist.txt
** Fixed Wordlist drawing on the mouse when unable to detect the caret position
** Fixed words not being learned when hitting Ctrl-Shift-C while Learning is off
** Large amounts of code refactoring, including renaming all global variables and fixing function scope
** Fixed having length of 1 not work with ForceNewWordCharacters
zotune
Posts: 85
Joined: 17 Nov 2014, 17:57

Re: TypingAid v2.20.0 - Word AutoCompletion Utility

29 Apr 2015, 01:40

New version with settings GUI looks promising, great job. Though where is the wordlist now? (Can I change it in the settings Window?)

Also, with this new Database wordlist, I don't think I'll be able to incorporate it into my own script (I share the .txt file on the network).

Is there any way to fix the IP issue in 2.19, or perhaps use 2.20 without database?

Kind regards
Mikael
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.20.0 - Word AutoCompletion Utility

29 Apr 2015, 06:03

Thanks!

Wordlist.txt is the same as it always was. WordlistLearned.txt has been replaced (it's still written to, but it's not read from unless WordlistLearned.db does not exist). If you need to manually edit WordlistLearned, right now the only way is to shut down the script, delete the .db file, and edit the .txt file. The .db will then be rebuilt.

Why can't you share the WordlistLearned.db over the network? It should work even better... I *think* you may even be able to access and use it from both PC's at once. One thing you won't have to do is close the script anymore before the file is updated on the other PC - updates should all be live.

The code changes since 2.19 have been so drastic that I have no plans to make further changes in 2.19.
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.21.0 - Word AutoCompletion Utility

01 May 2015, 14:16

TypingAid 2.21.0.0 has been released!

*2.21.0 5/1/2015
** Added the ability to insert a word by clicking on it in the Wordlist (turn of Single Click in the settings to require a double click for insertion)
** Added a setting to sort Learned Words before words in Wordlist.txt
** Added a setting to specify charactes which will terminate the current word, add the character to the end of the word, and permanently learn the word
** Added Setting back in for NumPresses (if set to 2, double hit the number to insert the word)
** Reorganized Settings Window to move more Wordlist Box settings to the Wordlist Box tab
** Changed "Save & Exit" in the settings window to "Save & Close"
** Minor code fixes

The new "End Word Characters" setting is pretty useful for programming. For example, if I had ( in my End Word Characters, I could type:
MyFunction(A,B)
MyFunction( would be learned, and would appear, with the (, the next time I start typing MyF...
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.21.0 - Word AutoCompletion Utility

01 May 2015, 22:16

Oops, download links fixed!
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.21.1 - Word AutoCompletion Utility

04 May 2015, 12:41

*2.21.1 5/4/2015
** Fixed clicking on a word in the 64-bit version
zotune
Posts: 85
Joined: 17 Nov 2014, 17:57

Re: TypingAid v2.21.1 - Word AutoCompletion Utility

21 May 2015, 15:30

Oh okay, sweet. Great work mate.

IP still doesn't work though.
Our network starts with 10.

Example:
10.211.114.38

I added it to Wordlist.txt with no luck :S

Edit: Removing . from terminating characters seems to have fixed it :)

Awesome!
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.21.1 - Word AutoCompletion Utility

21 May 2015, 18:48

Alternatively, you could set the number of characters to show the word list at to 2.

Glad it works for you :-)
User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: TypingAid v2.21.1 - Word AutoCompletion Utility

22 May 2015, 07:02

Hi!
I like your script. Even this writing I do with its help.
I did some minor changes for displaying ListBox. Maybe you could include some of them into your official script. Especially that in line 535 of my version.

Code: Select all

;These functions and labels are related to the shown list of words

InitializeListBox()
{
   global
 
   Gui, ListBoxGui: -Caption +AlwaysOnTop +ToolWindow +Delimiter%g_DelimiterChar%
 
   Local ListBoxFont
   IfNotEqual, prefs_ListBoxFontOverride,
      ListBoxFont := prefs_ListBoxFontOverride
   else {
         IfEqual, prefs_ListBoxFontFixed, On   
            ListBoxFont = Courier New
         else ListBoxFont = Tahoma
      }
 
   Gui, ListBoxGui:Font, s%prefs_ListBoxFontSize%, %ListBoxFont%
   Loop, %prefs_ListBoxRows%
   {
      GuiControl, ListBoxGui:-Redraw, g_ListBox%A_Index%
      ;can't use a g-label here as windows sometimes passes the click message when spamming the scrollbar arrows
      Gui, ListBoxGui: Add, ListBox, vg_ListBox%A_Index% R%A_Index% X0 Y0 hwndg_ListBoxHwnd%A_Index%
   }
 
   Return
}
 
ListBoxClickItem(wParam, lParam, msg, ClickedHwnd)
{
   global
   Local NewClickedItem
   Local TempRows
   static LastClickedItem
 
   TempRows := GetRows()
 
   if (ClickedHwnd != g_ListBoxHwnd%TempRows%)
   {
      return
   }
 
   ; if we clicked in the scrollbar, jump out
   if (A_GuiX > (g_ListBoxPosX + g_ListBoxContentWidth))
   {
      SetSwitchOffListBoxTimer()
      Return
   }
 
   GuiControlGet, g_MatchPos, ListBoxGui:, g_ListBox%TempRows%
 
   if (msg == g_WM_LBUTTONUP)
   {
      if prefs_DisabledAutoCompleteKeys not contains L
      {
         SwitchOffListBoxIfActive()
         EvaluateUpDown("$LButton")   
      } else {
         ; Track this to make sure we're double clicking on the same item
         NewClickedItem := g_MatchPos
         SetSwitchOffListBoxTimer()
      }
 
   } else if (msg == g_WM_LBUTTONDBLCLK)
   {
      SwitchOffListBoxIfActive()
 
      if prefs_DisabledAutoCompleteKeys contains L
      {
         if (LastClickedItem == g_MatchPos)
         {
            EvaluateUpDown("$LButton")   
         }
      }
   } else {
      SwitchOffListBoxIfActive()
   }
 
   ; clear or set LastClickedItem
   LastClickedItem := NewClickedItem
 
   Return
}
 
SetSwitchOffListBoxTimer()
{
   static DoubleClickTime
 
   if !(DoubleClickTime)
   {
      DoubleClickTime := DllCall("GetDoubleClickTime")
   }
   ;When single click is off, we have to wait for the double click time to pass
   ; before re-activating the edit window to allow double click to work
   SetTimer, SwitchOffListBoxIfActiveSub, -%DoubleClickTime%
}
 
 
SwitchOffListBoxIfActiveSub:
SwitchOffListBoxIfActive()
Return
 
ListBoxScroll(Hook, Event, EventHwnd)
{
   global
 
   Local MatchEnd
   Local SI
   Local TempRows
   Local Position
 
   if (g_ListBox_Id)
   {
 
      TempRows := GetRows()
      if (g_ListBoxHwnd%TempRows% != EventHwnd)
      {
         return
      }
 
      if (Event == g_EVENT_SYSTEM_SCROLLINGSTART)
      {
         ; make sure the timer is clear so we don't switch while scrolling
         SetTimer, SwitchOffListBoxIfActiveSub, Off
         return
      }
 
      SI:=GetScrollInfo(g_ListBoxHwnd%TempRows%)
 
      if (!SI.npos)
      {
         return
      }
 
      if (SI.npos == g_MatchStart)
      {
         return
      }
 
      g_MatchStart := SI.npos
 
      SetSwitchOffListBoxTimer()   
   }
}
 
; based on code by HotKeyIt
;  http://www.autohotkey.com/board/topic/78829-ahk-l-scrollinfo/
;  http://www.autohotkey.com/board/topic/55150-class-structfunc-sizeof-updated-010412-ahkv2/
GetScrollInfo(ctrlhwnd) {
  global g_SB_VERT
  global g_SIF_POS
  SI:=new _Struct("cbSize,fMask,nMin,nMax,nPage,nPos,nTrackPos")
  SI.cbSize:=sizeof(SI)
  SI.fMask := g_SIF_POS
  If !DllCall("GetScrollInfo","PTR",ctrlhwnd,"Int",g_SB_VERT,"PTR",SI[""])
    Return false
  else Return SI
}
 
ListBoxChooseItem(Row)
{
   global
   GuiControl, ListBoxGui: Choose, g_ListBox%Row%, %g_MatchPos%
}
 
;------------------------------------------------------------------------
 
CloseListBox()
{
   global g_ListBox_Id
   IfNotEqual, g_ListBox_Id,
   {
      Gui, ListBoxGui: Hide
      ListBoxEnd()
   }
   Return
}
 
DestroyListBox()
{
   Gui, ListBoxGui:Destroy
   ListBoxEnd()
   Return
}
 
ListBoxEnd()
{
   global g_ScrollEventHook
   global g_ScrollEventHookThread
   global g_ListBox_Id
   global g_WM_LBUTTONUP
   global g_WM_LBUTTONDBLCLK
 
   g_ListBox_Id =
 
   OnMessage(g_WM_LBUTTONUP, "")
   OnMessage(g_WM_LBUTTONDBLCLK, "")
 
   if (g_ScrollEventHook) {
      DllCall("UnhookWinEvent", "Uint", g_ScrollEventHook)
      g_ScrollEventHook =
      g_ScrollEventHookThread =
      MaybeCoUninitialize()
   }
   DisableKeyboardHotKeys()
   return
}
 
;------------------------------------------------------------------------
 
SavePriorMatchPosition()
{
   global g_MatchPos
   global g_MatchStart
   global g_OldMatch
   global g_OldMatchStart
   global g_singlematch
   global prefs_ArrowKeyMethod
 
   if !(g_MatchPos)
   {
      g_OldMatch =
      g_OldMatchStart = 
   } else IfEqual, prefs_ArrowKeyMethod, LastWord
   {
      g_OldMatch := g_singlematch[g_MatchPos]
      g_OldMatchStart = 
   } else IfEqual, prefs_ArrowKeyMethod, LastPosition
   {
      g_OldMatch := g_MatchPos
      g_OldMatchStart := g_MatchStart
   } else {
      g_OldMatch =
      g_OldMatchStart =
   }
 
   Return
}
 
SetupMatchPosition()
{
   global g_MatchPos
   global g_MatchStart
   global g_MatchTotal
   global g_OldMatch
   global g_OldMatchStart
   global g_singlematch
   global prefs_ArrowKeyMethod
   global prefs_ListBoxRows
 
   IfEqual, g_OldMatch, 
   {
      IfEqual, prefs_ArrowKeyMethod, Off
      {
         g_MatchPos = 
         g_MatchStart = 1
      } else {
         g_MatchPos = 1
         g_MatchStart = 1
      }
   } else IfEqual, prefs_ArrowKeyMethod, Off
   {
      g_MatchPos = 
      g_MatchStart = 1
   } else IfEqual, prefs_ArrowKeyMethod, LastPosition
   {
      IfGreater, g_OldMatch, %g_MatchTotal%
      {
         g_MatchStart := g_MatchTotal - (prefs_ListBoxRows - 1)
         IfLess, g_MatchStart, 1
            g_MatchStart = 1
         g_MatchPos := g_MatchTotal
      } else {
         g_MatchStart := g_OldMatchStart
         If ( g_MatchStart > (g_MatchTotal - (prefs_ListBoxRows - 1) ))
         {
            g_MatchStart := g_MatchTotal - (prefs_ListBoxRows - 1)
            IfLess, g_MatchStart, 1
               g_MatchStart = 1
         }
         g_MatchPos := g_OldMatch
      }
 
   } else IfEqual, prefs_ArrowKeyMethod, LastWord
   {
      ListPosition =
      Loop, %g_MatchTotal%
      {
         if ( g_OldMatch == g_singlematch[A_Index] )
         {
            ListPosition := A_Index
            Break
         }
      }
      IfEqual, ListPosition, 
      {
         g_MatchPos = 1
         g_MatchStart = 1
      } Else {
         g_MatchStart := ListPosition - (prefs_ListBoxRows - 1)
         IfLess, g_MatchStart, 1
            g_MatchStart = 1
         g_MatchPos := ListPosition
      }
   } else {
      g_MatchPos = 1
      g_MatchStart = 1
   }
 
   g_OldMatch = 
   g_OldMatchStart = 
   Return
}
 
RebuildMatchList()
{
   global g_Match
   global g_MatchLongestLength
   global g_MatchPos
   global g_MatchStart
   global g_MatchTotal
   global g_OriginalMatchStart
   global g_singlematch
   global prefs_ListBoxRows
 
   g_Match = 
   g_MatchLongestLength =
 
   if (!g_MatchPos)
   {
      ; do nothing
   } else if (g_MatchPos < g_MatchStart)
   {
      g_MatchStart := g_MatchPos
   } else if (g_MatchPos > (g_MatchStart + (prefs_ListBoxRows - 1)))
   {
      g_MatchStart := g_MatchPos - (prefs_ListBoxRows -1)
   }
 
   g_OriginalMatchStart := g_MatchStart
 
   Loop, %g_MatchTotal%
   {
      CurrentLength := AddToMatchList(A_Index,g_singlematch[A_Index])
      IfGreater, CurrentLength, %g_MatchLongestLength%
         g_MatchLongestLength := CurrentLength      
   }
   StringTrimRight, g_Match, g_Match, 1        ; Get rid of the last linefeed 
   Return
}
 
AddToMatchList(position,value)
{
   global g_DelimiterChar
   global g_Match
   global g_MatchStart
   global g_NumKeyMethod
 
   IfEqual, g_NumKeyMethod, Off
   {
      prefix =
   } else IfLess, position, %g_MatchStart%
   {
      prefix =
   } else if ( position > ( g_MatchStart + 9 ) )
   {
      prefix = 
   } else {
      prefix := Mod(position - g_MatchStart +1,10) . " "
   }
 
   g_Match .= prefix . value . g_DelimiterChar
   Return, StrLen("8 " . value)
}
 
;------------------------------------------------------------------------
 
;Show matched values
ShowListBox()
{
   global
 
   IfNotEqual, g_Match,
   {
      Local BorderWidthX
      Local ListBoxActualSize
      Local ListBoxActualSizeH
      Local ListBoxActualSizeW
      Local ListBoxPosY
      Local ListBoxSizeX
      Local ListBoxThread
      Local MatchEnd
      Local Rows
      Local ScrollBarWidth
      static ListBox_Old_Cursor
 
      Rows := GetRows()
 
      IfGreater, g_MatchTotal, %Rows%
      {
         SysGet, ScrollBarWidth, %g_SM_CXVSCROLL%
         if ScrollBarWidth is not integer
               ScrollBarWidth = 17         
      } else ScrollBarWidth = 0
 
      ; Grab the internal border width of the ListBox box
      SysGet, BorderWidthX, %g_SM_CXFOCUSBORDER%
      If BorderWidthX is not integer
         BorderWidthX = 1
 
 
      ;Use 8 pixels for each character in width
      ListBoxSizeX := g_ListBoxCharacterWidthComputed * g_MatchLongestLength + g_ListBoxCharacterWidthComputed + ScrollBarWidth + (BorderWidthX * 2)
 
 
      g_ListBoxPosX := HCaretX()
      ; + ListBoxOffset Move ListBox down a little so as not to hide the caret. 
      ListBoxPosY := HCaretY() + prefs_ListBoxOffset + 5 + 2 * prefs_ListBoxFontSize   ; <--------- RRR modification
 
      MatchEnd := g_MatchStart + (prefs_ListBoxRows - 1)
 
      Loop, %prefs_ListBoxRows%
      { 
         IfEqual, A_Index, %Rows%
         {
            GuiControl, ListBoxGui: -Redraw, g_ListBox%A_Index%
            GuiControl, ListBoxGui: Move, g_ListBox%A_Index%, w%ListBoxSizeX%
            GuiControl, ListBoxGui: ,g_ListBox%A_Index%, %g_DelimiterChar%%g_Match%
            IfNotEqual, g_MatchPos,
            {
               GuiControl, ListBoxGui: Choose, g_ListBox%A_Index%, %MatchEnd%
               GuiControl, ListBoxGui: Choose, g_ListBox%A_Index%, %g_MatchPos%
            }
            GuiControl, ListBoxGui: +AltSubmit +Redraw, g_ListBox%A_Index%
            GuiControl, ListBoxGui: Show, g_ListBox%A_Index%
            GuiControlGet, ListBoxActualSize, ListBoxGui: Pos, g_ListBox%A_Index%
            Continue
         }
 
         GuiControl, ListBoxGui: Hide, g_ListBox%A_Index%
         GuiControl, ListBoxGui: -Redraw, g_ListBox%A_Index%
         GuiControl, ListBoxGui: , g_ListBox%A_Index%, %g_DelimiterChar%
      }
 
      ForceWithinMonitorBounds(g_ListBoxPosX,ListBoxPosY,ListBoxActualSizeW,ListBoxActualSizeH,Rows)
 
      g_ListBoxContentWidth := ListBoxActualSizeW - ScrollBarWidth - BorderWidthX
 
      ; In rare scenarios, the Cursor may not have been detected. In these cases, we just won't show the ListBox.
      IF (!(g_ListBoxPosX) || !(ListBoxPosY))
      {
         return
      }
 
      IfEqual, g_ListBox_Id,
      {
 
         if prefs_DisabledAutoCompleteKeys not contains L
         {
            if (!ListBox_Old_Cursor)
            {
               ListBox_Old_Cursor := DllCall(g_SetClassLongFunction, "Uint", g_ListBoxHwnd%Rows%, "int", g_GCLP_HCURSOR, "int", g_cursor_hand)
            }
 
            DllCall(g_SetClassLongFunction, "Uint", g_ListBoxHwnd%Rows%, "int", g_GCLP_HCURSOR, "int", g_cursor_hand)
 
         ; we only need to set it back to the default cursor if we've ever unset the default cursor
         } else if (ListBox_Old_Cursor)
         {
            DllCall(g_SetClassLongFunction, "Uint", g_ListBoxHwnd%Rows%, "int", g_GCLP_HCURSOR, "int", ListBox_Old_Cursor)
         }
 
      }
 
      Gui, ListBoxGui: Show, NoActivate X%g_ListBoxPosX% Y%ListBoxPosY% H%ListBoxActualSizeH% W%ListBoxActualSizeW%, Word List Appears Here.
      Gui, ListBoxGui: +LastFound +AlwaysOnTop
 
      IfEqual, g_ListBox_Id,
      {
 
         EnableKeyboardHotKeys()   
      }
 
      WinGet, g_ListBox_Id, ID, Word List Appears Here.
 
      ListBoxThread := DllCall("GetWindowThreadProcessId", "UPtr", g_ListBox_Id)
      if (g_ScrollEventHook && (ListBoxThread != g_ScrollEventHookThread))
      {
         DllCall("UnhookWinEvent", "Uint", g_ScrollEventHook)
         g_ScrollEventHook =
         g_ScrollEventHookThread =
         MaybeCoUninitialize()
      }
 
      if (!g_ScrollEventHook) {
         MaybeCoInitializeEx()
         g_ScrollEventHook := DllCall("SetWinEventHook", "Uint", g_EVENT_SYSTEM_SCROLLINGSTART, "Uint", g_EVENT_SYSTEM_SCROLLINGEND, "Ptr", g_NULL, "Uint", g_ListBoxScrollCallback, "Uint", g_PID, "Uint", ListBoxThread, "Uint", g_NULL)
         g_ScrollEventHookThread := ListBoxThread
      }
 
      OnMessage(g_WM_LBUTTONUP, "ListBoxClickItem")
      OnMessage(g_WM_LBUTTONDBLCLK, "ListBoxClickItem")
 
      IfNotEqual, prefs_ListBoxOpacity, 255
         WinSet, Transparent, %prefs_ListBoxOpacity%, ahk_id %g_ListBox_Id%
   }
}
 
ForceWithinMonitorBounds(ByRef ListBoxPosX,ByRef ListBoxPosY,ListBoxActualSizeW,ListBoxActualSizeH,Rows)
{
   global prefs_ListBoxOffset
   global prefs_ListBoxFontSize              ; <---------- RRR modification
 
;Grab the number of non-dummy monitors
   SysGet, NumMonitors, 80
 
   IfLess, NumMonitors, 1
      NumMonitors =1
 
   Loop, %NumMonitors%
   {
      SysGet, Mon, Monitor, %A_Index%
      IF ( ( ListBoxPosX < MonLeft ) || (ListBoxPosX > MonRight ) || ( ListBoxPosY < MonTop ) || (ListBoxPosY > MonBottom ) )
         Continue
 
      If ( (ListBoxPosX + ListBoxActualSizeW + 6 * prefs_ListBoxFontSize) > MonRight ) ; <---------- RRR modification
      {
         ListBoxPosX := MonRight - ListBoxActualSizeW - 6 * prefs_ListBoxFontSize      ; <---------- RRR modification
         If ( ListBoxPosX < MonLeft )
            ListBoxPosX := MonLeft
      }
 
If ((ListBoxPosY + ListBoxActualSizeH + 3 * prefs_ListBoxFontSize) > (MonBottom ))       ; <---------- RRR modification
{
ListBoxPosY := HCaretY() - ListBoxActualSizeH - 2 * prefs_ListBoxFontSize * Rows / 5 - 2 ; <---------- RRR modification
         If ( ListBoxPosY < 1 )       ; <---------- RRR modification
            ListBoxPosY := 1          ; <---------- RRR modification
}
      Break
   }
 
   Return      
}
 
;------------------------------------------------------------------------
 
GetRows()
{
   global g_MatchTotal
   global prefs_ListBoxRows
   IfGreater, g_MatchTotal, %prefs_ListBoxRows% 
      Rows := prefs_ListBoxRows
   else Rows := g_MatchTotal
 
   Return, Rows
}
;------------------------------------------------------------------------
 
; function to grab the X position of the caret for the ListBox
HCaretX() 
{ 
   global g_Helper_Id
 
   WinGetPos, HelperX,,,, ahk_id %g_Helper_Id% 
   if HelperX !=
   { 
      return HelperX
   } 
   if ( CheckIfCaretNotDetectable() )
   { 
      MouseGetPos, MouseX
      return MouseX
   } 
   return A_CaretX 
} 
 
;------------------------------------------------------------------------
 
; function to grab the Y position of the caret for the ListBox
HCaretY() 
{ 
   global g_Helper_Id
 
   WinGetPos,,HelperY,,, ahk_id %g_Helper_Id% 
   if HelperY != 
   { 
      return HelperY
   } 
   if ( CheckIfCaretNotDetectable() )
   { 
      MouseGetPos, , MouseY
      return MouseY + 20
   } 
   return A_CaretY 
}
 
;------------------------------------------------------------------------
 
CheckIfCaretNotDetectable()
{
   ;Grab the number of non-dummy monitors
   SysGet, NumMonitors, 80
 
   IfLess, NumMonitors, 1
      NumMonitors = 1
 
   if !(A_CaretX)
   {
      Return, 1
   }
 
   ;if the X caret position is equal to the leftmost border of the monitor +1, we can't detect the caret position.
   Loop, %NumMonitors%
   {
      SysGet, Mon, Monitor, %A_Index%
      if ( A_CaretX = ( MonLeft ) )
      {
         Return, 1
      }
 
   }
 
   Return, 0
}
What I like less is slow loading of large WorldList and no suggest by very wrong spelling. That's why I sometimes switch to Uberi's AutoComplete.
Did you ever think about unifying both approaches?

Best wishes and many thanks!
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.21.1 - Word AutoCompletion Utility

22 May 2015, 07:18

I won't be able to take a look until the middle of June, but I will then. Are you sure large wordlists still load slowly? I would have expected 2.20 to fix that.
User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: TypingAid v2.21.1 - Word AutoCompletion Utility

22 May 2015, 13:11

With that insert into your code

Code: Select all

StartTime := A_TickCount
;Read in the WordList
ReadWordList()
ElapsedTime := A_TickCount - StartTime
MsgBox,  %ElapsedTime% milliseconds have elapsed.
I get following result: 39250 milliseconds have elapsed.
I'm using WordList with 593820 lines (6.925.178 bytes) on Windows 8 64-bit

What you could do in a few minutes is to type some long word on the bottom of the screen to see positioning of the diminishing ListBox above the cursor with my version of your ListBox.ahk
Maniac
Posts: 121
Joined: 24 Oct 2014, 07:15
Contact:

Re: TypingAid v2.21.1 - Word AutoCompletion Utility

22 May 2015, 22:44

Do you ever change your wordlist? You could add them to WordlistLearned.txt and skip the loading time.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: JoeWinograd, kashmirLZ and 71 guests