3 Commits

Author SHA1 Message Date
769be55153 Update README.adoc
All checks were successful
Alpine 3.23 Success
Alpine 3.23 aarch64 Success
Arch Linux AUR Success
OpenBSD 7.8 Success
2026-01-27 17:23:21 +01:00
1dc39f900c 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
2026-01-27 15:35:55 +01:00
dbea5cb193 CMakeLists.txt: adjust packaging
All checks were successful
Alpine 3.23 Success
Arch Linux AUR Success
OpenBSD 7.8 Success
Alpine 3.23 aarch64 Success
2026-01-25 12:02:53 +01:00
6 changed files with 106 additions and 15 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})
@@ -46,7 +46,7 @@ set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Directory navigator")
set (CPACK_PACKAGE_VENDOR "Premysl Eric Janouch")
set (CPACK_PACKAGE_CONTACT "Přemysl Eric Janouch <p@janouch.name>")
set (CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set (CPACK_GENERATOR "TGZ;ZIP")
set (CPACK_GENERATOR "TGZ")
set (CPACK_PACKAGE_FILE_NAME
"${PROJECT_NAME}-${PROJECT_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
set (CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}-${PROJECT_VERSION}")
@@ -54,5 +54,8 @@ set (CPACK_SOURCE_GENERATOR "TGZ;ZIP")
set (CPACK_SOURCE_IGNORE_FILES "/\\\\.git;/build;/CMakeLists.txt.user")
set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}")
set (CPACK_DEBIAN_PACKAGE_RECOMMENDS "mc")
set (CPACK_DEBIAN_PACKAGE_SECTION "utils")
set (CPACK_SET_DESTDIR TRUE)
include (CPack)

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:

View File

@@ -99,13 +99,13 @@ normal l enter
Helper programs
~~~~~~~~~~~~~~~
The F3, F13 and F4 keys are normally bound to actions 'view', 'view-raw',
and 'edit', similarly to Norton Commander and other orthodox file managers.
The helper programs used here may be changed by setting the PAGER and VISUAL
(or EDITOR) environment variables.
The F3, F13, F4, F14 keys are normally bound to actions 'view', 'view-raw',
'edit', and 'edit-raw', similarly to Norton Commander and other orthodox
file managers. The helper programs used here may be changed by setting
the PAGER and VISUAL (or EDITOR) environment variables.
If 'view' finds Midnight Commander, it will make use of its configuration
to apply any matching filter, such as to produce archive listings,
If 'view' and 'edit' find Midnight Commander, they will make use of its
configuration to apply any matching filter, such as to produce archive listings,
or it will run the respective command.
While it is mostly possible to get 'mcview' working using an invocation like

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 ();