From 6603c641c6ce675b010ca1977423747ca55d8795 Mon Sep 17 00:00:00 2001
From: Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
Date: Thu, 13 Aug 2015 01:56:37 +0200
Subject: [PATCH] abstract out reading full output of pipes

---
 helpers.lua                   | 15 ++++++++++++++-
 widgets/alsa.lua              |  6 ++----
 widgets/alsabar.lua           |  6 ++----
 widgets/base.lua              |  7 +++----
 widgets/contrib/kbdlayout.lua | 32 ++++++++++++++++++++++----------
 widgets/fs.lua                |  4 +---
 widgets/imap.lua              |  4 +---
 widgets/maildir.lua           |  8 ++++----
 widgets/net.lua               |  5 +----
 widgets/weather.lua           |  7 ++++---
 10 files changed, 54 insertions(+), 40 deletions(-)

diff --git a/helpers.lua b/helpers.lua
index dbee617..4e90e16 100644
--- a/helpers.lua
+++ b/helpers.lua
@@ -10,7 +10,8 @@ local debug  = require("debug")
 
 local capi   = { timer = timer }
 local io     = { open  = io.open,
-                 lines = io.lines }
+                 lines = io.lines,
+                 popen = io.popen }
 local rawget = rawget
 
 -- Lain helper functions for internal use
@@ -86,6 +87,18 @@ end
 
 -- }}}
 
+-- {{{ Pipe operations
+
+-- read the full output of a pipe (command)
+function helpers.read_pipe(cmd)
+   local f = assert(io.popen(cmd))
+   local output = f:read("*all")
+   f:close()
+   return output
+end
+
+-- }}}
+
 -- {{{ A map utility
 
 helpers.map_table = {}
diff --git a/widgets/alsa.lua b/widgets/alsa.lua
index 91bf488..85d5311 100644
--- a/widgets/alsa.lua
+++ b/widgets/alsa.lua
@@ -8,10 +8,10 @@
 --]]
 
 local newtimer        = require("lain.helpers").newtimer
+local read_pipe       = require("lain.helpers").read_pipe
 
 local wibox           = require("wibox")
 
-local io              = { popen  = io.popen }
 local string          = { match  = string.match,
                           format = string.format }
 
@@ -32,9 +32,7 @@ local function worker(args)
     alsa.widget = wibox.widget.textbox('')
 
     function alsa.update()
-        local f = assert(io.popen(string.format("%s get %s", alsa.cmd, alsa.channel)))
-        local mixer = f:read("*all")
-        f:close()
+        local mixer = read_pipe(string.format("%s get %s", alsa.cmd, alsa.channel))
 
         volume_now = {}
 
diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua
index f504cc0..c7498d2 100644
--- a/widgets/alsabar.lua
+++ b/widgets/alsabar.lua
@@ -8,12 +8,12 @@
 --]]
 
 local newtimer     = require("lain.helpers").newtimer
+local read_pipe    = require("lain.helpers").read_pipe
 
 local awful        = require("awful")
 local beautiful    = require("beautiful")
 local naughty      = require("naughty")
 
-local io           = { popen  = io.popen }
 local math         = { modf   = math.modf }
 local mouse        = mouse
 local string       = { format = string.format,
@@ -122,9 +122,7 @@ local function worker(args)
 
     function alsabar.update()
         -- Get mixer control contents
-        local f = assert(io.popen(string.format("%s get %s", alsabar.cmd, alsabar.channel)))
-        local mixer = f:read("*all")
-        f:close()
+        local mixer = read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.channel))
 
         -- Capture mixer control state:          [5%] ... ... [on]
         local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
diff --git a/widgets/base.lua b/widgets/base.lua
index 2a7bf10..2f377f7 100644
--- a/widgets/base.lua
+++ b/widgets/base.lua
@@ -7,9 +7,10 @@
 --]]
 
 local newtimer     = require("lain.helpers").newtimer
+local read_pipe    = require("lain.helpers").read_pipe
+
 local wibox        = require("wibox")
 
-local io           = { popen = io.popen }
 local setmetatable = setmetatable
 
 -- Basic template for custom widgets
@@ -25,9 +26,7 @@ local function worker(args)
     base.widget = wibox.widget.textbox('')
 
     function base.update()
-        local f = assert(io.popen(cmd))
-        output = f:read("*all")
-        f:close()
+        output = read_pipe(cmd)
         widget = base.widget
         settings()
     end
diff --git a/widgets/contrib/kbdlayout.lua b/widgets/contrib/kbdlayout.lua
index c5242c1..8d13a74 100644
--- a/widgets/contrib/kbdlayout.lua
+++ b/widgets/contrib/kbdlayout.lua
@@ -1,9 +1,17 @@
 
+--[[
+
+     Licensed under GNU General Public License v2 
+      * (c) 2015, Dario Gjorgjevski
+
+--]]
+
 local newtimer     = require("lain.helpers").newtimer
+local read_pipe    = require("lain.helpers").read_pipe
+
 local wibox        = require("wibox")
 
 local string       = { match = string.match }
-local io           = { popen = io.popen }
 
 local setmetatable = setmetatable
 
@@ -11,29 +19,33 @@ local function worker (args)
    local kbdlayout    = {}
    kbdlayout.widget   = wibox.widget.textbox('')
 
-   local settings     = args.settings or function () end
-   local layouts      = args.layouts
-   local idx          = 1
+   local layouts          = args.layouts
+   local settings         = args.settings or function () end
+   local add_us_secondary = args.add_us_secondary or true
+   local idx              = 1
    
    local function run_settings (layout, variant)
       widget = kbdlayout.widget
-      kbdlayout_now = { layout=layout, variant=variant }
+      kbdlayout_now = { layout=string.match(layout, "[^,]+"), -- Make sure to match the primary layout only.
+			variant=variant }
       settings()
    end
    
    function kbdlayout.update ()
-      local file   = assert(io.popen('setxkbmap -query'))
-      local status = file:read('*all')
-      file:close()
+      local status = read_pipe('setxkbmap -query')
 
-      run_settings(string.match(status, "layout:%s*([^\n]*)%s*"),
-		   string.match(status, "variant:%s*([^\n]*)%s*"))
+      run_settings(string.match(status, "layout:%s*([^\n]*)"),
+		   string.match(status, "variant:%s*([^\n]*)"))
    end
 
    function kbdlayout.set (i)
       idx = ((i - 1) % #layouts) + 1 -- Make sure to wrap around as needed.
       local to_execute = 'setxkbmap ' .. layouts[idx].layout
 
+      if add_us_secondary then
+	 to_execute = to_execute .. ",us"
+      end
+
       if layouts[idx].variant then
 	 to_execute = to_execute .. ' ' .. layouts[idx].variant
       end
diff --git a/widgets/fs.lua b/widgets/fs.lua
index c3a9e18..a01d3cf 100644
--- a/widgets/fs.lua
+++ b/widgets/fs.lua
@@ -38,9 +38,7 @@ end
 function fs:show(t_out)
     fs:hide()
 
-    local f = io.popen(helpers.scripts_dir .. "dfs")
-    ws = f:read("*all"):gsub("\n*$", "")
-    f:close()
+    ws = helpers.read_pipe(helpers.scripts_dir .. "dfs"):gsub("\n*$", "")
 
     if fs.followmouse then
         fs.notification_preset.screen = mouse.screen
diff --git a/widgets/imap.lua b/widgets/imap.lua
index 62b33d7..ea763df 100644
--- a/widgets/imap.lua
+++ b/widgets/imap.lua
@@ -43,9 +43,7 @@ local function worker(args)
 
     if not is_plain
     then
-        local f = io.popen(password)
-        password = f:read("*all"):gsub("\n", "")
-        f:close()
+        password = helpers.read_pipe(password):gsub("\n", "")
     end
 
     imap.widget = wibox.widget.textbox('')
diff --git a/widgets/maildir.lua b/widgets/maildir.lua
index 315ae34..cb96a30 100644
--- a/widgets/maildir.lua
+++ b/widgets/maildir.lua
@@ -8,12 +8,12 @@
 --]]
 
 local newtimer        = require("lain.helpers").newtimer
+local read_pipe       = require("lain.helpers").read_pipe
 
 local wibox           = require("wibox")
 
 local util            = require("lain.util")
 
-local io              = { popen  = io.popen }
 local os              = { getenv = os.getenv }
 local pairs           = pairs
 local string          = { len    = string.len,
@@ -50,10 +50,9 @@ local function worker(args)
                 -- match files that begin with a dot.
                 -- Afterwards the length of this string is the number of
                 -- new mails in that box.
-                local np = io.popen("find " .. line ..
+                local mailstring = read_pipe("find " .. line ..
                                     "/new -mindepth 1 -type f " ..
                                     "-not -name '.*' -printf a")
-                local mailstring = np:read("*all")
 
                 -- Strip off leading mailpath.
                 local box = string.match(line, mailpath .. "/*([^/]+)")
@@ -65,10 +64,11 @@ local function worker(args)
             end
         until line == nil
 
+	p:close()
         table.sort(boxes)
 
         newmail = "no mail"
-        --Count the total number of mails irrespective of where it was found
+        -- Count the total number of mails irrespective of where it was found
         total = 0
 
         for box, number in pairs(boxes)
diff --git a/widgets/net.lua b/widgets/net.lua
index d859d91..a578ae4 100644
--- a/widgets/net.lua
+++ b/widgets/net.lua
@@ -13,7 +13,6 @@ local notify_fg    = require("beautiful").fg_focus
 local naughty      = require("naughty")
 local wibox        = require("wibox")
 
-local io           = { popen  = io.popen }
 local string       = { format = string.format,
                        gsub   = string.gsub,
                        match  = string.match }
@@ -28,9 +27,7 @@ local net = {
 }
 
 function net.get_device()
-    f = io.popen("ip link show | cut -d' ' -f2,9")
-    ws = f:read("*all")
-    f:close()
+    local ws = helpers.read_pipe("ip link show | cut -d' ' -f2,9")
     ws = ws:match("%w+: UP") or ws:match("ppp%w+: UNKNOWN")
     if ws ~= nil then
         return ws:match("(%w+):")
diff --git a/widgets/weather.lua b/widgets/weather.lua
index fb37a52..8a0d751 100644
--- a/widgets/weather.lua
+++ b/widgets/weather.lua
@@ -7,9 +7,12 @@
 --]]
 
 local newtimer     = require("lain.helpers").newtimer
+local read_pipe    = require("lain.helpers").read_pipe
+
 local async        = require("lain.asyncshell")
 local json         = require("lain.util").dkjson
 local lain_icons   = require("lain.helpers").icons_dir
+
 local naughty      = require("naughty")
 local wibox        = require("wibox")
 
@@ -83,9 +86,7 @@ local function worker(args)
             if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then
                 weather.notification_text = ''
                 for i = 1, weather_now["cnt"] do
-                    local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"])))
-                    day = string.gsub(f:read("*all"), "\n", "")
-                    f:close()
+                    day = string.gsub(read_pipe(string.format(date_cmd, weather_now["list"][i]["dt"])), "\n", "")
 
                     tmin = math.floor(weather_now["list"][i]["temp"]["min"])
                     tmax = math.floor(weather_now["list"][i]["temp"]["max"])
-- 
2.39.5