fish v4 and some weechat stuff

master
Ben Harris 2025-01-07 18:39:08 -05:00
parent 734e67fb1f
commit bfd96e2285
18 changed files with 1039 additions and 6375 deletions

View File

@ -1,4 +1,7 @@
#!/bin/sh #!/bin/sh
set -e
set -u
matchplayApiKey=$(cat ~/Sync/Notes/keys/matchplayapikey.txt) matchplayApiKey=$(cat ~/Sync/Notes/keys/matchplayapikey.txt)
ifpaApiKey=$(cat ~/Sync/Notes/keys/ifpa-api-key.txt) ifpaApiKey=$(cat ~/Sync/Notes/keys/ifpa-api-key.txt)

View File

@ -76,4 +76,4 @@
# Set this to zero to hide seconds int the time display # Set this to zero to hide seconds int the time display
# Default 1 # Default 1
#TIME_SECONDS=0 #TIME_SECONDS=0
BYOBU_CHARMAP=x BYOBU_CHARMAP=UTF-8

View File

@ -0,0 +1,185 @@
# This is terribly complicated
# It's because:
# 1. bun run has to have dynamic completions
# 2. there are global options
# 3. bun {install add remove} gets special options
# 4. I don't know how to write fish completions well
# Contributions very welcome!!
function __fish__get_bun_bins
string split ' ' (bun getcompletes b)
end
function __fish__get_bun_scripts
set -lx SHELL bash
set -lx MAX_DESCRIPTION_LEN 40
string trim (string split '\n' (string split '\t' (bun getcompletes z)))
end
function __fish__get_bun_packages
if test (commandline -ct) != ""
set -lx SHELL fish
string split ' ' (bun getcompletes a (commandline -ct))
end
end
function __history_completions
set -l tokens (commandline --current-process --tokenize)
history --prefix (commandline) | string replace -r \^$tokens[1]\\s\* "" | string replace -r \^$tokens[2]\\s\* "" | string split ' '
end
function __fish__get_bun_bun_js_files
string split ' ' (bun getcompletes j)
end
set -l bun_install_boolean_flags yarn production optional development no-save dry-run force no-cache silent verbose global
set -l bun_install_boolean_flags_descriptions "Write a yarn.lock file (yarn v1)" "Don't install devDependencies" "Add dependency to optionalDependencies" "Add dependency to devDependencies" "Don't install devDependencies" "Don't install anything" "Always request the latest versions from the registry & reinstall all dependencies" "Ignore manifest cache entirely" "Don't output anything" "Excessively verbose logging" "Use global folder"
set -l bun_builtin_cmds_without_run dev create help bun upgrade discord install remove add init pm x
set -l bun_builtin_cmds_accepting_flags create help bun upgrade discord run init link unlink pm x
function __bun_complete_bins_scripts --inherit-variable bun_builtin_cmds_without_run -d "Emit bun completions for bins and scripts"
# Do nothing if we already have a builtin subcommand,
# or any subcommand other than "run".
if __fish_seen_subcommand_from $bun_builtin_cmds_without_run
or not __fish_use_subcommand && not __fish_seen_subcommand_from run
return
end
# Do we already have a bin or script subcommand?
set -l bins (__fish__get_bun_bins)
if __fish_seen_subcommand_from $bins
return
end
# Scripts have descriptions appended with a tab separator.
# Strip off descriptions for the purposes of subcommand testing.
set -l scripts (__fish__get_bun_scripts)
if __fish_seen_subcommand_from (string split \t -f 1 -- $scripts)
return
end
# Emit scripts.
for script in $scripts
echo $script
end
# Emit binaries and JS files (but only if we're doing `bun run`).
if __fish_seen_subcommand_from run
for bin in $bins
echo "$bin"\t"package bin"
end
for file in (__fish__get_bun_bun_js_files)
echo "$file"\t"Bun.js"
end
end
end
# Clear existing completions
complete -e -c bun
# Dynamically emit scripts and binaries
complete -c bun -f -a "(__bun_complete_bins_scripts)"
# Complete flags if we have no subcommand or a flag-friendly one.
set -l flag_applies "__fish_use_subcommand; or __fish_seen_subcommand_from $bun_builtin_cmds_accepting_flags"
complete -c bun \
-n $flag_applies --no-files -s 'u' -l 'origin' -r -d 'Server URL. Rewrites import paths'
complete -c bun \
-n $flag_applies --no-files -s 'p' -l 'port' -r -d 'Port number to start server from'
complete -c bun \
-n $flag_applies --no-files -s 'd' -l 'define' -r -d 'Substitute K:V while parsing, e.g. --define process.env.NODE_ENV:\"development\"'
complete -c bun \
-n $flag_applies --no-files -s 'e' -l 'external' -r -d 'Exclude module from transpilation (can use * wildcards). ex: -e react'
complete -c bun \
-n $flag_applies --no-files -l 'use' -r -d 'Use a framework (ex: next)'
complete -c bun \
-n $flag_applies --no-files -l 'hot' -r -d 'Enable hot reloading in Bun\'s JavaScript runtime'
# Complete dev and create as first subcommand.
complete -c bun \
-n "__fish_use_subcommand" -a 'dev' -d 'Start dev server'
complete -c bun \
-n "__fish_use_subcommand" -a 'create' -f -d 'Create a new project from a template'
# Complete "next" and "react" if we've seen "create".
complete -c bun \
-n "__fish_seen_subcommand_from create" -a 'next' -d 'new Next.js project'
complete -c bun \
-n "__fish_seen_subcommand_from create" -a 'react' -d 'new React project'
# Complete "upgrade" as first subcommand.
complete -c bun \
-n "__fish_use_subcommand" -a 'upgrade' -d 'Upgrade bun to the latest version' -x
# Complete "-h/--help" unconditionally.
complete -c bun \
-s "h" -l "help" -d 'See all commands and flags' -x
# Complete "-v/--version" if we have no subcommand.
complete -c bun \
-n "not __fish_use_subcommand" -l "version" -s "v" -d 'Bun\'s version' -x
# Complete additional subcommands.
complete -c bun \
-n "__fish_use_subcommand" -a 'discord' -d 'Open bun\'s Discord server' -x
complete -c bun \
-n "__fish_use_subcommand" -a 'bun' -d 'Generate a new bundle'
complete -c bun \
-n "__fish_seen_subcommand_from bun" -F -d 'Bundle this'
complete -c bun \
-n "__fish_seen_subcommand_from create; and __fish_seen_subcommand_from react next" -F -d "Create in directory"
complete -c bun \
-n "__fish_use_subcommand" -a 'init' -F -d 'Start an empty Bun project'
complete -c bun \
-n "__fish_use_subcommand" -a 'install' -f -d 'Install packages from package.json'
complete -c bun \
-n "__fish_use_subcommand" -a 'add' -F -d 'Add a package to package.json'
complete -c bun \
-n "__fish_use_subcommand" -a 'remove' -F -d 'Remove a package from package.json'
for i in (seq (count $bun_install_boolean_flags))
complete -c bun \
-n "__fish_seen_subcommand_from install add remove" -l "$bun_install_boolean_flags[$i]" -d "$bun_install_boolean_flags_descriptions[$i]"
end
complete -c bun \
-n "__fish_seen_subcommand_from install add remove" -l 'cwd' -d 'Change working directory'
complete -c bun \
-n "__fish_seen_subcommand_from install add remove" -l 'cache-dir' -d 'Choose a cache directory (default: $HOME/.bun/install/cache)'
complete -c bun \
-n "__fish_seen_subcommand_from add" -d 'Popular' -a '(__fish__get_bun_packages)'
complete -c bun \
-n "__fish_seen_subcommand_from add" -d 'History' -a '(__history_completions)'
complete -c bun \
-n "__fish_seen_subcommand_from pm; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts) cache;" -a 'bin ls cache hash hash-print hash-string' -f
complete -c bun \
-n "__fish_seen_subcommand_from pm; and __fish_seen_subcommand_from cache; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts);" -a 'rm' -f
# Add built-in subcommands with descriptions.
complete -c bun -n "__fish_use_subcommand" -a "create" -f -d "Create a new project from a template"
complete -c bun -n "__fish_use_subcommand" -a "build bun" --require-parameter -F -d "Transpile and bundle one or more files"
complete -c bun -n "__fish_use_subcommand" -a "upgrade" -d "Upgrade Bun"
complete -c bun -n "__fish_use_subcommand" -a "run" -d "Run a script or package binary"
complete -c bun -n "__fish_use_subcommand" -a "install" -d "Install dependencies from package.json" -f
complete -c bun -n "__fish_use_subcommand" -a "remove" -d "Remove a dependency from package.json" -f
complete -c bun -n "__fish_use_subcommand" -a "add" -d "Add a dependency to package.json" -f
complete -c bun -n "__fish_use_subcommand" -a "init" -d "Initialize a Bun project in this directory" -f
complete -c bun -n "__fish_use_subcommand" -a "link" -d "Register or link a local npm package" -f
complete -c bun -n "__fish_use_subcommand" -a "unlink" -d "Unregister a local npm package" -f
complete -c bun -n "__fish_use_subcommand" -a "pm" -d "Additional package management utilities" -f
complete -c bun -n "__fish_use_subcommand" -a "x" -d "Execute a package binary, installing if needed" -f
complete -c bun -n "__fish_use_subcommand" -a "outdated" -d "Display the latest versions of outdated dependencies" -f

View File

@ -1,3 +0,0 @@
if test -f ~/.cargo/env.fish
source ~/.cargo/env.fish
end

View File

@ -1,6 +1,3 @@
set -xg EDITOR vim
set -xg TZ 'America/Detroit'
if test -d ~/Maildir if test -d ~/Maildir
set -x MAIL ~/Maildir set -x MAIL ~/Maildir
end end
@ -29,7 +26,6 @@ if status --is-interactive && type -q rbenv
end end
end end
#set -x SSH_AGENT_PID ""
if test -S $HOME/.gnupg/S.gpg-agent if test -S $HOME/.gnupg/S.gpg-agent
set -x SSH_AUTH_SOCK $HOME/.gnupg/S.gpg-agent set -x SSH_AUTH_SOCK $HOME/.gnupg/S.gpg-agent
set -x GPG_SOCK $HOME/.gnupg/S.gpg-agent set -x GPG_SOCK $HOME/.gnupg/S.gpg-agent
@ -37,10 +33,6 @@ else
type -q gpgconf && set -x SSH_AUTH_SOCK (gpgconf --list-dirs agent-ssh-socket) type -q gpgconf && set -x SSH_AUTH_SOCK (gpgconf --list-dirs agent-ssh-socket)
end end
set -x BBJ_USER $USER
set -x DEBEMAIL ben@tilde.team
set -x DEBFULLNAME "Ben Harris"
# add dotnet completions if needed # add dotnet completions if needed
if status --is-interactive && type -q dotnet if status --is-interactive && type -q dotnet
complete -f -c dotnet -a "(dotnet complete)" complete -f -c dotnet -a "(dotnet complete)"

View File

@ -1,40 +1,54 @@
# This file contains fish universal variable definitions. # This file contains fish universal variable definitions.
# VERSION: 3.0 # VERSION: 3.0
SETUVAR --export BBJ_USER:ben
SETUVAR --export DEBEMAIL:ben\x40tilde\x2eteam SETUVAR --export DEBEMAIL:ben\x40tilde\x2eteam
SETUVAR --export DEBFULLNAME:Ben\x20Harris
SETUVAR DOTNET_CLI_TELEMETRY_OPTOUT:1 SETUVAR DOTNET_CLI_TELEMETRY_OPTOUT:1
SETUVAR --export EDITOR:vim
SETUVAR EMAIL:ben\x40tilde\x2eteam SETUVAR EMAIL:ben\x40tilde\x2eteam
SETUVAR --export TZ:America/Detroit
SETUVAR __fish_init_2_39_8:\x1d SETUVAR __fish_init_2_39_8:\x1d
SETUVAR __fish_init_2_3_0:\x1d SETUVAR __fish_init_2_3_0:\x1d
SETUVAR __fish_init_3_x:\x1d SETUVAR __fish_init_3_x:\x1d
SETUVAR __fish_initialized:3400 SETUVAR __fish_initialized:3800
SETUVAR fish_color_autosuggestion:555\x1ebrblack SETUVAR fish_color_autosuggestion:brblack
SETUVAR fish_color_cancel:\x2dr SETUVAR fish_color_cancel:\x2dr
SETUVAR fish_color_command:\x2d\x2dbold SETUVAR fish_color_command:normal
SETUVAR fish_color_comment:990000 SETUVAR fish_color_comment:red
SETUVAR fish_color_cwd:green SETUVAR fish_color_cwd:green
SETUVAR fish_color_cwd_root:red SETUVAR fish_color_cwd_root:red
SETUVAR fish_color_end:009900 SETUVAR fish_color_end:green
SETUVAR fish_color_error:ff0000 SETUVAR fish_color_error:brred
SETUVAR fish_color_escape:00a6b2 SETUVAR fish_color_escape:brcyan
SETUVAR fish_color_history_current:\x2d\x2dbold SETUVAR fish_color_history_current:\x2d\x2dbold
SETUVAR fish_color_host:normal SETUVAR fish_color_host:normal
SETUVAR fish_color_host_remote:yellow SETUVAR fish_color_host_remote:yellow
SETUVAR fish_color_keyword:normal
SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue
SETUVAR fish_color_normal:normal SETUVAR fish_color_normal:normal
SETUVAR fish_color_operator:00a6b2 SETUVAR fish_color_operator:brcyan
SETUVAR fish_color_param:00afff SETUVAR fish_color_option:cyan
SETUVAR fish_color_quote:999900 SETUVAR fish_color_param:cyan
SETUVAR fish_color_redirection:00afff SETUVAR fish_color_quote:yellow
SETUVAR fish_color_redirection:cyan\x1e\x2d\x2dbold
SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack
SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack
SETUVAR fish_color_status:990000 SETUVAR fish_color_status:red
SETUVAR fish_color_user:brgreen SETUVAR fish_color_user:brgreen
SETUVAR fish_color_valid_path:\x2d\x2dunderline SETUVAR fish_color_valid_path:\x2d\x2dunderline
SETUVAR fish_greeting:Welcome\x20to\x20fish\x2c\x20the\x20friendly\x20interactive\x20shell SETUVAR fish_greeting:Welcome\x20to\x20fish\x2c\x20the\x20friendly\x20interactive\x20shell
SETUVAR fish_key_bindings:fish_default_key_bindings SETUVAR fish_key_bindings:fish_default_key_bindings
SETUVAR fish_pager_color_background:\x1d
SETUVAR fish_pager_color_completion:normal SETUVAR fish_pager_color_completion:normal
SETUVAR fish_pager_color_description:B3A06D\x1eyellow SETUVAR fish_pager_color_description:yellow\x1e\x2di
SETUVAR fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline SETUVAR fish_pager_color_prefix:normal\x1e\x2d\x2dbold\x1e\x2d\x2dunderline
SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan
SETUVAR fish_pager_color_secondary_background:\x1d
SETUVAR fish_pager_color_secondary_completion:\x1d
SETUVAR fish_pager_color_secondary_description:\x1d
SETUVAR fish_pager_color_secondary_prefix:\x1d
SETUVAR fish_pager_color_selected_background:\x2dr SETUVAR fish_pager_color_selected_background:\x2dr
SETUVAR fish_pager_color_selected_completion:\x1d
SETUVAR fish_pager_color_selected_description:\x1d
SETUVAR fish_pager_color_selected_prefix:\x1d
SETUVAR fisher_dependency_count:bass\x1edone\x1egetopts\x1egitignore\x1ehumanize_duration\x1envm\x1espin SETUVAR fisher_dependency_count:bass\x1edone\x1egetopts\x1egitignore\x1ehumanize_duration\x1envm\x1espin

View File

@ -74,3 +74,6 @@
sort = version:refname sort = version:refname
[safe] [safe]
directory = * directory = *
[fetch]
prune = true
all = true

View File

@ -14,4 +14,3 @@ instant = on
timer = 1 timer = 1
[buffer] [buffer]
irc.tilde.#trivia.hotlist_max_level_nicks_add = "Oz:2,Nerd:2"

View File

@ -25,7 +25,7 @@ use_items = 1
[format] [format]
buffer = "${format_number}${indent}${format_nick_prefix}${color_hotlist}${if:(${buffer.full_name} =~ ^irc)?${if:(${irc_server.away_time} > 0)?${color:yellow}>}${if:(${irc_channel.part} == 1)?${color:red}_}${if:(${irc_server.is_connected} == 0)?${color:*magenta}*}}${if:${type}==private?↪}${name}" buffer = "${format_number}${indent}${format_nick_prefix}${color_hotlist}${if:(${buffer.full_name} =~ ^irc)?${if:(${irc_server.away_time} > 0)?${color:yellow}>}${if:(${irc_channel.part} == 1)?${color:red}_}${if:(${irc_server.is_connected} == 0)?${color:*magenta}*}}${if:${type}==private?↪}${name}"
buffer_current = "${color:,233}${format_number}${indent}${format_nick_prefix}${color:lightcyan}${name}" buffer_current = "${color:,darkgray}${format_number}${indent}${format_nick_prefix}${color:yellow}${name}"
hotlist = " ${color:green}(${hotlist}${color:green})" hotlist = " ${color:green}(${hotlist}${color:green})"
hotlist_highlight = "${color:magenta}" hotlist_highlight = "${color:magenta}"
hotlist_low = "${color:default}" hotlist_low = "${color:default}"

View File

@ -51,7 +51,7 @@ join_auto_add_chantype = off
list_buffer = on list_buffer = on
list_buffer_format_export = "${name} (${users}): "${topic}"" list_buffer_format_export = "${name} (${users}): "${topic}""
list_buffer_scroll_horizontal = 10 list_buffer_scroll_horizontal = 10
list_buffer_sort = "~name2" list_buffer_sort = "-users"
list_buffer_topic_strip_colors = on list_buffer_topic_strip_colors = on
msgbuffer_fallback = current msgbuffer_fallback = current
new_channel_position = none new_channel_position = none
@ -62,6 +62,7 @@ nick_mode = both
nick_mode_empty = off nick_mode_empty = off
nicks_hide_password = "nickserv" nicks_hide_password = "nickserv"
notice_as_pv = auto notice_as_pv = auto
notice_nicks_disable_notify = "chanserv,nickserv"
notice_welcome_redirect = on notice_welcome_redirect = on
notice_welcome_tags = "" notice_welcome_tags = ""
notify_tags_ison = "notify_message" notify_tags_ison = "notify_message"
@ -219,7 +220,7 @@ tilde.usermode
tilde.command_delay tilde.command_delay
tilde.command = "/msg idlerpg_bot login wowbagger ${sec.data.idlerpgpass}" tilde.command = "/msg idlerpg_bot login wowbagger ${sec.data.idlerpgpass}"
tilde.autojoin_delay tilde.autojoin_delay
tilde.autojoin = "#opers,#.tilde,#adventofcode,#anelki,#ascii.town,#aussie,#binary-counting,#bots,#club,#cosmic,#counting,#covid19,#fr,#gemini,#gopher,#helpdesk,#idlerpg,#linux,#meta,#midgard,#netnews,#nsfw,#rw.rs,#secret-sudoers,#selfhosting,#team,#tilde.zone-admin,#tildebot,#tilderadio,#tilderadio-djs,#tildetel,#topm,#town,#vim,#wiki,#tilde.green,#tildeverse,#pink,#politics,#tilde.zone,#institute,#ctrl-c,#music,#zine" tilde.autojoin = "#opers,#.tilde,#adventofcode,#anelki,#ascii.town,#bots,#club,#cosmic,#covid19,#fr,#gemini,#gopher,#helpdesk,#idlerpg,#linux,#meta,#netnews,#nsfw,#rw.rs,#secret-sudoers,#selfhosting,#team,#tilde.zone-admin,#tildebot,#tilderadio,#tilderadio-djs,#topm,#town,#wiki,#tilde.green,#tildeverse,#pink,#politics,#tilde.zone,#institute,#ctrl-c,#music,#zine"
tilde.autojoin_dynamic tilde.autojoin_dynamic
tilde.autorejoin tilde.autorejoin
tilde.autorejoin_delay tilde.autorejoin_delay
@ -311,7 +312,7 @@ town.usermode
town.command_delay town.command_delay
town.command town.command
town.autojoin_delay town.autojoin_delay
town.autojoin = "#announcements,#bots,#counting,#tildetown" town.autojoin = "#announcements,#bots,#counting,#tildetown,#sickos.net"
town.autojoin_dynamic town.autojoin_dynamic
town.autorejoin town.autorejoin
town.autorejoin_delay town.autorejoin_delay
@ -449,7 +450,7 @@ oftc.usermode
oftc.command_delay oftc.command_delay
oftc.command oftc.command
oftc.autojoin_delay oftc.autojoin_delay
oftc.autojoin = "#bitlbee,#debian-devel,#fish,#salsa,#tilde.team" oftc.autojoin = "#bitlbee,#debian-devel,#fish,#osm"
oftc.autojoin_dynamic oftc.autojoin_dynamic
oftc.autorejoin oftc.autorejoin
oftc.autorejoin_delay oftc.autorejoin_delay
@ -511,10 +512,10 @@ blinkenshell.split_msg_max_length
blinkenshell.charset_message blinkenshell.charset_message
blinkenshell.default_chantypes blinkenshell.default_chantypes
blinkenshell.registered_mode blinkenshell.registered_mode
inspircd.addresses = "irc.inspircd.org" inspircd.addresses = "irc.teranova.net/6697"
inspircd.proxy inspircd.proxy
inspircd.ipv6 inspircd.ipv6
inspircd.tls inspircd.tls = on
inspircd.tls_cert inspircd.tls_cert
inspircd.tls_password inspircd.tls_password
inspircd.tls_priorities inspircd.tls_priorities
@ -692,98 +693,6 @@ libera.split_msg_max_length
libera.charset_message libera.charset_message
libera.default_chantypes libera.default_chantypes
libera.registered_mode libera.registered_mode
ergo.addresses = "irc.ergo.chat/6697"
ergo.proxy
ergo.ipv6
ergo.tls = on
ergo.tls_cert
ergo.tls_password
ergo.tls_priorities
ergo.tls_dhkey_size
ergo.tls_fingerprint
ergo.tls_verify
ergo.password
ergo.capabilities
ergo.sasl_mechanism = external
ergo.sasl_username
ergo.sasl_password
ergo.sasl_key
ergo.sasl_timeout
ergo.sasl_fail
ergo.autoconnect
ergo.autoreconnect
ergo.autoreconnect_delay
ergo.nicks = "ben"
ergo.nicks_alternate
ergo.username
ergo.realname
ergo.local_hostname
ergo.usermode
ergo.command_delay
ergo.command
ergo.autojoin_delay
ergo.autojoin = "#ergo"
ergo.autojoin_dynamic
ergo.autorejoin
ergo.autorejoin_delay
ergo.connection_timeout
ergo.anti_flood
ergo.away_check
ergo.away_check_max_nicks
ergo.msg_kick
ergo.msg_part
ergo.msg_quit
ergo.notify
ergo.split_msg_max_length
ergo.charset_message
ergo.default_chantypes
ergo.registered_mode
snoonet.addresses = "irc.snoonet.org/6697"
snoonet.proxy
snoonet.ipv6
snoonet.tls = on
snoonet.tls_cert
snoonet.tls_password
snoonet.tls_priorities
snoonet.tls_dhkey_size
snoonet.tls_fingerprint
snoonet.tls_verify
snoonet.password
snoonet.capabilities
snoonet.sasl_mechanism
snoonet.sasl_username = "benharri"
snoonet.sasl_password = "${sec.data.snoonetpass}"
snoonet.sasl_key
snoonet.sasl_timeout
snoonet.sasl_fail
snoonet.autoconnect
snoonet.autoreconnect
snoonet.autoreconnect_delay
snoonet.nicks
snoonet.nicks_alternate
snoonet.username
snoonet.realname
snoonet.local_hostname
snoonet.usermode
snoonet.command_delay
snoonet.command
snoonet.autojoin_delay
snoonet.autojoin = "#personalfinance"
snoonet.autojoin_dynamic
snoonet.autorejoin
snoonet.autorejoin_delay
snoonet.connection_timeout
snoonet.anti_flood
snoonet.away_check
snoonet.away_check_max_nicks
snoonet.msg_kick
snoonet.msg_part
snoonet.msg_quit
snoonet.notify
snoonet.split_msg_max_length
snoonet.charset_message
snoonet.default_chantypes
snoonet.registered_mode
m455.addresses = "m455.casa/6697" m455.addresses = "m455.casa/6697"
m455.proxy m455.proxy
m455.ipv6 m455.ipv6
@ -814,7 +723,7 @@ m455.usermode
m455.command_delay m455.command_delay
m455.command m455.command
m455.autojoin_delay m455.autojoin_delay
m455.autojoin = "#basement,#serverroom,#siliconpals" m455.autojoin = "#basement"
m455.autojoin_dynamic m455.autojoin_dynamic
m455.autorejoin m455.autorejoin
m455.autorejoin_delay m455.autorejoin_delay
@ -830,52 +739,6 @@ m455.split_msg_max_length
m455.charset_message m455.charset_message
m455.default_chantypes m455.default_chantypes
m455.registered_mode m455.registered_mode
hackint.addresses = "irc.hackint.org/6697"
hackint.proxy
hackint.ipv6
hackint.tls = on
hackint.tls_cert
hackint.tls_password
hackint.tls_priorities
hackint.tls_dhkey_size
hackint.tls_fingerprint
hackint.tls_verify
hackint.password
hackint.capabilities
hackint.sasl_mechanism
hackint.sasl_username = "ben"
hackint.sasl_password = "${sec.data.hackintpass}"
hackint.sasl_key
hackint.sasl_timeout
hackint.sasl_fail
hackint.autoconnect
hackint.autoreconnect
hackint.autoreconnect_delay
hackint.nicks
hackint.nicks_alternate
hackint.username
hackint.realname
hackint.local_hostname
hackint.usermode
hackint.command_delay
hackint.command
hackint.autojoin_delay
hackint.autojoin = ""
hackint.autojoin_dynamic
hackint.autorejoin
hackint.autorejoin_delay
hackint.connection_timeout
hackint.anti_flood
hackint.away_check
hackint.away_check_max_nicks
hackint.msg_kick
hackint.msg_part
hackint.msg_quit
hackint.notify
hackint.split_msg_max_length
hackint.charset_message
hackint.default_chantypes
hackint.registered_mode
syn.addresses = "irc.us.synirc.net/6697" syn.addresses = "irc.us.synirc.net/6697"
syn.proxy syn.proxy
syn.ipv6 syn.ipv6
@ -968,3 +831,49 @@ efnet.split_msg_max_length
efnet.charset_message efnet.charset_message
efnet.default_chantypes efnet.default_chantypes
efnet.registered_mode efnet.registered_mode
twitch.addresses = "irc.chat.twitch.tv"
twitch.proxy
twitch.ipv6
twitch.tls
twitch.tls_cert
twitch.tls_password
twitch.tls_priorities
twitch.tls_dhkey_size
twitch.tls_fingerprint
twitch.tls_verify
twitch.password = "${sec.data.twitchoauth}"
twitch.capabilities
twitch.sasl_mechanism
twitch.sasl_username
twitch.sasl_password
twitch.sasl_key
twitch.sasl_timeout
twitch.sasl_fail
twitch.autoconnect
twitch.autoreconnect
twitch.autoreconnect_delay
twitch.nicks = "harriben"
twitch.nicks_alternate
twitch.username
twitch.realname
twitch.local_hostname
twitch.usermode
twitch.command_delay
twitch.command
twitch.autojoin_delay
twitch.autojoin = ""
twitch.autojoin_dynamic
twitch.autorejoin
twitch.autorejoin_delay
twitch.connection_timeout
twitch.anti_flood
twitch.away_check
twitch.away_check_max_nicks
twitch.msg_kick
twitch.msg_part
twitch.msg_quit
twitch.notify
twitch.split_msg_max_length
twitch.charset_message
twitch.default_chantypes
twitch.registered_mode

View File

@ -13,18 +13,6 @@
fifo.fifo = "on" fifo.fifo = "on"
guile.check_license = "off" guile.check_license = "off"
lua.check_license = "off" lua.check_license = "off"
lua.matrix.backlog_lines = "120"
lua.matrix.debug = "off"
lua.matrix.encrypted_message_color = "lightgreen"
lua.matrix.homeserver_url = "https://l4p1n.ch/"
lua.matrix.local_echo = "on"
lua.matrix.nick_style = "nick"
lua.matrix.password = "${sec.data.matrixpw}"
lua.matrix.presence_filter = "off"
lua.matrix.read_receipts = "on"
lua.matrix.timeout = "5"
lua.matrix.typing_notices = "on"
lua.matrix.user = "ben"
perl.check_license = "off" perl.check_license = "off"
perl.colorize_lines.alternate_color = "" perl.colorize_lines.alternate_color = ""
perl.colorize_lines.blacklist_buffers = "" perl.colorize_lines.blacklist_buffers = ""
@ -35,7 +23,7 @@ perl.colorize_lines.highlight_words = "off"
perl.colorize_lines.highlight_words_color = "" perl.colorize_lines.highlight_words_color = ""
perl.colorize_lines.ignore_tags = "irc_ctcp" perl.colorize_lines.ignore_tags = "irc_ctcp"
perl.colorize_lines.lines = "nicks" perl.colorize_lines.lines = "nicks"
perl.colorize_lines.nicks = "benharri,ben,bhh" perl.colorize_lines.nicks = "benharri,ben"
perl.colorize_lines.own_lines = "off" perl.colorize_lines.own_lines = "off"
perl.colorize_lines.own_lines_color = "" perl.colorize_lines.own_lines_color = ""
perl.colorize_lines.tags = "irc_privmsg" perl.colorize_lines.tags = "irc_privmsg"
@ -50,16 +38,6 @@ perl.highmon.nick_prefix = "<"
perl.highmon.nick_suffix = ">" perl.highmon.nick_suffix = ">"
perl.highmon.output = "buffer" perl.highmon.output = "buffer"
perl.highmon.short_names = "off" perl.highmon.short_names = "off"
perl.rslap.slapback = "random"
python.apply_corrections.check_every = "5"
python.apply_corrections.data_timeout = "60"
python.apply_corrections.message_limit = "2"
python.apply_corrections.print_format = "[nick]: [corrected]"
python.apply_corrections.print_limit = "1"
python.autojoin.autosave = "off"
python.autosavekey.add = "on"
python.autosavekey.mute = "off"
python.autosavekey.secure = "on"
python.buffer_autoclose.age_limit = "30" python.buffer_autoclose.age_limit = "30"
python.buffer_autoclose.ignore = "bitlbee.marley" python.buffer_autoclose.ignore = "bitlbee.marley"
python.buffer_autoclose.interval = "1" python.buffer_autoclose.interval = "1"
@ -67,7 +45,7 @@ python.buffer_autoclose.prefer = ""
python.check_license = "off" python.check_license = "off"
python.completion.replace_values = "shrug=>¯\_(ツ)_/¯;;wiki=>https://tilde.team/wiki/;;sword=>o()xxxx[{::::::::::::::::::::::::::::::::::>;;lenny=>( ͡° ͜ʖ ͡°);;byobu=>https://superuser.com/a/423397/866501;;fg=>(☞゚ヮ゚)☞;;huh=>(-_-)ゞ゛;;tablefix=>┬─┬ノ( º _ ºノ);;weedoc=>https://weechat.org/files/doc/stable/weechat_user.en.html;;weekeys=>https://weechat.org/files/doc/stable/weechat_user.en.html#key_bindings;;denko=>(´・ω・`);;yuno=>ლ(́ಠ◞益◟ಠ‵ლ);;tf=>(ノಥ益ಥ)ノ彡┻━┻;;tb=>┬─┬ノ( º _ ºノ);;ducc=>・゜゜・。。・゜゜\_o< QUACK!;;wat=>https://bhh.sh/wat.jpg;;matrix=>https://www.moparisthebest.com/images/xmpp-vs-matrix.jpg;;servers=>https://tilde.wiki/wiki/User:Ben/Servers;;nft=>https://youtu.be/YQ_xWvX1n9g" python.completion.replace_values = "shrug=>¯\_(ツ)_/¯;;wiki=>https://tilde.team/wiki/;;sword=>o()xxxx[{::::::::::::::::::::::::::::::::::>;;lenny=>( ͡° ͜ʖ ͡°);;byobu=>https://superuser.com/a/423397/866501;;fg=>(☞゚ヮ゚)☞;;huh=>(-_-)ゞ゛;;tablefix=>┬─┬ノ( º _ ºノ);;weedoc=>https://weechat.org/files/doc/stable/weechat_user.en.html;;weekeys=>https://weechat.org/files/doc/stable/weechat_user.en.html#key_bindings;;denko=>(´・ω・`);;yuno=>ლ(́ಠ◞益◟ಠ‵ლ);;tf=>(ノಥ益ಥ)ノ彡┻━┻;;tb=>┬─┬ノ( º _ ºノ);;ducc=>・゜゜・。。・゜゜\_o< QUACK!;;wat=>https://bhh.sh/wat.jpg;;matrix=>https://www.moparisthebest.com/images/xmpp-vs-matrix.jpg;;servers=>https://tilde.wiki/wiki/User:Ben/Servers;;nft=>https://youtu.be/YQ_xWvX1n9g"
python.go.auto_jump = "off" python.go.auto_jump = "off"
python.go.buffer_number = "on" python.go.buffer_number = "off"
python.go.color_name = "black,cyan" python.go.color_name = "black,cyan"
python.go.color_name_highlight = "red,cyan" python.go.color_name_highlight = "red,cyan"
python.go.color_name_highlight_selected = "red,brown" python.go.color_name_highlight_selected = "red,brown"
@ -89,12 +67,6 @@ python.grep.max_lines = "4000"
python.grep.show_summary = "on" python.grep.show_summary = "on"
python.grep.size_limit = "2048" python.grep.size_limit = "2048"
python.grep.timeout_secs = "300" python.grep.timeout_secs = "300"
python.listbuffer.autofocus = "on"
python.listbuffer.channel_min_width = "25"
python.listbuffer.modes_min_width = "8"
python.listbuffer.sort_inverted = "off"
python.listbuffer.sort_order = "users"
python.listbuffer.users_min_width = "8"
python.screen_away.away_suffix = "" python.screen_away.away_suffix = ""
python.screen_away.command_on_attach = "" python.screen_away.command_on_attach = ""
python.screen_away.command_on_detach = "" python.screen_away.command_on_detach = ""
@ -106,51 +78,6 @@ python.screen_away.no_output = "off"
python.screen_away.set_away = "on" python.screen_away.set_away = "on"
python.screen_away.socket_file = "" python.screen_away.socket_file = ""
python.screen_away.time_format = "since %Y-%m-%d %H:%M:%S%z" python.screen_away.time_format = "since %Y-%m-%d %H:%M:%S%z"
python.slack.auto_open_threads = "false"
python.slack.background_load_all_history = "false"
python.slack.channel_name_typing_indicator = "true"
python.slack.color_buflist_muted_channels = "darkgray"
python.slack.color_deleted = "red"
python.slack.color_edited_suffix = "095"
python.slack.color_reaction_suffix = "darkgray"
python.slack.color_reaction_suffix_added_by_you = "blue"
python.slack.color_thread_suffix = "lightcyan"
python.slack.color_typing_notice = "yellow"
python.slack.colorize_attachments = "prefix"
python.slack.colorize_private_chats = "false"
python.slack.debug_level = "3"
python.slack.debug_mode = "false"
python.slack.distracting_channels = ""
python.slack.external_user_suffix = "*"
python.slack.files_download_location = ""
python.slack.group_name_prefix = "&"
python.slack.history_fetch_count = "200"
python.slack.map_underline_to = "_"
python.slack.migrated = "true"
python.slack.muted_channels_activity = "personal_highlights"
python.slack.never_away = "false"
python.slack.notify_subscribed_threads = "auto"
python.slack.notify_usergroup_handle_updated = "false"
python.slack.record_events = "false"
python.slack.render_bold_as = "bold"
python.slack.render_emoji_as_string = "false"
python.slack.render_italic_as = "italic"
python.slack.send_typing_notice = "true"
python.slack.server_aliases = ""
python.slack.shared_name_prefix = "%"
python.slack.short_buffer_names = "false"
python.slack.show_buflist_presence = "true"
python.slack.show_reaction_nicks = "false"
python.slack.slack_api_token = "${sec.data.remotesslacktoken}"
python.slack.slack_timeout = "20000"
python.slack.switch_buffer_on_join = "true"
python.slack.thread_messages_in_channel = "false"
python.slack.unfurl_auto_link_display = "both"
python.slack.unfurl_ignore_alt_text = "false"
python.slack.unhide_buffers_with_activity = "false"
python.slack.use_full_names = "false"
python.topicdiff_alt.color_del = "darkgray"
python.topicdiff_alt.color_ins = "lightcyan"
ruby.check_license = "off" ruby.check_license = "off"
tcl.check_license = "off" tcl.check_license = "off"

View File

@ -1 +0,0 @@
../buffer_autoset.py

View File

@ -1,351 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2017 Sébastien Helleu <flashcode@flashtux.org>
#
# 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/>.
#
#
# Auto-set buffer properties when a buffer is opened.
# (this script requires WeeChat 1.0 or newer)
#
# History:
#
# 2021-06-02, Sébastien Helleu <flashcode@flashtux.org>:
# version 1.2: fix /help buffer_autoset
# 2018-04-14, Kim B. Heino:
# version 1.1: on startup apply settings to already opened buffers
# 2017-06-21, Sébastien Helleu <flashcode@flashtux.org>:
# version 1.0: rename command /autosetbuffer to /buffer_autoset
# 2015-09-28, Simmo Saan <simmo.saan@gmail.com>:
# version 0.9: instantly apply properties
# 2015-07-12, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.8: add option buffer_autoset.look.timer to add a small timer
# before setting buffer properties
# 2015-04-05, Nils Görs <libera@#weechat>:
# version 0.7: increase priority of hook_signal('buffer_opened')
# 2012-12-09, Nils Görs <libera@#weechat>:
# version 0.6: add support of core buffer
# 2012-03-09, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.5: fix reload of config file
# 2012-01-03, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.4: make script compatible with Python 3.x
# 2010-12-02, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.3: "no_highlight_nicks" replaced by "hotlist_max_level_nicks"
# 2010-10-11, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.2: add example in /help autosetbuffer with new buffer
# property "no_highlight_nicks"
# 2010-04-19, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.1: initial release
#
SCRIPT_NAME = "buffer_autoset"
SCRIPT_AUTHOR = "Sébastien Helleu <flashcode@flashtux.org>"
SCRIPT_VERSION = "1.2"
SCRIPT_LICENSE = "GPL3"
SCRIPT_DESC = "Auto-set buffer properties when a buffer is opened"
SCRIPT_COMMAND = SCRIPT_NAME
import_ok = True
try:
import weechat
except ImportError:
print("This script must be run under WeeChat.")
print("Get WeeChat now at: http://www.weechat.org/")
import_ok = False
CONFIG_FILE_NAME = "buffer_autoset"
# config file / options
bas_config_file = ""
bas_options = {}
# =================================[ config ]=================================
def bas_config_init():
"""
Initialization of configuration file.
Sections: buffer.
"""
global bas_config_file, bas_options
bas_config_file = weechat.config_new(CONFIG_FILE_NAME,
"bas_config_reload_cb", "")
if bas_config_file == "":
return
# section "look"
section_look = weechat.config_new_section(
bas_config_file, "look", 0, 0, "", "", "", "", "", "", "", "", "", "")
if not section_look:
weechat.config_free(bas_config_file)
return
# options in section "look"
bas_options["look_timer"] = weechat.config_new_option(
bas_config_file, section_look, "timer", "integer",
"Timer used to delay the set of properties (in milliseconds, "
"0 = don't use a timer)",
"", 0, 2147483647, "1", "1", 0, "", "", "", "", "", "")
bas_options["look_instant"] = weechat.config_new_option(
bas_config_file, section_look, "instant", "boolean",
"Instantly apply properties to buffers affected",
"", 0, 0, "on", "on", 0, "", "", "", "", "", "")
# section "buffer"
section_buffer = weechat.config_new_section(
bas_config_file, "buffer", 1, 1, "", "", "", "", "", "",
"bas_config_buffer_create_option_cb", "", "", "")
if not section_buffer:
weechat.config_free(bas_config_file)
return
def bas_config_buffer_create_option_cb(data, config_file, section, option_name,
value):
option = weechat.config_search_option(config_file, section, option_name)
if option:
return weechat.config_option_set(option, value, 1)
else:
option = weechat.config_new_option(config_file, section, option_name,
"string", "", "", 0, 0, "",
value, 0, "", "", "", "", "", "")
if not option:
return weechat.WEECHAT_CONFIG_OPTION_SET_ERROR
return weechat.WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE
def bas_config_reload_cb(data, config_file):
"""Reload configuration file."""
return weechat.config_reload(config_file)
def bas_config_read():
"""Read configuration file."""
global bas_config_file
return weechat.config_read(bas_config_file)
def bas_config_write():
"""Write configuration file."""
global bas_config_file
return weechat.config_write(bas_config_file)
# ================================[ command ]=================================
def bas_cmd(data, buffer, args):
"""Callback for /buffer_autoset command."""
args = args.strip()
if args == "":
weechat.command("", "/set %s.buffer.*" % CONFIG_FILE_NAME)
return weechat.WEECHAT_RC_OK
argv = args.split(None, 3)
if len(argv) > 0:
if argv[0] == "add":
if len(argv) < 4:
weechat.command("", "/help %s" % SCRIPT_COMMAND)
return weechat.WEECHAT_RC_OK
weechat.command("", "/set %s.buffer.%s.%s \"%s\""
% (CONFIG_FILE_NAME, argv[1], argv[2], argv[3]))
elif argv[0] == "del":
if len(argv) < 2:
weechat.command("", "/help %s" % SCRIPT_COMMAND)
return weechat.WEECHAT_RC_OK
weechat.command("", "/unset %s.buffer.%s"
% (CONFIG_FILE_NAME, argv[1]))
else:
weechat.command("", "/help %s" % SCRIPT_COMMAND)
return weechat.WEECHAT_RC_OK
return weechat.WEECHAT_RC_OK
def bas_completion_current_buffer_cb(data, completion_item, buffer,
completion):
"""
Complete with current buffer name (plugin.name),
for command '/buffer_autoset'.
"""
name = "%s.%s" % (weechat.buffer_get_string(buffer, "plugin"),
weechat.buffer_get_string(buffer, "name"))
weechat.hook_completion_list_add(completion, name,
0, weechat.WEECHAT_LIST_POS_BEGINNING)
return weechat.WEECHAT_RC_OK
def bas_completion_options_cb(data, completion_item, buffer, completion):
"""Complete with config options, for command '/buffer_autoset'."""
options = weechat.infolist_get("option", "",
"%s.buffer.*" % CONFIG_FILE_NAME)
if options:
while weechat.infolist_next(options):
weechat.hook_completion_list_add(
completion,
weechat.infolist_string(options, "option_name"),
0, weechat.WEECHAT_LIST_POS_SORT)
weechat.infolist_free(options)
return weechat.WEECHAT_RC_OK
# ==========================[ timer/signal/option ]===========================
def bas_apply_options_for_buffer(buffer):
full_name = weechat.buffer_get_string(buffer, "full_name")
options = weechat.infolist_get("option", "",
"%s.buffer.*" % CONFIG_FILE_NAME)
if not options:
return
while weechat.infolist_next(options):
option = weechat.infolist_string(options, "option_name")
value = weechat.infolist_string(options, "value")
if option:
pos = option.rfind(".")
if pos > 0:
buffer_mask = option[0:pos]
property = option[pos+1:]
if buffer_mask and property:
if weechat.string_match(full_name, buffer_mask, 1):
weechat.buffer_set(buffer, property, value)
weechat.infolist_free(options)
def bas_timer_buffer_opened_cb(data, remaining_calls):
full_name = data
buffer = weechat.buffer_search("==", full_name)
if not buffer:
return weechat.WEECHAT_RC_OK
bas_apply_options_for_buffer(buffer)
return weechat.WEECHAT_RC_OK
def bas_signal_buffer_opened_cb(data, signal, signal_data):
global bas_options
buffer = signal_data
timer = weechat.config_integer(bas_options["look_timer"])
if timer == 0:
bas_apply_options_for_buffer(buffer)
else:
weechat.hook_timer(timer, 0, 1,
"bas_timer_buffer_opened_cb",
weechat.buffer_get_string(buffer, "full_name"))
return weechat.WEECHAT_RC_OK
def bas_config_option_cb(data, option, value):
if not weechat.config_boolean(bas_options["look_instant"]):
return weechat.WEECHAT_RC_OK
if not weechat.config_get(option): # option was deleted
return weechat.WEECHAT_RC_OK
option = option[len("%s.buffer." % CONFIG_FILE_NAME):]
pos = option.rfind(".")
if pos > 0:
buffer_mask = option[0:pos]
property = option[pos+1:]
if buffer_mask and property:
buffers = weechat.infolist_get("buffer", "", buffer_mask)
if not buffers:
return weechat.WEECHAT_RC_OK
while weechat.infolist_next(buffers):
buffer = weechat.infolist_pointer(buffers, "pointer")
weechat.buffer_set(buffer, property, value)
weechat.infolist_free(buffers)
return weechat.WEECHAT_RC_OK
# ==================================[ main ]==================================
if __name__ == "__main__" and import_ok:
if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
SCRIPT_LICENSE, SCRIPT_DESC, "bas_unload_script", ""):
version = weechat.info_get("version_number", "") or 0
if int(version) < 0x01000000:
weechat.prnt("", "%s%s: WeeChat 1.0 is required for this script."
% (weechat.prefix("error"), SCRIPT_NAME))
else:
bas_config_init()
bas_config_read()
weechat.hook_command(
SCRIPT_COMMAND,
"Auto-set buffer properties when a buffer is opened",
"[add buffer property value] | [del option]",
" add: add a buffer/property/value in configuration file\n"
" del: delete an option from configuration file\n"
" buffer: name of a buffer (wildcard \"*\" is allowed)\n"
"property: buffer property\n"
" value: value for property\n"
" option: name of option from configuration file\n\n"
"Examples:\n"
" disable timestamp on channel #weechat:\n"
" /" + SCRIPT_COMMAND + " add irc.libera.#weechat "
"time_for_each_line 0\n"
" add word \"weechat\" in highlight list on channel "
"#savannah:\n"
" /" + SCRIPT_COMMAND + " add irc.libera.#savannah "
"highlight_words_add weechat\n"
" disable highlights from nick \"mike\" on libera server, "
"channel #weechat (requires WeeChat >= 0.3.4):\n"
" /" + SCRIPT_COMMAND + " add irc.libera.#weechat "
"hotlist_max_level_nicks_add mike:2\n"
" disable hotlist changes for nick \"bot\" on libera "
"server (all channels) (requires WeeChat >= 0.3.4):\n"
" /" + SCRIPT_COMMAND + " add irc.libera.* "
"hotlist_max_level_nicks_add bot:-1",
"add %(buffers_plugins_names)|"
"%(buffer_autoset_current_buffer) "
"%(buffer_properties_set)"
" || del %(buffer_autoset_options)",
"bas_cmd", "")
weechat.hook_completion(
"buffer_autoset_current_buffer",
"current buffer name for buffer_autoset",
"bas_completion_current_buffer_cb", "")
weechat.hook_completion(
"buffer_autoset_options",
"list of options for buffer_autoset",
"bas_completion_options_cb", "")
weechat.hook_signal("9000|buffer_opened",
"bas_signal_buffer_opened_cb", "")
weechat.hook_config("%s.buffer.*" % CONFIG_FILE_NAME,
"bas_config_option_cb", "")
# apply settings to all already opened buffers
buffers = weechat.infolist_get("buffer", "", "")
if buffers:
while weechat.infolist_next(buffers):
buffer = weechat.infolist_pointer(buffers, "pointer")
bas_signal_buffer_opened_cb("", "", buffer)
weechat.infolist_free(buffers)
# ==================================[ end ]===================================
def bas_unload_script():
""" Function called when script is unloaded. """
global bas_config_file
if bas_config_file:
bas_config_write()
return weechat.WEECHAT_RC_OK

View File

@ -1,74 +0,0 @@
from typing import Iterator, Tuple
import weechat
SCRIPT_NAME = "fzf"
SCRIPT_AUTHOR = "Trygve Aaberge <trygveaa@gmail.com>"
SCRIPT_VERSION = "0.1.0"
SCRIPT_LICENSE = "MIT"
SCRIPT_DESC = "Switch buffer using fzf (currently only works inside tmux)"
REPO_URL = "https://github.com/trygveaa/weechat-fzf"
def print_error(message: str) -> None:
weechat.prnt("", weechat.prefix("error") + message)
def fzf_process_cb(
data: str, command: str, return_code: int, out: str, err: str
) -> int:
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR or return_code == 2 or err:
print_error("Error running fzf (code {}): {}".format(return_code, err))
return weechat.WEECHAT_RC_OK
if out != "":
pointer, _ = out.split("\t", 1)
weechat.buffer_set(pointer, "display", "1")
return weechat.WEECHAT_RC_OK
def fzf_command_cb(data: str, buffer: str, args: str) -> int:
cmd = (
"fzf-tmux -- --delimiter='\t' --with-nth=3.. "
"--preview='tail -$LINES {2} 2>/dev/null'"
)
hook = weechat.hook_process_hashtable(cmd, {"stdin": "1"}, 0, "fzf_process_cb", "")
for buffer_info in buffers():
weechat.hook_set(hook, "stdin", "\t".join(buffer_info) + "\n")
weechat.hook_set(hook, "stdin_close", "")
return weechat.WEECHAT_RC_OK
def buffers() -> Iterator[Tuple[str, str, str, str]]:
logger_filenames = {}
logger_infolist = weechat.infolist_get("logger_buffer", "", "")
while weechat.infolist_next(logger_infolist):
buffer = weechat.infolist_pointer(logger_infolist, "buffer")
filename = weechat.infolist_string(logger_infolist, "log_filename")
logger_filenames[buffer] = filename
weechat.infolist_free(logger_infolist)
buffer_infolist = weechat.infolist_get("buffer", "", "")
while weechat.infolist_next(buffer_infolist):
pointer = weechat.infolist_pointer(buffer_infolist, "pointer")
number = weechat.infolist_integer(buffer_infolist, "number")
name = weechat.infolist_string(buffer_infolist, "name")
yield (pointer, logger_filenames.get(pointer, ""), str(number), name)
weechat.infolist_free(buffer_infolist)
def main() -> None:
if not weechat.register(
SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""
):
return
tmux = weechat.string_eval_expression("${env:TMUX}", {}, {}, {})
if not tmux:
print_error("Error: fzf.py currently only supports being run inside tmux")
return
weechat.hook_command(SCRIPT_NAME, SCRIPT_DESC, "", "", "", "fzf_command_cb", "")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,760 @@
#!/usr/bin/env python3
import weechat
import logging
import socket
import json
import os
import random
import textwrap
import datetime
"""
For completion to work, you need to set option
weechat.completion.default_template to include signal_contact_or_group, e.g.
%{nicks}|%(irc_channels)|%(signal_contact_or_group)
"""
try:
import emoji
except ImportError:
emoji = None
SCRIPT_NAME = 'signal'
SCRIPT_AUTHOR = 'Finn Herzfeld <finn@finn.io>'
SCRIPT_VERSION = '0.1'
SCRIPT_LICENSE = 'GPL3'
SCRIPT_DESC = 'Send and receive messages via Signal with weechat'
SCRIPT_COMMAND = 'signal'
SCRIPT_BUFFER = 'signal'
useragent = "%s v%s by %s" % (SCRIPT_NAME, SCRIPT_VERSION, SCRIPT_AUTHOR)
active_line = None
highlight = weechat.color("_bold")
own_uuid = None
def get_groupinfo(dictionary):
groupInfo = None
if 'group' in dictionary.keys():
groupInfo = dictionary['group']
elif 'groupV2' in dictionary.keys():
groupInfo = dictionary['groupV2']
return groupInfo
def get_groupid(groupinfo):
if groupinfo is None:
return None
if 'groupId' in groupinfo:
return groupinfo['groupId']
elif 'id' in groupinfo:
return groupinfo['id']
def get_groupname(groupinfo):
if 'title' in groupinfo:
return groupinfo['title']
if 'name' in groupinfo:
return groupinfo['name']
def get_logfile():
weechat_dir = weechat.info_get("weechat_data_dir", "") or weechat.info_get("weechat_dir", "") or "~/.weechat"
return os.path.join(os.path.expanduser(weechat_dir), "logs", "signal.log")
default_options = {
"socket": "/var/run/signald/signald.sock",
"loglevel": "WARN",
"sentry_dsn": "",
"number": ""
}
options = {}
buffers = {}
callbacks = {}
contacts = {}
groups = {}
signald_hook = None
signald_socket = None
def prnt(text):
logger.info(text)
weechat.prnt("", "signal\t%s" % text)
def show_msg(uuid, group, message, incoming, tags=[]):
identifier = uuid if group is None else group
buf = get_buffer(identifier, group is not None)
name = "Me"
if incoming:
name = contact_name(uuid)
if group is None:
# 1:1 messages are private messages
hotness = weechat.WEECHAT_HOTLIST_PRIVATE
tags.append("notify_private")
else:
# group messages are treated as 'messages'
hotness = weechat.WEECHAT_HOTLIST_MESSAGE
weechat.buffer_set(buf, "hotlist", hotness)
weechat.prnt_date_tags(buf, 0, ",".join(tags), "%s\t%s" % (name, message))
def contact_name(uuid):
if uuid == options["number"]:
return 'Me'
if uuid in contacts:
name = contacts[uuid]\
.get('name', uuid)\
.strip()
name = ''.join(x for x in name if x.isprintable())
return name
else:
return uuid
def init_config():
global default_options, options, logger
logging.basicConfig(filename=get_logfile())
logger = logging.getLogger("weechat_script")
for option, default_value in default_options.items():
if not weechat.config_is_set_plugin(option):
weechat.config_set_plugin(option, default_value)
options[option] = weechat.config_get_plugin(option)
return weechat.WEECHAT_RC_OK
def welcome(version):
prnt("")
prnt("")
if version != "":
prnt("Welcome to Signal Weechat! You're running {name} version {version} ({commit}).".format(**version))
if len(options['number']) > 0:
subscribe(options['number'])
else:
prnt("To begin, you must register or link to an existing device in signald.")
else:
prnt("You don't have signald running! See https://gitlab.com/thefinn93/signald")
prnt("")
prnt("")
def handle_version(payload):
if "id" not in payload:
welcome(payload)
else:
prnt("Connected to {name} version {version} ({commit})".format(**payload))
def receive(data, fd):
global signald_socket
try:
# awesome. since data is a string, but .recv() gives us bytes (that we
# don't necessarily want to decode, since they may be broken in the
# middle of a unicode character or something), we have to shoehorn
# bytes directly to a string. we use latin1 per:
# https://stackoverflow.com/a/42795285
# so we can roundtrip every byte
while not data.endswith("\n"):
raw = signald_socket.recv(1).decode('latin1')
if len(raw) == 0:
logger.info('signald socket disconnected, attempting to reconnect')
signald_socket.close()
close_socket()
init_socket()
return weechat.WEECHAT_RC_OK
data += raw
except socket.error:
logger.exception("Failed to read from signald.")
close_socket()
init_socket()
return weechat.WEECHAT_RC_OK
logger.debug("Got message from signald: %s", data)
payload = json.loads(data.encode('latin1'))
signald_callbacks = {
"version": handle_version,
"IncomingMessage": message_cb,
"list_contacts": contact_list_cb,
"list_groups": group_list_cb,
"send_results": noop_cb,
"sync_requested": noop_cb,
"listen_started": noop_cb,
"listen_stopped": noop_cb,
"account_refreshed": noop_cb,
"ListenerState": noop_cb,
"send": noop_cb,
"request_sync": noop_cb,
"ExceptionWrapper": noop_cb,
"WebSocketConnectionState": noop_cb,
"get_profile": noop_cb,
}
try:
if "id" in payload and payload["id"] in callbacks:
callback = callbacks.pop(payload["id"])
callback["func"](payload, *callback["args"], **callback["kwargs"])
elif payload.get('type') in signald_callbacks:
signald_callbacks[payload.get('type')](payload.get('data'))
else:
prnt("Got unhandled {} message from signald, see debug log for more info".format(payload.get('type')))
logger.warning("Got unhandled message of type %s from signald", payload.get('type'))
except:
logger.exception("exception while handling payload %s", json.dumps(payload, indent=" "))
return weechat.WEECHAT_RC_OK
def send(msgtype, cb=None, cb_args=[], cb_kwargs={}, **kwargs):
global signald_socket
request_id = kwargs.get("request_id", get_request_id())
payload = kwargs
payload['type'] = msgtype
payload["id"] = request_id
payload["version"] = "v1"
if cb is not None:
callbacks[request_id] = {"func": cb, "args": cb_args, "kwargs": cb_kwargs}
msg = json.dumps(payload)
logger.debug("Sending to signald: %s", msg)
try:
signald_socket.sendall((msg + "\n").encode('utf-8'))
except (BrokenPipeError, OSError):
close_socket()
init_socket()
def subscribe(number):
send("request_sync", account=number)
send("list_contacts", account=number)
send("list_groups", account=number)
send("get_profile", account=number, address={"number": number}, cb=set_uuid)
send("subscribe", account=number, cb=subscribe_cb, cb_kwargs={"number": number})
def subscribe_cb(payload, number):
prnt("Successfully subscribed to {}".format(number))
def render_message(message):
sticker = message.get('sticker')
if sticker is not None:
return "<sent sticker>"
reaction = message.get('reaction')
if reaction is not None:
name = contact_name(reaction['targetAuthor']['uuid'])
em = reaction["emoji"]
if emoji is not None:
em = emoji.demojize(em)
return "<reacted with {} to a message from {}>".format(em, name)
attachment_msg = ""
attachments = message.get('attachments')
if attachments is not None:
types = [attach['contentType'] for attach in attachments]
filenames = [attach['storedFilename'] for attach in attachments]
attachment_msg = "<sent {}>: \n{}\n\n".format(
', '.join(types),
'\n'.join(filenames))
quote = message.get('quote')
quote_msg = ""
if quote is not None:
quote_msg = quote['text']
if quote_msg != "":
wrapper = textwrap.TextWrapper(
width=64,
initial_indent="{}> ".format(weechat.color("lightgreen")),
subsequent_indent="{}> ".format(weechat.color("lightgreen"))
)
quote_msg = wrapper.fill(weechat.string_remove_color(quote_msg, "")) + "\n"
body = message.get('body', "")
mentions = message.get('mentions', [])
for mention in mentions[::-1]:
mentioned = contact_name(mention["uuid"])
body = "{first_part}{start_highlight}{name}{stop_highlight}{second_part}".format(
first_part=body[:mention["start"]],
start_highlight=weechat.color("lightgreen"),
name=mentioned,
stop_highlight=weechat.color("chat"),
second_part=body[mention["start"] + mention["length"]:])
if emoji is not None:
body = emoji.demojize(body)
message_string = attachment_msg + quote_msg + body
if message_string.strip() == "":
return None
else:
return message_string
def message_cb(payload):
if payload.get('data_message') is not None:
message = render_message(payload['data_message'])
timestamp = get_timestamp(payload)
author = get_author(payload)
tags = [
"author_{}".format(author),
"timestamp_{}".format(timestamp),
]
if message is not None:
groupInfo = get_groupinfo(payload['data_message'])
group = get_groupid(groupInfo)
show_msg(payload['source']['uuid'], group, message, True, tags)
elif payload.get('syncMessage') is not None:
# some syncMessages are to synchronize read receipts; we ignore these
if payload['syncMessage'].get('readMessages') is not None:
return
# if contactsComplete is present, the contact sync from initial plugin
# load (or someone else triggering a contacts sync on signald) is
# complete, and we should update our contacts list.
if payload['syncMessage'].get('contactsComplete', False):
send("list_contacts", account=options['number'])
return
# we don't know how to render anything besides sync messags with actual
# 'sent' info.
if 'sent' not in payload['syncMessage']:
return
message = render_message(payload['syncMessage']['sent']['message'])
timestamp = get_timestamp(payload)
author = get_author(payload)
tags = [
"author_{}".format(author),
"timestamp_{}".format(timestamp),
]
groupInfo = get_groupinfo(payload['syncMessage']['sent']['message'])
group = get_groupid(groupInfo)
dest = payload['syncMessage']['sent']['destination']['uuid'] if groupInfo is None else None
show_msg(dest, group, message, False, tags)
def noop_cb(payload):
pass
def contact_list_cb(payload):
global contacts
for contact in payload['profiles']:
uuid = contact['address']['uuid']
contacts[uuid] = contact
logger.debug("Checking for buffers with contact %s", contact)
if uuid in buffers:
b = buffers[uuid]
name = contact_name(uuid)
set_buffer_name(b, name)
def set_buffer_name(b, name):
logger.info("Setting buffer name to %s", name)
weechat.buffer_set(b, "title", name)
weechat.buffer_set(b, "name", name)
weechat.buffer_set(b, "shortname", name)
def group_list_cb(payload):
global groups
for group in payload.get('groups', []):
groups[get_groupid(group)] = group
for group in payload.get('groupsv2', []):
groups[get_groupid(group)] = group
def setup_group_buffer(groupId):
global groups
group = groups[groupId]
buffer = get_buffer(groupId, True)
set_buffer_name(buffer, get_groupname(group))
weechat.buffer_set(buffer, "nicklist", "1")
weechat.buffer_set(buffer, "nicklist_display_groups", "0")
for member in group['members']:
uuid = member['uuid']
member_name = contact_name(uuid)
entry = weechat.nicklist_search_nick(buffer, "", member_name)
if len(entry) == 0:
logger.debug("Adding %s to group %s", member_name, groupId)
weechat.nicklist_add_nick(buffer, "", member_name, "", "", "", 1)
def buffer_close_cb(identifier, buffer):
del buffers[identifier]
return weechat.WEECHAT_RC_OK
def get_buffer(identifier, isGroup):
if identifier not in buffers:
cb = "buffer_input_group" if isGroup else "buffer_input"
logger.debug("Creating buffer for identifier %s (%s)", identifier, "group" if isGroup else "contact")
buffers[identifier] = weechat.buffer_new(identifier, cb, identifier, "buffer_close_cb", identifier)
if not isGroup and identifier in contacts:
name = contact_name(identifier)
weechat.buffer_set(buffers[identifier], "localvar_set_type", "private")
set_buffer_name(buffers[identifier], name)
if isGroup:
setup_group_buffer(identifier)
weechat.hook_signal_send("logger_backlog", weechat.WEECHAT_HOOK_SIGNAL_POINTER, buffers[identifier])
return buffers[identifier]
def encode_message(message):
if emoji is not None:
message = emoji.emojize(message, use_aliases=True)
return message
def send_message(uuid, message, **kwargs):
encoded = encode_message(message)
request_id = get_request_id()
show_msg(uuid, None, message, False)
_, message_pointer = get_last_line()
send(
"send",
username=options["number"],
messageBody=encoded,
request_id=request_id,
cb=send_cb,
cb_args=[message_pointer,],
**kwargs
)
def buffer_input(uuid, buffer, message):
send_message(uuid, message, recipientAddress={"uuid": uuid})
return weechat.WEECHAT_RC_OK
def buffer_input_group(groupId, buffer, message):
send_message(groupId, message, recipientGroupId=groupId)
return weechat.WEECHAT_RC_OK
def close_socket():
global signald_socket
global signald_hook
if signald_socket is not None:
signald_socket.close()
if signald_hook is not None:
weechat.unhook(signald_hook)
def init_socket():
global signald_socket
global signald_hook
signald_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
signald_socket.connect(options["socket"])
# weechat really wants the last argument to be a string, but we really
# want it to be bytes. so we end up having to do a bunch of gnarly
# decoding and stuff in receive(). c'est la vie.
signald_hook = weechat.hook_fd(signald_socket.fileno(), 1, 0, 0, 'receive', '')
except Exception:
logger.exception("Failed to connect to signald socket")
def set_log_level():
level = logging.getLevelName(options['loglevel'].upper())
logger.setLevel(level)
logger.info("Log level set to %s", logging.getLevelName(level))
def config_changed(data, option, value):
global options
logger.debug('Config option %s changed to %s', option, value)
option = option.split("plugins.var.python.signal.")[-1]
options[option] = value
if option == 'loglevel':
set_log_level()
if option == 'number':
if len(value) == 0:
prnt("Set your number with /set plugins.var.python.signal.number +12024561414")
else:
logger.debug("Number is '%s'", value)
subscribe(value)
return weechat.WEECHAT_RC_OK
def shutdown():
logger.info("Shutdown called, closing signald socket")
close_socket()
return weechat.WEECHAT_RC_OK
def smsg_cmd_cb(data, buffer, args):
identifier = None
if len(args) == 0:
prnt("Usage: /smsg [number | group]")
else:
for uuid in contacts:
if uuid == args or contact_name(uuid).lower() == args.lower():
identifier = uuid
group = None
if not identifier:
for group in groups:
if get_groupname(groups[group]) == args:
identifier = group
if identifier:
buf = get_buffer(identifier, group is not None)
return weechat.WEECHAT_RC_OK
def signal_cmd_cb(data, buffer, args):
if args == 'list groups':
prnt('List of all available Signal groups:')
for group in groups:
prnt(get_groupname(groups[group]))
prnt('')
elif args == 'list contacts':
prnt('List of all available contacts:')
for uuid in contacts:
if contact_name(uuid) != options['number']:
prnt('{name}, {uuid}\n'.format(name=contact_name(uuid), uuid=uuid))
prnt('')
elif args.startswith('attach'):
attach_cmd_cb(data, buffer, args.lstrip("attach"))
elif args.startswith('reply'):
reply_cmd_cb(data, buffer, args.lstrip("reply"))
elif args.startswith('up'):
up_cmd_cb(data, buffer, "")
elif args.startswith('down'):
down_cmd_cb(data, buffer, "")
else: pass
return weechat.WEECHAT_RC_OK
def get_signal_uuid(buffer):
# check if buffer is a valid signal buffer and can be found in contacts
uuid = [n for n in buffers if buffers[n] == buffer]
if len(uuid) != 1:
prnt("{} uuids for buffer {} found".format(len(uuid), buffer))
return None
else:
return uuid[0]
def attach_cmd_cb(data, buffer, args):
# check if files exist
files = [f.strip() for f in args.split(",")]
for f in files:
if not os.path.exists(f):
prnt('Could not send attachment: file "{}" could not be found'.format(f))
return weechat.WEECHAT_RC_ERROR
# check if buffer is a valid signal buffer and can be found in contacts
uuid = get_signal_uuid(buffer)
if uuid is None:
prnt('Could not send attachment: buffer {} is no signal'.format(buffer))
return weechat.WEECHAT_RC_ERROR
# determine if it's a group or contact,
# send files and show confirmation message
if uuid in groups:
send("send", username=options["number"], recipientGroupId=uuid, attachments=files)
else:
send("send", username=options["number"], recipientAddress={"uuid": uuid}, attachments=files)
msg = "sent file(s):\n{}".format(files)
show_msg(uuid, None, msg, False)
return weechat.WEECHAT_RC_OK
def completion_cb(data, completion_item, buffer, completion):
for uuid in contacts:
weechat.completion_list_add(completion, contact_name(uuid).lower(), 0, weechat.WEECHAT_LIST_POS_SORT)
weechat.completion_list_add(completion, contact_name(uuid), 0, weechat.WEECHAT_LIST_POS_SORT)
for group in groups:
weechat.completion_list_add(completion, get_groupname(groups[group]).lower(), 0, weechat.WEECHAT_LIST_POS_SORT)
weechat.completion_list_add(completion, get_groupname(groups[group]), 0, weechat.WEECHAT_LIST_POS_SORT)
return weechat.WEECHAT_RC_OK
def get_author(payload):
source = payload.get('source', None)
if source is not None:
return source.get('uuid', '')
else:
return ''
def get_timestamp(payload):
data_message = payload.get('data_message', None)
if data_message is not None:
return data_message.get('timestamp', '')
else:
return ''
def get_tags(line_data):
hdata = weechat.hdata_get("line_data")
tags_count = weechat.hdata_get_var_array_size(hdata, line_data, "tags_array")
tags = [
weechat.hdata_string(hdata, line_data, "%d|tags_array" % i)
for i in range(tags_count)
]
return tags
def get_last_line():
hdata = weechat.hdata_get("line_data")
own_lines = weechat.hdata_pointer(weechat.hdata_get("buffer"), weechat.current_buffer(), "own_lines")
if own_lines:
line = weechat.hdata_pointer(weechat.hdata_get("lines"), own_lines, "last_line")
if line:
line_data = weechat.hdata_pointer(weechat.hdata_get("line"), line, "data")
return (line, line_data)
return None
def move_active_line(previous=True):
global active_line
if active_line is None:
active_line = get_last_line()
return
other_line = "prev_line" if previous else "next_line"
line, _ = active_line
line = weechat.hdata_pointer(weechat.hdata_get("line"), line, other_line)
if line:
line_data = weechat.hdata_pointer(weechat.hdata_get("line"), line, "data")
active_line = (line, line_data)
def active_line_toggle_highlight(on=True):
global active_line
hdata = weechat.hdata_get("line_data")
if active_line is None:
return
line, line_data = active_line
tags = get_tags(line_data)
message = weechat.hdata_string(hdata, line_data, "message")
if "signal_highlight" in tags and on is False:
message = message[len(highlight):]
tags.remove("signal_highlight")
elif "signal_highlight" not in tags and on is True:
message = "{}{}".format(highlight, message)
tags.append("signal_highlight")
weechat.hdata_update(hdata, line_data, {"message": message})
weechat.hdata_update(hdata, line_data, {"tags_array": ",".join(tags)})
def reset_active_line_cb(data, signal, signal_data):
global active_line
if active_line is None:
return weechat.WEECHAT_RC_OK
active_line_toggle_highlight(on=False)
active_line = None
return weechat.WEECHAT_RC_OK
def up_cmd_cb(data, buffer, args):
if get_signal_uuid(buffer) is None:
return weechat.WEECHAT_RC_ERROR
active_line_toggle_highlight(on=False)
move_active_line(previous=True)
active_line_toggle_highlight(on=True)
return weechat.WEECHAT_RC_OK
def down_cmd_cb(data, buffer, args):
if get_signal_uuid(buffer) is None:
return weechat.WEECHAT_RC_ERROR
active_line_toggle_highlight(on=False)
move_active_line(previous=False)
active_line_toggle_highlight(on=True)
return weechat.WEECHAT_RC_OK
def reply_cmd_cb(data, buffer, args):
hdata = weechat.hdata_get("line_data")
if active_line is None:
prnt("No line for reply selected")
return weechat.WEECHAT_RC_ERROR
line, line_data = active_line
tags = get_tags(line_data)
author = [t for t in tags if t.startswith("author_")]
timestamp = [t for t in tags if t.startswith("timestamp_")]
if len(author) != 1 or len(timestamp) != 1:
prnt("Could not reply: Found {} authors and {} timestamps".format(
len(author),
len(timestamp))
)
return weechat.WEECHAT_RC_ERROR
timestamp = timestamp[0].replace("timestamp_", "")
author = author[0].replace("author_", "")
uuid = get_signal_uuid(buffer)
if uuid is None:
prnt('Could not send reply: buffer {} is no signal'.format(buffer))
return weechat.WEECHAT_RC_ERROR
old_message = weechat.hdata_string(hdata, line_data, "message")
if len(old_message) > 20:
old_message = old_message[:20] + "..."
show_msg(uuid, None, "{}> reply to: {}{}".format(
weechat.color("green"), old_message, weechat.color("chat")
), False)
quote = {
"id": timestamp,
"author": {
"uuid": author,
}
}
if uuid in groups:
send_message(
uuid,
args,
recipientGroupId=uuid,
quote=quote
)
else:
send_message(
uuid,
args,
recipientAddress={"uuid": uuid},
quote=quote
)
return weechat.WEECHAT_RC_OK
def get_request_id():
# returns timestamp in milliseconds, as used by signal
timestamp = str(int(datetime.datetime.now().timestamp() * 1000))
return "weechat-signal-{}-{}".format(timestamp, random.randint(0, 1000))
def set_uuid(payload):
# set own uuid from get_profile request
global own_uuid
if own_uuid is not None:
return
address = payload['data'].get('address', None)
if address is not None:
if address.get('number', None) == options["number"]:
own_uuid = address.get('uuid', None)
prnt("set own_uuid to {}".format(own_uuid))
def send_cb(payload, line_data):
global own_uuid
hdata = weechat.hdata_get("line_data")
timestamp = payload['data'].get('timestamp', None)
if timestamp is None or own_uuid is None:
return
tags = get_tags(line_data)
tags.append("author_{}".format(own_uuid))
tags.append("timestamp_{}".format(timestamp))
weechat.hdata_update(hdata, line_data, {"tags_array": ",".join(tags)})
if __name__ == "__main__":
try:
if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, 'shutdown', ''):
weechat.hook_config('plugins.var.python.%s.*' % SCRIPT_NAME, 'config_changed', '')
init_config()
set_log_level()
smsg_help = [
"number: the full e164 number (including country code) for the contact",
]
signal_help = [
"contacts: list all contact names and numbers",
"groups: list all group names",
"attach: one or multiple comma-separated filenames to send as attachment to the conversation of the active buffer",
]
logger.debug("Registering command...")
weechat.hook_completion('signal_contact_or_group','Script to complete numbers','completion_cb', '')
weechat.hook_command("smsg", "Open a buffer to message someone (or some group) on signal", "[<number or group name>]",
"\n".join(smsg_help), "%(number)", "smsg_cmd_cb", "")
weechat.hook_command("signal", "List contacts or group names, or send attachments", "list [contacts | groups | attach]",
"\n".join(signal_help), "%(list)", "signal_cmd_cb", "")
weechat.hook_signal("buffer_switch", "reset_active_line_cb", "")
init_socket()
except Exception:
logger.exception("Failed to initialize plugin.")

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@ diff_color = on
diff_command = "auto" diff_command = "auto"
display_source = on display_source = on
quiet_actions = on quiet_actions = on
sort = "i,p,n" sort = "i,u"
translate_description = on translate_description = on
use_keys = on use_keys = on

View File

@ -280,7 +280,7 @@ buflist.position = left
buflist.priority = 100 buflist.priority = 100
buflist.separator = on buflist.separator = on
buflist.size = 0 buflist.size = 0
buflist.size_max = 20 buflist.size_max = 23
buflist.type = root buflist.type = root
fset.color_bg = default fset.color_bg = default
fset.color_bg_inactive = default fset.color_bg_inactive = default