 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
TomXIII
Joined: 14 Apr 2009 Posts: 182
|
Posted: Wed Mar 17, 2010 7:31 pm Post subject: Best Hotstring Recognition algorithm? [not solved] |
|
|
Hi everybody!
I have a great project in mind using hotstrings. To begin this project, I'm searching for a great algorithm to recognize hotstrings. I'm studying some scripts like ISense, Texter, TypingAid to find a good compromise.
I know that the best way is using "Input" with infinite loop because the built-in method is not usefull with compiled scripts.
Here are some objectives/ideas:
- Only recognize words
- Don't trigger if caret is in another line, edit or window
- can work even if a user type really fast
- hotstrings can only be triggered by "space" key
- No special length is required to trigger hotkey, it will trigger only if the user press space and the last word matches (from custom list!)
Thanks in advance for your ideas!
Last edited by TomXIII on Thu Mar 18, 2010 7:59 am; edited 2 times in total |
|
| Back to top |
|
 |
question4u Guest
|
Posted: Wed Mar 17, 2010 8:29 pm Post subject: |
|
|
| TomXIII wrote: | | ... the built-in method is not usefull with compiled scripts. | Why isn't the built-in method for hotstrings usefull for compiled scripts? |
|
| Back to top |
|
 |
TomXIII
Joined: 14 Apr 2009 Posts: 182
|
Posted: Wed Mar 17, 2010 9:00 pm Post subject: |
|
|
Yep, I know that hotstrings works even with compiled scripts otherwise there would be a lot of posts about this problem!
With compiled scripts users cannot create custom hotstrings without add them and recompile after. The users cannot create new hotstrings while a compiled script is running.
The most common solution for customs hotstrings is to use Infinite loop and monitor keystroke one by one and add each characters to get a string. The string is compared with a list of words taken in another file (txt, ini...). If the user have pressed a trigger key (space, tab, enter) and there was a match with last string, the script will send the full string (in your case: "by the way"). |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4652 Location: AHK Forum
|
Posted: Wed Mar 17, 2010 9:45 pm Post subject: |
|
|
Try following using AutoHotkey_H.
Instead compiling a script, rename AutoHotkey.exe to MyHotString.exe.
Then save this little modified example from AutoHotkey Help as MyHotString.ini
Double click MyHotString.exe.
Press #h for new hotstring or #s to change EndChars | Code: | /*
[Config]
*/
#Hotstring =EndChars `n `t
/*
[Script]
This is only necessary to make below not belong to [Config]
*/
AutoTrim,Off
SetWorkingDir % A_ScriptDir
IniRead,EndChars,% A_ScriptFullPath,Config,#HotString
StringReplace,EndChars,EndChars,% "EndChars "s,,
Return
#s::
InputBox,EndChars,EndChars,Enter EndChars,,200,130,,,,,%EndChars%
If (!ErrorLevel && EndChars!=""){
IniWrite,% "EndChars " EndChars,% A_ScriptFullPath,Config,#HotString
Reload
}
Return
#h:: ; Win+H hotkey
; Get the text currently selected. The clipboard is used instead of
; "ControlGet Selected" because it works in a greater variety of editors
; (namely word processors). Save the current clipboard contents to be
; restored later. Although this handles only plain text, it seems better
; than nothing:
AutoTrim Off ; Retain any leading and trailing whitespace on the clipboard.
ClipboardOld = %ClipboardAll%
Clipboard = ; Must start off blank for detection to work.
Send ^c
ClipWait 1
if ErrorLevel ; ClipWait timed out.
return
; Replace CRLF and/or LF with `n for use in a "send-raw" hotstring:
; The same is done for any other characters that might otherwise
; be a problem in raw mode:
StringReplace, Hotstring, Clipboard, ``, ````, All ; Do this replacement first to avoid interfering with the others below.
StringReplace, Hotstring, Hotstring, `r`n, ``r, All ; Using `r works better than `n in MS Word, etc.
StringReplace, Hotstring, Hotstring, `n, ``r, All
StringReplace, Hotstring, Hotstring, %A_Tab%, ``t, All
StringReplace, Hotstring, Hotstring, `;, ```;, All
Clipboard = %ClipboardOld% ; Restore previous contents of clipboard.
; This will move the InputBox's caret to a more friendly position:
SetTimer, MoveCaret, 10
; Show the InputBox, providing the default hotstring:
InputBox, Hotstring, New Hotstring, Type your abreviation at the indicated insertion point. You can also edit the replacement text if you wish.`n`nExample entry: :R:btw`::by the way,,,,,,,, :R:`::%Hotstring%
if ErrorLevel ; The user pressed Cancel.
return
IfInString, Hotstring, :R`:::
{
MsgBox You didn't provide an abbreviation. The hotstring has not been added.
return
}
; Otherwise, add the hotstring and reload the script:
FileAppend, `n%Hotstring%, %A_ScriptFullPath% ; Put a `n at the beginning in case file lacks a blank line at its end.
Reload
Sleep 200 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached.
MsgBox, 4,, The hotstring just added appears to be improperly formatted. Would you like to open the script for editing? Note that the bad hotstring is at the bottom of the script.
IfMsgBox, Yes, Edit
return
MoveCaret:
IfWinNotActive, New Hotstring
return
; Otherwise, move the InputBox's insertion point to where the user will type the abbreviation.
Send {Home}{Right 3}
SetTimer, MoveCaret, Off
return |
Alternatively you could use compiled script and AutoHotkey.dll, there you can load and terminate a script. _________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
TomXIII
Joined: 14 Apr 2009 Posts: 182
|
Posted: Wed Mar 17, 2010 10:17 pm Post subject: |
|
|
@HotKeyIt:
I read your method and I like the Ini/Script method.
| Quote: | | Alternatively you could use compiled script and AutoHotkey.dll, there you can load and terminate a script. | Just for curiosity, could you give me a little sample script? |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4652 Location: AHK Forum
|
Posted: Wed Mar 17, 2010 10:31 pm Post subject: |
|
|
Sure  | Code: | SetWorkingDir % A_ScriptDir
a:=AhkDllObject("AutoHotkey.dll")
Loop {
a.ahktextdll("#Persistent`n::btw::by the way this hotstring was created at " A_Hour ":" A_Min ":" A_Sec)
InputBox,v,Enter btw,Enter btw followed by a Space or Tab,,400,130
}
Escape::ExitApp |
_________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
TomXIII
Joined: 14 Apr 2009 Posts: 182
|
Posted: Thu Mar 18, 2010 12:07 am Post subject: |
|
|
| Thx for the sample! |
|
| Back to top |
|
 |
