Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f9feaf9b4 | ||
|
|
fbc3227515 | ||
|
|
02a8adadc4 | ||
|
|
1e6fdd9e29 | ||
|
|
12c85202f9 | ||
|
|
7f41df91f1 |
+21
-3
@@ -17,6 +17,7 @@ REQUIREMENTS
|
|||||||
- Optional: wl-copy / xclip / xsel / pbcopy (for clipboard support)
|
- Optional: wl-copy / xclip / xsel / pbcopy (for clipboard support)
|
||||||
- Optional: mpv, vlc, feh, zathura, etc. (for smart file opening)
|
- Optional: mpv, vlc, feh, zathura, etc. (for smart file opening)
|
||||||
- Optional: readlink (for symlink display)
|
- Optional: readlink (for symlink display)
|
||||||
|
- Optional: file (for MIME type detection)
|
||||||
|
|
||||||
|
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
@@ -41,9 +42,15 @@ Manual installation:
|
|||||||
|
|
||||||
USAGE
|
USAGE
|
||||||
-----
|
-----
|
||||||
sfm
|
sfm [path]
|
||||||
|
|
||||||
sfm will opens in the current directory.
|
If no path is given, sfm opens in the current directory.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
sfm # open in current directory
|
||||||
|
sfm /mnt/data # open at a specific path
|
||||||
|
sfm ~ # open home directory
|
||||||
|
sfm .. # open parent directory
|
||||||
|
|
||||||
|
|
||||||
NAVIGATION
|
NAVIGATION
|
||||||
@@ -68,11 +75,23 @@ DISPLAY TOGGLES
|
|||||||
---------------
|
---------------
|
||||||
. Toggle hidden files (dotfiles)
|
. Toggle hidden files (dotfiles)
|
||||||
T Toggle size/date detail column
|
T Toggle size/date detail column
|
||||||
|
P Toggle preview pane (right side)
|
||||||
s Cycle sort mode: name -> size -> date
|
s Cycle sort mode: name -> size -> date
|
||||||
i Show file info (permissions, size, date) in status bar
|
i Show file info (permissions, size, date) in status bar
|
||||||
R Refresh current directory listing
|
R Refresh current directory listing
|
||||||
|
|
||||||
|
|
||||||
|
PREVIEW PANE
|
||||||
|
------------
|
||||||
|
Press P to toggle the preview pane on the right side of the screen.
|
||||||
|
The list pane takes the left half, preview takes the right half.
|
||||||
|
|
||||||
|
Text files Shows file contents line by line
|
||||||
|
Directories Shows entry count
|
||||||
|
Symlinks Shows link target
|
||||||
|
Binary files Shows file size
|
||||||
|
|
||||||
|
|
||||||
FILE OPERATIONS
|
FILE OPERATIONS
|
||||||
---------------
|
---------------
|
||||||
r Rename selected entry
|
r Rename selected entry
|
||||||
@@ -164,4 +183,3 @@ DATA FILES
|
|||||||
----------
|
----------
|
||||||
~/.config/sfm/bookmarks Saved bookmarks (one path per line)
|
~/.config/sfm/bookmarks Saved bookmarks (one path per line)
|
||||||
~/.local/share/sfm-trash/ Trashed files
|
~/.local/share/sfm-trash/ Trashed files
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,11 @@ term_rows() { tput_cmd lines || echo 24; }
|
|||||||
term_cols() { tput_cmd cols || echo 80; }
|
term_cols() { tput_cmd cols || echo 80; }
|
||||||
|
|
||||||
# --- state ---
|
# --- state ---
|
||||||
CWD="$PWD"
|
if [ -n "$1" ]; then
|
||||||
|
CWD=$(cd "$1" 2>/dev/null && pwd) || { printf 'sfm: %s: no such directory\n' "$1" >&2; exit 1; }
|
||||||
|
else
|
||||||
|
CWD=$(cd "$PWD" 2>/dev/null && pwd) || CWD="/"
|
||||||
|
fi
|
||||||
SEL=0
|
SEL=0
|
||||||
OFFSET=0
|
OFFSET=0
|
||||||
PREV_SEL=0
|
PREV_SEL=0
|
||||||
@@ -79,9 +83,20 @@ INFO_MSG="" # ephemeral message shown in botbar
|
|||||||
SHOW_HIDDEN=0 # 1 = show dotfiles
|
SHOW_HIDDEN=0 # 1 = show dotfiles
|
||||||
SORT_MODE="name" # name | size | date
|
SORT_MODE="name" # name | size | date
|
||||||
SHOW_DETAILS=0 # 1 = show size+date column
|
SHOW_DETAILS=0 # 1 = show size+date column
|
||||||
|
SHOW_PREVIEW=0 # 1 = show preview pane on right
|
||||||
TRASH_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/sfm-trash"
|
TRASH_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/sfm-trash"
|
||||||
mkdir -p "$TRASH_DIR"
|
mkdir -p "$TRASH_DIR"
|
||||||
PREV_CWD="" # last visited directory, for jumping back
|
PREV_CWD="" # last visited directory, for jumping back
|
||||||
|
|
||||||
|
# normalise CWD: resolve to absolute canonical path, no double slashes
|
||||||
|
norm_cwd() {
|
||||||
|
CWD=$(cd "$CWD" 2>/dev/null && pwd) || CWD="/"
|
||||||
|
# squeeze any double slashes (some systems return // for //<path>)
|
||||||
|
CWD=$(printf '%s' "$CWD" | tr -s '/')
|
||||||
|
}
|
||||||
|
|
||||||
|
# safely join CWD with a name, avoiding double slash at root
|
||||||
|
joinpath() { [ "$CWD" = "/" ] && printf '/%s' "$1" || printf '%s/%s' "$CWD" "$1"; }
|
||||||
BOOKMARK_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/sfm/bookmarks"
|
BOOKMARK_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/sfm/bookmarks"
|
||||||
mkdir -p "$(dirname "$BOOKMARK_FILE")"
|
mkdir -p "$(dirname "$BOOKMARK_FILE")"
|
||||||
[ -f "$BOOKMARK_FILE" ] || touch "$BOOKMARK_FILE"
|
[ -f "$BOOKMARK_FILE" ] || touch "$BOOKMARK_FILE"
|
||||||
@@ -94,17 +109,19 @@ load_entries() {
|
|||||||
# build list of dir names then file names, including dotfiles if enabled
|
# build list of dir names then file names, including dotfiles if enabled
|
||||||
for d in "$CWD"/*/; do
|
for d in "$CWD"/*/; do
|
||||||
[ -d "$d" ] || continue
|
[ -d "$d" ] || continue
|
||||||
|
[ -L "${d%/}" ] && continue # symlinks handled separately
|
||||||
name="${d%/}"; name="${name##*/}"
|
name="${d%/}"; name="${name##*/}"
|
||||||
[ "$name" = "*" ] && continue
|
[ "$name" = "*" ] && continue
|
||||||
case "$name" in .*) continue ;; esac # skip dotdirs here, handle below
|
case "$name" in .*) continue ;; esac
|
||||||
ENTRIES="$ENTRIES
|
ENTRIES="$ENTRIES
|
||||||
${name}/"
|
${name}/"
|
||||||
COUNT=$((COUNT + 1))
|
COUNT=$((COUNT + 1))
|
||||||
done
|
done
|
||||||
if [ "$SHOW_HIDDEN" = "1" ]; then
|
if [ "$SHOW_HIDDEN" = "1" ]; then
|
||||||
for d in "$CWD"/./; do : ; done # no-op, just to avoid error
|
for d in "$CWD"/./; do : ; done
|
||||||
for d in "$CWD"/.*/; do
|
for d in "$CWD"/.*/; do
|
||||||
[ -d "$d" ] || continue
|
[ -d "$d" ] || continue
|
||||||
|
[ -L "${d%/}" ] && continue # symlinks handled separately
|
||||||
name="${d%/}"; name="${name##*/}"
|
name="${d%/}"; name="${name##*/}"
|
||||||
[ "$name" = "." ] || [ "$name" = ".." ] && continue
|
[ "$name" = "." ] || [ "$name" = ".." ] && continue
|
||||||
[ "$name" = ".*" ] && continue
|
[ "$name" = ".*" ] && continue
|
||||||
@@ -416,6 +433,85 @@ render_row() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_preview() {
|
||||||
|
_rows=$1; _cols=$2; _px=$3; _pw=$4
|
||||||
|
entry=$(get_entry "$SEL")
|
||||||
|
# clear preview area first
|
||||||
|
_r=2
|
||||||
|
while [ "$_r" -le $((_rows - 1)) ]; do
|
||||||
|
goto "$_r" "$_px"
|
||||||
|
printf '\033[K'
|
||||||
|
_r=$((_r + 1))
|
||||||
|
done
|
||||||
|
[ -z "$entry" ] && return
|
||||||
|
_path=$(joinpath "${entry%/}"); _path="${_path%@}"
|
||||||
|
|
||||||
|
# draw vertical divider
|
||||||
|
_r=2
|
||||||
|
while [ "$_r" -le $((_rows - 1)) ]; do
|
||||||
|
goto "$_r" $((_px - 1))
|
||||||
|
printf '%s|%s' "${CYAN}" "${RESET}"
|
||||||
|
_r=$((_r + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
case "$entry" in
|
||||||
|
*/)
|
||||||
|
# directory: show entry count
|
||||||
|
_dc=$(ls -1 "$_path" 2>/dev/null | wc -l | tr -d '[:space:]')
|
||||||
|
goto 2 "$_px"
|
||||||
|
printf '%s[dir] %s items%s' "${CYAN}" "${_dc}" "${RESET}"
|
||||||
|
;;
|
||||||
|
*@)
|
||||||
|
# symlink
|
||||||
|
_tgt=$(readlink "$_path" 2>/dev/null || echo "?")
|
||||||
|
goto 2 "$_px"
|
||||||
|
printf '%s[symlink]%s' "${MAGENTA}${BOLD}" "${RESET}"
|
||||||
|
goto 3 "$_px"
|
||||||
|
printf '%s-> %s%s' "${WHITE}" "${_tgt}" "${RESET}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# detect if text via extension or mime
|
||||||
|
_ext="${entry##*.}"
|
||||||
|
_ext=$(printf '%s' "$_ext" | tr '[:upper:]' '[:lower:]')
|
||||||
|
_is_text=0
|
||||||
|
case "$_ext" in
|
||||||
|
txt|md|markdown|rst|log|conf|cfg|ini|toml|yaml|yml|\
|
||||||
|
sh|bash|zsh|py|rb|pl|lua|js|ts|json|xml|html|htm|\
|
||||||
|
css|c|h|cpp|rs|go|java|php|r|sql|vim|env|gitignore|\
|
||||||
|
diff|patch|csv|tsv|lock|mod|sum) _is_text=1 ;;
|
||||||
|
esac
|
||||||
|
if [ "$_is_text" = "0" ] && command -v file >/dev/null 2>&1; then
|
||||||
|
case "$(file --mime-type -b "$_path" 2>/dev/null)" in
|
||||||
|
text/*) _is_text=1 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [ "$_is_text" = "1" ]; then
|
||||||
|
_max_lines=$((_rows - 3))
|
||||||
|
_line_n=0
|
||||||
|
while IFS= read -r _line && [ "$_line_n" -lt "$_max_lines" ]; do
|
||||||
|
# truncate to preview width
|
||||||
|
if [ "${#_line}" -gt "$((_pw - 1))" ]; then
|
||||||
|
_line=$(printf '%s' "$_line" | cut -c1-$((_pw - 2)))
|
||||||
|
_line="${_line}~"
|
||||||
|
fi
|
||||||
|
goto "$((_line_n + 2))" "$_px"
|
||||||
|
printf '%s%s%s' "${WHITE}" "$_line" "${RESET}"
|
||||||
|
_line_n=$((_line_n + 1))
|
||||||
|
done < "$_path"
|
||||||
|
if [ "$_line_n" -eq 0 ]; then
|
||||||
|
goto 2 "$_px"
|
||||||
|
printf '%s(empty file)%s' "${WHITE}" "${RESET}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# binary / unknown
|
||||||
|
goto 2 "$_px"
|
||||||
|
_sz=$(ls -lh "$_path" 2>/dev/null | awk '{print $5}')
|
||||||
|
printf '%s[binary] %s%s' "${YELLOW}" "${_sz}" "${RESET}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
draw_topbar() {
|
draw_topbar() {
|
||||||
_cols=$1
|
_cols=$1
|
||||||
spaces=$(printf '%*s' "$_cols" '')
|
spaces=$(printf '%*s' "$_cols" '')
|
||||||
@@ -426,7 +522,7 @@ draw_topbar() {
|
|||||||
draw_botbar() {
|
draw_botbar() {
|
||||||
_rows=$1; _cols=$2
|
_rows=$1; _cols=$2
|
||||||
if [ "$SEARCHING" = "1" ]; then
|
if [ "$SEARCHING" = "1" ]; then
|
||||||
info=" $((SEL + 1))/${COUNT} ${CWD}"
|
info=" $([ "$COUNT" -eq 0 ] && echo 0 || echo $((SEL + 1)))/${COUNT} ${CWD}"
|
||||||
keys=" search: ${FILTER} "
|
keys=" search: ${FILTER} "
|
||||||
maxk=$((_cols - ${#info} - 1))
|
maxk=$((_cols - ${#info} - 1))
|
||||||
[ "${#keys}" -gt "$maxk" ] && keys=$(printf '%s' "$keys" | cut -c1-"$maxk")
|
[ "${#keys}" -gt "$maxk" ] && keys=$(printf '%s' "$keys" | cut -c1-"$maxk")
|
||||||
@@ -440,9 +536,8 @@ draw_botbar() {
|
|||||||
"${YELLOW}${keys}" \
|
"${YELLOW}${keys}" \
|
||||||
"${RESET}"
|
"${RESET}"
|
||||||
elif [ -n "$INFO_MSG" ]; then
|
elif [ -n "$INFO_MSG" ]; then
|
||||||
info=" $((SEL + 1))/${COUNT} ${CWD}"
|
info=" $([ "$COUNT" -eq 0 ] && echo 0 || echo $((SEL + 1)))/${COUNT} ${CWD}"
|
||||||
msg=" ${INFO_MSG} "
|
msg=" ${INFO_MSG} " padlen=$((_cols - ${#info} - ${#msg}))
|
||||||
padlen=$((_cols - ${#info} - ${#msg}))
|
|
||||||
[ "$padlen" -lt 0 ] && padlen=0
|
[ "$padlen" -lt 0 ] && padlen=0
|
||||||
pad=$(printf '%*s' "$padlen" '')
|
pad=$(printf '%*s' "$padlen" '')
|
||||||
goto "$_rows" 1
|
goto "$_rows" 1
|
||||||
@@ -461,7 +556,7 @@ draw_botbar() {
|
|||||||
[ "$SORT_MODE" != "name" ] && _ind="${_ind} [sort:${SORT_MODE}]"
|
[ "$SORT_MODE" != "name" ] && _ind="${_ind} [sort:${SORT_MODE}]"
|
||||||
[ "$SHOW_DETAILS" = "1" ] && _ind="${_ind} [details]"
|
[ "$SHOW_DETAILS" = "1" ] && _ind="${_ind} [details]"
|
||||||
hint=" press ? for help "
|
hint=" press ? for help "
|
||||||
info=" $((SEL + 1))/${COUNT} ${CWD}${_ind}"
|
info=" $([ "$COUNT" -eq 0 ] && echo 0 || echo $((SEL + 1)))/${COUNT} ${CWD}${_ind}"
|
||||||
padlen=$((_cols - ${#info} - ${#hint}))
|
padlen=$((_cols - ${#info} - ${#hint}))
|
||||||
[ "$padlen" -lt 0 ] && padlen=0
|
[ "$padlen" -lt 0 ] && padlen=0
|
||||||
pad=$(printf '%*s' "$padlen" '')
|
pad=$(printf '%*s' "$padlen" '')
|
||||||
@@ -479,6 +574,15 @@ draw() {
|
|||||||
COLS=$(term_cols)
|
COLS=$(term_cols)
|
||||||
LIST_ROWS=$((ROWS - 2)) # row 1 = topbar, row ROWS = botbar
|
LIST_ROWS=$((ROWS - 2)) # row 1 = topbar, row ROWS = botbar
|
||||||
|
|
||||||
|
# split layout when preview enabled
|
||||||
|
if [ "$SHOW_PREVIEW" = "1" ]; then
|
||||||
|
LIST_COLS=$((COLS / 2))
|
||||||
|
PREV_COL=$((LIST_COLS + 2))
|
||||||
|
PREV_WIDTH=$((COLS - LIST_COLS - 2))
|
||||||
|
else
|
||||||
|
LIST_COLS=$COLS
|
||||||
|
fi
|
||||||
|
|
||||||
# clamp selection
|
# clamp selection
|
||||||
[ "$SEL" -lt 0 ] && SEL=0
|
[ "$SEL" -lt 0 ] && SEL=0
|
||||||
[ "$COUNT" -gt 0 ] && [ "$SEL" -ge "$COUNT" ] && SEL=$((COUNT - 1))
|
[ "$COUNT" -gt 0 ] && [ "$SEL" -ge "$COUNT" ] && SEL=$((COUNT - 1))
|
||||||
@@ -494,7 +598,6 @@ draw() {
|
|||||||
[ "$OFFSET" != "$PREV_OFFSET" ] && NEED_FULL_REDRAW=1
|
[ "$OFFSET" != "$PREV_OFFSET" ] && NEED_FULL_REDRAW=1
|
||||||
|
|
||||||
if [ "$NEED_FULL_REDRAW" = "1" ]; then
|
if [ "$NEED_FULL_REDRAW" = "1" ]; then
|
||||||
# --- full repaint: move to top without erasing, overwrite every row ---
|
|
||||||
printf '\033[H'
|
printf '\033[H'
|
||||||
draw_topbar "$COLS"
|
draw_topbar "$COLS"
|
||||||
|
|
||||||
@@ -502,22 +605,29 @@ draw() {
|
|||||||
idx=$OFFSET
|
idx=$OFFSET
|
||||||
while [ "$row" -le $((LIST_ROWS + 1)) ] && [ "$idx" -lt "$COUNT" ]; do
|
while [ "$row" -le $((LIST_ROWS + 1)) ] && [ "$idx" -lt "$COUNT" ]; do
|
||||||
sel=0; [ "$idx" -eq "$SEL" ] && sel=1
|
sel=0; [ "$idx" -eq "$SEL" ] && sel=1
|
||||||
render_row "$row" "$idx" "$sel" "$COLS"
|
render_row "$row" "$idx" "$sel" "$LIST_COLS"
|
||||||
row=$((row + 1))
|
row=$((row + 1))
|
||||||
idx=$((idx + 1))
|
idx=$((idx + 1))
|
||||||
done
|
done
|
||||||
# blank leftover rows (e.g. after entering a smaller directory)
|
# show (empty) if directory has no entries
|
||||||
|
if [ "$COUNT" -eq 0 ]; then
|
||||||
|
goto 2 1
|
||||||
|
printf '%s (empty)%s%s' "${WHITE}" "${ERASE_LINE}" "${RESET}"
|
||||||
|
row=3
|
||||||
|
fi
|
||||||
|
# blank leftover rows
|
||||||
while [ "$row" -le $((LIST_ROWS + 1)) ]; do
|
while [ "$row" -le $((LIST_ROWS + 1)) ]; do
|
||||||
goto "$row" 1
|
goto "$row" 1
|
||||||
printf '%s' "${ERASE_LINE}"
|
printf '%s' "${ERASE_LINE}"
|
||||||
row=$((row + 1))
|
row=$((row + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
|
[ "$SHOW_PREVIEW" = "1" ] && draw_preview "$ROWS" "$COLS" "$PREV_COL" "$PREV_WIDTH"
|
||||||
|
|
||||||
draw_botbar "$ROWS" "$COLS"
|
draw_botbar "$ROWS" "$COLS"
|
||||||
NEED_FULL_REDRAW=0
|
NEED_FULL_REDRAW=0
|
||||||
else
|
else
|
||||||
# --- fast path: only touch the two rows whose highlight state changed ---
|
# --- fast path ---
|
||||||
# if nothing moved, skip entirely — no flicker at boundaries
|
|
||||||
if [ "$SEL" = "$PREV_SEL" ] && [ "$OFFSET" = "$PREV_OFFSET" ]; then
|
if [ "$SEL" = "$PREV_SEL" ] && [ "$OFFSET" = "$PREV_OFFSET" ]; then
|
||||||
return 2>/dev/null || true
|
return 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
@@ -525,12 +635,14 @@ draw() {
|
|||||||
new_row=$(( (SEL - OFFSET) + 2 ))
|
new_row=$(( (SEL - OFFSET) + 2 ))
|
||||||
|
|
||||||
if [ "$prev_row" -ge 2 ] && [ "$prev_row" -le $((LIST_ROWS + 1)) ]; then
|
if [ "$prev_row" -ge 2 ] && [ "$prev_row" -le $((LIST_ROWS + 1)) ]; then
|
||||||
render_row "$prev_row" "$PREV_SEL" 0 "$COLS"
|
render_row "$prev_row" "$PREV_SEL" 0 "$LIST_COLS"
|
||||||
fi
|
fi
|
||||||
if [ "$new_row" -ge 2 ] && [ "$new_row" -le $((LIST_ROWS + 1)) ]; then
|
if [ "$new_row" -ge 2 ] && [ "$new_row" -le $((LIST_ROWS + 1)) ]; then
|
||||||
render_row "$new_row" "$SEL" 1 "$COLS"
|
render_row "$new_row" "$SEL" 1 "$LIST_COLS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
[ "$SHOW_PREVIEW" = "1" ] && draw_preview "$ROWS" "$COLS" "$PREV_COL" "$PREV_WIDTH"
|
||||||
|
|
||||||
draw_botbar "$ROWS" "$COLS"
|
draw_botbar "$ROWS" "$COLS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -744,7 +856,7 @@ do_help() {
|
|||||||
bw=$((COLS - 4))
|
bw=$((COLS - 4))
|
||||||
[ "$bw" -gt 52 ] && bw=52
|
[ "$bw" -gt 52 ] && bw=52
|
||||||
[ "$bw" -lt 36 ] && bw=36
|
[ "$bw" -lt 36 ] && bw=36
|
||||||
bh=41
|
bh=42
|
||||||
_help_bx=$(( (COLS - bw) / 2 )); [ "$_help_bx" -lt 1 ] && _help_bx=1
|
_help_bx=$(( (COLS - bw) / 2 )); [ "$_help_bx" -lt 1 ] && _help_bx=1
|
||||||
_help_by=$(( (ROWS - bh) / 2 )); [ "$_help_by" -lt 1 ] && _help_by=1
|
_help_by=$(( (ROWS - bh) / 2 )); [ "$_help_by" -lt 1 ] && _help_by=1
|
||||||
_help_iw=$((bw - 2))
|
_help_iw=$((bw - 2))
|
||||||
@@ -766,32 +878,33 @@ do_help() {
|
|||||||
help_row 11 " i file info in status bar"
|
help_row 11 " i file info in status bar"
|
||||||
help_row 12 " s cycle sort: name/size/date"
|
help_row 12 " s cycle sort: name/size/date"
|
||||||
help_row 13 " T toggle size/date details"
|
help_row 13 " T toggle size/date details"
|
||||||
help_sep 14
|
help_row 14 " P toggle preview pane"
|
||||||
help_row 15 " space toggle multi-select"
|
help_sep 15
|
||||||
help_row 16 " a select all / deselect all"
|
help_row 16 " space toggle multi-select"
|
||||||
help_row 17 " y yank/copy (works on selection)"
|
help_row 17 " a select all / deselect all"
|
||||||
help_row 18 " x cut (works on selection)"
|
help_row 18 " y yank/copy (works on selection)"
|
||||||
help_row 19 " p paste"
|
help_row 19 " x cut (works on selection)"
|
||||||
help_row 20 " d delete (works on selection)"
|
help_row 20 " p paste"
|
||||||
help_sep 21
|
help_row 21 " d delete (works on selection)"
|
||||||
help_row 22 " r rename R refresh"
|
help_sep 22
|
||||||
help_row 23 " m make directory"
|
help_row 23 " r rename R refresh"
|
||||||
help_row 24 " n new file"
|
help_row 24 " m make directory"
|
||||||
help_row 25 " u trash file (safe delete)"
|
help_row 25 " n new file"
|
||||||
help_row 26 " U open trash directory"
|
help_row 26 " u trash file (safe delete)"
|
||||||
help_row 27 " ! drop to shell in CWD"
|
help_row 27 " U open trash directory"
|
||||||
help_row 28 " o open with custom program"
|
help_row 28 " ! drop to shell in CWD"
|
||||||
help_sep 29
|
help_row 29 " o open with custom program"
|
||||||
help_row 30 " b bookmark current dir"
|
help_sep 30
|
||||||
help_row 31 " B open bookmark picker"
|
help_row 31 " b bookmark current dir"
|
||||||
help_row 32 " c copy path to clipboard"
|
help_row 32 " B open bookmark picker"
|
||||||
help_row 33 " ~ go to home directory"
|
help_row 33 " c copy path to clipboard"
|
||||||
help_row 34 " \` jump to previous directory"
|
help_row 34 " ~ go to home directory"
|
||||||
help_sep 35
|
help_row 35 " \` jump to previous directory"
|
||||||
help_row 36 " q quit"
|
help_sep 36
|
||||||
help_row 37 " ? this help"
|
help_row 37 " q quit"
|
||||||
help_row 38 ""
|
help_row 38 " ? this help"
|
||||||
help_row 39 " press any key to close..."
|
help_row 39 ""
|
||||||
|
help_row 40 " press any key to close..."
|
||||||
|
|
||||||
goto "$(( _help_by + bh ))" "$_help_bx"
|
goto "$(( _help_by + bh ))" "$_help_bx"
|
||||||
printf '%s+%s+%s' "${BOLD}${CYAN}" "$_help_hl" "${RESET}"
|
printf '%s+%s+%s' "${BOLD}${CYAN}" "$_help_hl" "${RESET}"
|
||||||
@@ -856,11 +969,18 @@ do_toggle_hidden() {
|
|||||||
|
|
||||||
do_toggle_details() {
|
do_toggle_details() {
|
||||||
if [ "$SHOW_DETAILS" = "0" ]; then
|
if [ "$SHOW_DETAILS" = "0" ]; then
|
||||||
SHOW_DETAILS=1
|
SHOW_DETAILS=1; INFO_MSG="details on"
|
||||||
INFO_MSG="details on"
|
|
||||||
else
|
else
|
||||||
SHOW_DETAILS=0
|
SHOW_DETAILS=0; INFO_MSG="details off"
|
||||||
INFO_MSG="details off"
|
fi
|
||||||
|
NEED_FULL_REDRAW=1
|
||||||
|
}
|
||||||
|
|
||||||
|
do_toggle_preview() {
|
||||||
|
if [ "$SHOW_PREVIEW" = "0" ]; then
|
||||||
|
SHOW_PREVIEW=1; INFO_MSG="preview on"
|
||||||
|
else
|
||||||
|
SHOW_PREVIEW=0; INFO_MSG="preview off"
|
||||||
fi
|
fi
|
||||||
NEED_FULL_REDRAW=1
|
NEED_FULL_REDRAW=1
|
||||||
}
|
}
|
||||||
@@ -871,7 +991,7 @@ do_go_back() {
|
|||||||
SELECTED=""
|
SELECTED=""
|
||||||
PREV_CWD="$CWD"
|
PREV_CWD="$CWD"
|
||||||
LAST_CHILD="${CWD##*/}/" # name of current dir with trailing slash
|
LAST_CHILD="${CWD##*/}/" # name of current dir with trailing slash
|
||||||
CWD=$(dirname "$CWD")
|
CWD=$(cd "$(dirname "$CWD")" && pwd)
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
||||||
load_entries
|
load_entries
|
||||||
# restore selection to the directory we just came from
|
# restore selection to the directory we just came from
|
||||||
@@ -888,20 +1008,20 @@ do_open() {
|
|||||||
*/)
|
*/)
|
||||||
FILTER=""
|
FILTER=""
|
||||||
SELECTED=""
|
SELECTED=""
|
||||||
_target="${CWD}/${entry%/}"
|
_target=$(joinpath "${entry%/}")
|
||||||
if [ ! -x "$_target" ] || [ ! -r "$_target" ]; then
|
if [ ! -x "$_target" ] || [ ! -r "$_target" ]; then
|
||||||
INFO_MSG="permission denied: ${entry%/}"
|
INFO_MSG="permission denied: ${entry%/}"
|
||||||
NEED_FULL_REDRAW=1
|
NEED_FULL_REDRAW=1
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
PREV_CWD="$CWD"
|
PREV_CWD="$CWD"
|
||||||
CWD=$(cd "$_target" && pwd)
|
CWD=$(cd "$_target" && pwd); norm_cwd
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
||||||
load_entries
|
load_entries
|
||||||
;;
|
;;
|
||||||
*@)
|
*@)
|
||||||
_name="${entry%@}"
|
_name="${entry%@}"
|
||||||
_target="${CWD}/${_name}"
|
_target=$(joinpath "$_name")
|
||||||
if [ -d "$_target" ]; then
|
if [ -d "$_target" ]; then
|
||||||
if [ ! -x "$_target" ] || [ ! -r "$_target" ]; then
|
if [ ! -x "$_target" ] || [ ! -r "$_target" ]; then
|
||||||
INFO_MSG="permission denied: ${_name}"
|
INFO_MSG="permission denied: ${_name}"
|
||||||
@@ -910,7 +1030,7 @@ do_open() {
|
|||||||
fi
|
fi
|
||||||
FILTER=""; SELECTED=""
|
FILTER=""; SELECTED=""
|
||||||
PREV_CWD="$CWD"
|
PREV_CWD="$CWD"
|
||||||
CWD=$(cd "$_target" && pwd)
|
CWD=$(cd "$_target" && pwd); norm_cwd
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
||||||
load_entries
|
load_entries
|
||||||
else
|
else
|
||||||
@@ -1057,7 +1177,7 @@ do_shell() {
|
|||||||
printf '%s(type "exit" to return to fm)%s\n' "${YELLOW}" "${RESET}"
|
printf '%s(type "exit" to return to fm)%s\n' "${YELLOW}" "${RESET}"
|
||||||
${SHELL:-sh}
|
${SHELL:-sh}
|
||||||
# restore CWD in case user cd'd around
|
# restore CWD in case user cd'd around
|
||||||
CWD="${PWD}"
|
CWD="${PWD}"; norm_cwd
|
||||||
setup_term; hide_cursor
|
setup_term; hide_cursor
|
||||||
NEED_FULL_REDRAW=1
|
NEED_FULL_REDRAW=1
|
||||||
}
|
}
|
||||||
@@ -1093,7 +1213,7 @@ do_trash() {
|
|||||||
do_open_trash() {
|
do_open_trash() {
|
||||||
PREV_CWD="$CWD"
|
PREV_CWD="$CWD"
|
||||||
FILTER=""; SELECTED=""
|
FILTER=""; SELECTED=""
|
||||||
CWD="$TRASH_DIR"
|
CWD="$TRASH_DIR"; norm_cwd
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
||||||
load_entries
|
load_entries
|
||||||
}
|
}
|
||||||
@@ -1122,7 +1242,7 @@ do_copy_path() {
|
|||||||
do_jump_back() {
|
do_jump_back() {
|
||||||
[ -z "$PREV_CWD" ] && { INFO_MSG="no previous directory"; NEED_FULL_REDRAW=1; return; }
|
[ -z "$PREV_CWD" ] && { INFO_MSG="no previous directory"; NEED_FULL_REDRAW=1; return; }
|
||||||
_tmp="$CWD"
|
_tmp="$CWD"
|
||||||
CWD="$PREV_CWD"
|
CWD="$PREV_CWD"; norm_cwd
|
||||||
PREV_CWD="$_tmp"
|
PREV_CWD="$_tmp"
|
||||||
FILTER=""; SELECTED=""
|
FILTER=""; SELECTED=""
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
||||||
@@ -1197,7 +1317,7 @@ do_bookmark_jump() {
|
|||||||
'[C') # right — open
|
'[C') # right — open
|
||||||
_chosen=$(awk -v n="$_bsel" 'NR==n&&NF{print;exit}' "$BOOKMARK_FILE")
|
_chosen=$(awk -v n="$_bsel" 'NR==n&&NF{print;exit}' "$BOOKMARK_FILE")
|
||||||
if [ -n "$_chosen" ] && [ -d "$_chosen" ]; then
|
if [ -n "$_chosen" ] && [ -d "$_chosen" ]; then
|
||||||
PREV_CWD="$CWD"; CWD="$_chosen"
|
PREV_CWD="$CWD"; CWD="$_chosen"; norm_cwd
|
||||||
FILTER=""; SELECTED=""
|
FILTER=""; SELECTED=""
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
||||||
load_entries
|
load_entries
|
||||||
@@ -1213,7 +1333,7 @@ do_bookmark_jump() {
|
|||||||
l)
|
l)
|
||||||
_chosen=$(awk -v n="$_bsel" 'NR==n&&NF{print;exit}' "$BOOKMARK_FILE")
|
_chosen=$(awk -v n="$_bsel" 'NR==n&&NF{print;exit}' "$BOOKMARK_FILE")
|
||||||
if [ -n "$_chosen" ] && [ -d "$_chosen" ]; then
|
if [ -n "$_chosen" ] && [ -d "$_chosen" ]; then
|
||||||
PREV_CWD="$CWD"; CWD="$_chosen"
|
PREV_CWD="$CWD"; CWD="$_chosen"; norm_cwd
|
||||||
FILTER=""; SELECTED=""
|
FILTER=""; SELECTED=""
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
|
||||||
load_entries
|
load_entries
|
||||||
@@ -1364,6 +1484,7 @@ while true; do
|
|||||||
/) do_search ;;
|
/) do_search ;;
|
||||||
'.') do_toggle_hidden ;;
|
'.') do_toggle_hidden ;;
|
||||||
T) do_toggle_details ;;
|
T) do_toggle_details ;;
|
||||||
|
P) do_toggle_preview ;;
|
||||||
i) do_info ;;
|
i) do_info ;;
|
||||||
'!') do_shell ;;
|
'!') do_shell ;;
|
||||||
o) do_open_with ;;
|
o) do_open_with ;;
|
||||||
@@ -1371,7 +1492,7 @@ while true; do
|
|||||||
u) do_trash ;;
|
u) do_trash ;;
|
||||||
U) do_open_trash ;;
|
U) do_open_trash ;;
|
||||||
'`') do_jump_back ;;
|
'`') do_jump_back ;;
|
||||||
'~') PREV_CWD="$CWD"; CWD="$HOME"; FILTER=""; SELECTED=""
|
'~') PREV_CWD="$CWD"; CWD=$(cd "$HOME" && pwd); FILTER=""; SELECTED=""
|
||||||
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0; load_entries ;;
|
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0; load_entries ;;
|
||||||
c) do_copy_path ;;
|
c) do_copy_path ;;
|
||||||
"$(printf '\033')") do_clear_filter ;;
|
"$(printf '\033')") do_clear_filter ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user