Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command for selecting, copying and pasting multiple file clipboard entries at once #751

Closed
u01jmg3 opened this issue Jul 22, 2017 · 11 comments

Comments

@u01jmg3
Copy link

u01jmg3 commented Jul 22, 2017

Relating to issue #234, I have a follow up query.

In the issue, instructions were given on how to copy multiple files:

  1. Copy file or files.
    • If they don't appear in CopyQ, you'll have to set proper format to save in "Item" configuration tab under "Data" item -- usually text/uri-list should be in the list.
  2. Select all items in CopyQ (Ctrl + A) and press Ctrl + C.
  3. Paste back into file manager
    • Pasting items on activation from main window or tray menu is also possible
  • This works great.
  • My follow up question is how in CopyQ I can bundle this up as a custom command to make it easier to run? Can this even be done?
@hluk
Copy link
Owner

hluk commented Jul 22, 2017

Could be done with the command below (add it to CopyQ).

[Command]
Command="
    copyq:
    var len = length()
    var uriList = ''
    for (var i = 0; i < len; ++i) {
      var path = str(read(mimeUriList, i))
      if (path)
        uriList += path + '\\n'
    }
    
    if (!uriList) {
      popup('No files available to paste')
      abort()
    }
    
    copy(mimeUriList, uriList)
    paste()"
GlobalShortcut=meta+alt+f
Icon=\xf114
Name=Paste All Files

But this pastes all files found in the first tab, maybe it would be better to stop at the first item which isn't a file. Not sure what your use case is.

@u01jmg3
Copy link
Author

u01jmg3 commented Jul 22, 2017

Thanks for this

Assuming CopyQ is empty, my use case is to use the standard Ctrl + C ability in Windows to add multiple files from multiple locations to the CopyQ clipboard one at a time.

I would then jump to CopyQ and using a custom command paste all the files I had in the clipboard to my current window.

Would that work? It's effectively using CopyQ as a basket/queue system to prevent having to copy and paste each file one at a time.

... maybe it would be better to stop at the first item which isn't a file...

With this command, I would expect to skip anything that isn't a file. Only interested in file objects that are in the clipboard.

@hluk
Copy link
Owner

hluk commented Jul 22, 2017

The command can be used without opening the application window. Just set the shortcut to whatever you like. Pressing the shortcut copies all files in CopyQ and pastes them to current window.

@u01jmg3
Copy link
Author

u01jmg3 commented Jul 22, 2017

  • Just tested the command out and it does everything I need it to but paste to the current window. Instead nothing is pasted.
  • However, if I do the standard Ctrl + V it pastes what it is supposed to.
  • What could be wrong?

@hluk
Copy link
Owner

hluk commented Jul 22, 2017

Seems that the target app is ignoring Shift+Insert (the default shortcut for pasting). To use Ctrl+V instead you have to change it manually in config file (see this comment; config file on Linux is ~/.config/copyq/copyq.conf).

@u01jmg3
Copy link
Author

u01jmg3 commented Jul 22, 2017

Appreciate your help

I'm on Windows so I added paste_with_ctrl_v_windows=".*" to the [General] section in %APPDATA%\copyq\copyq.ini but pasting is still not working using the 'Paste All Files' command.


As a side, it would also be good if only unique paths were allowed otherwise running the command several times will result in duplicate paths being copied to the clipboard.

@hluk
Copy link
Owner

hluk commented Jul 23, 2017

You can try putting an interval before pasting (e.g. sleep(500) to wait 500 milliseconds).

[Command]
Command="
    copyq:
    var len = length()
    var uriList = ''
    for (var i = 0; i < len; ++i) {
      var path = str(read(mimeUriList, i))
      if (path)
        uriList += path + '\\n'
    }
    
    if (!uriList) {
      popup('No files available to paste')
      abort()
    }
    
    copy(mimeUriList, uriList)
    sleep(500)
    paste()"
GlobalShortcut=meta+alt+f
Icon=\xf114
Name=Paste All Files

