Add and integrate sdn-edit
All checks were successful
Alpine 3.23 Success
Alpine 3.23 aarch64 Success
Arch Linux AUR Success
OpenBSD 7.8 Success

This commit is contained in:
2026-01-27 15:35:03 +01:00
parent dbea5cb193
commit 1dc39f900c
5 changed files with 96 additions and 8 deletions

View File

@@ -36,9 +36,9 @@ include (GNUInstallDirs)
# sdn-mc-ext should be in libexec, but we prefer it in PATH.
install (TARGETS sdn sdn-mc-ext
DESTINATION ${CMAKE_INSTALL_BINDIR})
install (PROGRAMS sdn-install sdn-open sdn-view
install (PROGRAMS sdn-install sdn-open sdn-view sdn-edit
DESTINATION ${CMAKE_INSTALL_BINDIR})
install (FILES sdn.1 sdn-install.1 sdn-open.1 sdn-view.1
install (FILES sdn.1 sdn-install.1 sdn-open.1 sdn-view.1 sdn-edit.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})

6
NEWS
View File

@@ -1,3 +1,9 @@
Unreleased
* Added an sdn-edit script analogous to sdn-view, bound it to F4,
and moved the original key binding to F14.
1.1.0 (2026-01-10)
* Added selection functionality, and adjusted key bindings:

48
sdn-edit Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/sh -e
# sdn-edit: an editor for sdn that makes use of Midnight Commander configuration
# to make more kinds of files directly editable
if [ "$#" -ne 1 ]
then
echo "Usage: $0 FILE" >&2
exit 2
fi
# This handles both MC_DATADIR and odd installation locations.
datadir=
if command -v mc >/dev/null
then datadir=$(mc --datadir | sed 's/ (.*)$//')
fi
config=
for dir in "$HOME"/.config/mc "$datadir" /etc/mc
do
if [ -n "$dir" -a -f "$dir/mc.ext.ini" ]
then
config=$dir/mc.ext.ini
break
fi
done
# This is often used in %env{} expansion, so let's be on the same page.
export PAGER=${PAGER:-less}
export MC_EXT_FILENAME=$(realpath "$1")
export MC_EXT_BASENAME=$(basename "$1")
export MC_EXT_CURRENTDIR=$(dirname "$MC_EXT_FILENAME")
output=$(sdn-mc-ext <"$config" "$(file -Lbz "$1")" \
"$MC_EXT_FILENAME" "$MC_EXT_BASENAME" "$MC_EXT_CURRENTDIR" Edit || :)
kind=$(echo "$output" | sed -n 1p)
command=$(echo "$output" | sed -n 2p)
case "$kind" in
'')
if [ -n "$command" ]
then eval "$command"
else "${VISUAL:-${EDITOR:-vi}}" -- "$MC_EXT_FILENAME"
fi
;;
*)
echo "Unsupported: $kind" >&2
exit 1
esac

24
sdn-edit.1 Normal file
View File

@@ -0,0 +1,24 @@
.Dd January 27, 2026
.Dt SDN-EDIT 1
.Os
.Sh NAME
.Nm sdn-edit
.Nd run Midnight Commander edit configuration externally
.Sh SYNOPSIS
.Nm sdn-edit
.Ar path
.Sh DESCRIPTION
.Nm
invokes
.Ev VISUAL ,
.Ev EDITOR
or a fallback editor on the passed filename.
.Pp
If it succeeds in finding a
.Xr mc 1
.Pa mc.ext.ini
file, it will first process it, and run the respective command.
.Sh REPORTING BUGS
Use
.Lk https://git.janouch.name/p/sdn
to report bugs, request features, or submit pull requests.

22
sdn.cpp
View File

@@ -440,7 +440,7 @@ enum { ALT = 1 << 24, SYM = 1 << 25 }; // Outside the range of Unicode
#define ACTIONS(XX) XX(NONE) XX(HELP) XX(QUIT) XX(QUIT_NO_CHDIR) \
XX(ENTER) XX(OPEN) XX(CHOOSE) XX(CHOOSE_FULL) \
XX(VIEW_RAW) XX(VIEW) XX(EDIT) XX(SORT_LEFT) XX(SORT_RIGHT) \
XX(VIEW_RAW) XX(VIEW) XX(EDIT) XX(EDIT_RAW) XX(SORT_LEFT) XX(SORT_RIGHT) \
XX(SELECT) XX(DESELECT) XX(SELECT_TOGGLE) XX(SELECT_ABORT) \
XX(UP) XX(DOWN) XX(TOP) XX(BOTTOM) XX(HIGH) XX(MIDDLE) XX(LOW) \
XX(PAGE_PREVIOUS) XX(PAGE_NEXT) XX(SCROLL_UP) XX(SCROLL_DOWN) XX(CENTER) \
@@ -466,7 +466,7 @@ static map<Key, action> g_normal_actions {
{'t', ACTION_CHOOSE}, {'T', ACTION_CHOOSE_FULL},
{KEY (F (1)), ACTION_HELP}, {'h', ACTION_HELP},
{KEY (F (3)), ACTION_VIEW}, {KEY (F (13)), ACTION_VIEW_RAW},
{KEY (F (4)), ACTION_EDIT},
{KEY (F (4)), ACTION_EDIT}, {KEY (F (14)), ACTION_EDIT_RAW},
{'q', ACTION_QUIT}, {ALT | 'q', ACTION_QUIT_NO_CHDIR},
// M-o ought to be the same shortcut the navigator is launched with
{ALT | 'o', ACTION_QUIT}, {'<', ACTION_SORT_LEFT}, {'>', ACTION_SORT_RIGHT},
@@ -1081,9 +1081,16 @@ fun sdn_view (const string &filename) {
(const char *) getenv ("PAGER"), "less", "cat"}, filename);
}
fun edit (const string &filename) {
run_program ({(const char *) getenv ("VISUAL"),
(const char *) getenv ("EDITOR"), "vi"}, filename);
fun edit_raw (const string &filename) {
run_program ({
(const char *) getenv ("VISUAL"), (const char *) getenv ("EDITOR"),
"vi"}, filename);
}
fun sdn_edit (const string &filename) {
run_program ({(const char *) getenv ("SDN_EDITOR"), "sdn-edit",
(const char *) getenv ("VISUAL"), (const char *) getenv ("EDITOR"),
"vi"}, filename);
}
fun run_pager (FILE *contents) {
@@ -1550,7 +1557,10 @@ fun handle (Key k) -> bool {
(is_directory ? change_dir : sdn_view) (current.filename);
break;
case ACTION_EDIT:
edit (current.filename);
sdn_edit (current.filename);
break;
case ACTION_EDIT_RAW:
edit_raw (current.filename);
break;
case ACTION_HELP:
show_help ();