Menuekopf

Mittwoch, 20. Juli 2022

Some useful scripts for CopyQ (Clipboard Manager)

 

Anyone who needs to work productively on a PC will probably appreciate an external clipboard manager.


There are some very good clipboard managers out there, I eventually got stuck with Ditto and CopyQ, which are more or less in the same league. Both are awesome tools.


For now I'm using CopyQ again, although it's constantly changing. CopyQ can be adapted a little more to your own needs, but Ditto is a little easier to use. But if you want to get the most out of these clipboard managers, you have to delve deeper into both.


As I said, at the moment I am using CopyQ at daily work and I would like to present a few scripts that I'm using and that I did not find on the net in this form.


Here we go:


Scripts can be used to extend the functionality and adapt these tools to your own use cases.

You can use these scripts by the 'Paste Commands' button at the bottom of the commands configuration dialog.

Alternatively, you can also download the scripts from my website and add them to your commands using the 'Load Command' button. 
These scripts do not do any harm, but it is possible that your browser complains that they are malware when you try to download them.


Tab Switcher:

A script for switching the current tab by using keyboard in combination with a popup menu. I've used this shortcut (CTRL-G) with this function in Ditto very often and couldn't find a corresponding similar function in CopyQ.


[Command]
Name=Switch Tab
Command="
     copyq:
        var tabs = tab()
        var items = []
        for (i in tabs) {
           var engine = tabs[i]
           var item = {}
           item[mimeText] = engine.replace(new RegExp('&', 'g'), '')
           items.push(item)
        }
        var i = menuItems(items)
        if (i == -1)
           abort()
      target = tabs[i]    
       show(target)"
InMenu=true
Icon=\xf022
Shortcut=ctrl+g

Move To Tab:

A script for moving the selected clipboard items to a tab by using keyboard in combination with a popup menu. This script is based on the script above, so the selection popup menu looks the same.
I've used this shortcut (CTRL-M) with this function in Ditto very often and couldn't find a corresponding similar function in CopyQ.


[Command]
Name=Move To Tab
Command="
     copyq:
        var tabs = tab()
        var items = []
        for (i in tabs) {
           var engine = tabs[i]
           var item = {}
           item[mimeText] = engine.replace(new RegExp('&', 'g'), '')
           items.push(item)
        }
        var i = menuItems(items)
        if (i == -1)
           abort()
        target = tabs[i]    
        items = selecteditems()
        source = selectedtab()    
        for (i in items) {
           tab(source)
           item = getitem(items[i])
           tab(target)
           setitem(i, item)
        }
       tab(source)
         remove.apply(this, items)
       tab(target)
         selectitems.apply(this, items)
    "
InMenu=true
Icon=\xf061
Shortcut=ctrl+m

Tab for EMails:

A script that examines the clipboard entry for an email address when copying it and moves it to a tab called EMails.

Download: https://www.hrmprofil.de/Down/EMailsToTab.ini

[Command]
Name=Tab for EMails
Match="^([a-zA-Z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
Command="
    copyq:
    var tabName = 'EMails';
    var url = str(input()).trim()
    if (url === str(read(0)))
        abort()
    setData(mimeText, url)
    setData(mimeOutputTab, tabName)"
Input=text/plain
Automatic=true
Icon=\xf15b

Tab for YouTube Videos:

A script that examines the clipboard entry for a YouTube URL when copying it and moves it to a tab called YouTube within URL main tab. This script is based on a script called Tab for URLs with Title and Icon from this repository. Only the check for YouTube URLs has been added.

Note: This script must be placed below the mentioned script if you want use these two scripts together.


[Command]
Name=Tab for YouTube
Match=^https?://
Command="
    copyq:
    var tabName = '&URLs/&YouTube';
    function lower(data) {
        return str(data).toLowerCase()
    }
    function findHeader(reply, headerName) {
        reply.data  // fetches data and headers
        var headers = reply.headers
        for (var i in headers) {
            var header = headers[i]
            if (lower(header[0]) === headerName)
               return header[1]
        }
        return ''
    }
    function fetchContent(url, maxRedirects) {
        if (maxRedirects === undefined)
            maxRedirects = 4
        serverLog('Fetching: ' + url)
        var reply = networkGet(url)
        if (maxRedirects == 0)
            return reply
        var header = findHeader(reply, 'location')
        if (header)
            return fetchContent(header, maxRedirects - 1)
        return reply
    }
    function decodeHtml(html) {
        return html.replace(/&#(\\d+);/g, function(match, charCode) {
            return String.fromCharCode(charCode);
        });
    }
    function isHtml(reply) {
        var headers = reply.headers
        for (var i in headers) {
          var header = headers[i]
          if (lower(header[0]) === 'content-type')
             return lower(header[1]).indexOf(mimeHtml) === 0
        }
        return false
    }
    function grep(content, re) {
        return content ? (re.exec(content) || [])[1] : ''
    }
    function getTitle(content) {
        var title = grep(content, /<title[^>]*>([^<]*)<\\/title>/i)
        return title ? decodeHtml(title.trim()) : ''
    }
    function getFavicon(content) {
        var iconLine = grep(content, /<link([^>]*rel=[\"'](?:shortcut )?icon[\"'][^>]*)/i)
        var icon = grep(iconLine, /href=[\"']([^\"']*)/i)
        if (!icon)
          return ''
        // Icon path can be complete URL.
        if (icon.indexOf('://') != -1)
          return fetchContent(icon).data
        // Icon path can be missing protocol.
        if (icon.substr(0, 2) === '//') {
          var i = url.search(/\\/\\//)
          var protocol = (i == -1) ? 'http:' : url.substr(0, i)
          return fetchContent(protocol + icon).data
        }
        // Icon path can be relative to host URL.
        if (icon[0] === '/') {
          var baseUrl = url.substr(0, url.search(/[^\\/:](\\/|$)/) + 1)
          return fetchContent(baseUrl + icon).data
        }
        // Icon path can be relative to current URL.
        var baseUrl = url.substr(0, url.lastIndexOf('/') + 1)
        return fetchContent(baseUrl + icon).data
    }
    function isVideo(url) {
         var youtube = '^((?:https?:)?\\\\/\\\\/)?((?:www|m)\\\\.)?((?:youtube(-nocookie)?\\\\.com|youtu.be))(\\\\/(?:[\\\\w\\\\-]+\\\\?v=|embed\\\\/|v\\\\/)?)([\\\\w\\\\-]+)(\\\\S+)?$'
          yt = url.match(youtube)
          return yt
      //return false
    }
    var url = str(input()).trim()
    serverLog('Fetching icon and title: ' + url)

    // URL already added? (Just check the top of the list.)
    if (url === str(read(0)))
        abort()
    if (!isVideo(url))
      abort()

    // Fetch HTML.
    var reply = fetchContent(url)
    if (!isHtml(reply))
        abort()
    var content = str(reply.data)
    var title = getTitle(content)
    var icon = getFavicon(content)
    setData(mimeText, url)
    setData(mimeItemNotes, title || '')
    setData(mimeIcon, icon)
    setData(mimeOutputTab, tabName)
    "
Input=text/plain
Automatic=true
Icon=\xf0c1

Delete items after expire date:

A script that will delete all deletable (= unpinned) items from the (main) clipboard tab after expire date. In Ditto there was an option called Paste Entries expire after XY days. In CopyQ there is only an optional counter called Maximum numer of items in history. I prefer a clearing of the main history clipboard tab by days. Therefore I created this script command. You can assign expire days, so all clipboard items will be deleted that are older than the expire date.

Note1: This script is an add-on for a script called Store Copy Time. Therefore the script 'Store Copy Time' must be installed. You can download it from the offcial repository: https://github.com/hluk/copyq-commands/tree/master/Automatic

Note2: Please use this script at your own risk. This script won't do any harm, but since it deletes items and depends on various ancillary parameters, it may need some specific adjustments.


copyq:

// (main) tab for storing clipboard

var tabname = 'Zwis&chenablage';


// for safety -> you can uncomment this line if this script is working with your CopyQ environment

var tabdel = 'DeletedItems';


// NOTE: This script is an add-on for the script called Store Copy Time, it will not work without that script!

// https://github.com/hluk/copyq-commands/blob/master/Automatic/store-copy-time.ini

// must be equal to the mime string of 'Store Copy Time' command

// because the stored datetime will be extracted from this unique field!!!

var mimestring = 'application/x-copyq-user-copy-time';


const msPerDay = 24 * 60 * 60 * 1000; // Number of milliseconds per day

const today = new Date(Date.now())

// default expire days

var maxdays = 200;


var ndays = dialog(

'.title', 'Delete items >= x days?',

'Enter days', str(maxdays),

)

if (!ndays)

abort()

maxdays = Math.abs(parseInt(ndays));


// source = selectedtab()

tab(tabname)


var items = []

var icount = 0;

var sel = ItemSelection(tabname).selectAll() // selectRemovable()


for (i = sel.length-1; i >= 0; --i) {


if (!plugins.itempinned.isPinned(i)) {

var item = getItem(i)

// we need the preliminary work of 'Store Copy Time' command

if (item[mimestring] != undefined) {

var dtext = str(item[mimestring])

var sdate = new Date(Date.parse(dtext));

var days = (sdate.getTime() - today.getTime()) / msPerDay;

if (days <= maxdays * -1)

{

// just for debugging -> store expired items and list them in a context menu at the end

//var itm = {}

//itm[mimeText] = text // str(days)

//items.push(itm)


// for safety -> you can uncomment the next three lines if this script is working

// with your CopyQ environment, otherwise there will be a copy of your removed items :-)

tab(tabdel)

setItem(i, item)

tab(tabname)

// now remove the expired items

remove(i)

icount ++;

}

}

}

}

if (icount > 0)

popup("Items deleted:", icount, 5 * 1000)


// just for debugging -> store expired items and list them on a context menu

//var i = menuItems(items)




These self-made scripts make it easier for me to use CopyQ. The first two scripts were particularly important to me because they allow me a smooth transition from Ditto.
Besides, for me a smooth keyboard operation is crucial for a good clipboard manager.

Thanks for reading and as usual some good and powerful music at the end of my blog article :)


Keine Kommentare: