• Stars
    star
    58
  • Rank 498,058 (Top 11 %)
  • Language
    Lua
  • Created almost 12 years ago
  • Updated almost 12 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Lua REPL with global name tab-completion and a shell sub-mode

A better REPL for Lua

luaish is based on lua.lua which is a Lua interpreter front-end written in Lua by David Manura.

/mnt/extra/luaish$ lua52 lua.lua -h
usage: lua.lua [options] [script [args]].
Available options are:
  -e stat  execute string 'stat'
  -l name  require library 'name'
  -i       enter interactive mode after executing 'script'
  -v       show version information
  --       stop handling options
  -        execute stdin and stop handling options

Starting from this good working point, I first modified lua.lua to be 5.2 compatible, and added 'readline-like' support using lua-linenoise which is a linenoise binding by Rob Hoelz. Although only a few hundred lines of C, linenoise is more than capable for straightforward line editing and history. And it has enough tab completion support for our purposes.

So, say if you have typed 'st' then will give you the only matching Lua global, which is 'string'. If you now enter '.' , will cycle through all the available string table functions.

This also works with objects (such as strings). After 's:r' will complete 's:rep' for us:

> s = '#'
> = s:rep(10)
"##########"

There is also a few shortcuts defined, so 'fn' gives 'function', and 'rt' gives 'return'.

luaish makes the command history available in the usual way, and saves it in the ~/luai-history file. Anything you put in the ~/luairc.lua file will be loaded at startup.

luaish uses luaposix for directory iteration and setting the process environment.

There is an optional dependency on Microlight, which is only used to provide some table-dumping abilities to the REPL:

> = {1,2;one=1}
{1,2,one=1}

Shell Mode

It can be irritating to have to switch between the Lua interactive prompt and the shell, as separate programs. However, Lua would make a bad shell, in the same way (arguably) that Bash makes a poor programming language.

Any line begining with '.' is assumed to be a shell command:

> .tail luaish.lua
local luarc =  home..'/.luairc.lua'
local f = io.open(luarc,'r')
if f then
        f:close()
        dofile(luarc)
else
        print 'no ~/.luairc.lua found'
end

return lsh
> .ls
luaish.lua  lua.lua  readme.md

In this shell sub-mode, tab completion switches to working with paths. In the above case, I typed '.tail l' and tabbed twice to get '.tail luaish.lua'.

cd is available, but is a pseudo-command. It changes the current working directory for the whole session, and updates the title bar of the terminal window. It acts rather like the pushd command, so that the pseudo-command back goes back to the directory you came from.

> .cd ../lua/Penlight
../lua/Penlight
> .ls
github  Penlight  stevedonovan.github.com
> .back
/mnt/extra/luaish
> .cd ../lua
> .lua hello.lua
hello dolly!
> .l hello.lua
hello dolly!

'l' is another pseudo-command, which is equivalent to the Lua call dofile 'hello.lua; thereafter '.l' will load the last named file.

Note that this works as expected:

> .export P=$(pwd)
> .echo $P
/mnt/extra/luaish

But, given that luaish is just creating a subshell for commands, how can this command modify the environment of luaish? How this is done is discussed next.

Shell and Lua Mode communication

If a shell command ends with a '| - ' then 'fun' is assumed to be a function in the global table 'luaish'. The predefined '>' function sets the global with the given name to the output, as a Lua table:

> .ls -1 | -> ls
> = ls
{"luaish.lua","lua.lua","readme.md"}

Another built-in function is 'lf', which presents numbered output lines, You can then refer to the line as '$n'

> .ls -1 | -lf
 1 luaish.lua
 2 lua.lua
 3 readme.md
> .head -n 2 $3
## A better REPL for Lua

Any Lua globals are also expanded:

> P = 'hello'
> .echo $P $(pwd)
hello /mnt/extra/luaish

The 'ls -1 |-lf' pattern is common enough that an alias is provided:

> .dir *.lua
 1 luaish.lua
 2 lua.lua

which is defined so:

luaish.add_alias('dir','ls -1 %s |-lf')

Nothing fancy goes on here; any arguments to the alias are passed to the command directly.

Now the implementation of 'export' can be explained. There is a built-in function which uses luaposix's setenv function:

function luaish.lsetenv (f)
    local line = f:read()
    local var, value = line:match '^(%S+) "(.-)"$'
    posix.setenv(var,value)
end

(Note that these functions are passed a file object for reading from the shell process)

Here is the long way of using 'lsetenv':

>.export P=$(pwd) && echo P "$P" | -lsetenv

And that's exactly what the builtin-command 'export' outputs when you say:

>.export P=$(pwd)

Lua string values can be passed to the shell as expanded globals, but there's also an equivalent '| -' mechanism for pumping data into a shell command:

> t = {'one','two','three'}
> .-print t | sort
one
three
two

Again, 'print' is a function in the 'luaish' table; these functions work exactly like the others, except they write to their file object. Here is a simplified implementation:

function luaish.print (f,name)
    for _,line in ipairs(_G[name]) do 
        f:write(line,'\n')
    end
end

The purpose of ~/.luairc.lua is to let people define their own Lua filters and aliases, as well as preloading useful libraries.

More Possibilities

luaish is currently in the 'executable proposal' stage of development, for people to try out and play with the possibilities. It could do with some refactoring, so that a person may use it only as a linenoise-equiped Lua prompt, or even use that old dog readline itself. Rob Hoelz and myself will be looking at how to build a more generalized and extendable framework.

Currently, you may either use the 'push input' or 'pop output' forms, but not together. Since popen2 can be implemented using luaposix, this restriction can be lifted, and we can have a general mechanism for pumping Lua data through a shell filter:

> . -print idata | sort | -> sdata

More Repositories

1

gentle-intro

A gentle Rust tutorial
Rust
820
star
2

luar

luar is a Go package for conveniently working with the luago Lua bindings. Arbitrary Go functions can be registered
Go
300
star
3

winapi

Minimal but useful Lua bindings to the Windows API
C
188
star
4

Microlight

A little library of useful Lua functions, intended as the 'light' version of Penlight
Lua
163
star
5

LuaMacro

An extended Lua macro preprocessor
Lua
144
star
6

runner

Tool for running Rust snippets
Rust
141
star
7

Lake

A Lua-based Build Tool
Lua
129
star
8

luabuild

A highly customizable Lua 5.2 build system, allowing for common external modules to be linked in statically, and built-in modules to be excluded
C
77
star
9

UnderC

Interactive C++ Interpreter for x86 Systems
C++
57
star
10

chrono-english

Converting informal English dates (like `date` command) to chrono DateTime in Rust
Rust
54
star
11

llib

A compact library for C99 (and MSVC in C++ mode) providing refcounted arrays, maps, lists and a cool lexical scanner.
C
40
star
12

MonoLuaInterface

Mono-buildable version of LuaInterface
C#
36
star
13

el

A more commamd-line friendly style of using Lua
Lua
32
star
14

outstreams

C++ wrapper around stdio that overloads the call operator to output fields
C++
32
star
15

Orbiter

A personal Lua Web Application Server
Lua
29
star
16

llua

Higher-level C API for Lua based on llib
C
29
star
17

lua-patterns

Exposing Lua string patterns to Rust
Rust
28
star
18

ltags

Exuberant CTags compatible tag files from Lua projects
Lua
25
star
19

stevedonovan.github.com

Project Pages
HTML
24
star
20

lua-command-tools

Command-line utilties for performing common Lua one-liners, like matching string patterns and substitution.
Lua
22
star
21

findr

Expression-oriented fast file finder
Rust
20
star
22

lapp

a Rust port of the Lua Lapp framework: a straightforward GNU-style command-line parser which uses usage text to define arguments
Rust
17
star
23

mosquitto-client

Rust
15
star
24

LuaExpatUtils

Utilities for pretty-printing lxp.dom style LOM and constructing LOM documents
Lua
15
star
25

lglob

Extended undefined-variable checker for Lua 5.1 and 5.2
Lua
14
star
26

luafaq

Unofficial Lua FAQ
14
star
27

shmake

A shell-based build tool.
C
12
star
28

cs-repl

A REPL for C# (formerly known as CSI)
C#
12
star
29

rx-cpp

Modern C++ Regular Expressions library, wrapping both POSIX and Lua string patterns.
C++
11
star
30

scanlex

A simple lexical scanner in Rust
Rust
11
star
31

LuaRocksTools

Support utilities for working with LuaRocks
Lua
10
star
32

lua-gentle-intro

8
star
33

grun

A command-line runner for Go expressions
Go
8
star
34

easy-shortcuts

Useful helpers for implementing short command-line tools in Rust
Rust
8
star
35

tinycpp

Compact 'fake' standard library strings and streams, for experimental purposes only ;)
C++
7
star
36

ldeb

ldeb converts Lua scripts into Debian packages
Lua
7
star
37

Webrocks

A self-contained local web interface to LuaRocks
JavaScript
6
star
38

flot-rs

Rust
6
star
39

rockspec

A command-line tool and DSL for generating rockspecs for LuaRocks
Lua
5
star
40

cargo-docgen

Cargo subcommand for testing and formatting Rust documentation tests
Rust
3
star
41

moi

MOI (MQTT Orchestration Interface) is a simple management tool for groups of remote systems
Rust
1
star
42

lily-extras

A collection of examples and extensions for the Lily programming language
C
1
star
43

ght

ght is a friendly HTTP/API command-line tool in the footsteps of HTTPie
Go
1
star
44

jaywalk

Java utility classes for easier command-line and GUI programs
1
star
45

xflag

Extended version of Go's flag package, with support for opening files and positional parameters
1
star