Skip to content

Conversation

@sewnie
Copy link
Contributor

@sewnie sewnie commented May 17, 2025

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

@mcepl
Copy link
Collaborator

mcepl commented May 17, 2025

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.

@rnpnr
Copy link
Collaborator

rnpnr commented May 17, 2025

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

@sewnie
Copy link
Contributor Author

sewnie commented May 17, 2025

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

@rnpnr
Copy link
Collaborator

rnpnr commented May 17, 2025

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.

Copy link
Collaborator

@rnpnr rnpnr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been using this for a while and it works great. I want to apply but there is an issue with the configure script now. Termkey always requires curses. But you can still build vis with no curses interface once termkey is built.

So the logic that needs to be covered is that when CONFIG_SYSTEM_TERMKEY=0 we need the cflags/ldflags from curses even when CONFIG_CURSES=0.

@sewnie
Copy link
Contributor Author

sewnie commented Jun 30, 2025

termkey requires either curses or unibilium though.

@rnpnr
Copy link
Collaborator

rnpnr commented Jun 30, 2025

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.

@sewnie
Copy link
Contributor Author

sewnie commented Jun 30, 2025

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

@rnpnr
Copy link
Collaborator

rnpnr commented Jun 30, 2025

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.

@mcepl
Copy link
Collaborator

mcepl commented Jul 28, 2025

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

@mcepl
Copy link
Collaborator

mcepl commented Nov 28, 2025

What's the status of this PR? Is it ready or not? What’s missing?

sewnie and others added 3 commits November 29, 2025 13:18
As discussed in martanne#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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants