]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/env ruby | |
2 | ||
3 | require "time" | |
4 | require "ncurses" | |
5 | require "inifile" | |
6 | require "open3" | |
7 | require 'optparse' | |
8 | require 'ostruct' | |
9 | require_relative 'buffer' | |
10 | require_relative 'windows' | |
11 | ||
12 | class IO | |
13 | def readline_nonblock | |
14 | buffer = "" | |
15 | buffer << read_nonblock(1) while buffer[-1] != "\n" | |
16 | buffer | |
17 | rescue IO::WaitReadable => blocking | |
18 | if (not buffer.empty?) | |
19 | ungetc(buffer) | |
20 | end | |
21 | raise blocking | |
22 | end | |
23 | end | |
24 | ||
25 | class OptParse | |
26 | def parse(args) | |
27 | ||
28 | options = OpenStruct.new() | |
29 | options.inifile = nil | |
30 | ||
31 | opt_parser = OptionParser.new() do |opts| | |
32 | ||
33 | opts.banner = "Usage: monitor [options]" | |
34 | opts.separator "" | |
35 | ||
36 | opts.on( '-f', "-f ini_file", "chose a different initialization file") do |ini| | |
37 | options.inifile = ini | |
38 | end | |
39 | end | |
40 | opt_parser.parse!(args) | |
41 | return options | |
42 | end | |
43 | end | |
44 | ||
45 | def find_ini(option_inifile) | |
46 | if(not option_inifile.nil?) | |
47 | inifile = option_inifile | |
48 | elsif(ENV.has_key?('MONITOR_RC')) | |
49 | inifile = ENV['MONITOR_RC'] | |
50 | elsif(Process.uid == 0) | |
51 | inifile = "/etc/monitor.rc" | |
52 | else | |
53 | inifile = ENV['HOME']+"/.monitorrc" | |
54 | end | |
55 | return inifile | |
56 | end | |
57 | ||
58 | def read_ini(ini) | |
59 | inifile = IniFile.load(ini) | |
60 | if(inifile.nil?) | |
61 | puts "Initialization file not found or not readable" | |
62 | exit | |
63 | end | |
64 | return inifile | |
65 | end | |
66 | ||
67 | def print_line(win, str, hscroll=0) | |
68 | revert_color = false | |
69 | str[0,5].match(/\033\[3(.)m/) { |c| #Line starts with an escape sequence. We handle that `a la xterm` | |
70 | Ncurses.init_pair(10, c[1].to_i, Ncurses::COLOR_BLACK) | |
71 | win.attron(Ncurses.COLOR_PAIR(10)) | |
72 | revert_color = true | |
73 | str = str[5,str.length] | |
74 | } | |
75 | str = str.gsub("\011"," ") | |
76 | #Any other control char is ignored and escaped | |
77 | str = str.gsub(/[[:cntrl:]]/) { |m| | |
78 | "^"+(m.ord + 64).chr | |
79 | } | |
80 | if(hscroll > 0) | |
81 | strcut = str[hscroll,str.length] | |
82 | if(strcut.nil? or strcut.empty?) | |
83 | str = "" | |
84 | else | |
85 | str = "…"+strcut | |
86 | end | |
87 | end | |
88 | strlen = str.length | |
89 | winlen = win.getmaxx-win.getcurx-1 | |
90 | if(strlen <= winlen) | |
91 | win.addstr(str + " "*(winlen-strlen)) | |
92 | else | |
93 | win.addstr(str[0,winlen-1]+"…") | |
94 | end | |
95 | if(revert_color) | |
96 | win.attroff(Ncurses.COLOR_PAIR(10)) | |
97 | end | |
98 | end | |
99 | ||
100 | def make_bufwins(inifile) | |
101 | bufwins = [] | |
102 | inifile.each_section do |section| | |
103 | bufwin = Buff_Win.new(Ncurses.COLS()-Ncurses.COLS()/4, | |
104 | Ncurses.COLS()/4, | |
105 | inifile[section]) | |
106 | bufwins.push(bufwin) | |
107 | end | |
108 | return bufwins | |
109 | end | |
110 | ||
111 | def update_buffers(bufwins) | |
112 | bufwins.each do |bufwin| | |
113 | bufwin.update() | |
114 | end | |
115 | end | |
116 | ||
117 | def redraw_all(list,bufwins,curr_bufwin) | |
118 | bufwins.each do |bufwin| | |
119 | bufwin.move_resize(Ncurses.COLS()-Ncurses.COLS()/4,Ncurses.COLS()/4) | |
120 | end | |
121 | list.resize(Ncurses.LINES(), Ncurses.COLS()/4) | |
122 | list.clear() | |
123 | list.print_list() | |
124 | list.refresh() | |
125 | curr_bufwin.refresh() | |
126 | end | |
127 | ||
128 | ||
129 | options = OptParse.new().parse(ARGV) | |
130 | inifile = read_ini(find_ini(options.inifile)) | |
131 | begin | |
132 | # initialize ncurses | |
133 | Ncurses.initscr | |
134 | Ncurses.start_color | |
135 | Ncurses.cbreak # provide unbuffered input | |
136 | Ncurses.noecho # turn off input echoing | |
137 | #Ncurses.nonl # turn off newline translation | |
138 | #Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt | |
139 | Ncurses.stdscr.keypad(true) # turn on keypad mode | |
140 | Ncurses.init_pair(1, Ncurses::COLOR_RED, Ncurses::COLOR_BLACK) | |
141 | Ncurses.init_pair(10, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK) | |
142 | ||
143 | ||
144 | list = List_Win.new(inifile) | |
145 | bufwins = make_bufwins(inifile) | |
146 | entry = 0 | |
147 | cur_bufwin = bufwins[entry] | |
148 | cur_bufwin.show_win() | |
149 | list.print_list() | |
150 | while(ch = list.getch()) do | |
151 | case(ch) | |
152 | when "n".ord | |
153 | entry = (entry +1) % bufwins.length | |
154 | cur_bufwin = bufwins[entry] | |
155 | cur_bufwin.show_win() | |
156 | list.print_list(entry=entry) | |
157 | when "p".ord | |
158 | entry = (entry -1) % bufwins.length | |
159 | cur_bufwin = bufwins[entry] | |
160 | cur_bufwin.show_win() | |
161 | list.print_list(entry=entry) | |
162 | when 12 #ctrl+L | |
163 | redraw_all(list,bufwins,cur_bufwin) | |
164 | when 18 #ctrl+R | |
165 | cur_bufwin.update(force=true) | |
166 | when Ncurses::KEY_RESIZE | |
167 | redraw_all(list,bufwins,cur_bufwin) | |
168 | when Ncurses::KEY_LEFT | |
169 | cur_bufwin.hscroll(scroll=-1) | |
170 | when Ncurses::KEY_RIGHT | |
171 | cur_bufwin.hscroll(scroll=1) | |
172 | when Ncurses::KEY_DOWN | |
173 | cur_bufwin.scroll(scroll=-1) | |
174 | when Ncurses::KEY_UP | |
175 | cur_bufwin.scroll(scroll=1) | |
176 | when Ncurses::KEY_NPAGE | |
177 | cur_bufwin.scroll(scroll=0,goto=nil,fact=-0.75) | |
178 | when Ncurses::KEY_PPAGE | |
179 | cur_bufwin.scroll(scroll=0,goto=nil,fact=0.75) | |
180 | when Ncurses::KEY_HOME | |
181 | cur_bufwin.scroll(scroll=0,goto=1.0) | |
182 | when Ncurses::KEY_END | |
183 | cur_bufwin.scroll(scroll=0,goto=0.0) | |
184 | when Ncurses::ERR | |
185 | update_buffers(bufwins) | |
186 | cur_bufwin.show_win() | |
187 | when "q".ord | |
188 | break | |
189 | else | |
190 | next | |
191 | end | |
192 | end | |
193 | ||
194 | ensure | |
195 | Ncurses.echo | |
196 | Ncurses.nocbreak | |
197 | Ncurses.nl | |
198 | Ncurses.endwin | |
199 | end |