[neomutt-users] [RFC] Lua scripting in Neomutt

Guyzmo z+mutt+neomutt at m0g.net
Thu Jan 19 23:57:38 CET 2017


Hello y'all,

after some discussion about scripting on the [tracker][0], I have done a
first shot at implementing [Lua scripting][1] in Neomutt.

Right now, the API is pretty limited, and is summed up below, as well as
on this [ticket comment][2].

If I'm writing this mail, is to get some feedback about the
implementation, and ideas about how to use the API and what would be the
best next things to implement.

One of the ideas I have is that we can start building some regression testing
using Lua. To that purpose, I introduced a `-B` command line parameter to
prevent Neomutt from launching the curses UI, and exit without entering a loop.

# two new commands

    :lua <lua command>
    :lua-source <.lua file>

# Lua API

print messages on stdout:

    mutt.print('hello world')

print a message in the status line:

    mutt.message('hi there o/')

print an error in the status line:

    mutt.error('Oops... Looks like an error!')

the simplest API is the following:

    mutt.enter(line)

which is equivalent to the `enter-command` feature (the : key).
It expects a single parameter being the full command line you'd give in
Neomutt.

Then there is the two following functions, that are direct binding to
the C equivalent function (no real equivalent in the Neomutt UI):

    mutt.call(command, args...)

which takes a command name, and expects the exact number of arguments
(string separated) that the command expects. All commands are the ones
callable from the `enter-command` prompt.

Then you have the get/set API

    mutt.get(key)
    mutt.set(key, value)

they get and set values for all variables available in Neomutt. Values are
strongly typed, and if not properly typed, it will throw an exception.

Then all commands available are accessible as functions (using some
Lua syntactic sugar around the mutt.call() API).

    mutt.command.*

# Example

Here are some examples of what can be done in Lua:

:lua mutt.enter("color quoted brightblue default")
:lua mutt.call("color", "quoted", "brightblue", "default")
:lua mutt.command.color("quoted", "brightblue", "default")
:lua mutt.set("visual", "less")
:lua mutt.set("connect_timeout",42)
:lua mutt.set("arrow_cursor", true)
:lua mutt.set("abort_noattach", mutt.QUAD_ASKNO)
:lua mutt.set("alias_file", "~/muttrc")
:lua mutt.set("mbox_type", "Maildir")
:lua mutt.set("sort", "date")
:lua mutt.set("mask", "!^\\\\.[^.]")
:lua mutt.set("to_chars", "+TCFL")
:lua mutt.set("from", "fubar at example.org")
:lua mutt.message(mutt.get('alias_file'))
/home/guyzmo/muttrc

For the development of the feature, I even implemented a [poor man's test suite][5]

# References

[0]:https://github.com/neomutt/neomutt/issues/153
[1]:https://github.com/neomutt/neomutt/pull/298
[2]:https://github.com/neomutt/neomutt/issues/153#issuecomment-272904748
[3]:https://gist.github.com/guyzmo/9ed8ec8cd54486cf6e97d4c8f2526a2e
[4]:https://gist.github.com/guyzmo/9ed8ec8cd54486cf6e97d4c8f2526a2e

I hope you'll enjoy the feature, and come up with great ideas and ways to use
it! It was fun implementing those ☺ But it'll be lovely to see people start
trying and using it ♥

Cheers 🍻

-- 
Zmo


More information about the neomutt-users mailing list