--- a/main.c Sun Mar 01 18:35:43 2009 +0200
+++ b/main.c Tue Mar 03 23:15:04 2009 +0200
@@ -127,33 +127,132 @@
return 0;
}
+// expects table on top
+static void lua_options_callback (char *key, char *value, lua_State *L)
+{
+ char *loc = from_utf8 (key);
+ lua_pushstring (L, loc);
+ g_free (loc);
+ loc = from_utf8 (value);
+ lua_pushstring (L, loc);
+ g_free (loc);
+ lua_settable (L, -3);
+}
+
/// main.option
/// Sets or gets value of mcabber option.
/// You can specify nil as a value to delete option.
-/// XXX: Should we do types here?
-/// A: string (option name), string (value, optional)
+/// If you omit option name, it returns hash table of all options.
+/// A: string (option name, optional), string (value, optional)
/// R: string (value, optional)
static int lua_main_option (lua_State *L)
{
- char *name = to_utf8 (luaL_checkstring (L, 1));
- if (lua_gettop (L) > 1) { // Set
- if (lua_type (L, 2) == LUA_TNIL) // Unset
- settings_del (SETTINGS_TYPE_OPTION, name);
- else { // Set
- char *value = to_utf8 (luaL_checkstring (L, 2));
- settings_set (SETTINGS_TYPE_OPTION, name, value);
- g_free (value);
+ int top = lua_gettop (L);
+ if (top > 0) {
+ char *name = to_utf8 (luaL_checkstring (L, 1));
+ if (top > 1) { // Set
+ if (lua_type (L, 2) == LUA_TNIL) // Unset
+ settings_del (SETTINGS_TYPE_OPTION, name);
+ else { // Set
+ char *value = to_utf8 (luaL_checkstring (L, 2));
+ settings_set (SETTINGS_TYPE_OPTION, name, value);
+ g_free (value);
+ }
+ g_free (name);
+ return 0;
+ } else { // Get
+ char *value = from_utf8 (settings_get (SETTINGS_TYPE_OPTION, name));
+ if (value) {
+ lua_pushstring (L, value);
+ g_free (value);
+ } else
+ lua_pushnil (L);
+ g_free (name);
+ return 1;
}
- g_free (name);
- return 0;
- } else { // Get
- char *value = from_utf8 (settings_get (SETTINGS_TYPE_OPTION, name));
- if (value) {
- lua_pushstring (L, value);
- g_free (value);
- } else
- lua_pushnil (L);
- g_free (name);
+ } else { // List
+ lua_newtable (L);
+ settings_foreach (SETTINGS_TYPE_OPTION, (void (*)(char *key, char *val, void *ud)) lua_options_callback, L);
+ return 1;
+ }
+}
+
+/// main.alias
+/// Sets or gets alias.
+/// You can specify nil as a command to delete alias.
+/// If you omit alias name, it will return hash table of all aliases.
+/// A: string (alias name, optional), string (command, optional)
+/// R: string (command, optional)
+static int lua_main_alias (lua_State *L)
+{
+ int top = lua_gettop (L);
+ if (top > 0) {
+ char *name = to_utf8 (luaL_checkstring (L, 1));
+ if (top > 1) { // Set
+ if (lua_type (L, 2) == LUA_TNIL) { // Unset
+ settings_del (SETTINGS_TYPE_ALIAS, name);
+ compl_del_category_word (COMPL_CMD, name);
+ } else { // Set
+ char *value = to_utf8 (luaL_checkstring (L, 2));
+ if (!settings_get (SETTINGS_TYPE_ALIAS, name))
+ compl_add_category_word (COMPL_CMD, name);
+ settings_set (SETTINGS_TYPE_ALIAS, name, value);
+ g_free (value);
+ }
+ g_free (name);
+ return 0;
+ } else { // Get
+ char *value = from_utf8 (settings_get (SETTINGS_TYPE_ALIAS, name));
+ if (value) {
+ lua_pushstring (L, value);
+ g_free (value);
+ } else
+ lua_pushnil (L);
+ g_free (name);
+ return 1;
+ }
+ } else { // List
+ lua_newtable (L);
+ settings_foreach (SETTINGS_TYPE_ALIAS, (void (*)(char *key, char *val, void *ud)) lua_options_callback, L);
+ return 1;
+ }
+}
+
+/// main.bind
+/// Sets or gets alias.
+/// You can specify nil as a command to unbind key.
+/// If you omit keycode, it will return hash table of all bindings.
+/// A: string (keycode, optional), string (command, optional)
+/// R: string (command, optional)
+static int lua_main_alias (lua_State *L)
+{
+ int top = lua_gettop (L);
+ if (top > 0) {
+ // just to be sure...
+ char *name = to_utf8 (luaL_checkstring (L, 1));
+ if (top > 1) { // Set
+ if (lua_type (L, 2) == LUA_TNIL) // Unset
+ settings_del (SETTINGS_TYPE_BINDING, name);
+ else { // Set
+ char *value = to_utf8 (luaL_checkstring (L, 2));
+ settings_set (SETTINGS_TYPE_BINDING, name, value);
+ g_free (value);
+ }
+ g_free (name);
+ return 0;
+ } else { // Get
+ char *value = from_utf8 (settings_get (SETTINGS_TYPE_BINDING, name));
+ if (value) {
+ lua_pushstring (L, value);
+ g_free (value);
+ } else
+ lua_pushnil (L);
+ g_free (name);
+ return 1;
+ }
+ } else { // List
+ lua_newtable (L);
+ settings_foreach (SETTINGS_TYPE_BINDING, (void (*)(char *key, char *val, void *ud)) lua_options_callback, L);
return 1;
}
}
@@ -430,6 +529,8 @@
static GSList *lua_added_commands = NULL;
+static GSList *lua_added_categories = NULL;
+
/// command function
/// Function to handle newly registered command.
/// A: string (arguments)
@@ -443,6 +544,48 @@
}
}
+/// main.add_category
+/// Adds completion category.
+/// A: table (values are used as words for completion, optional)
+/// R: integer (category id, in fact completion type) or nil
+static int lua_main_add_category (lua_State *L)
+{
+ guint cid;
+ if (lua_gettop (L) > 0)
+ luaL_argcheck (L, lua_type (L, 1) == LUA_TTABLE, 1, "table expected");
+ cid = compl_new_category ();
+ if (cid) {
+ lua_pushnil (L);
+ while (lua_next (L, 3)) {
+ char *word = to_utf8 (luaL_checkstring (L, -1));
+ if (word) {
+ compl_add_category_word (cid, word);
+ g_free (word);
+ }
+ lua_pop (L, 1);
+ }
+ }
+ } else
+ cid = compl_new_category ();
+ if (cid) {
+ lua_added_categories = g_slist_prepend (lua_added_categories, (gpoiner) cid);
+ lua_pushinteger (L, cid);
+ } else
+ lua_pushnil (L);
+ return 1;
+}
+
+/// main.del_category
+/// Removes completion category.
+/// A: integer (category id)
+static int lua_main_del_category (lua_State *L)
+{
+ guint cid = luaL_checkinteger (L, 1);
+ compl_del_category (cid);
+ lua_added_categories = g_slist_remove (lua_added_categories, (gpointer) cid);
+ return 0;
+}
+
/// main.add_completion
/// Adds word to a completion list.
/// A: integer (completion group id), string (word)
@@ -486,6 +629,7 @@
if (lua_type (L, 3) == LUA_TTABLE) {
cid = compl_new_category ();
if (cid) {
+ lua_added_categories = g_slist_prepend (lua_added_categories, (gpoiner) cid);
lua_pushnil (L);
while (lua_next (L, 3)) {
char *word = to_utf8 (luaL_checkstring (L, -1));
@@ -746,8 +890,12 @@
reg ( connection )
reg ( log )
reg ( option )
+ reg ( alias )
+ reg ( binding )
reg ( add_feature )
reg ( del_feature )
+ reg ( add_category )
+ reg ( del_category )
reg ( add_completion )
reg ( del_completion )
reg ( command )
@@ -836,6 +984,11 @@
g_free (name);
}
+static void lua_categories_destroy (guint id, gpointer ignore)
+{
+ compl_del_category (id);
+}
+
void g_module_unload (GModule *module)
{
if (lua) {
@@ -855,6 +1008,10 @@
g_slist_free (lua_added_commands);
lua_added_commands = NULL;
+ g_slist_foreach (lua_added_categories, (GFunc) lua_categories_destroy, NULL);
+ g_slist_free (lua_added_categories);
+ lua_added_categories = NULL;
+
cmd_del ("lua");
lua_close (lua);