You are not logged in.

#1 2020-12-31 06:14:31

karabaja4
Member
From: Croatia
Registered: 2008-09-14
Posts: 896

clip.sh - turn xclip into a clipboard manager

Hello.

I made this script that effectively turns xclip into a clipboard manager for XA_CLIPBOARD (CTRL+C/CTRL+V).

Motivation:

No clipboard manager really did what I wanted, which is:

  • Keep the clipboard data consistently after closing the application.

  • Don't depend on KDE or Gnome or depend on any daemons, so it's suitable for running in non-DE environment, e.g. Openbox.

  • Support images, and copying files around in common file managers (or any other funky format I may encounter).

  • Do not impact any other applications in any way.

  • I don't care about history.

xfce4-clipman-plugin was close to meet the requirements I had, but was causing slow exit for other applications.

This script keeps an instance of xclip running, and tries to guess the format based on '_pref' array defined in the script.
For example, if one of the available targets in the clipboard is 'image/png' and it finds 'image/png' in _pref, it will use that format first (if it doesn't find the format, it will default to 'UTF8_STRING').
This works reasonably well, and makes the clipboard behave like on Windows regarding pasting data when the application closes.

The script:

#!/bin/bash

set -uo pipefail

# TARGETS configuration
declare -ar _pref=(
    "image/png"
    "text/uri-list"
    "code/file-list"
)

_usage() {
    echo "Usage:"
    echo "  ./$(basename "${0}")"
    echo "Configuration:"
    echo "  Add your preferred TARGETS to the '_pref' array in the script to handle custom formats."
    echo "  Current _pref:"
    printf -- '  - %s\n' "${_pref[@]}"
    exit 1
}

(( ${#} > 0 )) && _usage

_log() {
    echo -e "\033[32m->\033[0m" "${@}"
}

_iteration() {
    local -r _utf8="UTF8_STRING"

    # target test of current selection
    local _ttres
    _ttres="$(xclip -selection clipboard -o -t TARGETS)"
    local -ir _ttec=${?}
    _log "TARGETS check exited with: ${_ttec}"
    local -a _targets
    mapfile -t _targets <<< "${_ttres}"

    if (( _ttec != 0 || ${#_targets[@]} == 0 ))
    then
        # on empty wait for any selection
        _log "Waiting on initial selection with: ${_utf8}"
        xclip -verbose -in -selection clipboard -t "${_utf8}" < /dev/null
    else
        _log "Preferred targets: ${_pref[*]}"
        _log "Clipboard targets: ${_targets[*]}"

        # join both lists together, and print first item of targets occuring in _pref
        local -r _match="$(printf '%s\n' "${_targets[@]}" "${_pref[@]}" "${_utf8}" | awk 'a[$0]++' | head -n1)"

        if [[ -n ${_match} ]]
        then
            _log "Matched target: ${_match}"
            xclip -verbose -out -selection clipboard -t "${_match}" | xclip -verbose -in -selection clipboard -t "${_match}"
        else
            _log "Unable to match targets"
            sleep 1
        fi
    fi
}

while true
do
    _log "$(head -c 80 /dev/zero | tr '\0' '-')"
    _iteration
done

Configuration:

Copying text, images, and files in some file managers should work out of the box.

If you need to support some custom format, run the script and examine the targets when you copy the data, e.g.:

-> Preferred targets: image/png text/uri-list code/file-list
-> Clipboard targets: TIMESTAMP TARGETS SAVE_TARGETS MULTIPLE strange/format

Add the strange/format from clipboard targets to '_pref' array.

github

* 01.01.2020. fixed some issues
* 02.02.2020. code cleanup

Last edited by karabaja4 (2021-01-06 21:34:39)

Offline

Board footer

Powered by FluxBB