[neomutt-users] Neomutt: now featuring Lua scripting!
Floyd Anderson
f.a at 31c0.net
Sun Apr 30 13:47:52 CEST 2017
On Fr, 28 Apr 13:26:06 +0200
Guyzmo <z+mutt+neomutt at m0g.net> wrote:
>On Fri, Apr 28, 2017 at 03:31:12AM +0200, Floyd Anderson wrote:
>> On Fr, 28 Apr Guyzmo <z+mutt+neomutt at m0g.net> wrote:
>> I have a question about this. Will it be mandatory to mixing ‘normal’
>> {,Neo}mutt configuration directives with Lua code or can both be placed
>> in separated files and sourced from there? That probably would prevent (new)
>> user from getting confused, I think.
>
>well yes! as said in the first post of this thread you can either call Lua
>commands from Neomuttrc (or the `enter-command` line) by prefixing Lua code
>with the Neomuttrc `lua` command…
>
>Or you can source a lua script, within the context of Neomutt's Lua
>runtime using the `lua-source path/to/source-file.lua` command.
Oh yes, ‘lua-source’ was what I have thought of but I’ve overlooked it
more than once. Sorry for the noise and thanks for the brief examples,
next time I will be more attentively — hopefully. So with:
ifndef USE_LUA finish
lua-source /some/dir/neomutt-startup.lua
at the end of the run-command file, I got all what I need. ;-)
>Also, to make it a bit more comfortable to mix Muttrc and lua code, I'd
>like to add to the Neomuttrc parser a syntax (inspired by vim's) like:
>
>```Neomuttrc
>lua << EOS
>function fubar()
> mutt.message("This is some multiline lua code")
>end
>EOS
>
>macro generic z :lua fubar()
>```
I think, having alternate ways doing things is always fine as long as
the realised result is the same. This way everyone can pick what meets
the needs. Although I dislike mixing of configuration and code (at least
in the same file), your example above is comfortable and really useful
while working on both, configuration and code (e.g. reloading, testing).
>> I’m sure I will when I found the way how to compile, install and testing
>> Neomutt without influencing my existing ‘old dog’. ;-)
>
>that's easy:
>
>```
>wget https://github.com/neomutt/neomutt/archive/neomutt-20170421.tar.gz
>tar xvzf neomutt-20170421.tar.gz
>cd neomutt-neomutt-20170421
># I like to keep the compilation output in a separate directory
>mkdir build
># build all stable features, plus lua, and skip all doc and i18n
>../configure --enable-everything --enable-lua --disable-doc --disable-po --disable-full-doc
>make
>./mutt
>```
Thank you for pointing this out, that helps especially `mkdir build` and
`make` (without ‘install’). It was a little bit bumpy (due to some other
packages depends on the formerly installed Lua 5.1.5 version) but lastly
I got it and here is my little interim conclusion:
# Working with Lua scripts
Within my sourced Lua start script I can do what I want, all works fine
(e.g. overriding native Lua functions, set NeoMutt related search path
via ‘package.path’, pull in pseudo Class modules with the ‘require()’
statement, extending global Lua table ‘_G’).
# Structure of mutt namespace
Before the mutt namespace grows up, I think it probably needs to be a
little bit more structured, for instance:
_G.mutt = {
const = { VERSION = '', QUAD_NO = 0, QUAD_YES = 1, … },
props = { … }, command = { … }, sidebar = { … },
index = { … }, pager = { … },
event = { OnFolderHook = function(mailbox),
OnSendHook = function(header), … },
…,
}
This way constants like QUAD_* can be easier kept as read-only by users
by manipulating the metatable of ‘const’. Currently the expressions:
:lua mutt.QUAD_YES = 'The answer is 42!'
:lua mutt:set('copy', mutt.QUAD_YES)
results as one does ‘set copy = no’. But on the other hand, if you would
argue: “When a user put nonsense in, he should not wonder why nonsense
comes out!“, I would say you are right — it’s just only an idea.
Another one is to let NeoMutt call user declared event handler until the
queue of handler functions is empty or one of them returns true (means
event is consumed). But for now something like:
folder-hook . :lua mutt.mailbox:defaults()
might do the job.
# Extending of mutt:set()
Since mutt:set() is a function, it can probably do more by default for
users convenience and may also results in shorter, clearly Lua scripts.
For instance:
1. reset an option to its default by passing a nil (not in list) value
:lua mutt:set('option', nil)
2. set a boolean option to true and return its current value afterwards
local current = mutt:set('option', true)
3. same as 2. but return its new and old value
local new,old = mutt:set('option', true)
4. same as 3. but return its new, old and default value
local _,_,def = mutt:set('option', true)
The second and third can be realised in pure Lua. While the fourth is a
little bit overkill, my favourite would be the second additionally with
the capability from the first.
# Visual behaviour of global print()
With the Environment:
NeoMutt: neomutt-20170428 (1.8.2)
Lua: 5.2.3
Terminal: rxvt-unicode (urxvt) and xfce4-terminal
I got a different (visual) behaviour on NeoMutt’s command line with
Lua’s global print() function which should usually be the same as with
mutt:print(). Currently a command like:
:lua print('hello world!')
results in a command line which is two lines high (second one is empty)
while the first looks like:
:lua print('hello world!')hello world!
After invoking the ‘refresh’ or ‘redraw-screen’ command (dependent on
mode), all looks as before.
These are just my first impressions with Lua enabled in NeoMutt. Keep up
the great work and let me know if I can help within the limits of my
resources.
--
Regards,
floyd
More information about the neomutt-users
mailing list