Created
June 25, 2023 03:21
-
-
Save hibiii/f28ca2083fc01ffa0585759efe715d50 to your computer and use it in GitHub Desktop.
Bash device to allow selecting files for file management in a more interactive way
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Interactive File Management Utilities by hibi | |
# | |
# This source file will let you select individual files and copy and move them | |
# around much like a graphical file manager would. Intended to be used with | |
# `source` in your bashrc. | |
# | |
# Usage: | |
# Fsel name1 [name2 [...]] - selects files and folders | |
# Funsel [name1 [name2 [...]]] - unselects files and folders, or all | |
# Fcp [destination] - copies the files here or to destination | |
# Fmv [destination] - moves the files here or to destination | |
# Flsel - lists the current selection | |
# | |
# NOTE: This file was made for bash. It is untested in other shells. | |
# File Select | |
# | |
# Selects files by one or more paths or globs, and store their paths into a | |
# temporary buffer (`_FMG_PATH_BUF`). The previous selection is not cleared, so | |
# you can select files from different directories. See `Funsel` to clear the | |
# selection. | |
function Fsel() { | |
if [[ ! $1 ]]; then | |
echo "usage: ${FUNCNAME[0]} name1 [name2 [...]]" | |
echo "selects files and folders into a buffer to move or paste later" | |
echo "(places filenames in a temporary buffer, glob matching)" | |
return 1 | |
fi | |
local files=("${_FMG_PATH_BUF[@]}") | |
local found_files=(`command ls -d "$@" 2>/dev/null`) | |
if [[ $? != 0 ]]; then | |
echo "error: could not find '$1'" | |
return 1 | |
fi | |
for file in "${found_files[@]}"; do | |
files+=("`realpath "$file"`") | |
done | |
# Deduplicate file paths | |
files=(`printf "%q\n" "${files[@]}" | sort -u`) | |
export _FMG_PATH_BUF=("${files[@]}") | |
return 0 | |
} | |
# File Unselect | |
# | |
# Removes files from the current selection. You can use either absolute paths, | |
# just the filename (or basename), or a glob. If no arguments are provided, then | |
# the entire selection is cleared. | |
function Funsel() { | |
if [[ ! $1 ]]; then | |
unset _FMG_PATH_BUF | |
return 0 | |
fi | |
local files=() | |
for current_file in "${_FMG_PATH_BUF[@]}"; do | |
local keep_this=true | |
for arg_glob in "$@"; do | |
if [[ $current_file == $arg_glob ]]; then | |
keep_this=false | |
fi | |
done | |
if [[ "$keep_this" == true ]]; then | |
files+=("$current_file") | |
fi | |
done | |
export _FMG_PATH_BUF=("${files[@]}") | |
return 0 | |
} | |
# Shared code between `Fmv` and `Fcp` functions. Not meant to be used normally. | |
function _ifmutilInternals@Paste() { | |
if [[ ${#_FMG_PATH_BUF[@]} < 1 ]]; then | |
echo "error: there are no selected files" | |
return 1 | |
fi | |
local destination | |
if [[ $2 ]]; then | |
if [[ -d "$2" || "${#_FMG_PATH_BUF[@]}" == 1 ]]; then | |
destination="$2" | |
else | |
echo "error: cannot copy or move to '$2' with multiple files as it is not a directory" | |
return 1 | |
fi | |
else | |
destination=. | |
fi | |
set -e | |
$1 "${_FMG_PATH_BUF[@]}" "$destination" | |
set +e | |
unset _FMG_PATH_BUF | |
return 0 | |
} | |
# File Move | |
# | |
# Move files to a destination directory, the current one. If given no arguments, | |
# files are moved to the current directory, otherwise to the given one. If the | |
# selection is a single file or directory, the destination may be the target | |
# path for the moved file. | |
function Fmv() { | |
if [[ $2 ]]; then | |
echo "error: too many arguments" | |
return 1 | |
fi | |
_ifmutilInternals@Paste mv "$1" | |
} | |
# File Copy | |
# | |
# Copies files to a destination directory, the current one. If there's a | |
# directory in the selection, it is copied recursively. If given no arguments, | |
# files are copied to the current directory, otherwise to the given one. If the | |
# selection is a single file or directory, the destination may be the target | |
# path for the copied file. | |
function Fcp() { | |
if [[ $2 ]]; then | |
echo "error: too many arguments" | |
return 1 | |
fi | |
_ifmutilInternals@Paste cp\ -r "$1" | |
} | |
# File List Selection | |
# | |
# List all the files currently selected. | |
function Flsel() { | |
if [[ ! $_FMG_PATH_BUF ]]; then | |
echo "selection is empty" | |
return 0; | |
fi | |
for entry in "${_FMG_PATH_BUF[@]}"; do echo "$entry"; done | column | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment