multiple file support for cclip

This commit is contained in:
2021-07-17 13:41:56 +03:00
parent 350dd576cb
commit 3e2250414f

View File

@@ -9,26 +9,29 @@ _help() {
can not be copied anymore. can not be copied anymore.
List clipboard names: List clipboard names:
$SELF l/list $SELF l/list [clipboard]
Make a link to clipboard: Make a link to clipboard:
$SELF c/copy filename[s] $SELF c/copy filename[s] [clipboard]
Paste files using clipboard: Paste files using clipboard:
$SELF p/paste [switches] clipboardname[s] $SELF p/paste [switches] [clipboardname[s]] [folder/]
Default folder: .
Switches: Switches:
-s Use soft link instead of file copying
-l Use hardlink instead of file copying -l Use hardlink instead of file copying
-k Keep clipboard link -k Keep clipboard link
-m Move instead of copy (can not be used with -h, can not -k) -m Move instead of copy (can not be used with -h, can not -k)
-a Paste all files from clipboard
Delete files using clipboard links: Delete source files using clipboard links (WARNING):
$SELF rm/remove clipboardname[s] $SELF rm/remove clipboardname[s]
Edit links manually:
$SELF e/edit clipboardname[s]
Clear clipboard links: Clear clipboard links:
$SELF d/del clipboardname[s] $SELF d/del clipboardname[s]
Clear all clipboard links: Clear all clipboard links:
$SELF D/Del clipboardname[s] $SELF D/Del
Get autocomplete: Get autocomplete:
$SELF autocomplete $SELF autocomplete
@@ -50,13 +53,18 @@ _load_config() {
} }
_list() { _list() {
cd "$STORAGE" if [[ ! $( ls -A "${STORAGE}" ) ]]; then
[[ $(ls -A) ]] || {
_msg "No clipboard entries" _msg "No clipboard entries"
return return
} fi
if [[ $# -gt 1 ]]; then
list_only="${2}"
fi
# TODO: single clipboard only
longest=4 longest=4
for n in *; do for f in ${STORAGE}/*; do
n=$( basename "$f" )
if [[ $longest -lt ${#n} ]]; then if [[ $longest -lt ${#n} ]]; then
longest=${#n} longest=${#n}
fi fi
@@ -65,16 +73,15 @@ _list() {
he=$( _qCol y U 2>/dev/null || true ) he=$( _qCol y U 2>/dev/null || true )
no=$( _qCol z 2>/dev/null || true ) no=$( _qCol z 2>/dev/null || true )
now=$( date -Idate ) now=$( date -Idate )
printf "%s%-${longest}s %-4s %-8s %s%s\n" "$he" Name Size Added Path "$no" printf "%s%-${longest}s %-10s %s%s\n" "$he" Name Added/Size Path "$no"
IFS=$'\n' IFS=$'\n'
while read n; do while read name; do
f=$( _get_item "$n" ) if [[ -n "$list_only" ]]; then
size=$( du -k -h -s --apparent-size "$f" | awk '{ print $1 }' ) if [[ ! "$list_only" = "$name" ]]; then
#type=$( stat --printf "%A" "$f" ) continue
#type=${type:0:1} fi
#if [[ "$type" = "-" ]]; then type=f; fi fi
date=$( stat --printf "%y" "${STORAGE}/$name" )
date=$( stat --printf "%y" "$n" )
if [[ "$date" = "$now"* ]]; then if [[ "$date" = "$now"* ]]; then
date=${date#* } date=${date#* }
date="${date:0:8}" date="${date:0:8}"
@@ -82,90 +89,151 @@ _list() {
date=${date%% *} date=${date%% *}
date="${date:2:8}" date="${date:2:8}"
fi fi
printf "%-${longest}s %-10s\n" \
"$name" \
"${date}"
while read f; do
if [[ ! -e "$f" ]]; then
size=MISS"!"
else
size=$( du -k -h -s --apparent-size "$f" | awk '{ print $1 }' )
fi
printf "%-${longest}s %-4s %-8s %s%s%s\n" \ printf "%-${longest}s %5s %s%s%s\n" \
"${n}" \ " " \
"$size" \ "$size" \
"${date}" \
"$hl" "${f}" \ "$hl" "${f}" \
"$no" "$no"
done < <( ls -t ) done < "${STORAGE}/$name"
done < <( ls "${STORAGE}" -t )
} }
_simple_list() { _simple_list() {
ls -1 "$STORAGE" ls -1 "$STORAGE"
} }
_get_item() {
# TODO: Items could be just symbolic links
cat "$STORAGE/$1"
}
_copy() { _copy() {
numargs=$#
if [[ $# -lt 2 ]]; then if [[ $# -lt 2 ]]; then
_help _help
fi fi
for (( i=2; i<=$#; i++ )); do for i in $@; do :; done
name=$( basename "${!i}" | tr -c '[:alnum:],_.\n\r' "-" ) if [[ ! -e "$i" ]]; then
CLIPBOARD=$( echo "$i" | tr -d './' | tr -cd '[[:print:]]' )
if [[ -z "$CLIPBOARD" ]]; then
_msg "Invalid clipboard name: '$i'"
exit 1
fi
numargs=$(( numargs - 1 ))
fi
for (( i=2; i<=$numargs; i++ )); do
#~ name=$( basename "${!i}" | tr -c '[:alnum:],_.\n\r' "-" )
name=$( basename "${!i}" )
origname="$name" origname="$name"
path=$( readlink -f "${!i}" ) path=$( readlink -f "${!i}" )
if [[ -d "$path" ]]; then if [[ -d "$path" ]]; then
path="$path/" path="$path/"
fi fi
post=0 printf "%s\n" "$path" >> "$STORAGE/${CLIPBOARD}"
while [[ -e "$STORAGE/${name}" ]]; do
post=$(( post + 1 ))
name="${origname}-${post}"
done done
printf "%s %s\n" "$name" "$path" sort -u -o "$STORAGE/${CLIPBOARD}" "$STORAGE/${CLIPBOARD}"
printf "%s" "$path" > "$STORAGE/${name}" _list l "$CLIPBOARD"
}
_edit() {
numargs=$#
if [[ $# -lt 2 ]]; then
_help
fi
for (( i=2; i<=$numargs; i++ )); do
CLIPBOARD=$( echo "${!i}" | tr -d './' | tr -cd '[[:print:]]' )
if [[ ! -f "$STORAGE/${!i}" ]]; then
echo "No such clipboard: ${!i}"
continue
fi
${VISUAL:-vim} "$STORAGE/${CLIPBOARD}"
_list l "$CLIPBOARD"
done done
} }
_paste() { _paste() {
if [[ $# -lt 2 ]]; then numargs=$#
_help keeplink=1
fi
for (( i=2; i<=$#; i++ )); do for (( i=2; i<=$#; i++ )); do
case ${!i} in case ${!i} in
-a) copy_all=1; ;; -s) softlink=1; ;;
-l) hardlink=1; ;; -l) hardlink=1; ;;
-k) keeplink=1; ;; -d) keeplink=0; ;;
-m) movelink=1; ;; -m) movelink=1; ;;
*)
if [[ ! -f "$STORAGE/${!i}" ]]; then
# no such clipboard
if [[ $i -gt 2 ]]; then
if [[ $i -eq $numargs ]]; then
# but argument is last (but not only)
OUTPUT=${!i}
numargs=$(( numargs - 1 ))
continue
fi
fi
echo No such clipboard: ${!i}
return
fi
;;
esac esac
done done
if [[ "$copy_all" = 1 ]]; then echo "Pasting to folder: $OUTPUT"
for n in "$STORAGE"/*; do mkdir -p "$OUTPUT"
_paste_single "$( basename "$n" )" for (( i=2; i<=$numargs; i++ )); do
done
return
fi
for (( i=2; i<=$#; i++ )); do
if [[ "${!i}" =~ ^-.$ ]]; then if [[ "${!i}" =~ ^-.$ ]]; then
continue continue
fi fi
_paste_single "${!i}" single_copied=1
_paste_clipboard "${!i}"
done done
if [[ ! "$single_copied" = 1 ]]; then
_paste_clipboard "$CLIPBOARD"
fi
} }
_paste_single() {
if [[ ! -e "$STORAGE/$1" ]];then _paste_clipboard() {
if [[ ! -f "$STORAGE/$1" ]];then
_msg "No such clipboard: '$1'" _msg "No such clipboard: '$1'"
return return
fi fi
path=$( _get_item "$1" ) while read f; do
if [[ ! -e "$path" ]]; then _paste_single "$f"
_msg "No such path: $1 -> '$path'" done < "${STORAGE}/$1"
if [[ "$movelink" = 1 ]]; then
keeplink=0
fi
if [[ "$softlink" = 1 ]]; then
keeplink=1
fi
if [[ ! "$keeplink" = 1 ]]; then
echo "Removing link: $1"
rm "$STORAGE/$1"
fi
}
_paste_single() {
if [[ ! -e "$1" ]]; then
_msg "No such path: $1"
return return
fi fi
target=$( basename "$path" ) target=$( basename "$1" )
if [[ -d "$path" ]]; then if [[ -d "$1" ]]; then
extension="" extension=""
basetarget="${target}" basetarget="${target}"
else else
@@ -180,55 +248,76 @@ _paste_single() {
origbase="$basetarget" origbase="$basetarget"
post=0 post=0
while [[ -e "${basetarget}${extension}" ]]; do while [[ -e "${OUTPUT}/${basetarget}${extension}" ]]; do
post=$(( post + 1 )) post=$(( post + 1 ))
basetarget="${origbase}-${post}" basetarget="${origbase}-${post}"
done done
target="${basetarget}${extension}" target="${basetarget}${extension}"
# -L dereference symlinks, -P no-deref (keep as symlink)
# -H follow symlinks
if [[ "$movelink" = 1 ]]; then if [[ "$movelink" = 1 ]]; then
keeplink=0 echo Moving "${1} -> $target"
echo Moving "${path} -> $target" mv "$1" "$target"
mv "$path" "$target" || return return $?
else fi
hardlinkswitch=""
if [[ "$softlink$hardlink" = "11" ]]; then
_msg "Can not do both soft and hard link"
exit 1
fi
if [[ "$softlink" = 1 ]]; then
echo Symbolic link "${1} -> ${OUTPUT}/$target"
ln -s "${1}" "${OUTPUT}/$target"
return $?
fi
if [[ "$hardlink" = 1 ]]; then if [[ "$hardlink" = 1 ]]; then
hardlinkswitch="-l" echo Hard link "${1} -> ${OUTPUT}/$target"
fi cp -aTl "${1}" "${OUTPUT}/$target"
echo Copying "${path} -> $target" return $?
cp -aT $hardlinkswitch "${path}" "$target" || return
fi
if [[ ! "$keeplink" = 1 ]]; then
echo "Removing link: $1"
rm "$STORAGE/$1"
fi fi
echo Copying "${1} -> ${OUTPUT}/$target"
cp -aT "${1}" "${OUTPUT}/$target" || return
} }
_remove() { _remove() {
# Remove files based on clipboard
if [[ $# -lt 2 ]]; then if [[ $# -lt 2 ]]; then
_help _help
fi fi
for (( i=2; i<=$#; i++ )); do for (( i=2; i<=$#; i++ )); do
if [[ ! -e "$STORAGE/${!i}" ]];then CLIPBOARD=$( echo "${!i}" | tr -d './' | tr -cd '[[:print:]]' )
_msg "No such clipboard: '${!i}'"
continue
fi
path=$( _get_item "${!i}" )
if [[ ! -e "$path" ]]; then
_msg "No such path: $1 -> '$path'"
continue
fi
echo "Removing data: ${path}" if [[ ! -e "$STORAGE/${CLIPBOARD}" ]];then
rm -ir "$path" _msg "No such clipboard: '${CLIPBOARD}'"
echo "Removing link: ${!i}" continue
rm "$STORAGE/${!i}" fi
_list l "$CLIPBOARD"
echo "Sure to delete? [Enter]"
read foo
while read f; do
if [[ ! -e "$f" ]]; then
_msg "No such path: '$f'"
continue
fi
echo "Removing SOURCE data: ${f}"
rm -r "$f" || exit 1
done < "${STORAGE}/$CLIPBOARD"
echo "Removing clipboard: ${CLIPBOARD}"
rm "$STORAGE/${CLIPBOARD}"
done done
} }
_delete() { # name _delete() { # name
if [[ $# -lt 2 ]]; then
_help
fi
for (( i=2; i<=$#; i++ )); do for (( i=2; i<=$#; i++ )); do
name=$( basename "${!i}" ) name=$( basename "${!i}" )
if [[ ! -e "$STORAGE/$name" ]]; then if [[ ! -e "$STORAGE/$name" ]]; then
@@ -236,7 +325,8 @@ _delete() { # name
EC=1 EC=1
continue continue
fi fi
printf "Removing %s: %s\n" "$name" $( _get_item "$name" ) printf "Clearing %s:\n" "$name"
cat "$STORAGE/$name"
rm "$STORAGE/$name" rm "$STORAGE/$name"
done done
} }
@@ -247,7 +337,7 @@ _delete_all() {
} }
_simple_list _simple_list
[[ "$FORCE" -ne 1 ]] && { [[ "$FORCE" -ne 1 ]] && {
read -p "Really delete the whole clipboard? ($STORAGE) Break to cancel. " foo read -p "Really clear the whole clipboard? ($STORAGE) Break to cancel. " foo
} }
rm -vrf "$STORAGE/" rm -vrf "$STORAGE/"
mkdir "$STORAGE" mkdir "$STORAGE"
@@ -268,7 +358,7 @@ if [[ $COMP_CWORD -eq 1 ]]; then
fi fi
if [[ $COMP_CWORD -eq 2 ]]; then if [[ $COMP_CWORD -eq 2 ]]; then
case ${COMP_WORDS[$(( $COMP_CWORD - 1 ))]} in case ${COMP_WORDS[$(( $COMP_CWORD - 1 ))]} in
p|paste|d*|rm|remove) p|paste|d*|e|edit|rm|remove)
local IFS=$'"'"'\n'"'"' local IFS=$'"'"'\n'"'"'
local remotelist=( $( eval CCLIP_EXEC simplelist ) ) local remotelist=( $( eval CCLIP_EXEC simplelist ) )
COMPREPLY=( $(compgen -W "${remotelist[*]}" -- $curr_arg ) ); COMPREPLY=( $(compgen -W "${remotelist[*]}" -- $curr_arg ) );
@@ -294,11 +384,14 @@ done
_load_config _load_config
source qolop &>/dev/null || true source qolop &>/dev/null || true
CMD="${1:-list}" CMD="${1:-list}"
[[ "$CMD" = help || "$CMD" = "-h" || "$CMD" = "--help" ]] && { _help; } CLIPBOARD=0
[[ "$CMD" = "l" || "$CMD" = "list" ]] && { _list; } OUTPUT=.
[[ "$CMD" = help || "$CMD" = h || "$CMD" = "-h" || "$CMD" = "--help" ]] && { _help; }
[[ "$CMD" = "l" || "$CMD" = "list" ]] && { _list "$@"; }
[[ "$CMD" = "c" || "$CMD" = "copy" ]] && { _copy "$@"; } [[ "$CMD" = "c" || "$CMD" = "copy" ]] && { _copy "$@"; }
[[ "$CMD" = "d" || "$CMD" = "delete" || "$CMD" = "del" ]] && { _delete "$@"; } [[ "$CMD" = "d" || "$CMD" = "delete" || "$CMD" = "del" ]] && { _delete "$@"; }
[[ "$CMD" = "D" || "$CMD" = "Delete" || "$CMD" = "Del" ]] && { _delete_all; } [[ "$CMD" = "D" || "$CMD" = "Delete" || "$CMD" = "Del" ]] && { _delete_all; }
[[ "$CMD" = "e" || "$CMD" = "edit" ]] && { _edit "$@"; }
[[ "$CMD" = "p" || "$CMD" = "paste" ]] && { _paste "$@"; } [[ "$CMD" = "p" || "$CMD" = "paste" ]] && { _paste "$@"; }
[[ "$CMD" = "rm" || "$CMD" = "remove" ]] && { _remove "$@"; } [[ "$CMD" = "rm" || "$CMD" = "remove" ]] && { _remove "$@"; }