TomXIII
Joined: 14 Apr 2009 Posts: 182
|
Posted: Thu Mar 18, 2010 10:23 am Post subject: |
|
|
Here is a first (most simple) version:
Main file: | Code: | #Include, %A_ScriptDir%\GetKeyword.ahk
#SingleInstance, Force
SetKeyDelay, -1
SetWorkingDir, %A_ScriptDir%
endChars = {BS}{Enter}{Space}{Esc}{Tab}{Home}{End}{PGUP}{PGDN}{Up}{Down}{Left}{Right}{RShift}
specChars = .,`,,¿,?,¡,!,;,``,~,`%,$,&,*,-,+,=,\,/,>,<,|,@,#,:,_,(,),[,],{,}
GetKeyword()
Return
^!h::
GetKeyword()
Return
^!f::
exitFlag := 1
Return | GetKeyword.ahk: | Code: | GetKeyword()
{
global exitFlag, endChars, specChars
oldCaretX := A_CaretX
oldCaretY := A_CaretY
keyword := ""
Loop
{
If exitFlag
Break
Input, char, L1 V I, %endChars%
Error := ErrorLevel
If (oldCaretY<>A_CaretY || (A_CaretX<oldCaretX && Error<>"EndKey:BackSpace"))
{
keyword := ""
oldCaretX := A_CaretX
oldCaretY := A_CaretY
}
If InStr(Error, "EndKey")
{
If (Error="EndKey:Space")
{
IniRead, fullstring, %A_ScriptDir%\Hotstrings.ini, List, %keyword%, 0
If fullstring
SendFullstring(keyword)
keyword := "", char := ""
}
Else If (Error="EndKey:BackSpace")
StringTrimRight, keyword, keyword, 1
Else
keyword := "", char := ""
}
Else If char in %specChars%
keyword := "", char := ""
Else
keyword .= char
oldCaretX := A_CaretX , oldCaretY := A_CaretY
GuiControl,, keywordText, <%keyword%>
}
exitFlag := 0
} |
This solution needs improvments! |
|
| Back to top |
|
 |
SoLong&Thx4AllTheFish
Joined: 27 May 2007 Posts: 4999
|
Posted: Thu Mar 18, 2010 10:27 am Post subject: |
|
|
I haven't looked closely at your examples, but A_CaretX/Y aren't supported by all applications so they always return 0 so no changes is detected. _________________ AHK Wiki FAQ
TF : Text files & strings lib, TF Forum |
|
| Back to top |
|
 |
TomXIII
Joined: 14 Apr 2009 Posts: 182
|
Posted: Thu Mar 18, 2010 11:38 am Post subject: |
|
|
| @hugov:Its not a good news because it's the only way I found but THX! |
|
| Back to top |
|
 |
SoLong&Thx4AllTheFish
Joined: 27 May 2007 Posts: 4999
|
Posted: Thu Mar 18, 2010 1:01 pm Post subject: |
|
|
Tell me about it Many people have tried to find the caret in all apps. including me but all have failed (apart from workarounds like using imagesearch to look for the caret) the answer is probably somewhere in ACC (possibly COM) but that is out of my reach. _________________ AHK Wiki FAQ
TF : Text files & strings lib, TF Forum |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4652 Location: AHK Forum
|
Posted: Thu Mar 18, 2010 1:17 pm Post subject: |
|
|
You'll possibly need Input command here:
| Code: | ^!f::
exitFlag := 1
Input ; will cancel Input command and set ErrorLevel to NewInput
Return |
With regards to your Caret problem, why do you need to catch Caret at all, you can catch any keys and mouse clicks? _________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
TomXIII
Joined: 14 Apr 2009 Posts: 182
|
Posted: Fri Mar 19, 2010 9:56 am Post subject: |
|
|
| @HotKeyIt:Thx! It works fine with you add. For the caret problem, I take you solution about catching mouse click, it works but sometimes not! I'm on a good way! |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|