Elv13 / awesome-configs

My AwesomeWM configuration
126 stars 19 forks source link

fd_async questions #3

Closed ghost closed 10 years ago

ghost commented 10 years ago

Hello, is there any way to use this module for reading a program output and return its output as string? Something like that would be really cool:

local run = fd_async.run_async('sleep 5;echo test')
run:connect_signal("request::completed", function(c) print(c) end)

or even better, eval Lua code:

function test() return "hello world" end
local run = fd_async.eval_async(test)
run:connect_signal("request::completed", function(output) print(output) end)

Thank you very much.

Elv13 commented 10 years ago

It is possible (in fact, I think that probably 80% of that code works with exec fds). I don't have the code right now (it is on my todo list). I will see if I can do it later today. Here is a network socket example from pyschon http://sprunge.us/VKXC?lua

Elv13 commented 10 years ago

Done!

*Async eval can be done using lgi.GLib.ASync()

ghost commented 10 years ago

Nice, thanks. Some changes that you might be interested in:

--- fd_async.lua-org    2014-03-08 21:31:07.764218914 +0200
+++ fd_async.lua    2014-03-08 21:42:07.349253019 +0200
@@ -7,6 +7,8 @@
 local ipairs = ipairs
 local pairs = pairs
 local tostring = tostring
+local table = table
+local os = os
 local gio = require("lgi").Gio
 local gobject = require("lgi").GObject
 local glib = require("lgi").GLib
@@ -139,45 +141,53 @@

 -- Execute a command async
 function module.exec_command_async(command,cwd)
-  local req = create_request()
+  if not command then return end
+  local cwd = cwd or os.getenv("HOME")
+  local env = {}
+  for _,v in ipairs({"PATH","DISPLAY","HOME","XAUTHORITY","SHELL"}) do
+    table.insert(env, v.."="..os.getenv(v))
+  end
   local argv = glib.shell_parse_argv(command)
-
-  local pid, stdin, stdout, stderr = glib.spawn_async_with_pipes(cwd,argv,nil,2,function() end)
-  local stream = gio.UnixInputStream.new(stdout)
-  local filter = gio.DataInputStream.new(stream)
-  local errstream = gio.UnixInputStream.new(stderr)
-  local errfilter = gio.DataInputStream.new(errstream)
-  local ret = {}
-  local function get_line(obj, res)
-    local result, err = obj:read_line_finish_utf8(res)
-    req:emit_signal("new::line",result)
-    if (result and not filter:is_closed()) then
-      ret[#ret+1] = result
-      filter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_line)
-    else
-      filter:close()
-      stream:close()
-      errfilter:close()
-      errstream:close()
-      req:emit_signal("request::completed",table.concat(ret,"\n"))
+  local pid, stdin, stdout, stderr = glib.spawn_async_with_pipes(cwd,argv,env,glib.SpawnFlags.SEARCH_PATH,function() end)
+  if pid then
+    local req = create_request()
+    local stream = gio.UnixInputStream.new(stdout)
+    local filter = gio.DataInputStream.new(stream)
+    local errstream = gio.UnixInputStream.new(stderr)
+    local errfilter = gio.DataInputStream.new(errstream)
+    local ret = {}
+    local function get_line(obj, res)
+      local result, err = obj:read_line_finish_utf8(res)
+      req:emit_signal("new::line",result)
+      if (result and not filter:is_closed()) then
+        ret[#ret+1] = result
+        filter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_line)
+      else
+        filter:close()
+        stream:close()
+        errfilter:close()
+        errstream:close()
+        req:emit_signal("request::completed",table.concat(ret,"\n"))
+      end
     end
-  end
-  local function get_error_line(obj,res)
-    local result, err = obj:read_line_finish_utf8(res)
-    req:emit_signal("new::error",result)
-    if result or not errstream:is_open() then
-      errfilter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_error)
-    else
-      filter:close()
-      stream:close()
-      errfilter:close()
-      errstream:close()
-      req:emit_signal("request::completed",table.concat(ret,"\n"))
+    local function get_error_line(obj,res)
+      local result, err = obj:read_line_finish_utf8(res)
+      req:emit_signal("new::error",result)
+      if (result and not errfilter:is_closed()) then
+        ret[#ret+1] = result
+        errfilter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_error_line)
+      else
+        filter:close()
+        stream:close()
+        errfilter:close()
+        errstream:close()
+        req:emit_signal("request::completed",table.concat(ret,"\n"))
+      end
     end
+    filter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_line)
+    errfilter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_error_line)
+    return req
   end
-  filter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_line)
-  errfilter:read_line_async(glib.PRIORITY_DEFAULT,nil,get_error)
-  return req
 end

 ---------------------------------------------------------------------

http://ix.io/aZM/lua