New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve support of a scripting language #153
Comments
It's a simple language to understand. By contrast, Perl required me to define interfaces and create wrappers.
It's a programming language like all the others: variables, loops, etc.
To be useful for scripting, I decided I needed to be able to:
The last item makes the scripting really useful. |
@flatcap Yeah, I notice Lua have the speed (almost comparable with C/C++), not sure why everyone choose python. (I use python here but really hoping to use Lua) python seems nice as most systems have it by default but I hate having 2 different versions of python with their respectives libraries which wasted me around 200MB each. Not sure about ruby and perl, from what I know, I think they are mostly used to do something related to text and strings. Fun fact: Neovim port most of the vim scripts to lua https://github.com/neovim/neovim/wiki/FAQ#design |
This is a list of everything I could think to script. GeneralAll scripts would be passed:
Have access to functions:
ConfigAllow script to be embedded in normal Mutt config files, e.g. like PHP: Pass in:
<?lua
if (MUTT_VERSION > "20160916") then
mutt_config("set sidebar_visible")
end
?> Lua's print() function could be overridden to call mutt_message() IndexA one-pass processing of the mailbox. Add new expandos, %L1, %L2, etc to be filled by the script. Pass in:
Define functions to:
Can optionally disable Mutt's colouring PagerA one-pass processing of an email. Define functions to:
‡ Actions are non-destructive SidebarSidebar mailbox entries
‡ Actions are non-destructive e.g.
HooksThese hooks might be useful to override with a script:
Most useful, would be a new-mail-hook. Pass it:
Allow it a small set of functions:
Status BarGenerate: $status_format, $ts_status_format Pass info about current:
Testing frameworkNeed to expose:
Be able to:
Automation:
Create a test rig, built from Mutt code, that takes a mailbox and a script.
|
About the lua integration in the config files, I'd rather prefer to follow vim/neovim's way of adding a mutt command:
that would work on a single environment, so that:
then we could extend using the following UNIX standard syntax pretty easily:
because mutt config is not a tag based language, I'd rather see the above syntax instead of suggested:
|
I have had a little thought on lua integration, and I've read a bit on the neovim approach. New mutt commands
eventually make it possible to introduce a new syntax in neomutt to parse multiline lua scripts inline of an rc file:
APIAs a start we could consider having only a couple of APIs
to make it possible to run context-aware commands, extending the API to support arguments and prevent any interactive enquiring will be necessary, cf #294. Keep the API close to the C code
eventually turn it into a nicer lua API using lua itselfwe could then have some code to expose a nice OO-like approach to the API using a Something in the idea of lua-client Add the ability to create new commands and hooksFinally, the toughest part will be to have mutt integrate lua code from mutt, by adding the ability to register new:
|
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
I have implemented the first step in this branch:
as a next step exposing existing |
This is the branch: https://github.com/guyzmo/neomutt/tree/feature/lua-scripting, not the one in the neomutt organization. I tested this and got I also tested the lua-source with this script:
And mutt entered pager mode, even though the terminal borked and I had to |
Oops, my bad, it's Here's a few examples:
Basically if you set in your muttrc:
error messages will be in red, and the others in cyan. |
just added the
😎 |
I can confirm this, it works! |
updates to the API: former
and new
but it is also exposed as straight lua methods:
the set API now supports all internal types, cf this gist:
and it will throw exceptions at you if you do it wrong! |
Added support for
|
Added It's exiting before the part sending mails in |
I'm pretty much done with the first part of the implementation. Please review the code, test the features, break it, and come back commenting and cristicising it! 🤗 |
So, I spent the afternoon playing around with this. Once we can integrate hooks into executing LUA code, the sky is the limit! Some context first. I use mutt with various accounts, so instead of manually managing the "mailboxes" for new accounts, I put them in a hierarchy and wrote a Python script to create the mailboxes command for me. It's ugly, but it works for my setup. Here's the hierarchy
This lets me call my mutt wrapper The Python script receives a profile and creates the mutt "mailboxes" command. Here it is: https://gist.github.com/somini/84c5d624d0f14784e60da3817530ab48 I converted it to LUA (minus some improvements) and it works perfectly. Since I use the mutt bindings, it can be much improved and doesn't suffer from string escaping bugs. Here: https://gist.github.com/somini/c13f73d60d3a550ffa69314048daa2ec |
I do have a bug report, if I set |
The options in |
Regarding the PR from @guyzmo : in general nice work :) I don't use mutt much, but i think it would provide some great readability advantages when we can replace our conditional features with lua. What do you think about that? |
@somini indeed, the |
@toogley yes, I believe that the |
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf #153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: #153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf #153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: #153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: #153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: #153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adds the following to Mutt's API: * `:lua` to execute a line of Lua * `:lua-source` to load and run a Lua source file * exposes the following Mutt API in Lua: * `mutt.message()` To write a message on Mutt's command line * `mutt.error()` To write an error message on Mutt's command line * `mutt.enter()` run an arbitrary Mutt command, like with `:enter-command` * `mutt.get()` get a variable from Mutt * `mutt.set()` sets a variable from Mutt (with type enforcement) * `mutt.call()` calls a command available in mutt, with arguments * `mutt.command.*` exposes all the commands from within Mutt * For some technical details: * proper error handling of the Lua interpreter * exposed mutt_option_set and mutt_option_get from init fixes: neomutt#153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
* adding two commands: - lua: to parse a line of lua code - lua-source: to load and parse a lua file * binding two mutt functions in lua: - mutt_message and - mutt_error cf #153 Signed-off-by: Guyzmo <guyzmo+github+pub@m0g.net>
hurra 🙌👍♥ |
The main target of this issue is to collect ideas around improving the scripting ability of mutt.
make mutt completely scriptable by a scripting language
It would be great if mutt would allow configuration in a scripting language. I think the main advantages of this point is readability for complex things and making mutt configs more powerful.
what is the problem with the existing solutions?
!zsh -ic FunctionToExecute<enter>
which consumes just space withoutpoviding information.
Lua
advantages
Python
advantages
disadvantages
@flatcap worked already on integrating lua
some general ideas
Questions
lets discuss :)
The text was updated successfully, but these errors were encountered: