#!/usr/bin/env sh # Description: Open a Drag and drop window, to drop files onto other programs. # Also provides drag and drop window for files. # # Dependencies: # - dragon (https://github.com/mwh/dragon), or # - kitty (https://github.com/kovidgoyal/kitty) # # Notes if using dragon: # 1. Files that are dropped will be added to nnn's selection # Some web-based files will be downloaded to current dir # with curl and it may overwrite some existing files # 2. The user has to mm to clear nnn's selection first # # Shell: POSIX compliant # Author: 0xACE # If you want system notification, put this equal to 1 notify=0 selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection} resp=f all= if type dragon-drag-and-drop >/dev/null 2>&1; then dnd="dragon-drag-and-drop" elif type dragon-drop >/dev/null 2>&1; then dnd="dragon-drop" elif [ "$TERM" = "xterm-kitty" ]; then dnd="kitten dnd" else dnd="dragon" fi add_file() { printf '%s\0' "$@" >>"$selection" } use_all() { printf "mark --all (a) [default=none]: " read -r resp if [ "$resp" = "a" ]; then all="--all" else all="" fi } if [ -s "$selection" ]; then printf "Drop file (r). Drag selection (s), Drag current directory (d) or drag current file (f) [default=f]: " read -r resp else printf "Drop file (r). Drag current directory (d) or drag current file (f) [default=f]: " read -r resp if [ "$resp" = "s" ]; then resp=f fi fi clear_tui() { pid=$! reset # nnn to dnd wait $pid reset # dnd to nnn } if [ "$dnd" = "kitten dnd" ]; then if [ "$resp" = "s" ]; then # shellcheck disable=SC2086 xargs -0 $dnd 2>/dev/null <"$selection" & elif [ "$resp" = "d" ]; then $dnd "$PWD/"* 2>/dev/null & else # send one or receive $dnd "$1" 2>/dev/null & fi clear_tui if [ "$resp" = "s" ]; then [ -p "$NNN_PIPE" ] && printf "-" >"$NNN_PIPE" # clear selection fi else if [ "$resp" = "s" ]; then use_all sed -z 's|'"$PWD/"'||g' <"$selection" | xargs -0 "$dnd" "$all" 2>/dev/null & elif [ "$resp" = "d" ]; then use_all "$dnd" "$all" "$PWD/"* 2>/dev/null & elif [ "$resp" = "r" ]; then true >"$selection" "$dnd" --print-path --target 2>/dev/null | while read -r f; do if printf "%s" "$f" | grep -q '^\(https\?\|ftps\?\|s\?ftp\)://'; then if output=$(curl -fsLJOS "$f" 2>&1); then filename="$(basename "${f%%\?*}")" add_file "$PWD/$filename" if [ $notify = 1 ]; then notify-send "Download Complete" "Finished downloading $filename" fi else if [ $notify = 1 ]; then notify-send "Download Failed" "$output" else echo "Download Failed: $output" fi fi elif [ -e "$f" ]; then add_file "$f" fi done & elif [ -n "$1" ] && [ -e "$1" ]; then "$dnd" "$1" 2>/dev/null & fi fi