NeoMutt  2025-12-11-435-g4ac674
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 struct Buffer *token = buf_pool_get();
70
72
74 mutt_debug(LL_DEBUG2, "%s\n", buf_string(token));
75
76 if (luaL_dostring(LuaState, buf_string(token)) != LUA_OK)
77 {
78 mutt_debug(LL_DEBUG2, "%s -> failure\n", buf_string(token));
79 buf_printf(err, "%s: %s", buf_string(token), lua_tostring(LuaState, -1));
80 /* pop error message from the stack */
81 lua_pop(LuaState, 1);
82 goto done;
83 }
84 mutt_debug(LL_DEBUG2, "%s -> success\n", buf_string(token));
85 buf_reset(line); // Clear the rest of the line
86
88
89done:
90 buf_pool_release(&token);
91 return rc;
92}
93
100enum CommandResult parse_lua_source(const struct Command *cmd, struct Buffer *line,
101 const struct ParseContext *pc, struct ParseError *pe)
102{
103 struct Buffer *err = pe->message;
104
105 if (!MoreArgs(line))
106 {
107 buf_printf(err, _("%s: too few arguments"), cmd->name);
108 return MUTT_CMD_WARNING;
109 }
110
111 struct Buffer *token = buf_pool_get();
113
114 mutt_debug(LL_DEBUG2, "enter\n");
115
117
118 if (parse_extract_token(token, line, TOKEN_NO_FLAGS) != 0)
119 {
120 buf_printf(err, _("source: error at %s"), line->dptr);
121 goto done;
122 }
123 if (MoreArgs(line))
124 {
125 buf_printf(err, _("%s: too many arguments"), cmd->name);
126 rc = MUTT_CMD_WARNING;
127 goto done;
128 }
129
130 expand_path(token, false);
131
132 if (luaL_dofile(LuaState, buf_string(token)) != LUA_OK)
133 {
134 mutt_error(_("Couldn't source lua source: %s"), lua_tostring(LuaState, -1));
135 lua_pop(LuaState, 1);
136 goto done;
137 }
138
139 rc = MUTT_CMD_SUCCESS;
140
141done:
142 buf_pool_release(&token);
143 return rc;
144}
145
149const struct Command LuaCommands[] = {
150 // clang-format off
151 { "lua", CMD_LUA, parse_lua,
152 N_("Run a Lua expression or call a Lua function"),
153 N_("lua <lua-command>"),
154 "optionalfeatures.html#lua" },
155 { "lua-source", CMD_LUA_SOURCE, parse_lua_source,
156 N_("Execute a Lua script file"),
157 N_("lua-source <filename>"),
158 "optionalfeatures.html#lua" },
159
160 { NULL, CMD_NONE, NULL, NULL, NULL, NULL, CF_NO_FLAGS },
161 // clang-format on
162};
163
167void lua_cleanup(void)
168{
169 if (LuaState)
170 {
171 lua_close(LuaState);
172 LuaState = NULL;
173 }
174}
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:100
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:440
lua_State * LuaState
Global Lua State.
Definition lua.c:56
void lua_cleanup(void)
Clean up Lua.
Definition commands.c:167
const struct Command LuaCommands[]
List of NeoMutt commands to register.
Definition commands.c:149
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:121
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