Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Autocomplete 1.2


  • Please log in to reply
207 replies to this topic
Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010

Suggests and completes words as you type! Write faster and more efficiently.

 

ScreenshotScreenshot.png

 

Changelog

Update: Way better match results. Way better wordlist. Way better everything!

Update: Bugfixes and key lists are saved in settings.

Update: Hosting has been moved to GitHub, and a nice README is now included.

Update: Edit your wordlist and tweak settings easily using a shiny GUI! Also, ranking algorithm fixes for bad offset calculation. The ranker should give excellent results now. Oh, and case correction should work with accented characters too. Thanks for the suggestions and bug reports ChefTom and Yuxie!

Update: Ranking algorithm tweaks! Frequency sorted wordlists start taking frequency into account. More popular words will be placed higher in the suggestions list.

Update: Subsequence matching! Type "avrce" and "avarice" will be suggested. Type "rupstil" and "Rumpelstiltskin" will be suggested. Abbreviations benefit greatly from this. In short, the typed letters will match a word if they are present in the order given, instead of the word having to start with those letters. In addition, matching is now case insensitive and supports accented characters. Returned results are also ranked and sorted by several criteria now, such as prefix length, extraneous characters, and total length. Ideas come from BrandonHotkey and Persil.

Update: Automatic width adjustment! The width will expand as needed to fit the words in it. Idea comes courtesy of oldbrother.

Update: I was inspired by berban to revisit this old script, and I have made speed improvements - approximately 30 times faster - when searching the wordlist. However, it requires a wordlist that is sorted by the first character of each item. The new searching method is simply a prefix table (a table of pointers to the beginning of a certain prefix) combined with the original search, for a good balance between speed and memory usage. Please redownload the script and the wordlist (both of them - the wordlist has been updated too) to take advantage of the changes.
Another feature is that although the wordlist contains so many words, they are split into categories based on their frequency of use, so the autocomplete is more likely to complete "drea" with "dream" then "dreadnoughts", even though it is alphabetically farther away.

Links

DOWNLOAD
GitHub repository



shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
Great script.
I would like to auto-complete with an Enter, and have Esc+Enter to enter a carriage return.
Keep up the good work.

closed
  • Members
  • 509 posts
  • Last active: Jan 14 2012 06:14 PM
  • Joined: 07 Feb 2008
Thanks for sharing much appreciated.I only will look into changing the positon of the window for me it is too close to where i am typing. :)

tidbit
  • Administrators
  • 2709 posts
  • Hates playing Janitor
  • Last active: Jan 15 2016 11:37 PM
  • Joined: 09 Mar 2008
this is pretty awesome (time to replace my crappy autocomplete plugin!). though the DDL seems to be in the way a bit on some applications, like Opera.
but nice and fast :)

I have a few word databased, one with nearly 900,000 words. and another cleaned up database of ~100,000 words. and a further cleaned up one of ~7,000 words. I can upload them if you'd like.

rawr. be very afraid
*poke*
. Populate the AutoHotkey city. Pointless but somewhat fun. .


Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010

I would like to auto-complete with an Enter, and have Esc+Enter to enter a carriage return.


Done. Comment out line 98 to disable this behavior.

I only will look into changing the positon of the window for me it is too close to where i am typing.


Also done. See the OffsetX and the OffsetY variables.

I have a few word databased, one with nearly 900,000 words. and another cleaned up database of ~100,000 words. and a further cleaned up one of ~7,000 words. I can upload them if you'd like.


I'd like that very much. :D

Pip
  • Guests
  • Last active:
  • Joined: --
I love this.

Is there any chance you can make it recognise the SEND command from an OSK - like the one here:
http://www.autohotke...topic53955.html

Rather than having to type?

Thanks

Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010

Is there any chance you can make it recognise the SEND command from an OSK - like the one here:
http://www.autohotke...topic53955.html

Rather than having to type?


Well, because it's purpose was to befuddle keyloggers by using SendPlay, AHK can't detect the keys it sends. However, if you are willing to give up the security it offers, replace all uses of "SendPlay" with "Send":

