summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2022-01-21 21:48:05 -0500
committerJune McEnroe <june@causal.agency>2022-01-21 22:02:56 -0500
commit72ec8e997beac9551685b7939dda34b024a41d29 (patch)
tree1aef5a2dcbd04bc276813a3ae32329c17a33889b
parentdash: Replace autotools with cmake (diff)
downloaddash-72ec8e997beac9551685b7939dda34b024a41d29.tar.gz
dash-72ec8e997beac9551685b7939dda34b024a41d29.zip
dash: Bind libedit's secret filename completion function
Check if the FreeBSD (and by extension macOS) _el_fn_sh_complete version
of the function exists, which does shell escaping of completed filenames
before _el_fn_complete learned to.

Tab is bound after calling el_set() and el_source() since the default
bindings set tab to something else, and it should always be filename
completion in the shell.
-rw-r--r--CMakeLists.txt4
-rw-r--r--config.h.in1
-rw-r--r--src/histedit.c8
3 files changed, 13 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5385049..9fc4bc8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -140,6 +140,10 @@ if(WITH_LIBEDIT)
 	else()
 		message(SEND_ERROR "Can't find libedit.")
 	endif()
+	set(CMAKE_REQUIRED_LIBRARIES edit)
+	check_symbol_exists(
+		_el_fn_sh_complete "histedit.h" HAVE__EL_FN_SH_COMPLETE
+	)
 else()
 	add_compile_definitions(SMALL)
 endif()
diff --git a/config.h.in b/config.h.in
index 382ad35..67341e0 100644
--- a/config.h.in
+++ b/config.h.in
@@ -21,4 +21,5 @@
 #cmakedefine HAVE_FNMATCH
 #cmakedefine HAVE_GLOB
 #cmakedefine HAVE_ST_MTIM
+#cmakedefine HAVE__EL_FN_SH_COMPLETE
 #cmakedefine WITH_LINENO
diff --git a/src/histedit.c b/src/histedit.c
index f5c90ab..3525e02 100644
--- a/src/histedit.c
+++ b/src/histedit.c
@@ -116,6 +116,13 @@ histedit(void)
 				if (hist)
 					el_set(el, EL_HIST, history, hist);
 				el_set(el, EL_PROMPT, getprompt);
+#ifdef HAVE__EL_FN_SH_COMPLETE
+				el_set(el, EL_ADDFN, "sh-complete", "Filename completion",
+					_el_fn_sh_complete);
+#else
+				el_set(el, EL_ADDFN, "sh-complete", "Filename completion",
+					_el_fn_complete);
+#endif
 			} else {
 bad:
 				out2str("sh: can't initialize editing\n");
@@ -133,6 +140,7 @@ bad:
 			else if (Eflag)
 				el_set(el, EL_EDITOR, "emacs");
 			el_source(el, NULL);
+			el_set(el, EL_BIND, "^I", "sh-complete", NULL);
 		}
 	} else {
 		INTOFF;