StrokesPlus.net
Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
Rob Otter  
#1 Posted : Friday, October 30, 2020 1:18:59 AM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
Would it be possible to specify no trigger for text expansion?

Use case is that I used to have some "favorite" typos in words, e.g. "acutal" instead of "actual" or "brwoser" instead of "browser" ("brwosing" / "brwosing" and similar adds to that).
An auto-correction performed by spn when it discovers the first characters would help alot. Currently, I use same AHK scripts for that but would like to abandon these and replace it by spn.
Rob  
#2 Posted : Friday, October 30, 2020 7:49:12 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 754
United States
Location: Tampa, FL

Thanks: 16 times
Was thanked: 174 time(s) in 151 post(s)
Send me the AHK script so I can see what it's doing.
Rob Otter  
#3 Posted : Friday, October 30, 2020 12:45:38 PM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
OK, I will fiddle it out on Sunday. It's part of a bigger tool written in AHK, called ac'tivAid (in module "Hotstrings") and I need some time for that. At the moment, my little grandson is visiting us...
Rob Otter  
#4 Posted : Sunday, November 1, 2020 3:23:33 AM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
Oh well, there is nothing to find out from the toolset - it turns out that AutoHotkey supports on-the-fly replacement out of the box:
https://www.autohotkey.com/docs/Hotstrings.htm
Rob  
#5 Posted : Sunday, November 1, 2020 7:04:36 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 754
United States
Location: Tampa, FL

Thanks: 16 times
Was thanked: 174 time(s) in 151 post(s)
I see, the autocorrect ahk just leverages the hotstrings functionality, which has a little more control over the monitoring/replacement via control codes.

So this would be a moderate and potentially breaking change, as well as (arguably) a little outside of the original scope for the Text Expansion functionality built into S+.

However, I think this would be a good opportunity to utilize a plug-in, to provide more advanced features for those who are looking for something a bit more - and perhaps it could later be integrated into S+ if the plug-in is highly popular.

It could also be handled within scripts via utilizing the keyboard hook event binding functionality, though I think a plug-in would be easier to manage (using the same event bindings) - especially by being able to build a UI for it instead of having to do everything in script. The plug-in could have a method to open its "Settings" window, which could be bound to a S+ hotkey, for example.

I will tinker around with it some, as time permits. If you're familiar with C# it's not something very difficult to do - it's really just the tedious part of ensuring it handles all of the situations properly, without interfering with the UX of someone just typing in an app.
Rob Otter  
#6 Posted : Monday, November 2, 2020 3:21:40 AM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
I´d appreciate if you would have a look at it, as I am not very good at C#. It´s nothing very urgent, even if it would be very nice having it so I could eleminate the use for AHK a bit more...
Rob  
#7 Posted : Thursday, November 5, 2020 1:15:19 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 754
United States
Location: Tampa, FL

Thanks: 16 times
Was thanked: 174 time(s) in 151 post(s)
Okay, I threw this together and it seems to work okay, but I haven't really tested it a lot.


Plug-In Only (extract using 7-Zip or make sure to right-click DLL, Properties, unblock/mark as safe):


Source code (Visual Studio 2019 Community [free] edition is fine):



Note: It's possible that if you're not using S+ installed in the standard location, the plug-in might not find the references to StrokesPlus.net.exe and WindowsInput.dll necessary to work. Let me know if that happens.



Once you add the plug-in to S+, you'll need to add a few scripts to get it started.

Global Actions > Load/Unload > Load
Code:
// Only perform this last script engine in the pool, since it only needs
// to be done once
if(__spEngineWrapper.Engine.Name == sp.EngineList().Last().Engine.Name)
{
    // Instantiate auto correct plugin object and store for later use
    sp.StoreObject("autoCorrect", new AutoCorrect());
    
    // Optional pass string parameter, list of terminator/reset characters
    // e.g. autoCorrect.Bind(". \t"); //only period, space, and tab

    // These characters control when the token is reset 
    // and if T is used in a replacement entry
    // Default is "-()[]{}:;'\" /\\,.?! \t\n" 
    //  - Note special characters are escaped: " (\"), \ (\\), Tab (\t), Enter (\n)
    //  - Also, there is a space between ! and \t for the space character

    // Start watching keystrokes (bind to keyboard events)
    sp.GetStoredObject("autoCorrect").Bind(); 
}

