Jump to content

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

RegEx Powered Dynamic Hotstrings


  • Please log in to reply
225 replies to this topic
Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Regarding your post, I don't understand the bug you mention?

I already said, it prevents hotstrings(k) from removing k from the list of expressions. For example,
hotstrings("\bann(a|e)" , "Ann%$1%")
; This is supposed to "remove hotstring definition from triggering an action":
hotstrings("\bann(a|e)")

Your second change breaks entries like ...

I forgot to replace "$" with "$$" in k and a. For example,
t := RegExReplace(t, "\n\Q" . k . "\E\r.*?\n|$", "`n" RegExReplace(k,"\$","$$$$") "`r" RegExReplace(a,"\$","$$$$") "`n", _, 1)
Notice that the replacement string is actually "$$", with each doubled up to specify a single literal character.

If possible please post back on the problem there and what difference changing that line should make.

Again, I already said what it does: replaces any identical expressions already existing in the list. For instance, without the change, code like the following
hotstrings("omg" , "oh my god")
Sleep, 5000
hotstrings("omg" , "oh my god{!}")
will result in "omg" being expanded to "oh my god oh my god!" if the script has been running for at least 5 seconds. This is because there are two "omg" entries in the list (but also because of the first issue in the list below.)

Both of these changes are specifically useful for loading hotstring definitions from an external file, and later reloading them or modifying them via a GUI. (Someone Asked for Help with such a script recently.)

While debugging this, I've noticed some other issues:
[*:145j8knn]Sometimes the "recognizer" seems to act on what was there, not what it was replaced with. (One could argue that neither should be recognized, but that's not the point.) For instance, if I use hotstrings("\bann(a|e)", "Ann%$1%") and type "anna", it replaces it with "Anna". If I then backspace the "a" and type another "a", or type some other letter then backspace it, "Anna" is replaced with "Anna".
[*:145j8knn]I had originally noticed it with "oh my g" being replaced with "oh moh my god" or something similar. After modifying the script, it no longer happens this way for "omg"->"oh my god". :?[*:145j8knn]This is especially problematic if I click into another window (like Firefox) and start typing then backspace what I typed, as it then deletes part of my text and types "Anna". This is partly a separate issue:
[*:145j8knn]Unlike AutoHotkey's hotstring recognizer, hotstrings() does not reset when you click, press arrow keys, home, end, etc. (Clicking and +home,delete are the main problems for me.)[/list]

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
I committed an update which should have hopefully resolved the issues mentioned. Thanks for the bug reports.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


rjwilmsi
  • Members
  • 30 posts
  • Last active: Nov 21 2012 12:40 PM
  • Joined: 18 May 2005

I committed an update which should have hopefully resolved the issues mentioned. Thanks for the bug reports.

Thanks for the update - it is certainly an improvement. The "isn't" bug I had has now gone too. Also, the main bug I was suffering from was over extra firing of hotkeys, which I believe is the issue Lexikos mentioned.

However, one bug introduced by this update (I'm pretty sure) is that now backspacing of a hotstring doesn't work: e.g. type anna, get it converted to Anna by hotstrings("\bann(a|e)" , "Ann%$1%") rule, but then if backspace is pressed immediately, the character before Anna is deleted rather than the last 'a' in Anna. If the e = line is changed to remove BS this doesn't happen, but does that break other things? Thanks.

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
Both bugs fixed in v2.53.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008
Thanks, this is great until we get fully implemented dynamic hotstrings!


Just a little modification I made in my own version of the function;
StringSplit, x, A_LoopField, `r
			If (RegExMatch(s, x1 . "$", $)) ; match
			{
				StringLen, l, $
				SendInput, {BS %l%}
				If (IsLabel([color=red]SubStr(x2, 1, -1)) && SubStr(x2,0) = ":"[/color])
					Gosub, [color=red]% SubStr(x2, 1, -1)[/color]
				Else
				{
					Transform, x0, Deref, %x2%
					Send, %x0%
				}
			}
Just makes it so you have to put a colon ( : ) after a label name if you want it to go to a label instead of replace the text; simply makes it a bit harder to accidentally go to a label instead of replacing the text...

Edit: Fixed with updated code.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Thanks Titan. [Edit]327%[/b] faster for removing, and 54% faster for replacing:
Else If a =
        t := RegExReplace(t, "\n\Q" . k . "\E\r.*?\n")
    Else If k !=
        t := RegExReplace(t, "\n\Q" . k . "\E\r.*?\n|$", "`n" RegExReplace(k,"\$","$$$$") "`r" RegExReplace(a,"\$","$$$$") "`n", _, 1)
Or maybe you just felt like rewriting it the long way. :p
End edit.]

Krogdor, it isn't possible for a label name to end with ":", therefore (IsLabel(x2) && SubStr(x2,0) = ":") will always evaluate to false. I suggest:
if (SubStr(x2,0)=":" && IsLabel(SubStr(x2,1,-1)))


Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008
Yeah, sorry about that Lexikos—I wasn't at the computer with my script so I was just going off of what I remembered. That would be the correct way to implement it.

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

Just makes it so you have to put a colon ( : ) after a label name if you want it to go to a label instead of replace the text

I like the idea, but I'll keep it as it is now for the sake of compatibility.

I suppose you assumed avoiding RegExReplace would be more efficient, without having actually benchmarked it.

I had a tough time with the GC on Mono so I was actually concerned with the memory usage of:

To improve performance, the 100 most recently used regular expressions are kept cached in memory (in compiled form).

I haven't benchmarked this either so I can't be certain. Either way I should hope a parsing loop is more newb friendly which is a good enough reason to keep it.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


rjwilmsi
  • Members
  • 30 posts
  • Last active: Nov 21 2012 12:40 PM
  • Joined: 18 May 2005
Thanks to all for the continued work on this script. I have a bug with the latest version of the script to report. I believe Lexikos may have already mentioned this, but here goes:
hotstrings("(A|a)quir" , "%$1%cquir") ; acquire
using the above hotstring if 'aquir' is typed this is autoreplaced to 'acquir'. All correct so far, but if you then press backspace and 'r' another 'a' is added to the front of the word. This can be continued multiple times. I believe this is a problem for any hotstrings where the replace is longer than the find.

If the line with 'e = BS' is changed to remove 'BS' this goes away, but then this removes the fact that the function can work on user-corrected words.

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
Thanks for the report. Fixed in v2.54.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


indeez
  • Guests
  • Last active:
  • Joined: --
First if all, many thanx for your script!

Possibly you'd find it interesting: I'd had modified it a little bit in order to catch the numpad keys. I had to correct IP addresses because in my native keyboard layout there's a comma `,' on the numpad Del and often IP addresses were typed as 1,2,3,4

So here's the trivial addition to your script (suppose diff-form suits you)
--- Hotstrings.ahk-orig	Thu Mar 19 19:43:12 2009
+++ Hotstrings.ahk	Thu Mar 19 21:57:20 2009
@@ -33,7 +33,7 @@
 			If A_Index not between 33 and 58
 				Hotkey, %m%%c%, __hs
 		}