Row=5 ;This is the BIG Gui 
Gui, Add, Button, x5 y%Row% w20 h20 gSendP , ``
Gui, Add, Button, x30 y%Row% w20 h20 gSendP , 1
Gui, Add, Button, x55 y%Row% w20 h20 gSendP, 2
Gui, Add, Button, x80 y%Row% w20 h20 gSendP , 3
Gui, Add, Button, x105 y%Row% w20 h20 gSendP , 4
Gui, Add, Button, x130 y%Row% w20 h20 gSendP , 5
Gui, Add, Button, x155 y%Row% w20 h20 gSendP , 6
Gui, Add, Button, x180 y%Row% w20 h20 gSendP , 7
Gui, Add, Button, x205 y%Row% w20 h20 gSendP , 8
Gui, Add, Button, x230 y%Row% w20 h20 gSendP , 9
Gui, Add, Button, x255 y%Row% w20 h20 gSendP , 0
Gui, Add, Button, x280 y%Row% w20 h20 gSendP , -
Gui, Add, Button, x305 y%Row% w20 h20 gSendP , =
Gui, Add, Button, x330 y%Row% w20 h20 gSendP , \
Gui, Add, Button, x355 y%Row% w20 h20 , Bs
Row=30
Gui, Add, Button, x5 y%Row% w30 h20 , Tb
Gui, Add, Button, x40 y%Row% w20 h20 gSendP , Q
Gui, Add, Button, x65 y%Row% w20 h20 gSendP , W
Gui, Add, Button, x90 y%Row% w20 h20 gSendP , E
Gui, Add, Button, x115 y%Row% w20 h20 gSendP , R
Gui, Add, Button, x140 y%Row% w20 h20 gSendP , T
Gui, Add, Button, x165 y%Row% w20 h20 gSendP , Y
Gui, Add, Button, x190 y%Row% w20 h20 gSendP , U
Gui, Add, Button, x215 y%Row% w20 h20 gSendP , I
Gui, Add, Button, x240 y%Row% w20 h20 gSendP , O
Gui, Add, Button, x265 y%Row% w20 h20 gSendP , P
Gui, Add, Button, x290 y%Row% w20 h20 gSendP , [
Gui, Add, Button, x315 y%Row% w20 h20 gSendP , ]
Gui, Add, Button, x340 y%Row% w35 h28 , En
Row=55
Gui, Add, Button, x5 y%Row% w40 h20 , Cl
Gui, Add, Button, x50 y%Row% w20 h20 gSendP , A
Gui, Add, Button, x75 y%Row% w20 h20 gSendP , S
Gui, Add, Button, x100 y%Row% w20 h20 gSendP , D
Gui, Add, Button, x125 y%Row% w20 h20 gSendP , F
Gui, Add, Button, x150 y%Row% w20 h20 gSendP , G
Gui, Add, Button, x175 y%Row% w20 h20 gSendP , H
Gui, Add, Button, x200 y%Row% w20 h20 gSendP , J
Gui, Add, Button, x225 y%Row% w20 h20 gSendP , K
Gui, Add, Button, x250 y%Row% w20 h20 gSendP , L
Gui, Add, Button, x275 y%Row% w20 h20 gSendP , `;
Gui, Add, Button, x300 y%Row% w20 h20 gSendP , '
Gui, Add, Button, x325 y%Row% w50 h20 , En
Row=80
Gui, Add, Button, x5 y%Row% w55 h20 , Shift
Gui, Add, Button, x65 y%Row% w20 h20 gSendP , Z
Gui, Add, Button, x90 y%Row% w20 h20 gSendP , X
Gui, Add, Button, x115 y%Row% w20 h20 gSendP , C
Gui, Add, Button, x140 y%Row% w20 h20 gSendP , V
Gui, Add, Button, x165 y%Row% w20 h20 gSendP , B
Gui, Add, Button, x190 y%Row% w20 h20 gSendP , N
Gui, Add, Button, x215 y%Row% w20 h20 gSendP , M
Gui, Add, Button, x240 y%Row% w20 h20 gSendP , `,
Gui, Add, Button, x265 y%Row% w20 h20 gSendP , .
Gui, Add, Button, x290 y%Row% w20 h20 gSendP , /
Gui, Add, Button, x315 y%Row% w60 h20 , Shift
Row=105
Gui, Add, Text, x5 y%Row% w70 h20 , CapsLock Off
Gui, Add, Button, x90 y%Row% w145 h20 , Space
Gui, Show, xCenter y820 h130 w380, GUI Keyboard
WinSet, AlwaysOnTop, On , GUI Keyboard

Caps:=0 ;Preset Caps and Shift to off
Sh:=0

SetTimer WWA, 100 ;Monitor What Window is Active so it can send to the correct window 
WWA:
WinGetActiveTitle, Active
If Active<>GUI Keyboard
Dest=%Active%
Return

GuiClose:
ExitApp
Return

SendP: ;sub that sends most keys
If((Caps+Sh)=0) ;check Caps and Shift state
StringLower, Letter, A_GuiControl ;if off make lower
Else
StringUpper, Letter, A_GuiControl ;if on make UPPER
if Sh=1 ;if shift was on turn it off
GoSub ShiftOff
WinActivate %Dest% ;Activate the window to sent to
Send %Letter%
Return

ButtonSpace: ; Send the keys that don't heve the actual letter on them
WinActivate %Dest%
Send {Space}
Return

ButtonBs:
WinActivate %Dest%
Send {BS}
Return

ButtonTb:
WinActivate %Dest%
Send {Tab}
Return

ButtonEn:
WinActivate %Dest%
Send {Enter}
Return

ButtonCl: ;Change the Caps state and it's label on the Gui
Caps:=!Caps
ControlSetText, Static1, % "CapsLock " . Caps ? "On" : "Off", GUI Keyboard
Return

ButtonShift: ;Turn Shift on and Change the Buttons to shifted state
Temp1 = ~!@#$`%^&*()_+|
Loop, Parse, Temp1
 ControlSetText, Button%A_Index%, %A_LoopField%, GUI Keyboard
ControlSetText, Button27, {, GUI Keyboard
ControlSetText, Button28, }, GUI Keyboard
ControlSetText, Button40, :, GUI Keyboard
ControlSetText, Button41, ", GUI Keyboard
ControlSetText, Button51, <, GUI Keyboard
ControlSetText, Button52, >, GUI Keyboard
ControlSetText, Button53, ?, GUI Keyboard
Sh:=1
Return

ShiftOff: ;Turn Shift off and Change the Buttons to non shifted state
Temp1 = ``1234567890-=\
Loop, Parse, Temp1
 ControlSetText, Button%A_Index%, %A_LoopField%, GUI Keyboard
ControlSetText, Button27, [, GUI Keyboard
ControlSetText, Button28, ], GUI Keyboard
ControlSetText, Button40, `;, GUI Keyboard
ControlSetText, Button41, ', GUI Keyboard
ControlSetText, Button51, `,, GUI Keyboard
ControlSetText, Button52, ., GUI Keyboard
ControlSetText, Button53, /, GUI Keyboard
Sh:=0
Return

(also shortened the code)

Pip
  • Guests
  • Last active:
  • Joined: --
I'm using the second version that starts with:


SendMode Play ;here you can change the Send Mode, key order, and what shift changes the characters to

Do I just change this mode?

Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010
Yes, change that to "Input", or if that doesn't work, "Event".

tidbit
  • Administrators
  • 2709 posts
  • Hates playing Janitor
  • Last active: Jan 15 2016 11:37 PM
  • Joined: 09 Mar 2008
Here are my word lists.
seems my 'clean' list versions were a lot smaller (1/2 the size) then I thought.

contains an 870,000 and 100,000 and 3,300 word database. I believe I got them from here and another site I can't remember (probably the one you used), and refined over the last couple years (I like lists :p)

With my smallest word list, you probably don't even need the frequency numbers (I assume what those number are at the front)

ps: notepad++ opens Massive text files perfectly fine.

rawr. be very afraid
*poke*
. Populate the AutoHotkey city. Pointless but somewhat fun. .


Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010
Thanks, tidbit!

Notepad++ is based on SciTE, which can open huge files, but uses hundreds of megabytes of memory in the process. Task Manager also shows 100% CPU usage for about 30 seconds. Personally, I prefer TheGun, which is an editor written completely in ASM :shock: , designed for large files.

Pip
  • Guests
  • Last active:
  • Joined: --
Been trying - but it's too much for me.

Shame - I think the autocomplete would be more useful for an OSK than for anything - especially the first version you did where you just clicked on the word (without pressing enter).

Anyway - still a really cool program.

Thanks

Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010

Been trying - but it's too much for me.


If you mean changing the OSK to work with this script, just replace:

SendMode Play

With:

SendMode Input

Or if that doesn't work:

SendMode Event


Pip
  • Guests
  • Last active:
  • Joined: --
Yeh -tried both...did't make any difference.

The OSK I use is

SendMode Play ;here you can change the Send Mode, key order, and what shift changes the characters to
Row1:="1‡2‡3‡4‡5‡6‡7‡8‡9‡0‡-‡=‡\‡Bs"
Row2:="Q‡W‡E‡R‡T‡Y‡U‡I‡O‡P‡[‡]"
Row3:="A‡S‡D‡F‡G‡H‡J‡K‡L‡;‡'"
Row4:="Z‡X‡C‡V‡B‡N‡M‡,‡.‡/"
ShiftAble:="``~‡1!‡2@‡3#‡4$‡5%‡6^‡7&‡8*‡9(‡0)‡-_‡=+‡\|‡[{‡]}‡`;:‡'""‡,<‡.>‡/?"

CoordMode, Mouse, Screen
Menu, Tray, NoStandard
Menu, Tray, Add, Show Keyboard, ShowMe
Menu, Tray, Add, Help, HelpMe
Menu, Tray, Add
Menu, Tray, Add, Exit, ExitScript
Menu, Tray, Default, Show Keyboard ;Double click on Icon to Show
Menu, Tray, Icon , C:\WINDOWS\system32\main.cpl,8  ;not sure if everybody has this icon but I have it on XpSp3

OnMessage(0x205 , "RightClickCap") ;WM_RBUTTONUP Right to send Caps
OnMessage(0x207 , "MButtonMove") ;WM_MBUTTONDOWN Middle click to move Gui

Caps:=0,Sh:=0 ;Preset Caps and Shift to off
;http://www.autohotkey.com/forum/viewtopic.php?t=62257 thanks Wicked
Gui, +LastFound +AlwaysOnTop +ToolWindow -Caption +Border +E0x08000000
Gui, Add, Button, x5 y5 w20 h20 gSendP , ``
Loop, Parse, Row1,‡
 Gui, Add, Button, x+2 w20 h20 gSendP , %A_LoopField%
Gui, Add, Button, x5 y27 w30 h20 gSendP, Tab
Loop, Parse, Row2,‡
 Gui, Add, Button, x+2 w20 h20 gSendP , %A_LoopField%
Gui, Add, Button, x+2 w32 h26 gSendA, En ;.
Gui, Add, Button, x5 y49 w40 h20 , Caps
Loop, Parse, Row3,‡
 Gui, Add, Button, x+2 w20 h20 gSendP , %A_LoopField%
Gui, Add, Button, x+2 w44 h20 gSendA, En
Gui, Add, Button, x5 y71 w53 h20 , Shift
Loop, Parse, Row4,‡
 Gui, Add, Button, x+2 w20 h20 gSendP , %A_LoopField%
Gui, Add, Button, x+2 w53 h20 , Shift
Gui, Add, Text, x5 y93 w70 h20 vCapsLabel, CapsLock Off
Gui, Add, Button, x+2 w132 h20 gSendP, Space
Gui, Add, Button, x+2 w20 h20 gSendA , <
Gui, Add, Button, x+2 w20 h20 gSendA , ^
Gui, Add, Button, x+2 w20 h20 gSendA , v
Gui, Add, Button, x+2 w20 h20 gSendA , >
Gui, Add, Button, x+2 h20 , Hide
Pos:=A_ScreenHeight - 135
ShowMe:
Gui, Show,xCenter y%Pos% NoActivate ,GUI Keyboard
Return

SendP: ;sub that sends most keys
If((Caps+Sh)=0) ;check Caps and Shift state
 StringLower, Letter, A_GuiControl ;if off make lower
Else
 StringUpper, Letter, A_GuiControl ;if on make UPPER
ifEqual Sh,1, GoSub ShiftOff ;if shift was on turn it off
Send % (Letter="&&") ? "&" : "{" Letter "}"
Return

SendA: ;sub that sends Arrows and Enter
IfEqual, A_GuiControl, <, Send {Left}
IfEqual, A_GuiControl, ^, Send {Up}
IfEqual, A_GuiControl, v, Send {Down}
IfEqual, A_GuiControl, >, Send {Right}
IfEqual, A_GuiControl, En, Send {Enter}
Return

ButtonCaps: ;Change the Caps state and it's label on the Gui
GuiControl, , CapsLabel, % (Caps:=!Caps) ? "CapsLock On" : "CapsLock Off"
Return

ButtonHide:
Gui, Hide
Return

ButtonShift: ;Turn Shift on and Change the Buttons to shifted state
ShiftOff: ;Turn Shift off and Change the Buttons to non shifted state
Loop, Parse, ShiftAble, ‡
 {
 StringSplit Var, A_LoopField
 If (A_ThisLabel="ButtonShift" && Sh=0)
  GuiControl, , %Var1% , % (Var2="&") ? "&&" : Var2
 Else
   GuiControl, , % (Var2="&") ? "&&" : Var2 , %Var1%
 }
Sh:=(A_ThisLabel="ButtonShift" && Sh=0) ? 1 : 0
Return

HelpMe:
MsgBox,
(
Middle click on the Gui to move

Right click on a letter to send it uppercase
  Bonus Right click does not toggle shift back off

The Shift and Caps Buttons are seperate from the System ones
)
Return

ExitScript:
ExitApp

MButtonMove() {
While GetKeyState("MButton","p") {
 MouseGetPos X,Y
 WinMove, GUI Keyboard,,% X-157 ,% Y-60
 }
}

RightClickCap()
{
MouseGetPos,,,,Control
ControlGetText, Text, %Control%
If (StrLen(Text)=1 || Text="&&")
 {
 StringUpper, Letter, Text
 Send % (Letter="&&") ? "&" : "{" Letter "}"
 }
}

From here
http://www.autohotke...topic53955.html

I tried replacing the first line with
SendMode Input
and also with
SendMode Event
But no change

Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010
Oh, I see the problem. The word recognizer is being reset every time to you click on the OSK. This version of the code should fix it:

#NoEnv

WordListFile = %A_ScriptDir%\WordList.txt
MaxResults = 30
OffsetX = 0
OffsetY = 20

CoordMode, Caret
FileRead, WordList, %WordListFile%
IfInString, WordList, `r
 StringReplace, WordList, WordList, `r,, All
StringReplace, WordList, WordList, `n, `n, UseErrorLevel
MsgBox % ErrorLevel + 1
ParseList := SubStr(ParseList,1,-1), WordList .= "`n"
Gui, Add, ListBox, x0 y0 w150 h160 vMatched gCompleteWord AltSubmit
Gui, -Caption +ToolWindow +AlwaysOnTop +LastFound
hWnd := WinExist()
Gui, Show, w150 h160 Hide, AutoComplete
SetHotkeys()
Return

GuiClose:
ExitApp

SetHotkeys()
{
 NormKeyList = abcdefghijklmnopqrstuvwxyz1234567890
 ResetKeyList = Esc,Space,Home,PGUP,PGDN,End,Left,Right,RButton,MButton,Enter,`,,.,/,[,],`;,\,-,=,``
 Loop, Parse, NormKeyList
 {
  Hotkey, ~%A_LoopField%, KeyPressed, UseErrorLevel
  Hotkey, ~+%A_LoopField%, ShiftedKey, UseErrorLevel
 }
 Hotkey, ~', KeyPressed, UseErrorLevel
 Loop, Parse, ResetKeyList, CSV
  Hotkey, ~*%A_LoopField%, ResetWord, UseErrorLevel
 Hotkey, ~*", ResetWord, UseErrorLevel
}

KeyPressed:
CurrentWord .= SubStr(A_ThisHotkey,2)
Gosub, Suggest
Return

ShiftedKey:
CurrentWord .= SubStr(A_ThisHotkey,3)
Gosub, Suggest
Return

ResetWord:
CurrentWord = 
Gui, Hide
Return

Suggest:
If CurrentWord = 
{
 Gui, Hide
 Return
}
MatchList := "", Temp3 := StrLen(CurrentWord), Temp2 := 1
While, ((Temp1 := InStr(WordList,"," . CurrentWord,False,Temp2)) && A_Index <= MaxResults)
 Temp1 ++, Temp2 := InStr(WordList,"`n",False,Temp1), MatchList .= "|" . SubStr(WordList,Temp1,Temp2 - Temp1)
If MatchList = 
{
 Gui, Hide
 Return
}
GuiControl,, Matched, %MatchList%
GuiControl, Choose, Matched, 1
Gui, Show, % "x" . (A_CaretX + OffsetX) . " y" . (A_CaretY + OffsetY) . " NoActivate"
Return

CompleteWord:
If A_GuiEvent Not In ,DoubleClick
 Return
GuiControlGet, Temp1,, Matched
MatchList .= "|"
StringGetPos, Temp1, MatchList, |, L%Temp1%
Temp1 += 2 + StrLen(CurrentWord), Temp1 := SubStr(MatchList,Temp1,InStr(MatchList,"|",False,Temp1) - Temp1)
Gosub, ResetWord
SendRaw, %Temp1%
Return

~BackSpace::
StringTrimRight, CurrentWord, CurrentWord, 1
Gosub, Suggest
Return

#IfWinExist AutoComplete ahk_class AutoHotkeyGUI

~LButton::
MouseGetPos,,, Temp1
Temp2 := WinExist("GUI Keyboard")
If Temp1 Not In %hWnd%,%Temp2%
 Gosub, ResetWord
Return

Enter::
Tab::
Gosub, CompleteWord
Return

Up::
GuiControlGet, Temp1,, Matched
GuiControl, Choose, Matched, % Temp1 - 1
Return

Down::
GuiControlGet, Temp1,, Matched
GuiControl, Choose, Matched, % Temp1 + 1
Return

#IfWinActive