O CopyQ permite criar scripts que estendem sua funcionalidade, possibilitando desde registrar o histórico de cópias até comparar conteúdos e exibir metadados como timestamps. Os scripts são escritos em JavaScript, e é possível encontrar exemplos na documentação oficial:
Estrutura de Dados: row, item e mimeType
No contexto do CopyQ:
row: representa uma posição no histórico de itens.item: um objeto contendo múltiplos dados associados a diferentes tipos MIME (mimeType).mimeType: define o tipo do conteúdo armazenado, podendo ser padrões comotext/plain,application/x-copyq-tags, ou customizados, comoapplication/x-copyq-user-copy-time.
Você pode acessar o valer de um campo específico com a sintaxe item[mimeType].
Funções Úteis da API
A seguir estão algumas funções frequentemente utilizaads nos scripts do CopyQ:
execute(comando, argumentos..., null, entrada)
Executa um comando externo. Tudo após null será passado via stdin. Exemplo equivalente:
echo entrada | comando argumentos
selectedItemData(índice)
Retorna os dados do item selecionado na posição índice. Use selectedItemData(índice)[mimeType] para acessar valores específicos.
selectedItemData()
Retorna todos os itens selecionados como um array. selectedItemData()[índice] equivale a selectedItemData(índice).
setSelectedItemData(índice, item)
Define os dados de um item selecionado em uma determinada posição.
selectedItems()
Retorna os índices das linhas dos itens atualmente selecionados. Pode-se usar selectedItems()[índice] para obter uma linha específica.
currentItem() e index()
Obtém o índice (base zero) do último item clicado durante seleção múltipla.
read([linha], mimeType...)
Lê dados de uma linha específica. Se omitido, assume-se a linha 0. Pode ler vários mimeTypes ao mesmo tempo.
write(linha, mimeType, dado, [mimeType, dado]...)
Escreve dados em uma linha específica. Alternativamente, aceita objetos completos de item.
getItem(linha) / setItem(linha, texto | item)
Recupera ou altera um item inteiro em uma linha. getItem(linha)[mimeType] é equivalente a read(mimeType, linha).
data(mimeType) / setData(mimeType, valor) / removeData(mimeType)
Manipula dados associados à última entrada copiada. Útil para adicionar metadados temporários.
Exemplo Prático: Registrar e Exibir Timestamp
// Salva a hora da cópia
const horario = dateString('yyyy-MM-dd hh:mm:ss')
setData('application/x-copyq-user-copy-time', horario)
// Adiciona ao campo de tags
const mimeTag = 'application/x-copyq-tags'
const tagsAntigas = data(mimeTag)
const novasTags = `${tagsAntigas}, ${horario}`
setData(mimeTag, novasTags)
Comparando Itens com WinMerge
// Recupera dois itens selecionados
let item1 = selectedItemData(0)?.[mimeText]
let item2 = selectedItemData(1)?.[mimeText]
let conteudo1, conteudo2
let hora1, hora2
if (!item2) {
// Caso não haja seleção, usa os últimos dois itens do histórico
conteudo1 = read(1)
conteudo2 = read(0)
hora1 = read('application/x-copyq-user-copy-time', 1)
hora2 = read('application/x-copyq-user-copy-time', 0)
} else {
conteudo1 = item2
conteudo2 = item1
hora1 = selectedItemData(1)['application/x-copyq-user-copy-time']
hora2 = selectedItemData(0)['application/x-copyq-user-copy-time']
}
function arquivoTemporario(conteudo) {
const arquivo = new TemporaryFile()
arquivo.openWriteOnly()
arquivo.write(conteudo)
arquivo.close()
return arquivo
}
const tmp1 = arquivoTemporario(conteudo1)
const tmp2 = arquivoTemporario(conteudo2)
// Executa comparação com WinMerge
execute(
'winmergeu',
'/e', '/x', '/u', '/fl',
'/dl', `Clipboard @ ${hora1}`,
'/dr', `Clipboard @ ${hora2}`,
tmp1.fileName(),
tmp2.fileName()
)
sleep(5000) // Mantém arquivos vivos enquanto o programa roda
Depuração de Scripts
Você pode testar seus scripts diretamente pelo terminal:
# Avaliar um script inline
copyq eval '<SCRIPT>'
# Ler script de um arquivo
cat script.js | copyq eval -
# Exemplo prático
./copyq.exe eval "print(JSON.stringify(selectedItemsData()[0]))"
No Windows, recomenda-se usar o Git Bash caso o cmd não mostre saída visível.
Inspecionando Objetos
Muitas vezes, ao tentar imprimir um objeto diretamente, você verá algo como "[object Object]". Para visualizar seu conteúdo completo, utilize:
print(JSON.stringify(objeto))