commit 12c85202f92282e7c92c3295c01f494bcbe13a95
parent 7f41df91f18cb32a34d4cff2746e4344d8f7830d
Author: emmett1 <emmett1.2miligrams@protonmail.com>
Date: Mon, 16 Mar 2026 00:11:24 +0800
fix double slash at directory name
Diffstat:
| M | sfm | | | 34 | ++++++++++++++++++++++------------ |
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/sfm b/sfm
@@ -61,7 +61,7 @@ term_rows() { tput_cmd lines || echo 24; }
term_cols() { tput_cmd cols || echo 80; }
# --- state ---
-CWD="$PWD"
+CWD="$PWD"; CWD=$(cd "$CWD" 2>/dev/null && pwd) || CWD="/"
SEL=0
OFFSET=0
PREV_SEL=0
@@ -82,6 +82,16 @@ SHOW_DETAILS=0 # 1 = show size+date column
TRASH_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/sfm-trash"
mkdir -p "$TRASH_DIR"
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"
mkdir -p "$(dirname "$BOOKMARK_FILE")"
[ -f "$BOOKMARK_FILE" ] || touch "$BOOKMARK_FILE"
@@ -873,7 +883,7 @@ do_go_back() {
SELECTED=""
PREV_CWD="$CWD"
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
load_entries
# restore selection to the directory we just came from
@@ -890,20 +900,20 @@ do_open() {
*/)
FILTER=""
SELECTED=""
- _target="${CWD}/${entry%/}"
+ _target=$(joinpath "${entry%/}")
if [ ! -x "$_target" ] || [ ! -r "$_target" ]; then
INFO_MSG="permission denied: ${entry%/}"
NEED_FULL_REDRAW=1
return
fi
PREV_CWD="$CWD"
- CWD=$(cd "$_target" && pwd)
+ CWD=$(cd "$_target" && pwd); norm_cwd
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
load_entries
;;
*@)
_name="${entry%@}"
- _target="${CWD}/${_name}"
+ _target=$(joinpath "$_name")
if [ -d "$_target" ]; then
if [ ! -x "$_target" ] || [ ! -r "$_target" ]; then
INFO_MSG="permission denied: ${_name}"
@@ -912,7 +922,7 @@ do_open() {
fi
FILTER=""; SELECTED=""
PREV_CWD="$CWD"
- CWD=$(cd "$_target" && pwd)
+ CWD=$(cd "$_target" && pwd); norm_cwd
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
load_entries
else
@@ -1059,7 +1069,7 @@ do_shell() {
printf '%s(type "exit" to return to fm)%s\n' "${YELLOW}" "${RESET}"
${SHELL:-sh}
# restore CWD in case user cd'd around
- CWD="${PWD}"
+ CWD="${PWD}"; norm_cwd
setup_term; hide_cursor
NEED_FULL_REDRAW=1
}
@@ -1095,7 +1105,7 @@ do_trash() {
do_open_trash() {
PREV_CWD="$CWD"
FILTER=""; SELECTED=""
- CWD="$TRASH_DIR"
+ CWD="$TRASH_DIR"; norm_cwd
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
load_entries
}
@@ -1124,7 +1134,7 @@ do_copy_path() {
do_jump_back() {
[ -z "$PREV_CWD" ] && { INFO_MSG="no previous directory"; NEED_FULL_REDRAW=1; return; }
_tmp="$CWD"
- CWD="$PREV_CWD"
+ CWD="$PREV_CWD"; norm_cwd
PREV_CWD="$_tmp"
FILTER=""; SELECTED=""
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
@@ -1199,7 +1209,7 @@ do_bookmark_jump() {
'[C') # right — open
_chosen=$(awk -v n="$_bsel" 'NR==n&&NF{print;exit}' "$BOOKMARK_FILE")
if [ -n "$_chosen" ] && [ -d "$_chosen" ]; then
- PREV_CWD="$CWD"; CWD="$_chosen"
+ PREV_CWD="$CWD"; CWD="$_chosen"; norm_cwd
FILTER=""; SELECTED=""
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
load_entries
@@ -1215,7 +1225,7 @@ do_bookmark_jump() {
l)
_chosen=$(awk -v n="$_bsel" 'NR==n&&NF{print;exit}' "$BOOKMARK_FILE")
if [ -n "$_chosen" ] && [ -d "$_chosen" ]; then
- PREV_CWD="$CWD"; CWD="$_chosen"
+ PREV_CWD="$CWD"; CWD="$_chosen"; norm_cwd
FILTER=""; SELECTED=""
SEL=0; OFFSET=0; PREV_SEL=0; PREV_OFFSET=0
load_entries
@@ -1373,7 +1383,7 @@ while true; do
u) do_trash ;;
U) do_open_trash ;;
'`') 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 ;;
c) do_copy_path ;;
"$(printf '\033')") do_clear_filter ;;