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