Lua Prompt

lua-users home
wiki

luaprompt is both an interactive Lua prompt that can be used instead of the official interpreter, as well as a module that provides a Lua command prompt that can be embedded in a host application. As a standalone interpreter it provides many conveniences that are missing from the official Lua interpreter. As an embedded prompt, it's meant for applications that use Lua as a configuration or interface language and can therefore benefit from an interactive prompt for debugging or regular use.

luaprompt features:

The prompt module

Both luaprompt, the prompt module and luap, the standalone interpreter can be installed via LuaRocks with:

luarocks install luaprompt

This will install both the module and the interpreter with the default configuration, but you can also customize the behavior of luaprompt. Please consult [luaprompt's GitHub page] for more information on how to build and use the prompt module.

Standalone usage

As a standalone interpreter, luaprompt tries to mimic the standard Lua interpreter as much as possible (currently only the -E flag is not supported), while providing the extra set of features described above. Below are a few snippets of a luaprompt session that are meant to illustrate the features luaprompt offers.

Tab completion works mostly like you would expect it to. It tries to complete table keys (and hence global variables), reserved keywords and file names. In the example sessions below [tab] stands for a tab keystroke. All characters that appear after a [tab] are supplied by the completer.

> band = [tab][tab]
_G              coroutine       error           in              math            package         rawset          table           until
_VERSION        debug           false           io              module          pairs           repeat          then            while
and             do              for             ipairs          next            pcall           require         tonumber        xpcall
assert          dofile          function        load            nil             print           return          tostring        
bit32           else            getmetatable    loadfile        not             rawequal        select          true            
break           elseif          goto            loadstring      or              rawget          setmetatable    type            
collectgarbage  end             if              local           os              rawlen          string          unpack          
> band = bi[tab]t32[tab].[tab][tab]
bit32.arshift  bit32.bnot     bit32.btest    bit32.extract  bit32.lshift   bit32.rrotate  
bit32.band     bit32.bor      bit32.bxor     bit32.lrotate  bit32.replace  bit32.rshift   

Generally luaprompt tries to complete as much as possible but it doesn't try to second-guess you when doing so. When completing the bit32 table it didn't immediately add a dot since it might cause frustration if you wanted to use bit32 as a function argument for instance. You therefore have to press the tab key one more time. Depending on the table's keys luaprompt might add an opening square bracket instead of a dot, or nothing at all.

> array = {1, 2, 3}
> a = ar[tab]ray[tab][[tab][tab]
array[1]  array[2]  array[3]  
> a = array[1[tab]]

The situation is similar with function values where an opening parenthesis is added after hitting one more tab on a fully completed function name.

If luaprompt can't complete table keys or keywords it goes for file names.

> loadfile("./[tab]
ChangeLog  Makefile   README     luap       luap.c     patch      prompt.c   prompt.h   

You can print out the value of any expression in luaprompt by simply typing it in. The behavior is identical to that of the official interpreter with the exception that you don't have to start the line with an equal sign.

>  1 + 2
3
>  _VERSION 
"Lua 5.2"

As in the official interpreter, the __tostring metamethods of values are honored.

>  io.stdin
file (0x7f3d0aeb2240)

When a value is printed luaprompt tries to do its best to format it so that it is as readable as possible. A complex logic is used to achieve that but a few examples will illustrate the basic features. (Unfortunately the wiki is not very flexible in terms of formatting so that it's hard to convey the different font colors and weights used by luaprompt.)

Arrays are printed in a linear fashion:

>  a = {1, 2, 3, 4, 5}
>  a
{ 1, 2, 3, 4, 5,  }

When they become too large to fit in one line the output is split into multiple lines:

>  for i = 1, 100 do a[i] = i end
>  a
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 
  23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 
  43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 
  63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 
  83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,  }

Tables with string keys are formatted with each key on a separate line:

>  coroutine
{ 
  yield = <function: 0x7f98dd0956e0>,
  status = <function: 0x7f98dd095820>,
  create = <function: 0x7f98dd095970>,
  wrap = <function: 0x7f98dd0959d0>,
  resume = <function: 0x7f98dd095aa0>,
  running = <function: 0x7f98dd095950>,
}

Mixed tables are handled as one might expect. The following example illustrates how luaprompt handles mixed and nested tables (as well as multi-line statements).

>  function recurse(n)
>> if n == 1 then return "foo" else
>> local a = {}
>> for i = 1, n do a[i] = i end
>> a.down = recurse(n - 1)
>> return a
>> end
>> end
>  recurse(2)
{ 1, 2, 
  down = "foo",
}

Of course the case of n = 2 is straightforward but luaprompt tries to handle even pathological cases as gracefully as possible. If the table is nested too deeply luaprompt will give up after a while but it will try to convey as much information about the structure of the table as possible and it will avoid printing badly formatted output at all costs.

Below is the output for n = 30. Setting n = 500 work's just as well, but the output is a bit longer.

>  recurse(30)
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 
  23, 24, 25, 26, 27, 28, 29, 30, 
  down = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
           21, 22, 23, 24, 25, 26, 27, 28, 29, 
           down = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
                    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 
                    down = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
                             16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 
                             down = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
                                      14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 
                                      25, 26, 
                                      down = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
                                               12, 13, 14, 15, 16, 17, 18, 19, 
                                               20, 21, 22, 23, 24, 25, 
                                               down = { 1, 2, 3, 4, 5, 6, 7, 8, 
                                                        9, 10, 11, 12, 13, 14, 
                                                        15, 16, 17, 18, 19, 20, 
                                                        21, 22, 23, 24, 
                                                        down = { 1, 2, 3, 4, 5, 
                                                                 6, 7, 8, 9, 10, 
                                                                 11, 12, 13, 14, 
                                                                 15, 16, 17, 18, 
                                                                 19, 20, 21, 22, 
                                                                 23, 
                                                                 down = { ... },
                                                        },
                                               },
                                      },
                             },
                    },
           },
  },
}

Finally luaprompt avoids infinite recursion when printing tables containing themselves by printing the nesting level instead of the actual table contents. In the example below the nested table with key b has a key named self with

>  recursive = {a = {1, 2, 3}, b = coroutine}
>  recursive.b.self = recursive.b
>  recursive.b.parent = recursive
>  recursive
{ 
  a = { 1, 2, 3,  },
  b = { 
        wrap = <function: 0x7fec9b79f9d0>,
        yield = <function: 0x7fec9b79f6e0>,
        self = { [-1]... },
        parent = { [-2]... },
        running = <function: 0x7fec9b79f950>,
        create = <function: 0x7fec9b79f970>,
        status = <function: 0x7fec9b79f820>,
        resume = <function: 0x7fec9b79faa0>,
  },
}

A nice example of a large table which contains all the above features is the globals table _G. It's handled as well as can be expected by luaprompt but the output is too large to quote here.

Source Code

The source code for luaprompt is distributed under the MIT/X11 license. You can get it at [the project's page at GitHub].

Alternatives

LuaRepl


RecentChanges · preferences
edit · history
Last edited November 13, 2015 8:31 pm GMT (diff)