A script for word selection that trims the trailing space?

Can I ask for some more help, now with a different script?

I want a script that will trim the trailing space of a word selected via double-clicking. I have the following simple script, which works fine when a selected word is followed by a space but has the undesired result of "trimming" the last character of a word when followed by a punctuation mark.

 

~LButton::
SystemDoubleClickTime := DllCall("GetDoubleClickTime")

If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < SystemDoubleClickTime)
{
Send +{Left}
}
Return

  

I also have this, found somewhere some time ago, but even though it looks complicated, it has the same result:

  

~LButton::
SystemDoubleClickTime := DllCall("GetDoubleClickTime")

If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < SystemDoubleClickTime)
{
; Copy everything in the Clipboard
oldClipboard := ClipboardAll

; Empty the Clipboard
clipboard =
; CTRL+ C = copy text selected
Send ^c
; Wait until the Clipboard grabs the content
ClipWait

AutoTrim, Off
word = %Clipboard%
StringLen, len1, word

AutoTrim, On
wordWithoutSpaces = %word%
StringLen, len2, wordWithoutSpaces

IfNotEqual, len1, len2
{
Sendinput +{left} ; SHIFT LEFT
}

; Give contents back to the Clipboard
Clipboard = %oldClipboard%

; Free memory of temp variable
oldClipboard =
}
Return

  • Hi Nora,

    The first script assumes there is always a trailing space. It just trims off the last character, whatever it is. If you double-click a word that is followed by a space, then the space is included in the selection and is removed from the selection by the "Send +{Left}".

    But if the word is followed by a punctuation mark, then double-clicking creates a selection that ends at the last character of the word. The "Send +{Left}" then removes this last character from the selection.

    The second script should work, as it does not assume there is always a trailing space. If there is a trailing space, then AutoTrim trims it off, which means that len1 and len2 will differ and the trailing space will be removed from the selection by the "Sendinput +{left}".

    So I can't see why the second script wouldn't work. How strange. Are you sure it does the same as the first script?

    One problem with both scripts is that there could be multiple trailing spaces. The "Send +{Left}" in the first script and the "Sendinput +{left}" in the second script would only remove the last space from the selection.

    You might be able to remove all of the trailing spaces from the selection by using "SendInput +{Left %n%}" in the second script, where "n" is equal to the difference in lengths, i.e. "n := len1-len2". I am unfortunately not using AutoHotKey any more, so I can't test whether using "%n%" like this works in a SendInput command.

    Best regards,
    Bruce Campbell
    ASAP Language Services

     

     

  • Thank you for taking a look Bruce. You're right about the multiple spaces, only the last one gets trimmed. I tried SendInput +{Left %n%} and it makes no difference, though.

    I'm hoping I can get that second script to work, but at the moment it doesn't do what it's supposed to do.
  • There is a very simple way to get rid of trailing spaces: just assign a variable to itself as a value, in the process, trailing spaces will be removed.

     

  • Hi Raphaël and Nora,

    Script 2 does exactly that by setting AutoTrim OFF before setting "word" equal to the ClipBoard, so that "word" DOES includes the trailing space in the selection and then setting AutoTrim ON before setting the variable "wordWithoutSpaces" equal to "word" so that any trailing spaces are trimmed.

    The question is why script 2 is not working.

    Nora, can you put msgbox commands in script 2 to display the contents of the different variables, like "word", "wordWithoutSpaces", "len1" and "len2"?

    Then double-click a word followed by a punctuation mark to find out why len1 and len2 are not equal.

    They should be equal, but the only way script 2 would execute the "Sendinput +{left}" is if they are NOT equal. So it would be interesting to see what is actually happening ...

    Best regards,
    Bruce Campbell
    ASAP Language Services
  • Hi Bruce,

    Good idea! Here are two screenshots. According to this, it should work, right?

             

     

    Here's a video showing the script in action. Not sure about the false start there at the beginning with the first word, but you can see how it works for all the words except the last one right before the period.

  • Hi Nora,

    Okay. Problem solved :-)

    To make the script work in Word and Notepad, you need a "Sleep, 200" after emptying the clipboard. Here is what the script looks like:

    ~LButton::
    SystemDoubleClickTime := DllCall("GetDoubleClickTime")

    If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < SystemDoubleClickTime)
    {
    ; Copy everything in the Clipboard
    oldClipboard := ClipboardAll

    ; Empty the Clipboard
    clipboard =

    Sleep, 200 ; without this the script breaks in Word and Notepad !!

    ; CTRL+C = copy text selected
    Send ^c
    ; Wait until the Clipboard grabs the content
    ClipWait

    AutoTrim, Off
    word = %Clipboard%
    StringLen, len1, word

    AutoTrim, On
    wordWithoutSpaces = %word%
    StringLen, len2, wordWithoutSpaces

    n := len1 - len2 ; introduce variable n so that multiple spaces can be eliminated !!
    If (n > 0)
    {
    Sendinput +{left %n%} ; SHIFT LEFT
    }

    ; Give contents back to the Clipboard
    Clipboard = %oldClipboard%

    ; Free memory of temp variable
    oldClipboard =

    }
    Return

  • Hi Nora,

    You might be able to reduce the "Sleep, 200".

    I can get away with "Sleep, 100", but if I try "Sleep, 75" the script breaks in Word and Notepad.

    Actually, the script isn't "breaking", it turns out it is just waiting for the "ClipWait" command to return, but it never does.

    To prevent "ClipWait" from waiting forever, you can change the "ClipWait" command to "ClipWait, 0.5"

    That way it will only wait a half a second. If you use too small a sleep period, the "ClipWait, 0.5" command will time out and the script will continue executing with the variable "word" empty, so it will appear that the command is not working.

    Best regards,
    Bruce Campbell
    ASAP Language Services
  • Bruce,

    Thank you so much, this does exactly what I need! I'll have a closer look tomorrow to understand the changes you made and hopefully learn from that.

    I'll be using this practically only in Studio. In fact, I'll be using it in Studio with Dragon while editing, so it will save me having to add and delete spaces after selecting a word.

    Thank you again!
  • Glad I could help Nora,

    Normally the Sleep would not be needed. I think what is happening is that the script starts running before the selection has stabilized.

    You double click and then there is a lag before the word is actually selected and ready to be copied with a Ctrl-C. The lag is longer in Word and Notepad than it is in Studio.

    So if the script starts immediately after a double click and zooms to the Ctrl-C before the word has actually been selected, then the Clipboard remains empty, and ClipWait waits forever.

    If you are using this mainly with Studio, then it can be sped up a bit using "IfWinNotActive". See the script below :-)

    Again, you might be able to reduce the "Sleep, 200", and you might be able to eliminate the "Sleep, 50" (and the else branch) altogether.

    Best regards,
    Bruce Campbell
    ASAP Language Services

    ~LButton::
    SystemDoubleClickTime := DllCall("GetDoubleClickTime")

    If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < SystemDoubleClickTime)
    {
    ; Copy everything in the Clipboard
    oldClipboard := ClipboardAll

    ; Empty the Clipboard
    clipboard =

    IfWinNotActive SDL Trados Studio
    {
    Sleep, 200 ; This sleep command is for all windows other than Studio. You might be able to use a number less than 200.
    }
    else
    {
    Sleep, 50 ; This sleep command is for Studio. I don't need to sleep in Studio, so you might be able to delete this line.
    }

    ; CTRL+C = copy text selected
    SendInput ^c

    ; Wait until the Clipboard grabs the content
    ClipWait, 0.5 ; Just in case you don't sleep long enough, the 0.5 keeps the script from waiting forever.

    AutoTrim, Off
    word = %Clipboard%
    StringLen, len1, word

    AutoTrim, On
    wordWithoutSpaces = %word%
    StringLen, len2, wordWithoutSpaces

    n := len1 - len2 ; introduce variable n so that multiple spaces can be eliminated !!
    If (n > 0)
    {
    Sendinput +{left %n%} ; SHIFT LEFT
    }

    ; Give contents back to the Clipboard
    Clipboard = %oldClipboard%

    ; Free memory of temp variable
    oldClipboard =

    }
    Return

  • Hi Nora,

    Eventualy I had time to have a look to the 2nd script. The reason it didn't work is because there was an error in the IfNotEqual line. Furthermore, I believe a Sleep line makes the script less erratic.

    Here is the script working:

    ~LButton::
        SystemDoubleClickTime := DllCall("GetDoubleClickTime")
        If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < SystemDoubleClickTime)
        {
            ; Copy everything in the Clipboard
            oldClipboard := ClipboardAll

            ; Empty the Clipboard
            clipboard =
            ; CTRL+ C = copy text selected
            Send ^c
            ; Wait until the Clipboard grabs the content
            ClipWait,0

            AutoTrim, Off
            word = %Clipboard%
            StringLen, len1, word

            AutoTrim, On
            wordWithoutSpaces = %word%
            StringLen, len2, wordWithoutSpaces    
            
            IfNotEqual len1,%len2%
            {
                Sleep, 100
                Sendinput +{left} ; SHIFT LEFT
            }

            ; Give contents back to the Clipboard
            Clipboard = %oldClipboard%

            ; Free memory of temp variable
            oldClipboard =
        }
    Return

    PS.: I wrote that 2nd script a couple of years ago and I couldn't find it when I wanted to use it for myslef and then I was lazy to redo it. Thanks for finding it and spotting the bug, Nora!

    … Jesús Prieto …

  • Hi Bruce,

    I've realized only now, (a year later!) that I never thanked you for this, so thank you!
  • Hi Nora,

    I am curious. What does this script do exactly?

    Olivier Den Hartigh
  • Hi Olivier,

    When this script is loaded, double-clicking on a word to select it trims the trailing space, if there's one, so that only the word is selected, without any spaces.

    This is the regular behavior when you double-click on a word:

    And this is the behavior with the script:

  • Hi Nora,

    Yes, this is definitely the kind of scripts I would like to put in my bag of tricks, correcting an annoying behaviour which I did not realize I could do without until you brought it up.
    So, thank you, Nora.

    It seems to work in Notepad++ and ScitTE4AutoHotkey which I use to edit my scripts, also in Word, but not in Studio.
    I am using this version of the script:


    ~LButton::
    SystemDoubleClickTime := DllCall("GetDoubleClickTime")
    If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < SystemDoubleClickTime)
    {
    ; Copy everything in the Clipboard
    oldClipboard := ClipboardAll

    ; Empty the Clipboard
    clipboard =
    ; CTRL+ C = copy text selected
    Send ^c
    ; Wait until the Clipboard grabs the content
    ClipWait,0

    AutoTrim, Off
    word = %Clipboard%
    StringLen, len1, word

    AutoTrim, On
    wordWithoutSpaces = %word%
    StringLen, len2, wordWithoutSpaces

    IfNotEqual len1,%len2%
    {
    Sleep, 100
    Sendinput +{left} ; SHIFT LEFT
    }

    ; Give contents back to the Clipboard
    Clipboard = %oldClipboard%

    ; Free memory of temp variable
    oldClipboard =
    }
    Return

    Olivier Den Hartigh
  • I've added
    Sleep 200
    before
    Send ^c
    With this Sleep command I let the Editor to actually select the word before executing the next line of code, so I've seen it's less erratic.