a9f1df02501f

More
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 21 Oct 2023 15:01:32 -0400
parents 80f0db7bdfd0
children 96273ff110b3
branches/tags (none)
files bin/bootstrap.sh stumpwmrc weechat-old/.agignore weechat-old/GandiStandardSSLCA.crt weechat-old/alias.conf weechat-old/aspell.conf weechat-old/autosort.conf weechat-old/buffers.conf weechat-old/buflist.conf weechat-old/charset.conf weechat-old/exec.conf weechat-old/fifo.conf weechat-old/fset.conf weechat-old/icon.png weechat-old/logger.conf weechat-old/lua.conf weechat-old/perl.conf weechat-old/perl/autoload/colorize_lines.pl weechat-old/python.conf weechat-old/python/autoload/autosort.py weechat-old/python/autoload/brows.py weechat-old/python/autoload/editor.py weechat-old/python/autoload/notify.py weechat-old/python/autoload/quotes.py weechat-old/python/autoload/urlgrab.py weechat-old/python/autoload/wee_slack.py weechat-old/python/autosort.py weechat-old/python/colon_complete.py weechat-old/python/listbuffer.py weechat-old/python/sanitize_jira.py weechat-old/relay.conf weechat-old/rmodifier.conf weechat-old/ruby.conf weechat-old/script.conf weechat-old/spell.conf weechat-old/tcl.conf weechat-old/trigger.conf weechat-old/typing.conf weechat-old/urlgrab.conf weechat-old/weechat.conf weechat-old/xfer.conf weechat/.agignore weechat/GandiStandardSSLCA.crt weechat/alias.conf weechat/aspell.conf weechat/autosort.conf weechat/buffers.conf weechat/buflist.conf weechat/charset.conf weechat/exec.conf weechat/fifo.conf weechat/fset.conf weechat/icon.png weechat/logger.conf weechat/lua.conf weechat/perl.conf weechat/perl/autoload/colorize_lines.pl weechat/python.conf weechat/python/autoload/autosort.py weechat/python/autoload/brows.py weechat/python/autoload/editor.py weechat/python/autoload/notify.py weechat/python/autoload/quotes.py weechat/python/autoload/urlgrab.py weechat/python/autoload/wee_slack.py weechat/python/autosort.py weechat/python/colon_complete.py weechat/python/listbuffer.py weechat/python/sanitize_jira.py weechat/relay.conf weechat/rmodifier.conf weechat/ruby.conf weechat/ruby/autoload/challengeauth.rb weechat/script.conf weechat/spell.conf weechat/tcl.conf weechat/trigger.conf weechat/typing.conf weechat/urlgrab.conf weechat/weechat.conf weechat/xfer.conf

Changes

--- a/bin/bootstrap.sh	Fri Oct 20 14:03:50 2023 -0400
+++ b/bin/bootstrap.sh	Sat Oct 21 15:01:32 2023 -0400
@@ -17,6 +17,7 @@
 mkdir -p ~/bin
 mkdir -p ~/src
 mkdir -p ~/.w3m
+mkdir -p ~/.weechat
 
 ensure_link "src/dotfiles/hgrc" ".hgrc"
 
@@ -61,7 +62,6 @@
 ensure_link "src/dotfiles/vim/vimrc-minimal"           ".vimrc-minimal"
 ensure_link "src/dotfiles/w3m-keymap"                  ".w3m/keymap"
 ensure_link "src/dotfiles/w3m-config"                  ".w3m/config"
-ensure_link "src/dotfiles/weechat"                     ".weechat"
 ensure_link "src/dotfiles/xbindkeysrc"                 ".xbindkeysrc"
 ensure_link "src/dotfiles/xsessionrc"                  ".xsessionrc"
 
--- a/stumpwmrc	Fri Oct 20 14:03:50 2023 -0400
+++ b/stumpwmrc	Sat Oct 21 15:01:32 2023 -0400
@@ -424,6 +424,9 @@
         (pass:*pass-notification-message* t))
     (pass:pass-copy)))
 
+(defcommand switch-yubikeys () ()
+  (echo (run-shell-command "switch-yubikeys" t)))
+
 (defcommand generate-password () ()
   (run-shell-command "genpass | pbc")
   (message "Generated a fresh password and copied it to the clipboard."))
@@ -673,6 +676,7 @@
   ("H-SunPageUp" "st-font-up")
   ("H-SunPageDown" "st-font-down")
   ("H-Home" "st-font-reset")
+  ("H-F4" "switch-yubikeys")
   ("H-\\" "pass-personal")
   ("H-|" "generate-password")
   ("H-b" "browser")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/.agignore	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,2 @@
