vis icon indicating copy to clipboard operation
vis copied to clipboard

build: allow vendored termkey

Open sewnie opened this issue 8 months ago • 10 comments

As discussed in #79, martanne expressed his refusal for a vendored libtermkey, however, there are distributions that do not want to package an EOL or deprecated library, hence, this patch, similar to Neovim, vendors libtermkey into the source tree, while still allowing distributors to use the system libtermkey by default, if detected.

Changed of note to libtermkey:

  • Removed unibilium support

sewnie avatar May 17 '25 08:05 sewnie

I have it now in the devel branch, but I am not sure about it: Neovim is not exactly shining example in terms of dependencies management, they always went slightly too NIH-syndrom way to my taste. Isn’t this the moment, where you can be the saviour of the universe, pick libtermkey and start your own fork with it, which can be then used both by us and them? Seems certainly better than to maintain these files separately in the unknown number of vendored copies.

mcepl avatar May 17 '25 09:05 mcepl

I see no problem with vendoring it. If you want your project to last and you insist on using libraries this is the only way.

Changed of note to libtermkey:

  • Removed unibilium support

I would go one-step further and fix termkey so that it builds as a single file:

0001-termkey-build-as-single-file.patch.txt

commit f7016ad
Author: Randy Palamar <[email protected]>
Date:   Sat May 17 07:27:49 2025 -0600

    termkey: build as single file

diff --git a/configure b/configure
index d901660..a3c299e 100755
--- a/configure
+++ b/configure
@@ -348,9 +348,11 @@ EOF
 fi
 
 CONFIG_SYSTEM_TERMKEY=0
-TERMKEY_SRC='termkey.c driver-csi.c driver-ti.c'
+TERMKEY_SRC='termkey-vis.c'
 
-if test "$systermkey" != "no" ; then
+if test "$systermkey" = "no" ; then
+	CFLAGS_TERMKEY="-Itermkey"
+else
 	printf "checking for system libtermkey... "
 	cat > "$tmpc" <<EOF
 #include <termkey.h>
diff --git a/termkey-vis.c b/termkey-vis.c
new file mode 100644
index 0000000..1050079
--- /dev/null
+++ b/termkey-vis.c
@@ -0,0 +1,5 @@
+#include "termkey/termkey.h"
+
+#include "termkey/driver-csi.c"
+#include "termkey/driver-ti.c"
+#include "termkey/termkey.c"
diff --git a/driver-csi.c b/termkey/driver-csi.c
similarity index 98%
rename from driver-csi.c
rename to termkey/driver-csi.c
index 37b1498..026c72c 100644
--- a/driver-csi.c
+++ b/termkey/driver-csi.c
@@ -499,7 +499,7 @@ static int register_keys(void)
   return 1;
 }
 
-static void *new_driver(TermKey *tk, const char *term)
+static void *csi_new_driver(TermKey *tk, const char *term)
 {
   if(!keyinfo_initialised)
     if(!register_keys())
@@ -516,7 +516,7 @@ static void *new_driver(TermKey *tk, const char *term)
   return csi;
 }
 
-static void free_driver(void *info)
+static void csi_free_driver(void *info)
 {
   TermKeyCsi *csi = info;
 
@@ -694,7 +694,7 @@ static TermKeyResult peekkey_ctrlstring(TermKey *tk, TermKeyCsi *csi, size_t int
   return TERMKEY_RES_KEY;
 }
 
-static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep)
+static TermKeyResult csi_peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep)
 {
   if(tk->buffcount == 0)
     return tk->is_closed ? TERMKEY_RES_EOF : TERMKEY_RES_NONE;
@@ -737,10 +737,10 @@ static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force
 struct TermKeyDriver termkey_driver_csi = {
   .name        = "CSI",
 
-  .new_driver  = new_driver,
-  .free_driver = free_driver,
+  .new_driver  = csi_new_driver,
+  .free_driver = csi_free_driver,
 
-  .peekkey = peekkey,
+  .peekkey = csi_peekkey,
 };
 
 TermKeyResult termkey_interpret_string(TermKey *tk, const TermKeyKey *key, const char **strp)
diff --git a/driver-ti.c b/termkey/driver-ti.c
similarity index 96%
rename from driver-ti.c
rename to termkey/driver-ti.c
index 723885a..0356fb9 100644
--- a/driver-ti.c
+++ b/termkey/driver-ti.c
@@ -320,7 +320,7 @@ static int load_terminfo(TermKeyTI *ti)
   return 1;
 }
 
