Prompt when in doubt (#623)

* Update deps

* Prompt for user input when in doubt

- Ask before delete.
- For copy, move or symlink operations, ask what to do if a file with
  the same name exists.
- Update version.

Closes: https://github.com/sayanarijit/xplr/issues/615
pull/629/head
Arijit Basu 12 months ago committed by GitHub
parent 2a775371f6
commit ab90381fda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

12
Cargo.lock generated

@ -73,7 +73,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86d6b683edf8d1119fe420a94f8a7e389239666aa72e65495d91c00462510151"
dependencies = [
"anstyle",
"bstr 1.4.0",
"bstr 1.5.0",
"doc-comment",
"predicates",
"predicates-core",
@ -121,9 +121,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "1.4.0"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09"
checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5"
dependencies = [
"memchr",
"once_cell",
@ -638,9 +638,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "jf"
version = "0.2.3"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad399f2a6f800a46dc26f773fac1f51ad1794b3d891ca0ed1662812a6e0e2b0f"
checksum = "379d1f8869705532e4cb467908eccbf83e433b0ac4bb2618cf6217c8303a2798"
dependencies = [
"serde_json",
"serde_yaml",
@ -1799,7 +1799,7 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "xplr"
version = "0.21.1"
version = "0.21.2"
dependencies = [
"ansi-to-tui",
"anyhow",

@ -8,7 +8,7 @@ path = './benches/criterion.rs'
[package]
name = 'xplr'
version = '0.21.1'
version = '0.21.2'
authors = ['Arijit Basu <hi@arijitbasu.in>']
edition = '2021'
description = 'A hackable, minimal, fast TUI file explorer'
@ -40,7 +40,7 @@ textwrap = "0.16"
snailquote = "0.3.1"
skim = { version = "0.10.4", default-features = false }
time = { version = "0.3.21", features = ["serde", "local-offset", "formatting", "macros"] }
jf = "0.2.3"
jf = "0.3.1"
[dependencies.lscolors]
version = "0.14.0"

@ -246,7 +246,7 @@ sudo cp target/release/xplr /usr/local/bin/
[7]: https://archlinux.org/packages/community/x86_64/xplr
[8]: https://aur.archlinux.org/packages/?O=0&SeB=n&K=xplr&outdated=&SB=n&SO=a&PP=50&do_Search=Go
[9]: https://github.com/shubham-cpp/void-pkg-templates
[10]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/xplr
[10]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/file-managers/xplr/default.nix
[11]: https://ports.macports.org/port/xplr
[12]: https://formulae.brew.sh/formula/xplr
[13]: https://cgit.freebsd.org/ports/plain/misc/xplr/

@ -45,7 +45,7 @@ compatibility.
### Instructions
#### [v0.20.2][48] -> [v0.21.1][49]
#### [v0.20.2][48] -> [v0.21.2][49]
- Some plugins might stop rendering colors. Wait for them to update.
- Rename `xplr.config.general.sort_and_filter_ui.search_identifier` to
@ -516,5 +516,5 @@ Else do the following:
[46]: https://github.com/sayanarijit/xplr/releases/tag/v0.18.0
[47]: https://github.com/sayanarijit/xplr/releases/tag/v0.19.4
[48]: https://github.com/sayanarijit/xplr/releases/tag/v0.20.2
[49]: https://github.com/sayanarijit/xplr/releases/tag/v0.21.1
[49]: https://github.com/sayanarijit/xplr/releases/tag/v0.21.2
[50]: https://github.com/lotabout/skim#search-syntax

@ -157,11 +157,11 @@ xplr.config.general.logs.error.style = { fg = "Red" }
-- * format: nullable string
-- * style: [Style](https://xplr.dev/en/style)
xplr.config.general.table.header.cols = {
{ format = " index", style = {} },
{ format = " index", style = {} },
{ format = "╭─── path", style = {} },
{ format = "perm", style = {} },
{ format = "size", style = {} },
{ format = "modified", style = {} },
{ format = "perm", style = {} },
{ format = "size", style = {} },
{ format = "modified", style = {} },
}
-- Style of the table header.
@ -478,7 +478,7 @@ xplr.config.general.sort_and_filter_ui.search_identifiers = {
--
-- Type: nullable string
xplr.config.general.sort_and_filter_ui.search_direction_identifiers.ordered.format =
""
""
-- The shape of unordered indicator for search ordering identifiers in Sort & filter panel.
--
@ -676,7 +676,7 @@ xplr.config.general.panel_ui.sort_and_filter.border_style = {}
-- Type: nullable list of [Node Sorter](https://xplr.dev/en/sorting#node-sorter-applicable)
xplr.config.general.initial_sorting = {
{ sorter = "ByCanonicalIsDir", reverse = true },
{ sorter = "ByIRelativePath", reverse = false },
{ sorter = "ByIRelativePath", reverse = false },
}
-- The name of one of the modes to use when xplr loads.
@ -1280,21 +1280,21 @@ xplr.config.modes.builtin.default = {
}
xplr.config.modes.builtin.default.key_bindings.on_key["v"] =
xplr.config.modes.builtin.default.key_bindings.on_key["space"]
xplr.config.modes.builtin.default.key_bindings.on_key["space"]
xplr.config.modes.builtin.default.key_bindings.on_key["V"] =
xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-a"]
xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-a"]
xplr.config.modes.builtin.default.key_bindings.on_key["/"] =
xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-f"]
xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-f"]
xplr.config.modes.builtin.default.key_bindings.on_key["h"] =
xplr.config.modes.builtin.default.key_bindings.on_key["left"]
xplr.config.modes.builtin.default.key_bindings.on_key["left"]
xplr.config.modes.builtin.default.key_bindings.on_key["j"] =
xplr.config.modes.builtin.default.key_bindings.on_key["down"]
xplr.config.modes.builtin.default.key_bindings.on_key["down"]
xplr.config.modes.builtin.default.key_bindings.on_key["k"] =
xplr.config.modes.builtin.default.key_bindings.on_key["up"]
xplr.config.modes.builtin.default.key_bindings.on_key["up"]
xplr.config.modes.builtin.default.key_bindings.on_key["l"] =
xplr.config.modes.builtin.default.key_bindings.on_key["right"]
xplr.config.modes.builtin.default.key_bindings.on_key["right"]
xplr.config.modes.builtin.default.key_bindings.on_key["tab"] =
xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-i"] -- compatibility workaround
xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-i"] -- compatibility workaround
-- The builtin debug error mode.
--
@ -1443,15 +1443,15 @@ xplr.config.modes.builtin.selection_ops = {
{
BashExec0 = [===[
TMPFILE="$(mktemp)"
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
echo $(printf %q "${PTH:?}") >> "${TMPFILE:?}"
done < "${XPLR_PIPE_SELECTION_OUT:?}")
done < "${XPLR_PIPE_SELECTION_OUT:?}"
${EDITOR:-vi} "${TMPFILE:?}"
[ ! -e "$TMPFILE" ] && exit
"$XPLR" -m ClearSelection
(while IFS= read -r PTH_ESC; do
while IFS= read -r PTH_ESC; do
"$XPLR" -m 'SelectPath: %q' "$(eval printf %s ${PTH_ESC:?})"
done < "${TMPFILE:?}")
done < "${TMPFILE:?}"
rm -- "${TMPFILE:?}"
]===],
},
@ -1479,22 +1479,35 @@ xplr.config.modes.builtin.selection_ops = {
{
BashExec0 = [===[
"$XPLR" -m ExplorePwd
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
PTH_ESC=$(printf %q "$PTH")
BASENAME=$(basename -- "$PTH")
BASENAME_ESC=$(printf %q "$BASENAME")
while [ -e "$BASENAME" ]; do
BASENAME="$BASENAME (copied)"
BASENAME_ESC=$(printf %q "$BASENAME")
done
if [ -e "$BASENAME" ]; then
echo
echo "$BASENAME_ESC exists, do you want to overwrite it?"
read -p "[y]es, [n]o, [S]kip: " ANS < /dev/tty
case "$ANS" in
[yY]*)
;;
[nN]*)
read -p "Enter new name: " BASENAME < /dev/tty
BASENAME_ESC=$(printf %q "$BASENAME")
;;
*)
continue
;;
esac
fi
if cp -vr -- "${PTH:?}" "./${BASENAME:?}"; then
"$XPLR" -m 'LogSuccess: %q' "$PTH_ESC copied to ./$BASENAME_ESC"
"$XPLR" -m 'FocusPath: %q' "$BASENAME"
else
"$XPLR" -m 'LogError: %q' "could not copy $PTH_ESC to ./$BASENAME_ESC"
fi
done < "${XPLR_PIPE_SELECTION_OUT:?}")
read -p "[enter to continue]"
done < "${XPLR_PIPE_SELECTION_OUT:?}"
echo
read -p "[press enter to continue]"
]===],
},
"PopMode",
@ -1506,22 +1519,35 @@ xplr.config.modes.builtin.selection_ops = {
{
BashExec0 = [===[
"$XPLR" -m ExplorePwd
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
PTH_ESC=$(printf %q "$PTH")
BASENAME=$(basename -- "$PTH")
BASENAME_ESC=$(printf %q "$BASENAME")
while [ -e "$BASENAME" ]; do
BASENAME="$BASENAME (moved)"
BASENAME_ESC=$(printf %q "$BASENAME")
done
if [ -e "$BASENAME" ]; then
echo
echo "$BASENAME_ESC exists, do you want to overwrite it?"
read -p "[y]es, [n]o, [S]kip: " ANS < /dev/tty
case "$ANS" in
[yY]*)
;;
[nN]*)
read -p "Enter new name: " BASENAME < /dev/tty
BASENAME_ESC=$(printf %q "$BASENAME")
;;
*)
continue
;;
esac
fi
if mv -v -- "${PTH:?}" "./${BASENAME:?}"; then
"$XPLR" -m 'LogSuccess: %q' "$PTH_ESC moved to ./$BASENAME_ESC"
"$XPLR" -m 'FocusPath: %q' "$BASENAME"
else
"$XPLR" -m 'LogError: %q' "could not move $PTH_ESC to ./$BASENAME_ESC"
fi
done < "${XPLR_PIPE_SELECTION_OUT:?}")
read -p "[enter to continue]"
done < "${XPLR_PIPE_SELECTION_OUT:?}"
echo
read -p "[press enter to continue]"
]===],
},
"PopMode",
@ -1533,22 +1559,35 @@ xplr.config.modes.builtin.selection_ops = {
{
BashExec0 = [===[
"$XPLR" -m ExplorePwd
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
PTH_ESC=$(printf %q "$PTH")
BASENAME=$(basename -- "$PTH")
BASENAME_ESC=$(printf %q "$BASENAME")
while [ -e "$BASENAME" ]; do
BASENAME="$BASENAME (softlinked)"
BASENAME_ESC=$(printf %q "$BASENAME")
done
if [ -e "$BASENAME" ]; then
echo
echo "$BASENAME_ESC exists, do you want to overwrite it?"
read -p "[y]es, [n]o, [S]kip: " ANS < /dev/tty
case "$ANS" in
[yY]*)
;;
[nN]*)
read -p "Enter new name: " BASENAME < /dev/tty
BASENAME_ESC=$(printf %q "$BASENAME")
;;
*)
continue
;;
esac
fi
if ln -sv -- "${PTH:?}" "./${BASENAME:?}"; then
"$XPLR" -m 'LogSuccess: %q' "$PTH_ESC softlinked as ./$BASENAME_ESC"
"$XPLR" -m 'FocusPath: %q' "$BASENAME"
else
"$XPLR" -m 'LogError: %q' "could not softlink $PTH_ESC as ./$BASENAME_ESC"
fi
done < "${XPLR_PIPE_SELECTION_OUT:?}")
read -p "[enter to continue]"
done < "${XPLR_PIPE_SELECTION_OUT:?}"
echo
read -p "[press enter to continue]"
]===],
},
"PopMode",
@ -1560,22 +1599,35 @@ xplr.config.modes.builtin.selection_ops = {
{
BashExec0 = [===[
"$XPLR" -m ExplorePwd
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
PTH_ESC=$(printf %q "$PTH")
BASENAME=$(basename -- "$PTH")
BASENAME_ESC=$(printf %q "$BASENAME")
while [ -e "$BASENAME" ]; do
BASENAME="$BASENAME (hardlinked)"
BASENAME_ESC=$(printf %q "$BASENAME")
done
if [ -e "$BASENAME" ]; then
echo
echo "$BASENAME_ESC exists, do you want to overwrite it?"
read -p "[y]es, [n]o, [S]kip: " ANS < /dev/tty
case "$ANS" in
[yY]*)
;;
[nN]*)
read -p "Enter new name: " BASENAME < /dev/tty
BASENAME_ESC=$(printf %q "$BASENAME")
;;
*)
continue
;;
esac
fi
if ln -v -- "${PTH:?}" "./${BASENAME:?}"; then
"$XPLR" -m 'LogSuccess: %q' "$PTH_ESC hardlinked as ./$BASENAME_ESC"
"$XPLR" -m 'FocusPath: %q' "$BASENAME"
else
"$XPLR" -m 'LogError: %q' "could not hardlink $PTH_ESC as ./$BASENAME_ESC"
fi
done < "${XPLR_PIPE_SELECTION_OUT:?}")
read -p "[enter to continue]"
done < "${XPLR_PIPE_SELECTION_OUT:?}"
echo
read -p "[press enter to continue]"
]===],
},
"PopMode",
@ -1752,9 +1804,9 @@ xplr.config.modes.builtin.number = {
}
xplr.config.modes.builtin.number.key_bindings.on_key["j"] =
xplr.config.modes.builtin.number.key_bindings.on_key["down"]
xplr.config.modes.builtin.number.key_bindings.on_key["down"]
xplr.config.modes.builtin.number.key_bindings.on_key["k"] =
xplr.config.modes.builtin.number.key_bindings.on_key["up"]
xplr.config.modes.builtin.number.key_bindings.on_key["up"]
-- The builtin go to mode.
--
@ -1812,9 +1864,9 @@ xplr.config.modes.builtin.go_to = {
exit 1
fi
fi
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
$OPENER "${PTH:?}" > /dev/null 2>&1
done < "${XPLR_PIPE_RESULT_OUT:?}")
done < "${XPLR_PIPE_RESULT_OUT:?}"
]===],
},
"ClearScreen",
@ -1926,8 +1978,14 @@ xplr.config.modes.builtin.delete = {
messages = {
{
BashExec0 = [===[
cat "${XPLR_PIPE_RESULT_OUT:?}" | xargs -0 printf '%q\n'
echo
read -p "Permanently delete these files? [Y/n]: " ANS
[ "${ANS:-Y}" = "Y" ] || [ "$ANS" = "y" ] || exit 0
echo
"$XPLR" -m ExplorePwd
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
PTH_ESC=$(printf %q "$PTH")
if rm -rfv -- "${PTH:?}"; then
"$XPLR" -m 'LogSuccess: %q' "$PTH_ESC deleted"
@ -1935,8 +1993,9 @@ xplr.config.modes.builtin.delete = {
"$XPLR" -m 'LogError: %q' "could not delete $PTH_ESC"
"$XPLR" -m 'FocusPath: %q' "$PTH"
fi
done < "${XPLR_PIPE_RESULT_OUT:?}")
read -p "[enter to continue]"
done < "${XPLR_PIPE_RESULT_OUT:?}"
echo
read -p "[press enter to continue]"
]===],
},
"PopMode",
@ -1947,8 +2006,14 @@ xplr.config.modes.builtin.delete = {
messages = {
{
BashExec0 = [===[
cat "${XPLR_PIPE_RESULT_OUT:?}" | xargs -0 printf '%q\n'
echo
read -p "Permanently delete these files? [Y/n]: " ANS
[ "${ANS:-Y}" = "Y" ] || [ "$ANS" = "y" ] || exit 0
echo
"$XPLR" -m ExplorePwd
(while IFS= read -r -d '' PTH; do
while IFS= read -r -d '' PTH; do
PTH_ESC=$(printf %q "$PTH")
if [ -d "$PTH" ] && [ ! -L "$PTH" ]; then
if rmdir -v -- "${PTH:?}"; then
@ -1965,8 +2030,9 @@ xplr.config.modes.builtin.delete = {
"$XPLR" -m 'FocusPath: %q' "$PTH"
fi
fi
done < "${XPLR_PIPE_RESULT_OUT:?}")
read -p "[enter to continue]"
done < "${XPLR_PIPE_RESULT_OUT:?}"
echo
read -p "[press enter to continue]"
]===],
},
"PopMode",
@ -2220,9 +2286,9 @@ xplr.config.modes.builtin.search = {
}
xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-n"] =
xplr.config.modes.builtin.search.key_bindings.on_key["down"]
xplr.config.modes.builtin.search.key_bindings.on_key["down"]
xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-p"] =
xplr.config.modes.builtin.search.key_bindings.on_key["up"]
xplr.config.modes.builtin.search.key_bindings.on_key["up"]
-- The builtin filter mode.
--
@ -2923,14 +2989,14 @@ xplr.fn.builtin.fmt_general_table_row_cols_2 = function(m)
local T = xplr.util.paint("T", { fg = "Red" })
return xplr.util
.permissions_rwx(m.permissions)
:gsub("r", r)
:gsub("w", w)
:gsub("x", x)
:gsub("s", s)
:gsub("S", S)
:gsub("t", t)
:gsub("T", T)
.permissions_rwx(m.permissions)
:gsub("r", r)
:gsub("w", w)
:gsub("x", x)
:gsub("s", s)
:gsub("S", S)
:gsub("t", t)
:gsub("T", T)
end
-- Renders the fourth column in the table

@ -160,24 +160,24 @@ mod tests {
assert!(check_version(VERSION, "foo path").is_ok());
// Current release if OK
assert!(check_version("0.21.1", "foo path").is_ok());
assert!(check_version("0.21.2", "foo path").is_ok());
// Prev major release is ERR
// - Not yet
// Prev minor release is ERR (Change when we get to v1)
assert!(check_version("0.20.1", "foo path").is_err());
assert!(check_version("0.20.2", "foo path").is_err());
// Prev bugfix release is OK
assert!(check_version("0.21.0", "foo path").is_ok());
assert!(check_version("0.21.1", "foo path").is_ok());
// Next major release is ERR
assert!(check_version("1.20.1", "foo path").is_err());
assert!(check_version("1.20.2", "foo path").is_err());
// Next minor release is ERR
assert!(check_version("0.22.1", "foo path").is_err());
assert!(check_version("0.22.2", "foo path").is_err());
// Next bugfix release is ERR (Change when we get to v1)
assert!(check_version("0.21.2", "foo path").is_err());
assert!(check_version("0.21.3", "foo path").is_err());
}
}

Loading…
Cancel
Save