Script, How to Copy SELECTED Text (not in clipboard)

213 views
Skip to first unread message

Dennis Bareis

unread,
Feb 21, 2021, 12:10:35 AM2/21/21
to CopyQ
I'm wanting to set up a "copyq:" command on a hot key to read the current selected text and process it (I know how to get it from the clipboard).  Is that possible?  If so what javascript function do I use.

The documentation for the function I tried is probably meaningful to someone here as long as you use Linux and know what X11 mouse selection is...

copySelection(...) Same as copy(...) for Linux/X11 mouse selection  

Thanks, Dennis

Lukáš Holeček

unread,
Feb 21, 2021, 1:51:49 AM2/21/21
to Dennis Bareis, CopyQ
Hi Dennis,

There is a command template for modifying selected text: https://github.com/hluk/copyq-commands/blob/master/Templates/modify-selected-text.ini

It additionally pastes the text back, modifying the selection. But the basic idea to get the selected text is to trigger a copy operation (`copy()`) and get the copied text from clipboard (`str(clipboard())`).

BTW, if you are on Linux, you could use `var text = str(selection())` in some cases/apps and avoid the copy operation.

Lukas

--
You received this message because you are subscribed to the Google Groups "CopyQ" group.
To unsubscribe from this group and stop receiving emails from it, send an email to copyq+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/copyq/c21b756d-387f-4f36-b788-b0ec1ec05b49n%40googlegroups.com.

Dennis Bareis

unread,
Feb 21, 2021, 4:46:35 PM2/21/21
to CopyQ
Hi Lukáš,

Thanks for the quick reply, the "copy()" command did the trick. 

Could the documentation be improved to tell people what the function does rather than what it is similar to (I don't know Linux, X11 etc), I'm on Windows.  In some of the functions it isn't clear that the "selection" is, is it selected text or something selected in let's say a tab.  The documentation of the function could point to the examples you have provided.

Just to clarify, it doesn't modify the selection as the replacement text isn't selected (at least on Windows)?

Also, I have just copied this from other examples but I don't really know what it is doing (for example, I can't see any difference if copySelection() is commented out or not):

copy(Place)  // copy text to clipboard when text supplied, from selection otherwise?

//copySelection(Place)

paste()         //Paste current clipboard text?, is there a way to do this without updating the clipboard at all (or restoring things after)

Lukáš Holeček

unread,
Feb 22, 2021, 2:43:44 AM2/22/21
to Dennis Bareis, CopyQ
I thought "Linux/X11 mouse selection" might be clear that it's just for Linux, but the X11 part is confusing.

I'll try to change it to a link and drop the X11 part (it's basically GUI/windowing-system on Linux).

It would be also worth mentioning that the "selection" functions will do nothing on Windows and macOS.

Thanks for your feedback.

Lukas

Dennis Bareis

unread,
Feb 26, 2021, 5:10:24 PM2/26/21
to CopyQ
Hi Lukas,

