NeoMutt  2025-12-11-694-ga89709
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
commands.c
Go to the documentation of this file.
1
22
28
29#ifndef LUA_COMPAT_ALL
30#define LUA_COMPAT_ALL
31#endif
32#ifndef LUA_COMPAT_5_1
33#define LUA_COMPAT_5_1
34#endif
35
36#include "config.h"
37#include <lauxlib.h>
38#include <lua.h>
39#include <stdbool.h>
40#include <stdio.h>
41#include "mutt/lib.h"
42#include "core/lib.h"
43#include "lib.h"
44#include "parse/lib.h"
45#include "muttlib.h"
46
47extern lua_State *LuaState;
48
49bool lua_init_state(lua_State **l);
50
57enum CommandResult parse_lua(const struct Command *cmd, struct Buffer *line,
58 const struct ParseContext *pc, struct ParseError *pe)
59{
60 struct Buffer *err = pe->message;
61
62 if (!MoreArgs(line))
63 {
64 buf_printf(err, _("%s: too few arguments"), cmd->name);
65 return MUTT_CMD_WARNING;
66 }
67
68 // From here on, use the remainder of `line`, raw
70
72 mutt_debug(LL_DEBUG2, "%s\n", line->dptr);
73
74 if (luaL_dostring(LuaState, line->dptr) != LUA_OK)
75 {
76 mutt_debug(LL_DEBUG2, "%s -> failure\n", line->dptr);
77 buf_printf(err, "%s: %s", line->dptr, lua_tostring(LuaState, -1));
78 /* pop error message from the stack */
79 lua_pop(LuaState, 1);
80 goto done;
81 }
82 mutt_debug(LL_DEBUG2, "%s -> success\n", line->dptr);
83 buf_reset(line); // Clear the rest of the line
84
86
87done:
88 return rc;
89}
90
97enum CommandResult parse_lua_source(const struct Command *cmd, struct Buffer *line,
98 const struct ParseContext *pc, struct ParseError *pe)
99{
100 struct Buffer *err = pe->message;
101
102 if (!MoreArgs(line))
103 {
104 buf_printf(err, _("%s: too few arguments"), cmd->name);
105 return MUTT_CMD_WARNING;
106 }
107
108 struct Buffer *token = buf_pool_get();
110
111 mutt_debug(LL_DEBUG2, "enter\n");
112
114
115 if (parse_extract_token(token, line, TOKEN_NO_FLAGS) != 0)
116 {
117 buf_printf(err, _("source: error at %s"), line->dptr);
118 goto done;
119 }
120 if (MoreArgs(line))
121 {
122 buf_printf(err, _("%s: too many arguments"), cmd->name);
123 rc = MUTT_CMD_WARNING;
124 goto done;
125 }
126
127 expand_path(token, false);
128
129 if (luaL_dofile(LuaState, buf_string(token)) != LUA_OK)
130 {
131 mutt_error(_("Couldn't source lua source: %s"), lua_tostring(LuaState, -1));
132 lua_pop(LuaState, 1);
133 goto done;
134 }
135
136 rc = MUTT_CMD_SUCCESS;
137
138done:
139 buf_pool_release(&token);
140 return rc;
141}
142
146const struct Command LuaCommands[] = {
147 // clang-format off
148 { "lua", CMD_LUA, parse_lua,
149 N_("Run a Lua expression or call a Lua function"),
150 N_("lua <lua-command>"),
151 "optionalfeatures.html#lua" },
152 { "lua-source", CMD_LUA_SOURCE, parse_lua_source,
153 N_("Execute a Lua script file"),
154 N_("lua-source <filename>"),
155 "optionalfeatures.html#lua" },
156
157 { NULL, CMD_NONE, NULL, NULL, NULL, NULL, CF_NO_FLAGS },
158 // clang-format on
159};
160
164void lua_cleanup(void)
165{
166 if (LuaState)
167 {
168 lua_close(LuaState);
169 LuaState = NULL;
170 }
171}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
#define CF_NO_FLAGS
No flags are set.
Definition command.h:48
@ CMD_LUA_SOURCE
:lua-source
Definition command.h:89
@ CMD_LUA
:lua
Definition command.h:88
@ CMD_NONE
No Command.
Definition command.h:59
CommandResult
Error codes for command_t parse functions.
Definition command.h:37
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:40
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:38
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition command.h:39
Convenience wrapper for the core headers.
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:49
#define MoreArgs(buf)
Definition extract.h:31
#define TOKEN_NO_FLAGS
No flags are set.
Definition extract.h:45
enum CommandResult parse_lua_source(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'lua-source' command - Implements Command::parse() -.
Definition commands.c:97
enum CommandResult parse_lua(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'lua' command - Implements Command::parse() -.
Definition commands.c:57
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:46
bool lua_init_state(lua_State **l)
Initialise a Lua State.
Definition lua.c:446
lua_State * LuaState
Global Lua State.
Definition lua.c:56
void lua_cleanup(void)
Clean up Lua.
Definition commands.c:164
const struct Command LuaCommands[]
List of NeoMutt commands to register.
Definition commands.c:146
Integrated Lua scripting.
Convenience wrapper for the library headers.
#define N_(a)
Definition message.h:32
#define _(a)
Definition message.h:28
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
Some miscellaneous functions.
Text parsing functions.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
char * dptr
Current read/write position.
Definition buffer.h:38
const char * name
Name of the Command.
Definition command.h:159
Context for config parsing (history/backtrace)
Definition pcontext.h:34
Detailed error information from config parsing.
Definition perror.h:34
struct Buffer * message
Error message.
Definition perror.h:35