Released version 3-2015061300
[notion.git] / contrib / statusbar / statusbar_external.lua
blob577889296497d2023c44dc3181c0348385bf740e
1 -- Authors: Antti Vähäkotamäki
2 -- License: LGPL, version 2.1 or later
3 -- Last Changed: 2005
4 --
5 -- statusbar_external.lua
6 --
8 if not statusbar_external then
9 statusbar_external = {
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,
32 meter_length = 4,
33 hint_regexp = {
34 important = '9[456].',
35 critical = {
36 '9[789].',
37 '1...',
43 end
46 -- -- What is this?
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
53 -- statusbar to show.
55 --
56 -- -- How to use it?
58 -- Short version:
60 -- 1 ) modify settings variable
61 -- 2 ) update template to include specified keys
62 -- 3 ) dopath( "statusbar_external" ) in cfg_user.lua
65 -- Longer version:
67 -- There is an example settings-variable which can be
68 -- modified to specify your own programs. The needed
69 -- parameters are the following :
71 -- * template_key
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.
76 --
77 -- * external_program
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.
82 -- * execute_delay
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
88 -- programs.
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 ---------------------------------------------------------
126 local timers = {}
127 local callbacks = {}
129 -- Just print out stderr for now.
130 local function flush_stderr(partial_data)
131 local result = ""
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()
137 print(result, "\n")
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(
144 function(input_data)
145 local key = input_data
146 local 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,
159 callbacks[key])
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
183 re = { re }
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,
196 callbacks[key])
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,
204 cor) end,
205 coroutine.wrap(flush_stderr))
209 -- Start all
210 for key in pairs(statusbar_external) do
211 timers[key] = ioncore.create_timer()
212 callbacks[key] = loadstring("start_execute("..key..")")
213 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.