1 -- Authors: Antti Vähäkotamäki
2 -- License: LGPL, version 2.1 or later
5 -- statusbar_external.lua
8 if not statusbar_external
then
11 -- a simple example which shows utc time and date
12 -- in %udate every second with 'date -u'
14 template_key
= 'dateb',
15 external_program
= 'date',
16 execute_delay
= 1 * 1000,
20 template_key
= 'udate',
21 external_program
= 'date -u',
22 execute_delay
= 5 * 1000,
25 -- a more complicated example showing the usage
26 -- percentage of hda1 every 30 seconds in %hda1u
27 -- with df, grep and sed.
29 template_key
= 'hda1u',
30 external_program
= 'df|grep hda1|sed "s/.*\\(..%\\).*/\\1/"',
31 execute_delay
= 30 * 1000,
34 important
= '9[456].',
48 -- This is a simple "general" statusbar lua script which
49 -- lets you show output of external programs in ion
50 -- statusbar. This is convenient if you are not familiar
51 -- with lua but can handle yourself with some other
52 -- language enough to output what you would want the
60 -- 1 ) modify settings variable
61 -- 2 ) update template to include specified keys
62 -- 3 ) dopath( "statusbar_external" ) in cfg_user.lua
67 -- There is an example settings-variable which can be
68 -- modified to specify your own programs. The needed
69 -- parameters are the following :
72 -- An unique name for the meter. You must add this
73 -- name with preceding % (for example %meter_name)
74 -- into your statusbar template which is usually set
75 -- in cfg_statusbar.lua.
78 -- The program to execute. The last line of each
79 -- flushed output this program writes to stdout is
80 -- inserted as the content of the meter.
83 -- The delay to wait before running the program again
84 -- once it stops sending data. Some programs just
85 -- send the data and exit while others continue
86 -- sending data periodically. This value can be used
87 -- to control the update rate for the first type of
90 -- * meter_length (optional)
91 -- The space reserved for this meter in characters.
92 -- If the value is not specified or is less than 1
93 -- then the space is determined by the length of the
94 -- data being shown but some people do not want their
95 -- statusbar width to change randomly.
97 -- * hint_regexp (optional)
98 -- These regular expressions (in Lua syntax) are
99 -- matched with the data and in case of a match the
100 -- named hint is set to the meter. The value can be
101 -- either a string containing the regexp or a table
102 -- containing several possible regexps (Lua regexp
103 -- doesn't have an 'or'). By default the themes define
104 -- a color for 'important' and 'critical' hints.
106 -- After this script is loaded it starts executing all
107 -- the provided programs and updates the statusbar every
108 -- time one of them prints (and flushes) something.
110 -- Also this is not a normal statusd script so it
111 -- doesn't get loaded by template name automatically
112 -- when ion starts. You must add
114 -- dopath( "statusbar_external" )
116 -- to some script that is being loaded in Ion. For
117 -- example ~/.ion3/cfg_user.lua is a good place. Note
118 -- that cfg_statusbar.lua is not loaded inside the
119 -- Ion process but in a separate process and thus this
120 -- script can not be loaded from that file!
124 ---------------------------------------------------------
129 -- Just print out stderr for now.
130 local function flush_stderr(partial_data
)
132 while partial_data
do
133 result
= result
.. partial_data
134 -- Yield until we get more input. popen_bgread will call resume on us.
135 partial_data
= coroutine
.yield()
140 -- Execute a program. This will continuously retrieve output from the program.
141 function start_execute(key
)
142 -- Read output from the program and (if data) then update the statusbar
143 local handle_output_changes
= coroutine
.create(
145 local key
= input_data
147 local partial_data
= ""
148 -- Keep reading data until we have it all
149 while partial_data
do
150 data
= data
.. partial_data
151 -- Yield until we get more input.
152 -- popen_bgread will call resume on us.
153 partial_data
= coroutine
.yield()
156 -- If no updates, then just schedule another run
157 if not data
or data
== "" then
158 return timers
[key
]:set(statusbar_external
[key
].execute_delay
,
162 -- remove all but the last line
163 data
= string.gsub( data
, "\n$", "" )
164 data
= string.gsub( data
, ".*\n", "" );
166 local sets
= statusbar_external
[key
]
167 local t_key
= sets
.template_key
168 local t_length
= sets
.meter_length
169 local h_regexp
= sets
.hint_regexp
171 if not tlength
or t_length
< 1 then
172 t_length
= string.len( data
)
175 mod_statusbar
.inform( t_key
, data
)
176 mod_statusbar
.inform( t_key
.. "_hint", '' )
177 mod_statusbar
.inform(t_key
.. "_template", string.rep( ' ', t_length
))
179 if not h_regexp
then h_regexp
= {} end
181 for hint
, re
in pairs( h_regexp
) do
182 if ( type( re
) == 'string' ) then
186 for _
, r
in ipairs( re
) do
187 if ( string.find( data
, r
) ) then
188 mod_statusbar
.inform(t_key
.. "_hint", hint
)
193 mod_statusbar
.update()
195 return timers
[key
]:set(statusbar_external
[key
].execute_delay
,
200 -- We need to pass it the key before calling a background call.
201 coroutine
.resume(handle_output_changes
, key
)
202 ioncore
.popen_bgread(statusbar_external
[key
].external_program
,
203 function(cor
) coroutine
.resume(handle_output_changes
,
205 coroutine
.wrap(flush_stderr
))
210 for key
in pairs(statusbar_external
) do
211 timers
[key
] = ioncore
.create_timer()
212 callbacks
[key
] = loadstring("start_execute("..key
..")")
217 -- Copyright (c) Antti Vähäkotamäki 2005.
219 -- Ion is free software; you can redistribute it and/or modify it under
220 -- the terms of the GNU Lesser General Public License as published by
221 -- the Free Software Foundation; either version 2.1 of the License, or
222 -- (at your option) any later version.