-		e = BS|Space|Enter|Return|Tab
+		e = BS|Space|Enter|Return|Tab|Numpad0|Numpad1|Numpad2|Numpad3|Numpad4|Numpad5|Numpad6|Numpad7|Numpad8|Numpad9|NumpadDot|NumpadDel
 		Loop, Parse, e, |
 			Hotkey, %m%%A_LoopField%, __hs
 		z = 1
@@ -54,6 +54,28 @@
 				q := "`t"
 			Else If q in Enter,Return
 				q := "`n"
+			Else If q = Numpad0
+				q := "0"
+			Else If q = Numpad1
+				q := "1"
+			Else If q = Numpad2
+				q := "2"
+			Else If q = Numpad3
+				q := "3"
+			Else If q = Numpad4
+				q := "4"
+			Else If q = Numpad5
+				q := "5"
+			Else If q = Numpad6
+				q := "6"
+			Else If q = Numpad7
+				q := "7"
+			Else If q = Numpad8
+				q := "8"
+			Else If q = Numpad9
+				q := "9"
+			Else If q in NumpadDot,NumpadDel
+				q := ","
 			Else If (StrLen(q) != 1)
 				q = {%q%}
 			Else If (GetKeyState("Shift") or GetKeyState("CapsLock", "T"))
After than the code

hotstrings("(\d+)[^\d\s.](\d+)[^\d\s.](\d+)[^\d\s.](\d+)", "%$1%.%$2%.%$3%.%$4%")

works quite as expected

Thank you once more for that great script!

programmable
  • Members
  • 8 posts
  • Last active: Nov 10 2009 10:10 PM
  • Joined: 02 May 2008
This script works just fine for me, until I start using cut/paste.

hotstrings("(abcdefg)", "showHotstr")
Return

showHotstr:
msg := $1
MsgBox %msg%
Return

It works fine if i type

abcdefg

However, it fails if I cut/paste any part of the "abcdefg" string.

Any thoughts?

MasterFocus
  • Moderators
  • 4323 posts
  • Last active: Jan 28 2016 01:38 AM
  • Joined: 08 Apr 2009
Just to inform, the link is broken.
Hotstrings.ahk is currently located HERE.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Antonio França -- git.io -- github.com -- ahk4.net -- sites.google.com -- ahkscript.org

Member of the AHK community since 08/Apr/2009. Moderator since mid-2012.


HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Here is a small fix because some hotkeys are not being created, for example:
hotstrings("(\d\d?)\[color=Red];[/color](\d\d?)", "%$1%:%$2%")
If A_Index not between 33 and [color=Red]58[/color] ;should be 64 I think


guest3434
  • Guests
  • Last active:
  • Joined: --
I really like this script VERY much . I just have three questions:

1) How to add it to the autohotkey.ini (i know, i know i´m a newbie)
2) How is the performance impact if used with thousands of hotstrings and/or complicated/long regex rules?
3) I think this script is so great. Chris could implement it into autohotkey itself. What do you think?