From 675ad9b1bc91e41b6868527e4acb7dfaf33b05f4 Mon Sep 17 00:00:00 2001 From: George Rawlinson Date: Tue, 1 Nov 2016 15:25:24 +1300 Subject: [PATCH] Add weechat configuration --- Makefile | 33 +- README.md | 1 + weechat/.config/weechat/alias.conf | 41 + weechat/.config/weechat/aspell.conf | 20 + weechat/.config/weechat/buffers.conf | 73 + weechat/.config/weechat/charset.conf | 11 + weechat/.config/weechat/exec.conf | 11 + weechat/.config/weechat/irc.conf | 299 +++ weechat/.config/weechat/iset.conf | 30 + weechat/.config/weechat/logger.conf | 27 + .../.config/weechat/perl/autoload/buffers.pl | 1 + weechat/.config/weechat/perl/autoload/iset.pl | 1 + weechat/.config/weechat/perl/buffers.pl | 1840 +++++++++++++++++ weechat/.config/weechat/perl/iset.pl | 1624 +++++++++++++++ weechat/.config/weechat/plugins.conf | 15 + weechat/.config/weechat/relay.conf | 41 + weechat/.config/weechat/script.conf | 50 + weechat/.config/weechat/script/plugins.xml.gz | Bin 0 -> 102516 bytes weechat/.config/weechat/trigger.conf | 52 + weechat/.config/weechat/weechat.conf | 630 ++++++ weechat/.config/weechat/xfer.conf | 39 + zsh/.oh-my-zsh/custom/weechat.zsh | 2 + 22 files changed, 4827 insertions(+), 14 deletions(-) create mode 100644 weechat/.config/weechat/alias.conf create mode 100644 weechat/.config/weechat/aspell.conf create mode 100644 weechat/.config/weechat/buffers.conf create mode 100644 weechat/.config/weechat/charset.conf create mode 100644 weechat/.config/weechat/exec.conf create mode 100644 weechat/.config/weechat/irc.conf create mode 100644 weechat/.config/weechat/iset.conf create mode 100644 weechat/.config/weechat/logger.conf create mode 120000 weechat/.config/weechat/perl/autoload/buffers.pl create mode 120000 weechat/.config/weechat/perl/autoload/iset.pl create mode 100644 weechat/.config/weechat/perl/buffers.pl create mode 100644 weechat/.config/weechat/perl/iset.pl create mode 100644 weechat/.config/weechat/plugins.conf create mode 100644 weechat/.config/weechat/relay.conf create mode 100644 weechat/.config/weechat/script.conf create mode 100644 weechat/.config/weechat/script/plugins.xml.gz create mode 100644 weechat/.config/weechat/trigger.conf create mode 100644 weechat/.config/weechat/weechat.conf create mode 100644 weechat/.config/weechat/xfer.conf create mode 100644 zsh/.oh-my-zsh/custom/weechat.zsh diff --git a/Makefile b/Makefile index e743d05..08586b0 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help git lftp mpd ncmpcpp npm nvim ssh sway tmux urxvt wallpapers zsh clean +.PHONY: help git lftp mpd ncmpcpp npm nvim ssh sway tmux urxvt wallpapers weechat zsh clean .DEFAULT: help @@ -15,54 +15,58 @@ help: @echo "tmux > tmux config" @echo "urxvt > terminal colours & keyboard settings" @echo "wallpapers > system wallpapers" + @echo "weechat > irc client ui/colour configuration" @echo "zsh > shell, aliases and cool stuff" @echo "" @echo " mostly, i'm just lazy" -all: git lftp mpd ncmpcpp npm nvim ssh sway tmux urxvt wallpapers zsh +all: git lftp mpd ncmpcpp npm nvim ssh sway tmux urxvt wallpapers weechat zsh git: - @stow -t ~/ git + @stow -t ~/ --no-folding git lftp: - @stow -t ~/ lftp + @stow -t ~/ --no-folding lftp mpd: - @stow -t ~/ mpd + @stow -t ~/ --no-folding mpd ncmpcpp: - @stow -t ~/ ncmpcpp + @stow -t ~/ --no-folding ncmpcpp npm: @mkdir -p ~/.cache/npm ~/.local/share/npm - @stow -t ~/ npm + @stow -t ~/ --no-folding npm nvim: - @stow -t ~/ nvim + @stow -t ~/ --no-folding nvim curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim @echo "Run :PlugInstall when nvim is first run!" ssh: - @stow -t ~/ ssh + @stow -t ~/ --no-folding ssh sway: - @stow -t ~/ sway + @stow -t ~/ --no-folding sway tmux: git clone https://github.com/tmux-plugins/tpm ~/.config/tmux/plugins/tpm - @stow -t ~/ tmux + @stow -t ~/ --no-folding tmux urxvt: - @stow -t ~/ urxvt + @stow -t ~/ --no-folding urxvt wallpapers: - @stow -t ~/ wallpapers + @stow -t ~/ --no-folding wallpapers + +weechat: + @stow -t ~/ --no-folding weechat zsh: git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh git clone https://github.com/zsh-users/zsh-completions.git ~/.oh-my-zsh/custom/plugins/zsh-completions - @stow -t ~/ zsh + @stow -t ~/ --no-folding zsh clean: @stow -D git lftp npm nvim ssh sway tmux urxvt zsh @@ -72,4 +76,5 @@ clean: ~/.config/nvim \ ~/.config/sway \ ~/.config/tmux \ + ~/.config/weechat \ ~/.oh-my-zsh diff --git a/README.md b/README.md index c0a65ea..f290673 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ sway > minimal tiling wm for naughty computers tmux > tmux config urxvt > terminal colours & keyboard settings wallpapers > system wallpapers +weechat > irc client ui/colour configuration zsh > shell, aliases and cool stuff ``` diff --git a/weechat/.config/weechat/alias.conf b/weechat/.config/weechat/alias.conf new file mode 100644 index 0000000..069fc02 --- /dev/null +++ b/weechat/.config/weechat/alias.conf @@ -0,0 +1,41 @@ +# +# weechat -- alias.conf +# + +[cmd] +AAWAY = "allserv /away" +AME = "allchan /me" +AMSG = "allchan /msg *" +ANICK = "allserv /nick" +BEEP = "print -beep" +BYE = "quit" +C = "buffer clear" +CHAT = "dcc chat" +CL = "buffer clear" +CLOSE = "buffer close" +EXIT = "quit" +IG = "ignore" +J = "join" +K = "kick" +KB = "kickban" +LEAVE = "part" +M = "msg" +MSGBUF = "command -buffer $1 * /input send $2-" +MUB = "unban *" +N = "names" +Q = "query" +REDRAW = "window refresh" +SAY = "msg *" +SIGNOFF = "quit" +T = "topic" +UB = "unban" +UMODE = "mode $nick" +V = "command core version" +W = "who" +WC = "window merge" +WI = "whois" +WII = "whois $1 $1" +WW = "whowas" + +[completion] +MSGBUF = "%(buffers_plugins_names)" diff --git a/weechat/.config/weechat/aspell.conf b/weechat/.config/weechat/aspell.conf new file mode 100644 index 0000000..26df178 --- /dev/null +++ b/weechat/.config/weechat/aspell.conf @@ -0,0 +1,20 @@ +# +# weechat -- aspell.conf +# + +[color] +misspelled = 1 +suggestions = 2 + +[check] +commands = "ame,amsg,away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic" +default_dict = "en_GB" +during_search = off +enabled = on +real_time = off +suggestions = -1 +word_min_length = 2 + +[dict] + +[option] diff --git a/weechat/.config/weechat/buffers.conf b/weechat/.config/weechat/buffers.conf new file mode 100644 index 0000000..e3180f5 --- /dev/null +++ b/weechat/.config/weechat/buffers.conf @@ -0,0 +1,73 @@ +# +# weechat -- buffers.conf +# + +[color] +current_bg = 240 +current_fg = 4 +default_bg = default +default_fg = default +hotlist_highlight_bg = default +hotlist_highlight_fg = magenta +hotlist_low_bg = default +hotlist_low_fg = white +hotlist_message_bg = default +hotlist_message_fg = 5 +hotlist_private_bg = default +hotlist_private_fg = 5 +none_channel_bg = default +none_channel_fg = default +number = 4 +number_char = 4 +prefix_bufname = default +queries_default_bg = default +queries_default_fg = default +queries_highlight_bg = default +queries_highlight_fg = default +queries_message_bg = default +queries_message_fg = default +suffix_bufname = default +whitelist_default_bg = default +whitelist_default_fg = default +whitelist_highlight_bg = default +whitelist_highlight_fg = default +whitelist_low_bg = default +whitelist_low_fg = default +whitelist_message_bg = default +whitelist_message_fg = default +whitelist_private_bg = default +whitelist_private_fg = default + +[look] +core_to_front = off +detach = 0 +detach_buffer_immediately = "" +detach_buffer_immediately_level = 2 +detach_display_window_number = off +detach_displayed_buffers = on +detach_free_content = off +detach_query = off +hide_merged_buffers = none +hotlist_counter = off +immune_detach_buffers = "" +indenting = on +indenting_amount = 2 +indenting_number = on +jump_prev_next_visited_buffer = off +mark_inactive = off +mouse_move_buffer = on +mouse_wheel = on +name_crop_suffix = "+" +name_size_max = 0 +number_char = "." +prefix = off +prefix_bufname = "" +prefix_empty = on +prefix_for_query = "" +short_names = on +show_lag = off +show_number = on +sort = number +suffix_bufname = "" +toggle_bar = on +whitelist_buffers = "" diff --git a/weechat/.config/weechat/charset.conf b/weechat/.config/weechat/charset.conf new file mode 100644 index 0000000..99a90d5 --- /dev/null +++ b/weechat/.config/weechat/charset.conf @@ -0,0 +1,11 @@ +# +# weechat -- charset.conf +# + +[default] +decode = "iso-8859-1" +encode = "" + +[decode] + +[encode] diff --git a/weechat/.config/weechat/exec.conf b/weechat/.config/weechat/exec.conf new file mode 100644 index 0000000..39f1929 --- /dev/null +++ b/weechat/.config/weechat/exec.conf @@ -0,0 +1,11 @@ +# +# weechat -- exec.conf +# + +[command] +default_options = "" +purge_delay = 0 + +[color] +flag_finished = lightred +flag_running = lightgreen diff --git a/weechat/.config/weechat/irc.conf b/weechat/.config/weechat/irc.conf new file mode 100644 index 0000000..4bb911a --- /dev/null +++ b/weechat/.config/weechat/irc.conf @@ -0,0 +1,299 @@ +# +# weechat -- irc.conf +# + +[look] +buffer_open_before_autojoin = on +buffer_open_before_join = off +buffer_switch_autojoin = off +buffer_switch_join = off +color_nicks_in_names = on +color_nicks_in_nicklist = on +color_nicks_in_server_messages = on +color_pv_nick_like_channel = on +ctcp_time_format = "%a, %d %b %Y %T %z" +display_away = local +display_ctcp_blocked = on +display_ctcp_reply = on +display_ctcp_unknown = on +display_host_join = on +display_host_join_local = on +display_host_quit = on +display_join_message = "329,332,333,366" +display_old_topic = on +display_pv_away_once = on +display_pv_back = on +highlight_channel = "$nick" +highlight_pv = "$nick" +highlight_server = "$nick" +highlight_tags_restrict = "irc_privmsg,irc_notice" +item_channel_modes_hide_args = "k" +item_display_server = buffer_plugin +item_nick_modes = on +item_nick_prefix = on +join_auto_add_chantype = off +msgbuffer_fallback = current +new_channel_position = none +new_pv_position = none +nick_completion_smart = speakers +nick_mode = prefix +nick_mode_empty = off +nicks_hide_password = "nickserv" +notice_as_pv = auto +notice_welcome_redirect = on +notice_welcome_tags = "" +notify_tags_ison = "notify_message" +notify_tags_whois = "notify_message" +part_closes_buffer = off +pv_buffer = independent +pv_tags = "notify_private" +raw_messages = 256 +server_buffer = independent +smart_filter = on +smart_filter_delay = 5 +smart_filter_join = on +smart_filter_join_unmask = 30 +smart_filter_mode = "+" +smart_filter_nick = on +smart_filter_quit = on +temporary_servers = off +topic_strip_colors = off + +[color] +input_nick = lightcyan +item_channel_modes = default +item_lag_counting = default +item_lag_finished = yellow +item_nick_modes = default +message_join = green +message_quit = red +mirc_remap = "1,-1:darkgray" +nick_prefixes = "q:lightred;a:lightcyan;o:121;h:lightmagenta;v:229;*:lightblue" +notice = green +reason_quit = default +topic_current = default +topic_new = white +topic_old = default + +[network] +autoreconnect_delay_growing = 2 +autoreconnect_delay_max = 600 +ban_mask_default = "*!$ident@$host" +channel_encode = off +colors_receive = on +colors_send = on +lag_check = 60 +lag_max = 1800 +lag_min_show = 500 +lag_reconnect = 0 +lag_refresh_interval = 1 +notify_check_ison = 1 +notify_check_whois = 5 +sasl_fail_unavailable = on +send_unknown_commands = off +whois_double_nick = off + +[msgbuffer] + +[ctcp] + +[ignore] + +[server_default] +addresses = "" +anti_flood_prio_high = 2 +anti_flood_prio_low = 2 +autoconnect = off +autojoin = "" +autoreconnect = on +autoreconnect_delay = 10 +autorejoin = off +autorejoin_delay = 30 +away_check = 0 +away_check_max_nicks = 25 +capabilities = "account-notify,away-notify,cap-notify,multi-prefix,server-time,znc.in/server-time-iso,znc.in/self-message" +command = "" +command_delay = 0 +connection_timeout = 60 +ipv6 = on +local_hostname = "" +msg_kick = "" +msg_part = "WeeChat ${info:version}" +msg_quit = "WeeChat ${info:version}" +nicks = "" +nicks_alternate = on +notify = "" +password = "" +proxy = "" +realname = "" +sasl_fail = continue +sasl_key = "" +sasl_mechanism = plain +sasl_password = "" +sasl_timeout = 15 +sasl_username = "" +ssl = off +ssl_cert = "" +ssl_dhkey_size = 2048 +ssl_fingerprint = "" +ssl_priorities = "NORMAL:-VERS-SSL3.0" +ssl_verify = on +username = "" + +[server] +snoonet.addresses = "${sec.data.zncaddr}" +snoonet.proxy +snoonet.ipv6 +snoonet.ssl = on +snoonet.ssl_cert +snoonet.ssl_priorities +snoonet.ssl_dhkey_size +snoonet.ssl_fingerprint +snoonet.ssl_verify = off +snoonet.password = "${sec.data.zncuser}/Snoonet:${sec.data.zncpass}" +snoonet.capabilities +snoonet.sasl_mechanism +snoonet.sasl_username +snoonet.sasl_password +snoonet.sasl_key +snoonet.sasl_timeout +snoonet.sasl_fail +snoonet.autoconnect = on +snoonet.autoreconnect +snoonet.autoreconnect_delay +snoonet.nicks = "nonick" +snoonet.nicks_alternate +snoonet.username +snoonet.realname +snoonet.local_hostname +snoonet.command +snoonet.command_delay +snoonet.autojoin +snoonet.autorejoin +snoonet.autorejoin_delay +snoonet.connection_timeout +snoonet.anti_flood_prio_high +snoonet.anti_flood_prio_low +snoonet.away_check +snoonet.away_check_max_nicks +snoonet.msg_kick +snoonet.msg_part +snoonet.msg_quit +snoonet.notify +freenode.addresses = "${sec.data.zncaddr}" +freenode.proxy +freenode.ipv6 +freenode.ssl = on +freenode.ssl_cert +freenode.ssl_priorities +freenode.ssl_dhkey_size +freenode.ssl_fingerprint +freenode.ssl_verify = off +freenode.password = "${sec.data.zncuser}/freenode:${sec.data.zncpass}" +freenode.capabilities +freenode.sasl_mechanism +freenode.sasl_username +freenode.sasl_password +freenode.sasl_key +freenode.sasl_timeout +freenode.sasl_fail +freenode.autoconnect = on +freenode.autoreconnect +freenode.autoreconnect_delay +freenode.nicks = "nonick" +freenode.nicks_alternate +freenode.username +freenode.realname +freenode.local_hostname +freenode.command +freenode.command_delay +freenode.autojoin +freenode.autorejoin +freenode.autorejoin_delay +freenode.connection_timeout +freenode.anti_flood_prio_high +freenode.anti_flood_prio_low +freenode.away_check +freenode.away_check_max_nicks +freenode.msg_kick +freenode.msg_part +freenode.msg_quit +freenode.notify +synirc.addresses = "${sec.data.zncaddr}" +synirc.proxy +synirc.ipv6 +synirc.ssl = on +synirc.ssl_cert +synirc.ssl_priorities +synirc.ssl_dhkey_size +synirc.ssl_fingerprint +synirc.ssl_verify = off +synirc.password = "${sec.data.zncuser}/SynIRC:${sec.data.zncpass}" +synirc.capabilities +synirc.sasl_mechanism +synirc.sasl_username +synirc.sasl_password +synirc.sasl_key +synirc.sasl_timeout +synirc.sasl_fail +synirc.autoconnect = on +synirc.autoreconnect +synirc.autoreconnect_delay +synirc.nicks = "nonick" +synirc.nicks_alternate +synirc.username +synirc.realname +synirc.local_hostname +synirc.command +synirc.command_delay +synirc.autojoin +synirc.autorejoin +synirc.autorejoin_delay +synirc.connection_timeout +synirc.anti_flood_prio_high +synirc.anti_flood_prio_low +synirc.away_check +synirc.away_check_max_nicks +synirc.msg_kick +synirc.msg_part +synirc.msg_quit +synirc.notify +rizon.addresses = "${sec.data.zncaddr}" +rizon.proxy +rizon.ipv6 +rizon.ssl = on +rizon.ssl_cert +rizon.ssl_priorities +rizon.ssl_dhkey_size +rizon.ssl_fingerprint +rizon.ssl_verify +rizon.password = "${sec.data.zncuser}/Rizon:${sec.data.zncpass}" +rizon.capabilities +rizon.sasl_mechanism +rizon.sasl_username +rizon.sasl_password +rizon.sasl_key +rizon.sasl_timeout +rizon.sasl_fail +rizon.autoconnect = on +rizon.autoreconnect +rizon.autoreconnect_delay +rizon.nicks = "nonick" +rizon.nicks_alternate +rizon.username +rizon.realname +rizon.local_hostname +rizon.command +rizon.command_delay +rizon.autojoin +rizon.autorejoin +rizon.autorejoin_delay +rizon.connection_timeout +rizon.anti_flood_prio_high +rizon.anti_flood_prio_low +rizon.away_check +rizon.away_check_max_nicks +rizon.msg_kick +rizon.msg_part +rizon.msg_quit +rizon.notify diff --git a/weechat/.config/weechat/iset.conf b/weechat/.config/weechat/iset.conf new file mode 100644 index 0000000..cafe04f --- /dev/null +++ b/weechat/.config/weechat/iset.conf @@ -0,0 +1,30 @@ +# +# weechat -- iset.conf +# + +[color] +bg_selected = red +help_default_value = green +help_option_name = white +help_text = default +option = default +option_selected = white +type = brown +type_selected = yellow +value = cyan +value_diff = magenta +value_diff_selected = lightmagenta +value_selected = lightcyan +value_undef = green +value_undef_selected = lightgreen + +[help] +show_help_bar = on +show_help_extra_info = on +show_plugin_description = off + +[look] +scroll_horiz = 10 +show_current_line = on +use_mute = off +value_search_char = "=" diff --git a/weechat/.config/weechat/logger.conf b/weechat/.config/weechat/logger.conf new file mode 100644 index 0000000..55a3fed --- /dev/null +++ b/weechat/.config/weechat/logger.conf @@ -0,0 +1,27 @@ +# +# weechat -- logger.conf +# + +[look] +backlog = 20 + +[color] +backlog_end = default +backlog_line = default + +[file] +auto_log = off +flush_delay = 120 +info_lines = off +mask = "%Y/%m/$plugin.$name.weechatlog" +name_lower_case = on +nick_prefix = "" +nick_suffix = "" +path = "%h/logs/" +replacement_char = "_" +time_format = "%Y-%m-%d %H:%M:%S" + +[level] +irc = 0 + +[mask] diff --git a/weechat/.config/weechat/perl/autoload/buffers.pl b/weechat/.config/weechat/perl/autoload/buffers.pl new file mode 120000 index 0000000..445dc3c --- /dev/null +++ b/weechat/.config/weechat/perl/autoload/buffers.pl @@ -0,0 +1 @@ +../buffers.pl \ No newline at end of file diff --git a/weechat/.config/weechat/perl/autoload/iset.pl b/weechat/.config/weechat/perl/autoload/iset.pl new file mode 120000 index 0000000..2746e0d --- /dev/null +++ b/weechat/.config/weechat/perl/autoload/iset.pl @@ -0,0 +1 @@ +../iset.pl \ No newline at end of file diff --git a/weechat/.config/weechat/perl/buffers.pl b/weechat/.config/weechat/perl/buffers.pl new file mode 100644 index 0000000..73eb4b5 --- /dev/null +++ b/weechat/.config/weechat/perl/buffers.pl @@ -0,0 +1,1840 @@ +# +# Copyright (C) 2008-2014 Sebastien Helleu +# Copyright (C) 2011-2013 Nils G +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# +# Display sidebar with list of buffers. +# +# History: +# +# 2016-05-01, mumixam : +# v5.4: added option "detach_buffer_immediately_level" +# 2015-08-21, Matthew Cox +# v5.3: add option "indenting_amount", to adjust the indenting of channel buffers +# 2015-05-02, arza : +# v5.2: truncate long names (name_size_max) more when mark_inactive adds parenthesis +# 2015-03-29, Ed Santiago : +# v5.1: merged buffers: always indent, except when filling is horizontal +# 2014-12-12 +# v5.0: fix cropping non-latin buffer names +# 2014-08-29, Patrick Steinhardt : +# v4.9: add support for specifying custom buffer names +# 2014-07-19, Sebastien Helleu : +# v4.8: add support of ctrl + mouse wheel to jump to previous/next buffer, +# new option "mouse_wheel" +# 2014-06-22, Sebastien Helleu : +# v4.7: fix typos in options +# 2014-04-05, Sebastien Helleu : +# v4.6: add support of hidden buffers (WeeChat >= 0.4.4) +# 2014-01-01, Sebastien Helleu : +# v4.5: add option "mouse_move_buffer" +# 2013-12-11, Sebastien Helleu : +# v4.4: fix buffer number on drag to the end of list when option +# weechat.look.buffer_auto_renumber is off +# 2013-12-10, nils_2@freenode.#weechat: +# v4.3: add options "prefix_bufname" and "suffix_bufname (idea by silverd) +# : fix hook_timer() for show_lag wasn't disabled +# : improved signal handling (less updating of buffers list) +# 2013-11-07, Sebastien Helleu : +# v4.2: use default filling "columns_vertical" when bar position is top/bottom +# 2013-10-31, nils_2@freenode.#weechat: +# v4.1: add option "detach_buffer_immediately" (idea by farn) +# 2013-10-20, nils_2@freenode.#weechat: +# v4.0: add options "detach_displayed_buffers", "detach_display_window_number" +# 2013-09-27, nils_2@freenode.#weechat: +# v3.9: add option "toggle_bar" and option "show_prefix_query" (idea by IvarB) +# : fix problem with linefeed at end of list of buffers (reported by grawity) +# 2012-10-18, nils_2@freenode.#weechat: +# v3.8: add option "mark_inactive", to mark buffers you are not in (idea by xrdodrx) +# : add wildcard "*" for immune_detach_buffers (idea by StarWeaver) +# : add new options "detach_query" and "detach_free_content" (idea by StarWeaver) +# 2012-10-06, Nei : +# v3.7: call menu on right mouse if menu script is loaded. +# 2012-10-06, nils_2 : +# v3.6: add new option "hotlist_counter" (idea by torque). +# 2012-06-02, nils_2 : +# v3.5: add values "server|channel|private|all|keepserver|none" to option "hide_merged_buffers" (suggested by dominikh). +# 2012-05-25, nils_2 : +# v3.4: add new option "show_lag". +# 2012-04-07, Sebastien Helleu : +# v3.3: fix truncation of wide chars in buffer name (option name_size_max) (bug #36034) +# 2012-03-15, nils_2 : +# v3.2: add new option "detach"(weechat >= 0.3.8) +# add new option "immune_detach_buffers" (requested by Mkaysi) +# add new function buffers_whitelist add|del|reset (suggested by FiXato) +# add new function buffers_detach add|del|reset +# 2012-03-09, Sebastien Helleu : +# v3.1: fix reload of config file +# 2012-01-29, nils_2 : +# v3.0: fix: buffers did not update directly during window_switch (reported by FiXato) +# 2012-01-29, nils_2 : +# v2.9: add options "name_size_max" and "name_crop_suffix" +# 2012-01-08, nils_2 : +# v2.8: fix indenting for option "show_number off" +# fix unset of buffer activity in hotlist when buffer was moved with mouse +# add buffer with free content and core buffer sorted first (suggested by nyuszika7h) +# add options queries_default_fg/bg and queries_message_fg/bg (suggested by FiXato) +# add clicking with left button on current buffer will do a jump_previously_visited_buffer (suggested by FiXato) +# add clicking with right button on current buffer will do a jump_next_visited_buffer +# add additional informations in help texts +# add default_fg and default_bg for whitelist channels +# internal changes (script is now 3Kb smaller) +# 2012-01-04, Sebastien Helleu : +# v2.7: fix regex lookup in whitelist buffers list +# 2011-12-04, nils_2 : +# v2.6: add own config file (buffers.conf) +# add new behavior for indenting (under_name) +# add new option to set different color for server buffers and buffers with free content +# 2011-10-30, nils_2 : +# v2.5: add new options "show_number_char" and "color_number_char", +# add help-description for options +# 2011-08-24, Sebastien Helleu : +# v2.4: add mouse support +# 2011-06-06, nils_2 : +# v2.3: added: missed option "color_whitelist_default" +# 2011-03-23, Sebastien Helleu : +# v2.2: fix color of nick prefix with WeeChat >= 0.3.5 +# 2011-02-13, nils_2 : +# v2.1: add options "color_whitelist_*" +# 2010-10-05, Sebastien Helleu : +# v2.0: add options "sort" and "show_number" +# 2010-04-12, Sebastien Helleu : +# v1.9: replace call to log() by length() to align buffer numbers +# 2010-04-02, Sebastien Helleu : +# v1.8: fix bug with background color and option indenting_number +# 2010-04-02, Helios : +# v1.7: add indenting_number option +# 2010-02-25, m4v : +# v1.6: add option to hide empty prefixes +# 2010-02-12, Sebastien Helleu : +# v1.5: add optional nick prefix for buffers like IRC channels +# 2009-09-30, Sebastien Helleu : +# v1.4: remove spaces for indenting when bar position is top/bottom +# 2009-06-14, Sebastien Helleu : +# v1.3: add option "hide_merged_buffers" +# 2009-06-14, Sebastien Helleu : +# v1.2: improve display with merged buffers +# 2009-05-02, Sebastien Helleu : +# v1.1: sync with last API changes +# 2009-02-21, Sebastien Helleu : +# v1.0: remove timer used to update bar item first time (not needed any more) +# 2009-02-17, Sebastien Helleu : +# v0.9: fix bug with indenting of private buffers +# 2009-01-04, Sebastien Helleu : +# v0.8: update syntax for command /set (comments) +# 2008-10-20, Jiri Golembiovsky : +# v0.7: add indenting option +# 2008-10-01, Sebastien Helleu : +# v0.6: add default color for buffers, and color for current active buffer +# 2008-09-18, Sebastien Helleu : +# v0.5: fix color for "low" level entry in hotlist +# 2008-09-18, Sebastien Helleu : +# v0.4: rename option "show_category" to "short_names", +# remove option "color_slash" +# 2008-09-15, Sebastien Helleu : +# v0.3: fix bug with priority in hotlist (var not defined) +# 2008-09-02, Sebastien Helleu : +# v0.2: add color for buffers with activity and config options for +# colors, add config option to display/hide categories +# 2008-03-15, Sebastien Helleu : +# v0.1: script creation +# +# Help about settings: +# display all settings for script (or use iset.pl script to change settings): +# /set buffers* +# show help text for option buffers.look.whitelist_buffers: +# /help buffers.look.whitelist_buffers +# +# Mouse-support (standard key bindings): +# left mouse-button: +# - click on a buffer to switch to selected buffer +# - click on current buffer will do action jump_previously_visited_buffer +# - drag a buffer and drop it on another position will move the buffer to position +# right mouse-button: +# - click on current buffer will do action jump_next_visited_buffer +# - moving buffer to the left/right will close buffer. +# + +use strict; +use Encode qw( decode encode ); +# -----------------------------[ internal ]------------------------------------- +my $SCRIPT_NAME = "buffers"; +my $SCRIPT_VERSION = "5.4"; + +my $BUFFERS_CONFIG_FILE_NAME = "buffers"; +my $buffers_config_file; +my $cmd_buffers_whitelist= "buffers_whitelist"; +my $cmd_buffers_detach = "buffers_detach"; + +my $maxlength; + +my %mouse_keys = ("\@item(buffers):button1*" => "hsignal:buffers_mouse", + "\@item(buffers):button2*" => "hsignal:buffers_mouse", + "\@bar(buffers):ctrl-wheelup" => "hsignal:buffers_mouse", + "\@bar(buffers):ctrl-wheeldown" => "hsignal:buffers_mouse"); +my %options; +my %hotlist_level = (0 => "low", 1 => "message", 2 => "private", 3 => "highlight"); +my @whitelist_buffers = (); +my @immune_detach_buffers= (); +my @detach_buffer_immediately= (); +my @buffers_focus = (); +my %buffers_timer = (); +my %Hooks = (); + +# --------------------------------[ init ]-------------------------------------- +weechat::register($SCRIPT_NAME, "Sebastien Helleu ", + $SCRIPT_VERSION, "GPL3", + "Sidebar with list of buffers", "shutdown_cb", ""); +my $weechat_version = weechat::info_get("version_number", "") || 0; + +buffers_config_init(); +buffers_config_read(); + +weechat::bar_item_new($SCRIPT_NAME, "build_buffers", ""); +weechat::bar_new($SCRIPT_NAME, "0", "0", "root", "", "left", "columns_vertical", + "vertical", "0", "0", "default", "default", "default", "1", + $SCRIPT_NAME); + +if ( check_bar_item() == 0 ) +{ + weechat::command("", "/bar show " . $SCRIPT_NAME) if ( weechat::config_boolean($options{"toggle_bar"}) eq 1 ); +} + +weechat::hook_signal("buffer_opened", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_closed", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_merged", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_unmerged", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_moved", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_renamed", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_switch", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_hidden", "buffers_signal_buffer", ""); # WeeChat >= 0.4.4 +weechat::hook_signal("buffer_unhidden", "buffers_signal_buffer", ""); # WeeChat >= 0.4.4 +weechat::hook_signal("buffer_localvar_added", "buffers_signal_buffer", ""); +weechat::hook_signal("buffer_localvar_changed", "buffers_signal_buffer", ""); + +weechat::hook_signal("window_switch", "buffers_signal_buffer", ""); +weechat::hook_signal("hotlist_changed", "buffers_signal_hotlist", ""); +#weechat::hook_command_run("/input switch_active_*", "buffers_signal_buffer", ""); +weechat::bar_item_update($SCRIPT_NAME); + + +if ($weechat_version >= 0x00030600) +{ + weechat::hook_focus($SCRIPT_NAME, "buffers_focus_buffers", ""); + weechat::hook_hsignal("buffers_mouse", "buffers_hsignal_mouse", ""); + weechat::key_bind("mouse", \%mouse_keys); +} + +weechat::hook_command($cmd_buffers_whitelist, + "add/del current buffer to/from buffers whitelist", + "[add] || [del] || [reset]", + " add: add current buffer in configuration file\n". + " del: delete current buffer from configuration file\n". + "reset: reset all buffers from configuration file ". + "(no confirmation!)\n\n". + "Examples:\n". + "/$cmd_buffers_whitelist add\n", + "add %-||". + "del %-||". + "reset %-", + "buffers_cmd_whitelist", ""); +weechat::hook_command($cmd_buffers_detach, + "add/del current buffer to/from buffers detach", + "[add] || [del] || [reset]", + " add: add current buffer in configuration file\n". + " del: delete current buffer from configuration file\n". + "reset: reset all buffers from configuration file ". + "(no confirmation!)\n\n". + "Examples:\n". + "/$cmd_buffers_detach add\n", + "add %-||". + "del %-||". + "reset %-", + "buffers_cmd_detach", ""); + +if ($weechat_version >= 0x00030800) +{ + weechat::hook_config("buffers.look.detach", "hook_timer_detach", ""); + if (weechat::config_integer($options{"detach"}) > 0) + { + $Hooks{timer_detach} = weechat::hook_timer(weechat::config_integer($options{"detach"}) * 1000, + 60, 0, "buffers_signal_hotlist", ""); + } +} + +weechat::hook_config("buffers.look.show_lag", "hook_timer_lag", ""); + +if (weechat::config_boolean($options{"show_lag"})) +{ + $Hooks{timer_lag} = weechat::hook_timer( + weechat::config_integer(weechat::config_get("irc.network.lag_refresh_interval")) * 1000, + 0, 0, "buffers_signal_hotlist", ""); +} + +# -------------------------------- [ command ] -------------------------------- +sub buffers_cmd_whitelist +{ +my ( $data, $buffer, $args ) = @_; + $args = lc($args); + my $buffers_whitelist = weechat::config_string( weechat::config_get("buffers.look.whitelist_buffers") ); + return weechat::WEECHAT_RC_OK if ( $buffers_whitelist eq "" and $args eq "del" or $buffers_whitelist eq "" and $args eq "reset" ); + my @buffers_list = split( /,/, $buffers_whitelist ); + # get buffers name + my $infolist = weechat::infolist_get("buffer", weechat::current_buffer(), ""); + weechat::infolist_next($infolist); + my $buffers_name = weechat::infolist_string($infolist, "name"); + weechat::infolist_free($infolist); + return weechat::WEECHAT_RC_OK if ( $buffers_name eq "" ); # should never happen + + if ( $args eq "add" ) + { + return weechat::WEECHAT_RC_OK if ( grep /^$buffers_name$/, @buffers_list ); # check if buffer already in list + push @buffers_list, ( $buffers_name ); + my $buffers_list = &create_whitelist(\@buffers_list); + weechat::config_option_set( weechat::config_get("buffers.look.whitelist_buffers"), $buffers_list, 1); + weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" added to buffers whitelist"); + } + elsif ( $args eq "del" ) + { + return weechat::WEECHAT_RC_OK unless ( grep /^$buffers_name$/, @buffers_list ); # check if buffer is in list + @buffers_list = grep {$_ ne $buffers_name} @buffers_list; # delete entry + my $buffers_list = &create_whitelist(\@buffers_list); + weechat::config_option_set( weechat::config_get("buffers.look.whitelist_buffers"), $buffers_list, 1); + weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" deleted from buffers whitelist"); + } + elsif ( $args eq "reset" ) + { + return weechat::WEECHAT_RC_OK if ( $buffers_whitelist eq "" ); + weechat::config_option_set( weechat::config_get("buffers.look.whitelist_buffers"), "", 1); + weechat::print(weechat::current_buffer(), "buffers whitelist is empty, now..."); + } + return weechat::WEECHAT_RC_OK; +} +sub buffers_cmd_detach +{ + my ( $data, $buffer, $args ) = @_; + $args = lc($args); + my $immune_detach_buffers = weechat::config_string( weechat::config_get("buffers.look.immune_detach_buffers") ); + return weechat::WEECHAT_RC_OK if ( $immune_detach_buffers eq "" and $args eq "del" or $immune_detach_buffers eq "" and $args eq "reset" ); + + my @buffers_list = split( /,/, $immune_detach_buffers ); + # get buffers name + my $infolist = weechat::infolist_get("buffer", weechat::current_buffer(), ""); + weechat::infolist_next($infolist); + my $buffers_name = weechat::infolist_string($infolist, "name"); + weechat::infolist_free($infolist); + return weechat::WEECHAT_RC_OK if ( $buffers_name eq "" ); # should never happen + + if ( $args eq "add" ) + { + return weechat::WEECHAT_RC_OK if ( grep /^$buffers_name$/, @buffers_list ); # check if buffer already in list + push @buffers_list, ( $buffers_name ); + my $buffers_list = &create_whitelist(\@buffers_list); + weechat::config_option_set( weechat::config_get("buffers.look.immune_detach_buffers"), $buffers_list, 1); + weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" added to immune detach buffers"); + } + elsif ( $args eq "del" ) + { + return weechat::WEECHAT_RC_OK unless ( grep /^$buffers_name$/, @buffers_list ); # check if buffer is in list + @buffers_list = grep {$_ ne $buffers_name} @buffers_list; # delete entry + my $buffers_list = &create_whitelist(\@buffers_list); + weechat::config_option_set( weechat::config_get("buffers.look.immune_detach_buffers"), $buffers_list, 1); + weechat::print(weechat::current_buffer(), "buffer \"$buffers_name\" deleted from immune detach buffers"); + } + elsif ( $args eq "reset" ) + { + return weechat::WEECHAT_RC_OK if ( $immune_detach_buffers eq "" ); + weechat::config_option_set( weechat::config_get("buffers.look.immune_detach_buffers"), "", 1); + weechat::print(weechat::current_buffer(), "immune detach buffers is empty, now..."); + } + return weechat::WEECHAT_RC_OK; +} + +sub create_whitelist +{ + my @buffers_list = @{$_[0]}; + my $buffers_list = ""; + foreach (@buffers_list) + { + $buffers_list .= $_ .","; + } + # remove last "," + chop $buffers_list; + return $buffers_list; +} + +# -------------------------------- [ config ] -------------------------------- +sub hook_timer_detach +{ + my $detach = $_[2]; + if ( $detach eq 0 ) + { + weechat::unhook($Hooks{timer_detach}) if $Hooks{timer_detach}; + $Hooks{timer_detach} = ""; + } + else + { + weechat::unhook($Hooks{timer_detach}) if $Hooks{timer_detach}; + $Hooks{timer_detach} = weechat::hook_timer( weechat::config_integer( $options{"detach"}) * 1000, 60, 0, "buffers_signal_hotlist", ""); + } + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + +sub hook_timer_lag +{ + my $lag = $_[2]; + if ( $lag eq "off" ) + { + weechat::unhook($Hooks{timer_lag}) if $Hooks{timer_lag}; + $Hooks{timer_lag} = ""; + } + else + { + weechat::unhook($Hooks{timer_lag}) if $Hooks{timer_lag}; + $Hooks{timer_lag} = weechat::hook_timer( weechat::config_integer(weechat::config_get("irc.network.lag_refresh_interval")) * 1000, 0, 0, "buffers_signal_hotlist", ""); + } + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + +sub buffers_config_read +{ + return weechat::config_read($buffers_config_file) if ($buffers_config_file ne ""); +} +sub buffers_config_write +{ + return weechat::config_write($buffers_config_file) if ($buffers_config_file ne ""); +} +sub buffers_config_reload_cb +{ + my ($data, $config_file) = ($_[0], $_[1]); + return weechat::config_reload($config_file) +} +sub buffers_config_init +{ + $buffers_config_file = weechat::config_new($BUFFERS_CONFIG_FILE_NAME, + "buffers_config_reload_cb", ""); + return if ($buffers_config_file eq ""); + +my %default_options_color = +("color_current_fg" => [ + "current_fg", "color", + "foreground color for current buffer", + "", 0, 0, "lightcyan", "lightcyan", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_current_bg" => [ + "current_bg", "color", + "background color for current buffer", + "", 0, 0, "red", "red", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_default_fg" => [ + "default_fg", "color", + "default foreground color for buffer name", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_default_bg" => [ + "default_bg", "color", + "default background color for buffer name", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "color_hotlist_low_bg" => [ + "hotlist_low_bg", "color", + "change background color of buffer name if a low message received", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "color_number" => [ + "number", "color", + "color for buffer number", + "", 0, 0, "lightgreen", "lightgreen", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_number_char" => [ + "number_char", "color", + "color for buffer number char", + "", 0, 0, "lightgreen", "lightgreen", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_default_fg" => [ + "whitelist_default_fg", "color", + "default foreground color for whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_default_bg" => [ + "whitelist_default_bg", "color", + "default background color for whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_low_fg" => [ + "whitelist_low_fg", "color", + "low color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_low_bg" => [ + "whitelist_low_bg", "color", + "low color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_message_fg" => [ + "whitelist_message_fg", "color", + "message color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_message_bg" => [ + "whitelist_message_bg", "color", + "message color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_private_fg" => [ + "whitelist_private_fg", "color", + "private color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_private_bg" => [ + "whitelist_private_bg", "color", + "private color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_highlight_fg" => [ + "whitelist_highlight_fg", "color", + "highlight color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_whitelist_highlight_bg" => [ + "whitelist_highlight_bg", "color", + "highlight color of whitelist buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "queries_default_fg" => [ + "queries_default_fg", "color", + "foreground color for query buffer without message", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "queries_default_bg" => [ + "queries_default_bg", "color", + "background color for query buffer without message", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "queries_message_fg" => [ + "queries_message_fg", "color", + "foreground color for query buffer with unread message", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "queries_message_bg" => [ + "queries_message_bg", "color", + "background color for query buffer with unread message", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "queries_highlight_fg" => [ + "queries_highlight_fg", "color", + "foreground color for query buffer with unread highlight", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "queries_highlight_bg" => [ + "queries_highlight_bg", "color", + "background color for query buffer with unread highlight", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_prefix_bufname" => [ + "prefix_bufname", "color", + "color for prefix of buffer name", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "color_suffix_bufname" => [ + "suffix_bufname", "color", + "color for suffix of buffer name", + "", 0, 0, "default", "default", 0, + "", "", "buffers_signal_config", "", "", "" + ], +); + +my %default_options_look = +( + "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", "", "", "" + ], + "show_lag" => [ + "show_lag", "boolean", + "show lag behind server name. 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", "", "", "" + ], + "look_whitelist_buffers" => [ + "whitelist_buffers", "string", + "comma separated list of buffers for using a different color scheme ". + "(for example: freenode.#weechat,freenode.#weechat-fr)", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config_whitelist", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "indenting_amount" => [ + "indenting_amount", "integer", + "amount of indenting to use. This option only takes effect if bar ". + "is left/right positioned, and indenting is enabled", + "", 0, 16, 2, 2, 0, + "", "", "buffers_signal_config", "", "", "" + ], + "short_names" => [ + "short_names", "boolean", + "display short names (remove text before first \".\" in buffer name)", + "", 0, 0, "on", "on", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "show_number" => [ + "show_number", "boolean", + "display buffer number in front of buffer name", + "", 0, 0, "on", "on", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "show_number_char" => [ + "number_char", "string", + "display a char behind buffer number", + "", 0, 0, ".", ".", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "show_prefix_bufname" => [ + "prefix_bufname", "string", + "prefix displayed in front of buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "show_suffix_bufname" => [ + "suffix_bufname", "string", + "suffix displayed at end of buffer name", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "show_prefix" => [ + "prefix", "boolean", + "displays your prefix for channel in front of buffer name", + "", 0, 0, "off", "off", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "show_prefix_empty" => [ + "prefix_empty", "boolean", + "use a placeholder for channels without prefix", + "", 0, 0, "on", "on", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "show_prefix_query" => [ + "prefix_for_query", "string", + "prefix displayed in front of query buffer", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "sort" => [ + "sort", "integer", + "sort buffer-list by \"number\" or \"name\"", + "number|name", 0, 0, "number", "number", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "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", "", "", "" + ], + "name_size_max" => [ + "name_size_max", "integer", + "maximum size of buffer name. 0 means no limitation", + "", 0, 256, 0, 0, 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "detach" => [ + "detach", "integer", + "detach buffer 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", "", "", "" + ], + "immune_detach_buffers" => [ + "immune_detach_buffers", "string", + "comma separated list of buffers to NOT automatically detach. ". + "Allows \"*\" wildcard. Ex: \"BitlBee,freenode.*\"", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config_immune_detach_buffers", "", "", "" + ], + "detach_query" => [ + "detach_query", "boolean", + "query buffer will be detached", + "", 0, 0, "off", "off", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "detach_buffer_immediately" => [ + "detach_buffer_immediately", "string", + "comma separated list of buffers to detach immediately. Buffers ". + "will attach again based on notify level set in ". + "\"detach_buffer_immediately_level\". Allows \"*\" wildcard. ". + "Ex: \"BitlBee,freenode.*\"", + "", 0, 0, "", "", 0, + "", "", "buffers_signal_config_detach_buffer_immediately", "", "", "" + ], + "detach_buffer_immediately_level" => [ + "detach_buffer_immediately_level", "integer", + "The value determines what notify level messages are reattached from activity. ". + " This option works in conjunction with \"detach_buffer_immediately\" ". + "0: low priority (like join/part messages), ". + "1: message, ". + "2: private, ". + "3: highlight", + "", 0, 3, 2, 2, 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "detach_displayed_buffers" => [ + "detach_displayed_buffers", "boolean", + "buffers displayed in a (split) window will be detached", + "", 0, 0, "on", "on", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "mark_inactive" => [ + "mark_inactive", "boolean", + "if option is \"on\", inactive buffers (those you are not in) will have ". + "parentheses around them. An inactive buffer will not be detached.", + "", 0, 0, "off", "off", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "toggle_bar" => [ + "toggle_bar", "boolean", + "if option is \"on\", buffers bar will hide/show when script is ". + "(un)loaded.", + "", 0, 0, "on", "on", 0, + "", "", "buffers_signal_config", "", "", "" + ], + "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", "", "", "" + ], + "mouse_wheel" => [ + "mouse_wheel", "boolean", + "if option is \"on\", mouse wheel jumps to previous/next buffer in list.", + "", 0, 0, "on", "on", 0, + "", "", "buffers_signal_config", "", "", "" + ], +); + # section "color" + my $section_color = weechat::config_new_section( + $buffers_config_file, + "color", 0, 0, "", "", "", "", "", "", "", "", "", ""); + if ($section_color eq "") + { + weechat::config_free($buffers_config_file); + return; + } + foreach my $option (keys %default_options_color) + { + $options{$option} = weechat::config_new_option( + $buffers_config_file, + $section_color, + $default_options_color{$option}[0], + $default_options_color{$option}[1], + $default_options_color{$option}[2], + $default_options_color{$option}[3], + $default_options_color{$option}[4], + $default_options_color{$option}[5], + $default_options_color{$option}[6], + $default_options_color{$option}[7], + $default_options_color{$option}[8], + $default_options_color{$option}[9], + $default_options_color{$option}[10], + $default_options_color{$option}[11], + $default_options_color{$option}[12], + $default_options_color{$option}[13], + $default_options_color{$option}[14]); + } + + # section "look" + my $section_look = weechat::config_new_section( + $buffers_config_file, + "look", 0, 0, "", "", "", "", "", "", "", "", "", ""); + if ($section_look eq "") + { + weechat::config_free($buffers_config_file); + return; + } + foreach my $option (keys %default_options_look) + { + $options{$option} = weechat::config_new_option( + $buffers_config_file, + $section_look, + $default_options_look{$option}[0], + $default_options_look{$option}[1], + $default_options_look{$option}[2], + $default_options_look{$option}[3], + $default_options_look{$option}[4], + $default_options_look{$option}[5], + $default_options_look{$option}[6], + $default_options_look{$option}[7], + $default_options_look{$option}[8], + $default_options_look{$option}[9], + $default_options_look{$option}[10], + $default_options_look{$option}[11], + $default_options_look{$option}[12], + $default_options_look{$option}[13], + $default_options_look{$option}[14], + $default_options_look{$option}[15]); + } +} + +sub build_buffers +{ + my $str = ""; + + # get bar position (left/right/top/bottom) + my $position = "left"; + my $option_position = weechat::config_get("weechat.bar.buffers.position"); + if ($option_position ne "") + { + $position = weechat::config_string($option_position); + } + + # read hotlist + my %hotlist; + my $infolist = weechat::infolist_get("hotlist", "", ""); + while (weechat::infolist_next($infolist)) + { + $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")} = + weechat::infolist_integer($infolist, "priority"); + if ( weechat::config_boolean( $options{"hotlist_counter"} ) eq 1 and $weechat_version >= 0x00030500) + { + $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_00"} = + weechat::infolist_integer($infolist, "count_00"); # low message + $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_01"} = + weechat::infolist_integer($infolist, "count_01"); # channel message + $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_02"} = + weechat::infolist_integer($infolist, "count_02"); # private message + $hotlist{weechat::infolist_pointer($infolist, "buffer_pointer")."_count_03"} = + weechat::infolist_integer($infolist, "count_03"); # highlight message + } + } + weechat::infolist_free($infolist); + + # read buffers list + @buffers_focus = (); + my @buffers; + my @current1 = (); + my @current2 = (); + my $old_number = -1; + my $max_number = 0; + my $max_number_digits = 0; + my $active_seen = 0; + $infolist = weechat::infolist_get("buffer", "", ""); + while (weechat::infolist_next($infolist)) + { + # ignore hidden buffers (WeeChat >= 0.4.4) + if ($weechat_version >= 0x00040400) + { + next if (weechat::infolist_integer($infolist, "hidden")); + } + my $buffer; + my $number = weechat::infolist_integer($infolist, "number"); + if ($number ne $old_number) + { + @buffers = (@buffers, @current2, @current1); + @current1 = (); + @current2 = (); + $active_seen = 0; + } + if ($number > $max_number) + { + $max_number = $number; + } + $old_number = $number; + my $active = weechat::infolist_integer($infolist, "active"); + if ($active) + { + $active_seen = 1; + } + $buffer->{"pointer"} = weechat::infolist_pointer($infolist, "pointer"); + $buffer->{"number"} = $number; + $buffer->{"active"} = $active; + $buffer->{"current_buffer"} = weechat::infolist_integer($infolist, "current_buffer"); + $buffer->{"num_displayed"} = weechat::infolist_integer($infolist, "num_displayed"); + $buffer->{"plugin_name"} = weechat::infolist_string($infolist, "plugin_name"); + $buffer->{"name"} = weechat::infolist_string($infolist, "name"); + $buffer->{"short_name"} = weechat::infolist_string($infolist, "short_name"); + $buffer->{"full_name"} = $buffer->{"plugin_name"}.".".$buffer->{"name"}; + $buffer->{"type"} = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type"); + #weechat::print("", $buffer->{"type"}); + + # check if buffer is active (or maybe a /part, /kick channel) + if ($buffer->{"type"} eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1) + { + my $server = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_server"); + my $channel = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_channel"); + my $infolist_channel = weechat::infolist_get("irc_channel", "", $server.",".$channel); + if ($infolist_channel) + { + weechat::infolist_next($infolist_channel); + $buffer->{"nicks_count"} = weechat::infolist_integer($infolist_channel, "nicks_count"); + }else + { + $buffer->{"nicks_count"} = 0; + } + weechat::infolist_free($infolist_channel); + } + + my $result = check_immune_detached_buffers($buffer->{"name"}); # checking for wildcard + my $maxlevel = weechat::config_integer($options{"detach_buffer_immediately_level"}); + next if ( check_detach_buffer_immediately($buffer->{"name"}) eq 1 + and $buffer->{"current_buffer"} eq 0 + and ( not exists $hotlist{$buffer->{"pointer"}} or $hotlist{$buffer->{"pointer"}} < $maxlevel) ); # checking for buffer to immediately detach + + unless ($result) + { + my $detach_time = weechat::config_integer( $options{"detach"}); + my $current_time = time(); + # set timer for buffers with no hotlist action + $buffers_timer{$buffer->{"pointer"}} = $current_time + if ( not exists $hotlist{$buffer->{"pointer"}} + and $buffer->{"type"} eq "channel" + and not exists $buffers_timer{$buffer->{"pointer"}} + and $detach_time > 0); + + $buffers_timer{$buffer->{"pointer"}} = $current_time + if (weechat::config_boolean($options{"detach_query"}) eq 1 + and not exists $hotlist{$buffer->{"pointer"}} + and $buffer->{"type"} eq "private" + and not exists $buffers_timer{$buffer->{"pointer"}} + and $detach_time > 0); + + $detach_time = 0 + if (weechat::config_boolean($options{"detach_query"}) eq 0 + and $buffer->{"type"} eq "private"); + + # free content buffer + $buffers_timer{$buffer->{"pointer"}} = $current_time + if (weechat::config_boolean($options{"detach_free_content"}) eq 1 + and not exists $hotlist{$buffer->{"pointer"}} + and $buffer->{"type"} eq "" + and not exists $buffers_timer{$buffer->{"pointer"}} + and $detach_time > 0); + $detach_time = 0 + if (weechat::config_boolean($options{"detach_free_content"}) eq 0 + and $buffer->{"type"} eq ""); + + $detach_time = 0 if (weechat::config_boolean($options{"mark_inactive"}) eq 1 and defined $buffer->{"nicks_count"} and $buffer->{"nicks_count"} == 0); + + # check for detach + unless ( $buffer->{"current_buffer"} eq 0 + and not exists $hotlist{$buffer->{"pointer"}} +# and $buffer->{"type"} eq "channel" + and exists $buffers_timer{$buffer->{"pointer"}} + and $detach_time > 0 + and $weechat_version >= 0x00030800 + and $current_time - $buffers_timer{$buffer->{"pointer"}} >= $detach_time) + { + if ($active_seen) + { + push(@current2, $buffer); + } + else + { + push(@current1, $buffer); + } + } + elsif ( $buffer->{"current_buffer"} eq 0 + and not exists $hotlist{$buffer->{"pointer"}} +# and $buffer->{"type"} eq "channel" + and exists $buffers_timer{$buffer->{"pointer"}} + and $detach_time > 0 + and $weechat_version >= 0x00030800 + and $current_time - $buffers_timer{$buffer->{"pointer"}} >= $detach_time) + { # check for option detach_displayed_buffers and if buffer is displayed in a split window + if ( $buffer->{"num_displayed"} eq 1 + and weechat::config_boolean($options{"detach_displayed_buffers"}) eq 0 ) + { + my $infolist_window = weechat::infolist_get("window", "", ""); + while (weechat::infolist_next($infolist_window)) + { + my $buffer_ptr = weechat::infolist_pointer($infolist_window, "buffer"); + if ($buffer_ptr eq $buffer->{"pointer"}) + { + $buffer->{"window"} = weechat::infolist_integer($infolist_window, "number"); + } + } + weechat::infolist_free($infolist_window); + + push(@current2, $buffer); + } + } + } + else # buffer in "immune_detach_buffers" + { + if ($active_seen) + { + push(@current2, $buffer); + } + else + { + push(@current1, $buffer); + } + } + } # while end + + + if ($max_number >= 1) + { + $max_number_digits = length(int($max_number)); + } + @buffers = (@buffers, @current2, @current1); + weechat::infolist_free($infolist); + + # sort buffers by number, name or shortname + my %sorted_buffers; + if (1) + { + my $number = 0; + for my $buffer (@buffers) + { + my $key; + if (weechat::config_integer( $options{"sort"} ) eq 1) # number = 0; name = 1 + { + my $name = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_custom_name"); + if (not defined $name or $name eq "") { + if (weechat::config_boolean( $options{"short_names"} ) eq 1) { + $name = $buffer->{"short_name"}; + } else { + $name = $buffer->{"name"}; + } + } + if (weechat::config_integer($options{"name_size_max"}) >= 1) + { + $maxlength = weechat::config_integer($options{"name_size_max"}); + if($buffer->{"type"} eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1 and $buffer->{"nicks_count"} == 0) + { + $maxlength -= 2; + } + $name = encode("UTF-8", substr(decode("UTF-8", $name), 0, $maxlength)); + } + if ( weechat::config_boolean($options{"core_to_front"}) eq 1) + { + if ( (weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "channel" ) and ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "private") ) + { + my $type = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type"); + if ( $type eq "" and $name ne "weechat") + { + $name = " " . $name + }else + { + $name = " " . $name; + } + } + } + $key = sprintf("%s%08d", lc($name), $buffer->{"number"}); + } + else + { + $key = sprintf("%08d", $number); + } + $sorted_buffers{$key} = $buffer; + $number++; + } + } + + # build string with buffers + $old_number = -1; + foreach my $key (sort keys %sorted_buffers) + { + my $buffer = $sorted_buffers{$key}; + + if ( weechat::config_string($options{"hide_merged_buffers"}) eq "server" ) + { + # buffer type "server" or merged with core? + if ( ($buffer->{"type"} eq "server" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) ) + { + next; + } + } + if ( weechat::config_string($options{"hide_merged_buffers"}) eq "channel" ) + { + # buffer type "channel" or merged with core? + if ( ($buffer->{"type"} eq "channel" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) ) + { + next; + } + } + if ( weechat::config_string($options{"hide_merged_buffers"}) eq "private" ) + { + # buffer type "private" or merged with core? + if ( ($buffer->{"type"} eq "private" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) ) + { + next; + } + } + if ( weechat::config_string($options{"hide_merged_buffers"}) eq "keepserver" ) + { + if ( ($buffer->{"type"} ne "server" or $buffer->{"plugin_name"} eq "core") && (! $buffer->{"active"}) ) + { + next; + } + } + if ( weechat::config_string($options{"hide_merged_buffers"}) eq "all" ) + { + if ( ! $buffer->{"active"} ) + { + next; + } + } + + push(@buffers_focus, $buffer); # buffer > buffers_focus, for mouse support + my $color = ""; + my $bg = ""; + + $color = weechat::config_color( $options{"color_default_fg"} ); + $bg = weechat::config_color( $options{"color_default_bg"} ); + + if ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") eq "private" ) + { + if ( (weechat::config_color($options{"queries_default_bg"})) ne "default" || (weechat::config_color($options{"queries_default_fg"})) ne "default" ) + { + $bg = weechat::config_color( $options{"queries_default_bg"} ); + $color = weechat::config_color( $options{"queries_default_fg"} ); + } + } + # check for core and buffer with free content + if ( (weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "channel" ) and ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") ne "private") ) + { + $color = weechat::config_color( $options{"color_none_channel_fg"} ); + $bg = weechat::config_color( $options{"color_none_channel_bg"} ); + } + # default whitelist buffer? + if (grep {$_ eq $buffer->{"name"}} @whitelist_buffers) + { + $color = weechat::config_color( $options{"color_whitelist_default_fg"} ); + $bg = weechat::config_color( $options{"color_whitelist_default_bg"} ); + } + + $color = "default" if ($color eq ""); + + # color for channel and query buffer + if (exists $hotlist{$buffer->{"pointer"}}) + { + delete $buffers_timer{$buffer->{"pointer"}}; + # check if buffer is in whitelist buffer + if (grep {$_ eq $buffer->{"name"}} @whitelist_buffers) + { + $bg = weechat::config_color( $options{"color_whitelist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_bg"} ); + $color = weechat::config_color( $options{"color_whitelist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_fg"} ); + } + elsif ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") eq "private" ) + { + # queries_default_fg/bg and buffers.color.queries_message_fg/bg + if ( (weechat::config_color($options{"queries_highlight_fg"})) ne "default" || + (weechat::config_color($options{"queries_highlight_bg"})) ne "default" || + (weechat::config_color($options{"queries_message_fg"})) ne "default" || + (weechat::config_color($options{"queries_message_bg"})) ne "default" ) + { + if ( ($hotlist{$buffer->{"pointer"}}) == 2 ) + { + $bg = weechat::config_color( $options{"queries_message_bg"} ); + $color = weechat::config_color( $options{"queries_message_fg"} ); + } + + elsif ( ($hotlist{$buffer->{"pointer"}}) == 3 ) + { + $bg = weechat::config_color( $options{"queries_highlight_bg"} ); + $color = weechat::config_color( $options{"queries_highlight_fg"} ); + } + }else + { + $bg = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_bg"} ); + $color = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_fg"} ); + } + }else + { + $bg = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_bg"} ); + $color = weechat::config_color( $options{"color_hotlist_".$hotlist_level{$hotlist{$buffer->{"pointer"}}}."_fg"} ); + } + } + + if ($buffer->{"current_buffer"}) + { + $color = weechat::config_color( $options{"color_current_fg"} ); + $bg = weechat::config_color( $options{"color_current_bg"} ); + } + my $color_bg = ""; + $color_bg = weechat::color(",".$bg) if ($bg ne ""); + + # create channel number for output + if ( weechat::config_string( $options{"show_prefix_bufname"} ) ne "" ) + { + $str .= $color_bg . + weechat::color( weechat::config_color( $options{"color_prefix_bufname"} ) ). + weechat::config_string( $options{"show_prefix_bufname"} ). + weechat::color("default"); + } + + if ( weechat::config_boolean( $options{"show_number"} ) eq 1 ) # on + { + if (( weechat::config_boolean( $options{"indenting_number"} ) eq 1) + && (($position eq "left") || ($position eq "right"))) + { + $str .= weechat::color("default").$color_bg + .(" " x ($max_number_digits - length(int($buffer->{"number"})))); + } + if ($old_number ne $buffer->{"number"}) + { + $str .= weechat::color( weechat::config_color( $options{"color_number"} ) ) + .$color_bg + .$buffer->{"number"} + .weechat::color("default") + .$color_bg + .weechat::color( weechat::config_color( $options{"color_number_char"} ) ) + .weechat::config_string( $options{"show_number_char"} ) + .$color_bg; + } + else + { + # Indentation aligns channels in a visually appealing way + # when viewing list top-to-bottom... + my $indent = (" " x length($buffer->{"number"}))." "; + # ...except when list is top/bottom and channels left-to-right. + my $option_pos = weechat::config_string( weechat::config_get( "weechat.bar.buffers.position" ) ); + if (($option_pos eq 'top') || ($option_pos eq 'bottom')) { + my $option_filling = weechat::config_string( weechat::config_get( "weechat.bar.buffers.filling_top_bottom" ) ); + if ($option_filling =~ /horizontal/) { + $indent = ''; + } + } + $str .= weechat::color("default") + .$color_bg + .$indent; + } + } + + if (( weechat::config_integer( $options{"indenting"} ) ne 0 ) # indenting NOT off + && (($position eq "left") || ($position eq "right"))) + { + my $type = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type"); + if (($type eq "channel") || ($type eq "private")) + { + if ( weechat::config_integer( $options{"indenting"} ) eq 1 ) + { + $str .= (" " x weechat::config_integer( $options{"indenting_amount"} ) ); + } + elsif ( (weechat::config_integer($options{"indenting"}) eq 2) and (weechat::config_integer($options{"indenting_number"}) eq 0) ) #under_name + { + if ( weechat::config_boolean( $options{"show_number"} ) eq 0 ) + { + $str .= (" " x weechat::config_integer( $options{"indenting_amount"} ) ); + } + else + { + $str .= ( (" " x ( $max_number_digits - length($buffer->{"number"}) )).(" " x weechat::config_integer( $options{"indenting_amount"} ) ) ); + } + } + } + } + + $str .= weechat::config_string( $options{"show_prefix_query"}) if (weechat::config_string( $options{"show_prefix_query"} ) ne "" and $buffer->{"type"} eq "private"); + + if (weechat::config_boolean( $options{"show_prefix"} ) eq 1) + { + my $nickname = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_nick"); + if ($nickname ne "") + { + # with version >= 0.3.2, this infolist will return only nick + # with older versions, whole nicklist is returned for buffer, and this can be very slow + my $infolist_nick = weechat::infolist_get("nicklist", $buffer->{"pointer"}, "nick_".$nickname); + if ($infolist_nick ne "") + { + while (weechat::infolist_next($infolist_nick)) + { + if ((weechat::infolist_string($infolist_nick, "type") eq "nick") + && (weechat::infolist_string($infolist_nick, "name") eq $nickname)) + { + my $prefix = weechat::infolist_string($infolist_nick, "prefix"); + if (($prefix ne " ") or (weechat::config_boolean( $options{"show_prefix_empty"} ) eq 1)) + { + # with version >= 0.3.5, it is now a color name (for older versions: option name with color) + if (int($weechat_version) >= 0x00030500) + { + $str .= weechat::color(weechat::infolist_string($infolist_nick, "prefix_color")); + } + else + { + $str .= weechat::color(weechat::config_color( + weechat::config_get( + weechat::infolist_string($infolist_nick, "prefix_color")))); + } + $str .= $prefix; + } + last; + } + } + weechat::infolist_free($infolist_nick); + } + } + } + if ($buffer->{"type"} eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1 and $buffer->{"nicks_count"} == 0) + { + $str .= "("; + } + + $str .= weechat::color($color) . weechat::color(",".$bg); + + my $name = weechat::buffer_get_string($buffer->{"pointer"}, "localvar_custom_name"); + if (not defined $name or $name eq "") + { + if (weechat::config_boolean( $options{"short_names"} ) eq 1) { + $name = $buffer->{"short_name"}; + } else { + $name = $buffer->{"name"}; + } + } + + if (weechat::config_integer($options{"name_size_max"}) >= 1) # check max_size of buffer name + { + $name = decode("UTF-8", $name); + + $maxlength = weechat::config_integer($options{"name_size_max"}); + if($buffer->{"type"} eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1 and $buffer->{"nicks_count"} == 0) + { + $maxlength -= 2; + } + + $str .= encode("UTF-8", substr($name, 0, $maxlength)); + $str .= weechat::color(weechat::config_color( $options{"color_number_char"})).weechat::config_string($options{"name_crop_suffix"}) if (length($name) > weechat::config_integer($options{"name_size_max"})); + $str .= add_inactive_parentless($buffer->{"type"}, $buffer->{"nicks_count"}); + $str .= add_hotlist_count($buffer->{"pointer"}, %hotlist); + } + else + { + $str .= $name; + $str .= add_inactive_parentless($buffer->{"type"}, $buffer->{"nicks_count"}); + $str .= add_hotlist_count($buffer->{"pointer"}, %hotlist); + } + + if ( weechat::buffer_get_string($buffer->{"pointer"}, "localvar_type") eq "server" and weechat::config_boolean($options{"show_lag"}) eq 1) + { + my $color_lag = weechat::config_color(weechat::config_get("irc.color.item_lag_finished")); + my $min_lag = weechat::config_integer(weechat::config_get("irc.network.lag_min_show")); + my $infolist_server = weechat::infolist_get("irc_server", "", $buffer->{"short_name"}); + weechat::infolist_next($infolist_server); + my $lag = (weechat::infolist_integer($infolist_server, "lag")); + weechat::infolist_free($infolist_server); + if ( int($lag) > int($min_lag) ) + { + $lag = $lag / 1000; + $str .= weechat::color("default") . " (" . weechat::color($color_lag) . $lag . weechat::color("default") . ")"; + } + } + if (weechat::config_boolean($options{"detach_displayed_buffers"}) eq 0 + and weechat::config_boolean($options{"detach_display_window_number"}) eq 1) + { + if ($buffer->{"window"}) + { + $str .= weechat::color("default") . " (" . weechat::color(weechat::config_color( $options{"color_number"})) . $buffer->{"window"} . weechat::color("default") . ")"; + } + } + $str .= weechat::color("default"); + + if ( weechat::config_string( $options{"show_suffix_bufname"} ) ne "" ) + { + $str .= weechat::color( weechat::config_color( $options{"color_suffix_bufname"} ) ). + weechat::config_string( $options{"show_suffix_bufname"} ). + weechat::color("default"); + } + + $str .= "\n"; + $old_number = $buffer->{"number"}; + } + + # remove spaces and/or linefeed at the end + $str =~ s/\s+$//; + chomp($str); + return $str; +} + +sub add_inactive_parentless +{ +my ($buf_type, $buf_nicks_count) = @_; +my $str = ""; + if ($buf_type eq "channel" and weechat::config_boolean( $options{"mark_inactive"} ) eq 1 and $buf_nicks_count == 0) + { + $str .= weechat::color(weechat::config_color( $options{"color_number_char"})); + $str .= ")"; + } +return $str; +} + +sub add_hotlist_count +{ +my ($bufpointer, %hotlist) = @_; + +return "" if ( weechat::config_boolean( $options{"hotlist_counter"} ) eq 0 or ($weechat_version < 0x00030500)); # off +my $col_number_char = weechat::color(weechat::config_color( $options{"color_number_char"}) ); +my $str = " ".$col_number_char."("; + +# 0 = low level +if (defined $hotlist{$bufpointer."_count_00"}) +{ + my $bg = weechat::config_color( $options{"color_hotlist_low_bg"} ); + my $color = weechat::config_color( $options{"color_hotlist_low_fg"} ); + $str .= weechat::color($bg). + weechat::color($color). + $hotlist{$bufpointer."_count_00"} if ($hotlist{$bufpointer."_count_00"} ne "0"); +} + +# 1 = message +if (defined $hotlist{$bufpointer."_count_01"}) +{ + my $bg = weechat::config_color( $options{"color_hotlist_message_bg"} ); + my $color = weechat::config_color( $options{"color_hotlist_message_fg"} ); + if ($str =~ /[0-9]$/) + { + $str .= ",". + weechat::color($bg). + weechat::color($color). + $hotlist{$bufpointer."_count_01"} if ($hotlist{$bufpointer."_count_01"} ne "0"); + }else + { + $str .= weechat::color($bg). + weechat::color($color). + $hotlist{$bufpointer."_count_01"} if ($hotlist{$bufpointer."_count_01"} ne "0"); + } +} +# 2 = private +if (defined $hotlist{$bufpointer."_count_02"}) +{ + my $bg = weechat::config_color( $options{"color_hotlist_private_bg"} ); + my $color = weechat::config_color( $options{"color_hotlist_private_fg"} ); + if ($str =~ /[0-9]$/) + { + $str .= ",". + weechat::color($bg). + weechat::color($color). + $hotlist{$bufpointer."_count_02"} if ($hotlist{$bufpointer."_count_02"} ne "0"); + }else + { + $str .= weechat::color($bg). + weechat::color($color). + $hotlist{$bufpointer."_count_02"} if ($hotlist{$bufpointer."_count_02"} ne "0"); + } +} +# 3 = highlight +if (defined $hotlist{$bufpointer."_count_03"}) +{ + my $bg = weechat::config_color( $options{"color_hotlist_highlight_bg"} ); + my $color = weechat::config_color( $options{"color_hotlist_highlight_fg"} ); + if ($str =~ /[0-9]$/) + { + $str .= ",". + weechat::color($bg). + weechat::color($color). + $hotlist{$bufpointer."_count_03"} if ($hotlist{$bufpointer."_count_03"} ne "0"); + }else + { + $str .= weechat::color($bg). + weechat::color($color). + $hotlist{$bufpointer."_count_03"} if ($hotlist{$bufpointer."_count_03"} ne "0"); + } +} +$str .= $col_number_char. ")"; + +$str = "" if (weechat::string_remove_color($str, "") eq " ()"); # remove color and check for buffer with no messages +return $str; +} + +sub buffers_signal_buffer +{ + my ($data, $signal, $signal_data) = @_; + + # check for buffer_switch and set or remove detach time + if ($weechat_version >= 0x00030800) + { + if ($signal eq "buffer_switch") + { + my $pointer = weechat::hdata_get_list (weechat::hdata_get("buffer"), "gui_buffer_last_displayed"); # get switched buffer + my $current_time = time(); + if ( weechat::buffer_get_string($pointer, "localvar_type") eq "channel") + { + $buffers_timer{$pointer} = $current_time; + } + else + { + delete $buffers_timer{$pointer}; + } + } + if ($signal eq "buffer_opened") + { + my $current_time = time(); + $buffers_timer{$signal_data} = $current_time; + } + if ($signal eq "buffer_closing") + { + delete $buffers_timer{$signal_data}; + } + } + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + +sub buffers_signal_hotlist +{ + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + + +sub buffers_signal_config_whitelist +{ + @whitelist_buffers = (); + @whitelist_buffers = split( /,/, weechat::config_string( $options{"look_whitelist_buffers"} ) ); + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + +sub buffers_signal_config_immune_detach_buffers +{ + @immune_detach_buffers = (); + @immune_detach_buffers = split( /,/, weechat::config_string( $options{"immune_detach_buffers"} ) ); + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + +sub buffers_signal_config_detach_buffer_immediately +{ + @detach_buffer_immediately = (); + @detach_buffer_immediately = split( /,/, weechat::config_string( $options{"detach_buffer_immediately"} ) ); + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + +sub buffers_signal_config +{ + weechat::bar_item_update($SCRIPT_NAME); + return weechat::WEECHAT_RC_OK; +} + +# called when mouse click occured in buffers item: this callback returns buffer +# hash according to line of item where click occured +sub buffers_focus_buffers +{ + my %info = %{$_[1]}; + my $item_line = int($info{"_bar_item_line"}); + undef my $hash; + if (($info{"_bar_item_name"} eq $SCRIPT_NAME) && ($item_line >= 0) && ($item_line <= $#buffers_focus)) + { + $hash = $buffers_focus[$item_line]; + } + else + { + $hash = {}; + my $hash_focus = $buffers_focus[0]; + foreach my $key (keys %$hash_focus) + { + $hash->{$key} = "?"; + } + } + return $hash; +} + +# called when a mouse action is done on buffers item, to execute action +# possible actions: jump to a buffer or move buffer in list (drag & drop of buffer) +sub buffers_hsignal_mouse +{ + my ($data, $signal, %hash) = ($_[0], $_[1], %{$_[2]}); + my $current_buffer = weechat::buffer_get_integer(weechat::current_buffer(), "number"); # get current buffer number + + if ( $hash{"_key"} eq "button1" ) + { + # left mouse button + if ($hash{"number"} eq $hash{"number2"}) + { + if ( weechat::config_boolean($options{"jump_prev_next_visited_buffer"}) ) + { + if ( $current_buffer eq $hash{"number"} ) + { + weechat::command("", "/input jump_previously_visited_buffer"); + } + else + { + weechat::command("", "/buffer ".$hash{"full_name"}); + } + } + else + { + weechat::command("", "/buffer ".$hash{"full_name"}); + } + } + else + { + move_buffer(%hash) if (weechat::config_boolean($options{"mouse_move_buffer"})); + } + } + elsif ( ($hash{"_key"} eq "button2") && (weechat::config_boolean($options{"jump_prev_next_visited_buffer"})) ) + { + # right mouse button + if ( $current_buffer eq $hash{"number2"} ) + { + weechat::command("", "/input jump_next_visited_buffer"); + } + } + elsif ( $hash{"_key"} =~ /wheelup$/ ) + { + # wheel up + if (weechat::config_boolean($options{"mouse_wheel"})) + { + weechat::command("", "/buffer -1"); + } + } + elsif ( $hash{"_key"} =~ /wheeldown$/ ) + { + # wheel down + if (weechat::config_boolean($options{"mouse_wheel"})) + { + weechat::command("", "/buffer +1"); + } + } + else + { + my $infolist = weechat::infolist_get("hook", "", "command,menu"); + my $has_menu_command = weechat::infolist_next($infolist); + weechat::infolist_free($infolist); + + if ( $has_menu_command && $hash{"_key"} =~ /button2/ ) + { + if ($hash{"number"} eq $hash{"number2"}) + { + weechat::command($hash{"pointer"}, "/menu buffer1 $hash{short_name} $hash{number}"); + } + else + { + weechat::command($hash{"pointer"}, "/menu buffer2 $hash{short_name}/$hash{short_name2} $hash{number} $hash{number2}") + } + } + else + { + move_buffer(%hash) if (weechat::config_boolean($options{"mouse_move_buffer"})); + } + } +} + +sub move_buffer +{ + my %hash = @_; + my $number2 = $hash{"number2"}; + if ($number2 eq "?") + { + # if number 2 is not known (end of gesture outside buffers list), then set it + # according to mouse gesture + $number2 = "1"; + if (($hash{"_key"} =~ /gesture-right/) || ($hash{"_key"} =~ /gesture-down/)) + { + $number2 = "999999"; + if ($weechat_version >= 0x00030600) + { + my $hdata_buffer = weechat::hdata_get("buffer"); + my $last_gui_buffer = weechat::hdata_get_list($hdata_buffer, "last_gui_buffer"); + if ($last_gui_buffer) + { + $number2 = weechat::hdata_integer($hdata_buffer, $last_gui_buffer, "number") + 1; + } + } + } + } + my $ptrbuf = weechat::current_buffer(); + weechat::command($hash{"pointer"}, "/buffer move ".$number2); +} + +sub check_immune_detached_buffers +{ + my ($buffername) = @_; + foreach ( @immune_detach_buffers ){ + my $immune_buffer = weechat::string_mask_to_regex($_); + if ($buffername =~ /^$immune_buffer$/i) + { + return 1; + } + } + return 0; +} + +sub check_detach_buffer_immediately +{ + my ($buffername) = @_; + foreach ( @detach_buffer_immediately ){ + my $detach_buffer = weechat::string_mask_to_regex($_); + if ($buffername =~ /^$detach_buffer$/i) + { + return 1; + } + } + return 0; +} + +sub shutdown_cb +{ + weechat::command("", "/bar hide " . $SCRIPT_NAME) if ( weechat::config_boolean($options{"toggle_bar"}) eq 1 ); + return weechat::WEECHAT_RC_OK +} + +sub check_bar_item +{ + my $item = 0; + my $infolist = weechat::infolist_get("bar", "", ""); + while (weechat::infolist_next($infolist)) + { + my $bar_items = weechat::infolist_string($infolist, "items"); + if (index($bar_items, $SCRIPT_NAME) != -1) + { + my $name = weechat::infolist_string($infolist, "name"); + if ($name ne $SCRIPT_NAME) + { + $item = 1; + last; + } + } + } + weechat::infolist_free($infolist); + return $item; +} diff --git a/weechat/.config/weechat/perl/iset.pl b/weechat/.config/weechat/perl/iset.pl new file mode 100644 index 0000000..163dfb5 --- /dev/null +++ b/weechat/.config/weechat/perl/iset.pl @@ -0,0 +1,1624 @@ +# +# Copyright (C) 2008-2014 Sebastien Helleu +# Copyright (C) 2010-2015 Nils Görs +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Set WeeChat and plugins options interactively. +# +# History: +# +# 2016-07-08, nils_2 +# version 4.2: add diff function +# 2016-02-06, Sebastien Helleu : +# version 4.1: remove debug print +# 2015-12-24, Sebastien Helleu : +# version 4.0: add support of parent options (inherited values in irc servers) +# with WeeChat >= 1.4 +# 2015-05-16, Sebastien Helleu : +# version 3.9: fix cursor position when editing an option with WeeChat >= 1.2 +# 2015-05-02, arza : +# version 3.8: don't append "null" to /set when setting an undefined setting +# 2015-05-01, nils_2 : +# version 3.7: fix two perl warnings (reported by t3chguy) +# 2014-09-30, arza : +# version 3.6: fix current line counter when options aren't found +# 2014-06-03, nils_2 : +# version 3.5: add new option "use_mute" +# 2014-01-30, stfn : +# version 3.4: add new options "color_value_diff" and "color_value_diff_selected" +# 2014-01-16, luz : +# version 3.3: fix bug with column alignment in iset buffer when option +# name contains unicode characters +# 2013-08-03, Sebastien Helleu : +# version 3.2: allow "q" as input in iset buffer to close it +# 2013-07-14, Sebastien Helleu : +# version 3.1: remove unneeded calls to iset_refresh() in mouse callback +# (faster mouse actions when lot of options are displayed), +# fix bug when clicking on a line after the last option displayed +# 2013-04-30, arza : +# version 3.0: simpler title, fix refresh on unset +# 2012-12-16, nils_2 : +# version 2.9: fix focus window with iset buffer on mouse click +# 2012-08-25, nils_2 : +# version 2.8: most important key and mouse bindings for iset buffer added to title-bar (idea The-Compiler) +# 2012-07-31, nils_2 : +# version 2.7: add combined option and value search (see /help iset) +# : add exact value search (see /help iset) +# : fix problem with metacharacter in value search +# : fix use of uninitialized value for unset option and reset value of option +# 2012-07-25, nils_2 : +# version 2.6: switch to iset buffer (if existing) when command /iset is called with arguments +# 2012-03-17, Sebastien Helleu : +# version 2.5: fix check of sections when creating config file +# 2012-03-09, Sebastien Helleu : +# version 2.4: fix reload of config file +# 2012-02-02, nils_2 : +# version 2.3: fixed: refresh problem with new search results and cursor was outside window. +# : add: new option "current_line" in title bar +# version 2.2: fixed: refresh error when toggling plugins description +# 2011-11-05, nils_2 : +# version 2.1: use own config file (iset.conf), fix own help color (used immediately) +# 2011-10-16, nils_2 : +# version 2.0: add support for left-mouse-button and more sensitive mouse gesture (for integer/color options) +# add help text for mouse support +# 2011-09-20, Sebastien Helleu : +# version 1.9: add mouse support, fix iset buffer, fix errors on first load under FreeBSD +# 2011-07-21, nils_2 : +# version 1.8: added: option "show_plugin_description" (alt+p) +# fixed: typos in /help iset (lower case for alt+'x' keys) +# 2011-05-29, nils_2 : +# version 1.7: added: version check for future needs +# added: new option (scroll_horiz) and usage of scroll_horiz function (weechat >= 0.3.6 required) +# fixed: help_bar did not pop up immediately using key-shortcut +# 2011-02-19, nils_2 : +# version 1.6: added: display of all possible values in help bar (show_help_extra_info) +# fixed: external user options never loaded when starting iset first time +# 2011-02-13, Sebastien Helleu : +# version 1.5: use new help format for command arguments +# 2011-02-03, nils_2 : +# version 1.4: fixed: restore value filter after /upgrade using buffer local variable. +# 2011-01-14, nils_2 : +# version 1.3: added function to search for values (option value_search_char). +# code optimization. +# 2010-12-26, Sebastien Helleu : +# version 1.2: improve speed of /upgrade when iset buffer is open, +# restore filter used after /upgrade using buffer local variable, +# use /iset filter argument if buffer is open. +# 2010-11-21, drubin : +# version 1.1.1: fix bugs with cursor position +# 2010-11-20, nils_2 : +# version 1.1: cursor position set to value +# 2010-08-03, Sebastien Helleu : +# version 1.0: move misplaced call to infolist_free() +# 2010-02-02, rettub : +# version 0.9: turn all the help stuff off if option 'show_help_bar' is 'off', +# new key binding - to toggle help_bar and help stuff on/off +# 2010-01-30, nils_2 : +# version 0.8: fix error when option does not exist +# 2010-01-24, Sebastien Helleu : +# version 0.7: display iset bar only on iset buffer +# 2010-01-22, nils_2 and drubin: +# version 0.6: add description in a bar, fix singular/plural bug in title bar, +# fix selected line when switching buffer +# 2009-06-21, Sebastien Helleu : +# version 0.5: fix bug with iset buffer after /upgrade +# 2009-05-02, Sebastien Helleu : +# version 0.4: sync with last API changes +# 2009-01-04, Sebastien Helleu : +# version 0.3: open iset buffer when /iset command is executed +# 2009-01-04, Sebastien Helleu : +# version 0.2: use null values for options, add colors, fix refresh bugs, +# use new keys to reset/unset options, sort options by name, +# display number of options in buffer's title +# 2008-11-05, Sebastien Helleu : +# version 0.1: first official version +# 2008-04-19, Sebastien Helleu : +# script creation + +use strict; + +my $PRGNAME = "iset"; +my $VERSION = "4.2"; +my $DESCR = "Interactive Set for configuration options"; +my $AUTHOR = "Sebastien Helleu "; +my $LICENSE = "GPL3"; +my $LANG = "perl"; +my $ISET_CONFIG_FILE_NAME = "iset"; + +my $iset_config_file; +my $iset_buffer = ""; +my $wee_version_number = 0; +my @iset_focus = (); +my @options_names = (); +my @options_parent_names = (); +my @options_types = (); +my @options_values = (); +my @options_default_values = (); +my @options_parent_values = (); +my @options_is_null = (); +my $option_max_length = 0; +my $current_line = 0; +my $filter = "*"; +my $description = ""; +my $options_name_copy = ""; +my $iset_filter_title = ""; +# search modes: 0 = index() on value, 1 = grep() on value, 2 = grep() on option, 3 = grep on option & value, 4 = diff all, 5 = diff parts +my $search_mode = 2; +my $search_value = ""; +my $help_text_keys = "alt + space: toggle, +/-: increase/decrease, enter: change, ir: reset, iu: unset, v: toggle help bar"; +my $help_text_mouse = "Mouse: left: select, right: toggle/set, right + drag left/right: increase/decrease"; +my %options_iset; + +my %mouse_keys = ("\@chat(perl.$PRGNAME):button1" => "hsignal:iset_mouse", + "\@chat(perl.$PRGNAME):button2*" => "hsignal:iset_mouse", + "\@chat(perl.$PRGNAME):wheelup" => "/repeat 5 /iset **up", + "\@chat(perl.$PRGNAME):wheeldown" => "/repeat 5 /iset **down"); + + +sub iset_title +{ + if ($iset_buffer ne "") + { + my $current_line_counter = ""; + if (weechat::config_boolean($options_iset{"show_current_line"}) == 1) + { + if (@options_names eq 0) + { + $current_line_counter = "0/"; + } + else + { + $current_line_counter = ($current_line + 1) . "/"; + } + } + my $show_filter = ""; + if ($search_mode eq 0) + { + $iset_filter_title = "(value) "; + $show_filter = $search_value; + if ( substr($show_filter,0,1) eq weechat::config_string($options_iset{"value_search_char"}) ) + { + $show_filter = substr($show_filter,1,length($show_filter)); + } + } + elsif ($search_mode eq 1) + { + $iset_filter_title = "(value) "; + $show_filter = "*".$search_value."*"; + } + elsif ($search_mode eq 2) + { + $iset_filter_title = ""; + $filter = "*" if ($filter eq ""); + $show_filter = $filter; + } + elsif ($search_mode == 4 or $search_mode == 5) + { + $iset_filter_title = "diff: "; + $show_filter = "all"; + $show_filter = $search_value if $search_mode == 5; + } + elsif ($search_mode eq 3) + { + $iset_filter_title = "(option) "; + $show_filter = $filter + .weechat::color("default") + ." / (value) " + .weechat::color("yellow") + ."*".$search_value."*"; + } + weechat::buffer_set($iset_buffer, "title", + $iset_filter_title + .weechat::color("yellow") + .$show_filter + .weechat::color("default")." | " + .$current_line_counter + .@options_names + ." | " + .$help_text_keys + ." | " + .$help_text_mouse); + } +} + +sub iset_create_filter +{ + $filter = $_[0]; + if ( $search_mode == 3 ) + { + my @cmd_array = split(/ /,$filter); + my $array_count = @cmd_array; + $filter = $cmd_array[0]; + $filter = $cmd_array[0] . " " . $cmd_array[1] if ( $array_count >2 ); + } + $filter = "$1.*" if ($filter =~ /f (.*)/); # search file + $filter = "*.$1.*" if ($filter =~ /s (.*)/); # search section + if ((substr($filter, 0, 1) ne "*") && (substr($filter, -1, 1) ne "*")) + { + $filter = "*".$filter."*"; + } + if ($iset_buffer ne "") + { + weechat::buffer_set($iset_buffer, "localvar_set_iset_filter", $filter); + } +} + +sub iset_buffer_input +{ + my ($data, $buffer, $string) = ($_[0], $_[1], $_[2]); + + # string begins with space? + return weechat::WEECHAT_RC_OK if (substr($string, 0, 1 ) eq " "); + + if ($string eq "q") + { + weechat::buffer_close($buffer); + return weechat::WEECHAT_RC_OK; + } + $search_value = ""; + my @cmd_array = split(/ /,$string); + my $array_count = @cmd_array; + my $string2 = substr($string, 0, 1); + if ($string2 eq weechat::config_string($options_iset{"value_search_char"}) + or (defined $cmd_array[0] and $cmd_array[0] eq weechat::config_string($options_iset{"value_search_char"}).weechat::config_string($options_iset{"value_search_char"})) ) + { + $search_mode = 1; + $search_value = substr($string, 1); + iset_get_values($search_value); + if ($iset_buffer ne "") + { + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_value", $search_value); + } + } + # show all diff values + elsif ($string eq "d") + { + $search_mode = 4; +# iset_title(); + iset_create_filter("*"); + iset_get_options("*"); + } + elsif ( $array_count >= 2 and $cmd_array[0] eq "d") + { + $search_mode = 5; + $search_value = substr($cmd_array[1], 0); # cut value_search_char + $search_value = substr($cmd_array[2], 0) if ( $array_count > 2); # cut value_search_char + iset_create_filter($search_value); + iset_get_options($search_value); + + } + else + { + $search_mode = 2; + if ( $array_count >= 2 and $cmd_array[0] ne "f" or $cmd_array[0] ne "s" ) + { + if ( defined $cmd_array[1] and substr($cmd_array[1], 0, 1) eq weechat::config_string($options_iset{"value_search_char"}) + or defined $cmd_array[2] and substr($cmd_array[2], 0, 1) eq weechat::config_string($options_iset{"value_search_char"}) ) + { + $search_mode = 3; + $search_value = substr($cmd_array[1], 1); # cut value_search_char + $search_value = substr($cmd_array[2], 1) if ( $array_count > 2); # cut value_search_char + } + } + if ( $search_mode == 3) + { + iset_create_filter($string); + iset_get_options($search_value); + } + else + { + iset_create_filter($string); + iset_get_options(""); + } + } + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_mode", $search_mode); + weechat::buffer_clear($buffer); + $current_line = 0; + iset_refresh(); + return weechat::WEECHAT_RC_OK; +} + +sub iset_buffer_close +{ + $iset_buffer = ""; + + return weechat::WEECHAT_RC_OK; +} + +sub iset_init +{ + $current_line = 0; + $iset_buffer = weechat::buffer_search($LANG, $PRGNAME); + if ($iset_buffer eq "") + { + $iset_buffer = weechat::buffer_new($PRGNAME, "iset_buffer_input", "", "iset_buffer_close", ""); + } + else + { + my $new_filter = weechat::buffer_get_string($iset_buffer, "localvar_iset_filter"); + $search_mode = weechat::buffer_get_string($iset_buffer, "localvar_iset_search_mode"); + $search_value = weechat::buffer_get_string($iset_buffer, "localvar_iset_search_value"); + $filter = $new_filter if ($new_filter ne ""); + } + if ($iset_buffer ne "") + { + weechat::buffer_set($iset_buffer, "type", "free"); + iset_title(); + weechat::buffer_set($iset_buffer, "key_bind_ctrl-L", "/iset **refresh"); + weechat::buffer_set($iset_buffer, "key_bind_meta2-A", "/iset **up"); + weechat::buffer_set($iset_buffer, "key_bind_meta2-B", "/iset **down"); + weechat::buffer_set($iset_buffer, "key_bind_meta2-23~", "/iset **left"); + weechat::buffer_set($iset_buffer, "key_bind_meta2-24~" , "/iset **right"); + weechat::buffer_set($iset_buffer, "key_bind_meta- ", "/iset **toggle"); + weechat::buffer_set($iset_buffer, "key_bind_meta-+", "/iset **incr"); + weechat::buffer_set($iset_buffer, "key_bind_meta--", "/iset **decr"); + weechat::buffer_set($iset_buffer, "key_bind_meta-imeta-r", "/iset **reset"); + weechat::buffer_set($iset_buffer, "key_bind_meta-imeta-u", "/iset **unset"); + weechat::buffer_set($iset_buffer, "key_bind_meta-ctrl-J", "/iset **set"); + weechat::buffer_set($iset_buffer, "key_bind_meta-ctrl-M", "/iset **set"); + weechat::buffer_set($iset_buffer, "key_bind_meta-meta2-1~", "/iset **scroll_top"); + weechat::buffer_set($iset_buffer, "key_bind_meta-meta2-4~", "/iset **scroll_bottom"); + weechat::buffer_set($iset_buffer, "key_bind_meta-v", "/iset **toggle_help"); + weechat::buffer_set($iset_buffer, "key_bind_meta-p", "/iset **toggle_show_plugin_desc"); + weechat::buffer_set($iset_buffer, "localvar_set_iset_filter", $filter); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_mode", $search_mode); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_value", $search_value); + } +} + +sub iset_get_options +{ + my $var_value = $_[0]; + $var_value = "" if (not defined $var_value); + $var_value = lc($var_value); + $search_value = $var_value; + @iset_focus = (); + @options_names = (); + @options_parent_names = (); + @options_types = (); + @options_values = (); + @options_default_values = (); + @options_parent_values = (); + @options_is_null = (); + $option_max_length = 0; + my %options_internal = (); + my $i = 0; + my $key; + my $iset_struct; + my %iset_struct; + + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_value", $var_value) if ($search_mode == 3); + + my $infolist = weechat::infolist_get("option", "", $filter); + while (weechat::infolist_next($infolist)) + { + $key = sprintf("%08d", $i); + my $name = weechat::infolist_string($infolist, "full_name"); + my $parent_name = weechat::infolist_string($infolist, "parent_name"); + next if (weechat::config_boolean($options_iset{"show_plugin_description"}) == 0 and index ($name, "plugins.desc.") != -1); + my $type = weechat::infolist_string($infolist, "type"); + my $value = weechat::infolist_string($infolist, "value"); + my $default_value = weechat::infolist_string($infolist, "default_value"); + my $parent_value; + if ($parent_name && (($wee_version_number < 0x00040300) || (weechat::infolist_search_var($infolist, "parent_value")))) + { + $parent_value = weechat::infolist_string($infolist, "parent_value"); + } + my $is_null = weechat::infolist_integer($infolist, "value_is_null"); + + if ($search_mode == 3) + { + my $value = weechat::infolist_string($infolist, "value"); + if ( grep /\Q$var_value/,lc($value) ) + { + $options_internal{$name}{"parent_name"} = $parent_name; + $options_internal{$name}{"type"} = $type; + $options_internal{$name}{"value"} = $value; + $options_internal{$name}{"default_value"} = $default_value; + $options_internal{$name}{"parent_value"} = $parent_value; + $options_internal{$name}{"is_null"} = $is_null; + $option_max_length = length($name) if (length($name) > $option_max_length); + $iset_struct{$key} = $options_internal{$name}; + push(@iset_focus, $iset_struct{$key}); + } + } + # search for diff? + elsif ( $search_mode == 4 or $search_mode == 5) + { + if ($value ne $default_value ) + { + $options_internal{$name}{"parent_name"} = $parent_name; + $options_internal{$name}{"type"} = $type; + $options_internal{$name}{"value"} = $value; + $options_internal{$name}{"default_value"} = $default_value; + $options_internal{$name}{"parent_value"} = $parent_value; + $options_internal{$name}{"is_null"} = $is_null; + $option_max_length = length($name) if (length($name) > $option_max_length); + $iset_struct{$key} = $options_internal{$name}; + push(@iset_focus, $iset_struct{$key}); + } + } + else + { + $options_internal{$name}{"parent_name"} = $parent_name; + $options_internal{$name}{"type"} = $type; + $options_internal{$name}{"value"} = $value; + $options_internal{$name}{"default_value"} = $default_value; + $options_internal{$name}{"parent_value"} = $parent_value; + $options_internal{$name}{"is_null"} = $is_null; + $option_max_length = length($name) if (length($name) > $option_max_length); + $iset_struct{$key} = $options_internal{$name}; + push(@iset_focus, $iset_struct{$key}); + } + $i++; + } + weechat::infolist_free($infolist); + + foreach my $name (sort keys %options_internal) + { + push(@options_names, $name); + push(@options_parent_names, $options_internal{$name}{"parent_name"}); + push(@options_types, $options_internal{$name}{"type"}); + push(@options_values, $options_internal{$name}{"value"}); + push(@options_default_values, $options_internal{$name}{"default_value"}); + push(@options_parent_values, $options_internal{$name}{"parent_value"}); + push(@options_is_null, $options_internal{$name}{"is_null"}); + } +} + +sub iset_get_values +{ + my $var_value = $_[0]; + $var_value = lc($var_value); + if (substr($var_value,0,1) eq weechat::config_string($options_iset{"value_search_char"}) and $var_value ne weechat::config_string($options_iset{"value_search_char"})) + { + $var_value = substr($var_value,1,length($var_value)); + $search_mode = 0; + } + iset_search_values($var_value,$search_mode); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_mode", $search_mode); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_value", $var_value); + $search_value = $var_value; +} +sub iset_search_values +{ + my ($var_value,$search_mode) = ($_[0],$_[1]); + @options_names = (); + @options_parent_names = (); + @options_types = (); + @options_values = (); + @options_default_values = (); + @options_parent_values = (); + @options_is_null = (); + $option_max_length = 0; + my %options_internal = (); + my $i = 0; + my $infolist = weechat::infolist_get("option", "", "*"); + while (weechat::infolist_next($infolist)) + { + my $name = weechat::infolist_string($infolist, "full_name"); + my $parent_name = weechat::infolist_string($infolist, "parent_name"); + next if (weechat::config_boolean($options_iset{"show_plugin_description"}) == 0 and index ($name, "plugins.desc.") != -1); + my $type = weechat::infolist_string($infolist, "type"); + my $is_null = weechat::infolist_integer($infolist, "value_is_null"); + my $value = weechat::infolist_string($infolist, "value"); + my $default_value = weechat::infolist_string($infolist, "default_value"); + my $parent_value; + if ($parent_name && (($wee_version_number < 0x00040300) || (weechat::infolist_search_var($infolist, "parent_value")))) + { + $parent_value = weechat::infolist_string($infolist, "parent_value"); + } + if ($search_mode) + { + if ( grep /\Q$var_value/,lc($value) ) + { + $options_internal{$name}{"parent_name"} = $parent_name; + $options_internal{$name}{"type"} = $type; + $options_internal{$name}{"value"} = $value; + $options_internal{$name}{"default_value"} = $default_value; + $options_internal{$name}{"parent_value"} = $parent_value; + $options_internal{$name}{"is_null"} = $is_null; + $option_max_length = length($name) if (length($name) > $option_max_length); + } + } + else + { +# if ($value =~ /\Q$var_value/si) + if (lc($value) eq $var_value) + { + $options_internal{$name}{"parent_name"} = $parent_name; + $options_internal{$name}{"type"} = $type; + $options_internal{$name}{"value"} = $value; + $options_internal{$name}{"default_value"} = $default_value; + $options_internal{$name}{"parent_value"} = $parent_value; + $options_internal{$name}{"is_null"} = $is_null; + $option_max_length = length($name) if (length($name) > $option_max_length); + } + } + $i++; + } + weechat::infolist_free($infolist); + foreach my $name (sort keys %options_internal) + { + push(@options_names, $name); + push(@options_parent_names, $options_internal{$name}{"parent_name"}); + push(@options_types, $options_internal{$name}{"type"}); + push(@options_values, $options_internal{$name}{"value"}); + push(@options_default_values, $options_internal{$name}{"default_value"}); + push(@options_parent_values, $options_internal{$name}{"parent_value"}); + push(@options_is_null, $options_internal{$name}{"is_null"}); + } +} + +sub iset_refresh_line +{ + if ($iset_buffer ne "") + { + my $y = $_[0]; + if ($y <= $#options_names) + { + return if (! defined($options_types[$y])); + my $format = sprintf("%%s%%s%%s %%s %%-7s %%s %%s%%s%%s"); + my $padding; + if ($wee_version_number >= 0x00040200) + { + $padding = " " x ($option_max_length - weechat::strlen_screen($options_names[$y])); + } + else + { + $padding = " " x ($option_max_length - length($options_names[$y])); + } + my $around = ""; + $around = "\"" if ((!$options_is_null[$y]) && ($options_types[$y] eq "string")); + + my $color1 = weechat::color(weechat::config_color($options_iset{"color_option"})); + my $color2 = weechat::color(weechat::config_color($options_iset{"color_type"})); + my $color3 = ""; + my $color4 = ""; + if ($options_is_null[$y]) + { + $color3 = weechat::color(weechat::config_color($options_iset{"color_value_undef"})); + $color4 = weechat::color(weechat::config_color($options_iset{"color_value"})); + } + elsif ($options_values[$y] ne $options_default_values[$y]) + { + $color3 = weechat::color(weechat::config_color($options_iset{"color_value_diff"})); + } + else + { + $color3 = weechat::color(weechat::config_color($options_iset{"color_value"})); + } + if ($y == $current_line) + { + $color1 = weechat::color(weechat::config_color($options_iset{"color_option_selected"}).",".weechat::config_color($options_iset{"color_bg_selected"})); + $color2 = weechat::color(weechat::config_color($options_iset{"color_type_selected"}).",".weechat::config_color($options_iset{"color_bg_selected"})); + if ($options_is_null[$y]) + { + $color3 = weechat::color(weechat::config_color($options_iset{"color_value_undef_selected"}).",".weechat::config_color($options_iset{"color_bg_selected"})); + $color4 = weechat::color(weechat::config_color($options_iset{"color_value_selected"}).",".weechat::config_color($options_iset{"color_bg_selected"})); + } + elsif ($options_values[$y] ne $options_default_values[$y]) + { + $color3 = weechat::color(weechat::config_color($options_iset{"color_value_diff_selected"}).",".weechat::config_color($options_iset{"color_bg_selected"})); + } + else + { + $color3 = weechat::color(weechat::config_color($options_iset{"color_value_selected"}).",".weechat::config_color($options_iset{"color_bg_selected"})); + } + } + my $value = $options_values[$y]; + if ($options_is_null[$y]) + { + $value = "null"; + if ($options_parent_names[$y]) + { + if (defined $options_parent_values[$y]) + { + my $around_parent = ""; + $around_parent = "\"" if ($options_types[$y] eq "string"); + $value .= $color1." -> ".$color4.$around_parent.$options_parent_values[$y].$around_parent; + } + else + { + $value .= $color1." -> ".$color3."null"; + } + } + } + my $strline = sprintf($format, + $color1, $options_names[$y], $padding, + $color2, $options_types[$y], + $color3, $around, $value, $around); + weechat::print_y($iset_buffer, $y, $strline); + } + } +} + +sub iset_refresh +{ + iset_title(); + if (($iset_buffer ne "") && ($#options_names >= 0)) + { + foreach my $y (0 .. $#options_names) + { + iset_refresh_line($y); + } + } + + weechat::bar_item_update("isetbar_help") if (weechat::config_boolean($options_iset{"show_help_bar"}) == 1); +} + +sub iset_full_refresh +{ + $iset_buffer = weechat::buffer_search($LANG, $PRGNAME); + if ($iset_buffer ne "") + { + weechat::buffer_clear($iset_buffer) unless defined $_[0]; # iset_full_refresh(1) does a full refresh without clearing buffer + # search for "*" in $filter. + if ($filter =~ m/\*/ and $search_mode == 2) + { + iset_get_options(""); + } + else + { + if ($search_mode == 0) + { + $search_value = "=" . $search_value; + iset_get_values($search_value); + } + elsif ($search_mode == 1) + { + iset_get_values($search_value); + } + elsif ($search_mode == 3) + { + iset_create_filter($filter); + iset_get_options($search_value); + } + } + if (weechat::config_boolean($options_iset{"show_plugin_description"}) == 1) + { + iset_set_current_line($current_line); + }else + { + $current_line = $#options_names if ($current_line > $#options_names); + } + iset_refresh(); + weechat::command($iset_buffer, "/window refresh"); + } +} + +sub iset_set_current_line +{ + my $new_current_line = $_[0]; + if ($new_current_line >= 0) + { + my $old_current_line = $current_line; + $current_line = $new_current_line; + $current_line = $#options_names if ($current_line > $#options_names); + if ($old_current_line != $current_line) + { + iset_refresh_line($old_current_line); + iset_refresh_line($current_line); + weechat::bar_item_update("isetbar_help") if (weechat::config_boolean($options_iset{"show_help_bar"}) == 1); + } + } +} + +sub iset_signal_window_scrolled_cb +{ + my ($data, $signal, $signal_data) = ($_[0], $_[1], $_[2]); + if ($iset_buffer ne "") + { + my $infolist = weechat::infolist_get("window", $signal_data, ""); + if (weechat::infolist_next($infolist)) + { + if (weechat::infolist_pointer($infolist, "buffer") eq $iset_buffer) + { + my $old_current_line = $current_line; + my $new_current_line = $current_line; + my $start_line_y = weechat::infolist_integer($infolist, "start_line_y"); + my $chat_height = weechat::infolist_integer($infolist, "chat_height"); + $new_current_line += $chat_height if ($new_current_line < $start_line_y); + $new_current_line -= $chat_height if ($new_current_line >= $start_line_y + $chat_height); + $new_current_line = $start_line_y if ($new_current_line < $start_line_y); + $new_current_line = $start_line_y + $chat_height - 1 if ($new_current_line >= $start_line_y + $chat_height); + iset_set_current_line($new_current_line); + } + } + weechat::infolist_free($infolist); + } + + return weechat::WEECHAT_RC_OK; +} + +sub iset_get_window_number +{ + if ($iset_buffer ne "") + { + my $window = weechat::window_search_with_buffer($iset_buffer); + return "-window ".weechat::window_get_integer ($window, "number")." " if ($window ne ""); + } + return ""; +} + +sub iset_check_line_outside_window +{ + if ($iset_buffer ne "") + { + undef my $infolist; + if ($wee_version_number >= 0x00030500) + { + my $window = weechat::window_search_with_buffer($iset_buffer); + $infolist = weechat::infolist_get("window", $window, "") if $window; + } + else + { + $infolist = weechat::infolist_get("window", "", "current"); + } + if ($infolist) + { + if (weechat::infolist_next($infolist)) + { + my $start_line_y = weechat::infolist_integer($infolist, "start_line_y"); + my $chat_height = weechat::infolist_integer($infolist, "chat_height"); + my $window_number = ""; + if ($wee_version_number >= 0x00030500) + { + $window_number = "-window ".weechat::infolist_integer($infolist, "number")." "; + } + if ($start_line_y > $current_line) + { + weechat::command($iset_buffer, "/window scroll ".$window_number."-".($start_line_y - $current_line)); + } + else + { + if ($start_line_y <= $current_line - $chat_height) + { + weechat::command($iset_buffer, "/window scroll ".$window_number."+".($current_line - $start_line_y - $chat_height + 1)); + + } + } + } + weechat::infolist_free($infolist); + } + } +} + +sub iset_get_option_name_index +{ + my $option_name = $_[0]; + my $index = 0; + while ($index <= $#options_names) + { + return -1 if ($options_names[$index] gt $option_name); + return $index if ($options_names[$index] eq $option_name); + $index++; + } + return -1; +} + +sub iset_refresh_option +{ + my $option_name = $_[0]; + my $index = $_[1]; + my $infolist = weechat::infolist_get("option", "", $option_name); + if ($infolist) + { + weechat::infolist_next($infolist); + if (weechat::infolist_fields($infolist)) + { + $options_parent_names[$index] = weechat::infolist_string($infolist, "parent_name"); + $options_types[$index] = weechat::infolist_string($infolist, "type"); + $options_values[$index] = weechat::infolist_string($infolist, "value"); + $options_default_values[$index] = weechat::infolist_string($infolist, "default_value"); + $options_is_null[$index] = weechat::infolist_integer($infolist, "value_is_null"); + $options_parent_values[$index] = undef; + if ($options_parent_names[$index] + && (($wee_version_number < 0x00040300) || (weechat::infolist_search_var($infolist, "parent_value")))) + { + $options_parent_values[$index] = weechat::infolist_string($infolist, "parent_value"); + } + iset_refresh_line($index); + iset_title() if ($option_name eq "iset.look.show_current_line"); + } + else + { + iset_full_refresh(1); # if not found, refresh fully without clearing buffer + weechat::print_y($iset_buffer, $#options_names + 1, ""); + } + weechat::infolist_free($infolist); + } +} + +sub iset_config_cb +{ + my ($data, $option_name, $value) = ($_[0], $_[1], $_[2]); + + if ($iset_buffer ne "") + { + return weechat::WEECHAT_RC_OK if (weechat::info_get("weechat_upgrading", "") eq "1"); + + my $index = iset_get_option_name_index($option_name); + if ($index >= 0) + { + # refresh info about changed option + iset_refresh_option($option_name, $index); + # refresh any other option having this changed option as parent + foreach my $i (0 .. $#options_names) + { + if ($options_parent_names[$i] eq $option_name) + { + iset_refresh_option($options_names[$i], $i); + } + } + } + else + { + iset_full_refresh() if ($option_name ne "weechat.bar.isetbar.hidden"); + } + } + + return weechat::WEECHAT_RC_OK; +} + +sub iset_set_option +{ + my ($option, $value) = ($_[0],$_[1]); + if (defined $option and defined $value) + { + $option = weechat::config_get($option); + weechat::config_option_set($option, $value, 1) if ($option ne ""); + } +} + +sub iset_reset_option +{ + my $option = $_[0]; + if (defined $option) + { + $option = weechat::config_get($option); + weechat::config_option_reset($option, 1) if ($option ne ""); + } +} + +sub iset_unset_option +{ + my $option = $_[0]; + if (defined $option) + { + $option = weechat::config_get($option); + weechat::config_option_unset($option) if ($option ne ""); + } +} + + +sub iset_cmd_cb +{ + my ($data, $buffer, $args) = ($_[0], $_[1], $_[2]); + my $filter_set = 0; +# $search_value = ""; + if (($args ne "") && (substr($args, 0, 2) ne "**")) + { + my @cmd_array = split(/ /,$args); + my $array_count = @cmd_array; + if (substr($args, 0, 1) eq weechat::config_string($options_iset{"value_search_char"}) + or (defined $cmd_array[0] and $cmd_array[0] eq weechat::config_string($options_iset{"value_search_char"}).weechat::config_string($options_iset{"value_search_char"})) ) + { + $search_mode = 1; + my $search_value = substr($args, 1); # cut value_search_char + if ($iset_buffer ne "") + { + weechat::buffer_clear($iset_buffer); + weechat::command($iset_buffer, "/window refresh"); + } + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_mode", $search_mode); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_value", $search_value); + iset_init(); + iset_get_values($search_value); + iset_refresh(); + weechat::buffer_set($iset_buffer, "display", "1"); +# $filter = $var_value; + return weechat::WEECHAT_RC_OK; + } + else + { + # f/s option =value + # option =value + $search_mode = 2; # grep on option + if ( $array_count >= 2 and $cmd_array[0] ne "f" or $cmd_array[0] ne "s") + { + if ( defined $cmd_array[1] and substr($cmd_array[1], 0, 1) eq weechat::config_string($options_iset{"value_search_char"}) + or defined $cmd_array[2] and substr($cmd_array[2], 0, 1) eq weechat::config_string($options_iset{"value_search_char"}) ) + { + $search_mode = 3; # grep on option and value + $search_value = substr($cmd_array[1], 1); # cut value_search_char + $search_value = substr($cmd_array[2], 1) if ( $array_count > 2); # cut value_search_char + } + } + + # show all diff values + if ( $args eq "d") + { + $search_mode = 4; + $search_value = "*"; + $args = $search_value; + } + if ( $array_count >= 2 and $cmd_array[0] eq "d") + { + $search_mode = 5; + $search_value = substr($cmd_array[1], 0); # cut value_search_char + $search_value = substr($cmd_array[2], 0) if ( $array_count > 2); # cut value_search_char + $args = $search_value; + } + + iset_create_filter($args); + $filter_set = 1; + my $ptrbuf = weechat::buffer_search($LANG, $PRGNAME); + + if ($ptrbuf eq "") + { + iset_init(); + iset_get_options($search_value); + iset_full_refresh(); + weechat::buffer_set(weechat::buffer_search($LANG, $PRGNAME), "display", "1"); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_value", $search_value); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_mode", $search_mode); + return weechat::WEECHAT_RC_OK; + } + else + { + iset_get_options($search_value); + iset_full_refresh(); + weechat::buffer_set($ptrbuf, "display", "1"); + } + } + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_mode", $search_mode); + weechat::buffer_set($iset_buffer, "localvar_set_iset_search_value", $search_value); + } + if ($iset_buffer eq "") + { + iset_init(); + iset_get_options(""); + iset_refresh(); + } + else + { +# iset_get_options($search_value); + iset_full_refresh() if ($filter_set); + } + + if ($args eq "") + { + weechat::buffer_set($iset_buffer, "display", "1"); + } + else + { + if ($args eq "**refresh") + { + iset_full_refresh(); + } + if ($args eq "**up") + { + if ($current_line > 0) + { + $current_line--; + iset_refresh_line($current_line + 1); + iset_refresh_line($current_line); + iset_check_line_outside_window(); + } + } + if ($args eq "**down") + { + if ($current_line < $#options_names) + { + $current_line++; + iset_refresh_line($current_line - 1); + iset_refresh_line($current_line); + iset_check_line_outside_window(); + } + } + if ($args eq "**left" && $wee_version_number >= 0x00030600) + { + weechat::command($iset_buffer, "/window scroll_horiz ".iset_get_window_number()."-".weechat::config_integer($options_iset{"scroll_horiz"})."%"); + } + if ($args eq "**right" && $wee_version_number >= 0x00030600) + { + weechat::command($iset_buffer, "/window scroll_horiz ".iset_get_window_number().weechat::config_integer($options_iset{"scroll_horiz"})."%"); + } + if ($args eq "**scroll_top") + { + my $old_current_line = $current_line; + $current_line = 0; + iset_refresh_line ($old_current_line); + iset_refresh_line ($current_line); + iset_title(); + weechat::command($iset_buffer, "/window scroll_top ".iset_get_window_number()); + } + if ($args eq "**scroll_bottom") + { + my $old_current_line = $current_line; + $current_line = $#options_names; + iset_refresh_line ($old_current_line); + iset_refresh_line ($current_line); + iset_title(); + weechat::command($iset_buffer, "/window scroll_bottom ".iset_get_window_number()); + } + if ($args eq "**toggle") + { + if ($options_types[$current_line] eq "boolean") + { + iset_set_option($options_names[$current_line], "toggle"); + } + } + if ($args eq "**incr") + { + if (($options_types[$current_line] eq "integer") + || ($options_types[$current_line] eq "color")) + { + iset_set_option($options_names[$current_line], "++1"); + } + } + if ($args eq "**decr") + { + if (($options_types[$current_line] eq "integer") + || ($options_types[$current_line] eq "color")) + { + iset_set_option($options_names[$current_line], "--1"); + } + } + if ($args eq "**reset") + { + iset_reset_option($options_names[$current_line]); + } + if ($args eq "**unset") + { + iset_unset_option($options_names[$current_line]); + } + if ($args eq "**toggle_help") + { + if (weechat::config_boolean($options_iset{"show_help_bar"}) == 1) + { + weechat::config_option_set($options_iset{"show_help_bar"},0,1); + iset_show_bar(0); + } + else + { + weechat::config_option_set($options_iset{"show_help_bar"},1,1); + iset_show_bar(1); + } + } + if ($args eq "**toggle_show_plugin_desc") + { + if (weechat::config_boolean($options_iset{"show_plugin_description"}) == 1) + { + weechat::config_option_set($options_iset{"show_plugin_description"},0,1); + iset_full_refresh(); + iset_check_line_outside_window(); + iset_title(); + } + else + { + weechat::config_option_set($options_iset{"show_plugin_description"},1,1); + iset_full_refresh(); + iset_check_line_outside_window(); + iset_title(); + } + } + if ($args eq "**set") + { + my $quote = ""; + my $value = $options_values[$current_line]; + if ($options_is_null[$current_line]) + { + $value = ""; + } + else + { + $quote = "\"" if ($options_types[$current_line] eq "string"); + } + $value = " ".$quote.$value.$quote if ($value ne "" or $quote ne ""); + + my $set_command = "/set"; + my $start_index = 5; + if (weechat::config_boolean($options_iset{"use_mute"}) == 1) + { + $set_command = "/mute ".$set_command; + $start_index += 11; + } + $set_command = $set_command." ".$options_names[$current_line].$value; + my $pos_space = index($set_command, " ", $start_index); + if ($pos_space < 0) + { + $pos_space = 9999; + } + else + { + $pos_space = $pos_space + 1; + $pos_space = $pos_space + 1 if ($quote ne ""); + } + weechat::buffer_set($iset_buffer, "input", $set_command); + weechat::buffer_set($iset_buffer, "input_pos", "".$pos_space); + } + } + weechat::bar_item_update("isetbar_help") if (weechat::config_boolean($options_iset{"show_help_bar"}) == 1); + return weechat::WEECHAT_RC_OK; +} + +sub iset_get_help +{ + my ($redraw) = ($_[0]); + + return '' if (weechat::config_boolean($options_iset{"show_help_bar"}) == 0); + + if (not defined $options_names[$current_line]) + { + return "No option selected. Set a new filter using command line (use '*' to see all options)"; + } + if ($options_name_copy eq $options_names[$current_line] and not defined $redraw) + { + return $description; + } + $options_name_copy = $options_names[$current_line]; + my $optionlist =""; + $optionlist = weechat::infolist_get("option", "", $options_names[$current_line]); + weechat::infolist_next($optionlist); + my $full_name = weechat::infolist_string($optionlist,"full_name"); + my $option_desc = ""; + my $option_default_value = ""; + my $option_range = ""; + my $possible_values = ""; + my $re = qq(\Q$full_name); + if (grep (/^$re$/,$options_names[$current_line])) + { + $option_desc = weechat::infolist_string($optionlist, "description_nls"); + $option_desc = weechat::infolist_string($optionlist, "description") if ($option_desc eq ""); + $option_desc = "No help found" if ($option_desc eq ""); + $option_default_value = weechat::infolist_string($optionlist, "default_value"); + $possible_values = weechat::infolist_string($optionlist, "string_values") if (weechat::infolist_string($optionlist, "string_values") ne ""); + if ((weechat::infolist_string($optionlist, "type") eq "integer") && ($possible_values eq "")) + { + $option_range = weechat::infolist_integer($optionlist, "min") + ." .. ".weechat::infolist_integer($optionlist, "max"); + } + } + weechat::infolist_free($optionlist); + iset_title(); + + $description = weechat::color(weechat::config_color($options_iset{"color_help_option_name"})).$options_names[$current_line] + .weechat::color("bar_fg").": " + .weechat::color(weechat::config_color($options_iset{"color_help_text"})).$option_desc; + + # show additional infos like default value and possible values + + if (weechat::config_boolean($options_iset{"show_help_extra_info"}) == 1) + { + $description .= + weechat::color("bar_delim")." [" + .weechat::color("bar_fg")."default: " + .weechat::color("bar_delim")."\"" + .weechat::color(weechat::config_color($options_iset{"color_help_default_value"})).$option_default_value + .weechat::color("bar_delim")."\""; + if ($option_range ne "") + { + $description .= weechat::color("bar_fg").", values: ".$option_range; + } + if ($possible_values ne "") + { + $possible_values =~ s/\|/", "/g; # replace '|' to '", "' + $description .= weechat::color("bar_fg").", values: ". "\"" . $possible_values . "\""; + + } + $description .= weechat::color("bar_delim")."]"; + } + return $description; +} + +sub iset_check_condition_isetbar_cb +{ + my ($data, $modifier, $modifier_data, $string) = ($_[0], $_[1], $_[2], $_[3]); + my $buffer = weechat::window_get_pointer($modifier_data, "buffer"); + if ($buffer ne "") + { + if ((weechat::buffer_get_string($buffer, "plugin") eq $LANG) + && (weechat::buffer_get_string($buffer, "name") eq $PRGNAME)) + { + return "1"; + } + } + return "0"; +} + +sub iset_show_bar +{ + my $show = $_[0]; + my $barhidden = weechat::config_get("weechat.bar.isetbar.hidden"); + if ($barhidden) + { + if ($show) + { + if (weechat::config_boolean($options_iset{"show_help_bar"}) == 1) + { + if (weechat::config_boolean($barhidden)) + { + weechat::config_option_set($barhidden, 0, 1); + } + } + } + else + { + if (!weechat::config_boolean($barhidden)) + { + weechat::config_option_set($barhidden, 1, 1); + } + } + } +} + +sub iset_signal_buffer_switch_cb +{ + my $buffer_pointer = $_[2]; + my $show_bar = 0; + $show_bar = 1 if (weechat::buffer_get_integer($iset_buffer, "num_displayed") > 0); + iset_show_bar($show_bar); + iset_check_line_outside_window() if ($buffer_pointer eq $iset_buffer); + return weechat::WEECHAT_RC_OK; +} + +sub iset_item_cb +{ + return iset_get_help(); +} + +sub iset_upgrade_ended +{ + iset_full_refresh(); +} + +sub iset_end +{ + # when script is unloaded, we hide bar + iset_show_bar(0); +} + +# -------------------------------[ mouse support ]------------------------------------- + +sub hook_focus_iset_cb +{ + my %info = %{$_[1]}; + my $bar_item_line = int($info{"_bar_item_line"}); + undef my $hash; + if (($info{"_buffer_name"} eq $PRGNAME) && $info{"_buffer_plugin"} eq $LANG && ($bar_item_line >= 0) && ($bar_item_line <= $#iset_focus)) + { + $hash = $iset_focus[$bar_item_line]; + } + else + { + $hash = {}; + my $hash_focus = $iset_focus[0]; + foreach my $key (keys %$hash_focus) + { + $hash->{$key} = "?"; + } + } + return $hash; +} + +# _chat_line_y contains selected line +sub iset_hsignal_mouse_cb +{ + my ($data, $signal, %hash) = ($_[0], $_[1], %{$_[2]}); + + return weechat::WEECHAT_RC_OK unless (@options_types); + + if ($hash{"_buffer_name"} eq $PRGNAME && ($hash{"_buffer_plugin"} eq $LANG)) + { + if ($hash{"_key"} eq "button1") + { + iset_set_current_line($hash{"_chat_line_y"}); + } + elsif ($hash{"_key"} eq "button2") + { + if ($options_types[$hash{"_chat_line_y"}] eq "boolean") + { + iset_set_option($options_names[$hash{"_chat_line_y"}], "toggle"); + iset_set_current_line($hash{"_chat_line_y"}); + } + elsif ($options_types[$hash{"_chat_line_y"}] eq "string") + { + iset_set_current_line($hash{"_chat_line_y"}); + weechat::command("", "/$PRGNAME **set"); + } + } + elsif ($hash{"_key"} eq "button2-gesture-left" or $hash{"_key"} eq "button2-gesture-left-long") + { + if ($options_types[$hash{"_chat_line_y"}] eq "integer" or ($options_types[$hash{"_chat_line_y"}] eq "color")) + { + iset_set_current_line($hash{"_chat_line_y"}); + my $distance = distance($hash{"_chat_line_x"},$hash{"_chat_line_x2"}); + weechat::command("", "/repeat $distance /$PRGNAME **decr"); + } + } + elsif ($hash{"_key"} eq "button2-gesture-right" or $hash{"_key"} eq "button2-gesture-right-long") + { + if ($options_types[$hash{"_chat_line_y"}] eq "integer" or ($options_types[$hash{"_chat_line_y"}] eq "color")) + { + iset_set_current_line($hash{"_chat_line_y"}); + my $distance = distance($hash{"_chat_line_x"},$hash{"_chat_line_x2"}); + weechat::command("", "/repeat $distance /$PRGNAME **incr"); + } + } + } + window_switch(); +} + +sub window_switch +{ + my $current_window = weechat::current_window(); + my $dest_window = weechat::window_search_with_buffer(weechat::buffer_search("perl","iset")); + return 0 if ($dest_window eq "" or $current_window eq $dest_window); + + my $infolist = weechat::infolist_get("window", $dest_window, ""); + weechat::infolist_next($infolist); + my $number = weechat::infolist_integer($infolist, "number"); + weechat::infolist_free($infolist); + weechat::command("","/window " . $number); +} + +sub distance +{ + my ($x1,$x2) = ($_[0], $_[1]); + my $distance; + $distance = $x1 - $x2; + $distance = abs($distance); + if ($distance > 0) + { + use integer; + $distance = $distance / 3; + $distance = 1 if ($distance == 0); + } + elsif ($distance == 0) + { + $distance = 1; + } + return $distance; +} + +# -----------------------------------[ config ]--------------------------------------- + +sub iset_config_init +{ + $iset_config_file = weechat::config_new($ISET_CONFIG_FILE_NAME,"iset_config_reload_cb",""); + return if ($iset_config_file eq ""); + + # section "color" + my $section_color = weechat::config_new_section($iset_config_file,"color", 0, 0, "", "", "", "", "", "", "", "", "", ""); + if ($section_color eq "") + { + weechat::config_free($iset_config_file); + return; + } + $options_iset{"color_option"} = weechat::config_new_option( + $iset_config_file, $section_color, + "option", "color", "Color for option name in iset buffer", "", 0, 0, + "default", "default", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_option_selected"} = weechat::config_new_option( + $iset_config_file, $section_color, + "option_selected", "color", "Color for selected option name in iset buffer", "", 0, 0, + "white", "white", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_type"} = weechat::config_new_option( + $iset_config_file, $section_color, + "type", "color", "Color for option type (integer, boolean, string)", "", 0, 0, + "brown", "brown", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_type_selected"} = weechat::config_new_option( + $iset_config_file, $section_color, + "type_selected", "color", "Color for selected option type (integer, boolean, string)", "", 0, 0, + "yellow", "yellow", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_value"} = weechat::config_new_option( + $iset_config_file, $section_color, + "value", "color", "Color for option value", "", 0, 0, + "cyan", "cyan", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_value_selected"} = weechat::config_new_option( + $iset_config_file, $section_color, + "value_selected", "color", "Color for selected option value", "", 0, 0, + "lightcyan", "lightcyan", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_value_diff"} = weechat::config_new_option( + $iset_config_file, $section_color, + "value_diff", "color", "Color for option value different from default", "", 0, 0, + "magenta", "magenta", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_value_diff_selected"} = weechat::config_new_option( + $iset_config_file, $section_color, + "value_diff_selected", "color", "Color for selected option value different from default", "", 0, 0, + "lightmagenta", "lightmagenta", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_value_undef"} = weechat::config_new_option( + $iset_config_file, $section_color, + "value_undef", "color", "Color for option value undef", "", 0, 0, + "green", "green", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_value_undef_selected"} = weechat::config_new_option( + $iset_config_file, $section_color, + "value_undef_selected", "color", "Color for selected option value undef", "", 0, 0, + "lightgreen", "lightgreen", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_bg_selected"} = weechat::config_new_option( + $iset_config_file, $section_color, + "bg_selected", "color", "Background color for current selected option", "", 0, 0, + "red", "red", 0, "", "", "full_refresh_cb", "", "", ""); + $options_iset{"color_help_option_name"} = weechat::config_new_option( + $iset_config_file, $section_color, + "help_option_name", "color", "Color for option name in help-bar", "", 0, 0, + "white", "white", 0, "", "", "bar_refresh", "", "", ""); + $options_iset{"color_help_text"} = weechat::config_new_option( + $iset_config_file, $section_color, + "help_text", "color", "Color for option description in help-bar", "", 0, 0, + "default", "default", 0, "", "", "bar_refresh", "", "", ""); + $options_iset{"color_help_default_value"} = weechat::config_new_option( + $iset_config_file, $section_color, + "help_default_value", "color", "Color for default option value in help-bar", "", 0, 0, + "green", "green", 0, "", "", "bar_refresh", "", "", ""); + + # section "help" + my $section_help = weechat::config_new_section($iset_config_file,"help", 0, 0, "", "", "", "", "", "", "", "", "", ""); + if ($section_help eq "") + { + weechat::config_free($iset_config_file); + return; + } + $options_iset{"show_help_bar"} = weechat::config_new_option( + $iset_config_file, $section_help, + "show_help_bar", "boolean", "Show help bar", "", 0, 0, + "on", "on", 0, "", "", "toggle_help_cb", "", "", ""); + $options_iset{"show_help_extra_info"} = weechat::config_new_option( + $iset_config_file, $section_help, + "show_help_extra_info", "boolean", "Show additional information in help bar (default value, max./min. value) ", "", 0, 0, + "on", "on", 0, "", "", "", "", "", ""); + $options_iset{"show_plugin_description"} = weechat::config_new_option( + $iset_config_file, $section_help, + "show_plugin_description", "boolean", "Show plugin description in iset buffer", "", 0, 0, + "off", "off", 0, "", "", "full_refresh_cb", "", "", ""); + + # section "look" + my $section_look = weechat::config_new_section($iset_config_file, "look", 0, 0, "", "", "", "", "", "", "", "", "", ""); + if ($section_look eq "") + { + weechat::config_free($iset_config_file); + return; + } + $options_iset{"value_search_char"} = weechat::config_new_option( + $iset_config_file, $section_look, + "value_search_char", "string", "Trigger char to tell iset to search for value instead of option (for example: =red)", "", 0, 0, + "=", "=", 0, "", "", "", "", "", ""); + $options_iset{"scroll_horiz"} = weechat::config_new_option( + $iset_config_file, $section_look, + "scroll_horiz", "integer", "scroll content of iset buffer n%", "", 1, 100, + "10", "10", 0, "", "", "", "", "", ""); + $options_iset{"show_current_line"} = weechat::config_new_option( + $iset_config_file, $section_look, + "show_current_line", "boolean", "show current line in title bar.", "", 0, 0, + "on", "on", 0, "", "", "", "", "", ""); + $options_iset{"use_mute"} = weechat::config_new_option( + $iset_config_file, $section_look, + "use_mute", "boolean", "/mute command will be used in input bar", "", 0, 0, + "off", "off", 0, "", "", "", "", "", ""); +} + +sub iset_config_reload_cb +{ + my ($data,$config_file) = ($_[0], $_[1]); + return weechat::config_reload($config_file) +} + +sub iset_config_read +{ + return weechat::config_read($iset_config_file) if ($iset_config_file ne ""); +} + +sub iset_config_write +{ + return weechat::config_write($iset_config_file) if ($iset_config_file ne ""); +} + +sub full_refresh_cb +{ + iset_full_refresh(); + return weechat::WEECHAT_RC_OK; +} + +sub bar_refresh +{ + iset_get_help(1); + weechat::bar_item_update("isetbar_help") if (weechat::config_boolean($options_iset{"show_help_bar"}) == 1); + return weechat::WEECHAT_RC_OK; +} + +sub toggle_help_cb +{ + my $value = weechat::config_boolean($options_iset{"show_help_bar"}); + iset_show_bar($value); + return weechat::WEECHAT_RC_OK; +} + +# -----------------------------------[ main ]----------------------------------------- + +weechat::register($PRGNAME, $AUTHOR, $VERSION, $LICENSE, + $DESCR, "iset_end", ""); + +$wee_version_number = weechat::info_get("version_number", "") || 0; + +iset_config_init(); +iset_config_read(); + +weechat::hook_command($PRGNAME, "Interactive set", "d || f || s
|| [=][=]", + "d : show only changed options\n". + "f file : show options for a file\n". + "s section: show options for a section\n". + "text : show options with 'text' in name\n". + weechat::config_string($options_iset{"value_search_char"})."text : show options with 'text' in value\n". + weechat::config_string($options_iset{"value_search_char"}).weechat::config_string($options_iset{"value_search_char"})."text : show options with exact 'text' in value\n\n". + "Keys for iset buffer:\n". + "f11,f12 : move iset content left/right\n". + "up,down : move one option up/down\n". + "pgup,pdwn : move one page up/down\n". + "home,end : move to first/last option\n". + "ctrl+'L' : refresh options and screen\n". + "alt+space : toggle boolean on/off\n". + "alt+'+' : increase value (for integer or color)\n". + "alt+'-' : decrease value (for integer or color)\n". + "alt+'i',alt+'r': reset value of option\n". + "alt+'i',alt+'u': unset option\n". + "alt+enter : set new value for option (edit it with command line)\n". + "text,enter : set a new filter using command line (use '*' to see all options)\n". + "alt+'v' : toggle help bar on/off\n". + "alt+'p' : toggle option \"show_plugin_description\" on/off\n". + "q : as input in iset buffer to close it\n". + "\n". + "Mouse actions:\n". + "wheel up/down : move cursor up/down\n". + "left button : select an option from list\n". + "right button : toggle boolean (on/off) or set a new value for option (edit it with command line)\n". + "right button + drag left/right: increase/decrease value (for integer or color)\n". + "\n". + "Examples:\n". + " show changed options in 'aspell' plugin\n". + " /iset d aspell\n". + " show options for file 'irc'\n". + " /iset f irc\n". + " show options for section 'look'\n". + " /iset s look\n". + " show all options with text 'nicklist' in name\n". + " /iset nicklist\n". + " show all values which contain 'red'. ('" . weechat::config_string($options_iset{"value_search_char"}) . "' is a trigger char).\n". + " /iset ". weechat::config_string($options_iset{"value_search_char"}) ."red\n". + " show all values which hit 'off'. ('" . weechat::config_string($options_iset{"value_search_char"}) . weechat::config_string($options_iset{"value_search_char"}) . "' is a trigger char).\n". + " /iset ". weechat::config_string($options_iset{"value_search_char"}) . weechat::config_string($options_iset{"value_search_char"}) ."off\n". + " show options for file 'weechat' which contains value 'off'\n". + " /iset f weechat ".weechat::config_string($options_iset{"value_search_char"})."off\n". + "", + "", "iset_cmd_cb", ""); +weechat::hook_signal("upgrade_ended", "iset_upgrade_ended", ""); +weechat::hook_signal("window_scrolled", "iset_signal_window_scrolled_cb", ""); +weechat::hook_signal("buffer_switch", "iset_signal_buffer_switch_cb",""); +weechat::bar_item_new("isetbar_help", "iset_item_cb", ""); +weechat::bar_new("isetbar", "on", "0", "window", "", "top", "horizontal", + "vertical", "3", "3", "default", "cyan", "default", "1", + "isetbar_help"); +weechat::hook_modifier("bar_condition_isetbar", "iset_check_condition_isetbar_cb", ""); +weechat::hook_config("*", "iset_config_cb", ""); +$iset_buffer = weechat::buffer_search($LANG, $PRGNAME); +iset_init() if ($iset_buffer ne ""); + +if ($wee_version_number >= 0x00030600) +{ + weechat::hook_focus("chat", "hook_focus_iset_cb", ""); + weechat::hook_hsignal($PRGNAME."_mouse", "iset_hsignal_mouse_cb", ""); + weechat::key_bind("mouse", \%mouse_keys); +} diff --git a/weechat/.config/weechat/plugins.conf b/weechat/.config/weechat/plugins.conf new file mode 100644 index 0000000..8bb36fd --- /dev/null +++ b/weechat/.config/weechat/plugins.conf @@ -0,0 +1,15 @@ +# +# weechat -- plugins.conf +# + +[var] +fifo.fifo = "on" +guile.check_license = "off" +javascript.check_license = "off" +lua.check_license = "off" +perl.check_license = "off" +python.check_license = "off" +ruby.check_license = "off" +tcl.check_license = "off" + +[desc] diff --git a/weechat/.config/weechat/relay.conf b/weechat/.config/weechat/relay.conf new file mode 100644 index 0000000..aa38a43 --- /dev/null +++ b/weechat/.config/weechat/relay.conf @@ -0,0 +1,41 @@ +# +# weechat -- relay.conf +# + +[look] +auto_open_buffer = on +raw_messages = 256 + +[color] +client = cyan +status_active = lightblue +status_auth_failed = lightred +status_connecting = yellow +status_disconnected = lightred +status_waiting_auth = brown +text = default +text_bg = default +text_selected = white + +[network] +allow_empty_password = off +allowed_ips = "" +bind_address = "" +clients_purge_delay = 0 +compression_level = 6 +ipv6 = on +max_clients = 5 +password = "" +ssl_cert_key = "%h/ssl/relay.pem" +ssl_priorities = "NORMAL:-VERS-SSL3.0" +websocket_allowed_origins = "" + +[irc] +backlog_max_minutes = 1440 +backlog_max_number = 256 +backlog_since_last_disconnect = on +backlog_since_last_message = off +backlog_tags = "irc_privmsg" +backlog_time_format = "[%H:%M] " + +[port] diff --git a/weechat/.config/weechat/script.conf b/weechat/.config/weechat/script.conf new file mode 100644 index 0000000..e1577d4 --- /dev/null +++ b/weechat/.config/weechat/script.conf @@ -0,0 +1,50 @@ +# +# weechat -- script.conf +# + +[look] +columns = "%s %n %V %v %u | %d | %t" +diff_color = on +diff_command = "auto" +display_source = on +quiet_actions = on +sort = "p,n" +translate_description = on +use_keys = on + +[color] +status_autoloaded = cyan +status_held = white +status_installed = lightcyan +status_obsolete = lightmagenta +status_popular = yellow +status_running = lightgreen +status_unknown = lightred +text = default +text_bg = default +text_bg_selected = red +text_date = default +text_date_selected = white +text_delimiters = default +text_description = default +text_description_selected = white +text_extension = default +text_extension_selected = white +text_name = cyan +text_name_selected = lightcyan +text_selected = white +text_tags = brown +text_tags_selected = yellow +text_version = magenta +text_version_loaded = default +text_version_loaded_selected = white +text_version_selected = lightmagenta + +[scripts] +autoload = on +cache_expire = 1440 +download_timeout = 30 +hold = "" +path = "%h/script" +url = "http://weechat.org/files/plugins.xml.gz" +url_force_https = on diff --git a/weechat/.config/weechat/script/plugins.xml.gz b/weechat/.config/weechat/script/plugins.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..d29b2e6c9075ed0d00c8e78917ab3fe97e99351c GIT binary patch literal 102516 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

+7jbV5e);D@)b{QI3(e%D-MHK%VU%>+6GxjECF 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 M3rA+0xLQ;P0QL_Qvj6}9 literal 0 HcmV?d00001 diff --git a/weechat/.config/weechat/trigger.conf b/weechat/.config/weechat/trigger.conf new file mode 100644 index 0000000..df037be --- /dev/null +++ b/weechat/.config/weechat/trigger.conf @@ -0,0 +1,52 @@ +# +# weechat -- trigger.conf +# + +[look] +enabled = on +monitor_strip_colors = off + +[color] +flag_command = lightgreen +flag_conditions = yellow +flag_post_action = lightblue +flag_regex = lightcyan +flag_return_code = lightmagenta +regex = white +replace = cyan +trigger = green +trigger_disabled = red + +[trigger] +beep.arguments = "" +beep.command = "/print -beep" +beep.conditions = "${tg_displayed} && (${tg_highlight} || ${tg_msg_pv})" +beep.enabled = on +beep.hook = print +beep.post_action = none +beep.regex = "" +beep.return_code = ok +cmd_pass.arguments = "5000|input_text_display;5000|history_add;5000|irc_command_auth" +cmd_pass.command = "" +cmd_pass.conditions = "" +cmd_pass.enabled = on +cmd_pass.hook = modifier +cmd_pass.post_action = none +cmd_pass.regex = "==^((/(msg|m|quote) +nickserv +(id|identify|register|ghost +[^ ]+|release +[^ ]+|regain +[^ ]+) +)|/oper +[^ ]+ +|/quote +pass +|/set +[^ ]*password[^ ]* +|/secure +(passphrase|decrypt|set +[^ ]+) +)(.*)==${re:1}${hide:*,${re:+}}" +cmd_pass.return_code = ok +msg_auth.arguments = "5000|irc_message_auth" +msg_auth.command = "" +msg_auth.conditions = "" +msg_auth.enabled = on +msg_auth.hook = modifier +msg_auth.post_action = none +msg_auth.regex = "==^(.*(id|identify|register|ghost +[^ ]+|release +[^ ]+) +)(.*)==${re:1}${hide:*,${re:+}}" +msg_auth.return_code = ok +server_pass.arguments = "5000|input_text_display;5000|history_add" +server_pass.command = "" +server_pass.conditions = "" +server_pass.enabled = on +server_pass.hook = modifier +server_pass.post_action = none +server_pass.regex = "==^(/(server|connect) .*-(sasl_)?password=)([^ ]+)(.*)==${re:1}${hide:*,${re:4}}${re:5}" +server_pass.return_code = ok diff --git a/weechat/.config/weechat/weechat.conf b/weechat/.config/weechat/weechat.conf new file mode 100644 index 0000000..e46175b --- /dev/null +++ b/weechat/.config/weechat/weechat.conf @@ -0,0 +1,630 @@ +# +# weechat -- weechat.conf +# + +[debug] + +[startup] +command_after_plugins = "" +command_before_plugins = "" +display_logo = on +display_version = on +sys_rlimit = "" + +[look] +align_end_of_lines = message +bar_more_down = "▼" +bar_more_left = "◀" +bar_more_right = "▶" +bar_more_up = "▲" +bare_display_exit_on_input = on +bare_display_time_format = "%H:%M:%S" +buffer_auto_renumber = on +buffer_notify_default = all +buffer_position = end +buffer_search_case_sensitive = off +buffer_search_force_default = off +buffer_search_regex = off +buffer_search_where = prefix_message +buffer_time_format = "${color:252}%H:${color:245}%M:${color:240}%S" +color_basic_force_bold = off +color_inactive_buffer = on +color_inactive_message = on +color_inactive_prefix = on +color_inactive_prefix_buffer = on +color_inactive_time = off +color_inactive_window = on +color_nick_offline = off +color_pairs_auto_reset = 5 +color_real_white = off +command_chars = "" +command_incomplete = off +confirm_quit = off +confirm_upgrade = off +day_change = on +day_change_message_1date = "-- %a, %d %b %Y --" +day_change_message_2dates = "-- %%a, %%d %%b %%Y (%a, %d %b %Y) --" +eat_newline_glitch = off +emphasized_attributes = "" +highlight = "" +highlight_regex = "" +highlight_tags = "" +hotlist_add_conditions = "${away} || ${buffer.num_displayed} == 0" +hotlist_buffer_separator = ", " +hotlist_count_max = 2 +hotlist_count_min_msg = 2 +hotlist_names_count = 3 +hotlist_names_length = 0 +hotlist_names_level = 12 +hotlist_names_merged_buffers = off +hotlist_prefix = "" +hotlist_remove = merged +hotlist_short_names = on +hotlist_sort = group_time_asc +hotlist_suffix = "" +hotlist_unique_numbers = on +input_cursor_scroll = 20 +input_share = none +input_share_overwrite = off +input_undo_max = 32 +item_away_message = on +item_buffer_filter = "•" +item_buffer_zoom = "!" +item_mouse_status = "M" +item_time_format = "${color:252}%H:${color:245}%M" +jump_current_to_previous_buffer = on +jump_previous_buffer_when_closing = on +jump_smart_back_to_buffer = on +key_bind_safe = on +key_grab_delay = 800 +mouse = on +mouse_timer_delay = 100 +nick_color_force = "" +nick_color_hash = djb2 +nick_color_stop_chars = "_|[" +nick_prefix = "" +nick_suffix = "" +paste_auto_add_newline = on +paste_bracketed = on +paste_bracketed_timer_delay = 10 +paste_max_lines = 1 +prefix_action = " *" +prefix_align = right +prefix_align_max = 0 +prefix_align_min = 0 +prefix_align_more = "+" +prefix_align_more_after = on +prefix_buffer_align = right +prefix_buffer_align_max = 0 +prefix_buffer_align_more = "+" +prefix_buffer_align_more_after = on +prefix_error = "=!=" +prefix_join = "◥" +prefix_network = "--" +prefix_quit = "◣" +prefix_same_nick = "↪" +prefix_suffix = "|" +quote_nick_prefix = "<" +quote_nick_suffix = ">" +quote_time_format = "%H:%M:%S" +read_marker = line +read_marker_always_show = off +read_marker_string = "- " +save_config_on_exit = on +save_layout_on_exit = none +scroll_amount = 3 +scroll_bottom_after_switch = off +scroll_page_percent = 100 +search_text_not_found_alert = on +separator_horizontal = "-" +separator_vertical = "" +tab_width = 1 +time_format = "%a, %d %b %Y %T" +window_auto_zoom = off +window_separator_horizontal = on +window_separator_vertical = on +window_title = "WeeChat ${info:version}" +word_chars_highlight = "!\u00A0,-,_,|,alnum" +word_chars_input = "!\u00A0,-,_,|,alnum" + +[palette] + +[color] +bar_more = lightmagenta +chat = default +chat_bg = default +chat_buffer = white +chat_channel = white +chat_day_change = cyan +chat_delimiters = green +chat_highlight = yellow +chat_highlight_bg = magenta +chat_host = cyan +chat_inactive_buffer = default +chat_inactive_window = default +chat_nick = lightcyan +chat_nick_colors = "37,43,49,61,67,73,79,85,97,103,109,115,121,133,139,145,151,157,163,169,175,181,187,193,199,205,211,217,223,229" +chat_nick_offline = default +chat_nick_offline_highlight = default +chat_nick_offline_highlight_bg = blue +chat_nick_other = cyan +chat_nick_prefix = green +chat_nick_self = white +chat_nick_suffix = green +chat_prefix_action = white +chat_prefix_buffer = brown +chat_prefix_buffer_inactive_buffer = default +chat_prefix_error = yellow +chat_prefix_join = lightgreen +chat_prefix_more = lightmagenta +chat_prefix_network = magenta +chat_prefix_quit = lightred +chat_prefix_suffix = green +chat_read_marker = magenta +chat_read_marker_bg = default +chat_server = brown +chat_tags = red +chat_text_found = yellow +chat_text_found_bg = lightmagenta +chat_time = default +chat_time_delimiters = brown +chat_value = cyan +chat_value_null = blue +emphasized = yellow +emphasized_bg = magenta +input_actions = lightgreen +input_text_not_found = red +item_away = yellow +nicklist_away = cyan +nicklist_group = green +separator = blue +status_count_highlight = magenta +status_count_msg = brown +status_count_other = default +status_count_private = green +status_data_highlight = lightmagenta +status_data_msg = yellow +status_data_other = default +status_data_private = lightgreen +status_filter = green +status_more = yellow +status_mouse = green +status_name = white +status_name_ssl = lightgreen +status_nicklist_count = default +status_number = yellow +status_time = default + +[completion] +base_word_until_cursor = on +command_inline = on +default_template = "%(nicks)|%(irc_channels)" +nick_add_space = on +nick_completer = ":" +nick_first_only = off +nick_ignore_chars = "[]`_-^" +partial_completion_alert = on +partial_completion_command = off +partial_completion_command_arg = off +partial_completion_count = on +partial_completion_other = off + +[history] +display_default = 5 +max_buffer_lines_minutes = 0 +max_buffer_lines_number = 4096 +max_commands = 100 +max_visited_buffers = 50 + +[proxy] + +[network] +connection_timeout = 60 +gnutls_ca_file = "/etc/ssl/certs/ca-certificates.crt" +gnutls_handshake_timeout = 30 +proxy_curl = "" + +[plugin] +autoload = "*,!lua,!tcl,!ruby,!fifo,!xfer" +debug = off +extension = ".so,.dll" +path = "%h/plugins" +save_config_on_unload = on + +[bar] +buffers.color_bg = default +buffers.color_delim = default +buffers.color_fg = default +buffers.conditions = "" +buffers.filling_left_right = vertical +buffers.filling_top_bottom = columns_vertical +buffers.hidden = on +buffers.items = "buffers" +buffers.position = top +buffers.priority = 0 +buffers.separator = off +buffers.size = 0 +buffers.size_max = 0 +buffers.type = root +input.color_bg = default +input.color_delim = cyan +input.color_fg = default +input.conditions = "" +input.filling_left_right = vertical +input.filling_top_bottom = horizontal +input.hidden = off +input.items = "time,[input_prompt]+(away),[input_search],[input_paste],input_text" +input.position = bottom +input.priority = 1000 +input.separator = off +input.size = 1 +input.size_max = 0 +input.type = window +isetbar.color_bg = default +isetbar.color_delim = cyan +isetbar.color_fg = default +isetbar.conditions = "" +isetbar.filling_left_right = vertical +isetbar.filling_top_bottom = horizontal +isetbar.hidden = on +isetbar.items = "isetbar_help" +isetbar.position = top +isetbar.priority = 0 +isetbar.separator = on +isetbar.size = 3 +isetbar.size_max = 3 +isetbar.type = window +nicklist.color_bg = default +nicklist.color_delim = cyan +nicklist.color_fg = default +nicklist.conditions = "${nicklist}" +nicklist.filling_left_right = vertical +nicklist.filling_top_bottom = columns_vertical +nicklist.hidden = off +nicklist.items = "buffer_nicklist" +nicklist.position = right +nicklist.priority = 200 +nicklist.separator = off +nicklist.size = 0 +nicklist.size_max = 0 +nicklist.type = window +status.color_bg = darkgray +status.color_delim = cyan +status.color_fg = default +status.conditions = "" +status.filling_left_right = vertical +status.filling_top_bottom = horizontal +status.hidden = off +status.items = "[buffer_plugin],buffer_name,scroll,[hotlist],completion" +status.position = bottom +status.priority = 500 +status.separator = off +status.size = 1 +status.size_max = 0 +status.type = window +title.color_bg = darkgray +title.color_delim = cyan +title.color_fg = default +title.conditions = "" +title.filling_left_right = vertical +title.filling_top_bottom = horizontal +title.hidden = off +title.items = "buffer_title" +title.position = top +title.priority = 500 +title.separator = off +title.size = 1 +title.size_max = 0 +title.type = window + +[layout] + +[notify] + +[filter] + +[key] +ctrl-? = "/input delete_previous_char" +ctrl-A = "/input move_beginning_of_line" +ctrl-B = "/input move_previous_char" +ctrl-C_ = "/input insert \x1F" +ctrl-Cb = "/input insert \x02" +ctrl-Cc = "/input insert \x03" +ctrl-Ci = "/input insert \x1D" +ctrl-Co = "/input insert \x0F" +ctrl-Cv = "/input insert \x16" +ctrl-D = "/input delete_next_char" +ctrl-E = "/input move_end_of_line" +ctrl-F = "/input move_next_char" +ctrl-H = "/input delete_previous_char" +ctrl-I = "/input complete_next" +ctrl-J = "/input return" +ctrl-K = "/input delete_end_of_line" +ctrl-L = "/window refresh" +ctrl-M = "/input return" +ctrl-N = "/buffer +1" +ctrl-P = "/buffer -1" +ctrl-R = "/input search_text" +ctrl-Sctrl-U = "/input set_unread" +ctrl-T = "/input transpose_chars" +ctrl-U = "/input delete_beginning_of_line" +ctrl-W = "/input delete_previous_word" +ctrl-X = "/input switch_active_buffer" +ctrl-Y = "/input clipboard_paste" +meta-meta2-1~ = "/window scroll_top" +meta-meta2-23~ = "/bar scroll nicklist * b" +meta-meta2-24~ = "/bar scroll nicklist * e" +meta-meta2-4~ = "/window scroll_bottom" +meta-meta2-5~ = "/window scroll_up" +meta-meta2-6~ = "/window scroll_down" +meta-meta2-7~ = "/window scroll_top" +meta-meta2-8~ = "/window scroll_bottom" +meta-meta2-A = "/buffer -1" +meta-meta2-B = "/buffer +1" +meta-meta2-C = "/buffer +1" +meta-meta2-D = "/buffer -1" +meta-- = "/filter toggle @" +meta-/ = "/input jump_last_buffer_displayed" +meta-0 = "/buffer *10" +meta-1 = "/buffer *1" +meta-2 = "/buffer *2" +meta-3 = "/buffer *3" +meta-4 = "/buffer *4" +meta-5 = "/buffer *5" +meta-6 = "/buffer *6" +meta-7 = "/buffer *7" +meta-8 = "/buffer *8" +meta-9 = "/buffer *9" +meta-< = "/input jump_previously_visited_buffer" +meta-= = "/filter toggle" +meta-> = "/input jump_next_visited_buffer" +meta-OA = "/input history_global_previous" +meta-OB = "/input history_global_next" +meta-OC = "/input move_next_word" +meta-OD = "/input move_previous_word" +meta-OF = "/input move_end_of_line" +meta-OH = "/input move_beginning_of_line" +meta-Oa = "/input history_global_previous" +meta-Ob = "/input history_global_next" +meta-Oc = "/input move_next_word" +meta-Od = "/input move_previous_word" +meta2-15~ = "/buffer -1" +meta2-17~ = "/buffer +1" +meta2-18~ = "/window -1" +meta2-19~ = "/window +1" +meta2-1;3A = "/buffer -1" +meta2-1;3B = "/buffer +1" +meta2-1;3C = "/buffer +1" +meta2-1;3D = "/buffer -1" +meta2-1;3F = "/window scroll_bottom" +meta2-1;3H = "/window scroll_top" +meta2-1;5A = "/input history_global_previous" +meta2-1;5B = "/input history_global_next" +meta2-1;5C = "/input move_next_word" +meta2-1;5D = "/input move_previous_word" +meta2-1~ = "/input move_beginning_of_line" +meta2-200~ = "/input paste_start" +meta2-201~ = "/input paste_stop" +meta2-20~ = "/bar scroll title * -30%" +meta2-21~ = "/bar scroll title * +30%" +meta2-23;3~ = "/bar scroll nicklist * b" +meta2-23~ = "/bar scroll nicklist * -100%" +meta2-24;3~ = "/bar scroll nicklist * e" +meta2-24~ = "/bar scroll nicklist * +100%" +meta2-3~ = "/input delete_next_char" +meta2-4~ = "/input move_end_of_line" +meta2-5;3~ = "/window scroll_up" +meta2-5~ = "/window page_up" +meta2-6;3~ = "/window scroll_down" +meta2-6~ = "/window page_down" +meta2-7~ = "/input move_beginning_of_line" +meta2-8~ = "/input move_end_of_line" +meta2-A = "/input history_previous" +meta2-B = "/input history_next" +meta2-C = "/input move_next_char" +meta2-D = "/input move_previous_char" +meta2-F = "/input move_end_of_line" +meta2-G = "/window page_down" +meta2-H = "/input move_beginning_of_line" +meta2-I = "/window page_up" +meta2-Z = "/input complete_previous" +meta2-[E = "/buffer -1" +meta-_ = "/input redo" +meta-a = "/input jump_smart" +meta-b = "/input move_previous_word" +meta-d = "/input delete_next_word" +meta-f = "/input move_next_word" +meta-h = "/input hotlist_clear" +meta-jmeta-f = "/buffer -" +meta-jmeta-l = "/buffer +" +meta-jmeta-r = "/server raw" +meta-jmeta-s = "/server jump" +meta-j01 = "/buffer 1" +meta-j02 = "/buffer 2" +meta-j03 = "/buffer 3" +meta-j04 = "/buffer 4" +meta-j05 = "/buffer 5" +meta-j06 = "/buffer 6" +meta-j07 = "/buffer 7" +meta-j08 = "/buffer 8" +meta-j09 = "/buffer 9" +meta-j10 = "/buffer 10" +meta-j11 = "/buffer 11" +meta-j12 = "/buffer 12" +meta-j13 = "/buffer 13" +meta-j14 = "/buffer 14" +meta-j15 = "/buffer 15" +meta-j16 = "/buffer 16" +meta-j17 = "/buffer 17" +meta-j18 = "/buffer 18" +meta-j19 = "/buffer 19" +meta-j20 = "/buffer 20" +meta-j21 = "/buffer 21" +meta-j22 = "/buffer 22" +meta-j23 = "/buffer 23" +meta-j24 = "/buffer 24" +meta-j25 = "/buffer 25" +meta-j26 = "/buffer 26" +meta-j27 = "/buffer 27" +meta-j28 = "/buffer 28" +meta-j29 = "/buffer 29" +meta-j30 = "/buffer 30" +meta-j31 = "/buffer 31" +meta-j32 = "/buffer 32" +meta-j33 = "/buffer 33" +meta-j34 = "/buffer 34" +meta-j35 = "/buffer 35" +meta-j36 = "/buffer 36" +meta-j37 = "/buffer 37" +meta-j38 = "/buffer 38" +meta-j39 = "/buffer 39" +meta-j40 = "/buffer 40" +meta-j41 = "/buffer 41" +meta-j42 = "/buffer 42" +meta-j43 = "/buffer 43" +meta-j44 = "/buffer 44" +meta-j45 = "/buffer 45" +meta-j46 = "/buffer 46" +meta-j47 = "/buffer 47" +meta-j48 = "/buffer 48" +meta-j49 = "/buffer 49" +meta-j50 = "/buffer 50" +meta-j51 = "/buffer 51" +meta-j52 = "/buffer 52" +meta-j53 = "/buffer 53" +meta-j54 = "/buffer 54" +meta-j55 = "/buffer 55" +meta-j56 = "/buffer 56" +meta-j57 = "/buffer 57" +meta-j58 = "/buffer 58" +meta-j59 = "/buffer 59" +meta-j60 = "/buffer 60" +meta-j61 = "/buffer 61" +meta-j62 = "/buffer 62" +meta-j63 = "/buffer 63" +meta-j64 = "/buffer 64" +meta-j65 = "/buffer 65" +meta-j66 = "/buffer 66" +meta-j67 = "/buffer 67" +meta-j68 = "/buffer 68" +meta-j69 = "/buffer 69" +meta-j70 = "/buffer 70" +meta-j71 = "/buffer 71" +meta-j72 = "/buffer 72" +meta-j73 = "/buffer 73" +meta-j74 = "/buffer 74" +meta-j75 = "/buffer 75" +meta-j76 = "/buffer 76" +meta-j77 = "/buffer 77" +meta-j78 = "/buffer 78" +meta-j79 = "/buffer 79" +meta-j80 = "/buffer 80" +meta-j81 = "/buffer 81" +meta-j82 = "/buffer 82" +meta-j83 = "/buffer 83" +meta-j84 = "/buffer 84" +meta-j85 = "/buffer 85" +meta-j86 = "/buffer 86" +meta-j87 = "/buffer 87" +meta-j88 = "/buffer 88" +meta-j89 = "/buffer 89" +meta-j90 = "/buffer 90" +meta-j91 = "/buffer 91" +meta-j92 = "/buffer 92" +meta-j93 = "/buffer 93" +meta-j94 = "/buffer 94" +meta-j95 = "/buffer 95" +meta-j96 = "/buffer 96" +meta-j97 = "/buffer 97" +meta-j98 = "/buffer 98" +meta-j99 = "/buffer 99" +meta-k = "/input grab_key_command" +meta-l = "/window bare" +meta-m = "/mute mouse toggle" +meta-n = "/window scroll_next_highlight" +meta-p = "/window scroll_previous_highlight" +meta-r = "/input delete_line" +meta-s = "/mute aspell toggle" +meta-u = "/window scroll_unread" +meta-wmeta-meta2-A = "/window up" +meta-wmeta-meta2-B = "/window down" +meta-wmeta-meta2-C = "/window right" +meta-wmeta-meta2-D = "/window left" +meta-wmeta2-1;3A = "/window up" +meta-wmeta2-1;3B = "/window down" +meta-wmeta2-1;3C = "/window right" +meta-wmeta2-1;3D = "/window left" +meta-wmeta-b = "/window balance" +meta-wmeta-s = "/window swap" +meta-x = "/input zoom_merged_buffer" +meta-z = "/window zoom" +ctrl-_ = "/input undo" + +[key_search] +ctrl-I = "/input search_switch_where" +ctrl-J = "/input search_stop" +ctrl-M = "/input search_stop" +ctrl-R = "/input search_switch_regex" +meta2-A = "/input search_previous" +meta2-B = "/input search_next" +meta-c = "/input search_switch_case" + +[key_cursor] +ctrl-J = "/cursor stop" +ctrl-M = "/cursor stop" +meta-meta2-A = "/cursor move area_up" +meta-meta2-B = "/cursor move area_down" +meta-meta2-C = "/cursor move area_right" +meta-meta2-D = "/cursor move area_left" +meta2-1;3A = "/cursor move area_up" +meta2-1;3B = "/cursor move area_down" +meta2-1;3C = "/cursor move area_right" +meta2-1;3D = "/cursor move area_left" +meta2-A = "/cursor move up" +meta2-B = "/cursor move down" +meta2-C = "/cursor move right" +meta2-D = "/cursor move left" +@item(buffer_nicklist):K = "/window ${_window_number};/kickban ${nick}" +@item(buffer_nicklist):b = "/window ${_window_number};/ban ${nick}" +@item(buffer_nicklist):k = "/window ${_window_number};/kick ${nick}" +@item(buffer_nicklist):q = "/window ${_window_number};/query ${nick};/cursor stop" +@item(buffer_nicklist):w = "/window ${_window_number};/whois ${nick}" +@chat:Q = "hsignal:chat_quote_time_prefix_message;/cursor stop" +@chat:m = "hsignal:chat_quote_message;/cursor stop" +@chat:q = "hsignal:chat_quote_prefix_message;/cursor stop" + +[key_mouse] +@bar(buffers):ctrl-wheeldown = "hsignal:buffers_mouse" +@bar(buffers):ctrl-wheelup = "hsignal:buffers_mouse" +@bar(input):button2 = "/input grab_mouse_area" +@bar(nicklist):button1-gesture-down = "/bar scroll nicklist ${_window_number} +100%" +@bar(nicklist):button1-gesture-down-long = "/bar scroll nicklist ${_window_number} e" +@bar(nicklist):button1-gesture-up = "/bar scroll nicklist ${_window_number} -100%" +@bar(nicklist):button1-gesture-up-long = "/bar scroll nicklist ${_window_number} b" +@chat(perl.iset):button1 = "hsignal:iset_mouse" +@chat(perl.iset):button2* = "hsignal:iset_mouse" +@chat(perl.iset):wheeldown = "/repeat 5 /iset **down" +@chat(perl.iset):wheelup = "/repeat 5 /iset **up" +@chat(script.scripts):button1 = "/window ${_window_number};/script go ${_chat_line_y}" +@chat(script.scripts):button2 = "/window ${_window_number};/script go ${_chat_line_y};/script installremove -q ${script_name_with_extension}" +@chat(script.scripts):wheeldown = "/script down 5" +@chat(script.scripts):wheelup = "/script up 5" +@item(buffer_nicklist):button1 = "/window ${_window_number};/query ${nick}" +@item(buffer_nicklist):button1-gesture-left = "/window ${_window_number};/kick ${nick}" +@item(buffer_nicklist):button1-gesture-left-long = "/window ${_window_number};/kickban ${nick}" +@item(buffer_nicklist):button2 = "/window ${_window_number};/whois ${nick}" +@item(buffer_nicklist):button2-gesture-left = "/window ${_window_number};/ban ${nick}" +@item(buffers):button1* = "hsignal:buffers_mouse" +@item(buffers):button2* = "hsignal:buffers_mouse" +@bar:wheeldown = "/bar scroll ${_bar_name} ${_window_number} +20%" +@bar:wheelup = "/bar scroll ${_bar_name} ${_window_number} -20%" +@chat:button1 = "/window ${_window_number}" +@chat:button1-gesture-left = "/window ${_window_number};/buffer -1" +@chat:button1-gesture-left-long = "/window ${_window_number};/buffer 1" +@chat:button1-gesture-right = "/window ${_window_number};/buffer +1" +@chat:button1-gesture-right-long = "/window ${_window_number};/input jump_last_buffer" +@chat:ctrl-wheeldown = "/window scroll_horiz -window ${_window_number} +10%" +@chat:ctrl-wheelup = "/window scroll_horiz -window ${_window_number} -10%" +@chat:wheeldown = "/window scroll_down -window ${_window_number}" +@chat:wheelup = "/window scroll_up -window ${_window_number}" +@*:button3 = "/cursor go ${_x},${_y}" diff --git a/weechat/.config/weechat/xfer.conf b/weechat/.config/weechat/xfer.conf new file mode 100644 index 0000000..39ac5bd --- /dev/null +++ b/weechat/.config/weechat/xfer.conf @@ -0,0 +1,39 @@ +# +# weechat -- xfer.conf +# + +[look] +auto_open_buffer = on +progress_bar_size = 20 +pv_tags = "notify_private" + +[color] +status_aborted = lightred +status_active = lightblue +status_connecting = yellow +status_done = lightgreen +status_failed = lightred +status_waiting = lightcyan +text = default +text_bg = default +text_selected = white + +[network] +blocksize = 65536 +fast_send = on +own_ip = "" +port_range = "" +speed_limit = 0 +timeout = 300 + +[file] +auto_accept_chats = off +auto_accept_files = off +auto_accept_nicks = "" +auto_check_crc32 = off +auto_rename = on +auto_resume = on +convert_spaces = on +download_path = "%h/xfer" +upload_path = "~" +use_nick_in_filename = on diff --git a/zsh/.oh-my-zsh/custom/weechat.zsh b/zsh/.oh-my-zsh/custom/weechat.zsh new file mode 100644 index 0000000..771cad1 --- /dev/null +++ b/zsh/.oh-my-zsh/custom/weechat.zsh @@ -0,0 +1,2 @@ +# Conform to XDG base directory specifications +export WEECHAT_HOME="$HOME/.config/weechat"