]> git.rmz.io Git - dotfiles.git/blob - weechat/perl/buffers.pl
weechat: turn partial_completion_other on
[dotfiles.git] / weechat / perl / buffers.pl
1 #
2 # Copyright (C) 2008-2014 Sebastien Helleu <flashcode@flashtux.org>
3 # Copyright (C) 2011-2013 Nils G <weechatter@arcor.de>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #
18 #
19 # Display sidebar with list of buffers.
20 #
21 # History:
22 #
23 # 2014-01-01, Sebastien Helleu <flashcode@flashtux.org>:
24 # v4.5: add option "mouse_move_buffer"
25 # 2013-12-11, Sebastien Helleu <flashcode@flashtux.org>:
26 # v4.4: fix buffer number on drag to the end of list when option
27 # weechat.look.buffer_auto_renumber is off
28 # 2013-12-10, nils_2@freenode.#weechat:
29 # v4.3: add options "prefix_bufname" and "suffix_bufname (idea by silverd)
30 # : fix hook_timer() for show_lag wasn't disabled
31 # : improved signal handling (less updating of buffers list)
32 # 2013-11-07, Sebastien Helleu <flashcode@flashtux.org>:
33 # v4.2: use default filling "columns_vertical" when bar position is top/bottom
34 # 2013-10-31, nils_2@freenode.#weechat:
35 # v4.1: add option "detach_buffer_immediately" (idea by farn)
36 # 2013-10-20, nils_2@freenode.#weechat:
37 # v4.0: add options "detach_displayed_buffers", "detach_display_window_number"
38 # 2013-09-27, nils_2@freenode.#weechat:
39 # v3.9: add option "toggle_bar" and option "show_prefix_query" (idea by IvarB)
40 # : fix problem with linefeed at end of list of buffers (reported by grawity)
41 # 2012-10-18, nils_2@freenode.#weechat:
42 # v3.8: add option "mark_inactive", to mark buffers you are not in (idea by xrdodrx)
43 # : add wildcard "*" for immune_detach_buffers (idea by StarWeaver)
44 # : add new options "detach_query" and "detach_free_content" (idea by StarWeaver)
45 # 2012-10-06, Nei <anti.teamidiot.de>:
46 # v3.7: call menu on right mouse if menu script is loaded.
47 # 2012-10-06, nils_2 <weechatter@arcor.de>:
48 # v3.6: add new option "hotlist_counter" (idea by torque).
49 # 2012-06-02, nils_2 <weechatter@arcor.de>:
50 # v3.5: add values "server|channel|private|all|keepserver|none" to option "hide_merged_buffers" (suggested by dominikh).
51 # 2012-05-25, nils_2 <weechatter@arcor.de>:
52 # v3.4: add new option "show_lag".
53 # 2012-04-07, Sebastien Helleu <flashcode@flashtux.org>:
54 # v3.3: fix truncation of wide chars in buffer name (option name_size_max) (bug #36034)
55 # 2012-03-15, nils_2 <weechatter@arcor.de>:
56 # v3.2: add new option "detach"(weechat >= 0.3.8)
57 # add new option "immune_detach_buffers" (requested by Mkaysi)
58 # add new function buffers_whitelist add|del|reset (suggested by FiXato)
59 # add new function buffers_detach add|del|reset
60 # 2012-03-09, Sebastien Helleu <flashcode@flashtux.org>:
61 # v3.1: fix reload of config file
62 # 2012-01-29, nils_2 <weechatter@arcor.de>:
63 # v3.0: fix: buffers did not update directly during window_switch (reported by FiXato)
64 # 2012-01-29, nils_2 <weechatter@arcor.de>:
65 # v2.9: add options "name_size_max" and "name_crop_suffix"
66 # 2012-01-08, nils_2 <weechatter@arcor.de>:
67 # v2.8: fix indenting for option "show_number off"
68 # fix unset of buffer activity in hotlist when buffer was moved with mouse
69 # add buffer with free content and core buffer sorted first (suggested by nyuszika7h)
70 # add options queries_default_fg/bg and queries_message_fg/bg (suggested by FiXato)
71 # add clicking with left button on current buffer will do a jump_previously_visited_buffer (suggested by FiXato)
72 # add clicking with right button on current buffer will do a jump_next_visited_buffer
73 # add additional informations in help texts
74 # add default_fg and default_bg for whitelist channels
75 # internal changes (script is now 3Kb smaller)
76 # 2012-01-04, Sebastien Helleu <flashcode@flashtux.org>:
77 # v2.7: fix regex lookup in whitelist buffers list
78 # 2011-12-04, nils_2 <weechatter@arcor.de>:
79 # v2.6: add own config file (buffers.conf)
80 # add new behavior for indenting (under_name)
81 # add new option to set different color for server buffers and buffers with free content
82 # 2011-10-30, nils_2 <weechatter@arcor.de>:
83 # v2.5: add new options "show_number_char" and "color_number_char",
84 # add help-description for options
85 # 2011-08-24, Sebastien Helleu <flashcode@flashtux.org>:
86 # v2.4: add mouse support
87 # 2011-06-06, nils_2 <weechatter@arcor.de>:
88 # v2.3: added: missed option "color_whitelist_default"
89 # 2011-03-23, Sebastien Helleu <flashcode@flashtux.org>:
90 # v2.2: fix color of nick prefix with WeeChat >= 0.3.5
91 # 2011-02-13, nils_2 <weechatter@arcor.de>:
92 # v2.1: add options "color_whitelist_*"
93 # 2010-10-05, Sebastien Helleu <flashcode@flashtux.org>:
94 # v2.0: add options "sort" and "show_number"
95 # 2010-04-12, Sebastien Helleu <flashcode@flashtux.org>:
96 # v1.9: replace call to log() by length() to align buffer numbers
97 # 2010-04-02, Sebastien Helleu <flashcode@flashtux.org>:
98 # v1.8: fix bug with background color and option indenting_number
99 # 2010-04-02, Helios <helios@efemes.de>:
100 # v1.7: add indenting_number option
101 # 2010-02-25, m4v <lambdae2@gmail.com>:
102 # v1.6: add option to hide empty prefixes
103 # 2010-02-12, Sebastien Helleu <flashcode@flashtux.org>:
104 # v1.5: add optional nick prefix for buffers like IRC channels
105 # 2009-09-30, Sebastien Helleu <flashcode@flashtux.org>:
106 # v1.4: remove spaces for indenting when bar position is top/bottom
107 # 2009-06-14, Sebastien Helleu <flashcode@flashtux.org>:
108 # v1.3: add option "hide_merged_buffers"
109 # 2009-06-14, Sebastien Helleu <flashcode@flashtux.org>:
110 # v1.2: improve display with merged buffers
111 # 2009-05-02, Sebastien Helleu <flashcode@flashtux.org>:
112 # v1.1: sync with last API changes
113 # 2009-02-21, Sebastien Helleu <flashcode@flashtux.org>:
114 # v1.0: remove timer used to update bar item first time (not needed any more)
115 # 2009-02-17, Sebastien Helleu <flashcode@flashtux.org>:
116 # v0.9: fix bug with indenting of private buffers
117 # 2009-01-04, Sebastien Helleu <flashcode@flashtux.org>:
118 # v0.8: update syntax for command /set (comments)
119 # 2008-10-20, Jiri Golembiovsky <golemj@gmail.com>:
120 # v0.7: add indenting option
121 # 2008-10-01, Sebastien Helleu <flashcode@flashtux.org>:
122 # v0.6: add default color for buffers, and color for current active buffer
123 # 2008-09-18, Sebastien Helleu <flashcode@flashtux.org>:
124 # v0.5: fix color for "low" level entry in hotlist
125 # 2008-09-18, Sebastien Helleu <flashcode@flashtux.org>:
126 # v0.4: rename option "show_category" to "short_names",
127 # remove option "color_slash"
128 # 2008-09-15, Sebastien Helleu <flashcode@flashtux.org>:
129 # v0.3: fix bug with priority in hotlist (var not defined)
130 # 2008-09-02, Sebastien Helleu <flashcode@flashtux.org>:
131 # v0.2: add color for buffers with activity and config options for
132 # colors, add config option to display/hide categories
133 # 2008-03-15, Sebastien Helleu <flashcode@flashtux.org>:
134 # v0.1: script creation
135 #
136 # Help about settings:
137 # display all settings for script (or use iset.pl script to change settings):
138 # /set buffers*
139 # show help text for option buffers.look.whitelist_buffers:
140 # /help buffers.look.whitelist_buffers
141 #
142 # Mouse-support (standard key bindings):
143 # left mouse-button:
144 # - click on a buffer to switch to selected buffer
145 # - click on current buffer will do action jump_previously_visited_buffer
146 # - drag a buffer and drop it on another position will move the buffer to position
147 # right mouse-button:
148 # - click on current buffer will do action jump_next_visited_buffer
149 # - moving buffer to the left/right will close buffer.
150 #
151
152 use strict;
153 use Encode qw( decode encode );
154 # -------------------------------[ internal ]-------------------------------------
155 my $SCRIPT_NAME = "buffers";
156 my $SCRIPT_VERSION = "4.5";
157
158 my $BUFFERS_CONFIG_FILE_NAME = "buffers";
159 my $buffers_config_file;
160 my $cmd_buffers_whitelist= "buffers_whitelist";
161 my $cmd_buffers_detach = "buffers_detach";
162
163 my %mouse_keys = ("\@item(buffers):button1*" => "hsignal:buffers_mouse", # catch all left mouse button gestures
164 "\@item(buffers):button2*" => "hsignal:buffers_mouse"); # catch all right mouse button gestures
165 my %options;
166 my %hotlist_level = (0 => "low", 1 => "message", 2 => "private", 3 => "highlight");
167 my @whitelist_buffers = ();
168 my @immune_detach_buffers= ();
169 my @detach_buffer_immediately= ();
170 my @buffers_focus = ();
171 my %buffers_timer = ();
172 my %Hooks = ();
173
174 # --------------------------------[ init ]--------------------------------------
175 weechat::register($SCRIPT_NAME, "Sebastien Helleu <flashcode\@flashtux.org>", $SCRIPT_VERSION,
176 "GPL3", "Sidebar with list of buffers", "shutdown_cb", "");
177 my $weechat_version = weechat::info_get("version_number", "") || 0;
178
179 buffers_config_init();
180 buffers_config_read();
181
182 weechat::bar_item_new($SCRIPT_NAME, "build_buffers", "");
183 weechat::bar_new($SCRIPT_NAME, "0", "0", "root", "", "left", "columns_vertical",
184 "vertical", "0", "0", "default", "default", "default", "1",
185 $SCRIPT_NAME);
186
187 if ( check_bar_item() == 0 )
188 {
189 weechat::command("","/bar show " . $SCRIPT_NAME) if ( weechat::config_boolean($options{"toggle_bar"}) eq 1 );
190 }
191
192 weechat::hook_signal("buffer_opened", "buffers_signal_buffer", "");
193 weechat::hook_signal("buffer_closed", "buffers_signal_buffer", "");
194 weechat::hook_signal("buffer_merged", "buffers_signal_buffer", "");
195 weechat::hook_signal("buffer_unmerged", "buffers_signal_buffer", "");
196 weechat::hook_signal("buffer_moved", "buffers_signal_buffer", "");
197 weechat::hook_signal("buffer_renamed", "buffers_signal_buffer", "");
198 weechat::hook_signal("buffer_switch", "buffers_signal_buffer", "");
199
200 weechat::hook_signal("window_switch", "buffers_signal_buffer", "");
201 weechat::hook_signal("hotlist_changed", "buffers_signal_hotlist", "");
202 #weechat::hook_command_run("/input switch_active_*", "buffers_signal_buffer", "");
203 weechat::bar_item_update($SCRIPT_NAME);
204
205
206 if ($weechat_version >= 0x00030600)
207 {
208 weechat::hook_focus($SCRIPT_NAME, "buffers_focus_buffers", "");
209 weechat::hook_hsignal("buffers_mouse", "buffers_hsignal_mouse", "");
210 weechat::key_bind("mouse", \%mouse_keys);
211 }
212
213 weechat::hook_command( $cmd_buffers_whitelist,
214 "add/del current buffer to/from buffers whitelist",
215 "[add] || [del] || [reset]",
216
217 " add: add current buffer in configuration file\n".
218 " del: delete current buffer from configuration file\n".
219 "reset: reset all buffers from configuration file (no confirmation!)\n\n".
220 "Examples:\n".
221 "/$cmd_buffers_whitelist add\n",
222 "add %-||".
223 "del %-||".
224 "reset %-",
225 "buffers_cmd_whitelist", "");
226 weechat::hook_command( $cmd_buffers_detach,
227 "add/del current buffer to/from buffers detach",
228 "[add] || [del] || [reset]",
229
230 " add: add current buffer in configuration file\n".
231 " del: delete current buffer from configuration file\n".
232 "reset: reset all buffers from configuration file (no confirmation!)\n\n".
233 "Examples:\n".
234 "/$cmd_buffers_detach add\n",
235 "add %-||".
236 "del %-||".
237 "reset %-",
238 "buffers_cmd_detach", "");
239
240 if ($weechat_version >= 0x00030800)
241 {
242 weechat::hook_config("buffers.look.detach", "hook_timer_detach", "");
243 $Hooks{timer_detach} = weechat::hook_timer( weechat::config_integer( $options{"detach"}) * 1000, 60, 0, "buffers_signal_hotlist", "") if ( weechat::config_integer( $options{"detach"}) > 0 );
244 }
245
246 weechat::hook_config("buffers.look.show_lag", "hook_timer_lag", "");
247
248 $Hooks{timer_lag} = weechat::hook_timer( weechat::config_integer(weechat::config_get("irc.network.lag_refresh_interval")) * 1000, 0, 0, "buffers_signal_hotlist", "") if ( weechat::config_boolean($options{"show_lag"}) );
249
250 # -------------------------------- [ command ] --------------------------------
251 sub buffers_cmd_whitelist
252 {
253 my ( $data, $buffer, $args ) = @_;
254 $args = lc($args);
255 my $buffers_whitelist = weechat::config_string( weechat::config_get("buffers.look.whitelist_buffers") );
256 return weechat::WEECHAT_RC_OK if ( $buffers_whitelist eq "" and $args eq "del" or $buffers_whitelist eq "" and $args eq "reset" );
257 my @buffers_list = split( /,/, $buffers_whitelist );
258 # get buffers name
259 my $infolist = weechat::infolist_get("buffer", weechat::current_buffer(), "");
260 weechat::infolist_next($infolist);
261 my $buffers_name = weechat::infolist_string($infolist, "name");
262 weechat::infolist_free($infolist);
263 return weechat::WEECHAT_RC_OK if ( $buffers_name eq "" ); # should never happen
264
265 if ( $args eq "add" )
266 {
267 return weechat::WEECHAT_RC_OK if ( grep /^$buffers_name$/, @buffers_list ); # check if buffer already in list
268 push @buffers_list,( $buffers_name );
269 my $buffers_list = &create_whitelist(\@buffers_list);
270 weechat::config_option_set( weechat::config_get("buffers.look.whitelist_buffers"), $buffers_list,1 );
271 weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" added to buffers whitelist");
272 }
273 elsif ( $args eq "del" )
274 {
275 return weechat::WEECHAT_RC_OK unless ( grep /^$buffers_name$/, @buffers_list ); # check if buffer is in list
276 @buffers_list = grep {$_ ne $buffers_name} @buffers_list; # delete entry
277 my $buffers_list = &create_whitelist(\@buffers_list);
278 weechat::config_option_set( weechat::config_get("buffers.look.whitelist_buffers"), $buffers_list,1 );
279 weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" deleted from buffers whitelist");
280 }
281 elsif ( $args eq "reset" )
282 {
283 return weechat::WEECHAT_RC_OK if ( $buffers_whitelist eq "" );
284 weechat::config_option_set( weechat::config_get("buffers.look.whitelist_buffers"), "",1 );
285 weechat::print(weechat::current_buffer(), "buffers whitelist is empty, now...");
286 }
287 return weechat::WEECHAT_RC_OK;
288 }
289 sub buffers_cmd_detach
290 {
291 my ( $data, $buffer, $args ) = @_;
292 $args = lc($args);
293 my $immune_detach_buffers = weechat::config_string( weechat::config_get("buffers.look.immune_detach_buffers") );
294 return weechat::WEECHAT_RC_OK if ( $immune_detach_buffers eq "" and $args eq "del" or $immune_detach_buffers eq "" and $args eq "reset" );
295
296 my @buffers_list = split( /,/, $immune_detach_buffers );
297 # get buffers name
298 my $infolist = weechat::infolist_get("buffer", weechat::current_buffer(), "");
299 weechat::infolist_next($infolist);
300 my $buffers_name = weechat::infolist_string($infolist, "name");
301 weechat::infolist_free($infolist);
302 return weechat::WEECHAT_RC_OK if ( $buffers_name eq "" ); # should never happen
303
304 if ( $args eq "add" )
305 {
306 return weechat::WEECHAT_RC_OK if ( grep /^$buffers_name$/, @buffers_list ); # check if buffer already in list
307 push @buffers_list,( $buffers_name );
308 my $buffers_list = &create_whitelist(\@buffers_list);
309 weechat::config_option_set( weechat::config_get("buffers.look.immune_detach_buffers"), $buffers_list,1 );
310 weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" added to immune detach buffers");
311 }
312 elsif ( $args eq "del" )
313 {
314 return weechat::WEECHAT_RC_OK unless ( grep /^$buffers_name$/, @buffers_list ); # check if buffer is in list
315 @buffers_list = grep {$_ ne $buffers_name} @buffers_list; # delete entry
316 my $buffers_list = &create_whitelist(\@buffers_list);
317 weechat::config_option_set( weechat::config_get("buffers.look.immune_detach_buffers"), $buffers_list,1 );
318 weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" deleted from immune detach buffers");
319 }
320 elsif ( $args eq "reset" )
321 {
322 return weechat::WEECHAT_RC_OK if ( $immune_detach_buffers eq "" );
323 weechat::config_option_set( weechat::config_get("buffers.look.immune_detach_buffers"), "",1 );
324 weechat::print(weechat::current_buffer(), "immune detach buffers is empty, now...");
325 }
326 return weechat::WEECHAT_RC_OK;
327 }
328
329 sub create_whitelist
330 {
331 my @buffers_list = @{$_[0]};
332 my $buffers_list = "";
333 foreach (@buffers_list)
334 {
335 $buffers_list .= $_ .",";
336 }
337 chop $buffers_list; # remove last ","
338 return $buffers_list;
339 }
340
341 # -------------------------------- [ config ] --------------------------------
342 sub hook_timer_detach
343 {
344 my $detach = $_[2];
345 if ( $detach eq 0 )
346 {
347 weechat::unhook($Hooks{timer_detach}) if $Hooks{timer_detach};
348 $Hooks{timer_detach} = "";
349 }
350 else
351 {
352 weechat::unhook($Hooks{timer_detach}) if $Hooks{timer_detach};
353 $Hooks{timer_detach} = weechat::hook_timer( weechat::config_integer( $options{"detach"}) * 1000, 60, 0, "buffers_signal_hotlist", "");
354 }
355 weechat::bar_item_update($SCRIPT_NAME);
356 return weechat::WEECHAT_RC_OK;
357 }
358
359 sub hook_timer_lag
360 {
361 my $lag = $_[2];
362 if ( $lag eq "off" )
363 {
364 weechat::unhook($Hooks{timer_lag}) if $Hooks{timer_lag};
365 $Hooks{timer_lag} = "";
366 }
367 else
368 {
369 weechat::unhook($Hooks{timer_lag}) if $Hooks{timer_lag};
370 $Hooks{timer_lag} = weechat::hook_timer( weechat::config_integer(weechat::config_get("irc.network.lag_refresh_interval")) * 1000, 0, 0, "buffers_signal_hotlist", "");
371 }
372 weechat::bar_item_update($SCRIPT_NAME);
373 return weechat::WEECHAT_RC_OK;
374 }
375
376 sub buffers_config_read
377 {
378 return weechat::config_read($buffers_config_file) if ($buffers_config_file ne "");
379 }
380 sub buffers_config_write
381 {
382 return weechat::config_write($buffers_config_file) if ($buffers_config_file ne "");
383 }
384 sub buffers_config_reload_cb
385 {
386 my ($data,$config_file) = ($_[0], $_[1]);
387 return weechat::config_reload($config_file)
388 }
389 sub buffers_config_init
390 {
391 $buffers_config_file = weechat::config_new($BUFFERS_CONFIG_FILE_NAME,"buffers_config_reload_cb","");
392 return if ($buffers_config_file eq "");
393
394 my %default_options_color =
395 ("color_current_fg" => ["current_fg", "color", "foreground color for current buffer", "", 0, 0, "lightcyan", "lightcyan", 0, "", "", "buffers_signal_config", "", "", ""],
396 "color_current_bg" => ["current_bg", "color", "background color for current buffer", "", 0, 0, "red", "red", 0, "", "", "buffers_signal_config", "", "", ""],
397 "color_default_fg" => ["default_fg", "color", "default foreground color for buffer name", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
398 "color_default_bg" => ["default_bg", "color", "default background color for buffer name", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
399 "color_hotlist_highlight_fg" => ["hotlist_highlight_fg", "color", "change foreground color of buffer name if a highlight messaged received", "", 0, 0, "magenta", "magenta", 0, "", "", "buffers_signal_config", "", "", ""],
400 "color_hotlist_highlight_bg" => ["hotlist_highlight_bg", "color", "change background color of buffer name if a highlight messaged received", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
401 "color_hotlist_low_fg" => ["hotlist_low_fg", "color", "change foreground color of buffer name if a low message received", "", 0, 0, "white", "white", 0, "", "", "buffers_signal_config", "", "", ""],
402 "color_hotlist_low_bg" => ["hotlist_low_bg", "color", "change background color of buffer name if a low message received", "", 0, 0,
403 "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
404 "color_hotlist_message_fg" => ["hotlist_message_fg", "color", "change foreground color of buffer name if a normal message received", "", 0, 0, "yellow", "yellow", 0, "", "", "buffers_signal_config", "", "", ""],
405 "color_hotlist_message_bg" => ["hotlist_message_bg", "color", "change background color of buffer name if a normal message received", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
406 "color_hotlist_private_fg" => ["hotlist_private_fg", "color", "change foreground color of buffer name if a private message received", "", 0, 0, "lightgreen", "lightgreen", 0, "", "", "buffers_signal_config", "", "", ""],
407 "color_hotlist_private_bg" => ["hotlist_private_bg", "color", "change background color of buffer name if a private message received", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
408 "color_number" => ["number", "color", "color for buffer number", "", 0, 0, "lightgreen", "lightgreen", 0, "", "", "buffers_signal_config", "", "", ""],
409 "color_number_char" => ["number_char", "color", "color for buffer number char", "", 0, 0, "lightgreen", "lightgreen", 0, "", "", "buffers_signal_config", "", "", ""],
410 "color_whitelist_default_fg" => ["whitelist_default_fg", "color", "default foreground color for whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
411 "color_whitelist_default_bg" => ["whitelist_default_bg", "color", "default background color for whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
412 "color_whitelist_low_fg" => ["whitelist_low_fg", "color", "low color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
413 "color_whitelist_low_bg" => ["whitelist_low_bg", "color", "low color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
414 "color_whitelist_message_fg" => ["whitelist_message_fg", "color", "message color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
415 "color_whitelist_message_bg" => ["whitelist_message_bg", "color", "message color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
416 "color_whitelist_private_fg" => ["whitelist_private_fg", "color", "private color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
417 "color_whitelist_private_bg" => ["whitelist_private_bg", "color", "private color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
418 "color_whitelist_highlight_fg" => ["whitelist_highlight_fg", "color", "highlight color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
419 "color_whitelist_highlight_bg" => ["whitelist_highlight_bg", "color", "highlight color of whitelist buffer name", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
420 "color_none_channel_fg" => ["none_channel_fg", "color", "foreground color for none channel buffer (e.g.: core/server/plugin buffer)", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
421 "color_none_channel_bg" => ["none_channel_bg", "color", "background color for none channel buffer (e.g.: core/server/plugin buffer)", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
422 "queries_default_fg" => ["queries_default_fg", "color", "foreground color for query buffer without message", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
423 "queries_default_bg" => ["queries_default_bg", "color", "background color for query buffer without message", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
424 "queries_message_fg" => ["queries_message_fg", "color", "foreground color for query buffer with unread message", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
425 "queries_message_bg" => ["queries_message_bg", "color", "background color for query buffer with unread message", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
426 "queries_highlight_fg" => ["queries_highlight_fg", "color", "foreground color for query buffer with unread highlight", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
427 "queries_highlight_bg" => ["queries_highlight_bg", "color", "background color for query buffer with unread highlight", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
428 "color_prefix_bufname" => ["prefix_bufname", "color", "color for prefix of buffer name", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
429 "color_suffix_bufname" => ["suffix_bufname", "color", "color for suffix of buffer name", "", 0, 0, "default", "default", 0, "", "", "buffers_signal_config", "", "", ""],
430 );
431
432 my %default_options_look =
433 (
434 "hotlist_counter" => ["hotlist_counter", "boolean", "show number of message for the buffer (this option needs WeeChat >= 0.3.5). The relevant option for notification is \"weechat.look.buffer_notify_default\"", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
435 "show_lag" => ["show_lag", "boolean", "show lag behind servername. This option is using \"irc.color.item_lag_finished\", \"irc.network.lag_min_show\" and \"irc.network.lag_refresh_interval\"", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
436 "look_whitelist_buffers" => ["whitelist_buffers", "string", "comma separated list of buffers for using a differnt color scheme (for example: freenode.#weechat,freenode.#weechat-fr)", "", 0, 0, "", "", 0, "", "", "buffers_signal_config_whitelist", "", "", ""],
437 "hide_merged_buffers" => ["hide_merged_buffers", "integer", "hide merged buffers. The value determines which merged buffers should be hidden, keepserver meaning 'all except server buffers'. Other values correspondent to the buffer type.", "server|channel|private|keepserver|all|none", 0, 0, "none", "none", 0, "", "", "buffers_signal_config", "", "", ""],
438 "indenting" => ["indenting", "integer", "use indenting for channel and query buffers. This option only takes effect if bar is left/right positioned", "off|on|under_name", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
439 "indenting_number" => ["indenting_number", "boolean", "use indenting for numbers. This option only takes effect if bar is left/right positioned", "", 0, 0, "on", "on", 0, "", "", "buffers_signal_config", "", "", ""],
440 "short_names" => ["short_names", "boolean", "display short names (remove text before first \".\" in buffer name)", "", 0, 0, "on", "on", 0, "", "", "buffers_signal_config", "", "", ""],
441 "show_number" => ["show_number", "boolean", "display channel number in front of buffername", "", 0, 0, "on", "on", 0, "", "", "buffers_signal_config", "", "", ""],
442 "show_number_char" => ["number_char", "string", "display a char behind channel number", "", 0, 0, ".", ".", 0, "", "", "buffers_signal_config", "", "", ""],
443 "show_prefix_bufname" => ["prefix_bufname", "string", "prefix displayed in front of buffername", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
444 "show_suffix_bufname" => ["suffix_bufname", "string", "suffix displayed at end of buffername", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
445 "show_prefix" => ["prefix", "boolean", "displays your prefix for channel in front of buffername", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
446 "show_prefix_empty" => ["prefix_empty", "boolean", "use a placeholder for channels without prefix", "", 0, 0, "on", "on", 0, "", "", "buffers_signal_config", "", "", ""],
447 "show_prefix_query" => ["prefix_for_query", "string", "prefix displayed in front of query buffer", "", 0, 0, "", "", 0, "", "", "buffers_signal_config", "", "", ""],
448 "sort" => ["sort", "integer", "sort buffer-list by \"number\" or \"name\"", "number|name", 0, 0, "number", "number", 0, "", "", "buffers_signal_config", "", "", ""],
449 "core_to_front" => ["core_to_front", "boolean", "core buffer and buffers with free content will be listed first. Take only effect if buffer sort is by name", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
450 "jump_prev_next_visited_buffer" => ["jump_prev_next_visited_buffer", "boolean", "jump to previously or next visited buffer if you click with left/right mouse button on currently visiting buffer", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
451 "name_size_max" => ["name_size_max", "integer", "maximum size of buffer name. 0 means no limitation", "", 0, 256, 0, 0, 0, "", "", "buffers_signal_config", "", "", ""],
452 "name_crop_suffix" => ["name_crop_suffix", "string", "contains an optional char(s) that is appended when buffer name is shortened", "", 0, 0, "+", "+", 0, "", "", "buffers_signal_config", "", "", ""],
453 "detach" => ["detach", "integer", "detach channel from buffers list after a specific period of time (in seconds) without action (weechat ≥ 0.3.8 required) (0 means \"off\")", "", 0, 31536000, 0, "number", 0, "", "", "buffers_signal_config", "", "", ""],
454 "immune_detach_buffers" => ["immune_detach_buffers", "string", "comma separated list of buffers to NOT automatically detatch. Allows \"*\" wildcard. Ex: \"BitlBee,freenode.*\"", "", 0, 0, "", "", 0, "", "", "buffers_signal_config_immune_detach_buffers", "", "", ""],
455 "detach_query" => ["detach_query", "boolean", "query buffer will be detachted", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
456 "detach_buffer_immediately" => ["detach_buffer_immediately", "string", "comma separated list of buffers to detach immediately. A query and highlight message will attach buffer again. Allows \"*\" wildcard. Ex: \"BitlBee,freenode.*\"", "", 0, 0, "", "", 0, "", "", "buffers_signal_config_detach_buffer_immediately", "", "", ""],
457 "detach_free_content" => ["detach_free_content", "boolean", "buffers with free content will be detached (Ex: iset, chanmon)", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
458 "detach_displayed_buffers" => ["detach_displayed_buffers", "boolean", "buffers displayed in a (split) window will be detached", "", 0, 0, "on", "on", 0, "", "", "buffers_signal_config", "", "", ""],
459 "detach_display_window_number" => ["detach_display_window_number", "boolean", "window number will be add, behind buffer name (this option takes only effect with \"detach_displayed_buffers\" option)", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
460 "mark_inactive" => ["mark_inactive", "boolean", "if option is \"on\", inactive buffers (those you are not in) will have parentesis around them. An inactive buffer will not be detached.", "", 0, 0, "off", "off", 0, "", "", "buffers_signal_config", "", "", ""],
461 "toggle_bar" => ["toogle_bar", "boolean", "if option is \"on\", buffers bar will hide/show when script is (un)loaded.", "", 0, 0, "on", "on", 0, "", "", "buffers_signal_config", "", "", ""],
462 "mouse_move_buffer" => ["mouse_move_buffer", "boolean", "if option is \"on\", mouse gestures (drag & drop) can move buffers in list.", "", 0, 0, "on", "on", 0, "", "", "buffers_signal_config", "", "", ""],
463 );
464 # section "color"
465 my $section_color = weechat::config_new_section($buffers_config_file,"color", 0, 0, "", "", "", "", "", "", "", "", "", "");
466 if ($section_color eq "")
467 {
468 weechat::config_free($buffers_config_file);
469 return;
470 }
471 foreach my $option (keys %default_options_color)
472 {
473 $options{$option} = weechat::config_new_option($buffers_config_file, $section_color,
474 $default_options_color{$option}[0],$default_options_color{$option}[1],$default_options_color{$option}[2],
475 $default_options_color{$option}[3],$default_options_color{$option}[4],$default_options_color{$option}[5],
476 $default_options_color{$option}[6],$default_options_color{$option}[7],$default_options_color{$option}[8],
477 $default_options_color{$option}[9],$default_options_color{$option}[10],$default_options_color{$option}[11],
478 $default_options_color{$option}[12],$default_options_color{$option}[13],$default_options_color{$option}[14]);
479 }
480
481 # section "look"
482 my $section_look = weechat::config_new_section($buffers_config_file,"look", 0, 0, "", "", "", "", "", "", "", "", "", "");
483 if ($section_look eq "")
484 {
485 weechat::config_free($buffers_config_file);
486 return;
487 }
488 foreach my $option (keys %default_options_look)
489 {
490 $options{$option} = weechat::config_new_option($buffers_config_file, $section_look,
491 $default_options_look{$option}[0],$default_options_look{$option}[1],$default_options_look{$option}[2],
492 $default_options_look{$option}[3],$default_options_look{$option}[4],$default_options_look{$option}[5],
493 $default_options_look{$option}[6],$default_options_look{$option}[7],$default_options_look{$option}[8],
494 $default_options_look{$option}[9],$default_options_look{$option}[10],$default_options_look{$option}[11],
495 $default_options_look{$option}[12],$default_options_look{$option}[13],$default_options_look{$option}[14],
496 $default_options_look{$option}[15]);
497 }
498 }
499
500 sub build_buffers
501 {
502 my $str = "";
503
504 # get bar position (left/right/top/bottom)
505 my $position = "left";
506 my $option_position = weechat::config_get("weechat.bar.buffers.position");
507 if ($option_position ne "")
508 {
509 $position = weechat::config_string($option_position);
510 }
511
512 # read hotlist
513 my %hotlist;
514 my $infolist = weechat::infolist_get("hotlist", "", "");
515 while (weechat::infolist_next($infolist))
516 {
517 $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")} =
518 weechat::infolist_integer($infolist, "priority");
519 if ( weechat::config_boolean( $options{"hotlist_counter"} ) eq 1 and $weechat_version >= 0x00030500)
520 {
521 $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_00"} =
522 weechat::infolist_integer($infolist, "count_00"); # low message
523 $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_01"} =
524 weechat::infolist_integer($infolist, "count_01"); # channel message
525 $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_02"} =
526 weechat::infolist_integer($infolist, "count_02"); # private message
527 $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_03"} =
528 weechat::infolist_integer($infolist, "count_03"); # highlight message
529 }
530 }
531 weechat::infolist_free($infolist);
532
533 # read buffers list
534 @buffers_focus = ();
535 my @buffers;
536 my @current1 = ();
537 my @current2 = ();
538 my $old_number = -1;
539 my $max_number = 0;
540 my $max_number_digits = 0;
541 my $active_seen = 0;
542 $infolist = weechat::infolist_get("buffer", "", "");
543 while (weechat::infolist_next($infolist))
544 {
545 my $buffer;
546 my $number = weechat::infolist_integer($infolist, "number");
547 if ($number ne $old_number)
548 {
549 @buffers = (@buffers, @current2, @current1);
550 @current1 = ();
551 @current2 = ();
552 $active_seen = 0;
553 }
554 if ($number > $max_number)
555 {
556 $max_number = $number;
557 }
558 $old_number = $number;
559 my $active = weechat::infolist_integer($infolist, "active");
560 if ($active)
561 {
562 $active_seen = 1;
563 }
564 $buffer->{"pointer"} = weechat::infolist_pointer($infolist, "pointer");
565 $buffer->{"number"} = $number;
566 $buffer->{"active"} = $active;
567 $buffer->{"current_buffer"} = weechat::infolist_integer($infolist, "current_buffer");
568 $buffer->{"num_displayed"} = weechat::infolist_integer($infolist, "num_displayed");
569 $buffer->{"plugin_name"} = weechat::infolist_string($infolist, "plugin_name");
570 $buffer->{"name"} = weechat::infolist_string($infolist, "name");
571 $buffer->{"short_name"} = weechat::infolist_string($infolist, "short_name");
572 $buffer->{"full_name"} = $buffer->{"plugin_name"}.".".$buffer->{"name"};
573 $buffer->{"type"} = weechat::buffer_get_string($buffer->{"pointer"},"localvar_type");
574 # weechat::print("",$buffer->{"type"});
575
576 # check if buffer is active (or maybe a /part, /kick channel)
577 if ($buffer->{"type"} eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1)
578 {
579 my $server = weechat::buffer_get_string($buffer->{"pointer"},"localvar_server");
580 my $channel = weechat::buffer_get_string($buffer->{"pointer"},"localvar_channel");
581 my $infolist_channel = weechat::infolist_get("irc_channel","",$server.",".$channel);
582 if ($infolist_channel)
583 {
584 weechat::infolist_next($infolist_channel);
585 $buffer->{"nicks_count"} = weechat::infolist_integer($infolist_channel,"nicks_count");
586 }else
587 {
588 $buffer->{"nicks_count"} = 0;
589 }
590 weechat::infolist_free($infolist_channel);
591 }
592
593 my $result = check_immune_detached_buffers($buffer->{"name"}); # checking for wildcard
594
595 next if ( check_detach_buffer_immediately($buffer->{"name"}) eq 1
596 and $buffer->{"current_buffer"} eq 0
597 and ( not exists $hotlist{$buffer->{"pointer"}} or $hotlist{$buffer->{"pointer"}} < 2) ); # checking for buffer to immediately detach
598
599 unless ($result)
600 {
601 my $detach_time = weechat::config_integer( $options{"detach"});
602 my $current_time = time();
603 # set timer for buffers with no hotlist action
604 $buffers_timer{$buffer->{"pointer"}} = $current_time
605 if ( not exists $hotlist{$buffer->{"pointer"}}
606 and $buffer->{"type"} eq "channel"
607 and not exists $buffers_timer{$buffer->{"pointer"}}
608 and $detach_time > 0);
609
610 $buffers_timer{$buffer->{"pointer"}} = $current_time
611 if (weechat::config_boolean($options{"detach_query"}) eq 1
612 and not exists $hotlist{$buffer->{"pointer"}}
613 and $buffer->{"type"} eq "private"
614 and not exists $buffers_timer{$buffer->{"pointer"}}
615 and $detach_time > 0);
616
617 $detach_time = 0
618 if (weechat::config_boolean($options{"detach_query"}) eq 0
619 and $buffer->{"type"} eq "private");
620
621 # free content buffer
622 $buffers_timer{$buffer->{"pointer"}} = $current_time
623 if (weechat::config_boolean($options{"detach_free_content"}) eq 1
624 and not exists $hotlist{$buffer->{"pointer"}}
625 and $buffer->{"type"} eq ""
626 and not exists $buffers_timer{$buffer->{"pointer"}}
627 and $detach_time > 0);
628 $detach_time = 0
629 if (weechat::config_boolean($options{"detach_free_content"}) eq 0
630 and $buffer->{"type"} eq "");
631
632 $detach_time = 0 if (weechat::config_boolean($options{"mark_inactive"}) eq 1 and defined $buffer->{"nicks_count"} and $buffer->{"nicks_count"} == 0);
633
634 # check for detach
635 unless ( $buffer->{"current_buffer"} eq 0
636 and not exists $hotlist{$buffer->{"pointer"}}
637 # and $buffer->{"type"} eq "channel"
638 and exists $buffers_timer{$buffer->{"pointer"}}
639 and $detach_time > 0
640 and $weechat_version >= 0x00030800
641 and $current_time - $buffers_timer{$buffer->{"pointer"}} >= $detach_time)
642 {
643 if ($active_seen)
644 {
645 push(@current2, $buffer);
646 }
647 else
648 {
649 push(@current1, $buffer);
650 }
651 }
652 elsif ( $buffer->{"current_buffer"} eq 0
653 and not exists $hotlist{$buffer->{"pointer"}}
654 # and $buffer->{"type"} eq "channel"
655 and exists $buffers_timer{$buffer->{"pointer"}}
656 and $detach_time > 0
657 and $weechat_version >= 0x00030800
658 and $current_time - $buffers_timer{$buffer->{"pointer"}} >= $detach_time)
659 { # check for option detach_displayed_buffers and if buffer is displayed in a split window
660 if ( $buffer->{"num_displayed"} eq 1
661 and weechat::config_boolean($options{"detach_displayed_buffers"}) eq 0 )
662 {
663 my $infolist_window = weechat::infolist_get("window","","");
664 while (weechat::infolist_next($infolist_window))
665 {
666 my $buffer_ptr = weechat::infolist_pointer($infolist_window, "buffer");
667 if ($buffer_ptr eq $buffer->{"pointer"})
668 {
669 $buffer->{"window"} = weechat::infolist_integer($infolist_window, "number");
670 }
671 }
672 weechat::infolist_free($infolist_window);
673
674 push(@current2, $buffer);
675 }
676 }
677 }
678 else # buffer in "immune_detach_buffers"
679 {
680 if ($active_seen)
681 {
682 push(@current2, $buffer);
683 }
684 else
685 {
686 push(@current1, $buffer);
687 }
688 }
689 } # while end
690
691
692 if ($max_number >= 1)
693 {
694 $max_number_digits = length(int($max_number));
695 }
696 @buffers = (@buffers, @current2, @current1);
697 weechat::infolist_free($infolist);
698
699 # sort buffers by number, name or shortname
700 my %sorted_buffers;
701 if (1)
702 {
703 my $number = 0;
704 for my $buffer (@buffers)
705 {
706 my $key;
707 if (weechat::config_integer( $options{"sort"} ) eq 1) # number = 0; name = 1
708 {
709 my $name = $buffer->{"name"};
710 $name = $buffer->{"short_name"} if (weechat::config_boolean( $options{"short_names"} ) eq 1);
711 if (weechat::config_integer($options{"name_size_max"}) >= 1){
712 $name = encode("UTF-8", substr(decode("UTF-8", $name), 0, weechat::config_integer($options{"name_size_max"})));
713 }
714 if ( weechat::config_boolean($options{"core_to_front"}) eq 1)
715 {
716 if ( (weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "channel" ) and ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "private") )
717 {
718 my $type = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type");
719 if ( $type eq "" and $name ne "weechat")
720 {
721 $name = " " . $name
722 }else
723 {
724 $name = " " . $name;
725 }
726 }
727 }
728 $key = sprintf("%s%08d", lc($name), $buffer->{"number"});
729 }
730 else
731 {
732 $key = sprintf("%08d", $number);
733 }
734 $sorted_buffers{$key} = $buffer;
735 $number++;
736 }
737 }
738
739 # build string with buffers
740 $old_number = -1;
741 foreach my $key (sort keys %sorted_buffers)
742 {
743 my $buffer = $sorted_buffers{$key};
744
745 if ( weechat::config_string($options{"hide_merged_buffers"}) eq "server" )
746 {
747 # buffer type "server" or merged with core?
748 if ( ($buffer->{"type"} eq "server" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) )
749 {
750 next;
751 }
752 }
753 if ( weechat::config_string($options{"hide_merged_buffers"}) eq "channel" )
754 {
755 # buffer type "channel" or merged with core?
756 if ( ($buffer->{"type"} eq "channel" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) )
757 {
758 next;
759 }
760 }
761 if ( weechat::config_string($options{"hide_merged_buffers"}) eq "private" )
762 {
763 # buffer type "private" or merged with core?
764 if ( ($buffer->{"type"} eq "private" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) )
765 {
766 next;
767 }
768 }
769 if ( weechat::config_string($options{"hide_merged_buffers"}) eq "keepserver" )
770 {
771 if ( ($buffer->{"type"} ne "server" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) )
772 {
773 next;
774 }
775 }
776 if ( weechat::config_string($options{"hide_merged_buffers"}) eq "all" )
777 {
778 if ( ! $buffer->{"active"} )
779 {
780 next;
781 }
782 }
783
784 push(@buffers_focus, $buffer); # buffer > buffers_focus, for mouse support
785 my $color = "";
786 my $bg = "";
787
788 $color = weechat::config_color( $options{"color_default_fg"} );
789 $bg = weechat::config_color( $options{"color_default_bg"} );
790
791 if ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") eq "private" )
792 {
793 if ( (weechat::config_color($options{"queries_default_bg"})) ne "default" || (weechat::config_color($options{"queries_default_fg"})) ne "default" )
794 {
795 $bg = weechat::config_color( $options{"queries_default_bg"} );
796 $color = weechat::config_color( $options{"queries_default_fg"} );
797 }
798 }
799 # check for core and buffer with free content
800 if ( (weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "channel" ) and ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "private") )
801 {
802 $color = weechat::config_color( $options{"color_none_channel_fg"} );
803 $bg = weechat::config_color( $options{"color_none_channel_bg"} );
804 }
805 # default whitelist buffer?
806 if (grep {$_ eq $buffer->{"name"}} @whitelist_buffers)
807 {
808 $color = weechat::config_color( $options{"color_whitelist_default_fg"} );
809 $bg = weechat::config_color( $options{"color_whitelist_default_bg"} );
810 }
811
812 $color = "default" if ($color eq "");
813
814 # color for channel and query buffer
815 if (exists $hotlist{$buffer->{"pointer"}})
816 {
817 delete $buffers_timer{$buffer->{"pointer"}};
818 # check if buffer is in whitelist buffer
819 if (grep {$_ eq $buffer->{"name"}} @whitelist_buffers)
820 {
821 $bg = weechat::config_color( $options{"color_whitelist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_bg"} );
822 $color = weechat::config_color( $options{"color_whitelist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_fg"} );
823 }
824 elsif ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") eq "private" )
825 {
826 # queries_default_fg/bg and buffers.color.queries_message_fg/bg
827 if ( (weechat::config_color($options{"queries_highlight_fg"})) ne "default" ||
828 (weechat::config_color($options{"queries_highlight_bg"})) ne "default" ||
829 (weechat::config_color($options{"queries_message_fg"})) ne "default" ||
830 (weechat::config_color($options{"queries_message_bg"})) ne "default" )
831 {
832 if ( ($hotlist{$buffer->{"pointer"}}) == 2 )
833 {
834 $bg = weechat::config_color( $options{"queries_message_bg"} );
835 $color = weechat::config_color( $options{"queries_message_fg"} );
836 }
837
838 elsif ( ($hotlist{$buffer->{"pointer"}}) == 3 )
839 {
840 $bg = weechat::config_color( $options{"queries_highlight_bg"} );
841 $color = weechat::config_color( $options{"queries_highlight_fg"} );
842 }
843 }else
844 {
845 $bg = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_bg"} );
846 $color = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_fg"} );
847 }
848 }else
849 {
850 $bg = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_bg"} );
851 $color = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_fg"} );
852 }
853 }
854
855 if ($buffer->{"current_buffer"})
856 {
857 $color = weechat::config_color( $options{"color_current_fg"} );
858 $bg = weechat::config_color( $options{"color_current_bg"} );
859 }
860 my $color_bg = "";
861 $color_bg = weechat::color(",".$bg) if ($bg ne "");
862
863 # create channel number for output
864 if ( weechat::config_string( $options{"show_prefix_bufname"} ) ne "" )
865 {
866 $str .= $color_bg .
867 weechat::color( weechat::config_color( $options{"color_prefix_bufname"} ) ).
868 weechat::config_string( $options{"show_prefix_bufname"} ).
869 weechat::color("default");
870 }
871
872 if ( weechat::config_boolean( $options{"show_number"} ) eq 1 ) # on
873 {
874 if (( weechat::config_boolean( $options{"indenting_number"} ) eq 1)
875 && (($position eq "left") || ($position eq "right")))
876 {
877 $str .= weechat::color("default").$color_bg
878 .(" " x ($max_number_digits - length(int($buffer->{"number"}))));
879 }
880 if ($old_number ne $buffer->{"number"})
881 {
882 $str .= weechat::color( weechat::config_color( $options{"color_number"} ) )
883 .$color_bg
884 .$buffer->{"number"}
885 .weechat::color("default")
886 .$color_bg
887 .weechat::color( weechat::config_color( $options{"color_number_char"} ) )
888 .weechat::config_string( $options{"show_number_char"} )
889 .$color_bg;
890 }
891 else
892 {
893 my $indent = "";
894 $indent = ((" " x length($buffer->{"number"}))." ") if (($position eq "left") || ($position eq "right"));
895 $str .= weechat::color("default")
896 .$color_bg
897 .$indent;
898 }
899 }
900
901 if (( weechat::config_integer( $options{"indenting"} ) ne 0 ) # indenting NOT off
902 && (($position eq "left") || ($position eq "right")))
903 {
904 my $type = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type");
905 if (($type eq "channel") || ($type eq "private"))
906 {
907 if ( weechat::config_integer( $options{"indenting"} ) eq 1 )
908 {
909 $str .= " ";
910 }
911 elsif ( (weechat::config_integer($options{"indenting"}) eq 2) and (weechat::config_integer($options{"indenting_number"}) eq 0) ) #under_name
912 {
913 if ( weechat::config_boolean( $options{"show_number"} ) eq 0 )
914 {
915 $str .= " ";
916 }else
917 {
918 $str .= ( (" " x ( $max_number_digits - length($buffer->{"number"}) ))." " );
919 }
920 }
921 }
922 }
923
924 $str .= weechat::config_string( $options{"show_prefix_query"}) if (weechat::config_string( $options{"show_prefix_query"} ) ne "" and $buffer->{"type"} eq "private");
925
926 if (weechat::config_boolean( $options{"show_prefix"} ) eq 1)
927 {
928 my $nickname = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_nick");
929 if ($nickname ne "")
930 {
931 # with version >= 0.3.2, this infolist will return only nick
932 # with older versions, whole nicklist is returned for buffer, and this can be very slow
933 my $infolist_nick = weechat::infolist_get("nicklist", $buffer->{"pointer"}, "nick_".$nickname);
934 if ($infolist_nick ne "")
935 {
936 while (weechat::infolist_next($infolist_nick))
937 {
938 if ((weechat::infolist_string($infolist_nick, "type") eq "nick")
939 && (weechat::infolist_string($infolist_nick, "name") eq $nickname))
940 {
941 my $prefix = weechat::infolist_string($infolist_nick, "prefix");
942 if (($prefix ne " ") or (weechat::config_boolean( $options{"show_prefix_empty"} ) eq 1))
943 {
944 # with version >= 0.3.5, it is now a color name (for older versions: option name with color)
945 if (int($weechat_version) >= 0x00030500)
946 {
947 $str .= weechat::color(weechat::infolist_string($infolist_nick, "prefix_color"));
948 }
949 else
950 {
951 $str .= weechat::color(weechat::config_color(
952 weechat::config_get(
953 weechat::infolist_string($infolist_nick, "prefix_color"))));
954 }
955 $str .= $prefix;
956 }
957 last;
958 }
959 }
960 weechat::infolist_free($infolist_nick);
961 }
962 }
963 }
964 if ($buffer->{"type"} eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1 and $buffer->{"nicks_count"} == 0)
965 {
966 $str .= "(";
967 }
968
969 $str .= weechat::color($color) . weechat::color(",".$bg);
970
971 if (weechat::config_boolean( $options{"short_names"} ) eq 1)
972 {
973 if (weechat::config_integer($options{"name_size_max"}) >= 1) # check max_size of buffer name
974 {
975 $str .= encode("UTF-8", substr(decode("UTF-8", $buffer->{"short_name"}), 0, weechat::config_integer($options{"name_size_max"})));
976 $str .= weechat::color(weechat::config_color( $options{"color_number_char"})).weechat::config_string($options{"name_crop_suffix"}) if (length($buffer->{"short_name"}) > weechat::config_integer($options{"name_size_max"}));
977 $str .= add_inactive_parentless($buffer->{"type"},$buffer->{"nicks_count"});
978 $str .= add_hotlist_count($buffer->{"pointer"},%hotlist);
979 }
980 else
981 {
982 $str .= $buffer->{"short_name"};
983 $str .= add_inactive_parentless($buffer->{"type"},$buffer->{"nicks_count"});
984 $str .= add_hotlist_count($buffer->{"pointer"},%hotlist);
985 }
986 }
987 else
988 {
989 if (weechat::config_integer($options{"name_size_max"}) >= 1) # check max_size of buffer name
990 {
991 $str .= encode("UTF-8", substr(decode("UTF-8", $buffer->{"name"},), 0, weechat::config_integer($options{"name_size_max"})));
992 $str .= weechat::color(weechat::config_color( $options{"color_number_char"})).weechat::config_string($options{"name_crop_suffix"}) if (length($buffer->{"name"}) > weechat::config_integer($options{"name_size_max"}));
993 $str .= add_inactive_parentless($buffer->{"type"},$buffer->{"nicks_count"});
994 $str .= add_hotlist_count($buffer->{"pointer"},%hotlist);
995 }
996 else
997 {
998 $str .= $buffer->{"name"};
999 $str .= add_inactive_parentless($buffer->{"type"},$buffer->{"nicks_count"});
1000 $str .= add_hotlist_count($buffer->{"pointer"},%hotlist);
1001 }
1002 }
1003 if ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") eq "server" and weechat::config_boolean($options{"show_lag"}) eq 1)
1004 {
1005 my $color_lag = weechat::config_color(weechat::config_get("irc.color.item_lag_finished"));
1006 my $min_lag = weechat::config_integer(weechat::config_get("irc.network.lag_min_show"));
1007 my $infolist_server = weechat::infolist_get("irc_server","",$buffer->{"short_name"});
1008 weechat::infolist_next($infolist_server);
1009 my $lag = (weechat::infolist_integer($infolist_server, "lag"));
1010 weechat::infolist_free($infolist_server);
1011 if ( int($lag) > int($min_lag) )
1012 {
1013 $lag = $lag / 1000;
1014 $str .= weechat::color("default") . " (" . weechat::color($color_lag) . $lag . weechat::color("default") . ")";
1015 }
1016 }
1017 if (weechat::config_boolean($options{"detach_displayed_buffers"}) eq 0
1018 and weechat::config_boolean($options{"detach_display_window_number"}) eq 1)
1019 {
1020 if ($buffer->{"window"})
1021 {
1022 $str .= weechat::color("default") . " (" . weechat::color(weechat::config_color( $options{"color_number"})) . $buffer->{"window"} . weechat::color("default") . ")";
1023 }
1024 }
1025 $str .= weechat::color("default");
1026
1027 if ( weechat::config_string( $options{"show_suffix_bufname"} ) ne "" )
1028 {
1029 $str .= weechat::color( weechat::config_color( $options{"color_suffix_bufname"} ) ).
1030 weechat::config_string( $options{"show_suffix_bufname"} ).
1031 weechat::color("default");
1032 }
1033
1034 $str .= "\n";
1035 $old_number = $buffer->{"number"};
1036 }
1037
1038 # remove spaces and/or linefeed at the end
1039 $str =~ s/\s+$//;
1040 chomp($str);
1041 return $str;
1042 }
1043
1044 sub add_inactive_parentless
1045 {
1046 my ($buf_type, $buf_nicks_count) = @_;
1047 my $str = "";
1048 if ($buf_type eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1 and $buf_nicks_count == 0)
1049 {
1050 $str .= weechat::color(weechat::config_color( $options{"color_number_char"}));
1051 $str .= ")";
1052 }
1053 return $str;
1054 }
1055
1056 sub add_hotlist_count
1057 {
1058 my ($bufpointer,%hotlist) = @_;
1059
1060 return "" if ( weechat::config_boolean( $options{"hotlist_counter"} ) eq 0 or ($weechat_version < 0x00030500)); # off
1061 my $col_number_char = weechat::color(weechat::config_color( $options{"color_number_char"}) );
1062 my $str = " ".$col_number_char."(";
1063
1064 # 0 = low level
1065 if (defined $hotlist{$bufpointer."_count_00"})
1066 {
1067 my $bg = weechat::config_color( $options{"color_hotlist_low_bg"} );
1068 my $color = weechat::config_color( $options{"color_hotlist_low_fg"} );
1069 $str .= weechat::color($bg).
1070 weechat::color($color).
1071 $hotlist{$bufpointer."_count_00"} if ($hotlist{$bufpointer."_count_00"} ne "0");
1072 }
1073
1074 # 1 = message
1075 if (defined $hotlist{$bufpointer."_count_01"})
1076 {
1077 my $bg = weechat::config_color( $options{"color_hotlist_message_bg"} );
1078 my $color = weechat::config_color( $options{"color_hotlist_message_fg"} );
1079 if ($str =~ /[0-9]$/)
1080 {
1081 $str .= ",".
1082 weechat::color($bg).
1083 weechat::color($color).
1084 $hotlist{$bufpointer."_count_01"} if ($hotlist{$bufpointer."_count_01"} ne "0");
1085 }else
1086 {
1087 $str .= weechat::color($bg).
1088 weechat::color($color).
1089 $hotlist{$bufpointer."_count_01"} if ($hotlist{$bufpointer."_count_01"} ne "0");
1090 }
1091 }
1092 # 2 = private
1093 if (defined $hotlist{$bufpointer."_count_02"})
1094 {
1095 my $bg = weechat::config_color( $options{"color_hotlist_private_bg"} );
1096 my $color = weechat::config_color( $options{"color_hotlist_private_fg"} );
1097 if ($str =~ /[0-9]$/)
1098 {
1099 $str .= ",".
1100 weechat::color($bg).
1101 weechat::color($color).
1102 $hotlist{$bufpointer."_count_02"} if ($hotlist{$bufpointer."_count_02"} ne "0");
1103 }else
1104 {
1105 $str .= weechat::color($bg).
1106 weechat::color($color).
1107 $hotlist{$bufpointer."_count_02"} if ($hotlist{$bufpointer."_count_02"} ne "0");
1108 }
1109 }
1110 # 3 = highlight
1111 if (defined $hotlist{$bufpointer."_count_03"})
1112 {
1113 my $bg = weechat::config_color( $options{"color_hotlist_highlight_bg"} );
1114 my $color = weechat::config_color( $options{"color_hotlist_highlight_fg"} );
1115 if ($str =~ /[0-9]$/)
1116 {
1117 $str .= ",".
1118 weechat::color($bg).
1119 weechat::color($color).
1120 $hotlist{$bufpointer."_count_03"} if ($hotlist{$bufpointer."_count_03"} ne "0");
1121 }else
1122 {
1123 $str .= weechat::color($bg).
1124 weechat::color($color).
1125 $hotlist{$bufpointer."_count_03"} if ($hotlist{$bufpointer."_count_03"} ne "0");
1126 }
1127 }
1128 $str .= $col_number_char. ")";
1129
1130 $str = "" if (weechat::string_remove_color($str, "") eq " ()"); # remove color and check for buffer with no messages
1131 return $str;
1132 }
1133
1134 sub buffers_signal_buffer
1135 {
1136 my ($data, $signal, $signal_data) = @_;
1137
1138 # check for buffer_switch and set or remove detach time
1139 if ($weechat_version >= 0x00030800)
1140 {
1141 if ($signal eq "buffer_switch")
1142 {
1143 my $pointer = weechat::hdata_get_list (weechat::hdata_get("buffer"), "gui_buffer_last_displayed"); # get switched buffer
1144 my $current_time = time();
1145 if ( weechat::buffer_get_string($pointer, "localvar_type") eq "channel")
1146 {
1147 $buffers_timer{$pointer} = $current_time;
1148 }
1149 else
1150 {
1151 delete $buffers_timer{$pointer};
1152 }
1153 }
1154 if ($signal eq "buffer_opened")
1155 {
1156 my $current_time = time();
1157 $buffers_timer{$signal_data} = $current_time;
1158 }
1159 if ($signal eq "buffer_closing")
1160 {
1161 delete $buffers_timer{$signal_data};
1162 }
1163 }
1164 weechat::bar_item_update($SCRIPT_NAME);
1165 return weechat::WEECHAT_RC_OK;
1166 }
1167
1168 sub buffers_signal_hotlist
1169 {
1170 weechat::bar_item_update($SCRIPT_NAME);
1171 return weechat::WEECHAT_RC_OK;
1172 }
1173
1174
1175 sub buffers_signal_config_whitelist
1176 {
1177 @whitelist_buffers = ();
1178 @whitelist_buffers = split( /,/, weechat::config_string( $options{"look_whitelist_buffers"} ) );
1179 weechat::bar_item_update($SCRIPT_NAME);
1180 return weechat::WEECHAT_RC_OK;
1181 }
1182
1183 sub buffers_signal_config_immune_detach_buffers
1184 {
1185 @immune_detach_buffers = ();
1186 @immune_detach_buffers = split( /,/, weechat::config_string( $options{"immune_detach_buffers"} ) );
1187 weechat::bar_item_update($SCRIPT_NAME);
1188 return weechat::WEECHAT_RC_OK;
1189 }
1190
1191 sub buffers_signal_config_detach_buffer_immediately
1192 {
1193 @detach_buffer_immediately = ();
1194 @detach_buffer_immediately = split( /,/, weechat::config_string( $options{"detach_buffer_immediately"} ) );
1195 weechat::bar_item_update($SCRIPT_NAME);
1196 return weechat::WEECHAT_RC_OK;
1197 }
1198
1199 sub buffers_signal_config
1200 {
1201 weechat::bar_item_update($SCRIPT_NAME);
1202 return weechat::WEECHAT_RC_OK;
1203 }
1204
1205 # called when mouse click occured in buffers item: this callback returns buffer
1206 # hash according to line of item where click occured
1207 sub buffers_focus_buffers
1208 {
1209 my %info = %{$_[1]};
1210 my $item_line = int($info{"_bar_item_line"});
1211 undef my $hash;
1212 if (($info{"_bar_item_name"} eq $SCRIPT_NAME) && ($item_line >= 0) && ($item_line <= $#buffers_focus))
1213 {
1214 $hash = $buffers_focus[$item_line];
1215 }
1216 else
1217 {
1218 $hash = {};
1219 my $hash_focus = $buffers_focus[0];
1220 foreach my $key (keys %$hash_focus)
1221 {
1222 $hash->{$key} = "?";
1223 }
1224 }
1225 return $hash;
1226 }
1227
1228 # called when a mouse action is done on buffers item, to execute action
1229 # possible actions: jump to a buffer or move buffer in list (drag & drop of buffer)
1230 sub buffers_hsignal_mouse
1231 {
1232 my ($data, $signal, %hash) = ($_[0], $_[1], %{$_[2]});
1233 my $current_buffer = weechat::buffer_get_integer(weechat::current_buffer(), "number"); # get current buffer number
1234
1235 if ( $hash{"_key"} eq "button1" ) # left mouse button
1236 {
1237 if ($hash{"number"} eq $hash{"number2"})
1238 {
1239 if ( weechat::config_integer($options{"jump_prev_next_visited_buffer"}) eq 1 )
1240 {
1241 if ( $current_buffer eq $hash{"number"} )
1242 {
1243 weechat::command("","/input jump_previously_visited_buffer");
1244 }
1245 else
1246 {
1247 weechat::command("", "/buffer ".$hash{"full_name"});
1248 }
1249 }
1250 else
1251 {
1252 weechat::command("", "/buffer ".$hash{"full_name"});
1253 }
1254 }
1255 else
1256 {
1257 move_buffer(%hash) if (weechat::config_boolean($options{"mouse_move_buffer"}));
1258 }
1259 }
1260 elsif ( ($hash{"_key"} eq "button2") && (weechat::config_integer($options{"jump_prev_next_visited_buffer"}) eq 1) )# right mouse button
1261 {
1262 if ( $current_buffer eq $hash{"number2"} )
1263 {
1264 weechat::command("","/input jump_next_visited_buffer");
1265 }
1266 }
1267 else
1268 {
1269 my $infolist = weechat::infolist_get("hook", "", "command,menu");
1270 my $has_menu_command = weechat::infolist_next($infolist);
1271 weechat::infolist_free($infolist);
1272
1273 if ( $has_menu_command && $hash{"_key"} =~ /button2/ )
1274 {
1275 if ($hash{"number"} eq $hash{"number2"})
1276 {
1277 weechat::command($hash{"pointer"}, "/menu buffer1 $hash{short_name} $hash{number}");
1278 }
1279 else
1280 {
1281 weechat::command($hash{"pointer"}, "/menu buffer2 $hash{short_name}/$hash{short_name2} $hash{number} $hash{number2}")
1282 }
1283 }
1284 else
1285 {
1286 move_buffer(%hash) if (weechat::config_boolean($options{"mouse_move_buffer"}));
1287 }
1288 }
1289 }
1290
1291 sub move_buffer
1292 {
1293 my %hash = @_;
1294 my $number2 = $hash{"number2"};
1295 if ($number2 eq "?")
1296 {
1297 # if number 2 is not known (end of gesture outside buffers list), then set it
1298 # according to mouse gesture
1299 $number2 = "1";
1300 if (($hash{"_key"} =~ /gesture-right/) || ($hash{"_key"} =~ /gesture-down/))
1301 {
1302 $number2 = "999999";
1303 if ($weechat_version >= 0x00030600)
1304 {
1305 my $hdata_buffer = weechat::hdata_get("buffer");
1306 my $last_gui_buffer = weechat::hdata_get_list($hdata_buffer, "last_gui_buffer");
1307 if ($last_gui_buffer)
1308 {
1309 $number2 = weechat::hdata_integer($hdata_buffer, $last_gui_buffer, "number") + 1;
1310 }
1311 }
1312 }
1313 }
1314 my $ptrbuf = weechat::current_buffer();
1315 weechat::command($hash{"pointer"}, "/buffer move ".$number2);
1316 }
1317
1318 sub check_immune_detached_buffers
1319 {
1320 my ($buffername) = @_;
1321 foreach ( @immune_detach_buffers ){
1322 my $immune_buffer = weechat::string_mask_to_regex($_);
1323 if ($buffername =~ /^$immune_buffer$/i)
1324 {
1325 return 1;
1326 }
1327 }
1328 return 0;
1329 }
1330
1331 sub check_detach_buffer_immediately
1332 {
1333 my ($buffername) = @_;
1334 foreach ( @detach_buffer_immediately ){
1335 my $detach_buffer = weechat::string_mask_to_regex($_);
1336 if ($buffername =~ /^$detach_buffer$/i)
1337 {
1338 return 1;
1339 }
1340 }
1341 return 0;
1342 }
1343
1344 sub shutdown_cb
1345 {
1346 weechat::command("","/bar hide " . $SCRIPT_NAME) if ( weechat::config_boolean($options{"toggle_bar"}) eq 1 );
1347 return weechat::WEECHAT_RC_OK
1348 }
1349
1350 sub check_bar_item
1351 {
1352 my $item = 0;
1353 my $infolist = weechat::infolist_get("bar", "", "");
1354 while (weechat::infolist_next($infolist))
1355 {
1356 my $bar_items = weechat::infolist_string($infolist, "items");
1357 if (index($bar_items,$SCRIPT_NAME) != -1)
1358 {
1359 my $name = weechat::infolist_string($infolist, "name");
1360 if ($name ne $SCRIPT_NAME)
1361 {
1362 $item = 1;
1363 last;
1364 }
1365 }
1366 }
1367 weechat::infolist_free($infolist);
1368 return $item;
1369 }