added preview function
This commit is contained in:
@@ -83,6 +83,7 @@ INFO_MSG="" # ephemeral message shown in botbar
|
||||
SHOW_HIDDEN=0 # 1 = show dotfiles
|
||||
SORT_MODE="name" # name | size | date
|
||||
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"
|
||||
mkdir -p "$TRASH_DIR"
|
||||
PREV_CWD="" # last visited directory, for jumping back
|
||||
@@ -432,6 +433,85 @@ render_row() {
|
||||
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() {
|
||||
_cols=$1
|
||||
spaces=$(printf '%*s' "$_cols" '')
|
||||
@@ -494,6 +574,15 @@ draw() {
|
||||
COLS=$(term_cols)
|
||||
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
|
||||
[ "$SEL" -lt 0 ] && SEL=0
|
||||
[ "$COUNT" -gt 0 ] && [ "$SEL" -ge "$COUNT" ] && SEL=$((COUNT - 1))
|
||||
@@ -509,7 +598,6 @@ draw() {
|
||||
[ "$OFFSET" != "$PREV_OFFSET" ] && NEED_FULL_REDRAW=1
|
||||
|
||||
if [ "$NEED_FULL_REDRAW" = "1" ]; then
|
||||
# --- full repaint: move to top without erasing, overwrite every row ---
|
||||
printf '\033[H'
|
||||
draw_topbar "$COLS"
|
||||
|
||||
@@ -517,7 +605,7 @@ draw() {
|
||||
idx=$OFFSET
|
||||
while [ "$row" -le $((LIST_ROWS + 1)) ] && [ "$idx" -lt "$COUNT" ]; do
|
||||
sel=0; [ "$idx" -eq "$SEL" ] && sel=1
|
||||
render_row "$row" "$idx" "$sel" "$COLS"
|
||||
render_row "$row" "$idx" "$sel" "$LIST_COLS"
|
||||
row=$((row + 1))
|
||||
idx=$((idx + 1))
|
||||
done
|
||||
@@ -527,18 +615,19 @@ draw() {
|
||||
printf '%s (empty)%s%s' "${WHITE}" "${ERASE_LINE}" "${RESET}"
|
||||
row=3
|
||||
fi
|
||||
# blank leftover rows (e.g. after entering a smaller directory)
|
||||
# blank leftover rows
|
||||
while [ "$row" -le $((LIST_ROWS + 1)) ]; do
|
||||
goto "$row" 1
|
||||
printf '%s' "${ERASE_LINE}"
|
||||
row=$((row + 1))
|
||||
done
|
||||
|
||||
[ "$SHOW_PREVIEW" = "1" ] && draw_preview "$ROWS" "$COLS" "$PREV_COL" "$PREV_WIDTH"
|
||||
|
||||
draw_botbar "$ROWS" "$COLS"
|
||||
NEED_FULL_REDRAW=0
|
||||
else
|
||||
# --- fast path: only touch the two rows whose highlight state changed ---
|
||||
# if nothing moved, skip entirely — no flicker at boundaries
|
||||
# --- fast path ---
|
||||
if [ "$SEL" = "$PREV_SEL" ] && [ "$OFFSET" = "$PREV_OFFSET" ]; then
|
||||
return 2>/dev/null || true
|
||||
fi
|
||||
@@ -546,12 +635,14 @@ draw() {
|
||||
new_row=$(( (SEL - OFFSET) + 2 ))
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
[ "$SHOW_PREVIEW" = "1" ] && draw_preview "$ROWS" "$COLS" "$PREV_COL" "$PREV_WIDTH"
|
||||
|
||||
draw_botbar "$ROWS" "$COLS"
|
||||
fi
|
||||
|
||||
@@ -765,7 +856,7 @@ do_help() {
|
||||
bw=$((COLS - 4))
|
||||
[ "$bw" -gt 52 ] && bw=52
|
||||
[ "$bw" -lt 36 ] && bw=36
|
||||
bh=41
|
||||
bh=42
|
||||
_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_iw=$((bw - 2))
|
||||
@@ -787,32 +878,33 @@ do_help() {
|
||||
help_row 11 " i file info in status bar"
|
||||
help_row 12 " s cycle sort: name/size/date"
|
||||
help_row 13 " T toggle size/date details"
|
||||
help_sep 14
|
||||
help_row 15 " space toggle multi-select"
|
||||
help_row 16 " a select all / deselect all"
|
||||
help_row 17 " y yank/copy (works on selection)"
|
||||
help_row 18 " x cut (works on selection)"
|
||||
help_row 19 " p paste"
|
||||
help_row 20 " d delete (works on selection)"
|
||||
help_sep 21
|
||||
help_row 22 " r rename R refresh"
|
||||
help_row 23 " m make directory"
|
||||
help_row 24 " n new file"
|
||||
help_row 25 " u trash file (safe delete)"
|
||||
help_row 26 " U open trash directory"
|
||||
help_row 27 " ! drop to shell in CWD"
|
||||
help_row 28 " o open with custom program"
|
||||
help_sep 29
|
||||
help_row 30 " b bookmark current dir"
|
||||
help_row 31 " B open bookmark picker"
|
||||
help_row 32 " c copy path to clipboard"
|
||||
help_row 33 " ~ go to home directory"
|
||||
help_row 34 " \` jump to previous directory"
|
||||
help_sep 35
|
||||
help_row 36 " q quit"
|
||||
help_row 37 " ? this help"
|
||||
help_row 38 ""
|
||||
help_row 39 " press any key to close..."
|
||||
help_row 14 " P toggle preview pane"
|
||||
help_sep 15
|
||||
help_row 16 " space toggle multi-select"
|
||||
help_row 17 " a select all / deselect all"
|
||||
help_row 18 " y yank/copy (works on selection)"
|
||||
help_row 19 " x cut (works on selection)"
|
||||
help_row 20 " p paste"
|
||||
help_row 21 " d delete (works on selection)"
|
||||
help_sep 22
|
||||
help_row 23 " r rename R refresh"
|
||||
help_row 24 " m make directory"
|
||||
help_row 25 " n new file"
|
||||
help_row 26 " u trash file (safe delete)"
|
||||
help_row 27 " U open trash directory"
|
||||
help_row 28 " ! drop to shell in CWD"
|
||||
help_row 29 " o open with custom program"
|
||||
help_sep 30
|
||||
help_row 31 " b bookmark current dir"
|
||||
help_row 32 " B open bookmark picker"
|
||||
help_row 33 " c copy path to clipboard"
|
||||
help_row 34 " ~ go to home directory"
|
||||
help_row 35 " \` jump to previous directory"
|
||||
help_sep 36
|
||||
help_row 37 " q quit"
|
||||
help_row 38 " ? this help"
|
||||
help_row 39 ""
|
||||
help_row 40 " press any key to close..."
|
||||
|
||||
goto "$(( _help_by + bh ))" "$_help_bx"
|
||||
printf '%s+%s+%s' "${BOLD}${CYAN}" "$_help_hl" "${RESET}"
|
||||
@@ -877,11 +969,18 @@ do_toggle_hidden() {
|
||||
|
||||
do_toggle_details() {
|
||||
if [ "$SHOW_DETAILS" = "0" ]; then
|
||||
SHOW_DETAILS=1
|
||||
INFO_MSG="details on"
|
||||
SHOW_DETAILS=1; INFO_MSG="details on"
|
||||
else
|
||||
SHOW_DETAILS=0
|
||||
INFO_MSG="details off"
|
||||
SHOW_DETAILS=0; 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
|
||||
NEED_FULL_REDRAW=1
|
||||
}
|
||||
@@ -1385,6 +1484,7 @@ while true; do
|
||||
/) do_search ;;
|
||||
'.') do_toggle_hidden ;;
|
||||
T) do_toggle_details ;;
|
||||
P) do_toggle_preview ;;
|
||||
i) do_info ;;
|
||||
'!') do_shell ;;
|
||||
o) do_open_with ;;
|
||||
|
||||
Reference in New Issue
Block a user