AutoHotkey Community

It is currently May 27th, 2012, 3:01 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: March 17th, 2010, 8:31 pm 
Offline

Joined: April 14th, 2009, 10:40 am
Posts: 182
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 March 18th, 2010, 8:59 am, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2010, 9:29 pm 
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?
Code:
:*:btw::by the way


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2010, 10:00 pm 
Offline

Joined: April 14th, 2009, 10:40 am
Posts: 182
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").


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2010, 10:45 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
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 :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2010, 11:17 pm 
Offline

Joined: April 14th, 2009, 10:40 am
Posts: 182
@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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2010, 11:31 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
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 :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 1:07 am 
Offline

Joined: April 14th, 2009, 10:40 am
Posts: 182
Thx for the sample!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 11:23 am 
Offline

Joined: April 14th, 2009, 10:40 am
Posts: 182
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!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 11:27 am 
Offline

Joined: May 27th, 2007, 9:41 am
Posts: 4999
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 FAQ
TF : Text files & strings lib, TF Forum


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 12:38 pm 
Offline

Joined: April 14th, 2009, 10:40 am
Posts: 182
@hugov:Its not a good news because it's the only way I found but THX!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 2:01 pm 
Offline

Joined: May 27th, 2007, 9:41 am
Posts: 4999
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 FAQ
TF : Text files & strings lib, TF Forum


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 2:17 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
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 :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 19th, 2010, 10:56 am 
Offline

Joined: April 14th, 2009, 10:40 am
Posts: 182
@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!


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Google [Bot], rbrtryn and 29 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group