aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--core/ui.lua6
-rw-r--r--docs/api.md8
-rw-r--r--modules/lua/ta_api3
-rw-r--r--modules/lua/ta_tags1
-rw-r--r--src/textadept.c28
5 files changed, 32 insertions, 14 deletions
diff --git a/core/ui.lua b/core/ui.lua
index 497cadc4..19bf5881 100644
--- a/core/ui.lua
+++ b/core/ui.lua
@@ -26,6 +26,8 @@ local ui = ui
-- @field tabs (bool)
-- Whether or not to display the tab bar when multiple buffers are open.
-- The default value is `true`.
+-- A third option, `ui.SHOW_ALL_TABS` may be used to always show the tab bar,
+-- even if only one buffer is open.
-- @field silent_print (bool)
-- Whether or not to print messages to buffers silently.
-- This is not guaranteed to be a constant value, as Textadept may change it
@@ -33,8 +35,12 @@ local ui = ui
-- with a group of [`ui.print()`]() and [`ui._print()`]() function calls.
-- The default value is `false`, and focuses buffers when messages are printed
-- to them.
+-- @field SHOW_ALL_TABS (number)
+--
module('ui')]]
+ui.SHOW_ALL_TABS = 2 -- ui.tabs options must be greater than 1
+
ui.silent_print = false
-- Helper function for jumping to another view to print to, or creating a new
diff --git a/docs/api.md b/docs/api.md
index fe613407..958c69a0 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -7795,6 +7795,12 @@ Utilities for interacting with Textadept's user interface.
### Fields defined by `ui`
+<a id="ui.SHOW_ALL_TABS"></a>
+#### `ui.SHOW_ALL_TABS` (number)
+
+
+
+
<a id="ui.buffer_statusbar_text"></a>
#### `ui.buffer_statusbar_text` (string, Write-only)
@@ -7844,6 +7850,8 @@ The context menu for the buffer's tab, a [`ui.menu()`](#ui.menu).
Whether or not to display the tab bar when multiple buffers are open.
The default value is `true`.
+ A third option, `ui.SHOW_ALL_TABS` may be used to always show the tab bar,
+ even if only one buffer is open.
<a id="ui.title"></a>
#### `ui.title` (string, Write-only)
diff --git a/modules/lua/ta_api b/modules/lua/ta_api
index 014f3f73..4d1736b0 100644
--- a/modules/lua/ta_api
+++ b/modules/lua/ta_api
@@ -233,6 +233,7 @@ SEL_STREAM buffer.SEL_STREAM (number, Read-only)\n
SEL_THIN buffer.SEL_THIN (number, Read-only)\n
SESSION_LOAD events.SESSION_LOAD (string)\nEmitted when loading a session.\nArguments:\n\n* `session`: Table of session data to load. All handlers will have access\n to this same table.
SESSION_SAVE events.SESSION_SAVE (string)\nEmitted when saving a session.\nArguments:\n\n* `session`: Table of session data to save. All handlers will have access\n to this same table, and Textadept's default handler reserves the use of\n some keys.\n Note that functions, userdata, and circular table values cannot be saved.\n The latter case is not recognized at all, so beware.
+SHOW_ALL_TABS ui.SHOW_ALL_TABS (number)\n
SIGNAL textadept.editing.XPM_IMAGES.SIGNAL (table)\nThe image number for signals.
SLOT textadept.editing.XPM_IMAGES.SLOT (table)\nThe image number for slots.
STRING lexer.STRING (string)\nThe token name for string tokens.
@@ -927,7 +928,7 @@ tab_draw_mode view.tab_draw_mode (number)\nThe draw mode of visible tabs.\n\n* `
tab_indents buffer.tab_indents (bool)\nIndent text when tabbing within indentation.\nThe default value is `false`.
tab_label buffer.tab_label (string)\nThe buffer's tab label in the tab bar.
tab_width buffer.tab_width (number)\nThe number of space characters represented by a tab character.\nThe default value is `8`.
-tabs ui.tabs (bool)\nWhether or not to display the tab bar when multiple buffers are open.\nThe default value is `true`.
+tabs ui.tabs (bool)\nWhether or not to display the tab bar when multiple buffers are open.\nThe default value is `true`.\nA third option, `ui.SHOW_ALL_TABS` may be used to always show the tab bar,\neven if only one buffer is open.
tag buffer.tag (table, Read-only)\nList of capture text for capture numbers from a regular expression search.
tags _M.ansi_c.tags (table)\nList of ctags files to use for autocompletion in addition to the current\nproject's top-level *tags* file or the current directory's *tags* file.
tags _M.lua.tags (table)\nList of "fake" ctags files (or functions that return such files) to use for\nautocompletion.\nThe kind 'm' is recognized as a module, 'f' as a function, 't' as a table and\n'F' as a module or table field.\nThe *modules/lua/tadoc.lua* script can generate *tags* and\n*api* files for Lua modules via LuaDoc.
diff --git a/modules/lua/ta_tags b/modules/lua/ta_tags
index d105a598..c9165567 100644
--- a/modules/lua/ta_tags
+++ b/modules/lua/ta_tags
@@ -233,6 +233,7 @@ SEL_STREAM _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
SEL_THIN _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
SESSION_LOAD _HOME/modules/textadept/session.lua /^module('textadept.session')]]$/;" F class:events
SESSION_SAVE _HOME/modules/textadept/session.lua /^module('textadept.session')]]$/;" F class:events
+SHOW_ALL_TABS _HOME/core/ui.lua /^module('ui')]]$/;" F class:ui
SIGNAL _HOME/modules/textadept/editing.lua /^M.XPM_IMAGES = {not CURSES and '/* XPM */static char *class[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #001CD0","X c #008080","o c #0080E8","O c #00C0C0","+ c #24D0FC","@ c #00FFFF","# c #A4E8FC","$ c #C0FFFF","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or '*',not CURSES and '/* XPM */static char *namespace[] = {/* columns rows colors chars-per-pixel */"16 16 7 1 "," c #000000",". c #1D1D1D","X c #393939","o c #555555","O c #A8A8A8","+ c #AAAAAA","@ c None",/* pixels */"@@@@@@@@@@@@@@@@","@@@@+@@@@@@@@@@@","@@@.o@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@+.@@@@@@@+@@@@","@@+ @@@@@@@o.@@@","@@@ +@@@@@@+ @@@","@@@ +@@@@@@+ @@@","@@@.X@@@@@@@.+@@","@@@@+@@@@@@@ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@X.@@@","@@@@@@@@@@@+@@@@","@@@@@@@@@@@@@@@@"};' or '@',not CURSES and '/* XPM */static char *method[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOOOOO","OO X. OOOOOOOOO","OOOO OOOOOOOOOO"};' or '+',not CURSES and '/* XPM */static char *signal[] = {/* columns rows colors chars-per-pixel */"16 16 6 1 "," c #000000",". c #FF0000","X c #E0BC38","o c #F0DC5C","O c #FCFC80","+ c None",/* pixels */"++++++++++++++++","++++++++++++++++","++++++++++++++++","++++++++++ ++++","+++++++++ OO ++","++++++++ OOOOO +","+++++++ OOOOOX +","++++ + ooOOXX +","+++ OO oooXXX +","++ OOOOO ooXX ++","+ OOOOOX oX +++","+ ooOOXX + ++++","+ oooXXX +++++++","+ oooXX +++++..+","++ oX ++++++..+","++++ ++++++++++"};' or '~',not CURSES and '/* XPM */static char *slot[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOO ","OO X. OOOOOO O ","OOOO OOOOOOO "};' or '-',not CURSES and '/* XPM */static char *variable[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #8C748C","X c #9C94A4","o c #ACB4C0","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOO OOOOO","OOOOOOOO oo OOO","OOOOOOO ooooo OO","OOOOOO ooooo. OO","OOOOOO XXoo.. OO","OOOOOO XXX... OO","OOOOOO XXX.. OOO","OOOOOOO X. OOOO","OOOOOOOOO OOOOO","OOOOOOOOOOOOOOOO"};' or '.',not CURSES and '/* XPM */static char *struct[] = {/* columns rows colors chars-per-pixel */"16 16 14 1 "," c #000000",". c #008000","X c #00C000","o c #00FF00","O c #808000","+ c #C0C000","@ c #FFFF00","# c #008080","$ c #00C0C0","% c #00FFFF","& c #C0FFC0","* c #FFFFC0","= c #C0FFFF","- c None",/* pixels */"----- ---------","---- && -------","--- &&&oo ------","-- ooooo. ----","-- XXoo.. == --","-- XXX.. ===%% -","-- XXX. %%%%%# -","--- . $$%%## -","--- ** $$$### -","-- ***@@ $$## --","- @@@@@O $# ---","- ++@@OO - ----","- +++OOO -------","- +++OO --------","-- +O ---------","---- ----------"};' or '}',not CURSES and '/* XPM */static char *typedef[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #404040","X c #6D6D6D","o c #777777","O c #949494","+ c #ACACAC","@ c #BBBBBB","# c #DBDBDB","$ c #EEEEEE","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or ':',CLASS=1,NAMESPACE=2,METHOD=3,SIGNAL=4,SLOT=5,VARIABLE=6,STRUCT=7,TYPEDEF=8}$/;" F class:textadept.editing.XPM_IMAGES
SLOT _HOME/modules/textadept/editing.lua /^M.XPM_IMAGES = {not CURSES and '/* XPM */static char *class[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #001CD0","X c #008080","o c #0080E8","O c #00C0C0","+ c #24D0FC","@ c #00FFFF","# c #A4E8FC","$ c #C0FFFF","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or '*',not CURSES and '/* XPM */static char *namespace[] = {/* columns rows colors chars-per-pixel */"16 16 7 1 "," c #000000",". c #1D1D1D","X c #393939","o c #555555","O c #A8A8A8","+ c #AAAAAA","@ c None",/* pixels */"@@@@@@@@@@@@@@@@","@@@@+@@@@@@@@@@@","@@@.o@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@@ +@@@@@@@@@@@","@@+.@@@@@@@+@@@@","@@+ @@@@@@@o.@@@","@@@ +@@@@@@+ @@@","@@@ +@@@@@@+ @@@","@@@.X@@@@@@@.+@@","@@@@+@@@@@@@ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@+ @@@","@@@@@@@@@@@X.@@@","@@@@@@@@@@@+@@@@","@@@@@@@@@@@@@@@@"};' or '@',not CURSES and '/* XPM */static char *method[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOOOOO","OO X. OOOOOOOOO","OOOO OOOOOOOOOO"};' or '+',not CURSES and '/* XPM */static char *signal[] = {/* columns rows colors chars-per-pixel */"16 16 6 1 "," c #000000",". c #FF0000","X c #E0BC38","o c #F0DC5C","O c #FCFC80","+ c None",/* pixels */"++++++++++++++++","++++++++++++++++","++++++++++++++++","++++++++++ ++++","+++++++++ OO ++","++++++++ OOOOO +","+++++++ OOOOOX +","++++ + ooOOXX +","+++ OO oooXXX +","++ OOOOO ooXX ++","+ OOOOOX oX +++","+ ooOOXX + ++++","+ oooXXX +++++++","+ oooXX +++++..+","++ oX ++++++..+","++++ ++++++++++"};' or '~',not CURSES and '/* XPM */static char *slot[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #E0BC38","X c #F0DC5C","o c #FCFC80","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOO OOOO","OOOOOOOOO oo OO","OOOOOOOO ooooo O","OOOOOOO ooooo. O","OOOO O XXoo.. O","OOO oo XXX... O","OO ooooo XX.. OO","O ooooo. X. OOO","O XXoo.. O OOOO","O XXX... OOOOOOO","O XXX.. OOOOO ","OO X. OOOOOO O ","OOOO OOOOOOO "};' or '-',not CURSES and '/* XPM */static char *variable[] = {/* columns rows colors chars-per-pixel */"16 16 5 1 "," c #000000",". c #8C748C","X c #9C94A4","o c #ACB4C0","O c None",/* pixels */"OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOOOOOOOOO","OOOOOOOOO OOOOO","OOOOOOOO oo OOO","OOOOOOO ooooo OO","OOOOOO ooooo. OO","OOOOOO XXoo.. OO","OOOOOO XXX... OO","OOOOOO XXX.. OOO","OOOOOOO X. OOOO","OOOOOOOOO OOOOO","OOOOOOOOOOOOOOOO"};' or '.',not CURSES and '/* XPM */static char *struct[] = {/* columns rows colors chars-per-pixel */"16 16 14 1 "," c #000000",". c #008000","X c #00C000","o c #00FF00","O c #808000","+ c #C0C000","@ c #FFFF00","# c #008080","$ c #00C0C0","% c #00FFFF","& c #C0FFC0","* c #FFFFC0","= c #C0FFFF","- c None",/* pixels */"----- ---------","---- && -------","--- &&&oo ------","-- ooooo. ----","-- XXoo.. == --","-- XXX.. ===%% -","-- XXX. %%%%%# -","--- . $$%%## -","--- ** $$$### -","-- ***@@ $$## --","- @@@@@O $# ---","- ++@@OO - ----","- +++OOO -------","- +++OO --------","-- +O ---------","---- ----------"};' or '}',not CURSES and '/* XPM */static char *typedef[] = {/* columns rows colors chars-per-pixel */"16 16 10 1 "," c #000000",". c #404040","X c #6D6D6D","o c #777777","O c #949494","+ c #ACACAC","@ c #BBBBBB","# c #DBDBDB","$ c #EEEEEE","% c None",/* pixels */"%%%%% %%%%%%%%%","%%%% ## %%%%%%%","%%% ###++ %%%%%%","%% +++++. %%%%","%% oo++.. $$ %%","%% ooo.. $$$@@ %","%% ooo. @@@@@X %","%%% . OO@@XX %","%%% ## OOOXXX %","%% ###++ OOXX %%","% +++++. OX %%%","% oo++.. % %%%%","% ooo... %%%%%%%","% ooo.. %%%%%%%%","%% o. %%%%%%%%%","%%%% %%%%%%%%%%"};' or ':',CLASS=1,NAMESPACE=2,METHOD=3,SIGNAL=4,SLOT=5,VARIABLE=6,STRUCT=7,TYPEDEF=8}$/;" F class:textadept.editing.XPM_IMAGES
STRING _HOME/lexers/lexer.lua /^module('lexer')]=]$/;" F class:lexer
diff --git a/src/textadept.c b/src/textadept.c
index fe16f120..e8dc5584 100644
--- a/src/textadept.c
+++ b/src/textadept.c
@@ -189,7 +189,9 @@ static lua_State *lua;
#if CURSES
static bool quitting;
#endif
-static bool initing, closing, show_tabs = true, tab_sync, dialog_active;
+static bool initing, closing, tab_sync, dialog_active;
+static int tabs = 1; // int for more options than true/false
+#define show_tabs(condition) tabs && (condition || tabs > 1)
enum {SVOID, SINT, SLEN, SINDEX, SCOLOR, SBOOL, SKEYMOD, SSTRING, SSTRINGRET};
// Forward declarations.
@@ -679,8 +681,8 @@ static void sync_tabbar() {
lua_pushdoc(lua, SS(focused_view, SCI_GETDOCPOINTER, 0, 0)),
lua_gettable(lua, -2), lua_tointeger(lua, -1) - 1);
lua_pop(lua, 2); // index and buffers
- GtkNotebook *tabs = GTK_NOTEBOOK(tabbar);
- tab_sync = true, gtk_notebook_set_current_page(tabs, i), tab_sync = false;
+ GtkNotebook *notebook = GTK_NOTEBOOK(tabbar);
+ tab_sync = true, gtk_notebook_set_current_page(notebook, i), tab_sync = false;
//#elif CURSES
// TODO: tabs
#endif
@@ -864,7 +866,7 @@ static int ui_index(lua_State *L) {
lua_pushinteger(L, width), lua_rawseti(L, -2, 1);
lua_pushinteger(L, height), lua_rawseti(L, -2, 2);
} else if (strcmp(key, "tabs") == 0)
- lua_pushboolean(L, show_tabs);
+ tabs <= 1 ? lua_pushboolean(L, tabs) : lua_pushinteger(L, tabs);
else
lua_rawget(L, 1);
return 1;
@@ -937,10 +939,10 @@ static int ui_newindex(lua_State *L) {
if (w > 0 && h > 0) gtk_window_resize(GTK_WINDOW(window), w, h);
#endif
} else if (strcmp(key, "tabs") == 0) {
- show_tabs = lua_toboolean(L, 3);
+ tabs = !lua_isinteger(L, 3) ? lua_toboolean(L, 3) : lua_tointeger(L, 3);
#if GTK
gtk_widget_set_visible(
- tabbar, show_tabs && gtk_notebook_get_n_pages(GTK_NOTEBOOK(tabbar)) > 1);
+ tabbar, show_tabs(gtk_notebook_get_n_pages(GTK_NOTEBOOK(tabbar)) > 1));
//#elif CURSES
// TODO: tabs
#endif
@@ -1059,7 +1061,7 @@ static void remove_doc(lua_State *L, sptr_t doc) {
#if GTK
// Remove the tab from the tabbar.
gtk_notebook_remove_page(GTK_NOTEBOOK(tabbar), i - 1);
- gtk_widget_set_visible(tabbar, show_tabs && lua_rawlen(L, -2) > 2);
+ gtk_widget_set_visible(tabbar, show_tabs(lua_rawlen(L, -2) > 2));
//#elif CURSES
// TODO: tabs
#endif
@@ -1225,10 +1227,10 @@ static void show_context_menu(lua_State *L, GdkEventButton *event, char *k) {
/** Signal for a tab label mouse click. */
static bool tab_clicked(GtkWidget *label, GdkEventButton *event, void *L) {
- GtkNotebook *tabs = GTK_NOTEBOOK(tabbar);
- for (int i = 0; i < gtk_notebook_get_n_pages(tabs); i++) {
- GtkWidget *page = gtk_notebook_get_nth_page(tabs, i);
- if (label != gtk_notebook_get_tab_label(tabs, page)) continue;
+ GtkNotebook *notebook = GTK_NOTEBOOK(tabbar);
+ for (int i = 0; i < gtk_notebook_get_n_pages(notebook); i++) {
+ GtkWidget *page = gtk_notebook_get_nth_page(notebook, i);
+ if (label != gtk_notebook_get_tab_label(notebook, page)) continue;
emit(
L, "tab_clicked", LUA_TNUMBER, i + 1, LUA_TNUMBER, event->button,
LUA_TBOOLEAN, event->state & GDK_SHIFT_MASK,
@@ -1426,7 +1428,7 @@ static void new_buffer(sptr_t doc) {
lua_getfield(lua, -1, "tab_pointer"), lua_touserdata(lua, -1));
tab_sync = true;
int i = gtk_notebook_append_page(GTK_NOTEBOOK(tabbar), tab, NULL);
- gtk_widget_show(tab), gtk_widget_set_visible(tabbar, show_tabs && i > 0);
+ gtk_widget_show(tab), gtk_widget_set_visible(tabbar, show_tabs(i > 0));
gtk_notebook_set_current_page(GTK_NOTEBOOK(tabbar), i);
tab_sync = false;
lua_pop(lua, 2); // tab_pointer and buffer
@@ -1611,7 +1613,7 @@ static bool init_lua(lua_State *L, int argc, char **argv, bool reinit) {
if (platform) lua_pushboolean(L, true), lua_setglobal(L, platform);
#if CURSES
lua_pushboolean(L, true), lua_setglobal(L, "CURSES");
- show_tabs = false; // TODO: tabs
+ show_tabs = 0; // TODO: tabs
#endif
const char *charset = NULL;
#if GTK