mutt_idna.c mutt_sasl.c mutt_socket.c mutt_ssl.c mutt_ssl_gnutls.c \
mutt_tunnel.c pgp.c pgpinvoke.c pgpkey.c pgplib.c pgpmicalg.c \
pgppacket.c pop.c pop_auth.c pop_lib.c remailer.c resize.c sha1.c \
- mutt-lua.c nntp.c newsrc.c \
+ mutt_lua.c nntp.c newsrc.c \
sidebar.c smime.c smtp.c utf8.c wcwidth.c \
bcache.h browser.h hcache.h mbyte.h mutt_idna.h remailer.h url.h
mutt_regex.h mutt_sasl.h mutt_sasl_plain.h mutt_socket.h mutt_ssl.h \
mutt_tunnel.h mx.h pager.h pgp.h pop.h protos.h rfc1524.h rfc2047.h \
rfc2231.h rfc822.h rfc3676.h sha1.h sort.h mime.types \
- mutt-lua.h nntp.h ChangeLog.nntp \
+ mutt_lua.h nntp.h ChangeLog.nntp \
_regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h \
mbyte.h lib.h extlib.c pgpewrap.c smime_keys.pl pgplib.h \
README.SSL README.md README.neomutt README.notmuch smime.h group.h \
AX_LUA_LIBS(:,enable_lua=no)
AS_IF([test x$enable_lua = "xyes"], [
- AC_DEFINE(USE_LUA, 1, [Define if you want support for LUA.])
- MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS mutt-lua.o"
- CPPFLAGS="$CPPFLAGS $LUA_INCLUDE"
- LIBS="$LIBS $LUA_LIB"
+ AC_DEFINE(USE_LUA, 1, [Define if you want support for LUA.])
+ MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS mutt_lua.o"
+ CPPFLAGS="$CPPFLAGS $LUA_INCLUDE"
+ LIBS="$LIBS $LUA_LIB"
])
AM_CONDITIONAL(BUILD_LUA, test x$enable_lua = xyes)
#include "nntp.h"
#endif
-#ifdef USE_LUA
-#include "mutt-lua.h"
-#endif
#include <ctype.h>
#include <stdlib.h>
case OP_SIDEBAR_TOGGLE_VIRTUAL:
mutt_sb_toggle_virtual();
break;
-#endif
-#ifdef USE_LUA
- case OP_LUA_RUN:
- lua_test();
- break;
#endif
default:
if (menu->menu == MENU_MAIN)
{ "limit-current-thread", OP_LIMIT_CURRENT_THREAD, NULL },
{ "link-threads", OP_MAIN_LINK_THREADS, "&" },
{ "list-reply", OP_LIST_REPLY, "L" },
-#ifdef USE_LUA
- { "lua-run", OP_LUA_RUN, NULL },
-#endif
{ "mail", OP_MAIL, "m" },
{ "toggle-new", OP_TOGGLE_NEW, "N" },
{ "toggle-write", OP_TOGGLE_WRITE, "%" },
#endif
WHERE char *Inbox;
WHERE char *Ispell;
-#ifdef USE_LUA
-WHERE char *LuaScript;
-#endif
WHERE char *MailcapPath;
WHERE char *Maildir;
#if defined(USE_IMAP) || defined(USE_POP) || defined(USE_NNTP)
# include "mx.h"
#endif
+#ifdef USE_LUA
+#include "mutt_lua.h"
+#endif
+
#include "buffy.h"
#ifndef _MAKEDOC
** ``$$keywords_standard'' are \fCfalse\fP, mutt will save keywords
** to legacy headers to ensure that it does not lose your labels.
*/
-#ifdef USE_LUA
- { "lua_script", DT_STR, R_NONE, UL &LuaScript, 0 },
- /*
- ** .pp
- ** External Lua script to run.
- */
-#endif
{ "mail_check", DT_NUM, R_NONE, UL &BuffyTimeout, 5 },
/*
** .pp
#endif
{ "ignore", parse_ignore, 0 },
{ "lists", parse_lists, 0 },
+#ifdef USE_LUA
+ { "lua", mutt_lua_parse, 0 },
+ { "lua-source", mutt_lua_source_file, 0 },
+#endif
{ "macro", mutt_parse_macro, 0 },
{ "mailboxes", mutt_parse_mailboxes, MUTT_MAILBOXES },
{ "unmailboxes", mutt_parse_mailboxes, MUTT_UNMAILBOXES },
+++ /dev/null
-/* Copyright (C) 2016 Richard Russon <rich@flatcap.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-#include "mutt.h"
-#include "globals.h"
-
-/* The function we'll call from the lua script */
-int
-average (lua_State *l)
-{
- /* get number of arguments */
- int n = lua_gettop (l);
- int sum = 0;
- int i;
-
- /* loop through each argument */
- for (i = 1; i <= n; i++)
- {
-#if LUA_VERSION_NUM >= 503
- if (!lua_isinteger (l, i))
- {
- lua_pushstring (l, "Incorrect argument to 'average'");
- lua_error (l);
- }
-#endif
-
- /* total the arguments */
- sum += lua_tointeger (l, i);
- }
-
- /* push the average */
- lua_pushinteger (l, sum / n);
-
- /* return the number of results */
- return 1;
-}
-
-int
-get_lua_integer (lua_State *l, const char *name)
-{
- if (!name)
- return -1;
-
- /* lookup the name and put it on the stack */
- lua_getglobal (l, name);
- if (!lua_isnumber (l, -1))
- return -1;
-
- int ret = lua_tonumber (l, -1);
- lua_pop (l, 1);
-
- return ret;
-}
-
-int
-lua_test (void)
-{
- lua_State *l;
-
- if (!LuaScript)
- return 0;
-
- /* initialise Lua */
- l = luaL_newstate();
- if (!l)
- return 0;
-
- /* load Lua base libraries */
- luaL_openlibs (l);
-
- /* register our function */
- lua_register (l, "average", average);
-
- /* set some default values */
- lua_pushinteger (l, 15); lua_setglobal (l, "apple");
- lua_pushinteger (l, 27); lua_setglobal (l, "banana");
- lua_pushinteger (l, 39); lua_setglobal (l, "cherry");
-
- if (luaL_dofile (l, LuaScript) == 0)
- {
- /* retrieve the values */
- mutt_message ("apple = %d", get_lua_integer (l, "apple")); mutt_sleep(1);
- mutt_message ("banana = %d", get_lua_integer (l, "banana")); mutt_sleep(1);
- mutt_message ("cherry = %d", get_lua_integer (l, "cherry")); mutt_sleep(1);
-
- /* one value on the stack */
- if (lua_gettop (l) == 1)
- {
- mutt_message ("lua returned: %lld", lua_tointeger (l, 1));
- }
- else
- {
- mutt_message ("lua returned");
- }
- }
- else
- {
- mutt_error ("error running lua script");
- }
-
- /* cleanup Lua */
- lua_close (l);
-
- return 1;
-}
-
--- /dev/null
+/* Copyright (C) 2016 Richard Russon <rich@flatcap.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include <stdbool.h>
+
+#include "mutt.h"
+#include "globals.h"
+
+lua_State *Lua = NULL;
+
+static int _lua_mutt_message(lua_State *l) {
+ mutt_debug(2, "—→ _lua_mutt_message()\n");
+ const char *msg = lua_tostring(l, -1);
+ if (msg != NULL)
+ mutt_message(msg);
+ return 0;
+}
+
+static int _lua_mutt_error(lua_State *l) {
+ mutt_debug(2, "—→ _lua_mutt_error()\n");
+ const char *msg = lua_tostring(l, -1);
+ if (msg != NULL)
+ mutt_error(msg);
+ return 0;
+}
+
+static int _lua_mutt_error_handler(lua_State *l)
+{
+ mutt_error("Oops...");
+ return 0;
+}
+
+
+static const luaL_Reg luaMuttDecl[] =
+{
+ { "message", _lua_mutt_message },
+ { "error", _lua_mutt_error },
+ { NULL, NULL }
+};
+
+
+static int luaopen_mutt_decl(lua_State *l)
+{
+ mutt_debug(2, "—→ luaopen_mutt()\n");
+ luaL_newlib(l, luaMuttDecl);
+ return 1;
+}
+#define luaopen_mutt(L) do { luaL_requiref(L, "mutt", luaopen_mutt_decl, 1); } while (0);
+
+static bool _lua_init(void)
+{
+ if (Lua == NULL) {
+ mutt_debug(2, "—→ lua_init()\n");
+ Lua = luaL_newstate();
+
+ if (Lua == NULL) {
+ mutt_error("Error: Couldn't load the lua interpreter.");
+ return false;
+ }
+
+ lua_atpanic (Lua, _lua_mutt_error_handler);
+
+ /* load various Lua libraries */
+ luaL_openlibs(Lua);
+ luaopen_mutt(Lua);
+ }
+
+ return true;
+}
+
+// static void _lua_close(void)
+// {
+// printf("—→ lua_close()");
+// lua_close(Lua);
+// }
+
+int mutt_lua_parse (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
+{
+ int error;
+ _lua_init();
+ mutt_debug(2, "—→ mutt_lua_parse(%s)\n", tmp->data);
+ // printf("—→ mutt_lua_parse(%s)\n", s->dptr);
+
+ if ((error = luaL_dostring(Lua, s->dptr))) {
+ mutt_debug(2, "—→ mutt_lua_parse(%s) → failure\n", s->dptr);
+ // printf("—→ mutt_lua_parse(%s) → failure\n", s->dptr);
+ mutt_error("Lua error: %s\n", lua_tostring(Lua, -1));
+ lua_pop(Lua, 1);
+/* pop error message from the stack */
+ return -1;
+ }
+ mutt_debug(2, "—→ mutt_lua_parse(%s) → success\n", s->dptr);
+ // printf("—→ mutt_lua_parse(%s) → success\n", tmp->data);
+ return 1;
+}
+
+int mutt_lua_source_file (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
+{
+ mutt_debug(2, "—→ mutt_lua_source()\n");
+
+ _lua_init();
+
+ char path[_POSIX_PATH_MAX];
+
+ if (mutt_extract_token (tmp, s, 0) != 0)
+ {
+ snprintf (err->data, err->dsize, _("source: error at %s"), s->dptr);
+ return (-1);
+ }
+ if (MoreArgs (s))
+ {
+ strfcpy (err->data, _("source: too many arguments"), err->dsize);
+ return (-1);
+ }
+ strfcpy (path, tmp->data, sizeof (path));
+ mutt_expand_path (path, sizeof (path));
+
+ if (luaL_dofile(Lua, path)) {
+ mutt_error("Couldn't source lua source: %s", lua_tostring(Lua, -1));
+ lua_pop(Lua, 1);
+ return -1;
+ }
+ return 1;
+}
+
+/* The function we'll call from the lua script */
+int average (lua_State *l)
+{
+ /* get number of arguments */
+ int n = lua_gettop (l);
+ int sum = 0;
+ int i;
+
+ /* loop through each argument */
+ for (i = 1; i <= n; i++)
+ {
+#if LUA_VERSION_NUM >= 503
+ if (!lua_isinteger (l, i))
+ {
+ lua_pushstring (l, "Incorrect argument to 'average'");
+ lua_error (l);
+ }
+#endif
+
+ /* total the arguments */
+ sum += lua_tointeger (l, i);
+ }
+
+ /* push the average */
+ lua_pushinteger (l, sum / n);
+
+ /* return the number of results */
+ return 1;
+}
+
+int get_lua_integer (lua_State *l, const char *name)
+{
+ if (!name)
+ return -1;
+
+ /* lookup the name and put it on the stack */
+ lua_getglobal (l, name);
+ if (!lua_isnumber (l, -1))
+ return -1;
+
+ int ret = lua_tonumber (l, -1);
+ lua_pop (l, 1);
+
+ return ret;
+}
+
+// int lua_test (void)
+// {
+// if (!LuaScript)
+// return 0;
+
+// /* initialise Lua */
+// l = luaL_newstate();
+// if (!l)
+// return 0;
+
+// /* load Lua base libraries */
+// luaL_openlibs (l);
+
+// /* register our function */
+// lua_register (l, "average", average);
+
+// /* set some default values */
+// lua_pushinteger (l, 15); lua_setglobal (l, "apple");
+// lua_pushinteger (l, 27); lua_setglobal (l, "banana");
+// lua_pushinteger (l, 39); lua_setglobal (l, "cherry");
+
+// if (luaL_dofile (l, LuaScript) == 0)
+// {
+// /* retrieve the values */
+// mutt_message ("apple = %d", get_lua_integer (l, "apple")); mutt_sleep(1);
+// mutt_message ("banana = %d", get_lua_integer (l, "banana")); mutt_sleep(1);
+// mutt_message ("cherry = %d", get_lua_integer (l, "cherry")); mutt_sleep(1);
+
+// /* one value on the stack */
+// if (lua_gettop (l) == 1)
+// {
+// mutt_message ("lua returned: %lld", lua_tointeger (l, 1));
+// }
+// else
+// {
+// mutt_message ("lua returned");
+// }
+// }
+// else
+// {
+// mutt_error ("error running lua script");
+// }
+
+// /* cleanup Lua */
+// lua_close (l);
+
+// return 1;
+// }
+
#ifndef _MUTT_LUA_H_
#define _MUTT_LUA_H_
-int lua_test (void);
+#include "mutt.h"
+
+int mutt_lua_parse (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err);
+int mutt_lua_source_file (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err);
#endif /* _MUTT_LUA_H_ */