#!/usr/bin/env bash
#
# fff - fucking fast file-manager.
get_os() {
# Figure out the current operating system to set some specific variables.
# '$OSTYPE' typically stores the name of the OS kernel.
case $OSTYPE in
# Mac OS X / macOS.
darwin*)
opener=open
file_flags=bIL
;;
haiku)
opener=open
[[ -z $FFF_TRASH_CMD ]] &&
FFF_TRASH_CMD=trash
[[ $FFF_TRASH_CMD == trash ]] && {
FFF_TRASH=$(finddir -v "$PWD" B_TRASH_DIRECTORY)
mkdir -p "$FFF_TRASH"
}
;;
esac
}
setup_terminal() {
# Setup the terminal for the TUI.
# '\e[?1049h': Use alternative screen buffer.
# '\e[?7l': Disable line wrapping.
# '\e[?25l': Hide the cursor.
# '\e[2J': Clear the screen.
# '\e[1;Nr': Limit scrolling to scrolling area.
# Also sets cursor to (0,0).
printf '\e[?1049h\e[?7l\e[?25l\e[2J\e[1;%sr' "$max_items"
# Hide echoing of user input
stty -echo
}
reset_terminal() {
# Reset the terminal to a useable state (undo all changes).
# '\e[?7h': Re-enable line wrapping.
# '\e[?25h': Unhide the cursor.
# '\e[2J': Clear the terminal.
# '\e[;r': Set the scroll region to its default value.
# Also sets cursor to (0,0).
# '\e[?1049l: Restore main screen buffer.
printf '\e[?7h\e[?25h\e[2J\e[;r\e[?1049l'
# Show user input.
stty echo
}
clear_screen() {
# Only clear the scrolling window (dir item list).
# '\e[%sH': Move cursor to bottom of scroll area.
# '\e[9999C': Move cursor to right edge of the terminal.
# '\e[1J': Clear screen to top left corner (from cursor up).
# '\e[2J': Clear screen fully (if using tmux) (fixes clear issues).
# '\e[1;%sr': Clearing the screen resets the scroll region(?). Re-set it.
# Also sets cursor to (0,0).
printf '\e[%sH\e[9999C\e[1J%b\e[1;%sr' \
"$((LINES-2))" "${TMUX:+\e[2J}" "$max_items"
}
setup_options() {
# Some options require some setup.
# This function is called once on open to parse
# select options so the operation isn't repeated
# multiple times in the code.
# Format for normal files.
[[ $FFF_FILE_FORMAT == *%f* ]] && {
file_pre=${FFF_FILE_FORMAT/'%f'*}
file_post=${FFF_FILE_FORMAT/*'%f'}
}
# Format for marked files.
[[ $FFF_MARK_FORMAT == *%f* ]] && {
mark_pre=${FFF_MARK_FORMAT/'%f'*}
mark_post=${FFF_MARK_FORMAT/*'%f'}
}
# Find supported 'file' arguments.
file -I &>/dev/null || : "${file_flags:=biL}"
}
get_term_size() {
# Get terminal size ('stty' is POSIX and always available).
# This can't be done reliably across all bash versions in pure bash.
read -r LINES COLUMNS < <(stty size)
# Max list items that fit in the scroll area.
((max_items=LINES-3))
}
get_ls_colors() {
# Parse the LS_COLORS variable and declare each file type
# as a separate variable.
# Format: ':.ext=0;0:*.jpg=0;0;0:*png=0;0;0;0:'
[[ -z $LS_COLORS ]] && {
FFF_LS_COLORS=0
return
}
# Turn $LS_COLORS into an array.
IFS=: read -ra ls_cols <<< "$LS_COLORS"
for ((i=0;i<${#ls_cols[@]};i++)); {
# Separate patterns from file types.
[[ ${ls_cols[i]} =~ ^\*[^\.] ]] &&
ls_patterns+="${ls_cols[i]/=*}|"
# Prepend 'ls_' to all LS_COLORS items
# if they aren't types of files (symbolic links, block files etc.)
[[ ${ls_cols[i]} =~ ^(\*|\.) ]] && {
ls_cols[i]=${ls_cols[i]#\*}
ls_cols[i]=ls_${ls_cols[i]#.}
}
}
# Strip non-ascii characters from the string as they're
# used as a key to color the dir items and variable
# names in bash must be '[a-zA-z0-9_]'.
ls_cols=("${ls_cols[@]//[^a-zA-Z0-9=\\;]/_}")
# Store the patterns in a '|' separated string
# for use in a REGEX match later.
ls_patterns=${ls_patterns//\*}
ls_patterns=${ls_patterns%?}
# Define the ls_ variables.
# 'declare' can't be used here as variables are scoped
# locally. 'declare -g' is not available in 'bash 3'.
# 'export' is a viable alternative.
export "${ls_cols[@]}" &>/dev/null
}
get_w3m_path() {
# Find the path to the w3m-img library.
w3m_paths=(/usr/{pkg/,}{local/,}{bin,lib,libexec,lib64,libexec64}/w3m/w3mi*)
read -r w3m _ < <(type -p "$FFF_W3M_PATH" w3mimgdisplay "${w3m_paths[@]}")
}
get_mime_type() {
# Get a file's mime_type.