+logs/
+urls.log
Binary file weechat-old/GandiStandardSSLCA.crt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/alias.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,45 @@
+#
+# weechat -- alias.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[cmd]
+AAWAY = "allserv /away"
+AME = "allchan /me"
+AMSG = "allchan /msg *"
+ANICK = "allserv /nick"
+b = "/buffer"
+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"
+MUB = "unban *"
+N = "names"
+Q = "query"
+REDRAW = "window refresh"
+SAY = "msg *"
+SIGNOFF = "quit"
+T = "topic"
+UB = "unban"
+V = "command core version"
+W = "who"
+WC = "window merge"
+WI = "whois"
+WII = "whois $1 $1"
+WW = "whowas"
+
+[completion]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/aspell.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,33 @@
+#
+# weechat -- aspell.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use /set or similar command to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[color]
+misspelled = lightred
+suggestion = default
+suggestion_delimiter_dict = cyan
+suggestion_delimiter_word = cyan
+
+[check]
+commands = "ame,amsg,away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic"
+default_dict = "en"
+during_search = off
+enabled = off
+real_time = off
+suggestions = -1
+word_min_length = 2
+
+[dict]
+
+[look]
+suggestion_delimiter_dict = " / "
+suggestion_delimiter_word = ","
+
+[option]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/autosort.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,24 @@
+#
+# weechat -- autosort.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[sorting]
+case_sensitive = off
+debug_log = off
+replacements = "[]"
+rules = "[["core", 0], ["irc", 2], ["*", 1], ["irc.irc_raw", 0], ["irc.server", 1]]"
+signal_delay = 5
+signals = "buffer_opened buffer_merged buffer_unmerged buffer_renamed"
+sort_limit = 100
+sort_on_config_change = on
+
+[v3]
+helpers = "{"core_first": "${if:${buffer.full_name}!=core.weechat}", "irc_raw_first": "${if:${buffer.full_name}!=irc.irc_raw}", "irc_raw_last": "${if:${buffer.full_name}==irc.irc_raw}", "hashless_name": "${info:autosort_replace,#,,${info:autosort_escape,${buffer.name}}}", "script_or_plugin": "${if:${script_name}?${script_name}:${plugin}}"}"
+rules = "["${core_first}", "${info:autosort_order,${info:autosort_escape,${script_or_plugin}},core,*,irc,bitlbee,matrix,slack}", "${script_or_plugin}", "${irc_raw_first}", "${server}", "${info:autosort_order,${type},server,*,channel,private}", "${hashless_name}", "${buffer.full_name}"]"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/buffers.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,77 @@
+#
+# weechat -- buffers.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use /set or similar command to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[color]
+current_bg = green
+current_fg = black
+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 = green
+hotlist_private_bg = default
+hotlist_private_fg = *magenta
+none_channel_bg = default
+none_channel_fg = 240
+number = green
+number_char = green
+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_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_number = on
+jump_prev_next_visited_buffer = off
+mark_inactive = off
+mouse_move_buffer = 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 = ""
+toogle_bar = on
+whitelist_buffers = ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/buflist.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,41 @@
+#
+# weechat -- buflist.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[look]
+add_newline = on
+auto_scroll = 50
+display_conditions = "${buffer.hidden}==0"
+enabled = on
+mouse_jump_visited_buffer = off
+mouse_move_buffer = on
+mouse_wheel = on
+nick_prefix = off
+nick_prefix_empty = on
+signals_refresh = ""
+sort = "number,-active"
+use_items = 1
+
+[format]
+buffer = "${format_number}${indent}${format_nick_prefix}${color_hotlist}${format_name}"
+buffer_current = "${color:,blue}${format_buffer}"
+hotlist = " ${color:green}(${hotlist}${color:green})"
+hotlist_highlight = "${color:magenta}"
+hotlist_low = "${color:white}"
+hotlist_message = "${color:green}"
+hotlist_none = "${color:default}"
+hotlist_private = "${color:magenta}"
+hotlist_separator = "${color:default},"
+indent = "  "
+lag = " ${color:green}[${color:brown}${lag}${color:green}]"
+name = "${name}"
+nick_prefix = "${color_nick_prefix}${nick_prefix}"
+number = "${color:green}${number}${if:${number_displayed}?.: }"
+tls_version = " ${color:default}(${if:${tls_version}==TLS1.3?${color:green}:${if:${tls_version}==TLS1.2?${color:yellow}:${color:red}}}${translate:${tls_version}}${color:default})"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/charset.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,18 @@
+#
+# weechat -- charset.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[default]
+decode = "iso-8859-1"
+encode = ""
+
+[decode]
+
+[encode]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/exec.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,19 @@
+#
+# weechat -- exec.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[command]
+default_options = ""
+purge_delay = 0
+shell = "${env:SHELL}"
+
+[color]
+flag_finished = lightred
+flag_running = lightgreen
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/fifo.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,14 @@
+#
+# weechat -- fifo.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[file]
+enabled = on
+path = "%h/weechat_fifo"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/fset.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,96 @@
+#
+# weechat -- fset.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[look]
+auto_refresh = "*"
+auto_unmark = off
+condition_catch_set = "${count} >= 1"
+export_help_default = on
+format_number = 1
+marked_string = "*"
+scroll_horizontal = 10
+show_plugins_desc = off
+sort = "~name"
+unmarked_string = " "
+use_color_value = off
+use_keys = on
+use_mute = off
+
+[format]
+export_help = "# ${description2}"
+export_option = "/set ${name} ${quoted_value}"
+export_option_null = "/unset ${name}"
+option1 = ""
+option2 = "${marked} ${name}  ${type}  ${value2}${newline}  ${empty_name}  ${_default_value}${color:darkgray} -- ${min}..${max}${newline}  ${empty_name}  ${description}"
+
+[color]
+default_value = default
+default_value_selected = white
+description = default
+description_selected = white
+file = default
+file_changed = brown
+file_changed_selected = yellow
+file_selected = white
+help_default_value = white
+help_description = default
+help_name = white
+help_quotes = darkgray
+help_values = default
+index = cyan
+index_selected = lightcyan
+line_marked_bg1 = default
+line_marked_bg2 = default
+line_selected_bg1 = blue
+line_selected_bg2 = red
+marked = brown
+marked_selected = yellow
+max = default
+max_selected = white
+min = default
+min_selected = white
+name = default
+name_changed = brown
+name_changed_selected = yellow
+name_selected = white
+option = default
+option_changed = brown
+option_changed_selected = yellow
+option_selected = white
+parent_name = default
+parent_name_selected = white
+parent_value = cyan
+parent_value_selected = lightcyan
+quotes = darkgray
+quotes_changed = default
+quotes_changed_selected = white
+quotes_selected = default
+section = default
+section_changed = brown
+section_changed_selected = yellow
+section_selected = white
+string_values = default
+string_values_selected = white
+title_count_options = cyan
+title_current_option = lightcyan
+title_filter = yellow
+title_marked_options = lightgreen
+title_sort = white
+type = green
+type_selected = lightgreen
+unmarked = default
+unmarked_selected = white
+value = cyan
+value_changed = brown
+value_changed_selected = yellow
+value_selected = lightcyan
+value_undef = magenta
+value_undef_selected = lightmagenta
Binary file weechat-old/icon.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/logger.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,36 @@
+#
+# weechat -- logger.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[look]
+backlog = 20
+backlog_conditions = ""
+
+[color]
+backlog_end = darkgray
+backlog_line = darkgray
+
+[file]
+auto_log = on
+color_lines = off
+flush_delay = 120
+fsync = off
+info_lines = off
+mask = "$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]
+
+[mask]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/lua.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,14 @@
+#
+# weechat -- lua.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use /set or similar command to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[look]
+check_license = off
+eval_keep_context = on
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/perl.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,14 @@
+#
+# weechat -- perl.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[look]
+check_license = off
+eval_keep_context = on
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/perl/autoload/colorize_lines.pl	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,251 @@
+#
+# Copyright (c) 2010-2013 by Nils Görs <weechatter@arcor.de>
+# Copyleft (ɔ) 2013 by oakkitten
+#
+# colors the channel text with nick color and also highlight the whole line
+# colorize_nicks.py script will be supported
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+# with version 3.0 some options were renamed or have new possible values:
+# old:                  new:
+# avail_buffer          buffer
+# blacklist_channels    blacklist_buffers
+# highlight             new values
+
+# obsolete options:
+# buffer_autoset
+# hotlist_max_level_nicks_add
+# highlight_regex
+# highlight_words
+# shuffle
+# chat                  see option highlight
+
+# history:
+# 3.0: large part of script rewritten
+#      fix: works nicely with irc colors
+#      improved: highlight_regex and highlight_words work in a natural way
+#      removed: command /colorize_lines
+#      removed: option shuffle
+# 2.2: fix: regex with [tab] in message (patch by sqrrl)
+# 2.1: fix: changing highlight color did not apply messages already displayed (reported by rafi_)
+# 2.0: fix: debugging weechat::print() removed (thanks demure)
+# 1.9: fix: display bug with nick_mode
+# 1.8  add: option "use_irc_colors" (requested by Zertap)
+#      fix: empty char for nick_mode was used, even when "irc.look.nick_mode_empty" was OFF (reported by FlashCode)
+# 1.7: fix: broken lines in dcc chat (reported by equatorping)
+# 1.6: improved: wildcard "*" can be used for server and/or nick. (requested by ldvx)
+#    : add: new value, "only", for option "own_lines" (read help!)
+# 1.5: sync: option weechat.look.nickmode changed in 0.3.9 to "irc.look.nick_mode"
+# 1.4: fix: whole ctcp message was display in prefix (reported by : Mkaysi)
+# 1.3: fix: now using weechat::buffer_get_string() instead of regex to prevent problems with dots inside server-/channelnames (reported by surfhai)
+# 1.2: add: hook_modifier("colorize_lines") to use colorize_lines with another script.
+#    : fix: regex was too greedy and also hit tag "prefix_nick_ccc"
+# 1.1: fix:  problems with temporary server (reported by nand`)
+#    : improved: using weechat_string_has_highlight()
+# 1.0: fix: irc.look.nick_prefix wasn't supported
+# 0.9: added: option "own_nick" (idea by travkin)
+#    : new value (always) for option highlight
+#    : clean up code
+# 0.8.1: fix: regex()
+# 0.8: added: option "avail_buffer" and "nicks" (please read help-page) (suggested by ldvx)
+#    : fix: blacklist_buffers wasn't load at start
+#    : fix: nick_modes wasn't displayed since v0.7
+#    : rewrote init() routine
+#    : thanks to stfn for hint with unescaped variables in regex.
+# 0.7: fix: bug when irc.look.nick_suffix was set (reported and beta-testing by: hw2) (>= weechat 0.3.4)
+#      blacklist_buffers option supports servername
+#      clean up code
+# 0.6: code optimazations.
+#      rename of script (rainbow_text.pl -> colorize_lines.pl) (suggested by xt and flashcode)
+# 0.5: support of hotlist_max_level_nicks_add and weechat.color.chat_nick_colors (>= weechat 0.3.4)
+# 0.4: support of weechat.look.highlight_regex option (>= weechat 0.3.4)
+#    : support of weechat.look.highlight option
+#    : highlighted line did not work with "." inside servername
+#    ; internal "autoset" function fixed
+# 0.3: support of colorize_nicks.py implemented.
+#    : /me text displayed wrong nick colour (colour from suffix was used)
+#    : highlight messages will be checked case insensitiv
+# 0.2: supports highlight_words_add from buffer_autoset.py script (suggested: Emralegna)
+#    : correct look_nickmode colour will be used (bug reported by: Emralegna)
+#    : /me text will be coloured, too
+# 0.1: initial release
+#
+# Development is currently hosted at
+# https://github.com/weechatter/weechat-scripts
+
+# use Data::Dumper
+# $Data::Dumper::Useqq=1;
+
+use strict;
+my $prgname	= "colorize_lines";
+my $version	= "3.0";
+my $description	= "colors text in chat area with according nick color, including highlights";
+
+my %config = ("buffers"             => "all",       # all, channel, query
+              "blacklist_buffers"   => "",          # "a,b,c"
+              "lines"               => "on",
+              "highlight"           => "on",        # on, off, nicks
+              "nicks"               => "",          # "d,e,f", "/file"
+              "own_lines"           => "on",        # on, off, only
+);
+
+my %help_desc = ("buffers"             => "buffer type affected by the script (all/channel/query, default: all)",
+                 "blacklist_buffers"   => "comma-separated list of channels to be ignored (e.g. freenode.#weechat,*.#python)",
+                 "lines"               => "apply nickname color to the non-highlighted lines (off/on/nicks). the latter will limit highlighting to nicknames in option 'nicks'",
+                 "highlight"           => "apply highlight color to the highlighted lines (off/on/nicks). the latter will limit highlighting to nicknames in option 'nicks'",
+                 "nicks"               => "comma-separater list of nicks (e.g. freenode.cat,*.dog) OR file name starting with '/' (e.g. /file.txt). in the latter case, nicknames will get loaded from that file inside weechat folder (e.g. from ~/.weechat/file.txt). nicknames in file are newline-separated (e.g. freenode.dog\\n*.cat)",
+                 "own_lines"           => "apply nickname color to own lines (off/on/only). the latter turns off all other kinds of coloring altogether",
+);
+
+#################################################################################################### config
+
+# program starts here
+sub colorize_cb {
+    my ( $data, $modifier, $modifier_data, $string ) = @_;
+
+    # quit if it's not a privmsg or ctcp
+    # or we are not supposed to
+    if ((index($modifier_data,"irc_privmsg") == -1) ||
+        (index($modifier_data,"irc_ctcp") >= 0)) {
+        return $string;
+    }
+
+    # find buffer pointer
+    $modifier_data =~ m/([^;]*);([^;]*);/;
+    my $buffer = weechat::buffer_search($1, $2);
+    return $string if ($buffer eq "");
+
+    # find buffer name, server name
+    # return if buffer is in a blacklist
+    my $buffername = weechat::buffer_get_string($buffer, "name");
+    return $string if weechat::string_has_highlight($buffername, $config{blacklist_buffers});
+    my $servername = weechat::buffer_get_string($buffer, "localvar_server");
+
+    # find stuff between \t
+    $string =~ m/^([^\t]*)\t(.*)/;
+    my $left = $1;
+    my $right = $2;
+
+    # find nick of the sender
+    # find out if we are doing an action
+    my $nick = ($modifier_data =~ m/(^|,)nick_([^,]*)/) ? $2 : weechat::string_remove_color($left, "");
+    my $action = ($modifier_data =~ m/\birc_action\b/) ? 1 : 0;
+
+    ######################################## get color
+
+    my $color = "";
+    my $my_nick = weechat::buffer_get_string($buffer, "localvar_nick");
+    if ($my_nick eq $nick) {
+        # it's our own line
+        # process only if own_lines is "on" or "only" (i.e. not "off")
+        return $string if ($config{own_lines} eq "off");
+        $color = weechat::color("chat_nick_self");
+    } else {
+        # it's someone else's line
+        # don't process is own_lines are "only"
+        # in order to get correct matching, remove colors from the string
+        return $string if ($config{own_lines} eq "only");
+        my $right_nocolor = weechat::string_remove_color($right, "");
+        if (weechat::string_has_highlight($right_nocolor, weechat::buffer_string_replace_local_var($buffer, weechat::buffer_get_string($buffer, "highlight_words"))) ||
+            weechat::string_has_highlight($right_nocolor, weechat::config_string(weechat::config_get("weechat.look.highlight"))) ||
+            weechat::string_has_highlight_regex($right_nocolor, weechat::config_string(weechat::config_get("weechat.look.highlight_regex"))) ||
+            weechat::string_has_highlight_regex($right_nocolor, weechat::buffer_get_string($buffer, "highlight_regex"))
+           ) {
+            # we have a hilight! get a hilight color
+            # and replace the first occurance of coloring, that'd be nick color
+            # process only if highlight is "on" OR "nicks" & nick's in nicks
+            return $string if ($config{highlight} eq "off" ||
+                ($config{highlight} eq "nicks" && !weechat::string_has_highlight("$servername.$nick", $config{nicks})));
+            $color = weechat::color('chat_highlight');
+            $right =~ s/\31[^\31 ]+?\Q$nick/$color$nick/ if ($action);
+        } else {
+            # that's not a highlight
+            # process only if lines is "on" OR "nicks" & nick's in nicks
+            return $string if ($config{lines} eq "off" ||
+                ($config{lines} eq "nicks" && !weechat::string_has_highlight("$servername.$nick", $config{nicks})));
+            $color = weechat::info_get('irc_nick_color', $nick);
+        }
+    }
+
+    ######################################## inject colors and go!
+
+    my $out = "";
+    if ($action) {
+        # remove the first color reset - after * nick
+        # make other resets reset to our color
+        $right =~ s/\34//;
+        $right =~ s/\34/\34$color/g;
+        $out = $left . "\t" . $right . "\34"
+    } else {
+        # make other resets reset to our color
+        $right =~ s/\34/\34$color/g;
+        $out = $left . "\t" . $color . $right . "\34"
+    }
+    #weechat::print("", ""); weechat::print("", "\$str " . Dumper($string)); weechat::print("", "\$out " . Dumper($out));
+    return $out;
+}
+
+#################################################################################################### config
+
+# read nicknames if $conf{nisks} starts with /
+# after this, $conf{nisks} is of form a,b,c,d
+# if it doesnt start with /, assume it's already a,b,c,d
+sub nicklist_read {
+    return if (substr($config{nicks}, 0, 1) ne "/");
+    my $file = weechat::info_get("weechat_dir", "") . $config{nicks};
+    return unless -e $file;
+    my $nili = "";
+    open (WL, "<", $file) || DEBUG("$file: $!");
+    while (<WL>) {
+        chomp;                                                         # kill LF
+        $nili .= $_ . ",";
+    }
+    close WL;
+    chop $nili;                                                        # remove last ","
+    $config{nicks} = $nili;
+}
+
+# called when a config option ha been changed
+# $name = plugins.var.perl.$prgname.nicks etc
+sub toggle_config_by_set {
+    my ($pointer, $name, $value) = @_;
+    $name = substr($name,length("plugins.var.perl.$prgname."),length($name));
+    $config{$name} = lc($value);
+    nicklist_read() if ($name eq "nicks");
+}
+
+# read configuration from weechat OR
+#   set default options and
+#   set dectription if weechat >= 0.3.5
+# after done, read nicklist from file if needed
+sub init_config {
+    my $weechat_version = weechat::info_get('version_number', '') || 0;
+    foreach my $option (keys %config){
+        if (!weechat::config_is_set_plugin($option)) {
+            weechat::config_set_plugin($option, $config{$option});
+            weechat::config_set_desc_plugin($option, $help_desc{$option}) if ($weechat_version >= 0x00030500); # v0.3.5
+        } else {
+            $config{$option} = lc(weechat::config_get_plugin($option));
+        }
+    }
+    nicklist_read();
+}
+
+#################################################################################################### start
+
+weechat::register($prgname, "Nils Görs <weechatter\@arcor.de>", $version, "GPL3", $description, "", "");
+weechat::hook_modifier("500|weechat_print","colorize_cb", "");
+init_config();
+weechat::hook_config("plugins.var.perl.$prgname.*", "toggle_config_by_set", "");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,14 @@
+#
+# weechat -- python.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[look]
+check_license = off
+eval_keep_context = on
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autoload/autosort.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,1 @@
+../autosort.py
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autoload/brows.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,77 @@
+import subprocess
+import os
+
+SCRIPT_NAME = 'brows'
+SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION = '1.0'
+SCRIPT_LICENSE = 'MIT/X11'
+SCRIPT_DESC = 'Launch brows to view URLs'
+SCRIPT_COMMAND = 'brows'
+
+import_ok = True
+
+BROWS = os.environ.get('BROWS', 'brows')
+
+try:
+    import weechat
+except ImportError:
+    print('This is a weechat script, what are you doing, run it in weechat, jesus')
+    import_ok = False
+
+weechat_version = 0
+
+def hd(fn, name, obj, attr):
+    return fn(weechat.hdata_get(name), obj, attr)
+
+def hdp(name, obj, attr):
+    return hd(weechat.hdata_pointer, name, obj, attr)
+
+def hds(name, obj, attr):
+    return hd(weechat.hdata_string, name, obj, attr)
+
+def get_lines(buffer, numlines):
+    lines = hdp("buffer", buffer, "own_lines")
+    if not lines:
+        # null pointer wat do
+        return None
+
+    last_lines = []
+
+    line = hdp("lines", lines, "last_line")
+    for _ in range(numlines):
+        if not line:
+            # shit we're at the top of the buffer
+            break
+
+        data = hdp("line", line, "data")
+        msg = hds("line_data", data, "message")
+        msg = weechat.string_remove_color(msg, "")
+
+        last_lines.append(msg.strip())
+
+        line = hdp("line", line, "prev_line")
+
+    return last_lines
+
+def brows(data, buffer, args, numlines=100):
+    lines = get_lines(buffer, numlines)
+
+    proc = subprocess.Popen([BROWS], stdin=subprocess.PIPE)
+    proc.communicate(input='\n'.join(lines))
+    weechat.command("", "/window refresh")
+
+    return weechat.WEECHAT_RC_OK
+
+
+if __name__ == '__main__' and import_ok:
+    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
+                        SCRIPT_LICENSE, SCRIPT_DESC, '', ''):
+        weechat_version = weechat.info_get('version_number', '') or 0
+        weechat.hook_command(
+            SCRIPT_COMMAND,
+            'Launch brows to view URLs',
+            '',
+            '',
+            '',
+            'brows',
+            '')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autoload/editor.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,65 @@
+import subprocess
+import os
+import tempfile
+
+SCRIPT_NAME = 'editor'
+SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION = '1.0'
+SCRIPT_LICENSE = 'MIT/X11'
+SCRIPT_DESC = 'Launch an external editor to compose a message'
+SCRIPT_COMMAND = 'editor'
+
+import_ok = True
+
+EDITOR = os.environ.get('EDITOR','vim')
+
+try:
+    import weechat
+except ImportError:
+    print('This is a weechat script, what are you doing, run it in weechat, jesus')
+    import_ok = False
+
+weechat_version = 0
+
+
+def get_data(suffix, initial_data):
+    with tempfile.NamedTemporaryFile(suffix=".%s" % suffix, mode="w+") as tf:
+        tf.write(initial_data)
+        tf.flush()
+
+        if subprocess.call([EDITOR, tf.name]) != 0:
+            return None
+
+        # Reopen, because most editors do atomic write-tmp+rename saves which
+        # fucks with Python here.
+        tf.file.close()
+        with open(tf.name) as tf2:
+            return tf2.read()
+
+def editor(data, buffer, args):
+    suffix = args or "tmp"
+
+    line = weechat.buffer_get_string(buffer, "input")
+
+    data = get_data(suffix, line)
+    if data:
+        weechat.command(buffer, "/input delete_line")
+        weechat.command(buffer, data.strip())
+
+    weechat.command("", "/window refresh")
+
+    return weechat.WEECHAT_RC_OK
+
+
+if __name__ == '__main__' and import_ok:
+    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
+                        SCRIPT_LICENSE, SCRIPT_DESC, '', ''):
+        weechat_version = weechat.info_get('version_number', '') or 0
+        weechat.hook_command(
+            SCRIPT_COMMAND,
+            'Open $EDITOR to compose a message',
+            '[file-extension]',
+            'If an argument is given, it will be used as the extension for the temporary file.',
+            '',
+            'editor',
+            '')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autoload/notify.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,29 @@
+import weechat, subprocess
+
+SCRIPT_NAME = 'notify'
+SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION = '0.0.1'
+SCRIPT_LICENSE = 'MIT'
+SCRIPT_DESC = 'notify-send for weechat'
+
+weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', '')
+
+weechat.hook_print('', 'irc_privmsg', '', 1, 'notify', '')
+
+def _notify(text):
+    subprocess.call(['notify-send', text])
+
+def notify(data, buffer, date, tags, displayed, highlight, prefix, message):
+    # ignore if it's yourself
+    own_nick = weechat.buffer_get_string(buffer, 'localvar_nick')
+
+    if prefix == own_nick or prefix == ('@%s' % own_nick):
+        return weechat.WEECHAT_RC_OK
+
+    if int(highlight):
+        channel = weechat.buffer_get_string(buffer, 'localvar_channel')
+        _notify('%s %s\n%s' % (prefix, channel, message))
+    elif 'notify_private' in tags:
+        _notify('%s [PM]\n%s' % (prefix, message))
+
+    return weechat.WEECHAT_RC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autoload/quotes.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,124 @@
+import subprocess, os
+
+SCRIPT_NAME = 'quotes'
+SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION = '1.0'
+SCRIPT_LICENSE = 'MIT/X11'
+SCRIPT_DESC = 'Grab quotes and shove them into a text file.'
+SCRIPT_COMMAND = 'quo'
+SCRIPT_COMMAND_LONG = 'quoo'
+SCRIPT_COMMAND_COPY = 'cop'
+
+HOME = os.getenv("HOME")
+QUOTE_FILE = '%s/Dropbox/quotes.txt' % HOME
+COPY_FILE = '%s/.ircopy.irc' % HOME
+
+import_ok = True
+
+try:
+    import weechat
+except ImportError:
+    print('This is a weechat script, what are you doing, run it in weechat, jesus')
+    import_ok = False
+
+weechat_version = 0
+
+def hd(fn, name, obj, attr):
+    return fn(weechat.hdata_get(name), obj, attr)
+
+def hdp(name, obj, attr):
+    return hd(weechat.hdata_pointer, name, obj, attr)
+
+def hds(name, obj, attr):
+    return hd(weechat.hdata_string, name, obj, attr)
+
+def get_lines(buffer, numlines):
+    lines = hdp("buffer", buffer, "own_lines")
+    if not lines:
+        # null pointer wat do
+        return None
+
+    last_lines = []
+
+    line = hdp("lines", lines, "last_line")
+    for _ in range(numlines):
+        if not line:
+            # shit we're at the top of the buffer
+            break
+
+        data = hdp("line", line, "data")
+        msg = hds("line_data", data, "message")
+        pre = hds("line_data", data, "prefix")
+
+        msg = weechat.string_remove_color(msg, "")
+        pre = weechat.string_remove_color(pre, "")
+
+        last_lines.append("<%s> %s" % (pre.strip(), msg.strip()))
+
+        line = hdp("line", line, "prev_line")
+
+    last_lines.reverse()
+    return last_lines
+
+def quote_grab(data, buffer, args, numlines=15):
+    lines = get_lines(buffer, numlines)
+
+    with open(QUOTE_FILE, 'a') as f:
+        f.write("\n---\n")
+        f.write('\n'.join(lines))
+
+    subprocess.call(["nvim", QUOTE_FILE,
+                     # start at the bottom of the file
+                     "+",
+                     # move up N lines, where N is how many we appended
+                     "-c", "normal! %dk" % len(lines)])
+    weechat.command("", "/window refresh")
+
+    return weechat.WEECHAT_RC_OK
+
+def quote_grab_long(data, buffer, args):
+    return quote_grab(data, buffer, args, 75)
+
+def quote_grab_copy(data, buffer, args):
+    lines = get_lines(buffer, 1000)
+
+    with open(COPY_FILE, 'w') as f:
+        f.write('\n'.join(lines))
+
+    subprocess.call(["nvim", COPY_FILE,
+                     # start at the bottom of the file
+                     "+"])
+    weechat.command("", "/window refresh")
+
+    return weechat.WEECHAT_RC_OK
+
+if __name__ == '__main__' and import_ok:
+    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
+                        SCRIPT_LICENSE, SCRIPT_DESC, '', ''):
+        weechat_version = weechat.info_get('version_number', '') or 0
+        weechat.hook_command(
+            SCRIPT_COMMAND,
+            'Appends the last 15 lines of the current buffer to your quotes '
+            'file and opens it in Vim so you can trim it.',
+            '',
+            '',
+            '',
+            'quote_grab',
+            '')
+        weechat.hook_command(
+            SCRIPT_COMMAND_LONG,
+            'Appends the last 75 lines of the current buffer to your quotes '
+            'file and opens it in Vim so you can trim it.',
+            '',
+            '',
+            '',
+            'quote_grab_long',
+            '')
+        weechat.hook_command(
+            SCRIPT_COMMAND_COPY,
+            'Open the last 1000 lines of the file in Vim so you can copy.',
+            '',
+            '',
+            '',
+            'quote_grab_copy',
+            '')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autoload/urlgrab.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,699 @@
+# -*- coding: utf-8 -*-
+#
+# UrlGrab, for weechat version >= 0.3.0
+#
+#   Listens to all channels for URLs, collects them in a list, and launches
+#   them in your favourite web server on the local host or a remote server.
+#   Copies url to X11 clipboard via xsel
+#      (http://www.vergenet.net/~conrad/software/xsel)
+#
+# Usage:
+#
+#   The /url command provides access to all UrlGrab functions.  Run
+#   '/help url' for complete command usage.
+#
+#   In general, use '/url list' to list the entire url list for the current
+#   channel, and '/url <n>' to launch the nth url in the list.  For
+#   example, to launch the first (and most-recently added) url in the list,
+#   you would run '/url 1'
+#
+#   From the server window, you must specify a specific channel for the
+#   list and launch commands, for example:
+#     /url list weechat
+#     /url 3 weechat
+#
+# Configuration:
+#
+#   The '/url set' command lets you get and set the following options:
+#
+#   historysize
+#     The maximum number of URLs saved per channel.  Default is 10
+#
+#   method
+#     Must be one of 'local' or 'remote' - Defines how URLs are launched by
+#     the script.  If 'local', the script will run 'localcmd' on the host.
+#     If 'remote', the script will run 'remotessh remotehost remotecmd' on
+#     the local host which should normally use ssh to connect to another
+#     host and run the browser command there.
+#
+#   localcmd
+#     The command to run on the local host to launch URLs in 'local' mode.
+#     The string '%s' will be replaced with the URL.  The default is
+#     'firefox %s'.
+#
+#   remotessh
+#     The command (and arguments) used to connect to the remote host for
+#     'remote' mode.  The default is 'ssh -x' which will connect as the
+#     current username via ssh and disable X11 forwarding.
+#
+#   remotehost
+#     The remote host to which we will connect in 'remote' mode.  For ssh,
+#     this can just be a hostname or 'user@host' to specify a username
+#     other than your current login name.  The default is 'localhost'.
+#
+#   remotecmd
+#     The command to execute on the remote host for 'remote' mode.  The
+#     default is 'bash -c "DISPLAY=:0.0 firefox '%s'"'  Which runs bash, sets
+#     up the environment to display on the remote host's main X display,
+#     and runs firefox.  As with 'localcmd', the string '%s' will be
+#     replaced with the URL.
+#
+#   cmdoutput
+#     The file where the command output (if any) is saved.  Overwritten
+#     each time you launch a new URL.  Default is ~/.weechat/urllaunch.log
+#
+#   default
+#     The command that will be run if no arguemnts to /url are given.
+#     Default is show
+#
+# Requirements:
+#
+#  - Designed to run with weechat version 0.3 or better.
+#      http://www.weechat.org/
+#
+# Acknowlegements:
+#
+#  - Based on an earlier version called 'urlcollector.py' by 'kolter' of
+#    irc.freenode.net/#weechat Honestly, I just cleaned up the code a bit and
+#    made the settings a little more useful (to me).
+#
+#  - With changes by Leonid Evdokimov (weechat at darkk dot net another dot ru):
+#    http://darkk.net.ru/weechat/urlgrab.py
+#    v1.1:  added better handling of dead zombie-childs
+#           added parsing of private messages
+#           added default command setting
+#           added parsing of scrollback buffers on load
+#    v1.2:  `historysize` was ignored
+#
+#  - With changes by ExclusivE (exclusive_tm at mail dot ru):
+#    v1.3: X11 clipboard support
+#
+#  - V1.4 Just ported it over to weechat 0.2.7  drubin AT smartcube dot co dot za
+#  - V1.5  1) I created a logging feature for urls, Time, Date, buffer, and url.
+#           2) Added selectable urls support, similar to the iset plugin (Thanks FlashCode)
+#           3) Colors/formats are configuarable.
+#           4) browser now uses hook_process (Please test with remote clients)
+#           5) Added /url open http://url.com functionality
+#           6) Changed urls detection to use regexpressions so should be much better
+#                Thanks to xt of #weechat bassed on on urlbar.py
+#  - V1.6 FlashCode <flashcode@flashtux.org>: Increase timeout for hook_process
+#         (from 1 second to 1 minute)
+#  - V1.7 FlashCode <flashcode@flashtux.org>: Update WeeChat site
+#  - V1.8 drubin <drubin [at] smartcube . co.za>:
+#           - Changed remote cmd to be single option
+#           - Added scrolling on up and down arrow keys for /url show
+#           - Changed remotecmd to include options with public/private keys password auth doesn't work
+#  - V1.9 Specimen <spinifer [at] gmail . com>:
+#           - Changed the default command when /url is run with no arguments to 'show'
+#           - Removed '/url help' command, because /help <command> is the standard way
+#  - V2.0 Xilov: replace "/url help" by "/help url"
+#  - V2.1 nand: Changed default: firefox %s to firefox '%s' (localcmd)
+#  - V2.2 Sébastien Helleu <flashcode@flashtux.org>: fix reload of config file
+#  - V2.3 nand: Allowed trailing )s for unmatched (s in URLs
+#  - V2.4 nand: Escaped URLs via URL-encoding instead of shell escaping, fixes '
+#  - V2.5 nand: Fixed some URLs that got incorrectly mangled by escaping
+#  - V2.6 nesthib: Fixed escaping of "="
+#                  Added missing quotes in default parameter (firefox '%s')
+#                  Removed the mix of tabs and spaces in the file indentation
+#  - V2.7 dobbymoodge <john.w.lamb [at] gmail . com>
+#                     ( https://github.com/dobbymoodge/ ):
+#           - Added 'copycmd' setting, users can set command to pipe into
+#             for '/url copy'
+#  - V2.8 Simmo Saan <simmo.saan@gmail.com>:
+#           - Changed print hook to ignore filtered lines
+#  - V2.9 Dominik Heidler <dominik@heidler.eu>:
+#           - Updated script for python3 support (now python2 and 3 are both supported)
+#  - V3.0 Sébastien Helleu <flashcode@flashtux.org>:
+#           - Fix python 3 compatibility (replace "has_key" by "in")
+#
+# Copyright (C) 2005 David Rubin <drubin AT smartcube dot co dot za>
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+# USA.
+#
+
+from __future__ import print_function
+import sys
+import os
+try:
+    import weechat
+    import_ok = True
+except:
+    print("This script must be run under WeeChat.")
+    print("Get WeeChat now at: http://www.weechat.org/")
+    import_ok = False
+import subprocess
+import time
+try:
+    from urllib import quote
+except ImportError:
+    from urllib.parse import quote
+import re
+try:
+    from UserDict import UserDict
+except ImportError:
+    from collections import UserDict
+
+
+octet = r'(?:2(?:[0-4]\d|5[0-5])|1\d\d|\d{1,2})'
+ipAddr = r'%s(?:\.%s){3}' % (octet, octet)
+# Base domain regex off RFC 1034 and 1738
+label = r'[0-9a-z][-0-9a-z]*[0-9a-z]?'
+domain = r'%s(?:\.%s)*\.[a-z][-0-9a-z]*[a-z]?' % (label, label)
+urlRe = re.compile(r'(\w+://(?:%s|%s)(?::\d+)?(?:/[^\]>\s]*)?)' % (domain, ipAddr), re.I)
+
+
+SCRIPT_NAME    = "urlgrab"
+SCRIPT_AUTHOR  = "David Rubin <drubin [At] smartcube [dot] co [dot] za>"
+SCRIPT_VERSION = "3.0"
+SCRIPT_LICENSE = "GPL"
+SCRIPT_DESC    = "Url functionality Loggin, opening of browser, selectable links"
+CONFIG_FILE_NAME= "urlgrab"
+SCRIPT_COMMAND = "url"
+
+
+def stripParens(url):
+    return dropChar(')', url.count(')') - url.count('('), url[::-1])[::-1]
+
+def dropChar(c, n, xs):
+    if n == 0 or xs == []:
+        return xs
+    elif xs[0] == c:
+        return dropChar(c, n-1, xs[1:])
+    else:
+        return xs
+
+def urlGrabPrint(message):
+    bufferd=weechat.current_buffer()
+    if urlGrabSettings['output_main_buffer'] == 1 :
+        weechat.prnt("","[%s] %s" % ( SCRIPT_NAME, message ) )
+    else :
+        weechat.prnt(bufferd,"[%s] %s" % ( SCRIPT_NAME, message ) )
+
+def hashBufferName(bufferp):
+    if not weechat.buffer_get_string(bufferp, "short_name"):
+        bufferd = weechat.buffer_get_string(bufferp, "name")
+    else:
+        bufferd = weechat.buffer_get_string(bufferp, "short_name")
+    return bufferd
+
+def ug_config_reload_cb(data, config_file):
+    """ Reload configuration file. """
+    return weechat.config_reload(config_file)
+
+class UrlGrabSettings(UserDict):
+    def __init__(self):
+        UserDict.__init__(self)
+        self.data = {}
+        self.config_file = weechat.config_new(CONFIG_FILE_NAME,
+                                        "ug_config_reload_cb", "")
+        if not self.config_file:
+            return
+
+        section_color = weechat.config_new_section(
+            self.config_file, "color", 0, 0, "", "", "", "", "", "",
+                     "", "", "", "")
+        section_default = weechat.config_new_section(
+            self.config_file, "default", 0, 0, "", "", "", "", "", "",
+                     "", "", "", "")
+
+        self.data['color_buffer']=weechat.config_new_option(
+            self.config_file, section_color,
+            "color_buffer", "color", "Color to display buffer name", "", 0, 0,
+            "red", "red", 0, "", "", "", "", "", "")
+
+        self.data['color_url']=weechat.config_new_option(
+            self.config_file, section_color,
+            "color_url", "color", "Color to display urls", "", 0, 0,
+            "blue", "blue", 0, "", "", "", "", "", "")
+
+        self.data['color_time']=weechat.config_new_option(
+            self.config_file, section_color,
+            "color_time", "color", "Color to display time", "", 0, 0,
+            "cyan", "cyan", 0, "", "", "", "", "", "")
+
+        self.data['color_buffer_selected']=weechat.config_new_option(
+            self.config_file, section_color,
+            "color_buffer_selected", "color",
+            "Color to display buffer selected name", "", 0, 0, "red", "red",
+            0, "", "", "", "", "", "")
+
+        self.data['color_url_selected']=weechat.config_new_option(
+            self.config_file, section_color,
+            "color_url_selected", "color", "Color to display url selected",
+             "", 0, 0, "blue", "blue", 0, "", "", "", "", "", "")
+
+        self.data['color_time_selected']=weechat.config_new_option(
+            self.config_file, section_color,
+            "color_time_selected", "color", "Color to display tim selected",
+            "", 0, 0, "cyan", "cyan", 0, "", "", "", "", "", "")
+
+        self.data['color_bg_selected']=weechat.config_new_option(
+            self.config_file, section_color,
+            "color_bg_selected", "color", "Background for selected row", "", 0, 0,
+            "green", "green", 0, "", "", "", "", "", "")
+
+        self.data['historysize']=weechat.config_new_option(
+            self.config_file, section_default,
+            "historysize", "integer", "Max number of urls to store per buffer",
+            "", 0, 999, "10", "10", 0, "", "", "", "", "", "")
+
+        self.data['method']=weechat.config_new_option(
+            self.config_file, section_default,
+            "method", "string", """Where to launch URLs
+            If 'local', runs %localcmd%.
+            If 'remote' runs the following command:
+            '%remodecmd%'""", "", 0, 0,
+            "local", "local", 0, "", "", "", "", "", "")
+
+        self.data['copycmd']=weechat.config_new_option(
+            self.config_file, section_default,
+            "copycmd", "string",
+            "Command to pipe into for 'url copy'. "
+            "E.g. to copy into the CLIPBOARD buffer "
+            "instead of PRIMARY, you can use 'xsel -b "
+            "-i' here.", "", 0, 0,
+            "xsel -i", "xsel -i", 0, "", "", "", "", "", "")
+
+        self.data['localcmd']=weechat.config_new_option(
+            self.config_file, section_default,
+            "localcmd", "string", """Local command to execute""", "", 0, 0,
+            "firefox '%s'", "firefox '%s'", 0, "", "", "", "", "", "")
+
+        remotecmd="ssh -x localhost -i ~/.ssh/id_rsa -C \"export DISPLAY=\":0.0\" &&  firefox '%s'\""
+        self.data['remotecmd']=weechat.config_new_option(
+            self.config_file, section_default,
+            "remotecmd", "string", remotecmd, "", 0, 0,
+            remotecmd, remotecmd, 0, "", "", "", "", "", "")
+
+        self.data['url_log']=weechat.config_new_option(
+            self.config_file, section_default,
+            "url_log", "string", """log location""", "", 0, 0,
+            "~/.weechat/urls.log", "~/.weechat/urls.log", 0, "", "", "", "", "", "")
+
+        self.data['time_format']=weechat.config_new_option(
+            self.config_file, section_default,
+            "time_format", "string", """TIme format""", "", 0, 0,
+            "%H:%M:%S", "%H:%M:%S", 0, "", "", "", "", "", "")
+
+        self.data['output_main_buffer']=weechat.config_new_option(
+            self.config_file, section_default,
+            "output_main_buffer", "boolean",
+            """Print text to main buffer or current one""", "", 0, 0, "1", "1",
+             0, "", "", "", "", "", "")
+        weechat.config_read(self.config_file)
+
+    def __getitem__(self, key):
+        if key == "historysize":
+            return weechat.config_integer(self.data[key])
+        elif key == 'output_main_buffer':
+            return weechat.config_boolean(self.data[key])
+        #elif key.startswith('color'):
+        #    return weechat.config_color(self.data[key])
+        else:
+            return weechat.config_string(self.data[key])
+
+    def prnt(self, name, verbose = True):
+        weechat.prnt( ""," %s = %s" % (name.ljust(11), self.data[name]) )
+
+    def prntall(self):
+        for key in self.names():
+            self.prnt(key, verbose = False)
+
+    def createCmd(self, url):
+        str =""
+        if self['method'] == 'remote':
+            str = self['remotecmd']  % url
+        else:
+            str =  self['localcmd']  % url
+        return str
+
+class UrlGrabber:
+    def __init__(self, historysize):
+        # init
+        self.urls = {}
+        self.globalUrls = []
+        self.historysize = 5
+        # control
+        self.setHistorysize(historysize)
+
+    def setHistorysize(self, count):
+        if count > 1:
+            self.historysize = count
+
+    def getHistorysize(self):
+        return self.historysize
+
+    def addUrl(self, bufferp,url ):
+        global urlGrabSettings
+        self.globalUrls.insert(0,{"buffer":bufferp,
+            "url":url, "time":time.strftime(urlGrabSettings["time_format"])})
+        #Log urls only if we have set a log path.
+        if urlGrabSettings['url_log']:
+            try :
+                index = self.globalUrls[0]
+                logfile = os.path.expanduser(urlGrabSettings['url_log'])
+                dout = open(logfile, "a")
+                dout.write("%s %s %s\n" % (index['time'],
+                                           index['buffer'], index['url']))
+                dout.close()
+            except :
+                print("failed to log url check that %s is valid path" % urlGrabSettings['url_log'])
+                pass
+
+        # check for buffer
+        if not bufferp in self.urls:
+            self.urls[bufferp] = []
+        # add url
+        if url in self.urls[bufferp]:
+            self.urls[bufferp].remove(url)
+        self.urls[bufferp].insert(0, url)
+        # removing old urls
+        while len(self.urls[bufferp]) > self.historysize:
+            self.urls[bufferp].pop()
+
+    def hasIndex( self, bufferp, index ):
+        return bufferp in self.urls and \
+                len(self.url[bufferp]) >= index
+
+    def hasBuffer( self, bufferp ):
+        return bufferp in self.urls
+
+
+    def getUrl(self, bufferp, index):
+        url = ""
+        if  bufferp in self.urls:
+            if len(self.urls[bufferp]) >= index:
+                    url = self.urls[bufferp][index-1]
+        return url
+
+
+    def prnt(self, buff):
+        found = True
+        if buff in self.urls:
+            if len(self.urls[buff]) > 0:
+                i = 1
+                for url in self.urls[buff]:
+                    urlGrabPrint("--> " + str(i) + " : " + url)
+                    i += 1
+            else:
+                found = False
+        elif buff == "*":
+            for b in self.urls.keys():
+              self.prnt(b)
+        else:
+            found = False
+
+        if not found:
+            urlGrabPrint(buff + ": no entries")
+
+def urlGrabCheckMsgline(bufferp, message, isdisplayed):
+    global urlGrab, max_buffer_length
+    if not message or isdisplayed == 0:
+        return
+    # Ignore output from 'tinyurl.py' and our selfs
+    if ( message.startswith( "[AKA] http://tinyurl.com" ) or
+        message.startswith("[urlgrab]") ):
+        return
+    # Check for URLs
+    for url in urlRe.findall(message):
+        urlGrab.addUrl(bufferp,stripParens(url))
+        if max_buffer_length < len(bufferp):
+            max_buffer_length = len(bufferp)
+        if urlgrab_buffer:
+            refresh()
+
+
+def urlGrabCheck(data, bufferp, uber_empty, tagsn, isdisplayed, ishilight, prefix, message):
+    urlGrabCheckMsgline(hashBufferName(bufferp), message, isdisplayed)
+    return weechat.WEECHAT_RC_OK
+
+def urlGrabCopy(bufferd, index):
+    global urlGrab
+    if bufferd == "":
+        urlGrabPrint( "No current channel, you must activate one" )
+    elif not urlGrab.hasBuffer(bufferd):
+        urlGrabPrint("No URL found - Invalid channel")
+    else:
+        if index <= 0:
+            urlGrabPrint("No URL found - Invalid index")
+            return
+        url = urlGrab.getUrl(bufferd,index)
+    if url == "":
+        urlGrabPrint("No URL found - Invalid index")
+    else:
+        try:
+            pipe = os.popen(urlGrabSettings['copycmd'],"w")
+            pipe.write(url)
+            pipe.close()
+            urlGrabPrint("Url: %s gone to clipboard." % url)
+        except:
+            urlGrabPrint("Url: %s failed to copy to clipboard." % url)
+
+def urlGrabOpenUrl(url):
+    global urlGrab, urlGrabSettings
+    argl = urlGrabSettings.createCmd( quote(url, '/:#%?&+=') )
+    weechat.hook_process(argl,60000, "ug_open_cb", "")
+
+def ug_open_cb(data, command, code, out, err):
+    # weechat.prnt("", out)
+    # weechat.prnt("", err)
+    return weechat.WEECHAT_RC_OK
+
+
+def urlGrabOpen(bufferd, index):
+    global urlGrab, urlGrabSettings
+    if bufferd == "":
+        urlGrabPrint( "No current channel, you must specify one" )
+    elif not urlGrab.hasBuffer(bufferd) :
+        urlGrabPrint("No URL found - Invalid channel")
+    else:
+        if index <= 0:
+            urlGrabPrint("No URL found - Invalid index")
+            return
+        url =  urlGrab.getUrl(bufferd,index)
+        if url == "":
+            urlGrabPrint("No URL found - Invalid index")
+        else:
+            urlGrabPrint("loading %s %sly" % (url, urlGrabSettings["method"]))
+            urlGrabOpenUrl (url)
+
+def urlGrabList( args ):
+    global urlGrab
+    if len(args) == 0:
+        buf = hashBufferName(weechat.current_buffer())
+    else:
+        buf = args[0]
+    if buf == "" or buf == "all":
+        buf = "*"
+    urlGrab.prnt(buf)
+
+
+def urlGrabMain(data, bufferp, args):
+    if args[0:2] == "**":
+        keyEvent(data, bufferp, args[2:])
+        return weechat.WEECHAT_RC_OK
+
+    bufferd = hashBufferName(bufferp)
+    largs = args.split(" ")
+    #strip spaces
+    while '' in largs:
+        largs.remove('')
+    while ' ' in largs:
+        largs.remove(' ')
+    if len(largs) == 0 or largs[0] == "show":
+        if not urlgrab_buffer:
+            init()
+        refresh()
+        weechat.buffer_set(urlgrab_buffer, "display", "1")
+    elif largs[0] == 'open' and len(largs) == 2:
+        urlGrabOpenUrl(largs[1])
+    elif largs[0] == 'list':
+        urlGrabList( largs[1:] )
+    elif largs[0] == 'copy':
+        if len(largs) > 1:
+            no = int(largs[1])
+            urlGrabCopy(bufferd, no)
+        else:
+            urlGrabCopy(bufferd,1)
+    else:
+        try:
+            no = int(largs[0])
+            if len(largs) > 1:
+                urlGrabOpen(largs[1], no)
+            else:
+                urlGrabOpen(bufferd, no)
+        except ValueError:
+            #not a valid number so try opening it as a url..
+            for url in urlRe.findall(largs[0]):
+                urlGrabOpenUrl(stripParens(url))
+            urlGrabPrint( "Unknown command '%s'.  Try '/help url' for usage" % largs[0])
+    return weechat.WEECHAT_RC_OK
+
+def buffer_input(*kwargs):
+    return weechat.WEECHAT_RC_OK
+
+def buffer_close(*kwargs):
+    global urlgrab_buffer
+    urlgrab_buffer =  None
+    return weechat.WEECHAT_RC_OK
+
+def keyEvent (data, bufferp, args):
+    global urlGrab , urlGrabSettings, urlgrab_buffer, current_line
+    if args == "refresh":
+        refresh()
+    elif args == "up":
+        if current_line > 0:
+            current_line = current_line -1
+            refresh_line (current_line + 1)
+            refresh_line (current_line)
+            ugCheckLineOutsideWindow()
+    elif args == "down":
+         if current_line < len(urlGrab.globalUrls) - 1:
+            current_line = current_line +1
+            refresh_line (current_line - 1)
+            refresh_line (current_line)
+            ugCheckLineOutsideWindow()
+    elif args == "scroll_top":
+        temp_current = current_line
+        current_line =  0
+        refresh_line (temp_current)
+        refresh_line (current_line)
+        weechat.command(urlgrab_buffer, "/window scroll_top")
+        pass
+    elif args == "scroll_bottom":
+        temp_current = current_line
+        current_line =  len(urlGrab.globalUrls)
+        refresh_line (temp_current)
+        refresh_line (current_line)
+        weechat.command(urlgrab_buffer, "/window scroll_bottom")
+    elif args == "enter":
+        if urlGrab.globalUrls[current_line]:
+            urlGrabOpenUrl (urlGrab.globalUrls[current_line]['url'])
+
+def refresh_line (y):
+    global urlGrab , urlGrabSettings, urlgrab_buffer, current_line, max_buffer_length
+    #Print format  Time(space)buffer(max4 spaces, but lined up)url
+    format = "%%s%%s %%s%%-%ds%%s%%s" % (max_buffer_length+4)
+
+    #non selected colors
+    color_buffer = urlGrabSettings["color_buffer"]
+    color_url = urlGrabSettings["color_url"]
+    color_time =urlGrabSettings["color_time"]
+    #selected colors
+    color_buffer_selected = urlGrabSettings["color_buffer_selected"]
+    color_url_selected = urlGrabSettings["color_url_selected"]
+    color_time_selected = urlGrabSettings["color_time_selected"]
+
+    color_bg_selected = urlGrabSettings["color_bg_selected"]
+
+    color1 = color_time
+    color2 = color_buffer
+    color3 = color_url
+
+    #If this line is selected we change the colors.
+    if y == current_line:
+          color1 = "%s,%s" % (color_time_selected, color_bg_selected)
+          color2 = "%s,%s" % (color_buffer_selected, color_bg_selected)
+          color3 = "%s,%s" % (color_url_selected, color_bg_selected)
+
+    color1 = weechat.color(color1)
+    color2 = weechat.color(color2)
+    color3 = weechat.color(color3)
+    text = format % (color1,
+                    urlGrab.globalUrls[y]['time'],
+                    color2,
+                    urlGrab.globalUrls[y]['buffer'],
+                    color3,
+                    urlGrab.globalUrls[y]['url'] )
+    weechat.prnt_y(urlgrab_buffer,y,text)
+
+def ugCheckLineOutsideWindow():
+    global urlGrab , urlGrabSettings, urlgrab_buffer, current_line, max_buffer_length
+    if (urlgrab_buffer):
+        infolist = weechat.infolist_get("window", "", "current")
+        if (weechat.infolist_next(infolist)):
+            start_line_y = weechat.infolist_integer(infolist, "start_line_y")
+            chat_height = weechat.infolist_integer(infolist, "chat_height")
+            if(start_line_y > current_line):
+                weechat.command(urlgrab_buffer, "/window scroll -%i" %(start_line_y - current_line))
+            elif(start_line_y <= current_line - chat_height):
+                weechat.command(urlgrab_buffer, "/window scroll +%i"%(current_line - start_line_y - chat_height + 1))
+        weechat.infolist_free(infolist)
+
+
+def refresh():
+    global urlGrab
+    y=0
+    for x in urlGrab.globalUrls:
+        refresh_line (y)
+        y += 1
+
+
+def init():
+    global urlGrab , urlGrabSettings, urlgrab_buffer
+    if not urlgrab_buffer:
+        urlgrab_buffer = weechat.buffer_new("urlgrab", "buffer_input", "", "buffer_close", "")
+    if urlgrab_buffer:
+        weechat.buffer_set(urlgrab_buffer, "type", "free")
+        weechat.buffer_set(urlgrab_buffer, "key_bind_ctrl-R",        "/url **refresh")
+        weechat.buffer_set(urlgrab_buffer, "key_bind_meta2-A",       "/url **up")
+        weechat.buffer_set(urlgrab_buffer, "key_bind_meta2-B",       "/url **down")
+        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-ctrl-J",   "/url **enter")
+        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-ctrl-M",   "/url **enter")
+        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-meta2-1./~", "/url **scroll_top")
+        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-meta2-4~", "/url **scroll_bottom")
+        weechat.buffer_set(urlgrab_buffer, "title","Lists the urls in the applications")
+        weechat.buffer_set(urlgrab_buffer, "display", "1")
+
+def completion_urls_cb(data, completion_item, bufferp, completion):
+    """ Complete with URLS, for command '/url'. """
+    global urlGrab
+    bufferd = hashBufferName( bufferp)
+    for url in urlGrab.globalUrls :
+        if url['buffer'] == bufferd:
+            weechat.hook_completion_list_add(completion, url['url'], 0, weechat.WEECHAT_LIST_POS_SORT)
+    return weechat.WEECHAT_RC_OK
+
+def ug_unload_script():
+    """ Function called when script is unloaded. """
+    global urlGrabSettings
+    weechat.config_write(urlGrabSettings.config_file)
+    return weechat.WEECHAT_RC_OK
+
+#Main stuff
+if ( import_ok and
+    weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
+        SCRIPT_LICENSE,SCRIPT_DESC, "ug_unload_script", "") ):
+    urlgrab_buffer = None
+    current_line = 0
+    max_buffer_length = 0
+    urlGrabSettings = UrlGrabSettings()
+    urlGrab = UrlGrabber( urlGrabSettings['historysize'])
+    weechat.hook_print("", "", "", 1, "urlGrabCheck", "")
+    weechat.hook_command(SCRIPT_COMMAND,
+                             "Url Grabber",
+                             "[open <url> | <url> | show | copy [n] | [n] | list]",
+                             "open or <url>: opens the url\n"
+                             "show: Opens the select buffer to allow for url selection\n"
+                             "copy: Copies the nth url to the system clipboard\n"
+                             "list: Lists the urls in the current buffer\n",
+                             "open %(urlgrab_urls) || %(urlgrab_urls) || "
+                             "copy || show || list",
+                             "urlGrabMain", "")
+    weechat.hook_completion("urlgrab_urls", "list of URLs",
+                                "completion_urls_cb", "")
+else:
+    print("failed to load weechat")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autoload/wee_slack.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,1 @@
+/home/sjl/src/wee-slack/wee_slack.py
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/autosort.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,1075 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2013-2017 Maarten de Vries <maarten@de-vri.es>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+#
+# Autosort automatically keeps your buffers sorted and grouped by server.
+# You can define your own sorting rules. See /help autosort for more details.
+#
+# https://github.com/de-vri-es/weechat-autosort
+#
+
+#
+# Changelog:
+# 3.9:
+#   * Remove `buffers.pl` from recommended settings.
+# 3,8:
+#   * Fix relative sorting on script name in default rules.
+#   * Document a useful property of stable sort algorithms.
+# 3.7:
+#   * Make default rules work with bitlbee, matrix and slack.
+# 3.6:
+#   * Add more documentation on provided info hooks.
+# 3.5:
+#   * Add ${info:autosort_escape,...} to escape arguments for other info hooks.
+# 3.4:
+#   * Fix rate-limit of sorting to prevent high CPU load and lock-ups.
+#   * Fix bug in parsing empty arguments for info hooks.
+#   * Add debug_log option to aid with debugging.
+#   * Correct a few typos.
+# 3.3:
+#   * Fix the /autosort debug command for unicode.
+#   * Update the default rules to work better with Slack.
+# 3.2:
+#   * Fix python3 compatiblity.
+# 3.1:
+#   * Use colors to format the help text.
+# 3.0:
+#   * Switch to evaluated expressions for sorting.
+#   * Add `/autosort debug` command.
+#   * Add ${info:autosort_replace,from,to,text} to replace substrings in sort rules.
+#   * Add ${info:autosort_order,value,first,second,third} to ease writing sort rules.
+#   * Make tab completion context aware.
+# 2.8:
+#   * Fix compatibility with python 3 regarding unicode handling.
+# 2.7:
+#   * Fix sorting of buffers with spaces in their name.
+# 2.6:
+#   * Ignore case in rules when doing case insensitive sorting.
+# 2.5:
+#   * Fix handling unicode buffer names.
+#   * Add hint to set irc.look.server_buffer to independent and buffers.look.indenting to on.
+# 2.4:
+#   * Make script python3 compatible.
+# 2.3:
+#   * Fix sorting items without score last (regressed in 2.2).
+# 2.2:
+#   * Add configuration option for signals that trigger a sort.
+#   * Add command to manually trigger a sort (/autosort sort).
+#   * Add replacement patterns to apply before sorting.
+# 2.1:
+#   * Fix some minor style issues.
+# 2.0:
+#   * Allow for custom sort rules.
+#
+
+
+import json
+import math
+import re
+import sys
+import time
+import weechat
+
+SCRIPT_NAME     = 'autosort'
+SCRIPT_AUTHOR   = 'Maarten de Vries <maarten@de-vri.es>'
+SCRIPT_VERSION  = '3.9'
+SCRIPT_LICENSE  = 'GPL3'
+SCRIPT_DESC     = 'Flexible automatic (or manual) buffer sorting based on eval expressions.'
+
+
+config             = None
+hooks              = []
+signal_delay_timer = None
+sort_limit_timer   = None
+sort_queued        = False
+
+
+# Make sure that unicode, bytes and str are always available in python2 and 3.
+# For python 2, str == bytes
+# For python 3, str == unicode
+if sys.version_info[0] >= 3:
+	unicode = str
+
+def ensure_str(input):
+	'''
+	Make sure the given type if the correct string type for the current python version.
+	That means bytes for python2 and unicode for python3.
+	'''
+	if not isinstance(input, str):
+		if isinstance(input, bytes):
+			return input.encode('utf-8')
+		if isinstance(input, unicode):
+			return input.decode('utf-8')
+	return input
+
+
+if hasattr(time, 'perf_counter'):
+	perf_counter = time.perf_counter
+else:
+	perf_counter = time.clock
+
+def casefold(string):
+	if hasattr(string, 'casefold'): return string.casefold()
+	# Fall back to lowercasing for python2.
+	return string.lower()
+
+def list_swap(values, a, b):
+	values[a], values[b] = values[b], values[a]
+
+def list_move(values, old_index, new_index):
+	values.insert(new_index, values.pop(old_index))
+
+def list_find(collection, value):
+	for i, elem in enumerate(collection):
+		if elem == value: return i
+	return None
+
+class HumanReadableError(Exception):
+	pass
+
+def parse_int(arg, arg_name = 'argument'):
+	''' Parse an integer and provide a more human readable error. '''
+	arg = arg.strip()
+	try:
+		return int(arg)
+	except ValueError:
+		raise HumanReadableError('Invalid {0}: expected integer, got "{1}".'.format(arg_name, arg))
+
+def decode_rules(blob):
+	parsed = json.loads(blob)
+	if not isinstance(parsed, list):
+		log('Malformed rules, expected a JSON encoded list of strings, but got a {0}. No rules have been loaded. Please fix the setting manually.'.format(type(parsed)))
+		return []
+
+	for i, entry in enumerate(parsed):
+		if not isinstance(entry, (str, unicode)):
+			log('Rule #{0} is not a string but a {1}. No rules have been loaded. Please fix the setting manually.'.format(i, type(entry)))
+			return []
+
+	return parsed
+
+def decode_helpers(blob):
+	parsed = json.loads(blob)
+	if not isinstance(parsed, dict):
+		log('Malformed helpers, expected a JSON encoded dictionary but got a {0}. No helpers have been loaded. Please fix the setting manually.'.format(type(parsed)))
+		return {}
+
+	for key, value in parsed.items():
+		if not isinstance(value, (str, unicode)):
+			log('Helper "{0}" is not a string but a {1}. No helpers have been loaded. Please fix setting manually.'.format(key, type(value)))
+			return {}
+	return parsed
+
+class Config:
+	''' The autosort configuration. '''
+
+	default_rules = json.dumps([
+		'${core_first}',
+		'${info:autosort_order,${info:autosort_escape,${script_or_plugin}},core,*,irc,bitlbee,matrix,slack}',
+		'${script_or_plugin}',
+		'${irc_raw_first}',
+		'${server}',
+		'${info:autosort_order,${type},server,*,channel,private}',
+		'${hashless_name}',
+		'${buffer.full_name}',
+	])
+
+	default_helpers = json.dumps({
+		'core_first':       '${if:${buffer.full_name}!=core.weechat}',
+		'irc_raw_first':    '${if:${buffer.full_name}!=irc.irc_raw}',
+		'irc_raw_last':     '${if:${buffer.full_name}==irc.irc_raw}',
+		'hashless_name':    '${info:autosort_replace,#,,${info:autosort_escape,${buffer.name}}}',
+		'script_or_plugin': '${if:${script_name}?${script_name}:${plugin}}',
+	})
+
+	default_signal_delay = 5
+	default_sort_limit   = 100
+
+	default_signals = 'buffer_opened buffer_merged buffer_unmerged buffer_renamed'
+
+	def __init__(self, filename):
+		''' Initialize the configuration. '''
+
+		self.filename         = filename
+		self.config_file      = weechat.config_new(self.filename, '', '')
+		self.sorting_section  = None
+		self.v3_section       = None
+
+		self.case_sensitive   = False
+		self.rules            = []
+		self.helpers          = {}
+		self.signals          = []
+		self.signal_delay     = Config.default_signal_delay,
+		self.sort_limit       = Config.default_sort_limit,
+		self.sort_on_config   = True
+		self.debug_log        = False
+
+		self.__case_sensitive = None
+		self.__rules          = None
+		self.__helpers        = None
+		self.__signals        = None
+		self.__signal_delay   = None
+		self.__sort_limit     = None
+		self.__sort_on_config = None
+		self.__debug_log      = None
+
+		if not self.config_file:
+			log('Failed to initialize configuration file "{0}".'.format(self.filename))
+			return
+
+		self.sorting_section = weechat.config_new_section(self.config_file, 'sorting', False, False, '', '', '', '', '', '', '', '', '', '')
+		self.v3_section      = weechat.config_new_section(self.config_file, 'v3',      False, False, '', '', '', '', '', '', '', '', '', '')
+
+		if not self.sorting_section:
+			log('Failed to initialize section "sorting" of configuration file.')
+			weechat.config_free(self.config_file)
+			return
+
+		self.__case_sensitive = weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'case_sensitive', 'boolean',
+			'If this option is on, sorting is case sensitive.',
+			'', 0, 0, 'off', 'off', 0,
+			'', '', '', '', '', ''
+		)
+
+		weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'rules', 'string',
+			'Sort rules used by autosort v2.x and below. Not used by autosort anymore.',
+			'', 0, 0, '', '', 0,
+			'', '', '', '', '', ''
+		)
+
+		weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'replacements', 'string',
+			'Replacement patterns used by autosort v2.x and below. Not used by autosort anymore.',
+			'', 0, 0, '', '', 0,
+			'', '', '', '', '', ''
+		)
+
+		self.__rules = weechat.config_new_option(
+			self.config_file, self.v3_section,
+			'rules', 'string',
+			'An ordered list of sorting rules encoded as JSON. See /help autosort for commands to manipulate these rules.',
+			'', 0, 0, Config.default_rules, Config.default_rules, 0,
+			'', '', '', '', '', ''
+		)
+
+		self.__helpers = weechat.config_new_option(
+			self.config_file, self.v3_section,
+			'helpers', 'string',
+			'A dictionary helper variables to use in the sorting rules, encoded as JSON. See /help autosort for commands to manipulate these helpers.',
+			'', 0, 0, Config.default_helpers, Config.default_helpers, 0,
+			'', '', '', '', '', ''
+		)
+
+		self.__signals = weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'signals', 'string',
+			'A space separated list of signals that will cause autosort to resort your buffer list.',
+			'', 0, 0, Config.default_signals, Config.default_signals, 0,
+			'', '', '', '', '', ''
+		)
+
+		self.__signal_delay = weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'signal_delay', 'integer',
+			'Delay in milliseconds to wait after a signal before sorting the buffer list. This prevents triggering many times if multiple signals arrive in a short time. It can also be needed to wait for buffer localvars to be available.',
+			'', 0, 1000, str(Config.default_signal_delay), str(Config.default_signal_delay), 0,
+			'', '', '', '', '', ''
+		)
+
+		self.__sort_limit = weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'sort_limit', 'integer',
+			'Minimum delay in milliseconds to wait after sorting before signals can trigger a sort again. This is effectively a rate limit on sorting. Keeping signal_delay low while setting this higher can reduce excessive sorting without a long initial delay.',
+			'', 0, 1000, str(Config.default_sort_limit), str(Config.default_sort_limit), 0,
+			'', '', '', '', '', ''
+		)
+
+		self.__sort_on_config = weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'sort_on_config_change', 'boolean',
+			'Decides if the buffer list should be sorted when autosort configuration changes.',
+			'', 0, 0, 'on', 'on', 0,
+			'', '', '', '', '', ''
+		)
+
+		self.__debug_log = weechat.config_new_option(
+			self.config_file, self.sorting_section,
+			'debug_log', 'boolean',
+			'If enabled, print more debug messages. Not recommended for normal usage.',
+			'', 0, 0, 'off', 'off', 0,
+			'', '', '', '', '', ''
+		)
+
+		if weechat.config_read(self.config_file) != weechat.WEECHAT_RC_OK:
+			log('Failed to load configuration file.')
+
+		if weechat.config_write(self.config_file) != weechat.WEECHAT_RC_OK:
+			log('Failed to write configuration file.')
+
+		self.reload()
+
+	def reload(self):
+		''' Load configuration variables. '''
+
+		self.case_sensitive = weechat.config_boolean(self.__case_sensitive)
+
+		rules_blob    = weechat.config_string(self.__rules)
+		helpers_blob  = weechat.config_string(self.__helpers)
+		signals_blob  = weechat.config_string(self.__signals)
+
+		self.rules          = decode_rules(rules_blob)
+		self.helpers        = decode_helpers(helpers_blob)
+		self.signals        = signals_blob.split()
+		self.signal_delay   = weechat.config_integer(self.__signal_delay)
+		self.sort_limit     = weechat.config_integer(self.__sort_limit)
+		self.sort_on_config = weechat.config_boolean(self.__sort_on_config)
+		self.debug_log      = weechat.config_boolean(self.__debug_log)
+
+	def save_rules(self, run_callback = True):
+		''' Save the current rules to the configuration. '''
+		weechat.config_option_set(self.__rules, json.dumps(self.rules), run_callback)
+
+	def save_helpers(self, run_callback = True):
+		''' Save the current helpers to the configuration. '''
+		weechat.config_option_set(self.__helpers, json.dumps(self.helpers), run_callback)
+
+
+def pad(sequence, length, padding = None):
+	''' Pad a list until is has a certain length. '''
+	return sequence + [padding] * max(0, (length - len(sequence)))
+
+def log(message, buffer = 'NULL'):
+	weechat.prnt(buffer, 'autosort: {0}'.format(message))
+
+def debug(message, buffer = 'NULL'):
+	if config.debug_log:
+		weechat.prnt(buffer, 'autosort: debug: {0}'.format(message))
+
+def get_buffers():
+	''' Get a list of all the buffers in weechat. '''
+	hdata  = weechat.hdata_get('buffer')
+	buffer = weechat.hdata_get_list(hdata, "gui_buffers");
+
+	result = []
+	while buffer:
+		number = weechat.hdata_integer(hdata, buffer, 'number')
+		result.append((number, buffer))
+		buffer = weechat.hdata_pointer(hdata, buffer, 'next_buffer')
+	return hdata, result
+
+class MergedBuffers(list):
+	""" A list of merged buffers, possibly of size 1. """
+	def __init__(self, number):
+		super(MergedBuffers, self).__init__()
+		self.number = number
+
+def merge_buffer_list(buffers):
+	'''
+	Group merged buffers together.
+	The output is a list of MergedBuffers.
+	'''
+	if not buffers: return []
+	result = {}
+	for number, buffer in buffers:
+		if number not in result: result[number] = MergedBuffers(number)
+		result[number].append(buffer)
+	return result.values()
+
+def sort_buffers(hdata, buffers, rules, helpers, case_sensitive):
+	for merged in buffers:
+		for buffer in merged:
+			name = weechat.hdata_string(hdata, buffer, 'name')
+
+	return sorted(buffers, key=merged_sort_key(rules, helpers, case_sensitive))
+
+def buffer_sort_key(rules, helpers, case_sensitive):
+	''' Create a sort key function for a list of lists of merged buffers. '''
+	def key(buffer):
+		extra_vars = {}
+		for helper_name, helper in sorted(helpers.items()):
+			expanded = weechat.string_eval_expression(helper, {"buffer": buffer}, {}, {})
+			extra_vars[helper_name] = expanded if case_sensitive else casefold(expanded)
+		result = []
+		for rule in rules:
+			expanded = weechat.string_eval_expression(rule, {"buffer": buffer}, extra_vars, {})
+			result.append(expanded if case_sensitive else casefold(expanded))
+		return result
+
+	return key
+
+def merged_sort_key(rules, helpers, case_sensitive):
+	buffer_key = buffer_sort_key(rules, helpers, case_sensitive)
+	def key(merged):
+		best = None
+		for buffer in merged:
+			this = buffer_key(buffer)
+			if best is None or this < best: best = this
+		return best
+	return key
+
+def apply_buffer_order(buffers):
+	''' Sort the buffers in weechat according to the given order. '''
+	for i, buffer in enumerate(buffers):
+		weechat.buffer_set(buffer[0], "number", str(i + 1))
+
+def split_args(args, expected, optional = 0):
+	''' Split an argument string in the desired number of arguments. '''
+	split = args.split(' ', expected - 1)
+	if (len(split) < expected):
+		raise HumanReadableError('Expected at least {0} arguments, got {1}.'.format(expected, len(split)))
+	return split[:-1] + pad(split[-1].split(' ', optional), optional + 1, '')
+
+def do_sort(verbose = False):
+	start = perf_counter()
+
+	hdata, buffers = get_buffers()
+	buffers = merge_buffer_list(buffers)
+	buffers = sort_buffers(hdata, buffers, config.rules, config.helpers, config.case_sensitive)
+	apply_buffer_order(buffers)
+
+	elapsed = perf_counter() - start
+	if verbose:
+		log("Finished sorting buffers in {0:.4f} seconds.".format(elapsed))
+	else:
+		debug("Finished sorting buffers in {0:.4f} seconds.".format(elapsed))
+
+def command_sort(buffer, command, args):
+	''' Sort the buffers and print a confirmation. '''
+	do_sort(True)
+	return weechat.WEECHAT_RC_OK
+
+def command_debug(buffer, command, args):
+	hdata, buffers = get_buffers()
+	buffers = merge_buffer_list(buffers)
+
+	# Show evaluation results.
+	log('Individual evaluation results:')
+	start = perf_counter()
+	key = buffer_sort_key(config.rules, config.helpers, config.case_sensitive)
+	results = []
+	for merged in buffers:
+		for buffer in merged:
+			fullname = weechat.hdata_string(hdata, buffer, 'full_name')
+			results.append((fullname, key(buffer)))
+	elapsed = perf_counter() - start
+
+	for fullname, result in results:
+		fullname = ensure_str(fullname)
+		result = [ensure_str(x) for x in result]
+		log('{0}: {1}'.format(fullname, result))
+	log('Computing evaluation results took {0:.4f} seconds.'.format(elapsed))
+
+	return weechat.WEECHAT_RC_OK
+
+def command_rule_list(buffer, command, args):
+	''' Show the list of sorting rules. '''
+	output = 'Sorting rules:\n'
+	for i, rule in enumerate(config.rules):
+		output += '    {0}: {1}\n'.format(i, rule)
+	if not len(config.rules):
+		output += '    No sorting rules configured.\n'
+	log(output )
+
+	return weechat.WEECHAT_RC_OK
+
+
+def command_rule_add(buffer, command, args):
+	''' Add a rule to the rule list. '''
+	config.rules.append(args)
+	config.save_rules()
+	command_rule_list(buffer, command, '')
+
+	return weechat.WEECHAT_RC_OK
+
+
+def command_rule_insert(buffer, command, args):
+	''' Insert a rule at the desired position in the rule list. '''
+	index, rule = split_args(args, 2)
+	index = parse_int(index, 'index')
+
+	config.rules.insert(index, rule)
+	config.save_rules()
+	command_rule_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+
+def command_rule_update(buffer, command, args):
+	''' Update a rule in the rule list. '''
+	index, rule = split_args(args, 2)
+	index = parse_int(index, 'index')
+
+	config.rules[index] = rule
+	config.save_rules()
+	command_rule_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+
+def command_rule_delete(buffer, command, args):
+	''' Delete a rule from the rule list. '''
+	index = args.strip()
+	index = parse_int(index, 'index')
+
+	config.rules.pop(index)
+	config.save_rules()
+	command_rule_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+
+def command_rule_move(buffer, command, args):
+	''' Move a rule to a new position. '''
+	index_a, index_b = split_args(args, 2)
+	index_a = parse_int(index_a, 'index')
+	index_b = parse_int(index_b, 'index')
+
+	list_move(config.rules, index_a, index_b)
+	config.save_rules()
+	command_rule_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+
+def command_rule_swap(buffer, command, args):
+	''' Swap two rules. '''
+	index_a, index_b = split_args(args, 2)
+	index_a = parse_int(index_a, 'index')
+	index_b = parse_int(index_b, 'index')
+
+	list_swap(config.rules, index_a, index_b)
+	config.save_rules()
+	command_rule_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+
+def command_helper_list(buffer, command, args):
+	''' Show the list of helpers. '''
+	output = 'Helper variables:\n'
+
+	width = max(map(lambda x: len(x) if len(x) <= 30 else 0, config.helpers.keys()))
+
+	for name, expression in sorted(config.helpers.items()):
+		output += '    {0:>{width}}: {1}\n'.format(name, expression, width=width)
+	if not len(config.helpers):
+		output += '    No helper variables configured.'
+	log(output)
+
+	return weechat.WEECHAT_RC_OK
+
+
+def command_helper_set(buffer, command, args):
+	''' Add/update a helper to the helper list. '''
+	name, expression = split_args(args, 2)
+
+	config.helpers[name] = expression
+	config.save_helpers()
+	command_helper_list(buffer, command, '')
+
+	return weechat.WEECHAT_RC_OK
+
+def command_helper_delete(buffer, command, args):
+	''' Delete a helper from the helper list. '''
+	name = args.strip()
+
+	del config.helpers[name]
+	config.save_helpers()
+	command_helper_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+
+def command_helper_rename(buffer, command, args):
+	''' Rename a helper to a new position. '''
+	old_name, new_name = split_args(args, 2)
+
+	try:
+		config.helpers[new_name] = config.helpers[old_name]
+		del config.helpers[old_name]
+	except KeyError:
+		raise HumanReadableError('No such helper: {0}'.format(old_name))
+	config.save_helpers()
+	command_helper_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+
+def command_helper_swap(buffer, command, args):
+	''' Swap two helpers. '''
+	a, b = split_args(args, 2)
+	try:
+		config.helpers[b], config.helpers[a] = config.helpers[a], config.helpers[b]
+	except KeyError as e:
+		raise HumanReadableError('No such helper: {0}'.format(e.args[0]))
+
+	config.helpers.swap(index_a, index_b)
+	config.save_helpers()
+	command_helper_list(buffer, command, '')
+	return weechat.WEECHAT_RC_OK
+
+def call_command(buffer, command, args, subcommands):
+	''' Call a subcommand from a dictionary. '''
+	subcommand, tail = pad(args.split(' ', 1), 2, '')
+	subcommand = subcommand.strip()
+	if (subcommand == ''):
+		child   = subcommands.get(' ')
+	else:
+		command = command + [subcommand]
+		child   = subcommands.get(subcommand)
+
+	if isinstance(child, dict):
+		return call_command(buffer, command, tail, child)
+	elif callable(child):
+		return child(buffer, command, tail)
+
+	log('{0}: command not found'.format(' '.join(command)))
+	return weechat.WEECHAT_RC_ERROR
+
+def on_signal(data, signal, signal_data):
+	global signal_delay_timer
+	global sort_queued
+
+	# If the sort limit timeout is started, we're in the hold-off time after sorting, just queue a sort.
+	if sort_limit_timer is not None:
+		if sort_queued:
+			debug('Signal {0} ignored, sort limit timeout is active and sort is already queued.'.format(signal))
+		else:
+			debug('Signal {0} received but sort limit timeout is active, sort is now queued.'.format(signal))
+		sort_queued = True
+		return weechat.WEECHAT_RC_OK
+
+	# If the signal delay timeout is started, a signal was recently received, so ignore this signal.
+	if signal_delay_timer is not None:
+		debug('Signal {0} ignored, signal delay timeout active.'.format(signal))
+		return weechat.WEECHAT_RC_OK
+
+	# Otherwise, start the signal delay timeout.
+	debug('Signal {0} received, starting signal delay timeout of {1} ms.'.format(signal, config.signal_delay))
+	weechat.hook_timer(config.signal_delay, 0, 1, "on_signal_delay_timeout", "")
+	return weechat.WEECHAT_RC_OK
+
+def on_signal_delay_timeout(pointer, remaining_calls):
+	""" Called when the signal_delay_timer triggers. """
+	global signal_delay_timer
+	global sort_limit_timer
+	global sort_queued
+
+	signal_delay_timer = None
+
+	# If the sort limit timeout was started, we're still in the no-sort period, so just queue a sort.
+	if sort_limit_timer is not None:
+		debug('Signal delay timeout expired, but sort limit timeout is active, sort is now queued.')
+		sort_queued = True
+		return weechat.WEECHAT_RC_OK
+
+	# Time to sort!
+	debug('Signal delay timeout expired, starting sort.')
+	do_sort()
+
+	# Start the sort limit timeout if not disabled.
+	if config.sort_limit > 0:
+		debug('Starting sort limit timeout of {0} ms.'.format(config.sort_limit))
+		sort_limit_timer = weechat.hook_timer(config.sort_limit, 0, 1, "on_sort_limit_timeout", "")
+
+	return weechat.WEECHAT_RC_OK
+
+def on_sort_limit_timeout(pointer, remainin_calls):
+	""" Called when de sort_limit_timer triggers. """
+	global sort_limit_timer
+	global sort_queued
+
+	# If no signal was received during the timeout, we're done.
+	if not sort_queued:
+		debug('Sort limit timeout expired without receiving a signal.')
+		sort_limit_timer = None
+		return weechat.WEECHAT_RC_OK
+
+	# Otherwise it's time to sort.
+	debug('Signal received during sort limit timeout, starting queued sort.')
+	do_sort()
+	sort_queued = False
+
+	# Start the sort limit timeout again if not disabled.
+	if config.sort_limit > 0:
+		debug('Starting sort limit timeout of {0} ms.'.format(config.sort_limit))
+		sort_limit_timer = weechat.hook_timer(config.sort_limit, 0, 1, "on_sort_limit_timeout", "")
+
+	return weechat.WEECHAT_RC_OK
+
+
+def apply_config():
+	# Unhook all signals and hook the new ones.
+	for hook in hooks:
+		weechat.unhook(hook)
+	for signal in config.signals:
+		hooks.append(weechat.hook_signal(signal, 'on_signal', ''))
+
+	if config.sort_on_config:
+		debug('Sorting because configuration changed.')
+		do_sort()
+
+def on_config_changed(*args, **kwargs):
+	''' Called whenever the configuration changes. '''
+	config.reload()
+	apply_config()
+
+	return weechat.WEECHAT_RC_OK
+
+def parse_arg(args):
+	if not args: return '', None
+
+	result  = ''
+	escaped = False
+	for i, c in enumerate(args):
+		if not escaped:
+			if c == '\\':
+				escaped = True
+				continue
+			elif c == ',':
+				return result, args[i+1:]
+		result  += c
+		escaped  = False
+	return result, None
+
+def parse_args(args, max = None):
+	result = []
+	i = 0
+	while max is None or i < max:
+		i += 1
+		arg, args = parse_arg(args)
+		if arg is None: break
+		result.append(arg)
+		if args is None: break
+	return result, args
+
+def on_info_escape(pointer, name, arguments):
+	result = ''
+	for c in arguments:
+		if c == '\\':
+			result += '\\\\'
+		elif c == ',':
+			result += '\\,'
+		else:
+			result +=c
+	return result
+
+def on_info_replace(pointer, name, arguments):
+	arguments, rest = parse_args(arguments, 3)
+	if rest or len(arguments) < 3:
+		log('usage: ${{info:{0},old,new,text}}'.format(name))
+		return ''
+	old, new, text = arguments
+
+	return text.replace(old, new)
+
+def on_info_order(pointer, name, arguments):
+	arguments, rest = parse_args(arguments)
+	if len(arguments) < 1:
+		log('usage: ${{info:{0},value,first,second,third,...}}'.format(name))
+		return ''
+
+	value = arguments[0]
+	keys  = arguments[1:]
+	if not keys: return '0'
+
+	# Find the value in the keys (or '*' if we can't find it)
+	result = list_find(keys, value)
+	if result is None: result = list_find(keys, '*')
+	if result is None: result = len(keys)
+
+	# Pad result with leading zero to make sure string sorting works.
+	width = int(math.log10(len(keys))) + 1
+	return '{0:0{1}}'.format(result, width)
+
+
+def on_autosort_command(data, buffer, args):
+	''' Called when the autosort command is invoked. '''
+	try:
+		return call_command(buffer, ['/autosort'], args, {
+			' ':      command_sort,
+			'sort':   command_sort,
+			'debug':  command_debug,
+
+			'rules': {
+				' ':         command_rule_list,
+				'list':      command_rule_list,
+				'add':       command_rule_add,
+				'insert':    command_rule_insert,
+				'update':    command_rule_update,
+				'delete':    command_rule_delete,
+				'move':      command_rule_move,
+				'swap':      command_rule_swap,
+			},
+			'helpers': {
+				' ':      command_helper_list,
+				'list':   command_helper_list,
+				'set':    command_helper_set,
+				'delete': command_helper_delete,
+				'rename': command_helper_rename,
+				'swap':   command_helper_swap,
+			},
+		})
+	except HumanReadableError as e:
+		log(e)
+		return weechat.WEECHAT_RC_ERROR
+
+def add_completions(completion, words):
+	for word in words:
+		weechat.hook_completion_list_add(completion, word, 0, weechat.WEECHAT_LIST_POS_END)
+
+def autosort_complete_rules(words, completion):
+	if len(words) == 0:
+		add_completions(completion, ['add', 'delete', 'insert', 'list', 'move', 'swap', 'update'])
+	if len(words) == 1 and words[0] in ('delete', 'insert', 'move', 'swap', 'update'):
+		add_completions(completion, map(str, range(len(config.rules))))
+	if len(words) == 2 and words[0] in ('move', 'swap'):
+		add_completions(completion, map(str, range(len(config.rules))))
+	if len(words) == 2 and words[0] in ('update'):
+		try:
+			add_completions(completion, [config.rules[int(words[1])]])
+		except KeyError: pass
+		except ValueError: pass
+	else:
+		add_completions(completion, [''])
+	return weechat.WEECHAT_RC_OK
+
+def autosort_complete_helpers(words, completion):
+	if len(words) == 0:
+		add_completions(completion, ['delete', 'list', 'rename', 'set', 'swap'])
+	elif len(words) == 1 and words[0] in ('delete', 'rename', 'set', 'swap'):
+		add_completions(completion, sorted(config.helpers.keys()))
+	elif len(words) == 2 and words[0] == 'swap':
+		add_completions(completion, sorted(config.helpers.keys()))
+	elif len(words) == 2 and words[0] == 'rename':
+		add_completions(completion, sorted(config.helpers.keys()))
+	elif len(words) == 2 and words[0] == 'set':
+		try:
+			add_completions(completion, [config.helpers[words[1]]])
+		except KeyError: pass
+	return weechat.WEECHAT_RC_OK
+
+def on_autosort_complete(data, name, buffer, completion):
+	cmdline = weechat.buffer_get_string(buffer, "input")
+	cursor  = weechat.buffer_get_integer(buffer, "input_pos")
+	prefix  = cmdline[:cursor]
+	words   = prefix.split()[1:]
+
+	# If the current word isn't finished yet,
+	# ignore it for coming up with completion suggestions.
+	if prefix[-1] != ' ': words = words[:-1]
+
+	if len(words) == 0:
+		add_completions(completion, ['debug', 'helpers', 'rules', 'sort'])
+	elif words[0] == 'rules':
+		return autosort_complete_rules(words[1:], completion)
+	elif words[0] == 'helpers':
+		return autosort_complete_helpers(words[1:], completion)
+	return weechat.WEECHAT_RC_OK
+
+command_description = r'''{*white}# General commands{reset}
+
+{*white}/autosort {brown}sort{reset}
+Manually trigger the buffer sorting.
+
+{*white}/autosort {brown}debug{reset}
+Show the evaluation results of the sort rules for each buffer.
+
+
+{*white}# Sorting rule commands{reset}
+
+{*white}/autosort{brown} rules list{reset}
+Print the list of sort rules.
+
+{*white}/autosort {brown}rules add {cyan}<expression>{reset}
+Add a new rule at the end of the list.
+
+{*white}/autosort {brown}rules insert {cyan}<index> <expression>{reset}
+Insert a new rule at the given index in the list.
+
+{*white}/autosort {brown}rules update {cyan}<index> <expression>{reset}
+Update a rule in the list with a new expression.
+
+{*white}/autosort {brown}rules delete {cyan}<index>
+Delete a rule from the list.
+
+{*white}/autosort {brown}rules move {cyan}<index_from> <index_to>{reset}
+Move a rule from one position in the list to another.
+
+{*white}/autosort {brown}rules swap {cyan}<index_a> <index_b>{reset}
+Swap two rules in the list
+
+
+{*white}# Helper variable commands{reset}
+
+{*white}/autosort {brown}helpers list
+Print the list of helper variables.
+
+{*white}/autosort {brown}helpers set {cyan}<name> <expression>
+Add or update a helper variable with the given name.
+
+{*white}/autosort {brown}helpers delete {cyan}<name>
+Delete a helper variable.
+
+{*white}/autosort {brown}helpers rename {cyan}<old_name> <new_name>
+Rename a helper variable.
+
+{*white}/autosort {brown}helpers swap {cyan}<name_a> <name_b>
+Swap the expressions of two helper variables in the list.
+
+
+{*white}# Info hooks{reset}
+Autosort comes with a number of info hooks to add some extra functionality to regular weechat eval strings.
+Info hooks can be used in eval strings in the form of {cyan}${{info:some_hook,arguments}}{reset}.
+
+Commas and backslashes in arguments to autosort info hooks (except for {cyan}${{info:autosort_escape}}{reset}) must be escaped with a backslash.
+
+{*white}${{info:{brown}autosort_replace{white},{cyan}pattern{white},{cyan}replacement{white},{cyan}source{white}}}{reset}
+Replace all occurrences of {cyan}pattern{reset} with {cyan}replacement{reset} in the string {cyan}source{reset}.
+Can be used to ignore certain strings when sorting by replacing them with an empty string.
+
+For example: {cyan}${{info:autosort_replace,cat,dog,the dog is meowing}}{reset} expands to "the cat is meowing".
+
+{*white}${{info:{brown}autosort_order{white},{cyan}value{white},{cyan}option0{white},{cyan}option1{white},{cyan}option2{white},{cyan}...{white}}}
+Generate a zero-padded number that corresponds to the index of {cyan}value{reset} in the list of options.
+If one of the options is the special value {brown}*{reset}, then any value not explicitly mentioned will be sorted at that position.
+Otherwise, any value that does not match an option is assigned the highest number available.
+Can be used to easily sort buffers based on a manual sequence.
+
+For example: {cyan}${{info:autosort_order,${{server}},freenode,oftc,efnet}}{reset} will sort freenode before oftc, followed by efnet and then any remaining servers.
+Alternatively, {cyan}${{info:autosort_order,${{server}},freenode,oftc,*,efnet}}{reset} will sort any unlisted servers after freenode and oftc, but before efnet.
+
+{*white}${{info:{brown}autosort_escape{white},{cyan}text{white}}}{reset}
+Escape commas and backslashes in {cyan}text{reset} by prepending them with a backslash.
+This is mainly useful to pass arbitrary eval strings as arguments to other autosort info hooks.
+Otherwise, an eval string that expands to something with a comma would be interpreted as multiple arguments.
+
+For example, it can be used to safely pass buffer names to {cyan}${{info:autosort_replace}}{reset} like so:
+{cyan}${{info:autosort_replace,##,#,${{info:autosort_escape,${{buffer.name}}}}}}{reset}.
+
+
+{*white}# Description
+Autosort is a weechat script to automatically keep your buffers sorted. The sort
+order can be customized by defining your own sort rules, but the default should
+be sane enough for most people. It can also group IRC channel/private buffers
+under their server buffer if you like.
+
+Autosort uses a stable sorting algorithm, meaning that you can manually move buffers
+to change their relative order, if they sort equal with your rule set.
+
+{*white}# Sort rules{reset}
+Autosort evaluates a list of eval expressions (see {*default}/help eval{reset}) and sorts the
+buffers based on evaluated result. Earlier rules will be considered first. Only
+if earlier rules produced identical results is the result of the next rule
+considered for sorting purposes.
+
+You can debug your sort rules with the `{*default}/autosort debug{reset}` command, which will
+print the evaluation results of each rule for each buffer.
+
+{*brown}NOTE:{reset} The sort rules for version 3 are not compatible with version 2 or vice
+versa. You will have to manually port your old rules to version 3 if you have any.
+
+{*white}# Helper variables{reset}
+You may define helper variables for the main sort rules to keep your rules
+readable. They can be used in the main sort rules as variables. For example,
+a helper variable named `{cyan}foo{reset}` can be accessed in a main rule with the
+string `{cyan}${{foo}}{reset}`.
+
+{*white}# Automatic or manual sorting{reset}
+By default, autosort will automatically sort your buffer list whenever a buffer
+is opened, merged, unmerged or renamed. This should keep your buffers sorted in
+almost all situations. However, you may wish to change the list of signals that
+cause your buffer list to be sorted. Simply edit the `{cyan}autosort.sorting.signals{reset}`
+option to add or remove any signal you like.
+
+If you remove all signals you can still sort your buffers manually with the
+`{*default}/autosort sort{reset}` command. To prevent all automatic sorting, the option
+`{cyan}autosort.sorting.sort_on_config_change{reset}` should also be disabled.
+
+{*white}# Recommended settings
+For the best visual effect, consider setting the following options:
+  {*white}/set {cyan}irc.look.server_buffer{reset} {brown}independent{reset}
+
+This setting allows server buffers to be sorted independently, which is
+needed to create a hierarchical tree view of the server and channel buffers.
+
+If you are using the {*default}buflist{reset} plugin you can (ab)use Unicode to draw a tree
+structure with the following setting (modify to suit your need):
+  {*white}/set {cyan}buflist.format.indent {brown}"${{color:237}}${{if:${{buffer.next_buffer.local_variables.type}}=~^(channel|private)$?├─:└─}}"{reset}
+'''
+
+command_completion = '%(plugin_autosort) %(plugin_autosort) %(plugin_autosort) %(plugin_autosort) %(plugin_autosort)'
+
+info_replace_description = (
+	'Replace all occurrences of `pattern` with `replacement` in the string `source`. '
+	'Can be used to ignore certain strings when sorting by replacing them with an empty string. '
+	'See /help autosort for examples.'
+)
+info_replace_arguments = 'pattern,replacement,source'
+
+info_order_description = (
+	'Generate a zero-padded number that corresponds to the index of `value` in the list of options. '
+	'If one of the options is the special value `*`, then any value not explicitly mentioned will be sorted at that position. '
+	'Otherwise, any value that does not match an option is assigned the highest number available. '
+	'Can be used to easily sort buffers based on a manual sequence. '
+	'See /help autosort for examples.'
+)
+info_order_arguments = 'value,first,second,third,...'
+
+info_escape_description = (
+	'Escape commas and backslashes in `text` by prepending them with a backslash. '
+	'This is mainly useful to pass arbitrary eval strings as arguments to other autosort info hooks. '
+	'Otherwise, an eval string that expands to something with a comma would be interpreted as multiple arguments.'
+	'See /help autosort for examples.'
+)
+info_escape_arguments = 'text'
+
+
+if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
+	config = Config('autosort')
+
+	colors = {
+		'default':  weechat.color('default'),
+		'reset':    weechat.color('reset'),
+		'black':    weechat.color('black'),
+		'red':      weechat.color('red'),
+		'green':    weechat.color('green'),
+		'brown':    weechat.color('brown'),
+		'yellow':   weechat.color('yellow'),
+		'blue':     weechat.color('blue'),
+		'magenta':  weechat.color('magenta'),
+		'cyan':     weechat.color('cyan'),
+		'white':    weechat.color('white'),
+		'*default': weechat.color('*default'),
+		'*black':   weechat.color('*black'),
+		'*red':     weechat.color('*red'),
+		'*green':   weechat.color('*green'),
+		'*brown':   weechat.color('*brown'),
+		'*yellow':  weechat.color('*yellow'),
+		'*blue':    weechat.color('*blue'),
+		'*magenta': weechat.color('*magenta'),
+		'*cyan':    weechat.color('*cyan'),
+		'*white':   weechat.color('*white'),
+	}
+
+	weechat.hook_config('autosort.*', 'on_config_changed',  '')
+	weechat.hook_completion('plugin_autosort', '', 'on_autosort_complete', '')
+	weechat.hook_command('autosort', command_description.format(**colors), '', '', command_completion, 'on_autosort_command', '')
+	weechat.hook_info('autosort_escape',  info_escape_description,  info_escape_arguments,  'on_info_escape', '')
+	weechat.hook_info('autosort_replace', info_replace_description, info_replace_arguments, 'on_info_replace', '')
+	weechat.hook_info('autosort_order',   info_order_description,   info_order_arguments,   'on_info_order',   '')
+
+	apply_config()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/colon_complete.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,69 @@
+SCRIPT_NAME='coloncomplete'
+SCRIPT_AUTHOR='Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION='1.0'
+SCRIPT_LICENSE='MIT/X11'
+SCRIPT_DESC='Add a colon after nick completion when all the previous words in the input are also nicks.'
+
+EXTRA_NICKS = ['all', 'backend', 'clojerks', 'ops', 'support']
+
+import_ok=True
+
+try:
+    import weechat
+except ImportError:
+    print 'This script must be run under WeeChat'
+    print 'You can obtain a copy of WeeChat, for free, at http://www.weechat.org'
+    import_ok=False
+
+weechat_version=0
+
+def get_nicks(buffer, prefix=''):
+    channel = weechat.buffer_get_string(buffer, 'localvar_channel')
+    server = weechat.buffer_get_string(buffer, 'localvar_server')
+    prefix = prefix.lower()
+
+    matches = []
+
+    infolist = weechat.infolist_get('irc_nick', '', '%s,%s' % (server, channel))
+    while weechat.infolist_next(infolist):
+        nick = weechat.infolist_string(infolist, 'name')
+        if nick != 'localhost' and nick.lower().startswith(prefix):
+            matches.append(nick)
+    weechat.infolist_free(infolist)
+
+    for nick in EXTRA_NICKS:
+        if nick.lower().startswith(prefix):
+            matches.append(nick)
+
+    return matches
+
+def completer(data, buffer, command):
+    cb = weechat.current_buffer()
+    if command == "/input complete_next":
+        line = weechat.buffer_get_string(cb, "input")
+        words = line.split(' ')
+        prefix = words[-1]
+        if prefix and words and all([s.endswith(':') for s in words[:-1] if s]):
+            nicks = get_nicks(cb, prefix)
+            if len(nicks) == 1:
+                for _ in range(len(prefix)):
+                    weechat.command(buffer, "/input delete_previous_char")
+                weechat.command(buffer, "/input insert " + nicks[-1] + ":\\x20")
+            elif len(nicks) > 1:
+                l = min(len(nick) for nick in nicks)
+                for i in range(len(prefix), l):
+                    if len(set(nick[i] for nick in nicks)) > 1:
+                        break
+                    else:
+                        weechat.command(buffer, "/input insert " + nicks[0][i])
+
+                for nick in nicks:
+                    weechat.prnt(cb, "==> " + nick)
+                return weechat.WEECHAT_RC_OK_EAT
+
+    return weechat.WEECHAT_RC_OK
+
+if __name__ == "__main__" and import_ok:
+    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
+        weechat_version = weechat.info_get("version_number", "") or 0
+        weechat.hook_command_run('/input complete*', 'completer', '')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/listbuffer.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,467 @@
+# -*- coding: utf-8 -*-
+#
+# ListBuffer, version 0.8.1 for WeeChat version 0.3
+# Latest development version: https://github.com/FiXato/listbuffer
+#
+#   Show /list results in a common buffer and interact with them.
+#
+#   This script allows you to easily join channels from the /list output.
+#   It will open a common buffer for the /list result, through which you
+#   browse with your cursor keys, and join with the meta-enter keys.
+#   Adjust sorting with meta->, meta-< and meta-/ keybindings.
+#
+## History:
+### 2011-09-08: FiXato:
+#
+# * version 0.1:  initial release.
+#     * added a common buffer for /list results
+#     * added highlighting for currently selected line
+#     * added /join support via enter key
+#     * added scroll_top and scroll_bottom support
+#
+# * version 0.2:  /list format bugfix
+#     * added support for /list results without modes
+#     * some servers don't send 321 (/list start). Taken into account.
+#
+# * version 0.3: Sorting support
+#     * Added some basic sorting support. Scroll through sort options
+#       with meta-> and meta-< (users, channel, topic, modes)
+#
+### 2011-09-19: FiXato
+#
+# * version 0.4:
+#     * Case-insensitive buffer lookup fix.
+#     * Removed default enter keybind
+#
+### 2011-12-28: troydm:
+#
+# * version 0.5: It's an upside-down-world
+#     * Added inverted sorting support provided by Dmitry "troydm" Geurkov
+#       Use meta-/ to switch between inverted and regular sorting.
+#
+### 2012-02-10: FiXato:
+#
+# * version 0.6: Stop shoving that buffer in my face!
+#     * The listbuffer should no longer pop up by itself when you load the script.
+#       It should only pop up now when you actually do a /list query.
+#
+# * version 0.7: .. but please pop it up in my current window when I ask for it
+#     * Added setting plugins.var.python.listbuffer.autofocus
+#       This will autofocus the listbuffer in the current window if another window isn't
+#       already showing it, and of course only when the user issues /list
+#
+### 2012-07-10: FiXato:
+#
+# * version 0.7.1: Forgetful bugfix
+#     * Made sure lb_curline global variable is defined
+#
+### 2013-03-19: FiXato:
+#
+# * version 0.8: Sorted out the sorting
+#     * Added automatically updating options for sorting:
+#       * plugins.var.python.listbuffer.sort_inverted
+#       * plugins.var.python.listbuffer.sort_order
+# * version 0.8.1: Pad it baby!
+#     * Channel modes are equally padded even when there are no channel modes.
+#     * Added padding options:
+#       * plugins.var.python.listbuffer.modes_min_width
+#       * plugins.var.python.listbuffer.channel_min_width
+#       * plugins.var.python.listbuffer.users_min_width
+#
+## Acknowledgements:
+# * Dmitry "troydm" Geurkov, for providing the inverse-sorting patch to the project.
+# * Sebastien "Flashcode" Helleu, for developing the kick-ass IRC client WeeChat
+#    and the iset.pl script which inspired me to this script.
+# * Nils "nils_2" Görs, for his contributions to iset.pl which served as
+#    example code.
+# * David "drubin" Rubin, for his urlgrab.py script, which also served
+#    as example code.
+# * ArZa, whose listsort.pl script helped me getting started with
+#    grabbing the /list results. Parts of his code have been shamelessly
+#    copied and ported to Python.
+# * Khaled Mardam-Bey, for making me yearn for similar /list support in
+#    WeeChat as mIRC already offered. :P
+# * mave_, for pointing out that sort orders weren't remembered.
+#
+## TODO:
+#   - Auto-scroll selected line upon window scroll.
+#   - Add option to hide already joined channels.
+#   - Improve sorting methods
+#   - Add auto-join support
+#   - Detect if channel is already in auto-join
+#   - Allow automatically switching to the listbuffer
+#   - Add support for ALIS (/squery alis LIST * -mix 100 (IRCNet)
+#   - Make colours configurable
+#   - Limit number of channels to parse
+#   - Add filter support a la iset
+#   - Allow selecting multiple channels
+#   - Add optional command redirection.
+#
+## Copyright (c) 2011,2012,2013 Filip H.F. "FiXato" Slagter,
+#   <FiXato [at] Gmail [dot] com>
+#   http://profile.fixato.org
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+SCRIPT_NAME    = "listbuffer"
+SCRIPT_AUTHOR  = "Filip H.F. 'FiXato' Slagter <fixato [at] gmail [dot] com>"
+SCRIPT_VERSION = "0.8.1"
+SCRIPT_LICENSE = "MIT"
+SCRIPT_DESC    = "A common buffer for /list output."
+SCRIPT_COMMAND = "listbuffer"
+
+import_ok = True
+
+try:
+  import weechat
+except ImportError:
+  print "This script must be run under WeeChat."
+  import_ok = False
+
+import re
+
+lb_settings = (
+  ("autofocus", "on", "Focus the listbuffer in the current window if it isn't already displayed by a window."),
+  ("sort_order", "users", "Last used sort order for the channel list."),
+  ("sort_inverted", "on", "Invert the sort order for the channel list."),
+  ("modes_min_width", "8", "The minimum width used for modes in the channel list. If a channel has less modes than this amount, the column will be padded with spaces."),
+  ("channel_min_width", "25", "The minimum width used for the channel name in the channel list. If a channelname is shorter than this amount, the column will be padded with spaces."),
+  ("users_min_width", "8", "The minimum width used for the usercount in the channel list. If the usercount has less digits than this amount, the column will be padded with spaces."),
+)
+lb_buffer = None
+lb_curline = 0
+lb_channels = []
+lb_network = None
+lb_list_started = False
+lb_current_sort = None
+lb_sort_inverted = False
+lb_sort_options = (
+  'channel',
+  'users',
+  'modes',
+  'topic',
+)
+
+#                              server numeric Nick Chan  Users     Modes    Topic
+lb_channel_list_expression = '(:\S+) (\d{3}) (\S+) (\S+) (\d+) :(\[(.*?)\] )?(.*)'
+
+# Create listbuffer.
+def lb_create_buffer():
+  global lb_buffer, lb_curline
+
+  if not lb_buffer:
+    lb_buffer = weechat.buffer_new("listbuffer", "lb_input_cb", \
+                "", "lb_close_cb", "")
+    lb_set_buffer_title()
+    # Sets notify to 0 as this buffer does not need to be in hotlist.
+    weechat.buffer_set(lb_buffer, "notify", "0")
+    weechat.buffer_set(lb_buffer, "nicklist", "0")
+    weechat.buffer_set(lb_buffer, "type", "free")
+    weechat.buffer_set(lb_buffer, "key_bind_ctrl-L", "/listbuffer **refresh")
+    weechat.buffer_set(lb_buffer, "key_bind_meta2-A", "/listbuffer **up")
+    weechat.buffer_set(lb_buffer, "key_bind_meta2-B", "/listbuffer **down")
+    weechat.buffer_set(lb_buffer, "key_bind_meta2-1~", "/listbuffer **scroll_top")
+    weechat.buffer_set(lb_buffer, "key_bind_meta2-4~", "/listbuffer **scroll_bottom")
+    weechat.buffer_set(lb_buffer, "key_bind_meta-ctrl-J", "/listbuffer **enter")
+    weechat.buffer_set(lb_buffer, "key_bind_meta-ctrl-M", "/listbuffer **enter")
+    weechat.buffer_set(lb_buffer, "key_bind_meta->", "/listbuffer **sort_next")
+    weechat.buffer_set(lb_buffer, "key_bind_meta-<", "/listbuffer **sort_previous")
+    weechat.buffer_set(lb_buffer, "key_bind_meta-/", "/listbuffer **sort_invert")
+    lb_curline = 0
+  if weechat.config_get_plugin("autofocus") == "on":
+    if not weechat.window_search_with_buffer(lb_buffer):
+      weechat.command("", "/buffer " + weechat.buffer_get_string(lb_buffer,"name"))
+
+def lb_set_buffer_title():
+  global lb_buffer, lb_current_sort
+  ascdesc = '(v)' if lb_sort_inverted else '(^)'
+  weechat.buffer_set(lb_buffer, "title", lb_line_format({
+    'channel': 'Channel name%s' % (ascdesc if lb_current_sort == 'channel' else ''),
+    'users': 'Users%s' % (ascdesc if lb_current_sort == 'users' else ''),
+    'modes': 'Modes%s' % (ascdesc if lb_current_sort == 'modes' else ''),
+    'topic': 'Topic%s' % (ascdesc if lb_current_sort == 'topic' else ''),
+    'nomodes': None,
+  }))
+
+def lb_list_start(data, signal, message):
+  lb_initialise_list
+
+  return weechat.WEECHAT_RC_OK
+
+def lb_initialise_list(signal):
+  global lb_channels, lb_network, lb_list_started
+
+  lb_create_buffer()
+  lb_channels = []
+  lb_network = signal.split(',')[0]
+  lb_list_started = True
+  return
+
+
+def lb_list_chan(data, signal, message):
+  global lb_channels, lb_buffer, lb_list_started
+
+  # Work-around for IRCds which don't send 321 Numeric (/List start)
+  if not lb_list_started:
+    lb_initialise_list(signal)
+
+  for chan_data in re.findall(lb_channel_list_expression,message):
+    lb_channels.append({
+      'server':  chan_data[0][1:-1],
+      'numeric': chan_data[1],
+      'nick':    chan_data[2],
+      'channel': chan_data[3],
+      'users':   chan_data[4],
+      'nomodes': chan_data[5] == '',
+      'modes':   chan_data[6],
+      'topic':   weechat.hook_modifier_exec("irc_color_decode", "1", chan_data[7])
+    })
+  return weechat.WEECHAT_RC_OK
+
+def lb_list_end(data, signal, message):
+  global lb_list_started
+
+  # Work-around for IRCds which don't send 321 Numeric (/List start)
+  if not lb_list_started:
+    lb_initialise_list(signal)
+
+  lb_list_started = False
+  if lb_current_sort:
+    lb_sort()
+  lb_refresh()
+  return weechat.WEECHAT_RC_OK
+
+def keyEvent (data, buffer, args):
+  global lb_options
+  lb_options[args]()
+
+def lb_input_cb(data, buffer, input_data):
+  global lb_options, lb_curline
+  lb_options[input_data]()
+  return weechat.WEECHAT_RC_OK
+
+def lb_refresh():
+  global lb_channels, lb_buffer
+  weechat.buffer_clear(lb_buffer)
+
+  y = 0
+  for list_data in lb_channels:
+    lb_refresh_line(y)
+    y += 1
+  return
+
+def lb_refresh_line(y):
+  global lb_buffer, lb_curline, lb_channels
+  if y >= 0 and y < len(lb_channels):
+    formatted_line = lb_line_format(lb_channels[y], y == lb_curline)
+    weechat.prnt_y(lb_buffer, y, formatted_line)
+
+def lb_refresh_curline():
+  global lb_curline
+  lb_refresh_line(lb_curline-1)
+  lb_refresh_line(lb_curline)
+  lb_refresh_line(lb_curline+1)
+  return
+
+def lb_line_format(list_data,curr=False):
+  str = ""
+  if (curr):
+    str += weechat.color("yellow,red")
+  channel_text = list_data['channel'].ljust(int(weechat.config_get_plugin('channel_min_width')))
+  users_text = "(%s)" % list_data['users']
+  padded_users_text = users_text.rjust(int(weechat.config_get_plugin('users_min_width')) + 2)
+  str += "%s%s %s " % (weechat.color("bold"), channel_text, padded_users_text)
+  if not list_data['nomodes']:
+    modes = "[%s]" % list_data['modes']
+  else:
+    modes = "[]"
+  str += "%s: " % modes.rjust(int(weechat.config_get_plugin('modes_min_width')) + 2)
+  str += "%s" % list_data['topic']
+  return str
+
+def lb_line_up():
+  global lb_curline
+  if lb_curline <= 0:
+    return
+  lb_curline -= 1
+  lb_refresh_curline()
+  lb_check_outside_window()
+  return
+
+def lb_line_down():
+  global lb_curline, lb_channels
+  if lb_curline+1 >= len(lb_channels):
+    return
+  lb_curline += 1
+  lb_refresh_curline()
+  lb_check_outside_window()
+  return
+
+def lb_line_run():
+  global lb_channels, lb_curline, lb_network
+  buff = weechat.info_get("irc_buffer", lb_network)
+  channel = lb_channels[lb_curline]['channel']
+  command = "/join %s" % channel
+  weechat.command(buff, command)
+  return
+
+def lb_line_select():
+  return
+
+def lb_scroll_top():
+  global lb_curline
+  old_y = lb_curline
+  lb_curline = 0
+  lb_refresh_curline()
+  lb_refresh_line(old_y)
+  weechat.command(lb_buffer, "/window scroll_top")
+  return
+
+def lb_scroll_bottom():
+  global lb_curline, lb_channels
+  old_y = lb_curline
+  lb_curline = len(lb_channels)-1
+  lb_refresh_curline()
+  lb_refresh_line(old_y)
+  weechat.command(lb_buffer, "/window scroll_bottom")
+  return
+
+def lb_check_outside_window():
+  global lb_buffer, lb_curline
+  if (lb_buffer):
+    infolist = weechat.infolist_get("window", "", "current")
+    if (weechat.infolist_next(infolist)):
+      start_line_y = weechat.infolist_integer(infolist, "start_line_y")
+      chat_height = weechat.infolist_integer(infolist, "chat_height")
+      if(start_line_y > lb_curline):
+        weechat.command(lb_buffer, "/window scroll -%i" %(start_line_y - lb_curline))
+      elif(start_line_y <= lb_curline - chat_height):
+        weechat.command(lb_buffer, "/window scroll +%i"%(lb_curline - start_line_y - chat_height + 1))
+    weechat.infolist_free(infolist)
+
+def lb_sort_next():
+  global lb_current_sort, lb_sort_options
+  if lb_current_sort:
+    new_index = lb_sort_options.index(lb_current_sort) + 1
+  else:
+    new_index = 0
+
+  if len(lb_sort_options) <= new_index:
+    new_index = 0
+
+  lb_set_current_sort_order(lb_sort_options[new_index])
+  lb_sort()
+
+def lb_set_current_sort_order(value):
+  global lb_current_sort
+  lb_current_sort = value
+  weechat.config_set_plugin('sort_order', lb_current_sort)
+
+def lb_set_invert_sort_order(value):
+  global lb_sort_inverted
+  lb_sort_inverted = value
+  weechat.config_set_plugin('sort_inverted', ('on' if lb_sort_inverted else 'off'))
+
+def lb_sort_previous():
+  global lb_current_sort, lb_sort_options
+  if lb_current_sort:
+    new_index = lb_sort_options.index(lb_current_sort) - 1
+  else:
+    new_index = 0
+
+  if new_index < 0:
+    new_index = len(lb_sort_options) - 1
+
+  lb_set_current_sort_order(lb_sort_options[new_index])
+  lb_sort()
+
+def lb_sort(sort_key=None):
+  global lb_channels, lb_current_sort, lb_sort_inverted
+  if sort_key:
+    lb_set_current_sort_order(sort_key)
+  if lb_current_sort == 'users':
+    lb_channels = sorted(lb_channels, key=lambda chan_data: int(chan_data[lb_current_sort]))
+  else:
+    lb_channels = sorted(lb_channels, key=lambda chan_data: chan_data[lb_current_sort])
+  if lb_sort_inverted:
+    lb_channels.reverse()
+  lb_set_buffer_title()
+  lb_refresh()
+
+def lb_sort_invert():
+  global lb_current_sort, lb_sort_inverted
+  if lb_current_sort:
+    lb_set_invert_sort_order(not lb_sort_inverted)
+    lb_sort()
+
+def lb_close_cb(*kwargs):
+  """ A callback for buffer closing. """
+  global lb_buffer
+
+  lb_buffer = None
+  return weechat.WEECHAT_RC_OK
+
+lb_options = {
+  'refresh'     : lb_refresh,
+  'up'          : lb_line_up,
+  'down'        : lb_line_down,
+  'enter'       : lb_line_run,
+  'space'       : lb_line_select,
+  'scroll_top'  : lb_scroll_top,
+  'scroll_bottom': lb_scroll_bottom,
+  'sort_next'   : lb_sort_next,
+  'sort_previous': lb_sort_previous,
+  'sort_invert': lb_sort_invert
+}
+
+def lb_command_main(data, buffer, args):
+  if args[0:2] == "**":
+    keyEvent(data, buffer, args[2:])
+  return weechat.WEECHAT_RC_OK
+
+def lb_set_default_settings():
+  global lb_settings
+  # Set default settings
+  for option, default_value, description in lb_settings:
+     if not weechat.config_is_set_plugin(option):
+         weechat.config_set_plugin(option, default_value)
+         version = weechat.info_get("version_number", "") or 0
+         if int(version) >= 0x00030500:
+             weechat.config_set_desc_plugin(option, description)
+
+def lb_reset_stored_sort_order():
+  global lb_current_sort, lb_sort_inverted
+  lb_current_sort = weechat.config_get_plugin('sort_order')
+  lb_sort_inverted = (True if weechat.config_get_plugin('sort_inverted') == 'on' else False)
+
+if __name__ == "__main__" and import_ok:
+  if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
+                      SCRIPT_LICENSE, SCRIPT_DESC, "lb_close_cb", ""):
+    lb_set_default_settings()
+    lb_reset_stored_sort_order()
+    lb_buffer = weechat.buffer_search("python", "listbuffer")
+
+    weechat.hook_signal("*,irc_in_321", "lb_list_start", "")
+    weechat.hook_signal("*,irc_in_322", "lb_list_chan", "")
+    weechat.hook_signal("*,irc_in_323", "lb_list_end", "")
+    weechat.hook_command(SCRIPT_COMMAND,
+                          "List Buffer",
+                          "", "", "",
+                          "lb_command_main", "")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/python/sanitize_jira.py	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,33 @@
+import re, weechat, subprocess
+
+SCRIPT_NAME = 'sanitize_jira'
+SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION = '0.0.1'
+SCRIPT_LICENSE = 'MIT'
+SCRIPT_DESC = 'clean up the garbage jirabot sends to channels into something readable'
+
+weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', '')
+
+weechat.hook_line('*', '', 'nick_Jira_Cloud', 'sanitize_jira', '')
+
+first_line_re = re.compile(
+    r'(?P<link>https://[^/]+/browse/[^?]+)[?]atlOrigin=[^ ]+ [(](?P<title>.+)[)]'
+)
+
+detail_line_re = re.compile(
+    r'''Status: \x1a\x01[*](?P<status>[^*]+)[*]\x1b\x01.*Type: \x1a\x01[*](?P<type>[^*]+)[*]\x1b\x01.*Assignee: \x1a\x01[*](?P<assignee>[^*]+)[*]\x1b\x01.*Priority: \x1a\x01[*](?P<priority>[^*]+)[*]\x1b\x01'''
+)
+
+def sanitize_jira(data, line):
+    if 'sign up for an Atlassian account to view this link' in line['message']:
+        return {'message': ' '}
+
+    m = first_line_re.search(line['message'])
+    if m:
+        return {'message': '%s | %s' % (m.group('title'), m.group('link'))}
+
+    m = detail_line_re.search(line['message'])
+    if m:
+        return {'message': '%s / %s / %s' % (m.group('type'), m.group('status'), m.group('assignee'))}
+
+    return {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/relay.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,59 @@
+#
+# weechat -- relay.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[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 = ""
+auth_timeout = 60
+bind_address = ""
+clients_purge_delay = 0
+compression = 20
+ipv6 = on
+max_clients = 5
+nonce_size = 16
+password = ""
+password_hash_algo = "*"
+password_hash_iterations = 100000
+ssl_cert_key = "%h/ssl/relay.pem"
+ssl_priorities = "NORMAL:-VERS-SSL3.0"
+totp_secret = ""
+totp_window = 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] "
+
+[weechat]
+commands = ""
+
+[port]
+
+[path]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/rmodifier.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,11 @@
+#
+# rmodifier.conf -- weechat v0.4.3
+#
+
+[look]
+hide_char = "*"
+
+[modifier]
+nickserv = "history_add,input_text_display;^(/(msg|quote) +nickserv +(identify|ghost \S+) +)(.*);1,4*"
+oper = "history_add,input_text_display;^(/oper +\S+ +)(.*);1,2*"
+set_pass = "history_add;^(/set +\S*password\S* +)(.*);1,2*"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/ruby.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,14 @@
+#
+# weechat -- ruby.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[look]
+check_license = off
+eval_keep_context = on
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/script.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,57 @@
+#
+# weechat -- script.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[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 = darkgray
+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 = 60
+download_enabled = on
+download_timeout = 30
+hold = ""
+path = "%h/script"
+url = "http://www.weechat.org/files/plugins.xml.gz"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/spell.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,33 @@
+#
+# weechat -- spell.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[color]
+misspelled = lightred
+suggestion = default
+suggestion_delimiter_dict = cyan
+suggestion_delimiter_word = cyan
+
+[check]
+commands = "away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic"
+default_dict = ""
+during_search = off
+enabled = off
+real_time = off
+suggestions = -1
+word_min_length = 2
+
+[dict]
+
+[look]
+suggestion_delimiter_dict = " / "
+suggestion_delimiter_word = ","
+
+[option]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/tcl.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,14 @@
+#
+# weechat -- tcl.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use /set or similar command to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[look]
+check_license = off
+eval_keep_context = on
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/trigger.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,83 @@
+#
+# weechat -- trigger.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[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_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|quote) +nickserv +(id|identify|register|ghost +[^ ]+|release +[^ ]+|regain +[^ ]+) +)|/oper +[^ ]+ +|/quote +pass +|/set +[^ ]*password[^ ]* +|/secure +(passphrase|decrypt|set +[^ ]+) +)(.*)==$1$.*+"
+cmd_pass.return_code = ok
+dumbass_buffer.arguments = "4000|input_text_for_buffer;4000|history_add"
+dumbass_buffer.command = ""
+dumbass_buffer.conditions = ""
+dumbass_buffer.enabled = on
+dumbass_buffer.hook = modifier
+dumbass_buffer.post_action = none
+dumbass_buffer.regex = "==^ +/?b (.+)==/b ${re:1}"
+dumbass_buffer.return_code = ok
+idiot_buffer.arguments = "4000|input_text_for_buffer;4000|history_add"
+idiot_buffer.command = ""
+idiot_buffer.conditions = ""
+idiot_buffer.enabled = on
+idiot_buffer.hook = modifier
+idiot_buffer.post_action = none
+idiot_buffer.regex = "==^b (.+)==/b ${re:1}"
+idiot_buffer.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 +[^ ]+) +)(.*)==$1$.*+"
+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=)([^ ]+)(.*)==$1$.*4$5"
+server_pass.return_code = ok
+uncc.arguments = "weechat_print"
+uncc.command = ""
+uncc.conditions = "${tg_tag_nick}"
+uncc.enabled = on
+uncc.hook = modifier
+uncc.post_action = none
+uncc.regex = "== \[cc: [^ ]+\]===="
+uncc.return_code = ok
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/typing.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,19 @@
+#
+# weechat -- typing.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[look]
+delay_purge_paused = 30
+delay_purge_typing = 6
+delay_set_paused = 10
+enabled_nicks = off
+enabled_self = off
+input_min_chars = 4
+item_max_length = 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/urlgrab.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,29 @@
+#
+# weechat -- urlgrab.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[color]
+color_bg_selected = green
+color_buffer = red
+color_buffer_selected = red
+color_time = cyan
+color_time_selected = cyan
+color_url = blue
+color_url_selected = blue
+
+[default]
+copycmd = "xsel -i"
+historysize = 20
+localcmd = "xdg-open %s"
+method = "local"
+output_main_buffer = off
+remotecmd = "ssh -x localhost -i ~/.ssh/id_rsa -C "export DISPLAY=":0.0" &&  firefox %s""
+time_format = "%H:%M:%S"
+url_log = "~/.weechat/urls.log"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/weechat.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,693 @@
+#
+# WeeChat -- weechat.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[debug]
+
+[startup]
+command_after_plugins = ""
+command_before_plugins = ""
+display_logo = on
+display_version = on
+sys_rlimit = ""
+
+[look]
+align_end_of_lines = message
+align_multiline_words = on
+bar_more_down = "++"
+bar_more_left = "<<"
+bar_more_right = ">>"
+bar_more_up = "--"
+bare_display_exit_on_input = on
+bare_display_time_format = "%H:%M"
+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 = "%H:%M"
+buffer_time_same = ""
+color_basic_force_bold = off
+color_inactive_buffer = off
+color_inactive_message = on
+color_inactive_prefix = on
+color_inactive_prefix_buffer = on
+color_inactive_time = off
+color_inactive_window = off
+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 = "sjl,slosh,slj,horrifying,steve.losh,@steve.losh,stevelosh"
+highlight_regex = "(steve losh|rob ford|(jesus )?fucking christ|(horse|mouse|clown)fuckers?|((mother)?fuck([ie]ng?|er)?|(god?)?damn(ed)?|dammit|(bull|horse)?shite?){3,})"
+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 = "H: "
+hotlist_remove = merged
+hotlist_short_names = on
+hotlist_sort = group_time_asc
+hotlist_suffix = ""
+hotlist_unique_numbers = on
+hotlist_update_on_buffer_switch = 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 = "%H:%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 = off
+mouse_timer_delay = 100
+nick_color_force = ""
+nick_color_hash = djb2
+nick_color_hash_salt = ""
+nick_color_stop_chars = "_|["
+nick_prefix = ""
+nick_suffix = ""
+paste_auto_add_newline = on
+paste_bracketed = off
+paste_bracketed_timer_delay = 10
+paste_max_lines = 3
+prefix_action = " *"
+prefix_align = right
+prefix_align_max = 15
+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_same_nick_middle = ""
+prefix_suffix = "|"
+quote_nick_prefix = "<"
+quote_nick_suffix = ">"
+quote_time_format = "%H:%M:%S"
+read_marker = line
+read_marker_always_show = on
+read_marker_string = "─"
+read_marker_update_on_buffer_switch = on
+save_config_on_exit = off
+save_config_with_fsync = off
+save_layout_on_exit = all
+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 = ""
+word_chars_highlight = "!\u00A0,-,_,|,@,.,alnum"
+word_chars_input = "!\u00A0,-,_,|,alnum"
+
+[palette]
+
+[color]
+bar_more = magenta
+chat = default
+chat_bg = default
+chat_buffer = white
+chat_channel = white
+chat_day_change = cyan
+chat_delimiters = green
+chat_highlight = 207
+chat_highlight_bg = default
+chat_host = cyan
+chat_inactive_buffer = darkgray
+chat_inactive_window = darkgray
+chat_nick = lightcyan
+chat_nick_colors = "027,048,068,028,081,082,099,112,129,136,169,178,208,226,113,196,161,23,59,222"
+chat_nick_offline = darkgray
+chat_nick_offline_highlight = default
+chat_nick_offline_highlight_bg = darkgray
+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 = darkgray
+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 = green
+chat_read_marker_bg = default
+chat_server = brown
+chat_tags = red
+chat_text_found = yellow
+chat_text_found_bg = lightmagenta
+chat_time = 238
+chat_time_delimiters = 236
+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 = green
+status_count_highlight = magenta
+status_count_msg = brown
+status_count_other = 16
+status_count_private = green
+status_data_highlight = lightmagenta
+status_data_msg = yellow
+status_data_other = 16
+status_data_private = lightgreen
+status_filter = green
+status_more = 16
+status_mouse = green
+status_name = *16
+status_name_ssl = *16
+status_nicklist_count = default
+status_number = 16
+status_time = *16
+
+[completion]
+base_word_until_cursor = on
+command_inline = on
+default_template = "%(nicks)|%(irc_channels)"
+nick_add_space = on
+nick_case_sensitive = off
+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
+partial_completion_templates = "config_options"
+
+[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_system = on
+gnutls_ca_user = ""
+gnutls_handshake_timeout = 30
+proxy_curl = ""
+
+[plugin]
+autoload = "*"
+debug = off
+extension = ".so"
+path = "%h/plugins"
+save_config_on_unload = on
+
+[signal]
+sighup = "${if:${info:weechat_headless}?/reload:/quit -yes}"
+sigquit = "/quit -yes"
+sigterm = "/quit -yes"
+sigusr1 = ""
+sigusr2 = ""
+
+[bar]
+buffers.color_bg = default
+buffers.color_bg_inactive = default
+buffers.color_delim = default
+buffers.color_fg = default
+buffers.conditions = ""
+buffers.filling_left_right = vertical
+buffers.filling_top_bottom = horizontal
+buffers.hidden = on
+buffers.items = "buffers"
+buffers.position = left
+buffers.priority = 0
+buffers.separator = on
+buffers.size = 0
+buffers.size_max = 0
+buffers.type = root
+buflist.color_bg = default
+buflist.color_bg_inactive = default
+buflist.color_delim = default
+buflist.color_fg = default
+buflist.conditions = ""
+buflist.filling_left_right = vertical
+buflist.filling_top_bottom = columns_vertical
+buflist.hidden = off
+buflist.items = "buflist"
+buflist.position = left
+buflist.priority = 0
+buflist.separator = on
+buflist.size = 0
+buflist.size_max = 25
+buflist.type = root
+fset.color_bg = default
+fset.color_bg_inactive = default
+fset.color_delim = cyan
+fset.color_fg = default
+fset.conditions = "${buffer.full_name} == fset.fset"
+fset.filling_left_right = vertical
+fset.filling_top_bottom = horizontal
+fset.hidden = off
+fset.items = "fset"
+fset.position = top
+fset.priority = 0
+fset.separator = on
+fset.size = 3
+fset.size_max = 3
+fset.type = window
+input.color_bg = default
+input.color_bg_inactive = default
+input.color_delim = green
+input.color_fg = default
+input.conditions = ""
+input.filling_left_right = vertical
+input.filling_top_bottom = horizontal
+input.hidden = off
+input.items = "[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
+nicklist.color_bg = default
+nicklist.color_bg_inactive = 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 = on
+nicklist.items = "buffer_nicklist"
+nicklist.position = right
+nicklist.priority = 200
+nicklist.separator = on
+nicklist.size = 0
+nicklist.size_max = 0
+nicklist.type = window
+status.color_bg = green
+status.color_bg_inactive = default
+status.color_delim = 0
+status.color_fg = 0
+status.conditions = ""
+status.filling_left_right = vertical
+status.filling_top_bottom = horizontal
+status.hidden = off
+status.items = "[time],buffer_number+:+buffer_name,buffer_title"
+status.position = bottom
+status.priority = 500
+status.separator = off
+status.size = 1
+status.size_max = 0
+status.type = window
+title.color_bg = green
+title.color_bg_inactive = default
+title.color_delim = cyan
+title.color_fg = 16
+title.conditions = ""
+title.filling_left_right = vertical
+title.filling_top_bottom = horizontal
+title.hidden = on
+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]
+python.slack.10xgenomics.&cloud-alerts-pagerduty = highlight
+python.slack.10xgenomics.&cloud-sumo-prod-support-alerts = highlight
+python.slack.10xgenomics.&lacework-10xdev = highlight
+python.slack.10xgenomics.&lacework-10xprod = highlight
+python.slack.10xgenomics.&testing1234 = highlight
+
+[filter]
+irc_smart = on;*;irc_smart_filter;*
+nicks = on;*;irc_366;*
+
+[key]
+ctrl-? = "/input delete_previous_char"
+ctrl-A = "/input move_beginning_of_line"
+ctrl-B = "/brows"
+ctrl-Cb = "/input insert \x02"
+ctrl-Cc = "/input insert \x03"
+ctrl-Ci = "/input insert \x1D"
+ctrl-Co = "/input insert \x0F"
+ctrl-Cr = "/input insert \x12"
+ctrl-Cu = "/input insert \x15"
+ctrl-D = "/buffer close"
+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 jump_smart"
+ctrl-K = "/input delete_end_of_line"
+ctrl-L = "/window refresh"
+ctrl-M = "/input return"
+ctrl-N = "/buffer +1"
+ctrl-O = "/editor"
+ctrl-P = "/buffer -1"
+ctrl-R = "/input search_text"
+ctrl-Sctrl-U = "/input set_unread"
+ctrl-T = "/input transpose_chars"
+ctrl-U = "/url 1"
+ctrl-W = "/input delete_previous_word"
+ctrl-X = "/input switch_active_buffer"
+ctrl-Y = "/input clipboard_paste"
+meta-meta-OP = "/bar scroll buflist * b"
+meta-meta-OQ = "/bar scroll buflist * e"
+meta-meta2-11~ = "/bar scroll buflist * b"
+meta-meta2-12~ = "/bar scroll buflist * e"
+meta-meta2-1~ = "/window scroll_top"
+meta-meta2-23~ = "/bar scroll nicklist * yb"
+meta-meta2-24~ = "/bar scroll nicklist * ye"
+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 move -1"
+meta-meta2-B = "/buffer move +1"
+meta-meta2-C = "/buffer +1"
+meta-meta2-D = "/buffer -1"
+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-B = "/buflist toggle"
+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-OP = "/bar scroll buflist * -100%"
+meta-OQ = "/bar scroll buflist * +100%"
+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-11^ = "/bar scroll buflist * -100%"
+meta2-11~ = "/bar scroll buflist * -100%"
+meta2-12^ = "/bar scroll buflist * +100%"
+meta2-12~ = "/bar scroll buflist * +100%"
+meta2-15~ = "/bar scroll nicklist * y-100%"
+meta2-17~ = "/bar scroll nicklist * y+100%"
+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;3P = "/bar scroll buflist * b"
+meta2-1;3Q = "/bar scroll buflist * e"
+meta2-1;5A = "/input history_global_previous"
+meta2-1;5B = "/input history_global_next"
+meta2-1;5P = "/bar scroll buflist * -100%"
+meta2-1;5Q = "/bar scroll buflist * +100%"
+meta2-1;9A = "/buffer move -1"
+meta2-1;9B = "/buffer move +1"
+meta2-1~ = "/input move_beginning_of_line"
+meta2-20~ = "/bar scroll title * x-50%"
+meta2-21~ = "/bar scroll title * x+50%"
+meta2-23~ = "/bar scroll nicklist * y-100%"
+meta2-24~ = "/bar scroll nicklist * y+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"
+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-l = "/input jump_last_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-n = "/window scroll_next_highlight"
+meta-p = "/window scroll_previous_highlight"
+meta-r = "/input delete_line"
+meta-u = "/input 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 = "/bar toggle nicklist"
+meta-z = "/window zoom"
+ctrl-_ = "/input undo"
+
+[key_search]
+ctrl-J = "/input search_stop"
+ctrl-M = "/input search_stop"
+ctrl-R = "/input search_switch_case"
+meta2-A = "/input search_previous"
+meta2-B = "/input search_next"
+
+[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"
+@chat(python.*):D = "hsignal:slack_cursor_delete"
+@chat(python.*):L = "hsignal:slack_cursor_linkarchive"
+@chat(python.*):M = "hsignal:slack_cursor_message"
+@chat(python.*):R = "hsignal:slack_cursor_reply"
+@chat(python.*):T = "hsignal:slack_cursor_thread"
+@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(buflist):ctrl-wheeldown = "hsignal:buflist_mouse"
+@bar(buflist):ctrl-wheelup = "hsignal:buflist_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(fset.fset):button1 = "/window ${_window_number};/fset -go ${_chat_line_y}"
+@chat(fset.fset):button2* = "hsignal:fset_mouse"
+@chat(fset.fset):wheeldown = "/fset -down 5"
+@chat(fset.fset):wheelup = "/fset -up 5"
+@chat(python.*):button2 = "hsignal:slack_mouse"
+@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"
+@item(buflist):button1* = "hsignal:buflist_mouse"
+@item(buflist):button2* = "hsignal:buflist_mouse"
+@item(buflist2):button1* = "hsignal:buflist_mouse"
+@item(buflist2):button2* = "hsignal:buflist_mouse"
+@item(buflist3):button1* = "hsignal:buflist_mouse"
+@item(buflist3):button2* = "hsignal:buflist_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:wheeldown = "/window scroll_down -window ${_window_number}"
+@chat:wheelup = "/window scroll_up -window ${_window_number}"
+@*:button3 = "/cursor go ${_x},${_y}"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat-old/xfer.conf	Sat Oct 21 15:01:32 2023 -0400
@@ -0,0 +1,49 @@
+#
+# weechat -- xfer.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[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 = ""
+send_ack = on
+speed_limit_recv = 0
+speed_limit_send = 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"
+download_temporary_suffix = ".part"
+upload_path = "~"
+use_nick_in_filename = on
--- a/weechat/.agignore	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-logs/
-urls.log
Binary file weechat/GandiStandardSSLCA.crt has changed
--- a/weechat/alias.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#
-# weechat -- alias.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[cmd]
-AAWAY = "allserv /away"
-AME = "allchan /me"
-AMSG = "allchan /msg *"
-ANICK = "allserv /nick"
-b = "/buffer"
-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"
-MUB = "unban *"
-N = "names"
-Q = "query"
-REDRAW = "window refresh"
-SAY = "msg *"
-SIGNOFF = "quit"
-T = "topic"
-UB = "unban"
-V = "command core version"
-W = "who"
-WC = "window merge"
-WI = "whois"
-WII = "whois $1 $1"
-WW = "whowas"
-
-[completion]
--- a/weechat/aspell.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#
-# weechat -- aspell.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use /set or similar command to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[color]
-misspelled = lightred
-suggestion = default
-suggestion_delimiter_dict = cyan
-suggestion_delimiter_word = cyan
-
-[check]
-commands = "ame,amsg,away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic"
-default_dict = "en"
-during_search = off
-enabled = off
-real_time = off
-suggestions = -1
-word_min_length = 2
-
-[dict]
-
-[look]
-suggestion_delimiter_dict = " / "
-suggestion_delimiter_word = ","
-
-[option]
--- a/weechat/autosort.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-#
-# weechat -- autosort.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[sorting]
-case_sensitive = off
-debug_log = off
-replacements = "[]"
-rules = "[["core", 0], ["irc", 2], ["*", 1], ["irc.irc_raw", 0], ["irc.server", 1]]"
-signal_delay = 5
-signals = "buffer_opened buffer_merged buffer_unmerged buffer_renamed"
-sort_limit = 100
-sort_on_config_change = on
-
-[v3]
-helpers = "{"core_first": "${if:${buffer.full_name}!=core.weechat}", "irc_raw_first": "${if:${buffer.full_name}!=irc.irc_raw}", "irc_raw_last": "${if:${buffer.full_name}==irc.irc_raw}", "hashless_name": "${info:autosort_replace,#,,${info:autosort_escape,${buffer.name}}}", "script_or_plugin": "${if:${script_name}?${script_name}:${plugin}}"}"
-rules = "["${core_first}", "${info:autosort_order,${info:autosort_escape,${script_or_plugin}},core,*,irc,bitlbee,matrix,slack}", "${script_or_plugin}", "${irc_raw_first}", "${server}", "${info:autosort_order,${type},server,*,channel,private}", "${hashless_name}", "${buffer.full_name}"]"
--- a/weechat/buffers.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-#
-# weechat -- buffers.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use /set or similar command to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[color]
-current_bg = green
-current_fg = black
-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 = green
-hotlist_private_bg = default
-hotlist_private_fg = *magenta
-none_channel_bg = default
-none_channel_fg = 240
-number = green
-number_char = green
-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_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_number = on
-jump_prev_next_visited_buffer = off
-mark_inactive = off
-mouse_move_buffer = 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 = ""
-toogle_bar = on
-whitelist_buffers = ""
--- a/weechat/buflist.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#
-# weechat -- buflist.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[look]
-add_newline = on
-auto_scroll = 50
-display_conditions = "${buffer.hidden}==0"
-enabled = on
-mouse_jump_visited_buffer = off
-mouse_move_buffer = on
-mouse_wheel = on
-nick_prefix = off
-nick_prefix_empty = on
-signals_refresh = ""
-sort = "number,-active"
-use_items = 1
-
-[format]
-buffer = "${format_number}${indent}${format_nick_prefix}${color_hotlist}${format_name}"
-buffer_current = "${color:,blue}${format_buffer}"
-hotlist = " ${color:green}(${hotlist}${color:green})"
-hotlist_highlight = "${color:magenta}"
-hotlist_low = "${color:white}"
-hotlist_message = "${color:green}"
-hotlist_none = "${color:default}"
-hotlist_private = "${color:magenta}"
-hotlist_separator = "${color:default},"
-indent = "  "
-lag = " ${color:green}[${color:brown}${lag}${color:green}]"
-name = "${name}"
-nick_prefix = "${color_nick_prefix}${nick_prefix}"
-number = "${color:green}${number}${if:${number_displayed}?.: }"
-tls_version = " ${color:default}(${if:${tls_version}==TLS1.3?${color:green}:${if:${tls_version}==TLS1.2?${color:yellow}:${color:red}}}${translate:${tls_version}}${color:default})"
--- a/weechat/charset.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#
-# weechat -- charset.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[default]
-decode = "iso-8859-1"
-encode = ""
-
-[decode]
-
-[encode]
--- a/weechat/exec.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#
-# weechat -- exec.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[command]
-default_options = ""
-purge_delay = 0
-shell = "${env:SHELL}"
-
-[color]
-flag_finished = lightred
-flag_running = lightgreen
--- a/weechat/fifo.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#
-# weechat -- fifo.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[file]
-enabled = on
-path = "%h/weechat_fifo"
--- a/weechat/fset.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-#
-# weechat -- fset.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[look]
-auto_refresh = "*"
-auto_unmark = off
-condition_catch_set = "${count} >= 1"
-export_help_default = on
-format_number = 1
-marked_string = "*"
-scroll_horizontal = 10
-show_plugins_desc = off
-sort = "~name"
-unmarked_string = " "
-use_color_value = off
-use_keys = on
-use_mute = off
-
-[format]
-export_help = "# ${description2}"
-export_option = "/set ${name} ${quoted_value}"
-export_option_null = "/unset ${name}"
-option1 = ""
-option2 = "${marked} ${name}  ${type}  ${value2}${newline}  ${empty_name}  ${_default_value}${color:darkgray} -- ${min}..${max}${newline}  ${empty_name}  ${description}"
-
-[color]
-default_value = default
-default_value_selected = white
-description = default
-description_selected = white
-file = default
-file_changed = brown
-file_changed_selected = yellow
-file_selected = white
-help_default_value = white
-help_description = default
-help_name = white
-help_quotes = darkgray
-help_values = default
-index = cyan
-index_selected = lightcyan
-line_marked_bg1 = default
-line_marked_bg2 = default
-line_selected_bg1 = blue
-line_selected_bg2 = red
-marked = brown
-marked_selected = yellow
-max = default
-max_selected = white
-min = default
-min_selected = white
-name = default
-name_changed = brown
-name_changed_selected = yellow
-name_selected = white
-option = default
-option_changed = brown
-option_changed_selected = yellow
-option_selected = white
-parent_name = default
-parent_name_selected = white
-parent_value = cyan
-parent_value_selected = lightcyan
-quotes = darkgray
-quotes_changed = default
-quotes_changed_selected = white
-quotes_selected = default
-section = default
-section_changed = brown
-section_changed_selected = yellow
-section_selected = white
-string_values = default
-string_values_selected = white
-title_count_options = cyan
-title_current_option = lightcyan
-title_filter = yellow
-title_marked_options = lightgreen
-title_sort = white
-type = green
-type_selected = lightgreen
-unmarked = default
-unmarked_selected = white
-value = cyan
-value_changed = brown
-value_changed_selected = yellow
-value_selected = lightcyan
-value_undef = magenta
-value_undef_selected = lightmagenta
Binary file weechat/icon.png has changed
--- a/weechat/logger.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#
-# weechat -- logger.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[look]
-backlog = 20
-backlog_conditions = ""
-
-[color]
-backlog_end = darkgray
-backlog_line = darkgray
-
-[file]
-auto_log = on
-color_lines = off
-flush_delay = 120
-fsync = off
-info_lines = off
-mask = "$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]
-
-[mask]
--- a/weechat/lua.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#
-# weechat -- lua.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use /set or similar command to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[look]
-check_license = off
-eval_keep_context = on
--- a/weechat/perl.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#
-# weechat -- perl.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[look]
-check_license = off
-eval_keep_context = on
--- a/weechat/perl/autoload/colorize_lines.pl	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-#
-# Copyright (c) 2010-2013 by Nils Görs <weechatter@arcor.de>
-# Copyleft (ɔ) 2013 by oakkitten
-#
-# colors the channel text with nick color and also highlight the whole line
-# colorize_nicks.py script will be supported
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-# with version 3.0 some options were renamed or have new possible values:
-# old:                  new:
-# avail_buffer          buffer
-# blacklist_channels    blacklist_buffers
-# highlight             new values
-
-# obsolete options:
-# buffer_autoset
-# hotlist_max_level_nicks_add
-# highlight_regex
-# highlight_words
-# shuffle
-# chat                  see option highlight
-
-# history:
-# 3.0: large part of script rewritten
-#      fix: works nicely with irc colors
-#      improved: highlight_regex and highlight_words work in a natural way
-#      removed: command /colorize_lines
-#      removed: option shuffle
-# 2.2: fix: regex with [tab] in message (patch by sqrrl)
-# 2.1: fix: changing highlight color did not apply messages already displayed (reported by rafi_)
-# 2.0: fix: debugging weechat::print() removed (thanks demure)
-# 1.9: fix: display bug with nick_mode
-# 1.8  add: option "use_irc_colors" (requested by Zertap)
-#      fix: empty char for nick_mode was used, even when "irc.look.nick_mode_empty" was OFF (reported by FlashCode)
-# 1.7: fix: broken lines in dcc chat (reported by equatorping)
-# 1.6: improved: wildcard "*" can be used for server and/or nick. (requested by ldvx)
-#    : add: new value, "only", for option "own_lines" (read help!)
-# 1.5: sync: option weechat.look.nickmode changed in 0.3.9 to "irc.look.nick_mode"
-# 1.4: fix: whole ctcp message was display in prefix (reported by : Mkaysi)
-# 1.3: fix: now using weechat::buffer_get_string() instead of regex to prevent problems with dots inside server-/channelnames (reported by surfhai)
-# 1.2: add: hook_modifier("colorize_lines") to use colorize_lines with another script.
-#    : fix: regex was too greedy and also hit tag "prefix_nick_ccc"
-# 1.1: fix:  problems with temporary server (reported by nand`)
-#    : improved: using weechat_string_has_highlight()
-# 1.0: fix: irc.look.nick_prefix wasn't supported
-# 0.9: added: option "own_nick" (idea by travkin)
-#    : new value (always) for option highlight
-#    : clean up code
-# 0.8.1: fix: regex()
-# 0.8: added: option "avail_buffer" and "nicks" (please read help-page) (suggested by ldvx)
-#    : fix: blacklist_buffers wasn't load at start
-#    : fix: nick_modes wasn't displayed since v0.7
-#    : rewrote init() routine
-#    : thanks to stfn for hint with unescaped variables in regex.
-# 0.7: fix: bug when irc.look.nick_suffix was set (reported and beta-testing by: hw2) (>= weechat 0.3.4)
-#      blacklist_buffers option supports servername
-#      clean up code
-# 0.6: code optimazations.
-#      rename of script (rainbow_text.pl -> colorize_lines.pl) (suggested by xt and flashcode)
-# 0.5: support of hotlist_max_level_nicks_add and weechat.color.chat_nick_colors (>= weechat 0.3.4)
-# 0.4: support of weechat.look.highlight_regex option (>= weechat 0.3.4)
-#    : support of weechat.look.highlight option
-#    : highlighted line did not work with "." inside servername
-#    ; internal "autoset" function fixed
-# 0.3: support of colorize_nicks.py implemented.
-#    : /me text displayed wrong nick colour (colour from suffix was used)
-#    : highlight messages will be checked case insensitiv
-# 0.2: supports highlight_words_add from buffer_autoset.py script (suggested: Emralegna)
-#    : correct look_nickmode colour will be used (bug reported by: Emralegna)
-#    : /me text will be coloured, too
-# 0.1: initial release
-#
-# Development is currently hosted at
-# https://github.com/weechatter/weechat-scripts
-
-# use Data::Dumper
-# $Data::Dumper::Useqq=1;
-
-use strict;
-my $prgname	= "colorize_lines";
-my $version	= "3.0";
-my $description	= "colors text in chat area with according nick color, including highlights";
-
-my %config = ("buffers"             => "all",       # all, channel, query
-              "blacklist_buffers"   => "",          # "a,b,c"
-              "lines"               => "on",
-              "highlight"           => "on",        # on, off, nicks
-              "nicks"               => "",          # "d,e,f", "/file"
-              "own_lines"           => "on",        # on, off, only
-);
-
-my %help_desc = ("buffers"             => "buffer type affected by the script (all/channel/query, default: all)",
-                 "blacklist_buffers"   => "comma-separated list of channels to be ignored (e.g. freenode.#weechat,*.#python)",
-                 "lines"               => "apply nickname color to the non-highlighted lines (off/on/nicks). the latter will limit highlighting to nicknames in option 'nicks'",
-                 "highlight"           => "apply highlight color to the highlighted lines (off/on/nicks). the latter will limit highlighting to nicknames in option 'nicks'",
-                 "nicks"               => "comma-separater list of nicks (e.g. freenode.cat,*.dog) OR file name starting with '/' (e.g. /file.txt). in the latter case, nicknames will get loaded from that file inside weechat folder (e.g. from ~/.weechat/file.txt). nicknames in file are newline-separated (e.g. freenode.dog\\n*.cat)",
-                 "own_lines"           => "apply nickname color to own lines (off/on/only). the latter turns off all other kinds of coloring altogether",
-);
-
-#################################################################################################### config
-
-# program starts here
-sub colorize_cb {
-    my ( $data, $modifier, $modifier_data, $string ) = @_;
-
-    # quit if it's not a privmsg or ctcp
-    # or we are not supposed to
-    if ((index($modifier_data,"irc_privmsg") == -1) ||
-        (index($modifier_data,"irc_ctcp") >= 0)) {
-        return $string;
-    }
-
-    # find buffer pointer
-    $modifier_data =~ m/([^;]*);([^;]*);/;
-    my $buffer = weechat::buffer_search($1, $2);
-    return $string if ($buffer eq "");
-
-    # find buffer name, server name
-    # return if buffer is in a blacklist
-    my $buffername = weechat::buffer_get_string($buffer, "name");
-    return $string if weechat::string_has_highlight($buffername, $config{blacklist_buffers});
-    my $servername = weechat::buffer_get_string($buffer, "localvar_server");
-
-    # find stuff between \t
-    $string =~ m/^([^\t]*)\t(.*)/;
-    my $left = $1;
-    my $right = $2;
-
-    # find nick of the sender
-    # find out if we are doing an action
-    my $nick = ($modifier_data =~ m/(^|,)nick_([^,]*)/) ? $2 : weechat::string_remove_color($left, "");
-    my $action = ($modifier_data =~ m/\birc_action\b/) ? 1 : 0;
-
-    ######################################## get color
-
-    my $color = "";
-    my $my_nick = weechat::buffer_get_string($buffer, "localvar_nick");
-    if ($my_nick eq $nick) {
-        # it's our own line
-        # process only if own_lines is "on" or "only" (i.e. not "off")
-        return $string if ($config{own_lines} eq "off");
-        $color = weechat::color("chat_nick_self");
-    } else {
-        # it's someone else's line
-        # don't process is own_lines are "only"
-        # in order to get correct matching, remove colors from the string
-        return $string if ($config{own_lines} eq "only");
-        my $right_nocolor = weechat::string_remove_color($right, "");
-        if (weechat::string_has_highlight($right_nocolor, weechat::buffer_string_replace_local_var($buffer, weechat::buffer_get_string($buffer, "highlight_words"))) ||
-            weechat::string_has_highlight($right_nocolor, weechat::config_string(weechat::config_get("weechat.look.highlight"))) ||
-            weechat::string_has_highlight_regex($right_nocolor, weechat::config_string(weechat::config_get("weechat.look.highlight_regex"))) ||
-            weechat::string_has_highlight_regex($right_nocolor, weechat::buffer_get_string($buffer, "highlight_regex"))
-           ) {
-            # we have a hilight! get a hilight color
-            # and replace the first occurance of coloring, that'd be nick color
-            # process only if highlight is "on" OR "nicks" & nick's in nicks
-            return $string if ($config{highlight} eq "off" ||
-                ($config{highlight} eq "nicks" && !weechat::string_has_highlight("$servername.$nick", $config{nicks})));
-            $color = weechat::color('chat_highlight');
-            $right =~ s/\31[^\31 ]+?\Q$nick/$color$nick/ if ($action);
-        } else {
-            # that's not a highlight
-            # process only if lines is "on" OR "nicks" & nick's in nicks
-            return $string if ($config{lines} eq "off" ||
-                ($config{lines} eq "nicks" && !weechat::string_has_highlight("$servername.$nick", $config{nicks})));
-            $color = weechat::info_get('irc_nick_color', $nick);
-        }
-    }
-
-    ######################################## inject colors and go!
-
-    my $out = "";
-    if ($action) {
-        # remove the first color reset - after * nick
-        # make other resets reset to our color
-        $right =~ s/\34//;
-        $right =~ s/\34/\34$color/g;
-        $out = $left . "\t" . $right . "\34"
-    } else {
-        # make other resets reset to our color
-        $right =~ s/\34/\34$color/g;
-        $out = $left . "\t" . $color . $right . "\34"
-    }
-    #weechat::print("", ""); weechat::print("", "\$str " . Dumper($string)); weechat::print("", "\$out " . Dumper($out));
-    return $out;
-}
-
-#################################################################################################### config
-
-# read nicknames if $conf{nisks} starts with /
-# after this, $conf{nisks} is of form a,b,c,d
-# if it doesnt start with /, assume it's already a,b,c,d
-sub nicklist_read {
-    return if (substr($config{nicks}, 0, 1) ne "/");
-    my $file = weechat::info_get("weechat_dir", "") . $config{nicks};
-    return unless -e $file;
-    my $nili = "";
-    open (WL, "<", $file) || DEBUG("$file: $!");
-    while (<WL>) {
-        chomp;                                                         # kill LF
-        $nili .= $_ . ",";
-    }
-    close WL;
-    chop $nili;                                                        # remove last ","
-    $config{nicks} = $nili;
-}
-
-# called when a config option ha been changed
-# $name = plugins.var.perl.$prgname.nicks etc
-sub toggle_config_by_set {
-    my ($pointer, $name, $value) = @_;
-    $name = substr($name,length("plugins.var.perl.$prgname."),length($name));
-    $config{$name} = lc($value);
-    nicklist_read() if ($name eq "nicks");
-}
-
-# read configuration from weechat OR
-#   set default options and
-#   set dectription if weechat >= 0.3.5
-# after done, read nicklist from file if needed
-sub init_config {
-    my $weechat_version = weechat::info_get('version_number', '') || 0;
-    foreach my $option (keys %config){
-        if (!weechat::config_is_set_plugin($option)) {
-            weechat::config_set_plugin($option, $config{$option});
-            weechat::config_set_desc_plugin($option, $help_desc{$option}) if ($weechat_version >= 0x00030500); # v0.3.5
-        } else {
-            $config{$option} = lc(weechat::config_get_plugin($option));
-        }
-    }
-    nicklist_read();
-}
-
-#################################################################################################### start
-
-weechat::register($prgname, "Nils Görs <weechatter\@arcor.de>", $version, "GPL3", $description, "", "");
-weechat::hook_modifier("500|weechat_print","colorize_cb", "");
-init_config();
-weechat::hook_config("plugins.var.perl.$prgname.*", "toggle_config_by_set", "");
--- a/weechat/python.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#
-# weechat -- python.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[look]
-check_license = off
-eval_keep_context = on
--- a/weechat/python/autoload/autosort.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../autosort.py
\ No newline at end of file
--- a/weechat/python/autoload/brows.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-import subprocess
-import os
-
-SCRIPT_NAME = 'brows'
-SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION = '1.0'
-SCRIPT_LICENSE = 'MIT/X11'
-SCRIPT_DESC = 'Launch brows to view URLs'
-SCRIPT_COMMAND = 'brows'
-
-import_ok = True
-
-BROWS = os.environ.get('BROWS', 'brows')
-
-try:
-    import weechat
-except ImportError:
-    print('This is a weechat script, what are you doing, run it in weechat, jesus')
-    import_ok = False
-
-weechat_version = 0
-
-def hd(fn, name, obj, attr):
-    return fn(weechat.hdata_get(name), obj, attr)
-
-def hdp(name, obj, attr):
-    return hd(weechat.hdata_pointer, name, obj, attr)
-
-def hds(name, obj, attr):
-    return hd(weechat.hdata_string, name, obj, attr)
-
-def get_lines(buffer, numlines):
-    lines = hdp("buffer", buffer, "own_lines")
-    if not lines:
-        # null pointer wat do
-        return None
-
-    last_lines = []
-
-    line = hdp("lines", lines, "last_line")
-    for _ in range(numlines):
-        if not line:
-            # shit we're at the top of the buffer
-            break
-
-        data = hdp("line", line, "data")
-        msg = hds("line_data", data, "message")
-        msg = weechat.string_remove_color(msg, "")
-
-        last_lines.append(msg.strip())
-
-        line = hdp("line", line, "prev_line")
-
-    return last_lines
-
-def brows(data, buffer, args, numlines=100):
-    lines = get_lines(buffer, numlines)
-
-    proc = subprocess.Popen([BROWS], stdin=subprocess.PIPE)
-    proc.communicate(input='\n'.join(lines))
-    weechat.command("", "/window refresh")
-
-    return weechat.WEECHAT_RC_OK
-
-
-if __name__ == '__main__' and import_ok:
-    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
-                        SCRIPT_LICENSE, SCRIPT_DESC, '', ''):
-        weechat_version = weechat.info_get('version_number', '') or 0
-        weechat.hook_command(
-            SCRIPT_COMMAND,
-            'Launch brows to view URLs',
-            '',
-            '',
-            '',
-            'brows',
-            '')
--- a/weechat/python/autoload/editor.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-import subprocess
-import os
-import tempfile
-
-SCRIPT_NAME = 'editor'
-SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION = '1.0'
-SCRIPT_LICENSE = 'MIT/X11'
-SCRIPT_DESC = 'Launch an external editor to compose a message'
-SCRIPT_COMMAND = 'editor'
-
-import_ok = True
-
-EDITOR = os.environ.get('EDITOR','vim')
-
-try:
-    import weechat
-except ImportError:
-    print('This is a weechat script, what are you doing, run it in weechat, jesus')
-    import_ok = False
-
-weechat_version = 0
-
-
-def get_data(suffix, initial_data):
-    with tempfile.NamedTemporaryFile(suffix=".%s" % suffix, mode="w+") as tf:
-        tf.write(initial_data)
-        tf.flush()
-
-        if subprocess.call([EDITOR, tf.name]) != 0:
-            return None
-
-        # Reopen, because most editors do atomic write-tmp+rename saves which
-        # fucks with Python here.
-        tf.file.close()
-        with open(tf.name) as tf2:
-            return tf2.read()
-
-def editor(data, buffer, args):
-    suffix = args or "tmp"
-
-    line = weechat.buffer_get_string(buffer, "input")
-
-    data = get_data(suffix, line)
-    if data:
-        weechat.command(buffer, "/input delete_line")
-        weechat.command(buffer, data.strip())
-
-    weechat.command("", "/window refresh")
-
-    return weechat.WEECHAT_RC_OK
-
-
-if __name__ == '__main__' and import_ok:
-    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
-                        SCRIPT_LICENSE, SCRIPT_DESC, '', ''):
-        weechat_version = weechat.info_get('version_number', '') or 0
-        weechat.hook_command(
-            SCRIPT_COMMAND,
-            'Open $EDITOR to compose a message',
-            '[file-extension]',
-            'If an argument is given, it will be used as the extension for the temporary file.',
-            '',
-            'editor',
-            '')
--- a/weechat/python/autoload/notify.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-import weechat, subprocess
-
-SCRIPT_NAME = 'notify'
-SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION = '0.0.1'
-SCRIPT_LICENSE = 'MIT'
-SCRIPT_DESC = 'notify-send for weechat'
-
-weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', '')
-
-weechat.hook_print('', 'irc_privmsg', '', 1, 'notify', '')
-
-def _notify(text):
-    subprocess.call(['notify-send', text])
-
-def notify(data, buffer, date, tags, displayed, highlight, prefix, message):
-    # ignore if it's yourself
-    own_nick = weechat.buffer_get_string(buffer, 'localvar_nick')
-
-    if prefix == own_nick or prefix == ('@%s' % own_nick):
-        return weechat.WEECHAT_RC_OK
-
-    if int(highlight):
-        channel = weechat.buffer_get_string(buffer, 'localvar_channel')
-        _notify('%s %s\n%s' % (prefix, channel, message))
-    elif 'notify_private' in tags:
-        _notify('%s [PM]\n%s' % (prefix, message))
-
-    return weechat.WEECHAT_RC_OK
--- a/weechat/python/autoload/quotes.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-import subprocess, os
-
-SCRIPT_NAME = 'quotes'
-SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION = '1.0'
-SCRIPT_LICENSE = 'MIT/X11'
-SCRIPT_DESC = 'Grab quotes and shove them into a text file.'
-SCRIPT_COMMAND = 'quo'
-SCRIPT_COMMAND_LONG = 'quoo'
-SCRIPT_COMMAND_COPY = 'cop'
-
-HOME = os.getenv("HOME")
-QUOTE_FILE = '%s/Dropbox/quotes.txt' % HOME
-COPY_FILE = '%s/.ircopy.irc' % HOME
-
-import_ok = True
-
-try:
-    import weechat
-except ImportError:
-    print('This is a weechat script, what are you doing, run it in weechat, jesus')
-    import_ok = False
-
-weechat_version = 0
-
-def hd(fn, name, obj, attr):
-    return fn(weechat.hdata_get(name), obj, attr)
-
-def hdp(name, obj, attr):
-    return hd(weechat.hdata_pointer, name, obj, attr)
-
-def hds(name, obj, attr):
-    return hd(weechat.hdata_string, name, obj, attr)
-
-def get_lines(buffer, numlines):
-    lines = hdp("buffer", buffer, "own_lines")
-    if not lines:
-        # null pointer wat do
-        return None
-
-    last_lines = []
-
-    line = hdp("lines", lines, "last_line")
-    for _ in range(numlines):
-        if not line:
-            # shit we're at the top of the buffer
-            break
-
-        data = hdp("line", line, "data")
-        msg = hds("line_data", data, "message")
-        pre = hds("line_data", data, "prefix")
-
-        msg = weechat.string_remove_color(msg, "")
-        pre = weechat.string_remove_color(pre, "")
-
-        last_lines.append("<%s> %s" % (pre.strip(), msg.strip()))
-
-        line = hdp("line", line, "prev_line")
-
-    last_lines.reverse()
-    return last_lines
-
-def quote_grab(data, buffer, args, numlines=15):
-    lines = get_lines(buffer, numlines)
-
-    with open(QUOTE_FILE, 'a') as f:
-        f.write("\n---\n")
-        f.write('\n'.join(lines))
-
-    subprocess.call(["nvim", QUOTE_FILE,
-                     # start at the bottom of the file
-                     "+",
-                     # move up N lines, where N is how many we appended
-                     "-c", "normal! %dk" % len(lines)])
-    weechat.command("", "/window refresh")
-
-    return weechat.WEECHAT_RC_OK
-
-def quote_grab_long(data, buffer, args):
-    return quote_grab(data, buffer, args, 75)
-
-def quote_grab_copy(data, buffer, args):
-    lines = get_lines(buffer, 1000)
-
-    with open(COPY_FILE, 'w') as f:
-        f.write('\n'.join(lines))
-
-    subprocess.call(["nvim", COPY_FILE,
-                     # start at the bottom of the file
-                     "+"])
-    weechat.command("", "/window refresh")
-
-    return weechat.WEECHAT_RC_OK
-
-if __name__ == '__main__' and import_ok:
-    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
-                        SCRIPT_LICENSE, SCRIPT_DESC, '', ''):
-        weechat_version = weechat.info_get('version_number', '') or 0
-        weechat.hook_command(
-            SCRIPT_COMMAND,
-            'Appends the last 15 lines of the current buffer to your quotes '
-            'file and opens it in Vim so you can trim it.',
-            '',
-            '',
-            '',
-            'quote_grab',
-            '')
-        weechat.hook_command(
-            SCRIPT_COMMAND_LONG,
-            'Appends the last 75 lines of the current buffer to your quotes '
-            'file and opens it in Vim so you can trim it.',
-            '',
-            '',
-            '',
-            'quote_grab_long',
-            '')
-        weechat.hook_command(
-            SCRIPT_COMMAND_COPY,
-            'Open the last 1000 lines of the file in Vim so you can copy.',
-            '',
-            '',
-            '',
-            'quote_grab_copy',
-            '')
--- a/weechat/python/autoload/urlgrab.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,699 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# UrlGrab, for weechat version >= 0.3.0
-#
-#   Listens to all channels for URLs, collects them in a list, and launches
-#   them in your favourite web server on the local host or a remote server.
-#   Copies url to X11 clipboard via xsel
-#      (http://www.vergenet.net/~conrad/software/xsel)
-#
-# Usage:
-#
-#   The /url command provides access to all UrlGrab functions.  Run
-#   '/help url' for complete command usage.
-#
-#   In general, use '/url list' to list the entire url list for the current
-#   channel, and '/url <n>' to launch the nth url in the list.  For
-#   example, to launch the first (and most-recently added) url in the list,
-#   you would run '/url 1'
-#
-#   From the server window, you must specify a specific channel for the
-#   list and launch commands, for example:
-#     /url list weechat
-#     /url 3 weechat
-#
-# Configuration:
-#
-#   The '/url set' command lets you get and set the following options:
-#
-#   historysize
-#     The maximum number of URLs saved per channel.  Default is 10
-#
-#   method
-#     Must be one of 'local' or 'remote' - Defines how URLs are launched by
-#     the script.  If 'local', the script will run 'localcmd' on the host.
-#     If 'remote', the script will run 'remotessh remotehost remotecmd' on
-#     the local host which should normally use ssh to connect to another
-#     host and run the browser command there.
-#
-#   localcmd
-#     The command to run on the local host to launch URLs in 'local' mode.
-#     The string '%s' will be replaced with the URL.  The default is
-#     'firefox %s'.
-#
-#   remotessh
-#     The command (and arguments) used to connect to the remote host for
-#     'remote' mode.  The default is 'ssh -x' which will connect as the
-#     current username via ssh and disable X11 forwarding.
-#
-#   remotehost
-#     The remote host to which we will connect in 'remote' mode.  For ssh,
-#     this can just be a hostname or 'user@host' to specify a username
-#     other than your current login name.  The default is 'localhost'.
-#
-#   remotecmd
-#     The command to execute on the remote host for 'remote' mode.  The
-#     default is 'bash -c "DISPLAY=:0.0 firefox '%s'"'  Which runs bash, sets
-#     up the environment to display on the remote host's main X display,
-#     and runs firefox.  As with 'localcmd', the string '%s' will be
-#     replaced with the URL.
-#
-#   cmdoutput
-#     The file where the command output (if any) is saved.  Overwritten
-#     each time you launch a new URL.  Default is ~/.weechat/urllaunch.log
-#
-#   default
-#     The command that will be run if no arguemnts to /url are given.
-#     Default is show
-#
-# Requirements:
-#
-#  - Designed to run with weechat version 0.3 or better.
-#      http://www.weechat.org/
-#
-# Acknowlegements:
-#
-#  - Based on an earlier version called 'urlcollector.py' by 'kolter' of
-#    irc.freenode.net/#weechat Honestly, I just cleaned up the code a bit and
-#    made the settings a little more useful (to me).
-#
-#  - With changes by Leonid Evdokimov (weechat at darkk dot net another dot ru):
-#    http://darkk.net.ru/weechat/urlgrab.py
-#    v1.1:  added better handling of dead zombie-childs
-#           added parsing of private messages
-#           added default command setting
-#           added parsing of scrollback buffers on load
-#    v1.2:  `historysize` was ignored
-#
-#  - With changes by ExclusivE (exclusive_tm at mail dot ru):
-#    v1.3: X11 clipboard support
-#
-#  - V1.4 Just ported it over to weechat 0.2.7  drubin AT smartcube dot co dot za
-#  - V1.5  1) I created a logging feature for urls, Time, Date, buffer, and url.
-#           2) Added selectable urls support, similar to the iset plugin (Thanks FlashCode)
-#           3) Colors/formats are configuarable.
-#           4) browser now uses hook_process (Please test with remote clients)
-#           5) Added /url open http://url.com functionality
-#           6) Changed urls detection to use regexpressions so should be much better
-#                Thanks to xt of #weechat bassed on on urlbar.py
-#  - V1.6 FlashCode <flashcode@flashtux.org>: Increase timeout for hook_process
-#         (from 1 second to 1 minute)
-#  - V1.7 FlashCode <flashcode@flashtux.org>: Update WeeChat site
-#  - V1.8 drubin <drubin [at] smartcube . co.za>:
-#           - Changed remote cmd to be single option
-#           - Added scrolling on up and down arrow keys for /url show
-#           - Changed remotecmd to include options with public/private keys password auth doesn't work
-#  - V1.9 Specimen <spinifer [at] gmail . com>:
-#           - Changed the default command when /url is run with no arguments to 'show'
-#           - Removed '/url help' command, because /help <command> is the standard way
-#  - V2.0 Xilov: replace "/url help" by "/help url"
-#  - V2.1 nand: Changed default: firefox %s to firefox '%s' (localcmd)
-#  - V2.2 Sébastien Helleu <flashcode@flashtux.org>: fix reload of config file
-#  - V2.3 nand: Allowed trailing )s for unmatched (s in URLs
-#  - V2.4 nand: Escaped URLs via URL-encoding instead of shell escaping, fixes '
-#  - V2.5 nand: Fixed some URLs that got incorrectly mangled by escaping
-#  - V2.6 nesthib: Fixed escaping of "="
-#                  Added missing quotes in default parameter (firefox '%s')
-#                  Removed the mix of tabs and spaces in the file indentation
-#  - V2.7 dobbymoodge <john.w.lamb [at] gmail . com>
-#                     ( https://github.com/dobbymoodge/ ):
-#           - Added 'copycmd' setting, users can set command to pipe into
-#             for '/url copy'
-#  - V2.8 Simmo Saan <simmo.saan@gmail.com>:
-#           - Changed print hook to ignore filtered lines
-#  - V2.9 Dominik Heidler <dominik@heidler.eu>:
-#           - Updated script for python3 support (now python2 and 3 are both supported)
-#  - V3.0 Sébastien Helleu <flashcode@flashtux.org>:
-#           - Fix python 3 compatibility (replace "has_key" by "in")
-#
-# Copyright (C) 2005 David Rubin <drubin AT smartcube dot co dot za>
-#
-# 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 2
-# 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
-# USA.
-#
-
-from __future__ import print_function
-import sys
-import os
-try:
-    import weechat
-    import_ok = True
-except:
-    print("This script must be run under WeeChat.")
-    print("Get WeeChat now at: http://www.weechat.org/")
-    import_ok = False
-import subprocess
-import time
-try:
-    from urllib import quote
-except ImportError:
-    from urllib.parse import quote
-import re
-try:
-    from UserDict import UserDict
-except ImportError:
-    from collections import UserDict
-
-
-octet = r'(?:2(?:[0-4]\d|5[0-5])|1\d\d|\d{1,2})'
-ipAddr = r'%s(?:\.%s){3}' % (octet, octet)
-# Base domain regex off RFC 1034 and 1738
-label = r'[0-9a-z][-0-9a-z]*[0-9a-z]?'
-domain = r'%s(?:\.%s)*\.[a-z][-0-9a-z]*[a-z]?' % (label, label)
-urlRe = re.compile(r'(\w+://(?:%s|%s)(?::\d+)?(?:/[^\]>\s]*)?)' % (domain, ipAddr), re.I)
-
-
-SCRIPT_NAME    = "urlgrab"
-SCRIPT_AUTHOR  = "David Rubin <drubin [At] smartcube [dot] co [dot] za>"
-SCRIPT_VERSION = "3.0"
-SCRIPT_LICENSE = "GPL"
-SCRIPT_DESC    = "Url functionality Loggin, opening of browser, selectable links"
-CONFIG_FILE_NAME= "urlgrab"
-SCRIPT_COMMAND = "url"
-
-
-def stripParens(url):
-    return dropChar(')', url.count(')') - url.count('('), url[::-1])[::-1]
-
-def dropChar(c, n, xs):
-    if n == 0 or xs == []:
-        return xs
-    elif xs[0] == c:
-        return dropChar(c, n-1, xs[1:])
-    else:
-        return xs
-
-def urlGrabPrint(message):
-    bufferd=weechat.current_buffer()
-    if urlGrabSettings['output_main_buffer'] == 1 :
-        weechat.prnt("","[%s] %s" % ( SCRIPT_NAME, message ) )
-    else :
-        weechat.prnt(bufferd,"[%s] %s" % ( SCRIPT_NAME, message ) )
-
-def hashBufferName(bufferp):
-    if not weechat.buffer_get_string(bufferp, "short_name"):
-        bufferd = weechat.buffer_get_string(bufferp, "name")
-    else:
-        bufferd = weechat.buffer_get_string(bufferp, "short_name")
-    return bufferd
-
-def ug_config_reload_cb(data, config_file):
-    """ Reload configuration file. """
-    return weechat.config_reload(config_file)
-
-class UrlGrabSettings(UserDict):
-    def __init__(self):
-        UserDict.__init__(self)
-        self.data = {}
-        self.config_file = weechat.config_new(CONFIG_FILE_NAME,
-                                        "ug_config_reload_cb", "")
-        if not self.config_file:
-            return
-
-        section_color = weechat.config_new_section(
-            self.config_file, "color", 0, 0, "", "", "", "", "", "",
-                     "", "", "", "")
-        section_default = weechat.config_new_section(
-            self.config_file, "default", 0, 0, "", "", "", "", "", "",
-                     "", "", "", "")
-
-        self.data['color_buffer']=weechat.config_new_option(
-            self.config_file, section_color,
-            "color_buffer", "color", "Color to display buffer name", "", 0, 0,
-            "red", "red", 0, "", "", "", "", "", "")
-
-        self.data['color_url']=weechat.config_new_option(
-            self.config_file, section_color,
-            "color_url", "color", "Color to display urls", "", 0, 0,
-            "blue", "blue", 0, "", "", "", "", "", "")
-
-        self.data['color_time']=weechat.config_new_option(
-            self.config_file, section_color,
-            "color_time", "color", "Color to display time", "", 0, 0,
-            "cyan", "cyan", 0, "", "", "", "", "", "")
-
-        self.data['color_buffer_selected']=weechat.config_new_option(
-            self.config_file, section_color,
-            "color_buffer_selected", "color",
-            "Color to display buffer selected name", "", 0, 0, "red", "red",
-            0, "", "", "", "", "", "")
-
-        self.data['color_url_selected']=weechat.config_new_option(
-            self.config_file, section_color,
-            "color_url_selected", "color", "Color to display url selected",
-             "", 0, 0, "blue", "blue", 0, "", "", "", "", "", "")
-
-        self.data['color_time_selected']=weechat.config_new_option(
-            self.config_file, section_color,
-            "color_time_selected", "color", "Color to display tim selected",
-            "", 0, 0, "cyan", "cyan", 0, "", "", "", "", "", "")
-
-        self.data['color_bg_selected']=weechat.config_new_option(
-            self.config_file, section_color,
-            "color_bg_selected", "color", "Background for selected row", "", 0, 0,
-            "green", "green", 0, "", "", "", "", "", "")
-
-        self.data['historysize']=weechat.config_new_option(
-            self.config_file, section_default,
-            "historysize", "integer", "Max number of urls to store per buffer",
-            "", 0, 999, "10", "10", 0, "", "", "", "", "", "")
-
-        self.data['method']=weechat.config_new_option(
-            self.config_file, section_default,
-            "method", "string", """Where to launch URLs
-            If 'local', runs %localcmd%.
-            If 'remote' runs the following command:
-            '%remodecmd%'""", "", 0, 0,
-            "local", "local", 0, "", "", "", "", "", "")
-
-        self.data['copycmd']=weechat.config_new_option(
-            self.config_file, section_default,
-            "copycmd", "string",
-            "Command to pipe into for 'url copy'. "
-            "E.g. to copy into the CLIPBOARD buffer "
-            "instead of PRIMARY, you can use 'xsel -b "
-            "-i' here.", "", 0, 0,
-            "xsel -i", "xsel -i", 0, "", "", "", "", "", "")
-
-        self.data['localcmd']=weechat.config_new_option(
-            self.config_file, section_default,
-            "localcmd", "string", """Local command to execute""", "", 0, 0,
-            "firefox '%s'", "firefox '%s'", 0, "", "", "", "", "", "")
-
-        remotecmd="ssh -x localhost -i ~/.ssh/id_rsa -C \"export DISPLAY=\":0.0\" &&  firefox '%s'\""
-        self.data['remotecmd']=weechat.config_new_option(
-            self.config_file, section_default,
-            "remotecmd", "string", remotecmd, "", 0, 0,
-            remotecmd, remotecmd, 0, "", "", "", "", "", "")
-
-        self.data['url_log']=weechat.config_new_option(
-            self.config_file, section_default,
-            "url_log", "string", """log location""", "", 0, 0,
-            "~/.weechat/urls.log", "~/.weechat/urls.log", 0, "", "", "", "", "", "")
-
-        self.data['time_format']=weechat.config_new_option(
-            self.config_file, section_default,
-            "time_format", "string", """TIme format""", "", 0, 0,
-            "%H:%M:%S", "%H:%M:%S", 0, "", "", "", "", "", "")
-
-        self.data['output_main_buffer']=weechat.config_new_option(
-            self.config_file, section_default,
-            "output_main_buffer", "boolean",
-            """Print text to main buffer or current one""", "", 0, 0, "1", "1",
-             0, "", "", "", "", "", "")
-        weechat.config_read(self.config_file)
-
-    def __getitem__(self, key):
-        if key == "historysize":
-            return weechat.config_integer(self.data[key])
-        elif key == 'output_main_buffer':
-            return weechat.config_boolean(self.data[key])
-        #elif key.startswith('color'):
-        #    return weechat.config_color(self.data[key])
-        else:
-            return weechat.config_string(self.data[key])
-
-    def prnt(self, name, verbose = True):
-        weechat.prnt( ""," %s = %s" % (name.ljust(11), self.data[name]) )
-
-    def prntall(self):
-        for key in self.names():
-            self.prnt(key, verbose = False)
-
-    def createCmd(self, url):
-        str =""
-        if self['method'] == 'remote':
-            str = self['remotecmd']  % url
-        else:
-            str =  self['localcmd']  % url
-        return str
-
-class UrlGrabber:
-    def __init__(self, historysize):
-        # init
-        self.urls = {}
-        self.globalUrls = []
-        self.historysize = 5
-        # control
-        self.setHistorysize(historysize)
-
-    def setHistorysize(self, count):
-        if count > 1:
-            self.historysize = count
-
-    def getHistorysize(self):
-        return self.historysize
-
-    def addUrl(self, bufferp,url ):
-        global urlGrabSettings
-        self.globalUrls.insert(0,{"buffer":bufferp,
-            "url":url, "time":time.strftime(urlGrabSettings["time_format"])})
-        #Log urls only if we have set a log path.
-        if urlGrabSettings['url_log']:
-            try :
-                index = self.globalUrls[0]
-                logfile = os.path.expanduser(urlGrabSettings['url_log'])
-                dout = open(logfile, "a")
-                dout.write("%s %s %s\n" % (index['time'],
-                                           index['buffer'], index['url']))
-                dout.close()
-            except :
-                print("failed to log url check that %s is valid path" % urlGrabSettings['url_log'])
-                pass
-
-        # check for buffer
-        if not bufferp in self.urls:
-            self.urls[bufferp] = []
-        # add url
-        if url in self.urls[bufferp]:
-            self.urls[bufferp].remove(url)
-        self.urls[bufferp].insert(0, url)
-        # removing old urls
-        while len(self.urls[bufferp]) > self.historysize:
-            self.urls[bufferp].pop()
-
-    def hasIndex( self, bufferp, index ):
-        return bufferp in self.urls and \
-                len(self.url[bufferp]) >= index
-
-    def hasBuffer( self, bufferp ):
-        return bufferp in self.urls
-
-
-    def getUrl(self, bufferp, index):
-        url = ""
-        if  bufferp in self.urls:
-            if len(self.urls[bufferp]) >= index:
-                    url = self.urls[bufferp][index-1]
-        return url
-
-
-    def prnt(self, buff):
-        found = True
-        if buff in self.urls:
-            if len(self.urls[buff]) > 0:
-                i = 1
-                for url in self.urls[buff]:
-                    urlGrabPrint("--> " + str(i) + " : " + url)
-                    i += 1
-            else:
-                found = False
-        elif buff == "*":
-            for b in self.urls.keys():
-              self.prnt(b)
-        else:
-            found = False
-
-        if not found:
-            urlGrabPrint(buff + ": no entries")
-
-def urlGrabCheckMsgline(bufferp, message, isdisplayed):
-    global urlGrab, max_buffer_length
-    if not message or isdisplayed == 0:
-        return
-    # Ignore output from 'tinyurl.py' and our selfs
-    if ( message.startswith( "[AKA] http://tinyurl.com" ) or
-        message.startswith("[urlgrab]") ):
-        return
-    # Check for URLs
-    for url in urlRe.findall(message):
-        urlGrab.addUrl(bufferp,stripParens(url))
-        if max_buffer_length < len(bufferp):
-            max_buffer_length = len(bufferp)
-        if urlgrab_buffer:
-            refresh()
-
-
-def urlGrabCheck(data, bufferp, uber_empty, tagsn, isdisplayed, ishilight, prefix, message):
-    urlGrabCheckMsgline(hashBufferName(bufferp), message, isdisplayed)
-    return weechat.WEECHAT_RC_OK
-
-def urlGrabCopy(bufferd, index):
-    global urlGrab
-    if bufferd == "":
-        urlGrabPrint( "No current channel, you must activate one" )
-    elif not urlGrab.hasBuffer(bufferd):
-        urlGrabPrint("No URL found - Invalid channel")
-    else:
-        if index <= 0:
-            urlGrabPrint("No URL found - Invalid index")
-            return
-        url = urlGrab.getUrl(bufferd,index)
-    if url == "":
-        urlGrabPrint("No URL found - Invalid index")
-    else:
-        try:
-            pipe = os.popen(urlGrabSettings['copycmd'],"w")
-            pipe.write(url)
-            pipe.close()
-            urlGrabPrint("Url: %s gone to clipboard." % url)
-        except:
-            urlGrabPrint("Url: %s failed to copy to clipboard." % url)
-
-def urlGrabOpenUrl(url):
-    global urlGrab, urlGrabSettings
-    argl = urlGrabSettings.createCmd( quote(url, '/:#%?&+=') )
-    weechat.hook_process(argl,60000, "ug_open_cb", "")
-
-def ug_open_cb(data, command, code, out, err):
-    # weechat.prnt("", out)
-    # weechat.prnt("", err)
-    return weechat.WEECHAT_RC_OK
-
-
-def urlGrabOpen(bufferd, index):
-    global urlGrab, urlGrabSettings
-    if bufferd == "":
-        urlGrabPrint( "No current channel, you must specify one" )
-    elif not urlGrab.hasBuffer(bufferd) :
-        urlGrabPrint("No URL found - Invalid channel")
-    else:
-        if index <= 0:
-            urlGrabPrint("No URL found - Invalid index")
-            return
-        url =  urlGrab.getUrl(bufferd,index)
-        if url == "":
-            urlGrabPrint("No URL found - Invalid index")
-        else:
-            urlGrabPrint("loading %s %sly" % (url, urlGrabSettings["method"]))
-            urlGrabOpenUrl (url)
-
-def urlGrabList( args ):
-    global urlGrab
-    if len(args) == 0:
-        buf = hashBufferName(weechat.current_buffer())
-    else:
-        buf = args[0]
-    if buf == "" or buf == "all":
-        buf = "*"
-    urlGrab.prnt(buf)
-
-
-def urlGrabMain(data, bufferp, args):
-    if args[0:2] == "**":
-        keyEvent(data, bufferp, args[2:])
-        return weechat.WEECHAT_RC_OK
-
-    bufferd = hashBufferName(bufferp)
-    largs = args.split(" ")
-    #strip spaces
-    while '' in largs:
-        largs.remove('')
-    while ' ' in largs:
-        largs.remove(' ')
-    if len(largs) == 0 or largs[0] == "show":
-        if not urlgrab_buffer:
-            init()
-        refresh()
-        weechat.buffer_set(urlgrab_buffer, "display", "1")
-    elif largs[0] == 'open' and len(largs) == 2:
-        urlGrabOpenUrl(largs[1])
-    elif largs[0] == 'list':
-        urlGrabList( largs[1:] )
-    elif largs[0] == 'copy':
-        if len(largs) > 1:
-            no = int(largs[1])
-            urlGrabCopy(bufferd, no)
-        else:
-            urlGrabCopy(bufferd,1)
-    else:
-        try:
-            no = int(largs[0])
-            if len(largs) > 1:
-                urlGrabOpen(largs[1], no)
-            else:
-                urlGrabOpen(bufferd, no)
-        except ValueError:
-            #not a valid number so try opening it as a url..
-            for url in urlRe.findall(largs[0]):
-                urlGrabOpenUrl(stripParens(url))
-            urlGrabPrint( "Unknown command '%s'.  Try '/help url' for usage" % largs[0])
-    return weechat.WEECHAT_RC_OK
-
-def buffer_input(*kwargs):
-    return weechat.WEECHAT_RC_OK
-
-def buffer_close(*kwargs):
-    global urlgrab_buffer
-    urlgrab_buffer =  None
-    return weechat.WEECHAT_RC_OK
-
-def keyEvent (data, bufferp, args):
-    global urlGrab , urlGrabSettings, urlgrab_buffer, current_line
-    if args == "refresh":
-        refresh()
-    elif args == "up":
-        if current_line > 0:
-            current_line = current_line -1
-            refresh_line (current_line + 1)
-            refresh_line (current_line)
-            ugCheckLineOutsideWindow()
-    elif args == "down":
-         if current_line < len(urlGrab.globalUrls) - 1:
-            current_line = current_line +1
-            refresh_line (current_line - 1)
-            refresh_line (current_line)
-            ugCheckLineOutsideWindow()
-    elif args == "scroll_top":
-        temp_current = current_line
-        current_line =  0
-        refresh_line (temp_current)
-        refresh_line (current_line)
-        weechat.command(urlgrab_buffer, "/window scroll_top")
-        pass
-    elif args == "scroll_bottom":
-        temp_current = current_line
-        current_line =  len(urlGrab.globalUrls)
-        refresh_line (temp_current)
-        refresh_line (current_line)
-        weechat.command(urlgrab_buffer, "/window scroll_bottom")
-    elif args == "enter":
-        if urlGrab.globalUrls[current_line]:
-            urlGrabOpenUrl (urlGrab.globalUrls[current_line]['url'])
-
-def refresh_line (y):
-    global urlGrab , urlGrabSettings, urlgrab_buffer, current_line, max_buffer_length
-    #Print format  Time(space)buffer(max4 spaces, but lined up)url
-    format = "%%s%%s %%s%%-%ds%%s%%s" % (max_buffer_length+4)
-
-    #non selected colors
-    color_buffer = urlGrabSettings["color_buffer"]
-    color_url = urlGrabSettings["color_url"]
-    color_time =urlGrabSettings["color_time"]
-    #selected colors
-    color_buffer_selected = urlGrabSettings["color_buffer_selected"]
-    color_url_selected = urlGrabSettings["color_url_selected"]
-    color_time_selected = urlGrabSettings["color_time_selected"]
-
-    color_bg_selected = urlGrabSettings["color_bg_selected"]
-
-    color1 = color_time
-    color2 = color_buffer
-    color3 = color_url
-
-    #If this line is selected we change the colors.
-    if y == current_line:
-          color1 = "%s,%s" % (color_time_selected, color_bg_selected)
-          color2 = "%s,%s" % (color_buffer_selected, color_bg_selected)
-          color3 = "%s,%s" % (color_url_selected, color_bg_selected)
-
-    color1 = weechat.color(color1)
-    color2 = weechat.color(color2)
-    color3 = weechat.color(color3)
-    text = format % (color1,
-                    urlGrab.globalUrls[y]['time'],
-                    color2,
-                    urlGrab.globalUrls[y]['buffer'],
-                    color3,
-                    urlGrab.globalUrls[y]['url'] )
-    weechat.prnt_y(urlgrab_buffer,y,text)
-
-def ugCheckLineOutsideWindow():
-    global urlGrab , urlGrabSettings, urlgrab_buffer, current_line, max_buffer_length
-    if (urlgrab_buffer):
-        infolist = weechat.infolist_get("window", "", "current")
-        if (weechat.infolist_next(infolist)):
-            start_line_y = weechat.infolist_integer(infolist, "start_line_y")
-            chat_height = weechat.infolist_integer(infolist, "chat_height")
-            if(start_line_y > current_line):
-                weechat.command(urlgrab_buffer, "/window scroll -%i" %(start_line_y - current_line))
-            elif(start_line_y <= current_line - chat_height):
-                weechat.command(urlgrab_buffer, "/window scroll +%i"%(current_line - start_line_y - chat_height + 1))
-        weechat.infolist_free(infolist)
-
-
-def refresh():
-    global urlGrab
-    y=0
-    for x in urlGrab.globalUrls:
-        refresh_line (y)
-        y += 1
-
-
-def init():
-    global urlGrab , urlGrabSettings, urlgrab_buffer
-    if not urlgrab_buffer:
-        urlgrab_buffer = weechat.buffer_new("urlgrab", "buffer_input", "", "buffer_close", "")
-    if urlgrab_buffer:
-        weechat.buffer_set(urlgrab_buffer, "type", "free")
-        weechat.buffer_set(urlgrab_buffer, "key_bind_ctrl-R",        "/url **refresh")
-        weechat.buffer_set(urlgrab_buffer, "key_bind_meta2-A",       "/url **up")
-        weechat.buffer_set(urlgrab_buffer, "key_bind_meta2-B",       "/url **down")
-        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-ctrl-J",   "/url **enter")
-        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-ctrl-M",   "/url **enter")
-        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-meta2-1./~", "/url **scroll_top")
-        weechat.buffer_set(urlgrab_buffer, "key_bind_meta-meta2-4~", "/url **scroll_bottom")
-        weechat.buffer_set(urlgrab_buffer, "title","Lists the urls in the applications")
-        weechat.buffer_set(urlgrab_buffer, "display", "1")
-
-def completion_urls_cb(data, completion_item, bufferp, completion):
-    """ Complete with URLS, for command '/url'. """
-    global urlGrab
-    bufferd = hashBufferName( bufferp)
-    for url in urlGrab.globalUrls :
-        if url['buffer'] == bufferd:
-            weechat.hook_completion_list_add(completion, url['url'], 0, weechat.WEECHAT_LIST_POS_SORT)
-    return weechat.WEECHAT_RC_OK
-
-def ug_unload_script():
-    """ Function called when script is unloaded. """
-    global urlGrabSettings
-    weechat.config_write(urlGrabSettings.config_file)
-    return weechat.WEECHAT_RC_OK
-
-#Main stuff
-if ( import_ok and
-    weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
-        SCRIPT_LICENSE,SCRIPT_DESC, "ug_unload_script", "") ):
-    urlgrab_buffer = None
-    current_line = 0
-    max_buffer_length = 0
-    urlGrabSettings = UrlGrabSettings()
-    urlGrab = UrlGrabber( urlGrabSettings['historysize'])
-    weechat.hook_print("", "", "", 1, "urlGrabCheck", "")
-    weechat.hook_command(SCRIPT_COMMAND,
-                             "Url Grabber",
-                             "[open <url> | <url> | show | copy [n] | [n] | list]",
-                             "open or <url>: opens the url\n"
-                             "show: Opens the select buffer to allow for url selection\n"
-                             "copy: Copies the nth url to the system clipboard\n"
-                             "list: Lists the urls in the current buffer\n",
-                             "open %(urlgrab_urls) || %(urlgrab_urls) || "
-                             "copy || show || list",
-                             "urlGrabMain", "")
-    weechat.hook_completion("urlgrab_urls", "list of URLs",
-                                "completion_urls_cb", "")
-else:
-    print("failed to load weechat")
--- a/weechat/python/autoload/wee_slack.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-/home/sjl/src/wee-slack/wee_slack.py
\ No newline at end of file
--- a/weechat/python/autosort.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1075 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2013-2017 Maarten de Vries <maarten@de-vri.es>
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-
-#
-# Autosort automatically keeps your buffers sorted and grouped by server.
-# You can define your own sorting rules. See /help autosort for more details.
-#
-# https://github.com/de-vri-es/weechat-autosort
-#
-
-#
-# Changelog:
-# 3.9:
-#   * Remove `buffers.pl` from recommended settings.
-# 3,8:
-#   * Fix relative sorting on script name in default rules.
-#   * Document a useful property of stable sort algorithms.
-# 3.7:
-#   * Make default rules work with bitlbee, matrix and slack.
-# 3.6:
-#   * Add more documentation on provided info hooks.
-# 3.5:
-#   * Add ${info:autosort_escape,...} to escape arguments for other info hooks.
-# 3.4:
-#   * Fix rate-limit of sorting to prevent high CPU load and lock-ups.
-#   * Fix bug in parsing empty arguments for info hooks.
-#   * Add debug_log option to aid with debugging.
-#   * Correct a few typos.
-# 3.3:
-#   * Fix the /autosort debug command for unicode.
-#   * Update the default rules to work better with Slack.
-# 3.2:
-#   * Fix python3 compatiblity.
-# 3.1:
-#   * Use colors to format the help text.
-# 3.0:
-#   * Switch to evaluated expressions for sorting.
-#   * Add `/autosort debug` command.
-#   * Add ${info:autosort_replace,from,to,text} to replace substrings in sort rules.
-#   * Add ${info:autosort_order,value,first,second,third} to ease writing sort rules.
-#   * Make tab completion context aware.
-# 2.8:
-#   * Fix compatibility with python 3 regarding unicode handling.
-# 2.7:
-#   * Fix sorting of buffers with spaces in their name.
-# 2.6:
-#   * Ignore case in rules when doing case insensitive sorting.
-# 2.5:
-#   * Fix handling unicode buffer names.
-#   * Add hint to set irc.look.server_buffer to independent and buffers.look.indenting to on.
-# 2.4:
-#   * Make script python3 compatible.
-# 2.3:
-#   * Fix sorting items without score last (regressed in 2.2).
-# 2.2:
-#   * Add configuration option for signals that trigger a sort.
-#   * Add command to manually trigger a sort (/autosort sort).
-#   * Add replacement patterns to apply before sorting.
-# 2.1:
-#   * Fix some minor style issues.
-# 2.0:
-#   * Allow for custom sort rules.
-#
-
-
-import json
-import math
-import re
-import sys
-import time
-import weechat
-
-SCRIPT_NAME     = 'autosort'
-SCRIPT_AUTHOR   = 'Maarten de Vries <maarten@de-vri.es>'
-SCRIPT_VERSION  = '3.9'
-SCRIPT_LICENSE  = 'GPL3'
-SCRIPT_DESC     = 'Flexible automatic (or manual) buffer sorting based on eval expressions.'
-
-
-config             = None
-hooks              = []
-signal_delay_timer = None
-sort_limit_timer   = None
-sort_queued        = False
-
-
-# Make sure that unicode, bytes and str are always available in python2 and 3.
-# For python 2, str == bytes
-# For python 3, str == unicode
-if sys.version_info[0] >= 3:
-	unicode = str
-
-def ensure_str(input):
-	'''
-	Make sure the given type if the correct string type for the current python version.
-	That means bytes for python2 and unicode for python3.
-	'''
-	if not isinstance(input, str):
-		if isinstance(input, bytes):
-			return input.encode('utf-8')
-		if isinstance(input, unicode):
-			return input.decode('utf-8')
-	return input
-
-
-if hasattr(time, 'perf_counter'):
-	perf_counter = time.perf_counter
-else:
-	perf_counter = time.clock
-
-def casefold(string):
-	if hasattr(string, 'casefold'): return string.casefold()
-	# Fall back to lowercasing for python2.
-	return string.lower()
-
-def list_swap(values, a, b):
-	values[a], values[b] = values[b], values[a]
-
-def list_move(values, old_index, new_index):
-	values.insert(new_index, values.pop(old_index))
-
-def list_find(collection, value):
-	for i, elem in enumerate(collection):
-		if elem == value: return i
-	return None
-
-class HumanReadableError(Exception):
-	pass
-
-def parse_int(arg, arg_name = 'argument'):
-	''' Parse an integer and provide a more human readable error. '''
-	arg = arg.strip()
-	try:
-		return int(arg)
-	except ValueError:
-		raise HumanReadableError('Invalid {0}: expected integer, got "{1}".'.format(arg_name, arg))
-
-def decode_rules(blob):
-	parsed = json.loads(blob)
-	if not isinstance(parsed, list):
-		log('Malformed rules, expected a JSON encoded list of strings, but got a {0}. No rules have been loaded. Please fix the setting manually.'.format(type(parsed)))
-		return []
-
-	for i, entry in enumerate(parsed):
-		if not isinstance(entry, (str, unicode)):
-			log('Rule #{0} is not a string but a {1}. No rules have been loaded. Please fix the setting manually.'.format(i, type(entry)))
-			return []
-
-	return parsed
-
-def decode_helpers(blob):
-	parsed = json.loads(blob)
-	if not isinstance(parsed, dict):
-		log('Malformed helpers, expected a JSON encoded dictionary but got a {0}. No helpers have been loaded. Please fix the setting manually.'.format(type(parsed)))
-		return {}
-
-	for key, value in parsed.items():
-		if not isinstance(value, (str, unicode)):
-			log('Helper "{0}" is not a string but a {1}. No helpers have been loaded. Please fix setting manually.'.format(key, type(value)))
-			return {}
-	return parsed
-
-class Config:
-	''' The autosort configuration. '''
-
-	default_rules = json.dumps([
-		'${core_first}',
-		'${info:autosort_order,${info:autosort_escape,${script_or_plugin}},core,*,irc,bitlbee,matrix,slack}',
-		'${script_or_plugin}',
-		'${irc_raw_first}',
-		'${server}',
-		'${info:autosort_order,${type},server,*,channel,private}',
-		'${hashless_name}',
-		'${buffer.full_name}',
-	])
-
-	default_helpers = json.dumps({
-		'core_first':       '${if:${buffer.full_name}!=core.weechat}',
-		'irc_raw_first':    '${if:${buffer.full_name}!=irc.irc_raw}',
-		'irc_raw_last':     '${if:${buffer.full_name}==irc.irc_raw}',
-		'hashless_name':    '${info:autosort_replace,#,,${info:autosort_escape,${buffer.name}}}',
-		'script_or_plugin': '${if:${script_name}?${script_name}:${plugin}}',
-	})
-
-	default_signal_delay = 5
-	default_sort_limit   = 100
-
-	default_signals = 'buffer_opened buffer_merged buffer_unmerged buffer_renamed'
-
-	def __init__(self, filename):
-		''' Initialize the configuration. '''
-
-		self.filename         = filename
-		self.config_file      = weechat.config_new(self.filename, '', '')
-		self.sorting_section  = None
-		self.v3_section       = None
-
-		self.case_sensitive   = False
-		self.rules            = []
-		self.helpers          = {}
-		self.signals          = []
-		self.signal_delay     = Config.default_signal_delay,
-		self.sort_limit       = Config.default_sort_limit,
-		self.sort_on_config   = True
-		self.debug_log        = False
-
-		self.__case_sensitive = None
-		self.__rules          = None
-		self.__helpers        = None
-		self.__signals        = None
-		self.__signal_delay   = None
-		self.__sort_limit     = None
-		self.__sort_on_config = None
-		self.__debug_log      = None
-
-		if not self.config_file:
-			log('Failed to initialize configuration file "{0}".'.format(self.filename))
-			return
-
-		self.sorting_section = weechat.config_new_section(self.config_file, 'sorting', False, False, '', '', '', '', '', '', '', '', '', '')
-		self.v3_section      = weechat.config_new_section(self.config_file, 'v3',      False, False, '', '', '', '', '', '', '', '', '', '')
-
-		if not self.sorting_section:
-			log('Failed to initialize section "sorting" of configuration file.')
-			weechat.config_free(self.config_file)
-			return
-
-		self.__case_sensitive = weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'case_sensitive', 'boolean',
-			'If this option is on, sorting is case sensitive.',
-			'', 0, 0, 'off', 'off', 0,
-			'', '', '', '', '', ''
-		)
-
-		weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'rules', 'string',
-			'Sort rules used by autosort v2.x and below. Not used by autosort anymore.',
-			'', 0, 0, '', '', 0,
-			'', '', '', '', '', ''
-		)
-
-		weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'replacements', 'string',
-			'Replacement patterns used by autosort v2.x and below. Not used by autosort anymore.',
-			'', 0, 0, '', '', 0,
-			'', '', '', '', '', ''
-		)
-
-		self.__rules = weechat.config_new_option(
-			self.config_file, self.v3_section,
-			'rules', 'string',
-			'An ordered list of sorting rules encoded as JSON. See /help autosort for commands to manipulate these rules.',
-			'', 0, 0, Config.default_rules, Config.default_rules, 0,
-			'', '', '', '', '', ''
-		)
-
-		self.__helpers = weechat.config_new_option(
-			self.config_file, self.v3_section,
-			'helpers', 'string',
-			'A dictionary helper variables to use in the sorting rules, encoded as JSON. See /help autosort for commands to manipulate these helpers.',
-			'', 0, 0, Config.default_helpers, Config.default_helpers, 0,
-			'', '', '', '', '', ''
-		)
-
-		self.__signals = weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'signals', 'string',
-			'A space separated list of signals that will cause autosort to resort your buffer list.',
-			'', 0, 0, Config.default_signals, Config.default_signals, 0,
-			'', '', '', '', '', ''
-		)
-
-		self.__signal_delay = weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'signal_delay', 'integer',
-			'Delay in milliseconds to wait after a signal before sorting the buffer list. This prevents triggering many times if multiple signals arrive in a short time. It can also be needed to wait for buffer localvars to be available.',
-			'', 0, 1000, str(Config.default_signal_delay), str(Config.default_signal_delay), 0,
-			'', '', '', '', '', ''
-		)
-
-		self.__sort_limit = weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'sort_limit', 'integer',
-			'Minimum delay in milliseconds to wait after sorting before signals can trigger a sort again. This is effectively a rate limit on sorting. Keeping signal_delay low while setting this higher can reduce excessive sorting without a long initial delay.',
-			'', 0, 1000, str(Config.default_sort_limit), str(Config.default_sort_limit), 0,
-			'', '', '', '', '', ''
-		)
-
-		self.__sort_on_config = weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'sort_on_config_change', 'boolean',
-			'Decides if the buffer list should be sorted when autosort configuration changes.',
-			'', 0, 0, 'on', 'on', 0,
-			'', '', '', '', '', ''
-		)
-
-		self.__debug_log = weechat.config_new_option(
-			self.config_file, self.sorting_section,
-			'debug_log', 'boolean',
-			'If enabled, print more debug messages. Not recommended for normal usage.',
-			'', 0, 0, 'off', 'off', 0,
-			'', '', '', '', '', ''
-		)
-
-		if weechat.config_read(self.config_file) != weechat.WEECHAT_RC_OK:
-			log('Failed to load configuration file.')
-
-		if weechat.config_write(self.config_file) != weechat.WEECHAT_RC_OK:
-			log('Failed to write configuration file.')
-
-		self.reload()
-
-	def reload(self):
-		''' Load configuration variables. '''
-
-		self.case_sensitive = weechat.config_boolean(self.__case_sensitive)
-
-		rules_blob    = weechat.config_string(self.__rules)
-		helpers_blob  = weechat.config_string(self.__helpers)
-		signals_blob  = weechat.config_string(self.__signals)
-
-		self.rules          = decode_rules(rules_blob)
-		self.helpers        = decode_helpers(helpers_blob)
-		self.signals        = signals_blob.split()
-		self.signal_delay   = weechat.config_integer(self.__signal_delay)
-		self.sort_limit     = weechat.config_integer(self.__sort_limit)
-		self.sort_on_config = weechat.config_boolean(self.__sort_on_config)
-		self.debug_log      = weechat.config_boolean(self.__debug_log)
-
-	def save_rules(self, run_callback = True):
-		''' Save the current rules to the configuration. '''
-		weechat.config_option_set(self.__rules, json.dumps(self.rules), run_callback)
-
-	def save_helpers(self, run_callback = True):
-		''' Save the current helpers to the configuration. '''
-		weechat.config_option_set(self.__helpers, json.dumps(self.helpers), run_callback)
-
-
-def pad(sequence, length, padding = None):
-	''' Pad a list until is has a certain length. '''
-	return sequence + [padding] * max(0, (length - len(sequence)))
-
-def log(message, buffer = 'NULL'):
-	weechat.prnt(buffer, 'autosort: {0}'.format(message))
-
-def debug(message, buffer = 'NULL'):
-	if config.debug_log:
-		weechat.prnt(buffer, 'autosort: debug: {0}'.format(message))
-
-def get_buffers():
-	''' Get a list of all the buffers in weechat. '''
-	hdata  = weechat.hdata_get('buffer')
-	buffer = weechat.hdata_get_list(hdata, "gui_buffers");
-
-	result = []
-	while buffer:
-		number = weechat.hdata_integer(hdata, buffer, 'number')
-		result.append((number, buffer))
-		buffer = weechat.hdata_pointer(hdata, buffer, 'next_buffer')
-	return hdata, result
-
-class MergedBuffers(list):
-	""" A list of merged buffers, possibly of size 1. """
-	def __init__(self, number):
-		super(MergedBuffers, self).__init__()
-		self.number = number
-
-def merge_buffer_list(buffers):
-	'''
-	Group merged buffers together.
-	The output is a list of MergedBuffers.
-	'''
-	if not buffers: return []
-	result = {}
-	for number, buffer in buffers:
-		if number not in result: result[number] = MergedBuffers(number)
-		result[number].append(buffer)
-	return result.values()
-
-def sort_buffers(hdata, buffers, rules, helpers, case_sensitive):
-	for merged in buffers:
-		for buffer in merged:
-			name = weechat.hdata_string(hdata, buffer, 'name')
-
-	return sorted(buffers, key=merged_sort_key(rules, helpers, case_sensitive))
-
-def buffer_sort_key(rules, helpers, case_sensitive):
-	''' Create a sort key function for a list of lists of merged buffers. '''
-	def key(buffer):
-		extra_vars = {}
-		for helper_name, helper in sorted(helpers.items()):
-			expanded = weechat.string_eval_expression(helper, {"buffer": buffer}, {}, {})
-			extra_vars[helper_name] = expanded if case_sensitive else casefold(expanded)
-		result = []
-		for rule in rules:
-			expanded = weechat.string_eval_expression(rule, {"buffer": buffer}, extra_vars, {})
-			result.append(expanded if case_sensitive else casefold(expanded))
-		return result
-
-	return key
-
-def merged_sort_key(rules, helpers, case_sensitive):
-	buffer_key = buffer_sort_key(rules, helpers, case_sensitive)
-	def key(merged):
-		best = None
-		for buffer in merged:
-			this = buffer_key(buffer)
-			if best is None or this < best: best = this
-		return best
-	return key
-
-def apply_buffer_order(buffers):
-	''' Sort the buffers in weechat according to the given order. '''
-	for i, buffer in enumerate(buffers):
-		weechat.buffer_set(buffer[0], "number", str(i + 1))
-
-def split_args(args, expected, optional = 0):
-	''' Split an argument string in the desired number of arguments. '''
-	split = args.split(' ', expected - 1)
-	if (len(split) < expected):
-		raise HumanReadableError('Expected at least {0} arguments, got {1}.'.format(expected, len(split)))
-	return split[:-1] + pad(split[-1].split(' ', optional), optional + 1, '')
-
-def do_sort(verbose = False):
-	start = perf_counter()
-
-	hdata, buffers = get_buffers()
-	buffers = merge_buffer_list(buffers)
-	buffers = sort_buffers(hdata, buffers, config.rules, config.helpers, config.case_sensitive)
-	apply_buffer_order(buffers)
-
-	elapsed = perf_counter() - start
-	if verbose:
-		log("Finished sorting buffers in {0:.4f} seconds.".format(elapsed))
-	else:
-		debug("Finished sorting buffers in {0:.4f} seconds.".format(elapsed))
-
-def command_sort(buffer, command, args):
-	''' Sort the buffers and print a confirmation. '''
-	do_sort(True)
-	return weechat.WEECHAT_RC_OK
-
-def command_debug(buffer, command, args):
-	hdata, buffers = get_buffers()
-	buffers = merge_buffer_list(buffers)
-
-	# Show evaluation results.
-	log('Individual evaluation results:')
-	start = perf_counter()
-	key = buffer_sort_key(config.rules, config.helpers, config.case_sensitive)
-	results = []
-	for merged in buffers:
-		for buffer in merged:
-			fullname = weechat.hdata_string(hdata, buffer, 'full_name')
-			results.append((fullname, key(buffer)))
-	elapsed = perf_counter() - start
-
-	for fullname, result in results:
-		fullname = ensure_str(fullname)
-		result = [ensure_str(x) for x in result]
-		log('{0}: {1}'.format(fullname, result))
-	log('Computing evaluation results took {0:.4f} seconds.'.format(elapsed))
-
-	return weechat.WEECHAT_RC_OK
-
-def command_rule_list(buffer, command, args):
-	''' Show the list of sorting rules. '''
-	output = 'Sorting rules:\n'
-	for i, rule in enumerate(config.rules):
-		output += '    {0}: {1}\n'.format(i, rule)
-	if not len(config.rules):
-		output += '    No sorting rules configured.\n'
-	log(output )
-
-	return weechat.WEECHAT_RC_OK
-
-
-def command_rule_add(buffer, command, args):
-	''' Add a rule to the rule list. '''
-	config.rules.append(args)
-	config.save_rules()
-	command_rule_list(buffer, command, '')
-
-	return weechat.WEECHAT_RC_OK
-
-
-def command_rule_insert(buffer, command, args):
-	''' Insert a rule at the desired position in the rule list. '''
-	index, rule = split_args(args, 2)
-	index = parse_int(index, 'index')
-
-	config.rules.insert(index, rule)
-	config.save_rules()
-	command_rule_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-
-def command_rule_update(buffer, command, args):
-	''' Update a rule in the rule list. '''
-	index, rule = split_args(args, 2)
-	index = parse_int(index, 'index')
-
-	config.rules[index] = rule
-	config.save_rules()
-	command_rule_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-
-def command_rule_delete(buffer, command, args):
-	''' Delete a rule from the rule list. '''
-	index = args.strip()
-	index = parse_int(index, 'index')
-
-	config.rules.pop(index)
-	config.save_rules()
-	command_rule_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-
-def command_rule_move(buffer, command, args):
-	''' Move a rule to a new position. '''
-	index_a, index_b = split_args(args, 2)
-	index_a = parse_int(index_a, 'index')
-	index_b = parse_int(index_b, 'index')
-
-	list_move(config.rules, index_a, index_b)
-	config.save_rules()
-	command_rule_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-
-def command_rule_swap(buffer, command, args):
-	''' Swap two rules. '''
-	index_a, index_b = split_args(args, 2)
-	index_a = parse_int(index_a, 'index')
-	index_b = parse_int(index_b, 'index')
-
-	list_swap(config.rules, index_a, index_b)
-	config.save_rules()
-	command_rule_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-
-def command_helper_list(buffer, command, args):
-	''' Show the list of helpers. '''
-	output = 'Helper variables:\n'
-
-	width = max(map(lambda x: len(x) if len(x) <= 30 else 0, config.helpers.keys()))
-
-	for name, expression in sorted(config.helpers.items()):
-		output += '    {0:>{width}}: {1}\n'.format(name, expression, width=width)
-	if not len(config.helpers):
-		output += '    No helper variables configured.'
-	log(output)
-
-	return weechat.WEECHAT_RC_OK
-
-
-def command_helper_set(buffer, command, args):
-	''' Add/update a helper to the helper list. '''
-	name, expression = split_args(args, 2)
-
-	config.helpers[name] = expression
-	config.save_helpers()
-	command_helper_list(buffer, command, '')
-
-	return weechat.WEECHAT_RC_OK
-
-def command_helper_delete(buffer, command, args):
-	''' Delete a helper from the helper list. '''
-	name = args.strip()
-
-	del config.helpers[name]
-	config.save_helpers()
-	command_helper_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-
-def command_helper_rename(buffer, command, args):
-	''' Rename a helper to a new position. '''
-	old_name, new_name = split_args(args, 2)
-
-	try:
-		config.helpers[new_name] = config.helpers[old_name]
-		del config.helpers[old_name]
-	except KeyError:
-		raise HumanReadableError('No such helper: {0}'.format(old_name))
-	config.save_helpers()
-	command_helper_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-
-def command_helper_swap(buffer, command, args):
-	''' Swap two helpers. '''
-	a, b = split_args(args, 2)
-	try:
-		config.helpers[b], config.helpers[a] = config.helpers[a], config.helpers[b]
-	except KeyError as e:
-		raise HumanReadableError('No such helper: {0}'.format(e.args[0]))
-
-	config.helpers.swap(index_a, index_b)
-	config.save_helpers()
-	command_helper_list(buffer, command, '')
-	return weechat.WEECHAT_RC_OK
-
-def call_command(buffer, command, args, subcommands):
-	''' Call a subcommand from a dictionary. '''
-	subcommand, tail = pad(args.split(' ', 1), 2, '')
-	subcommand = subcommand.strip()
-	if (subcommand == ''):
-		child   = subcommands.get(' ')
-	else:
-		command = command + [subcommand]
-		child   = subcommands.get(subcommand)
-
-	if isinstance(child, dict):
-		return call_command(buffer, command, tail, child)
-	elif callable(child):
-		return child(buffer, command, tail)
-
-	log('{0}: command not found'.format(' '.join(command)))
-	return weechat.WEECHAT_RC_ERROR
-
-def on_signal(data, signal, signal_data):
-	global signal_delay_timer
-	global sort_queued
-
-	# If the sort limit timeout is started, we're in the hold-off time after sorting, just queue a sort.
-	if sort_limit_timer is not None:
-		if sort_queued:
-			debug('Signal {0} ignored, sort limit timeout is active and sort is already queued.'.format(signal))
-		else:
-			debug('Signal {0} received but sort limit timeout is active, sort is now queued.'.format(signal))
-		sort_queued = True
-		return weechat.WEECHAT_RC_OK
-
-	# If the signal delay timeout is started, a signal was recently received, so ignore this signal.
-	if signal_delay_timer is not None:
-		debug('Signal {0} ignored, signal delay timeout active.'.format(signal))
-		return weechat.WEECHAT_RC_OK
-
-	# Otherwise, start the signal delay timeout.
-	debug('Signal {0} received, starting signal delay timeout of {1} ms.'.format(signal, config.signal_delay))
-	weechat.hook_timer(config.signal_delay, 0, 1, "on_signal_delay_timeout", "")
-	return weechat.WEECHAT_RC_OK
-
-def on_signal_delay_timeout(pointer, remaining_calls):
-	""" Called when the signal_delay_timer triggers. """
-	global signal_delay_timer
-	global sort_limit_timer
-	global sort_queued
-
-	signal_delay_timer = None
-
-	# If the sort limit timeout was started, we're still in the no-sort period, so just queue a sort.
-	if sort_limit_timer is not None:
-		debug('Signal delay timeout expired, but sort limit timeout is active, sort is now queued.')
-		sort_queued = True
-		return weechat.WEECHAT_RC_OK
-
-	# Time to sort!
-	debug('Signal delay timeout expired, starting sort.')
-	do_sort()
-
-	# Start the sort limit timeout if not disabled.
-	if config.sort_limit > 0:
-		debug('Starting sort limit timeout of {0} ms.'.format(config.sort_limit))
-		sort_limit_timer = weechat.hook_timer(config.sort_limit, 0, 1, "on_sort_limit_timeout", "")
-
-	return weechat.WEECHAT_RC_OK
-
-def on_sort_limit_timeout(pointer, remainin_calls):
-	""" Called when de sort_limit_timer triggers. """
-	global sort_limit_timer
-	global sort_queued
-
-	# If no signal was received during the timeout, we're done.
-	if not sort_queued:
-		debug('Sort limit timeout expired without receiving a signal.')
-		sort_limit_timer = None
-		return weechat.WEECHAT_RC_OK
-
-	# Otherwise it's time to sort.
-	debug('Signal received during sort limit timeout, starting queued sort.')
-	do_sort()
-	sort_queued = False
-
-	# Start the sort limit timeout again if not disabled.
-	if config.sort_limit > 0:
-		debug('Starting sort limit timeout of {0} ms.'.format(config.sort_limit))
-		sort_limit_timer = weechat.hook_timer(config.sort_limit, 0, 1, "on_sort_limit_timeout", "")
-
-	return weechat.WEECHAT_RC_OK
-
-
-def apply_config():
-	# Unhook all signals and hook the new ones.
-	for hook in hooks:
-		weechat.unhook(hook)
-	for signal in config.signals:
-		hooks.append(weechat.hook_signal(signal, 'on_signal', ''))
-
-	if config.sort_on_config:
-		debug('Sorting because configuration changed.')
-		do_sort()
-
-def on_config_changed(*args, **kwargs):
-	''' Called whenever the configuration changes. '''
-	config.reload()
-	apply_config()
-
-	return weechat.WEECHAT_RC_OK
-
-def parse_arg(args):
-	if not args: return '', None
-
-	result  = ''
-	escaped = False
-	for i, c in enumerate(args):
-		if not escaped:
-			if c == '\\':
-				escaped = True
-				continue
-			elif c == ',':
-				return result, args[i+1:]
-		result  += c
-		escaped  = False
-	return result, None
-
-def parse_args(args, max = None):
-	result = []
-	i = 0
-	while max is None or i < max:
-		i += 1
-		arg, args = parse_arg(args)
-		if arg is None: break
-		result.append(arg)
-		if args is None: break
-	return result, args
-
-def on_info_escape(pointer, name, arguments):
-	result = ''
-	for c in arguments:
-		if c == '\\':
-			result += '\\\\'
-		elif c == ',':
-			result += '\\,'
-		else:
-			result +=c
-	return result
-
-def on_info_replace(pointer, name, arguments):
-	arguments, rest = parse_args(arguments, 3)
-	if rest or len(arguments) < 3:
-		log('usage: ${{info:{0},old,new,text}}'.format(name))
-		return ''
-	old, new, text = arguments
-
-	return text.replace(old, new)
-
-def on_info_order(pointer, name, arguments):
-	arguments, rest = parse_args(arguments)
-	if len(arguments) < 1:
-		log('usage: ${{info:{0},value,first,second,third,...}}'.format(name))
-		return ''
-
-	value = arguments[0]
-	keys  = arguments[1:]
-	if not keys: return '0'
-
-	# Find the value in the keys (or '*' if we can't find it)
-	result = list_find(keys, value)
-	if result is None: result = list_find(keys, '*')
-	if result is None: result = len(keys)
-
-	# Pad result with leading zero to make sure string sorting works.
-	width = int(math.log10(len(keys))) + 1
-	return '{0:0{1}}'.format(result, width)
-
-
-def on_autosort_command(data, buffer, args):
-	''' Called when the autosort command is invoked. '''
-	try:
-		return call_command(buffer, ['/autosort'], args, {
-			' ':      command_sort,
-			'sort':   command_sort,
-			'debug':  command_debug,
-
-			'rules': {
-				' ':         command_rule_list,
-				'list':      command_rule_list,
-				'add':       command_rule_add,
-				'insert':    command_rule_insert,
-				'update':    command_rule_update,
-				'delete':    command_rule_delete,
-				'move':      command_rule_move,
-				'swap':      command_rule_swap,
-			},
-			'helpers': {
-				' ':      command_helper_list,
-				'list':   command_helper_list,
-				'set':    command_helper_set,
-				'delete': command_helper_delete,
-				'rename': command_helper_rename,
-				'swap':   command_helper_swap,
-			},
-		})
-	except HumanReadableError as e:
-		log(e)
-		return weechat.WEECHAT_RC_ERROR
-
-def add_completions(completion, words):
-	for word in words:
-		weechat.hook_completion_list_add(completion, word, 0, weechat.WEECHAT_LIST_POS_END)
-
-def autosort_complete_rules(words, completion):
-	if len(words) == 0:
-		add_completions(completion, ['add', 'delete', 'insert', 'list', 'move', 'swap', 'update'])
-	if len(words) == 1 and words[0] in ('delete', 'insert', 'move', 'swap', 'update'):
-		add_completions(completion, map(str, range(len(config.rules))))
-	if len(words) == 2 and words[0] in ('move', 'swap'):
-		add_completions(completion, map(str, range(len(config.rules))))
-	if len(words) == 2 and words[0] in ('update'):
-		try:
-			add_completions(completion, [config.rules[int(words[1])]])
-		except KeyError: pass
-		except ValueError: pass
-	else:
-		add_completions(completion, [''])
-	return weechat.WEECHAT_RC_OK
-
-def autosort_complete_helpers(words, completion):
-	if len(words) == 0:
-		add_completions(completion, ['delete', 'list', 'rename', 'set', 'swap'])
-	elif len(words) == 1 and words[0] in ('delete', 'rename', 'set', 'swap'):
-		add_completions(completion, sorted(config.helpers.keys()))
-	elif len(words) == 2 and words[0] == 'swap':
-		add_completions(completion, sorted(config.helpers.keys()))
-	elif len(words) == 2 and words[0] == 'rename':
-		add_completions(completion, sorted(config.helpers.keys()))
-	elif len(words) == 2 and words[0] == 'set':
-		try:
-			add_completions(completion, [config.helpers[words[1]]])
-		except KeyError: pass
-	return weechat.WEECHAT_RC_OK
-
-def on_autosort_complete(data, name, buffer, completion):
-	cmdline = weechat.buffer_get_string(buffer, "input")
-	cursor  = weechat.buffer_get_integer(buffer, "input_pos")
-	prefix  = cmdline[:cursor]
-	words   = prefix.split()[1:]
-
-	# If the current word isn't finished yet,
-	# ignore it for coming up with completion suggestions.
-	if prefix[-1] != ' ': words = words[:-1]
-
-	if len(words) == 0:
-		add_completions(completion, ['debug', 'helpers', 'rules', 'sort'])
-	elif words[0] == 'rules':
-		return autosort_complete_rules(words[1:], completion)
-	elif words[0] == 'helpers':
-		return autosort_complete_helpers(words[1:], completion)
-	return weechat.WEECHAT_RC_OK
-
-command_description = r'''{*white}# General commands{reset}
-
-{*white}/autosort {brown}sort{reset}
-Manually trigger the buffer sorting.
-
-{*white}/autosort {brown}debug{reset}
-Show the evaluation results of the sort rules for each buffer.
-
-
-{*white}# Sorting rule commands{reset}
-
-{*white}/autosort{brown} rules list{reset}
-Print the list of sort rules.
-
-{*white}/autosort {brown}rules add {cyan}<expression>{reset}
-Add a new rule at the end of the list.
-
-{*white}/autosort {brown}rules insert {cyan}<index> <expression>{reset}
-Insert a new rule at the given index in the list.
-
-{*white}/autosort {brown}rules update {cyan}<index> <expression>{reset}
-Update a rule in the list with a new expression.
-
-{*white}/autosort {brown}rules delete {cyan}<index>
-Delete a rule from the list.
-
-{*white}/autosort {brown}rules move {cyan}<index_from> <index_to>{reset}
-Move a rule from one position in the list to another.
-
-{*white}/autosort {brown}rules swap {cyan}<index_a> <index_b>{reset}
-Swap two rules in the list
-
-
-{*white}# Helper variable commands{reset}
-
-{*white}/autosort {brown}helpers list
-Print the list of helper variables.
-
-{*white}/autosort {brown}helpers set {cyan}<name> <expression>
-Add or update a helper variable with the given name.
-
-{*white}/autosort {brown}helpers delete {cyan}<name>
-Delete a helper variable.
-
-{*white}/autosort {brown}helpers rename {cyan}<old_name> <new_name>
-Rename a helper variable.
-
-{*white}/autosort {brown}helpers swap {cyan}<name_a> <name_b>
-Swap the expressions of two helper variables in the list.
-
-
-{*white}# Info hooks{reset}
-Autosort comes with a number of info hooks to add some extra functionality to regular weechat eval strings.
-Info hooks can be used in eval strings in the form of {cyan}${{info:some_hook,arguments}}{reset}.
-
-Commas and backslashes in arguments to autosort info hooks (except for {cyan}${{info:autosort_escape}}{reset}) must be escaped with a backslash.
-
-{*white}${{info:{brown}autosort_replace{white},{cyan}pattern{white},{cyan}replacement{white},{cyan}source{white}}}{reset}
-Replace all occurrences of {cyan}pattern{reset} with {cyan}replacement{reset} in the string {cyan}source{reset}.
-Can be used to ignore certain strings when sorting by replacing them with an empty string.
-
-For example: {cyan}${{info:autosort_replace,cat,dog,the dog is meowing}}{reset} expands to "the cat is meowing".
-
-{*white}${{info:{brown}autosort_order{white},{cyan}value{white},{cyan}option0{white},{cyan}option1{white},{cyan}option2{white},{cyan}...{white}}}
-Generate a zero-padded number that corresponds to the index of {cyan}value{reset} in the list of options.
-If one of the options is the special value {brown}*{reset}, then any value not explicitly mentioned will be sorted at that position.
-Otherwise, any value that does not match an option is assigned the highest number available.
-Can be used to easily sort buffers based on a manual sequence.
-
-For example: {cyan}${{info:autosort_order,${{server}},freenode,oftc,efnet}}{reset} will sort freenode before oftc, followed by efnet and then any remaining servers.
-Alternatively, {cyan}${{info:autosort_order,${{server}},freenode,oftc,*,efnet}}{reset} will sort any unlisted servers after freenode and oftc, but before efnet.
-
-{*white}${{info:{brown}autosort_escape{white},{cyan}text{white}}}{reset}
-Escape commas and backslashes in {cyan}text{reset} by prepending them with a backslash.
-This is mainly useful to pass arbitrary eval strings as arguments to other autosort info hooks.
-Otherwise, an eval string that expands to something with a comma would be interpreted as multiple arguments.
-
-For example, it can be used to safely pass buffer names to {cyan}${{info:autosort_replace}}{reset} like so:
-{cyan}${{info:autosort_replace,##,#,${{info:autosort_escape,${{buffer.name}}}}}}{reset}.
-
-
-{*white}# Description
-Autosort is a weechat script to automatically keep your buffers sorted. The sort
-order can be customized by defining your own sort rules, but the default should
-be sane enough for most people. It can also group IRC channel/private buffers
-under their server buffer if you like.
-
-Autosort uses a stable sorting algorithm, meaning that you can manually move buffers
-to change their relative order, if they sort equal with your rule set.
-
-{*white}# Sort rules{reset}
-Autosort evaluates a list of eval expressions (see {*default}/help eval{reset}) and sorts the
-buffers based on evaluated result. Earlier rules will be considered first. Only
-if earlier rules produced identical results is the result of the next rule
-considered for sorting purposes.
-
-You can debug your sort rules with the `{*default}/autosort debug{reset}` command, which will
-print the evaluation results of each rule for each buffer.
-
-{*brown}NOTE:{reset} The sort rules for version 3 are not compatible with version 2 or vice
-versa. You will have to manually port your old rules to version 3 if you have any.
-
-{*white}# Helper variables{reset}
-You may define helper variables for the main sort rules to keep your rules
-readable. They can be used in the main sort rules as variables. For example,
-a helper variable named `{cyan}foo{reset}` can be accessed in a main rule with the
-string `{cyan}${{foo}}{reset}`.
-
-{*white}# Automatic or manual sorting{reset}
-By default, autosort will automatically sort your buffer list whenever a buffer
-is opened, merged, unmerged or renamed. This should keep your buffers sorted in
-almost all situations. However, you may wish to change the list of signals that
-cause your buffer list to be sorted. Simply edit the `{cyan}autosort.sorting.signals{reset}`
-option to add or remove any signal you like.
-
-If you remove all signals you can still sort your buffers manually with the
-`{*default}/autosort sort{reset}` command. To prevent all automatic sorting, the option
-`{cyan}autosort.sorting.sort_on_config_change{reset}` should also be disabled.
-
-{*white}# Recommended settings
-For the best visual effect, consider setting the following options:
-  {*white}/set {cyan}irc.look.server_buffer{reset} {brown}independent{reset}
-
-This setting allows server buffers to be sorted independently, which is
-needed to create a hierarchical tree view of the server and channel buffers.
-
-If you are using the {*default}buflist{reset} plugin you can (ab)use Unicode to draw a tree
-structure with the following setting (modify to suit your need):
-  {*white}/set {cyan}buflist.format.indent {brown}"${{color:237}}${{if:${{buffer.next_buffer.local_variables.type}}=~^(channel|private)$?├─:└─}}"{reset}
-'''
-
-command_completion = '%(plugin_autosort) %(plugin_autosort) %(plugin_autosort) %(plugin_autosort) %(plugin_autosort)'
-
-info_replace_description = (
-	'Replace all occurrences of `pattern` with `replacement` in the string `source`. '
-	'Can be used to ignore certain strings when sorting by replacing them with an empty string. '
-	'See /help autosort for examples.'
-)
-info_replace_arguments = 'pattern,replacement,source'
-
-info_order_description = (
-	'Generate a zero-padded number that corresponds to the index of `value` in the list of options. '
-	'If one of the options is the special value `*`, then any value not explicitly mentioned will be sorted at that position. '
-	'Otherwise, any value that does not match an option is assigned the highest number available. '
-	'Can be used to easily sort buffers based on a manual sequence. '
-	'See /help autosort for examples.'
-)
-info_order_arguments = 'value,first,second,third,...'
-
-info_escape_description = (
-	'Escape commas and backslashes in `text` by prepending them with a backslash. '
-	'This is mainly useful to pass arbitrary eval strings as arguments to other autosort info hooks. '
-	'Otherwise, an eval string that expands to something with a comma would be interpreted as multiple arguments.'
-	'See /help autosort for examples.'
-)
-info_escape_arguments = 'text'
-
-
-if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
-	config = Config('autosort')
-
-	colors = {
-		'default':  weechat.color('default'),
-		'reset':    weechat.color('reset'),
-		'black':    weechat.color('black'),
-		'red':      weechat.color('red'),
-		'green':    weechat.color('green'),
-		'brown':    weechat.color('brown'),
-		'yellow':   weechat.color('yellow'),
-		'blue':     weechat.color('blue'),
-		'magenta':  weechat.color('magenta'),
-		'cyan':     weechat.color('cyan'),
-		'white':    weechat.color('white'),
-		'*default': weechat.color('*default'),
-		'*black':   weechat.color('*black'),
-		'*red':     weechat.color('*red'),
-		'*green':   weechat.color('*green'),
-		'*brown':   weechat.color('*brown'),
-		'*yellow':  weechat.color('*yellow'),
-		'*blue':    weechat.color('*blue'),
-		'*magenta': weechat.color('*magenta'),
-		'*cyan':    weechat.color('*cyan'),
-		'*white':   weechat.color('*white'),
-	}
-
-	weechat.hook_config('autosort.*', 'on_config_changed',  '')
-	weechat.hook_completion('plugin_autosort', '', 'on_autosort_complete', '')
-	weechat.hook_command('autosort', command_description.format(**colors), '', '', command_completion, 'on_autosort_command', '')
-	weechat.hook_info('autosort_escape',  info_escape_description,  info_escape_arguments,  'on_info_escape', '')
-	weechat.hook_info('autosort_replace', info_replace_description, info_replace_arguments, 'on_info_replace', '')
-	weechat.hook_info('autosort_order',   info_order_description,   info_order_arguments,   'on_info_order',   '')
-
-	apply_config()
--- a/weechat/python/colon_complete.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-SCRIPT_NAME='coloncomplete'
-SCRIPT_AUTHOR='Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION='1.0'
-SCRIPT_LICENSE='MIT/X11'
-SCRIPT_DESC='Add a colon after nick completion when all the previous words in the input are also nicks.'
-
-EXTRA_NICKS = ['all', 'backend', 'clojerks', 'ops', 'support']
-
-import_ok=True
-
-try:
-    import weechat
-except ImportError:
-    print 'This script must be run under WeeChat'
-    print 'You can obtain a copy of WeeChat, for free, at http://www.weechat.org'
-    import_ok=False
-
-weechat_version=0
-
-def get_nicks(buffer, prefix=''):
-    channel = weechat.buffer_get_string(buffer, 'localvar_channel')
-    server = weechat.buffer_get_string(buffer, 'localvar_server')
-    prefix = prefix.lower()
-
-    matches = []
-
-    infolist = weechat.infolist_get('irc_nick', '', '%s,%s' % (server, channel))
-    while weechat.infolist_next(infolist):
-        nick = weechat.infolist_string(infolist, 'name')
-        if nick != 'localhost' and nick.lower().startswith(prefix):
-            matches.append(nick)
-    weechat.infolist_free(infolist)
-
-    for nick in EXTRA_NICKS:
-        if nick.lower().startswith(prefix):
-            matches.append(nick)
-
-    return matches
-
-def completer(data, buffer, command):
-    cb = weechat.current_buffer()
-    if command == "/input complete_next":
-        line = weechat.buffer_get_string(cb, "input")
-        words = line.split(' ')
-        prefix = words[-1]
-        if prefix and words and all([s.endswith(':') for s in words[:-1] if s]):
-            nicks = get_nicks(cb, prefix)
-            if len(nicks) == 1:
-                for _ in range(len(prefix)):
-                    weechat.command(buffer, "/input delete_previous_char")
-                weechat.command(buffer, "/input insert " + nicks[-1] + ":\\x20")
-            elif len(nicks) > 1:
-                l = min(len(nick) for nick in nicks)
-                for i in range(len(prefix), l):
-                    if len(set(nick[i] for nick in nicks)) > 1:
-                        break
-                    else:
-                        weechat.command(buffer, "/input insert " + nicks[0][i])
-
-                for nick in nicks:
-                    weechat.prnt(cb, "==> " + nick)
-                return weechat.WEECHAT_RC_OK_EAT
-
-    return weechat.WEECHAT_RC_OK
-
-if __name__ == "__main__" and import_ok:
-    if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
-        weechat_version = weechat.info_get("version_number", "") or 0
-        weechat.hook_command_run('/input complete*', 'completer', '')
--- a/weechat/python/listbuffer.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# ListBuffer, version 0.8.1 for WeeChat version 0.3
-# Latest development version: https://github.com/FiXato/listbuffer
-#
-#   Show /list results in a common buffer and interact with them.
-#
-#   This script allows you to easily join channels from the /list output.
-#   It will open a common buffer for the /list result, through which you
-#   browse with your cursor keys, and join with the meta-enter keys.
-#   Adjust sorting with meta->, meta-< and meta-/ keybindings.
-#
-## History:
-### 2011-09-08: FiXato:
-#
-# * version 0.1:  initial release.
-#     * added a common buffer for /list results
-#     * added highlighting for currently selected line
-#     * added /join support via enter key
-#     * added scroll_top and scroll_bottom support
-#
-# * version 0.2:  /list format bugfix
-#     * added support for /list results without modes
-#     * some servers don't send 321 (/list start). Taken into account.
-#
-# * version 0.3: Sorting support
-#     * Added some basic sorting support. Scroll through sort options
-#       with meta-> and meta-< (users, channel, topic, modes)
-#
-### 2011-09-19: FiXato
-#
-# * version 0.4:
-#     * Case-insensitive buffer lookup fix.
-#     * Removed default enter keybind
-#
-### 2011-12-28: troydm:
-#
-# * version 0.5: It's an upside-down-world
-#     * Added inverted sorting support provided by Dmitry "troydm" Geurkov
-#       Use meta-/ to switch between inverted and regular sorting.
-#
-### 2012-02-10: FiXato:
-#
-# * version 0.6: Stop shoving that buffer in my face!
-#     * The listbuffer should no longer pop up by itself when you load the script.
-#       It should only pop up now when you actually do a /list query.
-#
-# * version 0.7: .. but please pop it up in my current window when I ask for it
-#     * Added setting plugins.var.python.listbuffer.autofocus
-#       This will autofocus the listbuffer in the current window if another window isn't
-#       already showing it, and of course only when the user issues /list
-#
-### 2012-07-10: FiXato:
-#
-# * version 0.7.1: Forgetful bugfix
-#     * Made sure lb_curline global variable is defined
-#
-### 2013-03-19: FiXato:
-#
-# * version 0.8: Sorted out the sorting
-#     * Added automatically updating options for sorting:
-#       * plugins.var.python.listbuffer.sort_inverted
-#       * plugins.var.python.listbuffer.sort_order
-# * version 0.8.1: Pad it baby!
-#     * Channel modes are equally padded even when there are no channel modes.
-#     * Added padding options:
-#       * plugins.var.python.listbuffer.modes_min_width
-#       * plugins.var.python.listbuffer.channel_min_width
-#       * plugins.var.python.listbuffer.users_min_width
-#
-## Acknowledgements:
-# * Dmitry "troydm" Geurkov, for providing the inverse-sorting patch to the project.
-# * Sebastien "Flashcode" Helleu, for developing the kick-ass IRC client WeeChat
-#    and the iset.pl script which inspired me to this script.
-# * Nils "nils_2" Görs, for his contributions to iset.pl which served as
-#    example code.
-# * David "drubin" Rubin, for his urlgrab.py script, which also served
-#    as example code.
-# * ArZa, whose listsort.pl script helped me getting started with
-#    grabbing the /list results. Parts of his code have been shamelessly
-#    copied and ported to Python.
-# * Khaled Mardam-Bey, for making me yearn for similar /list support in
-#    WeeChat as mIRC already offered. :P
-# * mave_, for pointing out that sort orders weren't remembered.
-#
-## TODO:
-#   - Auto-scroll selected line upon window scroll.
-#   - Add option to hide already joined channels.
-#   - Improve sorting methods
-#   - Add auto-join support
-#   - Detect if channel is already in auto-join
-#   - Allow automatically switching to the listbuffer
-#   - Add support for ALIS (/squery alis LIST * -mix 100 (IRCNet)
-#   - Make colours configurable
-#   - Limit number of channels to parse
-#   - Add filter support a la iset
-#   - Allow selecting multiple channels
-#   - Add optional command redirection.
-#
-## Copyright (c) 2011,2012,2013 Filip H.F. "FiXato" Slagter,
-#   <FiXato [at] Gmail [dot] com>
-#   http://profile.fixato.org
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-SCRIPT_NAME    = "listbuffer"
-SCRIPT_AUTHOR  = "Filip H.F. 'FiXato' Slagter <fixato [at] gmail [dot] com>"
-SCRIPT_VERSION = "0.8.1"
-SCRIPT_LICENSE = "MIT"
-SCRIPT_DESC    = "A common buffer for /list output."
-SCRIPT_COMMAND = "listbuffer"
-
-import_ok = True
-
-try:
-  import weechat
-except ImportError:
-  print "This script must be run under WeeChat."
-  import_ok = False
-
-import re
-
-lb_settings = (
-  ("autofocus", "on", "Focus the listbuffer in the current window if it isn't already displayed by a window."),
-  ("sort_order", "users", "Last used sort order for the channel list."),
-  ("sort_inverted", "on", "Invert the sort order for the channel list."),
-  ("modes_min_width", "8", "The minimum width used for modes in the channel list. If a channel has less modes than this amount, the column will be padded with spaces."),
-  ("channel_min_width", "25", "The minimum width used for the channel name in the channel list. If a channelname is shorter than this amount, the column will be padded with spaces."),
-  ("users_min_width", "8", "The minimum width used for the usercount in the channel list. If the usercount has less digits than this amount, the column will be padded with spaces."),
-)
-lb_buffer = None
-lb_curline = 0
-lb_channels = []
-lb_network = None
-lb_list_started = False
-lb_current_sort = None
-lb_sort_inverted = False
-lb_sort_options = (
-  'channel',
-  'users',
-  'modes',
-  'topic',
-)
-
-#                              server numeric Nick Chan  Users     Modes    Topic
-lb_channel_list_expression = '(:\S+) (\d{3}) (\S+) (\S+) (\d+) :(\[(.*?)\] )?(.*)'
-
-# Create listbuffer.
-def lb_create_buffer():
-  global lb_buffer, lb_curline
-
-  if not lb_buffer:
-    lb_buffer = weechat.buffer_new("listbuffer", "lb_input_cb", \
-                "", "lb_close_cb", "")
-    lb_set_buffer_title()
-    # Sets notify to 0 as this buffer does not need to be in hotlist.
-    weechat.buffer_set(lb_buffer, "notify", "0")
-    weechat.buffer_set(lb_buffer, "nicklist", "0")
-    weechat.buffer_set(lb_buffer, "type", "free")
-    weechat.buffer_set(lb_buffer, "key_bind_ctrl-L", "/listbuffer **refresh")
-    weechat.buffer_set(lb_buffer, "key_bind_meta2-A", "/listbuffer **up")
-    weechat.buffer_set(lb_buffer, "key_bind_meta2-B", "/listbuffer **down")
-    weechat.buffer_set(lb_buffer, "key_bind_meta2-1~", "/listbuffer **scroll_top")
-    weechat.buffer_set(lb_buffer, "key_bind_meta2-4~", "/listbuffer **scroll_bottom")
-    weechat.buffer_set(lb_buffer, "key_bind_meta-ctrl-J", "/listbuffer **enter")
-    weechat.buffer_set(lb_buffer, "key_bind_meta-ctrl-M", "/listbuffer **enter")
-    weechat.buffer_set(lb_buffer, "key_bind_meta->", "/listbuffer **sort_next")
-    weechat.buffer_set(lb_buffer, "key_bind_meta-<", "/listbuffer **sort_previous")
-    weechat.buffer_set(lb_buffer, "key_bind_meta-/", "/listbuffer **sort_invert")
-    lb_curline = 0
-  if weechat.config_get_plugin("autofocus") == "on":
-    if not weechat.window_search_with_buffer(lb_buffer):
-      weechat.command("", "/buffer " + weechat.buffer_get_string(lb_buffer,"name"))
-
-def lb_set_buffer_title():
-  global lb_buffer, lb_current_sort
-  ascdesc = '(v)' if lb_sort_inverted else '(^)'
-  weechat.buffer_set(lb_buffer, "title", lb_line_format({
-    'channel': 'Channel name%s' % (ascdesc if lb_current_sort == 'channel' else ''),
-    'users': 'Users%s' % (ascdesc if lb_current_sort == 'users' else ''),
-    'modes': 'Modes%s' % (ascdesc if lb_current_sort == 'modes' else ''),
-    'topic': 'Topic%s' % (ascdesc if lb_current_sort == 'topic' else ''),
-    'nomodes': None,
-  }))
-
-def lb_list_start(data, signal, message):
-  lb_initialise_list
-
-  return weechat.WEECHAT_RC_OK
-
-def lb_initialise_list(signal):
-  global lb_channels, lb_network, lb_list_started
-
-  lb_create_buffer()
-  lb_channels = []
-  lb_network = signal.split(',')[0]
-  lb_list_started = True
-  return
-
-
-def lb_list_chan(data, signal, message):
-  global lb_channels, lb_buffer, lb_list_started
-
-  # Work-around for IRCds which don't send 321 Numeric (/List start)
-  if not lb_list_started:
-    lb_initialise_list(signal)
-
-  for chan_data in re.findall(lb_channel_list_expression,message):
-    lb_channels.append({
-      'server':  chan_data[0][1:-1],
-      'numeric': chan_data[1],
-      'nick':    chan_data[2],
-      'channel': chan_data[3],
-      'users':   chan_data[4],
-      'nomodes': chan_data[5] == '',
-      'modes':   chan_data[6],
-      'topic':   weechat.hook_modifier_exec("irc_color_decode", "1", chan_data[7])
-    })
-  return weechat.WEECHAT_RC_OK
-
-def lb_list_end(data, signal, message):
-  global lb_list_started
-
-  # Work-around for IRCds which don't send 321 Numeric (/List start)
-  if not lb_list_started:
-    lb_initialise_list(signal)
-
-  lb_list_started = False
-  if lb_current_sort:
-    lb_sort()
-  lb_refresh()
-  return weechat.WEECHAT_RC_OK
-
-def keyEvent (data, buffer, args):
-  global lb_options
-  lb_options[args]()
-
-def lb_input_cb(data, buffer, input_data):
-  global lb_options, lb_curline
-  lb_options[input_data]()
-  return weechat.WEECHAT_RC_OK
-
-def lb_refresh():
-  global lb_channels, lb_buffer
-  weechat.buffer_clear(lb_buffer)
-
-  y = 0
-  for list_data in lb_channels:
-    lb_refresh_line(y)
-    y += 1
-  return
-
-def lb_refresh_line(y):
-  global lb_buffer, lb_curline, lb_channels
-  if y >= 0 and y < len(lb_channels):
-    formatted_line = lb_line_format(lb_channels[y], y == lb_curline)
-    weechat.prnt_y(lb_buffer, y, formatted_line)
-
-def lb_refresh_curline():
-  global lb_curline
-  lb_refresh_line(lb_curline-1)
-  lb_refresh_line(lb_curline)
-  lb_refresh_line(lb_curline+1)
-  return
-
-def lb_line_format(list_data,curr=False):
-  str = ""
-  if (curr):
-    str += weechat.color("yellow,red")
-  channel_text = list_data['channel'].ljust(int(weechat.config_get_plugin('channel_min_width')))
-  users_text = "(%s)" % list_data['users']
-  padded_users_text = users_text.rjust(int(weechat.config_get_plugin('users_min_width')) + 2)
-  str += "%s%s %s " % (weechat.color("bold"), channel_text, padded_users_text)
-  if not list_data['nomodes']:
-    modes = "[%s]" % list_data['modes']
-  else:
-    modes = "[]"
-  str += "%s: " % modes.rjust(int(weechat.config_get_plugin('modes_min_width')) + 2)
-  str += "%s" % list_data['topic']
-  return str
-
-def lb_line_up():
-  global lb_curline
-  if lb_curline <= 0:
-    return
-  lb_curline -= 1
-  lb_refresh_curline()
-  lb_check_outside_window()
-  return
-
-def lb_line_down():
-  global lb_curline, lb_channels
-  if lb_curline+1 >= len(lb_channels):
-    return
-  lb_curline += 1
-  lb_refresh_curline()
-  lb_check_outside_window()
-  return
-
-def lb_line_run():
-  global lb_channels, lb_curline, lb_network
-  buff = weechat.info_get("irc_buffer", lb_network)
-  channel = lb_channels[lb_curline]['channel']
-  command = "/join %s" % channel
-  weechat.command(buff, command)
-  return
-
-def lb_line_select():
-  return
-
-def lb_scroll_top():
-  global lb_curline
-  old_y = lb_curline
-  lb_curline = 0
-  lb_refresh_curline()
-  lb_refresh_line(old_y)
-  weechat.command(lb_buffer, "/window scroll_top")
-  return
-
-def lb_scroll_bottom():
-  global lb_curline, lb_channels
-  old_y = lb_curline
-  lb_curline = len(lb_channels)-1
-  lb_refresh_curline()
-  lb_refresh_line(old_y)
-  weechat.command(lb_buffer, "/window scroll_bottom")
-  return
-
-def lb_check_outside_window():
-  global lb_buffer, lb_curline
-  if (lb_buffer):
-    infolist = weechat.infolist_get("window", "", "current")
-    if (weechat.infolist_next(infolist)):
-      start_line_y = weechat.infolist_integer(infolist, "start_line_y")
-      chat_height = weechat.infolist_integer(infolist, "chat_height")
-      if(start_line_y > lb_curline):
-        weechat.command(lb_buffer, "/window scroll -%i" %(start_line_y - lb_curline))
-      elif(start_line_y <= lb_curline - chat_height):
-        weechat.command(lb_buffer, "/window scroll +%i"%(lb_curline - start_line_y - chat_height + 1))
-    weechat.infolist_free(infolist)
-
-def lb_sort_next():
-  global lb_current_sort, lb_sort_options
-  if lb_current_sort:
-    new_index = lb_sort_options.index(lb_current_sort) + 1
-  else:
-    new_index = 0
-
-  if len(lb_sort_options) <= new_index:
-    new_index = 0
-
-  lb_set_current_sort_order(lb_sort_options[new_index])
-  lb_sort()
-
-def lb_set_current_sort_order(value):
-  global lb_current_sort
-  lb_current_sort = value
-  weechat.config_set_plugin('sort_order', lb_current_sort)
-
-def lb_set_invert_sort_order(value):
-  global lb_sort_inverted
-  lb_sort_inverted = value
-  weechat.config_set_plugin('sort_inverted', ('on' if lb_sort_inverted else 'off'))
-
-def lb_sort_previous():
-  global lb_current_sort, lb_sort_options
-  if lb_current_sort:
-    new_index = lb_sort_options.index(lb_current_sort) - 1
-  else:
-    new_index = 0
-
-  if new_index < 0:
-    new_index = len(lb_sort_options) - 1
-
-  lb_set_current_sort_order(lb_sort_options[new_index])
-  lb_sort()
-
-def lb_sort(sort_key=None):
-  global lb_channels, lb_current_sort, lb_sort_inverted
-  if sort_key:
-    lb_set_current_sort_order(sort_key)
-  if lb_current_sort == 'users':
-    lb_channels = sorted(lb_channels, key=lambda chan_data: int(chan_data[lb_current_sort]))
-  else:
-    lb_channels = sorted(lb_channels, key=lambda chan_data: chan_data[lb_current_sort])
-  if lb_sort_inverted:
-    lb_channels.reverse()
-  lb_set_buffer_title()
-  lb_refresh()
-
-def lb_sort_invert():
-  global lb_current_sort, lb_sort_inverted
-  if lb_current_sort:
-    lb_set_invert_sort_order(not lb_sort_inverted)
-    lb_sort()
-
-def lb_close_cb(*kwargs):
-  """ A callback for buffer closing. """
-  global lb_buffer
-
-  lb_buffer = None
-  return weechat.WEECHAT_RC_OK
-
-lb_options = {
-  'refresh'     : lb_refresh,
-  'up'          : lb_line_up,
-  'down'        : lb_line_down,
-  'enter'       : lb_line_run,
-  'space'       : lb_line_select,
-  'scroll_top'  : lb_scroll_top,
-  'scroll_bottom': lb_scroll_bottom,
-  'sort_next'   : lb_sort_next,
-  'sort_previous': lb_sort_previous,
-  'sort_invert': lb_sort_invert
-}
-
-def lb_command_main(data, buffer, args):
-  if args[0:2] == "**":
-    keyEvent(data, buffer, args[2:])
-  return weechat.WEECHAT_RC_OK
-
-def lb_set_default_settings():
-  global lb_settings
-  # Set default settings
-  for option, default_value, description in lb_settings:
-     if not weechat.config_is_set_plugin(option):
-         weechat.config_set_plugin(option, default_value)
-         version = weechat.info_get("version_number", "") or 0
-         if int(version) >= 0x00030500:
-             weechat.config_set_desc_plugin(option, description)
-
-def lb_reset_stored_sort_order():
-  global lb_current_sort, lb_sort_inverted
-  lb_current_sort = weechat.config_get_plugin('sort_order')
-  lb_sort_inverted = (True if weechat.config_get_plugin('sort_inverted') == 'on' else False)
-
-if __name__ == "__main__" and import_ok:
-  if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
-                      SCRIPT_LICENSE, SCRIPT_DESC, "lb_close_cb", ""):
-    lb_set_default_settings()
-    lb_reset_stored_sort_order()
-    lb_buffer = weechat.buffer_search("python", "listbuffer")
-
-    weechat.hook_signal("*,irc_in_321", "lb_list_start", "")
-    weechat.hook_signal("*,irc_in_322", "lb_list_chan", "")
-    weechat.hook_signal("*,irc_in_323", "lb_list_end", "")
-    weechat.hook_command(SCRIPT_COMMAND,
-                          "List Buffer",
-                          "", "", "",
-                          "lb_command_main", "")
--- a/weechat/python/sanitize_jira.py	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-import re, weechat, subprocess
-
-SCRIPT_NAME = 'sanitize_jira'
-SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION = '0.0.1'
-SCRIPT_LICENSE = 'MIT'
-SCRIPT_DESC = 'clean up the garbage jirabot sends to channels into something readable'
-
-weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', '')
-
-weechat.hook_line('*', '', 'nick_Jira_Cloud', 'sanitize_jira', '')
-
-first_line_re = re.compile(
-    r'(?P<link>https://[^/]+/browse/[^?]+)[?]atlOrigin=[^ ]+ [(](?P<title>.+)[)]'
-)
-
-detail_line_re = re.compile(
-    r'''Status: \x1a\x01[*](?P<status>[^*]+)[*]\x1b\x01.*Type: \x1a\x01[*](?P<type>[^*]+)[*]\x1b\x01.*Assignee: \x1a\x01[*](?P<assignee>[^*]+)[*]\x1b\x01.*Priority: \x1a\x01[*](?P<priority>[^*]+)[*]\x1b\x01'''
-)
-
-def sanitize_jira(data, line):
-    if 'sign up for an Atlassian account to view this link' in line['message']:
-        return {'message': ' '}
-
-    m = first_line_re.search(line['message'])
-    if m:
-        return {'message': '%s | %s' % (m.group('title'), m.group('link'))}
-
-    m = detail_line_re.search(line['message'])
-    if m:
-        return {'message': '%s / %s / %s' % (m.group('type'), m.group('status'), m.group('assignee'))}
-
-    return {}
--- a/weechat/relay.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-#
-# weechat -- relay.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[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 = ""
-auth_timeout = 60
-bind_address = ""
-clients_purge_delay = 0
-compression = 20
-ipv6 = on
-max_clients = 5
-nonce_size = 16
-password = ""
-password_hash_algo = "*"
-password_hash_iterations = 100000
-ssl_cert_key = "%h/ssl/relay.pem"
-ssl_priorities = "NORMAL:-VERS-SSL3.0"
-totp_secret = ""
-totp_window = 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] "
-
-[weechat]
-commands = ""
-
-[port]
-
-[path]
--- a/weechat/rmodifier.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#
-# rmodifier.conf -- weechat v0.4.3
-#
-
-[look]
-hide_char = "*"
-
-[modifier]
-nickserv = "history_add,input_text_display;^(/(msg|quote) +nickserv +(identify|ghost \S+) +)(.*);1,4*"
-oper = "history_add,input_text_display;^(/oper +\S+ +)(.*);1,2*"
-set_pass = "history_add;^(/set +\S*password\S* +)(.*);1,2*"
--- a/weechat/ruby.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#
-# weechat -- ruby.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[look]
-check_license = off
-eval_keep_context = on
--- a/weechat/ruby/autoload/challengeauth.rb	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-# Copyright (c) 2013 Dominik Honnef <dominikh@fork-bomb.org>
-
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-# History:
-# 2013-04-20, Dominik Honnef
-#   version 0.0.1: initial version
-
-require "openssl"
-
-QBot = "Q@CServe.quakenet.org"
-QBotHost = "Q!TheQBot@CServe.quakenet.org"
-Request = Struct.new(:username, :hash)
-
-def weechat_init
-  @requests = {}
-
-  Weechat.register("challengeauth",
-                   "Dominik Honnef",
-                   "0.0.1",
-                   "MIT",
-                   "Securely authenticate with QuakeNet by using CHALLENGEAUTH",
-                   "",
-                   "")
-
-  Weechat.hook_command("challengeauth",
-                       "Authenticate with Q using CHALLENGEAUTH",
-                       "[username] [password]",
-                       "",
-                       "",
-                       "challengeauth",
-                       "")
-
-  Weechat.hook_modifier("irc_in_notice", "challenge_notice", "")
-
-  return Weechat::WEECHAT_RC_OK
-end
-
-def calculate_q_hash(username, hash, challenge)
-  username = username.tr("A-Z[]\\\\^", "a-z{}|~")
-
-  key = OpenSSL::Digest::SHA256.hexdigest("#{username}:#{hash}")
-  return OpenSSL::HMAC.hexdigest("SHA256", key, challenge)
-end
-
-def get_server_buffer(server)
-  Weechat.buffer_search("irc", "server." + server)
-end
-
-def challengeauth(data, buffer, args)
-  plugin = Weechat.buffer_get_string(buffer, "localvar_plugin")
-  if plugin != "irc"
-    Weechat.print(buffer, "/challengeauth only works for IRC buffers.")
-    return Weechat.WEECHAT_RC_ERROR
-  end
-
-  server = Weechat.buffer_get_string(buffer, "localvar_server")
-  args = args.split(" ", 2)
-  username = args[0]
-  password = args[1]
-  hash = OpenSSL::Digest::SHA256.hexdigest(password[0, 10])
-
-  @requests[server] = Request.new(username, hash)
-  server_buffer = get_server_buffer(server)
-  Weechat.print(server_buffer, "Authenticating as #{username}...")
-  Weechat.command(server_buffer, "/quote PRIVMSG #{QBot} :CHALLENGE")
-
-  return Weechat::WEECHAT_RC_OK
-end
-
-def challenge_notice(modifier, data, server, line)
-  return line unless @requests.has_key?(server)
-
-  parts = line.split(" ")
-  return line unless parts.size > 5
-
-  host = parts[0][1..-1]
-  command = parts[3][1..-1]
-  challenge = parts[4]
-
-  return line if host != QBotHost || command != "CHALLENGE"
-
-  request = @requests[server]
-  response = calculate_q_hash(request.username, request.hash, challenge)
-  server_buffer = get_server_buffer(server)
-
-  Weechat.print(server_buffer, "Sending challengeauth for #{request.username}...")
-  Weechat.command(server_buffer,
-                  "/quote PRIVMSG %s :CHALLENGEAUTH %s %s HMAC-SHA-256" % [QBot, request.username, response])
-
-  @requests.delete(server)
-
-  return line
-end
--- a/weechat/script.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#
-# weechat -- script.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[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 = darkgray
-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 = 60
-download_enabled = on
-download_timeout = 30
-hold = ""
-path = "%h/script"
-url = "http://www.weechat.org/files/plugins.xml.gz"
--- a/weechat/spell.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#
-# weechat -- spell.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[color]
-misspelled = lightred
-suggestion = default
-suggestion_delimiter_dict = cyan
-suggestion_delimiter_word = cyan
-
-[check]
-commands = "away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic"
-default_dict = ""
-during_search = off
-enabled = off
-real_time = off
-suggestions = -1
-word_min_length = 2
-
-[dict]
-
-[look]
-suggestion_delimiter_dict = " / "
-suggestion_delimiter_word = ","
-
-[option]
--- a/weechat/tcl.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#
-# weechat -- tcl.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use /set or similar command to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[look]
-check_license = off
-eval_keep_context = on
--- a/weechat/trigger.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#
-# weechat -- trigger.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[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_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|quote) +nickserv +(id|identify|register|ghost +[^ ]+|release +[^ ]+|regain +[^ ]+) +)|/oper +[^ ]+ +|/quote +pass +|/set +[^ ]*password[^ ]* +|/secure +(passphrase|decrypt|set +[^ ]+) +)(.*)==$1$.*+"
-cmd_pass.return_code = ok
-dumbass_buffer.arguments = "4000|input_text_for_buffer;4000|history_add"
-dumbass_buffer.command = ""
-dumbass_buffer.conditions = ""
-dumbass_buffer.enabled = on
-dumbass_buffer.hook = modifier
-dumbass_buffer.post_action = none
-dumbass_buffer.regex = "==^ +/?b (.+)==/b ${re:1}"
-dumbass_buffer.return_code = ok
-idiot_buffer.arguments = "4000|input_text_for_buffer;4000|history_add"
-idiot_buffer.command = ""
-idiot_buffer.conditions = ""
-idiot_buffer.enabled = on
-idiot_buffer.hook = modifier
-idiot_buffer.post_action = none
-idiot_buffer.regex = "==^b (.+)==/b ${re:1}"
-idiot_buffer.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 +[^ ]+) +)(.*)==$1$.*+"
-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=)([^ ]+)(.*)==$1$.*4$5"
-server_pass.return_code = ok
-uncc.arguments = "weechat_print"
-uncc.command = ""
-uncc.conditions = "${tg_tag_nick}"
-uncc.enabled = on
-uncc.hook = modifier
-uncc.post_action = none
-uncc.regex = "== \[cc: [^ ]+\]===="
-uncc.return_code = ok
--- a/weechat/typing.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#
-# weechat -- typing.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[look]
-delay_purge_paused = 30
-delay_purge_typing = 6
-delay_set_paused = 10
-enabled_nicks = off
-enabled_self = off
-input_min_chars = 4
-item_max_length = 0
--- a/weechat/urlgrab.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#
-# weechat -- urlgrab.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[color]
-color_bg_selected = green
-color_buffer = red
-color_buffer_selected = red
-color_time = cyan
-color_time_selected = cyan
-color_url = blue
-color_url_selected = blue
-
-[default]
-copycmd = "xsel -i"
-historysize = 20
-localcmd = "xdg-open %s"
-method = "local"
-output_main_buffer = off
-remotecmd = "ssh -x localhost -i ~/.ssh/id_rsa -C "export DISPLAY=":0.0" &&  firefox %s""
-time_format = "%H:%M:%S"
-url_log = "~/.weechat/urls.log"
--- a/weechat/weechat.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,693 +0,0 @@
-#
-# WeeChat -- weechat.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart
-#
-
-[debug]
-
-[startup]
-command_after_plugins = ""
-command_before_plugins = ""
-display_logo = on
-display_version = on
-sys_rlimit = ""
-
-[look]
-align_end_of_lines = message
-align_multiline_words = on
-bar_more_down = "++"
-bar_more_left = "<<"
-bar_more_right = ">>"
-bar_more_up = "--"
-bare_display_exit_on_input = on
-bare_display_time_format = "%H:%M"
-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 = "%H:%M"
-buffer_time_same = ""
-color_basic_force_bold = off
-color_inactive_buffer = off
-color_inactive_message = on
-color_inactive_prefix = on
-color_inactive_prefix_buffer = on
-color_inactive_time = off
-color_inactive_window = off
-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 = "sjl,slosh,slj,horrifying,steve.losh,@steve.losh,stevelosh"
-highlight_regex = "(steve losh|rob ford|(jesus )?fucking christ|(horse|mouse|clown)fuckers?|((mother)?fuck([ie]ng?|er)?|(god?)?damn(ed)?|dammit|(bull|horse)?shite?){3,})"
-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 = "H: "
-hotlist_remove = merged
-hotlist_short_names = on
-hotlist_sort = group_time_asc
-hotlist_suffix = ""
-hotlist_unique_numbers = on
-hotlist_update_on_buffer_switch = 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 = "%H:%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 = off
-mouse_timer_delay = 100
-nick_color_force = ""
-nick_color_hash = djb2
-nick_color_hash_salt = ""
-nick_color_stop_chars = "_|["
-nick_prefix = ""
-nick_suffix = ""
-paste_auto_add_newline = on
-paste_bracketed = off
-paste_bracketed_timer_delay = 10
-paste_max_lines = 3
-prefix_action = " *"
-prefix_align = right
-prefix_align_max = 15
-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_same_nick_middle = ""
-prefix_suffix = "|"
-quote_nick_prefix = "<"
-quote_nick_suffix = ">"
-quote_time_format = "%H:%M:%S"
-read_marker = line
-read_marker_always_show = on
-read_marker_string = "─"
-read_marker_update_on_buffer_switch = on
-save_config_on_exit = off
-save_config_with_fsync = off
-save_layout_on_exit = all
-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 = ""
-word_chars_highlight = "!\u00A0,-,_,|,@,.,alnum"
-word_chars_input = "!\u00A0,-,_,|,alnum"
-
-[palette]
-
-[color]
-bar_more = magenta
-chat = default
-chat_bg = default
-chat_buffer = white
-chat_channel = white
-chat_day_change = cyan
-chat_delimiters = green
-chat_highlight = 207
-chat_highlight_bg = default
-chat_host = cyan
-chat_inactive_buffer = darkgray
-chat_inactive_window = darkgray
-chat_nick = lightcyan
-chat_nick_colors = "027,048,068,028,081,082,099,112,129,136,169,178,208,226,113,196,161,23,59,222"
-chat_nick_offline = darkgray
-chat_nick_offline_highlight = default
-chat_nick_offline_highlight_bg = darkgray
-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 = darkgray
-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 = green
-chat_read_marker_bg = default
-chat_server = brown
-chat_tags = red
-chat_text_found = yellow
-chat_text_found_bg = lightmagenta
-chat_time = 238
-chat_time_delimiters = 236
-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 = green
-status_count_highlight = magenta
-status_count_msg = brown
-status_count_other = 16
-status_count_private = green
-status_data_highlight = lightmagenta
-status_data_msg = yellow
-status_data_other = 16
-status_data_private = lightgreen
-status_filter = green
-status_more = 16
-status_mouse = green
-status_name = *16
-status_name_ssl = *16
-status_nicklist_count = default
-status_number = 16
-status_time = *16
-
-[completion]
-base_word_until_cursor = on
-command_inline = on
-default_template = "%(nicks)|%(irc_channels)"
-nick_add_space = on
-nick_case_sensitive = off
-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
-partial_completion_templates = "config_options"
-
-[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_system = on
-gnutls_ca_user = ""
-gnutls_handshake_timeout = 30
-proxy_curl = ""
-
-[plugin]
-autoload = "*"
-debug = off
-extension = ".so"
-path = "%h/plugins"
-save_config_on_unload = on
-
-[signal]
-sighup = "${if:${info:weechat_headless}?/reload:/quit -yes}"
-sigquit = "/quit -yes"
-sigterm = "/quit -yes"
-sigusr1 = ""
-sigusr2 = ""
-
-[bar]
-buffers.color_bg = default
-buffers.color_bg_inactive = default
-buffers.color_delim = default
-buffers.color_fg = default
-buffers.conditions = ""
-buffers.filling_left_right = vertical
-buffers.filling_top_bottom = horizontal
-buffers.hidden = on
-buffers.items = "buffers"
-buffers.position = left
-buffers.priority = 0
-buffers.separator = on
-buffers.size = 0
-buffers.size_max = 0
-buffers.type = root
-buflist.color_bg = default
-buflist.color_bg_inactive = default
-buflist.color_delim = default
-buflist.color_fg = default
-buflist.conditions = ""
-buflist.filling_left_right = vertical
-buflist.filling_top_bottom = columns_vertical
-buflist.hidden = off
-buflist.items = "buflist"
-buflist.position = left
-buflist.priority = 0
-buflist.separator = on
-buflist.size = 0
-buflist.size_max = 25
-buflist.type = root
-fset.color_bg = default
-fset.color_bg_inactive = default
-fset.color_delim = cyan
-fset.color_fg = default
-fset.conditions = "${buffer.full_name} == fset.fset"
-fset.filling_left_right = vertical
-fset.filling_top_bottom = horizontal
-fset.hidden = off
-fset.items = "fset"
-fset.position = top
-fset.priority = 0
-fset.separator = on
-fset.size = 3
-fset.size_max = 3
-fset.type = window
-input.color_bg = default
-input.color_bg_inactive = default
-input.color_delim = green
-input.color_fg = default
-input.conditions = ""
-input.filling_left_right = vertical
-input.filling_top_bottom = horizontal
-input.hidden = off
-input.items = "[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
-nicklist.color_bg = default
-nicklist.color_bg_inactive = 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 = on
-nicklist.items = "buffer_nicklist"
-nicklist.position = right
-nicklist.priority = 200
-nicklist.separator = on
-nicklist.size = 0
-nicklist.size_max = 0
-nicklist.type = window
-status.color_bg = green
-status.color_bg_inactive = default
-status.color_delim = 0
-status.color_fg = 0
-status.conditions = ""
-status.filling_left_right = vertical
-status.filling_top_bottom = horizontal
-status.hidden = off
-status.items = "[time],buffer_number+:+buffer_name,buffer_title"
-status.position = bottom
-status.priority = 500
-status.separator = off
-status.size = 1
-status.size_max = 0
-status.type = window
-title.color_bg = green
-title.color_bg_inactive = default
-title.color_delim = cyan
-title.color_fg = 16
-title.conditions = ""
-title.filling_left_right = vertical
-title.filling_top_bottom = horizontal
-title.hidden = on
-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]
-python.slack.10xgenomics.&cloud-alerts-pagerduty = highlight
-python.slack.10xgenomics.&cloud-sumo-prod-support-alerts = highlight
-python.slack.10xgenomics.&lacework-10xdev = highlight
-python.slack.10xgenomics.&lacework-10xprod = highlight
-python.slack.10xgenomics.&testing1234 = highlight
-
-[filter]
-irc_smart = on;*;irc_smart_filter;*
-nicks = on;*;irc_366;*
-
-[key]
-ctrl-? = "/input delete_previous_char"
-ctrl-A = "/input move_beginning_of_line"
-ctrl-B = "/brows"
-ctrl-Cb = "/input insert \x02"
-ctrl-Cc = "/input insert \x03"
-ctrl-Ci = "/input insert \x1D"
-ctrl-Co = "/input insert \x0F"
-ctrl-Cr = "/input insert \x12"
-ctrl-Cu = "/input insert \x15"
-ctrl-D = "/buffer close"
-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 jump_smart"
-ctrl-K = "/input delete_end_of_line"
-ctrl-L = "/window refresh"
-ctrl-M = "/input return"
-ctrl-N = "/buffer +1"
-ctrl-O = "/editor"
-ctrl-P = "/buffer -1"
-ctrl-R = "/input search_text"
-ctrl-Sctrl-U = "/input set_unread"
-ctrl-T = "/input transpose_chars"
-ctrl-U = "/url 1"
-ctrl-W = "/input delete_previous_word"
-ctrl-X = "/input switch_active_buffer"
-ctrl-Y = "/input clipboard_paste"
-meta-meta-OP = "/bar scroll buflist * b"
-meta-meta-OQ = "/bar scroll buflist * e"
-meta-meta2-11~ = "/bar scroll buflist * b"
-meta-meta2-12~ = "/bar scroll buflist * e"
-meta-meta2-1~ = "/window scroll_top"
-meta-meta2-23~ = "/bar scroll nicklist * yb"
-meta-meta2-24~ = "/bar scroll nicklist * ye"
-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 move -1"
-meta-meta2-B = "/buffer move +1"
-meta-meta2-C = "/buffer +1"
-meta-meta2-D = "/buffer -1"
-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-B = "/buflist toggle"
-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-OP = "/bar scroll buflist * -100%"
-meta-OQ = "/bar scroll buflist * +100%"
-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-11^ = "/bar scroll buflist * -100%"
-meta2-11~ = "/bar scroll buflist * -100%"
-meta2-12^ = "/bar scroll buflist * +100%"
-meta2-12~ = "/bar scroll buflist * +100%"
-meta2-15~ = "/bar scroll nicklist * y-100%"
-meta2-17~ = "/bar scroll nicklist * y+100%"
-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;3P = "/bar scroll buflist * b"
-meta2-1;3Q = "/bar scroll buflist * e"
-meta2-1;5A = "/input history_global_previous"
-meta2-1;5B = "/input history_global_next"
-meta2-1;5P = "/bar scroll buflist * -100%"
-meta2-1;5Q = "/bar scroll buflist * +100%"
-meta2-1;9A = "/buffer move -1"
-meta2-1;9B = "/buffer move +1"
-meta2-1~ = "/input move_beginning_of_line"
-meta2-20~ = "/bar scroll title * x-50%"
-meta2-21~ = "/bar scroll title * x+50%"
-meta2-23~ = "/bar scroll nicklist * y-100%"
-meta2-24~ = "/bar scroll nicklist * y+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"
-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-l = "/input jump_last_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-n = "/window scroll_next_highlight"
-meta-p = "/window scroll_previous_highlight"
-meta-r = "/input delete_line"
-meta-u = "/input 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 = "/bar toggle nicklist"
-meta-z = "/window zoom"
-ctrl-_ = "/input undo"
-
-[key_search]
-ctrl-J = "/input search_stop"
-ctrl-M = "/input search_stop"
-ctrl-R = "/input search_switch_case"
-meta2-A = "/input search_previous"
-meta2-B = "/input search_next"
-
-[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"
-@chat(python.*):D = "hsignal:slack_cursor_delete"
-@chat(python.*):L = "hsignal:slack_cursor_linkarchive"
-@chat(python.*):M = "hsignal:slack_cursor_message"
-@chat(python.*):R = "hsignal:slack_cursor_reply"
-@chat(python.*):T = "hsignal:slack_cursor_thread"
-@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(buflist):ctrl-wheeldown = "hsignal:buflist_mouse"
-@bar(buflist):ctrl-wheelup = "hsignal:buflist_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(fset.fset):button1 = "/window ${_window_number};/fset -go ${_chat_line_y}"
-@chat(fset.fset):button2* = "hsignal:fset_mouse"
-@chat(fset.fset):wheeldown = "/fset -down 5"
-@chat(fset.fset):wheelup = "/fset -up 5"
-@chat(python.*):button2 = "hsignal:slack_mouse"
-@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"
-@item(buflist):button1* = "hsignal:buflist_mouse"
-@item(buflist):button2* = "hsignal:buflist_mouse"
-@item(buflist2):button1* = "hsignal:buflist_mouse"
-@item(buflist2):button2* = "hsignal:buflist_mouse"
-@item(buflist3):button1* = "hsignal:buflist_mouse"
-@item(buflist3):button2* = "hsignal:buflist_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:wheeldown = "/window scroll_down -window ${_window_number}"
-@chat:wheelup = "/window scroll_up -window ${_window_number}"
-@*:button3 = "/cursor go ${_x},${_y}"
--- a/weechat/xfer.conf	Fri Oct 20 14:03:50 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#
-# weechat -- xfer.conf
-#
-# WARNING: It is NOT recommended to edit this file by hand,
-# especially if WeeChat is running.
-#
-# Use commands like /set or /fset to change settings in WeeChat.
-#
-# For more info, see: https://weechat.org/doc/quickstart/
-#
-
-[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 = ""
-send_ack = on
-speed_limit_recv = 0
-speed_limit_send = 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"
-download_temporary_suffix = ".part"
-upload_path = "~"
-use_nick_in_filename = on