mirror of
https://github.com/neovim/neovim.git
synced 2026-08-29 10:31:48 +00:00
feat(build): HAVE_UNIBILIUM
compile time features are hot again. Note: this changes the &term value for builtin definition from 'builtin_xterm' to just 'xterm'. It's an xterm regardless of we use an external definition or an internal. Prior to this commit the vast majority of POSIX users will have used external terminfo, so plugins and scripts are only going to have checked for &term == 'xterm' or 'tmux' or whatever. The status of external loading is still available in "nvim -V3" output.
This commit is contained in:
@@ -32,14 +32,12 @@ find_package(Iconv REQUIRED)
|
||||
find_package(Libuv 1.28.0 REQUIRED)
|
||||
find_package(Lpeg REQUIRED)
|
||||
find_package(Treesitter 0.25.0 REQUIRED)
|
||||
find_package(Unibilium 2.0 REQUIRED)
|
||||
find_package(UTF8proc REQUIRED)
|
||||
|
||||
target_link_libraries(main_lib INTERFACE
|
||||
iconv
|
||||
lpeg
|
||||
treesitter
|
||||
unibilium
|
||||
utf8proc)
|
||||
target_link_libraries(nlua0 PUBLIC lpeg)
|
||||
|
||||
@@ -48,6 +46,12 @@ if(ENABLE_LIBINTL)
|
||||
target_link_libraries(main_lib INTERFACE libintl)
|
||||
endif()
|
||||
|
||||
if(ENABLE_UNIBILIUM)
|
||||
find_package(Unibilium 2.0 REQUIRED)
|
||||
target_compile_definitions(nvim_bin PRIVATE HAVE_UNIBILIUM)
|
||||
target_link_libraries(main_lib INTERFACE unibilium)
|
||||
endif()
|
||||
|
||||
if(ENABLE_WASMTIME)
|
||||
find_package(Wasmtime 29.0.1 EXACT REQUIRED)
|
||||
target_link_libraries(main_lib INTERFACE wasmtime)
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unibilium.h>
|
||||
|
||||
#ifdef HAVE_UNIBILIUM
|
||||
# include <unibilium.h>
|
||||
#endif
|
||||
|
||||
#include "klib/kvec.h"
|
||||
#include "nvim/api/private/defs.h"
|
||||
@@ -68,71 +71,60 @@ bool terminfo_is_bsd_console(const char *term)
|
||||
const TerminfoEntry *terminfo_from_builtin(const char *term, char **termname)
|
||||
{
|
||||
if (terminfo_is_term_family(term, "xterm")) {
|
||||
*termname = "builtin_xterm";
|
||||
*termname = "xterm";
|
||||
return &xterm_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "screen")) {
|
||||
*termname = "builtin_screen";
|
||||
*termname = "screen";
|
||||
return &screen_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "tmux")) {
|
||||
*termname = "builtin_tmux";
|
||||
*termname = "tmux";
|
||||
return &tmux_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "rxvt")) {
|
||||
*termname = "builtin_rxvt";
|
||||
*termname = "rxvt";
|
||||
return &rxvt_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "putty")) {
|
||||
*termname = "builtin_putty";
|
||||
*termname = "putty";
|
||||
return &putty_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "linux")) {
|
||||
*termname = "builtin_linux";
|
||||
*termname = "linux";
|
||||
return &linux_16colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "interix")) {
|
||||
*termname = "builtin_interix";
|
||||
*termname = "interix";
|
||||
return &interix_8colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "iterm")
|
||||
|| terminfo_is_term_family(term, "iterm2")
|
||||
|| terminfo_is_term_family(term, "iTerm.app")
|
||||
|| terminfo_is_term_family(term, "iTerm2.app")) {
|
||||
*termname = "builtin_iterm";
|
||||
*termname = "iterm";
|
||||
return &iterm_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "st")) {
|
||||
*termname = "builtin_st";
|
||||
*termname = "st";
|
||||
return &st_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "gnome")
|
||||
|| terminfo_is_term_family(term, "vte")) {
|
||||
*termname = "builtin_vte";
|
||||
*termname = "vte";
|
||||
return &vte_256colour_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "cygwin")) {
|
||||
*termname = "builtin_cygwin";
|
||||
*termname = "cygwin";
|
||||
return &cygwin_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "win32con")) {
|
||||
*termname = "builtin_win32con";
|
||||
*termname = "win32con";
|
||||
return &win32con_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "conemu")) {
|
||||
*termname = "builtin_conemu";
|
||||
*termname = "conemu";
|
||||
return &conemu_terminfo;
|
||||
} else if (terminfo_is_term_family(term, "vtpcon")) {
|
||||
*termname = "builtin_vtpcon";
|
||||
*termname = "vtpcon";
|
||||
return &vtpcon_terminfo;
|
||||
} else {
|
||||
*termname = "builtin_ansi";
|
||||
*termname = "ansi";
|
||||
return &ansi_terminfo;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t unibi_find_ext_str(unibi_term *ut, const char *name)
|
||||
{
|
||||
size_t max = unibi_count_ext_str(ut);
|
||||
for (size_t i = 0; i < max; i++) {
|
||||
const char *n = unibi_get_ext_str_name(ut, i);
|
||||
if (n && 0 == strcmp(n, name)) {
|
||||
return (ssize_t)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool terminfo_from_unibilium(TerminfoEntry *ti, char *termname, Arena *arena)
|
||||
bool terminfo_from_database(TerminfoEntry *ti, char *termname, Arena *arena)
|
||||
{
|
||||
#ifdef HAVE_UNIBILIUM
|
||||
unibi_term *ut = unibi_from_term(termname);
|
||||
if (!ut) {
|
||||
return false;
|
||||
@@ -156,9 +148,9 @@ bool terminfo_from_unibilium(TerminfoEntry *ti, char *termname, Arena *arena)
|
||||
}
|
||||
|
||||
static const enum unibi_string uni_ids[] = {
|
||||
#define X(name) unibi_##name,
|
||||
# define X(name) unibi_##name,
|
||||
XLIST_TERMINFO_BUILTIN
|
||||
#undef X
|
||||
# undef X
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(uni_ids); i++) {
|
||||
@@ -167,26 +159,31 @@ bool terminfo_from_unibilium(TerminfoEntry *ti, char *termname, Arena *arena)
|
||||
}
|
||||
|
||||
static const char *uni_ext[] = {
|
||||
#define X(informal_name, terminfo_name) #terminfo_name,
|
||||
# define X(informal_name, terminfo_name) #terminfo_name,
|
||||
XLIST_TERMINFO_EXT
|
||||
#undef X
|
||||
# undef X
|
||||
};
|
||||
|
||||
size_t max = unibi_count_ext_str(ut);
|
||||
for (size_t i = 0; i < ARRAY_SIZE(uni_ext); i++) {
|
||||
ssize_t val = unibi_find_ext_str(ut, uni_ext[i]);
|
||||
if (val >= 0) {
|
||||
const char *data = unibi_get_ext_str(ut, (size_t)val);
|
||||
ti->defs[kTermExtOffset + i] = data ? arena_strdup(arena, data) : NULL;
|
||||
const char *name = uni_ext[i];
|
||||
for (size_t val = 0; val < max; val++) {
|
||||
const char *n = unibi_get_ext_str_name(ut, val);
|
||||
if (n && strequal(n, name)) {
|
||||
const char *data = unibi_get_ext_str(ut, val);
|
||||
ti->defs[kTermExtOffset + i] = data ? arena_strdup(arena, data) : NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define X(name) { unibi_key_##name, unibi_string_begin_ },
|
||||
#define Y(name) { unibi_key_##name, unibi_key_s##name },
|
||||
# define X(name) { unibi_key_##name, unibi_string_begin_ },
|
||||
# define Y(name) { unibi_key_##name, unibi_key_s##name },
|
||||
static const enum unibi_string uni_keys[][2] = {
|
||||
XYLIST_TERMINFO_KEYS
|
||||
};
|
||||
#undef X
|
||||
#undef Y
|
||||
# undef X
|
||||
# undef Y
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(uni_keys); i++) {
|
||||
const char *val = unibi_get_str(ut, uni_keys[i][0]);
|
||||
@@ -200,9 +197,9 @@ bool terminfo_from_unibilium(TerminfoEntry *ti, char *termname, Arena *arena)
|
||||
}
|
||||
|
||||
static const enum unibi_string uni_fkeys[] = {
|
||||
#define X(name) unibi_key_##name,
|
||||
# define X(name) unibi_key_##name,
|
||||
XLIST_TERMINFO_FKEYS
|
||||
#undef X
|
||||
# undef X
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(uni_fkeys); i++) {
|
||||
@@ -212,6 +209,9 @@ bool terminfo_from_unibilium(TerminfoEntry *ti, char *termname, Arena *arena)
|
||||
|
||||
unibi_destroy(ut);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *fmt(bool val)
|
||||
@@ -223,11 +223,16 @@ static const char *fmt(bool val)
|
||||
/// Serves a similar purpose as Vim `:set termcap` (removed in Nvim).
|
||||
///
|
||||
/// @return allocated string
|
||||
String terminfo_info_msg(const TerminfoEntry *ti, const char *termname)
|
||||
String terminfo_info_msg(const TerminfoEntry *ti, const char *termname, bool from_db)
|
||||
{
|
||||
StringBuilder data = KV_INITIAL_VALUE;
|
||||
|
||||
kv_printf(data, "&term: %s\n", termname);
|
||||
if (from_db) {
|
||||
kv_printf(data, "using terminfo database\n");
|
||||
} else {
|
||||
kv_printf(data, "using builtin terminfo\n");
|
||||
}
|
||||
kv_printf(data, "\n");
|
||||
|
||||
kv_printf(data, "Boolean capabilities:\n");
|
||||
|
||||
@@ -86,6 +86,7 @@ struct TUIData {
|
||||
int row, col;
|
||||
int out_fd;
|
||||
int pending_resize_events;
|
||||
bool terminfo_found_in_db;
|
||||
bool can_change_scroll_region;
|
||||
bool has_left_and_right_margin_mode;
|
||||
bool has_sync_mode;
|
||||
@@ -382,15 +383,15 @@ static void terminfo_start(TUIData *tui)
|
||||
#endif
|
||||
|
||||
// Set up terminfo.
|
||||
bool found_in_db = false;
|
||||
tui->terminfo_found_in_db = false;
|
||||
if (term) {
|
||||
if (terminfo_from_unibilium(&tui->ti, term, &tui->ti_arena)) {
|
||||
if (terminfo_from_database(&tui->ti, term, &tui->ti_arena)) {
|
||||
tui->term = arena_strdup(&tui->ti_arena, term);
|
||||
found_in_db = true;
|
||||
tui->terminfo_found_in_db = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_in_db) {
|
||||
if (!tui->terminfo_found_in_db) {
|
||||
const TerminfoEntry *new = terminfo_from_builtin(term, &tui->term);
|
||||
// we will patch it below, so make a copy
|
||||
memcpy(&tui->ti, new, sizeof tui->ti);
|
||||
@@ -1596,7 +1597,7 @@ static void show_verbose_terminfo(TUIData *tui)
|
||||
ADD_C(title, CSTR_AS_OBJ("Title"));
|
||||
ADD_C(chunks, ARRAY_OBJ(title));
|
||||
MAXSIZE_TEMP_ARRAY(info, 1);
|
||||
String str = terminfo_info_msg(&tui->ti, tui->term);
|
||||
String str = terminfo_info_msg(&tui->ti, tui->term, tui->terminfo_found_in_db);
|
||||
ADD_C(info, STRING_OBJ(str));
|
||||
ADD_C(chunks, ARRAY_OBJ(info));
|
||||
MAXSIZE_TEMP_ARRAY(end_fold, 2);
|
||||
|
||||
Reference in New Issue
Block a user