Can I run a function for the Lua shell prompt?

Viewed 120

I can set the prompt with _PROMPT = "> ", but can I make the prompt update every time?

I tried this, but it doesn't work:

i = 0

function inc()
    i = i + 1
    return i
end

_PROMPT = inc

This shows _PROMPT, but nothing related:

for k, v in pairs(_G) do
    print(k)
end
2 Answers

The primary prompt is the value of the global variable _PROMPT, if this value is a string; otherwise, the default prompt is used.

https://www.lua.org/manual/5.1/lua.html

You assigned a function to _PROMPT.

I tried

_PROMPT = {no = 0}; setmetatable (_PROMPT, {__tostring = function (self) self.no = self.no + 1; return tostring (self.no) .. ' >' end})

, but no luck, although _PROMPT was incremented every time I typed = _PROMPT.

UPD Yet this can be done! In Lua mailing list I was advised to use

setmetatable(_ENV, {__index = function(t, k) if k == '_PROMPT' then t._N = (t._N or 0) + 1; return t._N .. ' >' end end})

It works. This effectively is a way to override any global in a deeper sense than simply to assign a new value to it, or make a set of global variables effectively infinite.

You can start Lua in interactive mode with a one-liner:

lua -i -e "setmetatable(_ENV, {__index = function(t, k) if k == '_PROMPT' then t._N = (t._N or 0) + 1; return t._N .. ' >' end end})"

I found out a method with debug.sethook().
It sounds a bit strange but it is really simple ;-)
Here we go...

# /usr/bin/lua -i
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio
> debug.sethook(function(...) _PROMPT=os.date('%H:%M:%S # ') end,'r')
10:49:42 # -- Hiting ENTER some times
10:51:00 #
10:51:01 #
10:51:05 #

( Done with Lua 5.3.5 and tested 5.4 - Should work with 5.1 but not tested )
The 'r' means: Fire on each return

EDIT
Another way directly with _PROMPT and _PROMPT2...

-- Simple method for changing and/or time logging the prompts                                                                                                                                 
_PROMPT=setmetatable({},{__index=table})                                                                                                                                                                   
_PROMPT2=setmetatable({},{__index=table})                                                                                                                                                                  

getmetatable(_PROMPT).__tostring=function()
_PROMPT:insert(os.date('%H:%M:%S',os.time())..'> ')
return string.format('%s',_PROMPT:concat(#_PROMPT,#_PROMPT))
end                              

getmetatable(_PROMPT2).__tostring=function()
_PROMPT2:insert(os.date('%H:%M:%S',os.time())..'>> ')
return string.format('%s',_PROMPT2:concat(#_PROMPT2,#_PROMPT2))
end

...using __tostring and __index has table metamethods.

...much fun and stay healthy.

Related