BTW, which file manager do you use?

@u01jmg3
Copy link
Author

u01jmg3 commented Jul 23, 2017

sleep(500) has no effect. Tried increasing the timeout and having a command that contains just paste() but neither work. Could this be a bug?

By file manager do you mean what mechanism handles the file copying and pasting? I recently switched from the standard Windows 10 mechanism to Teracopy.


As a side, it would also be good if only unique paths were allowed otherwise running the command several times will result in duplicate paths being copied to the clipboard.

Any suggestions on how to achieve this? Tried switching to an array and then using indexOf to determine whether the path has already been evaluated but running the command multiple times still duplicates paths to the clipboard which is not ideal.

@hluk
Copy link
Owner

hluk commented Jul 23, 2017

Could this be a bug?

To paste clipboard, CopyQ only tries to send the shortcut to active window. There is probably lot of apps where this doesn't work (timing is off when simulating key presses, the shortcut is send to different widget, app uses an incompatible way of capturing keys etc.).

There could be a better way to do this on Windows but it's not critical enough for me now so someone else needs to implement this.

Alternatively you can use an external app to paste the clipboard (e.g. instead of paste() use something like execute('paste.exe', mimeUriList, uriList)); autohotkey could work but I don't know its command line interface.

Tried switching to an array and then using indexOf to determine whether the path has already been evaluated

Can you share the code?

@u01jmg3
Copy link
Author

u01jmg3 commented Jul 23, 2017

  • Okay, I managed to achieve a working set up with the help of Autohotkey for pasting in Windows.

How it Works - "Paste All Files"

  • Copy files to the clipboard using the standard Ctrl + c combination
    • The key here is that multiple copy actions can be performed allowing you to queue or basket multiple files from different locations on your computer.
    • e.g. this could be 2 files from your desktop and 1 from your Dropbox folder amounting to 2 separate copy actions.
  • From the example above, to paste the 3 files into your current window, 1 paste action is required but you would need to use the slightly different key combination of Ctrl + Alt + v

ℹ️ Please note the F2 key has been allocated in CopyQ to do the copying part whilst Ctrl + Alt + v is used in Autohotkey to do the pasting part.


  • CopyQ Command
[Command]
Name=Paste All Files
Command="
    copyq:
    var itemsLength    = length(),
        itemRowNumbers = [],
        paths          = [],
        uriList        = '',    
        fileTotal      = 0
    
    for (var i = 0; i < itemsLength; ++i) {
        var path = str(read(mimeUriList, i))
    
        if (path) {
            var files = path.split('\\n')
            
            for (var j = 0; j < files.length; ++j) {
                path = files[j]
                
                // Check path has not been added before
                if (paths.indexOf(path) === -1) {
                    uriList += path + '\\n'
                    paths.push(path)
                    ++fileTotal                
                }
            }
            
            itemRowNumbers.push(i)        
        }
    }
    
    if (!uriList) {
        popup('No files available to copy')
        abort()
    } else {
        popup('Pasting ' + fileTotal + ' file' + (fileTotal > 1 ? 's' : ''))
        copy(mimeUriList, uriList)
    
        // Remove all items after copying
        // Must be done backwards
        i = (itemsLength - 1)
        while (i >= 0) {
            if (itemRowNumbers.indexOf(i) !== -1) {
                remove(i)
            }
    
            i--
        }
    }"
Icon=\xf114
GlobalShortcut=f2
  • Autohotkey
!^v:: ; Ctrl-Alt-v
Send {F2} ; Function F2 key
Sleep 500
Send ^v ; Ctrl-v
Sleep 500
clipboard = ; Clear the clipboard
Return

If CopyQ's paste() function is enhanced in the future, I can drop having to use Autohotkey.

@u01jmg3 u01jmg3 closed this as completed Jul 23, 2017
@hluk
Copy link
Owner

hluk commented Jul 24, 2017

Nice! Thanks for sharing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants