lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


OK. I found a way to do this.
Just a few thoughts

The lack of assignment capability can be ameliorated by moving assignments in to a function.
Return values can then be made by assigning to table fields.

Some kind of slicing capability on return lists would have been nice.
Something along the lines of

ret.start, ret.stop, ret[] = string.find(...)

or some other way to specify that "ret" should suck up all remaining return values into a list

Instead i had to make do with some rather ugly assign/shift loops as can be seen in the attachment

Of course I also had to modify the main read loop, but this is covered in other list topics
(http://lua-users.org/lists/lua-l/2001-03/msg00159.html)

/Flemming

Flemming Madsen wrote:
Hello

I was contemplating a small lua exercise, a program for listing my currently vim'ed files a'la

local s,e,c,r,line,file,modified,pid,running
local fd = io.popen("sh -c 'vi -r 2>&1'", "r")

while (line = fd:read("*line")) do
      ^^^^^^
   if s,e,c = string.find(line, "^ *file name: ([%w%p]*)") then
      ^^^^^^^^
       file = c
   elseif s,e,c = string.find(line, "^ *modified: (%a*)") then
          ^^^^^^^^
       modified = c ~= "no"
   elseif s,e,c,r = string.find(line, "^ *process ID: (%d*)(.*)") then
          ^^^^^^^^^
       pid = c
       running = string.find(r, "(still running)", 1, true) ~= nil

       if file && modified then
           io.write(string.format("%d %8d%s %s", modified and 1 or 0,
                                  pid, running and "*" or " ", file)
       end
       file = nil
       running = nil
   end
end
fd:close()


Obviously this will not work, since assignments are not expressions in lua,
nor is there any way of embedding assignment in expressions

Is there an easy way around this that i missed. Is this even a candidate for the FAQ


Best /Flemming*
*

#!/usr/bin/env lua

local line,file,modified,pid,running

function findandset(line, pattern, ret)
    -- ret = {}; wont work as the reference is by value
    for k in pairs(ret) do ret[k] = nil end

    local t = {string.find(line, pattern)}
    if not t[1] then return nil end
    ret.start = t[1]
    ret.stop = t[2]
    local i=3
    while t[i] do ret[i-2] = t[i]; i=i+1 end
    --DEBUG for k,v in pairs(ret) do print(k, "=", v) end
    return ret
end

-- Make sure t is a table
local t = {}

local fd = io.popen("sh -c 'vi -r 2>&1'", "r")
while true do
    line = fd:read("*line")
    if not line then break end
    if findandset(line, "^ *file name: ([%w%p]*)", t) then
        file = t[1]
    elseif findandset(line, "^ *modified: (%a*)", t) then
        modified = t[1] ~= "no"
    elseif findandset(line, "^ *process ID: (%d*)(.*)", t) then
        pid = t[1]
        running = string.find(t[2], "(still running)", 1, true) ~= nil
        if file and modified ~= nil then
            io.write(string.format("%d %8d%s %s\n", modified and 1 or 0,
                                   pid, running and "*" or " ", file))
        end
        file = nil
        running = nil
    end
end