Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b729ffe8a | ||
|
|
25a329aba9 |
+78
-53
@@ -1,15 +1,15 @@
|
|||||||
sfm - Simple File Manager
|
sfm - Simple File Manager
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
sfm is a lightweight, terminal-based file manager written entirely in
|
sfm is a lightweight, terminal-based file manager written entirely in
|
||||||
POSIX sh. It runs in your terminal with no external dependencies beyond
|
POSIX sh. It runs in your terminal with no external dependencies beyond
|
||||||
standard Unix tools (ls, awk, tput, stty, mv, cp, rm). Designed to be
|
standard Unix tools (ls, awk, tput, stty, mv, cp, rm). Designed to be
|
||||||
fast, flicker-free, and keyboard-driven with a vim-inspired key layout.
|
fast, flicker-free, and keyboard-driven with a vim-inspired key layout.
|
||||||
|
|
||||||
|
|
||||||
REQUIREMENTS
|
REQUIREMENTS
|
||||||
------------
|
------------
|
||||||
- A POSIX-compatible shell (sh, dash, bash, etc.)
|
- A POSIX-compatible shell (sh, dash, bash, etc.)
|
||||||
@@ -18,41 +18,41 @@ REQUIREMENTS
|
|||||||
- 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)
|
- Optional: file (for MIME type detection)
|
||||||
|
|
||||||
|
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
------------
|
------------
|
||||||
Using make (recommended):
|
Using make (recommended):
|
||||||
|
|
||||||
make install
|
make install
|
||||||
|
|
||||||
This installs sfm to /usr/local/bin by default. To change the prefix:
|
This installs sfm to /usr/local/bin by default. To change the prefix:
|
||||||
|
|
||||||
make install PREFIX=/usr
|
make install PREFIX=/usr
|
||||||
|
|
||||||
To uninstall:
|
To uninstall:
|
||||||
|
|
||||||
make uninstall
|
make uninstall
|
||||||
|
|
||||||
Manual installation:
|
Manual installation:
|
||||||
|
|
||||||
cp sfm /usr/local/bin/sfm
|
cp sfm /usr/local/bin/sfm
|
||||||
chmod +x /usr/local/bin/sfm
|
chmod +x /usr/local/bin/sfm
|
||||||
|
|
||||||
|
|
||||||
USAGE
|
USAGE
|
||||||
-----
|
-----
|
||||||
sfm [path]
|
sfm [path]
|
||||||
|
|
||||||
If no path is given, sfm opens in the current directory.
|
If no path is given, sfm opens in the current directory.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
sfm # open in current directory
|
sfm # open in current directory
|
||||||
sfm /mnt/data # open at a specific path
|
sfm /mnt/data # open at a specific path
|
||||||
sfm ~ # open home directory
|
sfm ~ # open home directory
|
||||||
sfm .. # open parent directory
|
sfm .. # open parent directory
|
||||||
|
|
||||||
|
|
||||||
NAVIGATION
|
NAVIGATION
|
||||||
----------
|
----------
|
||||||
j / k or up/down arrows Move up / down
|
j / k or up/down arrows Move up / down
|
||||||
@@ -62,15 +62,15 @@ NAVIGATION
|
|||||||
G Jump to bottom of list
|
G Jump to bottom of list
|
||||||
~ Go to home directory
|
~ Go to home directory
|
||||||
` (backtick) Jump to previous directory
|
` (backtick) Jump to previous directory
|
||||||
|
|
||||||
|
|
||||||
SEARCH & FILTER
|
SEARCH & FILTER
|
||||||
---------------
|
---------------
|
||||||
/ Enter search mode (filters listing as you type)
|
/ Enter search mode (filters listing as you type)
|
||||||
esc Clear filter and exit search mode
|
esc Clear filter and exit search mode
|
||||||
enter Exit search mode but keep filter active
|
enter Exit search mode but keep filter active
|
||||||
|
|
||||||
|
|
||||||
DISPLAY TOGGLES
|
DISPLAY TOGGLES
|
||||||
---------------
|
---------------
|
||||||
. Toggle hidden files (dotfiles)
|
. Toggle hidden files (dotfiles)
|
||||||
@@ -79,19 +79,42 @@ DISPLAY TOGGLES
|
|||||||
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
|
PREVIEW PANE
|
||||||
------------
|
------------
|
||||||
Press P to toggle the preview pane on the right side of the screen.
|
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.
|
The list pane takes the left half, preview takes the right half.
|
||||||
|
|
||||||
Text files Shows file contents line by line
|
Text files Shows file contents line by line
|
||||||
Directories Shows entry count
|
Directories Shows directory contents
|
||||||
Symlinks Shows link target
|
Symlinks Shows link target
|
||||||
Binary files Shows file size
|
Binary files Shows file size
|
||||||
|
|
||||||
|
|
||||||
|
CUSTOM OPENER
|
||||||
|
-------------
|
||||||
|
sfm checks for a user-defined opener script at:
|
||||||
|
|
||||||
|
~/.config/sfm/opener
|
||||||
|
|
||||||
|
If the file exists and is executable, sfm passes the selected file
|
||||||
|
path to it instead of using the built-in smart opener. Example:
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
case "$1" in
|
||||||
|
*.jpg|*.jpeg) imv "$1" ;;
|
||||||
|
*.mp4) mpv "$1" ;;
|
||||||
|
*.html|*.pdf) firefox "$1" ;;
|
||||||
|
*) echo "no program set for this file type" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
Make it executable: chmod +x ~/.config/sfm/opener
|
||||||
|
|
||||||
|
If the opener script does not exist, sfm falls back to its built-in
|
||||||
|
smart opener automatically.
|
||||||
|
|
||||||
|
|
||||||
FILE OPERATIONS
|
FILE OPERATIONS
|
||||||
---------------
|
---------------
|
||||||
r Rename selected entry
|
r Rename selected entry
|
||||||
@@ -101,45 +124,45 @@ FILE OPERATIONS
|
|||||||
u Move to trash (safe delete)
|
u Move to trash (safe delete)
|
||||||
U Open trash directory
|
U Open trash directory
|
||||||
o Open with custom program
|
o Open with custom program
|
||||||
|
|
||||||
|
|
||||||
CLIPBOARD
|
CLIPBOARD
|
||||||
---------
|
---------
|
||||||
y Yank / copy (works on multi-selection)
|
y Yank / copy (works on multi-selection)
|
||||||
x Cut (works on multi-selection)
|
x Cut (works on multi-selection)
|
||||||
p Paste into current directory
|
p Paste into current directory
|
||||||
c Copy full path of selected entry to system clipboard
|
c Copy full path of selected entry to system clipboard
|
||||||
|
|
||||||
|
|
||||||
MULTI-SELECT
|
MULTI-SELECT
|
||||||
------------
|
------------
|
||||||
space Toggle multi-select on current entry (cursor advances)
|
space Toggle multi-select on current entry (cursor advances)
|
||||||
a Select all / deselect all
|
a Select all / deselect all
|
||||||
|
|
||||||
|
|
||||||
BOOKMARKS
|
BOOKMARKS
|
||||||
---------
|
---------
|
||||||
b Bookmark current directory (press again to remove)
|
b Bookmark current directory (press again to remove)
|
||||||
B Open bookmark picker (j/k navigate, enter jump)
|
B Open bookmark picker (j/k navigate, enter jump)
|
||||||
|
|
||||||
Bookmarks are saved to: ~/.config/sfm/bookmarks
|
Bookmarks are saved to: ~/.config/sfm/bookmarks
|
||||||
|
|
||||||
|
|
||||||
SHELL & UTILITIES
|
SHELL & UTILITIES
|
||||||
-----------------
|
-----------------
|
||||||
! Drop into $SHELL in current directory (type "exit" to return)
|
! Drop into $SHELL in current directory (type "exit" to return)
|
||||||
|
|
||||||
|
|
||||||
HELP
|
HELP
|
||||||
----
|
----
|
||||||
? Show keyboard shortcuts overlay
|
? Show keyboard shortcuts overlay
|
||||||
|
|
||||||
|
|
||||||
QUIT
|
QUIT
|
||||||
----
|
----
|
||||||
q Quit sfm
|
q Quit sfm
|
||||||
|
|
||||||
|
|
||||||
STATUS BAR INDICATORS
|
STATUS BAR INDICATORS
|
||||||
---------------------
|
---------------------
|
||||||
[hidden] Hidden files are visible
|
[hidden] Hidden files are visible
|
||||||
@@ -148,13 +171,13 @@ STATUS BAR INDICATORS
|
|||||||
[cut] A file is in the clipboard (cut mode)
|
[cut] A file is in the clipboard (cut mode)
|
||||||
[sel:N] N items are currently selected
|
[sel:N] N items are currently selected
|
||||||
[details] Size/date column is visible
|
[details] Size/date column is visible
|
||||||
|
|
||||||
|
|
||||||
SMART FILE OPENER
|
SMART FILE OPENER
|
||||||
-----------------
|
-----------------
|
||||||
When you open a file, sfm detects the file type by extension and
|
When you open a file, sfm detects the file type by extension and
|
||||||
MIME type, then picks an appropriate program automatically:
|
MIME type, then picks an appropriate program automatically:
|
||||||
|
|
||||||
Text / code $EDITOR (or vi)
|
Text / code $EDITOR (or vi)
|
||||||
Images imv, feh, sxiv, eog, gimp
|
Images imv, feh, sxiv, eog, gimp
|
||||||
Video mpv, vlc, mplayer, totem
|
Video mpv, vlc, mplayer, totem
|
||||||
@@ -162,24 +185,26 @@ MIME type, then picks an appropriate program automatically:
|
|||||||
PDF zathura, evince, okular, mupdf
|
PDF zathura, evince, okular, mupdf
|
||||||
Office docs libreoffice
|
Office docs libreoffice
|
||||||
Archives atool / bsdtar (lists contents in pager)
|
Archives atool / bsdtar (lists contents in pager)
|
||||||
|
|
||||||
Falls back to xdg-open, open (macOS), or $EDITOR if nothing matches.
|
Falls back to xdg-open, open (macOS), or $EDITOR if nothing matches.
|
||||||
Use 'o' to manually specify any program.
|
Use 'o' to manually specify any program.
|
||||||
|
|
||||||
|
|
||||||
TRASH
|
TRASH
|
||||||
-----
|
-----
|
||||||
Files deleted with 'u' are moved to:
|
Files deleted with 'u' are moved to:
|
||||||
|
|
||||||
~/.local/share/sfm-trash/
|
~/.local/share/sfm-trash/
|
||||||
|
|
||||||
Files are prefixed with a timestamp: YYYYMMDD_HHMMSS_filename
|
Files are prefixed with a timestamp: YYYYMMDD_HHMMSS_filename
|
||||||
Use U to browse the trash directory. To restore a file, rename it
|
Use U to browse the trash directory. To restore a file, rename it
|
||||||
(press r) to remove the timestamp prefix, then cut (x) and paste (p)
|
(press r) to remove the timestamp prefix, then cut (x) and paste (p)
|
||||||
it back to the desired location.
|
it back to the desired location.
|
||||||
|
|
||||||
|
|
||||||
DATA FILES
|
DATA FILES
|
||||||
----------
|
----------
|
||||||
~/.config/sfm/bookmarks Saved bookmarks (one path per line)
|
~/.config/sfm/bookmarks Saved bookmarks (one path per line)
|
||||||
|
~/.config/sfm/opener Custom file opener script (optional)
|
||||||
~/.local/share/sfm-trash/ Trashed files
|
~/.local/share/sfm-trash/ Trashed files
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# sfm - Simple File Manager in POSIX sh
|
# sfm - Simple File Manager in POSIX sh (flicker-free)
|
||||||
|
# version 0.4
|
||||||
|
|
||||||
# --- terminal control ---
|
# --- terminal control ---
|
||||||
tput_cmd() { command -v tput >/dev/null 2>&1 && tput "$@"; }
|
tput_cmd() { command -v tput >/dev/null 2>&1 && tput "$@"; }
|
||||||
@@ -456,10 +457,36 @@ draw_preview() {
|
|||||||
|
|
||||||
case "$entry" in
|
case "$entry" in
|
||||||
*/)
|
*/)
|
||||||
# directory: show entry count
|
# directory: list contents
|
||||||
_dc=$(ls -1 "$_path" 2>/dev/null | wc -l | tr -d '[:space:]')
|
_max_lines=$((_rows - 3))
|
||||||
goto 2 "$_px"
|
_pr=2
|
||||||
printf '%s[dir] %s items%s' "${CYAN}" "${_dc}" "${RESET}"
|
for _de in "$_path"/*/; do
|
||||||
|
[ "$_pr" -gt $((_rows - 1)) ] && break
|
||||||
|
[ -d "$_de" ] || continue
|
||||||
|
_dn="${_de%/}"; _dn="${_dn##*/}"
|
||||||
|
[ "$_dn" = "*" ] && continue
|
||||||
|
_dl=" ${_dn}/"
|
||||||
|
[ "${#_dl}" -gt "$((_pw - 1))" ] && _dl="$(printf '%s' "$_dl" | cut -c1-$((_pw-2)))~"
|
||||||
|
goto "$_pr" "$_px"
|
||||||
|
printf '%s%s%s' "${GREEN}${BOLD}" "$_dl" "${RESET}"
|
||||||
|
_pr=$((_pr + 1))
|
||||||
|
done
|
||||||
|
for _fe in "$_path"/*; do
|
||||||
|
[ "$_pr" -gt $((_rows - 1)) ] && break
|
||||||
|
[ -e "$_fe" ] || continue
|
||||||
|
[ -d "$_fe" ] && continue
|
||||||
|
_fn="${_fe##*/}"
|
||||||
|
[ "$_fn" = "*" ] && continue
|
||||||
|
_fl=" ${_fn}"
|
||||||
|
[ "${#_fl}" -gt "$((_pw - 1))" ] && _fl="$(printf '%s' "$_fl" | cut -c1-$((_pw-2)))~"
|
||||||
|
goto "$_pr" "$_px"
|
||||||
|
printf '%s%s%s' "${WHITE}" "$_fl" "${RESET}"
|
||||||
|
_pr=$((_pr + 1))
|
||||||
|
done
|
||||||
|
if [ "$_pr" -eq 2 ]; then
|
||||||
|
goto 2 "$_px"
|
||||||
|
printf '%s(empty)%s' "${WHITE}" "${RESET}"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
*@)
|
*@)
|
||||||
# symlink
|
# symlink
|
||||||
@@ -679,6 +706,14 @@ _run_gui() { "$@" >/dev/null 2>&1 & }
|
|||||||
|
|
||||||
open_file() {
|
open_file() {
|
||||||
_f="$1"
|
_f="$1"
|
||||||
|
|
||||||
|
# use user opener script if it exists and is executable
|
||||||
|
_opener="${XDG_CONFIG_HOME:-$HOME/.config}/sfm/opener"
|
||||||
|
if [ -x "$_opener" ]; then
|
||||||
|
"$_opener" "$_f"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
_ext="${_f##*.}"
|
_ext="${_f##*.}"
|
||||||
_ext=$(printf '%s' "$_ext" | tr '[:upper:]' '[:lower:]')
|
_ext=$(printf '%s' "$_ext" | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user