stylish updates.
[apps/madmutt.git] / lib-lua / madmutt.c
index d4f55a3..6fe2b4d 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "../mutt.h"
 
+/* {{{ madmutt functions */
+
 static int madmutt_pwd(lua_State *L)
 {
     char path[_POSIX_PATH_MAX];
@@ -56,49 +58,113 @@ static int madmutt_folder_name(lua_State *L)
     return 1;
 }
 
+static quadopt_t quadopt_parse(const char *s)
+{
+    if (!m_strcasecmp("yes", s))
+        return M_YES;
+    if (!m_strcasecmp("no", s))
+        return M_NO;
+    if (!m_strcasecmp("ask-yes", s))
+        return M_ASKYES;
+    if (!m_strcasecmp("ask-no", s))
+        return M_ASKNO;
+    return -1;
+}
+
 static int madmutt_assign(lua_State *L)
 {
     const char *idx = luaL_checkstring(L, 2);
     const char *val = luaL_checkstring(L, 3);
-    char buf[STRING];
+    int tk;
 
-    switch (lua_which_token(idx, -1)) {
-      default:
-        luaL_error(L, "bad subscript to madmutt: %s", val);
-        return 0;
+    switch ((tk = lua_which_token(idx, -1))) {
+        char buf[STRING];
+        int i;
 
       case LTK_DOTLOCK:
       case LTK_SENDMAIL:
       case LTK_SHELL:
+      case LTK_EDITOR:
         _mutt_expand_path(buf, sizeof(buf), val, 0);
         val = buf;
+        /* FALLTHROUGH */
+
+        mlua_regsets(tk, val);
+        return 0;
+
+      case LTK_QUIT:
+        i = quadopt_parse(val);
+        if (i < 0)
+            return luaL_error(L, "invalid quad option value: '%s'", val);
+        mlua_regseti(tk, i);
+        return 0;
+
+      case LTK_UNKNOWN:
+      case LTK_count:
         break;
     }
 
-    lua_getmetatable(L, 1);
-    lua_pushstring(L, idx);
-    lua_pushstring(L, val);
-    lua_rawset(L, -3);
+    return luaL_error(L, "read-only or inexistant property '%s'", idx, tk);
+}
 
-    return 0;
+static int madmutt_get(lua_State *L)
+{
+    const char *idx = luaL_checkstring(L, 2);
+    enum lua_token tk = lua_which_token(idx, -1);
+
+    switch (tk) {
+      case LTK_DOTLOCK:
+      case LTK_SENDMAIL:
+      case LTK_SHELL:
+      case LTK_EDITOR:
+        lua_pushstring(L, mlua_reggets(tk));
+        return 1;
+
+      case LTK_QUIT:
+        switch (mlua_reggeti(tk)) {
+          case M_YES:
+            lua_pushstring(L, "yes");
+            return 1;
+          case M_NO:
+            lua_pushstring(L, "no");
+            return 1;
+          case M_ASKNO:
+            lua_pushstring(L, "ask-no");
+            return 1;
+          case M_ASKYES:
+            lua_pushstring(L, "ask-yes");
+            return 1;
+          default:
+            return 0;
+        }
+
+      case LTK_UNKNOWN:
+      case LTK_count:
+        break;
+    }
+
+    lua_getmetatable(L, 1);
+    lua_replace(L, 1);
+    lua_rawget(L, 1);
+    return 1;
 }
 
 static const struct luaL_Reg madmutt_module_funcs[] = {
-    {"pwd",         madmutt_pwd},
+    { "pwd",         madmutt_pwd },
     /*
      ** .pp
      ** \fIThis is a read-only system property and, at runtime,
      ** specifies the current working directory of the madmutt
      ** binary.\fP
      */
-    {"folder_path", madmutt_folder_path},
+    { "folder_path", madmutt_folder_path },
     /*
      ** .pp
      ** \fIThis is a read-only system property and, at runtime,
      ** specifies the full path or URI of the folder currently
      ** open (if any).\fP
      */
-    {"folder_name", madmutt_folder_name},
+    { "folder_name", madmutt_folder_name },
     /*
      ** .pp
      ** \fIThis is a read-only system property and, at runtime,
@@ -118,10 +184,15 @@ static const struct luaL_Reg madmutt_module_funcs[] = {
      ** $$$folder nor a ``/'' were found in the name.
      */
 
-    {"__newindex",  madmutt_assign},
-    {NULL, NULL}
+    { "__newindex",  madmutt_assign },
+    { "__index",     madmutt_get },
+    { NULL, NULL }
 };
 
+/* }}} */
+
+/* {{{ read-only properties */
+
 static const struct {
     const char *key;
     const char *value;
@@ -166,22 +237,17 @@ static const struct {
      ** header chaching's database backend.\fP
      */
 #endif
-
-    {"dotlock",     "/mutt_dotlock"},
-    /*
-     ** .pp
-     ** Contains the path of the \fTmadmutt_dotlock(1)\fP binary to be used by
-     ** Madmutt.
-     */
-    {"sendmail",    SENDMAIL " -oem -oi"},
-    /*
-     ** .pp
-     ** Specifies the program and arguments used to deliver mail sent by Madmutt.
-     ** Madmutt expects that the specified program interprets additional
-     ** arguments as recipient addresses.
-     */
 };
 
+/* }}} */
+
+/* {{{ madmutt magic properties */
+
+static void madmutt_init_editor(char *buf, ssize_t len)
+{
+    m_strcpy(buf, len, getenv("VISUAL") ?: getenv("EDITOR") ?: "vi");
+}
+
 static void madmutt_init_shell(char *buf, ssize_t len)
 {
     struct passwd *pw = getpwuid(getuid());
@@ -197,15 +263,46 @@ static void madmutt_init_shell(char *buf, ssize_t len)
 static const struct {
     const char *key;
     void (*fun)(char *buf, ssize_t len);
+    const char *val;
 } madmutt_module_vars2[] = {
-    { "shell",          madmutt_init_shell },
+    { "dotlock",     NULL, BINDIR "/mutt_dotlock" },
+    /*
+     ** .pp
+     ** Contains the path of the \fTmadmutt_dotlock(1)\fP binary to be used by
+     ** Madmutt.
+     */
+    { "editor",       madmutt_init_editor, NULL },
+    /*
+     ** .pp
+     ** This variable specifies which editor is used by Madmutt.
+     ** It defaults to the value of the \fT$$$VISUAL\fP, or \fT$$$EDITOR\fP, environment
+     ** variable, or to the string "\fTvi\fP" if neither of those are set.
+     */
+    { "sendmail",    NULL, SENDMAIL " -oem -oi" },
+    /*
+     ** .pp
+     ** Specifies the program and arguments used to deliver mail sent by Madmutt.
+     ** Madmutt expects that the specified program interprets additional
+     ** arguments as recipient addresses.
+     */
+    { "shell",       madmutt_init_shell, NULL },
     /*
      ** .pp
      ** Command to use when spawning a subshell.  By default, the user's login
      ** shell from \fT/etc/passwd\fP is used.
      */
+    { "quit",         NULL, "yes" },
+    /*
+     ** .pp
+     ** This variable controls whether ``quit'' and ``exit'' actually quit
+     ** from Madmutt.  If it set to \fIyes\fP, they do quit, if it is set to \fIno\fP, they
+     ** have no effect, and if it is set to \fIask-yes\fP or \fIask-no\fP, you are
+     ** prompted for confirmation when you try to quit.
+     */
 };
 
+/* }}} */
+
 int luaopen_madmutt(lua_State *L)
 {
     int i;
@@ -220,19 +317,19 @@ int luaopen_madmutt(lua_State *L)
         lua_setfield(L, -2, madmutt_module_vars[i].key);
     }
 
+    lua_setmetatable(L, -2);
+
     for (i = 0; i < countof(madmutt_module_vars2); i++) {
-        char buf[STRING];
-        (madmutt_module_vars2[i].fun)(buf, sizeof(buf));
-        lua_pushstring(L, buf);
+        if (madmutt_module_vars2[i].fun) {
+            char buf[STRING];
+            (madmutt_module_vars2[i].fun)(buf, sizeof(buf));
+            lua_pushstring(L, buf);
+        } else {
+            lua_pushstring(L, madmutt_module_vars2[i].val);
+        }
         lua_setfield(L, -2, madmutt_module_vars2[i].key);
     }
 
-    lua_pushstring(L, "__index");
-    lua_pushvalue(L, -2);
-    lua_settable(L, -3);
-
-    lua_setmetatable(L, -2);
     lua_setglobal(L, "madmutt");
-
     return 1;
 }