Is there any way to avoid an approx 4 second delay if nothing is selected by perhaps:
* Checking for selection first? (I'm guessing no as otherwise copy() should be doing that)
* Adjusting the timeout?

Dennis

Lukáš Holeček

unread,
Feb 27, 2021, 4:36:55 AM2/27/21
to Dennis Bareis, CopyQ
Which delay do you mean?

Dennis Bareis

unread,
Feb 27, 2021, 5:12:40 AM2/27/21
to Lukáš Holeček, CopyQ
If I add logging before and after the copy(), it shows it takes 4 ish seconds when nothing is selected.

Lukáš Holeček

unread,
Feb 27, 2021, 5:54:08 AM2/27/21
to Dennis Bareis, CopyQ
Ah, yeah, `copy()` waits for a clipboard change. Maybe you can use:

    var wait = true;
    afterMilliseconds(0, function(){
        try {
            copy();
            doSomethingAfterSuccessfulCopy();
        } finally {
            wait = false;
        }
    });
    doSomethingWithoutWaiting();
    while (wait) {
        sleep(100);
    }


Dennis Bareis

unread,
Apr 10, 2021, 7:22:51 PM4/10/21
to CopyQ
Hi,

I'm just trying this out now due to a family emergency.  I have tried your solution but while it appears to be async in that further logging in the main line thread continues, it only seems to do so while the copy() hasn't yet started then pauses for the 4 second copy() timeout...

What I need is to replace "copy()" with "MyOwnCopy(500)" which will wait up to 500 ms for success or failure, it would raise an exception or return a return code to indicate success or failure but either way I'm not doing anything until I have the result.  

Lukáš Holeček

unread,
Apr 11, 2021, 5:00:30 AM4/11/21
to Dennis Bareis, CopyQ
Another try:

    var wait = true;
    afterMilliseconds(0, function() {
        try {
            copy();
        } finally {
            wait = false;
        }
    });

    // Wait no longer than ~500ms.
    for (var i = 0; i < 5 && wait; ++i) {
        sleep(100);
    }

    // Assume copy was successful if there is any text in clipboard.
    if (str(clipboard())) {
        // success in ~500ms
    } else {
        // failure in ~500ms
    }


Dennis Bareis

unread,
Jan 13, 2022, 12:50:53 AM1/13/22
to CopyQ
Hi,

I just got around to trying this again, this is my code basically just added a catch for debugging, it still hangs (only WAIT #1 executed). I also don't know why an exception was thrown.

This is my function:

//===========================================================================
function ReadSelectedTextIntoClipboard(HalfSecondsToWait)
//===========================================================================
{
    MyLog("[DEBUG] ReadSelectedTextIntoClipboard - START")


    var wait = true;
    afterMilliseconds(0, function() {
        try
        {
            MyLog("TRY: COPY")
            copy();
        }
        catch (error)
        {
            MyLog("CATCH: " + error)
        }
        finally
        {
            MyLog("FINALLY")
            wait = false;
        }
    });

    //--- Wait for wait to indicate completion ------------------------------
    for (var i = 1; i <= HalfSecondsToWait && wait; ++i)
    {
        //--- Sleep another half second -------------------------------------
        MyLog("Wait # " + i)
        sleep(500);

    }
    MyLog("Wait = " + wait)


    // Assume copy was successful if there is any text in clipboard.
    if (str(clipboard()))
    {
        MyLog("OK: CLIPBOARD = " + str(clipboard()))

        // success in ~500ms
    } else
    {
        MyLog("FAILED: CLIPBOARD = " + str(clipboard()))
    }

    MyLog("[DEBUG] ReadSelectedTextIntoClipboard - END")

}


and this is what was logged:

16:40:47.948: [DEBUG] ReadSelectedTextIntoClipboard - START
16:40:47.952: Wait # 1
16:40:47.955: TRY: COPY
16:40:51.662: CATCH: Error: Failed to copy to clipboard!
16:40:51.666: FINALLY
16:40:51.670: Exception in command "Look For Person Google etc (QUERY)": ScriptError: Failed to copy to clipboard!
16:40:51.670:    
16:40:51.670:    --- backtrace ---
16:40:51.670:    @eval code:835
16:40:51.670:    MyLog@eval code:258
16:40:51.670:    ReadSelectedTextIntoClipboard@eval code:852
16:40:51.670:    %entry@eval code:28
16:40:51.670:    %entry@eval code:2
16:40:51.670:    afterMillisecondsCallback
16:40:51.670:    eval:DB$/DB$-LookForPerson_Google_etc.js
16:40:51.670:    eval:source('DB$/DB$-LookForPerson...
16:40:51.670:    eval
16:40:51.670:    --- end backtrace ---
16:40:51.683: Command “Look For Person Google etc (QUERY)”
16:40:51.683:    Exit code: 4
16:40:51.683:    1. copyq:
16:40:51.683:    2. source('DB$/DB$-LookForPerson_Google_etc.js')

Reply all
Reply to author
Forward
0 new messages