Global Actions > Load/Unload > Unload
Code:
// Unbind and save auto correct on exit of S+
var autoCorrect = sp.GetStoredObject("autoCorrect");
if(autoCorrect != null)
{
    autoCorrect.Unbind();
    autoCorrect.SaveSettings();
}

Action or Hotkey to Show Settings Window for Auto Correct Entries
Code:
// Show the auto correct settings screen
sp.GetStoredObject("autoCorrect").ShowSettings();

The entries are saved alongside of the StrokesPlus.net.bin file (S+ settings) using the same logic for loading S+ settings.
For a standard install, this would be C:\Users\{USERNAME}\AppData\Roaming\StrokesPlus.net\AutoCorrect.txt

The format is similar to AHK:
Code:
:OPTIONS:TOKEN::REPLACEMENT

--replace "tset" with "test", matches case exactly, "TSeT" would NOT be replaced
--only replaces if a terminating character is pressed like space, period, etc.
:CT:tset::test  

--replace "txet" with "text" immediately, no need to press space, etc.
--does not care about the casing "TxeT" would be replaced
::txet::text

So:
C = Case-sensitive
T = Only replace if termination character pressed after the token
C and/or T can be combined or omitted entirely - no other options are available at this time, but the source can be modified if needed.

See the comments in the Load script regarding the terminating characters, there are default ones (matching AHK) but can be overridden when calling Bind().

The settings window is terribly crude, but does give a simple interface to add and remove entries. You can also edit the AutoCorrect.txt file (mentioned above) to add items in bulk more quickly. Just make sure to reload S+ if you change the AutoCorrect.txt file outside of the settings window - I didn't add any fancy file watching logic.
Rob Otter  
#8 Posted : Friday, November 6, 2020 9:14:07 AM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
Thanks for that, but unfortunately it´s not working. I´ve placed the DLL (no execution blocker set) to the standard location (C:\Program Files\StrokesPlus.net\Plug-Ins) and added the (un)load scripts as stated. When restarting S+, there is no error and the defined hotkey opens the settings window. But whatever I define (even with or without T C modifiers), it does not get corrected. Does the DLL need a specifc .Net version? I have .Net 4.8 on a brand new Windows 10 Pro 20H2 installation (german lang pack).
Imho this plugin should work immediately for every application - am I wrong here? Do I have to assign apps anywhere?
Rob  
#9 Posted : Friday, November 6, 2020 9:46:25 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 754
United States
Location: Tampa, FL

Thanks: 16 times
Was thanked: 174 time(s) in 151 post(s)
Hmm, .NET version shouldn't matter since if S+ can run, so can the plug-in (and you'd get an error anyway).

Wait, in Options > Advanced, do you have Enable Keyboard Hook Event Subscription checked?
thanks 1 user thanked Rob for this useful post.
Rob Otter on 11/6/2020(UTC)
Rob Otter  
#10 Posted : Friday, November 6, 2020 10:21:51 AM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
Bingo! Enabled the hook and it works!
I´ll play with the plugin a bit more and let you know about results.
Rob  
#11 Posted : Friday, November 6, 2020 10:33:31 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 754
United States
Location: Tampa, FL

Thanks: 16 times
Was thanked: 174 time(s) in 151 post(s)
Yeah, I forgot to include that very important piece of information BigGrin
Rob Otter  
#12 Posted : Wednesday, November 11, 2020 12:00:03 AM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
Hi Rob, what I´ve found out so far:

- I usually do not use standard delimiter characters but two dots (..) when I want to expand an abbreviation, therefore I do not define :T:dns::Desoxyribonukleinsaeure but rather ::dns..::Desoxyribonukleinsaeure (sophisticated example, because I still want to be able to have "DNS" unexpanded for "Domain Name Service", independent of case). This does not work, any hotstring with dots is not recognized (I guess standard delimiters jump in, even if :T: is not given).
- After each hotstring a delimiter character must be typed, otherwise the next hotstring is not expanded. Maybe this is not a big issue and currently I do not have real-live example where this would be hindering but I stumbled over it while testing.
Currently, all hotstrings work for all applications. Would it be a big deal to define different hotstrings for different applications?
Rob  
#13 Posted : Wednesday, November 11, 2020 12:26:18 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 754
United States
Location: Tampa, FL

Thanks: 16 times
Was thanked: 174 time(s) in 151 post(s)
Quote:
This does not work, any hotstring with dots is not recognized (I guess standard delimiters jump in, even if :T: is not given)

Are you calling this just like my example?
Code:
    // Default is "-()[]{}:;'\" /\\,.?! \t\n" 
    //  - Note special characters are escaped: " (\"), \ (\\), Tab (\t), Enter (\n)
    //  - Also, there is a space between ! and \t for the space character

    // Start watching keystrokes (bind to keyboard events)
    sp.GetStoredObject("autoCorrect").Bind();  

If so, you can pass in a string of terminating (reset token) characters to override the default.
So you could change it to not include the period (but leave the others as is:
Code:
p.GetStoredObject("autoCorrect").Bind("-()[]{}:;'\" /\\,?! \t\n");



Quote:
Currently, all hotstrings work for all applications. Would it be a big deal to define different hotstrings for different applications?

Yeah, it would be a decent amount of work to add application matching in. Not that it would be an massive effort, but it's a bit too much for me to work on at the moment.
Someone could take the source code of the plug-in I included in this post and modify it, ActionFunctions.ForegroundWindow (adding references to ManagedWinapi*.dll in the StrokesPlus.net install folder) to easily determine the active window, then update the code and Settings window accordingly.

I might circle back and take a look at adding that, but no promises. I kind of throw myself at something to help folks get started, then lose interest :)


Quote:
After each hotstring a delimiter character must be typed, otherwise the next hotstring is not expanded.

There does appear to be some kind of race condition there, like in my example of txet, if I type "t" after it's done the replacement, I end up with "ttext".
Again, I'll try to take a look into that. I have a ton of stuff going on with work, a hurricane about to hit our area(!), and other S+ support stuff - so it might be a little while.

thanks 1 user thanked Rob for this useful post.
Rob Otter on 11/11/2020(UTC)
Rob Otter  
#14 Posted : Wednesday, November 11, 2020 11:42:46 PM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
Thanks for the Bind Parameter values - I was not clear about that. Now periods are working fine!

There truly seems to be some kind of race conditions while autotyping: Depending on the application (and some other conditions that affect performance, like working in an RDP session), strings are lacking some characters, abbreviation characters are not deleted fully, ... - I imagine two possible fixes for this:
1) slower typing (higher waitstates after each character): Not only affects overall performance but might unreliable when it comes to poor responsiveness of applications (as said, like in RDP sessions)
2) replace char-by-char autotyping by pasting the full string at once: Possibly this means temporarily backing / restoring clipboard, which could be expensive

App-aware auto-correct would be a very nice to have, but not more - so, don´t put much effort in this. As you´ve provided the plugin source, I might step in and use it as a starter for further development in the next couple of weeks (when I find the time). For the time being, I still have a good functionality for my daily work, so thank you very much for your support!!!
Rob  
#15 Posted : Thursday, November 12, 2020 8:09:30 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 754
United States
Location: Tampa, FL

Thanks: 16 times
Was thanked: 174 time(s) in 151 post(s)
Try this, just to see how it works:

https://www.strokesplus....rect_Sync_PlugIn_1.0.zip

The only real difference is it processes the keystroke synchronously, instead of asynchronously. KeyboardHook.OnKeyboardHookEvent instead of KeyboardHook.OnKeyboardHookEventAsync

There isn't much technically different about these, except:
The S+ keyboard sends the key events to the plug-in and waits for the plug-in to finish processing the keystroke before continuing.
This method also supports setting the .Consume property to true, which tells S+ to discard the keystroke, which you cannot do asynchronously (since the event already happened).

The async version doesn't stop S+ from processing, it just sends the event to a queue for the plug-in to process. I'm thinking that these keystroke events queueing up might be the reason for the odd behavior.

Of course, there is a way to write the logic where it properly handles the keystrokes asynchronously without this issue, but this took me only like 1 minute to change to synchronous and upload, so see if you notice a difference.
Rob Otter  
#16 Posted : Friday, November 13, 2020 12:08:19 AM(UTC)
Rob Otter

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 10/26/2020(UTC)
Posts: 32
Germany
Location: Darmstadt

Thanks: 11 times
Was thanked: 1 time(s) in 1 post(s)
hm... while it works nearly perfect on my home PC, my office PC still shows the same flaws but at higher typing speed :-D
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.