mirror of https://tildegit.org/ben/dotfiles
fish v4 and some weechat stuff
parent
734e67fb1f
commit
bfd96e2285
bin/bin
byobu/.byobu
fish/.config/fish
git
|
@ -1,4 +1,7 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
|
||||
matchplayApiKey=$(cat ~/Sync/Notes/keys/matchplayapikey.txt)
|
||||
ifpaApiKey=$(cat ~/Sync/Notes/keys/ifpa-api-key.txt)
|
||||
|
||||
|
|
|
@ -76,4 +76,4 @@
|
|||
# Set this to zero to hide seconds int the time display
|
||||
# Default 1
|
||||
#TIME_SECONDS=0
|
||||
BYOBU_CHARMAP=x
|
||||
BYOBU_CHARMAP=UTF-8
|
||||
|
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
if test -f ~/.cargo/env.fish
|
||||
source ~/.cargo/env.fish
|
||||
end
|
|
@ -1,6 +1,3 @@
|
|||
set -xg EDITOR vim
|
||||
set -xg TZ 'America/Detroit'
|
||||
|
||||
if test -d ~/Maildir
|
||||
set -x MAIL ~/Maildir
|
||||
end
|
||||
|
@ -29,7 +26,6 @@ if status --is-interactive && type -q rbenv
|
|||
end
|
||||
end
|
||||
|
||||
#set -x SSH_AGENT_PID ""
|
||||
if test -S $HOME/.gnupg/S.gpg-agent
|
||||
set -x SSH_AUTH_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)
|
||||
end
|
||||
|
||||
set -x BBJ_USER $USER
|
||||
set -x DEBEMAIL ben@tilde.team
|
||||
set -x DEBFULLNAME "Ben Harris"
|
||||
|
||||
# add dotnet completions if needed
|
||||
if status --is-interactive && type -q dotnet
|
||||
complete -f -c dotnet -a "(dotnet complete)"
|
||||
|
|
|
@ -1,40 +1,54 @@
|
|||
# This file contains fish universal variable definitions.
|
||||
# VERSION: 3.0
|
||||
SETUVAR --export BBJ_USER:ben
|
||||
SETUVAR --export DEBEMAIL:ben\x40tilde\x2eteam
|
||||
SETUVAR --export DEBFULLNAME:Ben\x20Harris
|
||||
SETUVAR DOTNET_CLI_TELEMETRY_OPTOUT:1
|
||||
SETUVAR --export EDITOR:vim
|
||||
SETUVAR EMAIL:ben\x40tilde\x2eteam
|
||||
SETUVAR --export TZ:America/Detroit
|
||||
SETUVAR __fish_init_2_39_8:\x1d
|
||||
SETUVAR __fish_init_2_3_0:\x1d
|
||||
SETUVAR __fish_init_3_x:\x1d
|
||||
SETUVAR __fish_initialized:3400
|
||||
SETUVAR fish_color_autosuggestion:555\x1ebrblack
|
||||
SETUVAR __fish_initialized:3800
|
||||
SETUVAR fish_color_autosuggestion:brblack
|
||||
SETUVAR fish_color_cancel:\x2dr
|
||||
SETUVAR fish_color_command:\x2d\x2dbold
|
||||
SETUVAR fish_color_comment:990000
|
||||
SETUVAR fish_color_command:normal
|
||||
SETUVAR fish_color_comment:red
|
||||
SETUVAR fish_color_cwd:green
|
||||
SETUVAR fish_color_cwd_root:red
|
||||
SETUVAR fish_color_end:009900
|
||||
SETUVAR fish_color_error:ff0000
|
||||
SETUVAR fish_color_escape:00a6b2
|
||||
SETUVAR fish_color_end:green
|
||||
SETUVAR fish_color_error:brred
|
||||
SETUVAR fish_color_escape:brcyan
|
||||
SETUVAR fish_color_history_current:\x2d\x2dbold
|
||||
SETUVAR fish_color_host:normal
|
||||
SETUVAR fish_color_host_remote:yellow
|
||||
SETUVAR fish_color_keyword:normal
|
||||
SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue
|
||||
SETUVAR fish_color_normal:normal
|
||||
SETUVAR fish_color_operator:00a6b2
|
||||
SETUVAR fish_color_param:00afff
|
||||
SETUVAR fish_color_quote:999900
|
||||
SETUVAR fish_color_redirection:00afff
|
||||
SETUVAR fish_color_operator:brcyan
|
||||
SETUVAR fish_color_option:cyan
|
||||
SETUVAR fish_color_param:cyan
|
||||
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_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_valid_path:\x2d\x2dunderline
|
||||
SETUVAR fish_greeting:Welcome\x20to\x20fish\x2c\x20the\x20friendly\x20interactive\x20shell
|
||||
SETUVAR fish_key_bindings:fish_default_key_bindings
|
||||
SETUVAR fish_pager_color_background:\x1d
|
||||
SETUVAR fish_pager_color_completion:normal
|
||||
SETUVAR fish_pager_color_description:B3A06D\x1eyellow
|
||||
SETUVAR fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline
|
||||
SETUVAR fish_pager_color_description:yellow\x1e\x2di
|
||||
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_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_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
|
||||
|
|
|
@ -74,3 +74,6 @@
|
|||
sort = version:refname
|
||||
[safe]
|
||||
directory = *
|
||||
[fetch]
|
||||
prune = true
|
||||
all = true
|
||||
|
|
|
@ -14,4 +14,3 @@ instant = on
|
|||
timer = 1
|
||||
|
||||
[buffer]
|
||||
irc.tilde.#trivia.hotlist_max_level_nicks_add = "Oz:2,Nerd:2"
|
||||
|
|
|
@ -25,7 +25,7 @@ use_items = 1
|
|||
|
||||
[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_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_highlight = "${color:magenta}"
|
||||
hotlist_low = "${color:default}"
|
||||
|
|
|
@ -51,7 +51,7 @@ join_auto_add_chantype = off
|
|||
list_buffer = on
|
||||
list_buffer_format_export = "${name} (${users}): "${topic}""
|
||||
list_buffer_scroll_horizontal = 10
|
||||
list_buffer_sort = "~name2"
|
||||
list_buffer_sort = "-users"
|
||||
list_buffer_topic_strip_colors = on
|
||||
msgbuffer_fallback = current
|
||||
new_channel_position = none
|
||||
|
@ -62,6 +62,7 @@ nick_mode = both
|
|||
nick_mode_empty = off
|
||||
nicks_hide_password = "nickserv"
|
||||
notice_as_pv = auto
|
||||
notice_nicks_disable_notify = "chanserv,nickserv"
|
||||
notice_welcome_redirect = on
|
||||
notice_welcome_tags = ""
|
||||
notify_tags_ison = "notify_message"
|
||||
|
@ -219,7 +220,7 @@ tilde.usermode
|
|||
tilde.command_delay
|
||||
tilde.command = "/msg idlerpg_bot login wowbagger ${sec.data.idlerpgpass}"
|
||||
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.autorejoin
|
||||
tilde.autorejoin_delay
|
||||
|
@ -311,7 +312,7 @@ town.usermode
|
|||
town.command_delay
|
||||
town.command
|
||||
town.autojoin_delay
|
||||
town.autojoin = "#announcements,#bots,#counting,#tildetown"
|
||||
town.autojoin = "#announcements,#bots,#counting,#tildetown,#sickos.net"
|
||||
town.autojoin_dynamic
|
||||
town.autorejoin
|
||||
town.autorejoin_delay
|
||||
|
@ -449,7 +450,7 @@ oftc.usermode
|
|||
oftc.command_delay
|
||||
oftc.command
|
||||
oftc.autojoin_delay
|
||||
oftc.autojoin = "#bitlbee,#debian-devel,#fish,#salsa,#tilde.team"
|
||||
oftc.autojoin = "#bitlbee,#debian-devel,#fish,#osm"
|
||||
oftc.autojoin_dynamic
|
||||
oftc.autorejoin
|
||||
oftc.autorejoin_delay
|
||||
|
@ -511,10 +512,10 @@ blinkenshell.split_msg_max_length
|
|||
blinkenshell.charset_message
|
||||
blinkenshell.default_chantypes
|
||||
blinkenshell.registered_mode
|
||||
inspircd.addresses = "irc.inspircd.org"
|
||||
inspircd.addresses = "irc.teranova.net/6697"
|
||||
inspircd.proxy
|
||||
inspircd.ipv6
|
||||
inspircd.tls
|
||||
inspircd.tls = on
|
||||
inspircd.tls_cert
|
||||
inspircd.tls_password
|
||||
inspircd.tls_priorities
|
||||
|
@ -692,98 +693,6 @@ libera.split_msg_max_length
|
|||
libera.charset_message
|
||||
libera.default_chantypes
|
||||
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.proxy
|
||||
m455.ipv6
|
||||
|
@ -814,7 +723,7 @@ m455.usermode
|
|||
m455.command_delay
|
||||
m455.command
|
||||
m455.autojoin_delay
|
||||
m455.autojoin = "#basement,#serverroom,#siliconpals"
|
||||
m455.autojoin = "#basement"
|
||||
m455.autojoin_dynamic
|
||||
m455.autorejoin
|
||||
m455.autorejoin_delay
|
||||
|
@ -830,52 +739,6 @@ m455.split_msg_max_length
|
|||
m455.charset_message
|
||||
m455.default_chantypes
|
||||
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.proxy
|
||||
syn.ipv6
|
||||
|
@ -968,3 +831,49 @@ efnet.split_msg_max_length
|
|||
efnet.charset_message
|
||||
efnet.default_chantypes
|
||||
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
|
||||
|
|
|
@ -13,18 +13,6 @@
|
|||
fifo.fifo = "on"
|
||||
guile.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.colorize_lines.alternate_color = ""
|
||||
perl.colorize_lines.blacklist_buffers = ""
|
||||
|
@ -35,7 +23,7 @@ perl.colorize_lines.highlight_words = "off"
|
|||
perl.colorize_lines.highlight_words_color = ""
|
||||
perl.colorize_lines.ignore_tags = "irc_ctcp"
|
||||
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_color = ""
|
||||
perl.colorize_lines.tags = "irc_privmsg"
|
||||
|
@ -50,16 +38,6 @@ perl.highmon.nick_prefix = "<"
|
|||
perl.highmon.nick_suffix = ">"
|
||||
perl.highmon.output = "buffer"
|
||||
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.ignore = "bitlbee.marley"
|
||||
python.buffer_autoclose.interval = "1"
|
||||
|
@ -67,7 +45,7 @@ python.buffer_autoclose.prefer = ""
|
|||
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.go.auto_jump = "off"
|
||||
python.go.buffer_number = "on"
|
||||
python.go.buffer_number = "off"
|
||||
python.go.color_name = "black,cyan"
|
||||
python.go.color_name_highlight = "red,cyan"
|
||||
python.go.color_name_highlight_selected = "red,brown"
|
||||
|
@ -89,12 +67,6 @@ python.grep.max_lines = "4000"
|
|||
python.grep.show_summary = "on"
|
||||
python.grep.size_limit = "2048"
|
||||
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.command_on_attach = ""
|
||||
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.socket_file = ""
|
||||
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"
|
||||
tcl.check_license = "off"
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../buffer_autoset.py
|
|
@ -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
|
|
@ -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()
|
|
@ -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
|
@ -15,7 +15,7 @@ diff_color = on
|
|||
diff_command = "auto"
|
||||
display_source = on
|
||||
quiet_actions = on
|
||||
sort = "i,p,n"
|
||||
sort = "i,u"
|
||||
translate_description = on
|
||||
use_keys = on
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ buflist.position = left
|
|||
buflist.priority = 100
|
||||
buflist.separator = on
|
||||
buflist.size = 0
|
||||
buflist.size_max = 20
|
||||
buflist.size_max = 23
|
||||
buflist.type = root
|
||||
fset.color_bg = default
|
||||
fset.color_bg_inactive = default
|
||||
|
|
Loading…
Reference in New Issue