-static void *new_driver(TermKey *tk, const char *term)
+static void *ti_new_driver(TermKey *tk, const char *term)
 {
   TermKeyTI *ti = malloc(sizeof *ti);
   if(!ti)
@@ -345,7 +345,7 @@ static void *new_driver(TermKey *tk, const char *term)
   return ti;
 }
 
-static int start_driver(TermKey *tk, void *info)
+static int ti_start_driver(TermKey *tk, void *info)
 {
   TermKeyTI *ti = info;
   struct stat statbuf;
@@ -385,7 +385,7 @@ static int start_driver(TermKey *tk, void *info)
   return 1;
 }
 
-static int stop_driver(TermKey *tk, void *info)
+static int ti_stop_driver(TermKey *tk, void *info)
 {
   TermKeyTI *ti = info;
   struct stat statbuf;
@@ -420,7 +420,7 @@ static int stop_driver(TermKey *tk, void *info)
   return 1;
 }
 
-static void free_driver(void *info)
+static void ti_free_driver(void *info)
 {
   TermKeyTI *ti = info;
 
@@ -440,7 +440,7 @@ static void free_driver(void *info)
 
 #define CHARAT(i) (tk->buffer[tk->buffstart + (i)])
 
-static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep)
+static TermKeyResult ti_peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep)
 {
   TermKeyTI *ti = info;
 
@@ -546,11 +546,11 @@ static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node)
 struct TermKeyDriver termkey_driver_ti = {
   .name        = "terminfo",
 
-  .new_driver  = new_driver,
-  .free_driver = free_driver,
+  .new_driver  = ti_new_driver,
+  .free_driver = ti_free_driver,
 
-  .start_driver = start_driver,
-  .stop_driver  = stop_driver,
+  .start_driver = ti_start_driver,
+  .stop_driver  = ti_stop_driver,
 
-  .peekkey = peekkey,
+  .peekkey = ti_peekkey,
 };
diff --git a/termkey-internal.h b/termkey/termkey-internal.h
similarity index 100%
rename from termkey-internal.h
rename to termkey/termkey-internal.h
diff --git a/termkey.c b/termkey/termkey.c
similarity index 100%
rename from termkey.c
rename to termkey/termkey.c
diff --git a/termkey.h b/termkey/termkey.h
similarity index 100%
rename from termkey.h
rename to termkey/termkey.h

rnpnr avatar May 17 '25 13:05 rnpnr

I would go one-step further and fix termkey so that it builds as a single file:

what differences does this make? i think it would make a difference in the source tree if all of the termkey files were combined to simply a header and a c source file

sewnie avatar May 17 '25 13:05 sewnie

what differences does this make?

Smaller and better codegen. I have an incomplete patch locally for doing this with the entirety of vis and I would also want to include termkey in the build if its included in our tree.

rnpnr avatar May 17 '25 14:05 rnpnr

termkey requires either curses or unibilium though.

sewnie avatar Jun 30 '25 12:06 sewnie

termkey requires either curses or unibilium though.

Yes, indeed. But vis can still be compiled with the ui-terminal-vt100.c even if you have to link with curses for vendored termkey.

ui-terminal-vt100.c is what is used when CONFIG_CURSES=0 is set in config.mk.

rnpnr avatar Jun 30 '25 12:06 rnpnr

Sorry, I can't quite understand what to do here. Should it error out on no curses available if vendored termkey is used?

sewnie avatar Jun 30 '25 13:06 sewnie

Yes I think that is appropriate. CONFIG_CURSES is probably a bad name for enabling/disabling ui-terminal-vt100.c but you don't need to fix that.

rnpnr avatar Jun 30 '25 13:06 rnpnr

Also, does this build correctly test/util/keys.c ? It seems to me, that this commit breaks my bisect.

mcepl avatar Jul 28 '25 07:07 mcepl