Initial commit

This commit is contained in:
Dionysus 2023-06-08 03:29:31 -04:00
commit 69f69e396f
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
19 changed files with 6924 additions and 0 deletions

360
README.md Normal file
View File

@ -0,0 +1,360 @@
# WeeChat
> backup of my weechat setup
## Table of Contents
- [Setup](#setup)
- [WeeChat](#weechat)
- [Relay](#relay)
- [Settings](#settings)
- [Appearance](#appearance)
- [Settings](#appearance)
- [IRC](#appearance)
- [CTCP](#appearance)
- [Scripts](#appearance)
- [Triggers](#triggers)
- [Servers](#servers)
- [Services](#services)
- [Proxy](#proxy)
- [Relay](#relay)
- [Keys](#keys)
- [Todo](#todo)
---
### Setup
###### WeeChat
```shell
weechat -P "alias,buflist,charset,exec,fifo,fset,irc,perl,python,relay,script,trigger" -r "/set weechat.plugin.autoload alias,buflist,charset,exec,fifo,fset,irc,perl,python,relay,script,trigger;/save;/quit"
rm $HOME/.weechat/weechat.log && chmod 700 $HOME/.weechat && mkdir $HOME/.weechat/ssl
git clone --depth 1 https://github.com/acidvegas/weechat.git $HOME/weechat
mv $HOM E/weechat/alias.conf $HOME/.weechat/alias.conf && mv $HOME/weechat/scripts/perl/*.pl $HOME/.weechat/perl/autoload/ && mv $HOME/weechat/scripts/python/*.py $HOME/.weechat/python/autoload/
mkdir $HOME/.weechat/logs
openssl req -x509 -new -newkey rsa:4096 -sha256 -days 3650 -out $HOME/.weechat/ssl/cert.pem -keyout $HOME/.weechat/ssl/cert.pem
chmod 400 $HOME/.weechat/ssl/cert.pem
```
###### Relay
```shell
certbot certonly --standalone -d chat.acid.vegas -m acid.vegas@acid.vegas
echo -e "[Unit]\nDescription=cerbot renewal\n\n[Service]\nType=oneshot\nExecStart=/usr/bin/certbot renew -n --quiet --agree-tos --deploy-hook /home/acidvegas/.weechat/renew" > /etc/systemd/system/certbot.service
echo -e "[Unit]\nDescription=cerbot renewal timer\n\n[Timer]\nOnCalendar=0/12:00:00\nRandomizedDelaySec=1h\nPersistent=true\n\n[Install]\nWantedBy=timers.target" > /etc/systemd/system/certbot.timer
systemctl enable certbot.timer && systemctl start certbot.timer
echo "#!/bin/bash" > /home/acidvegas/.weechat/renew
echo "cat /etc/letsencrypt/live/chat.acid.vegas/fullchain.pem /etc/letsencrypt/live/chat.acid.vegas/privkey.pem > /home/acidvegas/.weechat/ssl/relay.pem" >> /home/acidvegas/.weechat/renew
echo "chown -R acidvegas:acidvegas /home/acidvegas/.weechat/ssl/relay.pem && chmod 400 /home/acidvegas/.weechat/ssl/relay.pem" >> /home/acidvegas/.weechat/renew
echo "printf '%b' '*/relay sslcertkey\n' > /home/acidvegas/.weechat/weechat_fifo" >> /home/acidvegas/.weechat/renew
chmod +x /home/acidvegas/.weechat/renew
mkdir -p $HOME/.config/systemd/user
echo -e "[Unit]\nDescription=headless weechat relay service\nAfter=network.target\n\n[Service]\nType=forking\nExecStart=/usr/bin/weechat-headless --daemon\n\n[Install]\nWantedBy=default.target" > $HOME/.config/systemd/user/weechat-headless.service
systemctl --user enable weechat-headless
```
---
### Settings
###### Appearance
```
/set buflist.format.buffer "${if:${type}==server?${if:${window[gui_current_window].buffer.local_variables.server}==${buffer.local_variables.server}?${if:${irc_server.is_connected}?${color:green,235}:${color:lightred,235}}• ${color:default,235}${name}:${if:${irc_server.is_connected}?${color:green,235}:${color:lightred,235}}• ${color:default,235}${indent}${name}}:}${if:${type}=~(channel|private)?${color_hotlist}${indent}${name}:}${if:${type}!~(channel|private|server)?${color:gray}${name}:}"
/set buflist.format.buffer_current "${if:${type}==server?${if:${window[gui_current_window].buffer.local_variables.server}==${buffer.local_variables.server}?${color:lightred}${if:${irc_server.is_connected}?${color:green,235}:${color:lightred,235}}• ${name}${format_hotlist}:${color:237}${if:${irc_server.is_connected}?${color:green,235}:${color:lightred,235}}• ${name}}${format_lag}${format_hotlist}:${if:${type}=~(channel|private)?• ${name}:${if:${type}!~(channel|private|server)?${color:lightblue}${name}:}}}"
/set buflist.format.hotlist_highlight "${color:yellow}"
/set buflist.format.hotlist_message "${color:cyan}"
/set buflist.format.hotlist_private "${color:yellow}"
/set irc.color.input_nick default
/set irc.color.nick_prefixes "y:green;q:green;a:lightred;o:red;h:yellow;v:lightblue;*:lightmagenta"
/set irc.color.reason_quit darkgray
/set irc.color.topic_new lightblue
/set irc.look.display_join_message ""
/set irc.look.display_old_topic off
/set irc.look.item_nick_modes off
/set irc.look.server_buffer independent
/set weechat.bar.buflist.size_max 20
/set weechat.bar.fset.separator off
/set weechat.bar.input.color_delim darkgray
/set weechat.bar.input.conditions "${window.buffer.full_name} != perl.highmon"
/set weechat.bar.input.items "[input_prompt]+(away),[input_search],[input_paste],input_text"
/set weechat.bar.input.separator off
/set weechat.bar.nicklist.size_max 15
/set weechat.bar.status.color_bg default
/set weechat.bar.status.color_delim darkgray
/set weechat.bar.status.conditions "${window.buffer.full_name} != perl.highmon"
/set weechat.bar.status.items "buffer_name+(buffer_modes)+[buffer_nicklist_count]"
/set weechat.bar.status.separator off
/set weechat.bar.title.color_bg black
/set weechat.bar.title.separator off
/set weechat.bar.title.size_max 2
/set weechat.look.chat_space_right on
/set weechat.color.chat_delimiters darkgray
/set weechat.color.chat_highlight_bg default
/set weechat.color.chat_host darkgray
/set weechat.color.chat_nick white
/set weechat.color.chat_nick_colors "cyan,magenta,green,brown,lightblue,default,lightcyan,lightmagenta,lightgreen,blue,31,35,38,40,49,63,70,80,92,99,112,126,130,138,142,148,160,162,167,169,174,176,178,184,186,210,212,215,247"
/set weechat.color.chat_prefix_error lightred
/set weechat.color.chat_prefix_network lightblue
/set weechat.color.chat_prefix_suffix darkgray
/set weechat.color.chat_read_marker darkgray
/set weechat.color.chat_time 235
/set weechat.color.chat_time_delimiters 235
/set weechat.color.separator darkgray
/set weechat.color.status_name_ssl white
/set weechat.look.bar_more_down "▼"
/set weechat.look.bar_more_left "◀"
/set weechat.look.bar_more_right "▶"
/set weechat.look.bar_more_up "▲"
/set weechat.look.buffer_time_format " %H:%M"
/set weechat.look.day_change off
/set weechat.look.item_buffer_filter "•"
/set weechat.look.prefix_align_max 15
/set weechat.look.prefix_join "▬▬▶"
/set weechat.look.prefix_quit "◀▬▬"
/set weechat.look.prefix_suffix "│"
/set weechat.look.quote_time_format "%H:%M"
/set weechat.look.read_marker_string "─"
/set weechat.look.separator_horizontal "─"
/set weechat.look.separator_vertical "│"
/set weechat.look.window_title "hardchats"
/set weechat.startup.display_logo off
/set weechat.startup.display_version off
```
###### Settings
```
/set buflist.look.mouse_wheel off
/set buflist.look.mouse off
/set fifo.file.path "${weechat_data_dir}/weechat_fifo"
/set irc.look.buffer_switch_autojoin off
/set irc.look.buffer_switch_join on
/set irc.look.join_auto_add_chantype on
/set irc.look.smart_filter off
/set irc.look.temporary_servers on
/set irc.network.ban_mask_default "*!*@$host"
/set logger.file.auto_log off
/set sec.crypt.hash_algo sha512
/set weechat.look.confirm_quit on
/set weechat.look.highlight "acidvegas,supernets,super nets"
/set weechat.look.mouse on
/set weechat.plugin.autoload "alias,buflist,charset,exec,fifo,fset,irc,perl,python,relay,script,trigger"
```
###### IRC
```
/set irc.server_default.anti_flood_prio_high 0
/set irc.server_default.anti_flood_prio_low 0
/set irc.server_default.autorejoin on
/set irc.server_default.autorejoin_delay 3
/set irc.server_default.command_delay 3
/set irc.server_default.msg_part "G-line: User has been permanently banned from this network."
/set irc.server_default.msg_quit "G-line: User has been permanently banned from this network."
/set irc.server_default.nicks "acidvegas,acid_vegas,acid.vegas,acidvegas_"
/set irc.server_default.realname "04MOST DANGEROUS MOTHERFUCK"
/set irc.server_default.sasl_mechanism external
/set irc.server_default.sasl_username "acidvegas"
/set irc.server_default.ssl_cert "%h/ssl/cert.pem"
/set irc.server_default.ssl_password "REDACTED"
/set irc.server_default.ssl_verify off
/set irc.server_default.username "stillfree"
```
###### CTCP
```
/set irc.ctcp.clientinfo ""
/set irc.ctcp.finger ""
/set irc.ctcp.ping ""
/set irc.ctcp.source ""
/set irc.ctcp.time ""
/set irc.ctcp.userinfo ""
/set irc.ctcp.version ""
/set irc.look.ctcp_time_format ""
/set irc.look.display_ctcp_blocked off
/set irc.look.display_ctcp_reply off
/set irc.look.display_ctcp_unknown off
```
###### Scripts
```
/set plugins.var.perl.highmon.first_run false
/set plugins.var.perl.highmon.short_names on
/set plugins.var.perl.keepnick.default_enable 1
/set plugins.var.perl.multiline.weechat_paste_fix "off"
```
---
### Triggers
```
/trigger del beep
/trigger add hate modifier irc_out1_PRIVMSG "" "/hate/04 HATE "
/trigger add input_command_color modifier "500|input_text_display" "${tg_string} =~ ^/($|[^/])" "#/(.+)#${color:39}/${color:74}${re:1}#"
/trigger add numberjump modifier "2000|input_text_for_buffer" "${tg_string} =~ ^/[0-9]+$" "=\/([0-9]+)=/buffer *${re:1}=" "" "" "none"
/trigger add url_color modifier "weechat_print" "${tg_tags} !~ irc_quit" ";[a-z]+://\S+;${color:32}${color:underline}${re:0}${color:-underline}${color:reset};" ""
/trigger add relay_awayclear signal relay_client_connected "" "" "/away -all"
/trigger add relay_setaway signal relay_client_disconnected "" "" "/away -all I am away"
/trigger add relay_setaway signal relay_client_disconnected "${info:relay_client_count,connected} == 0" "" "/away -all I am away"
```
---
### Servers
```
/server add 2f30 irc.2f30.org/6697 -tls
/server add anope irc.anope.org/6697 -tls
/server add blcknd irc.blcknd.net/6697 -tls
/server add efnet irc.servercentral.net/9999 -tls
/server add libera irc.libera.chat/6697 -tls
/server add gamesurge irc.gamesurge.net
/server add ircd ircd.chat/6697 -tls
/server add ircstorm irc.ircstorm.net/6699 -tls
/server add malvager irc.malvager.net/6697 -tls
/serber add netsec irc.priv8.chat/6697 -tls
/server add oftc irc.oftc.net/6697 -tls
/server add sandnet irc.sandngz.net/6697 -tls
/server add silph irc.silph.co/6697 -tls
/server add supernets irc.supernets.org/6697 -tls
/server add twisted irc.twistednet.org/6697 -tls
/server add unreal irc.unrealircd.org/6697 -tls
/server add wormnet wormnet1.team17.com
/server add wtfux irc.wtfux.org/6697 -tls
/set irc.server.2f30.autojoin #2f30
/set irc.server.anope.autojoin #anope
/set irc.server.blacknd.autojoin #blacknd,#chat
/set irc.server.efnet.autojoin #2600,#efnetnews,#exchange,#irc30,#lrh
/set irc.server.libera.autojoin #archlinux,#ircv3,#matrix,#music-theory,#python,#raspberrypi,#weechat
/set irc.server.gamesurge.autojoin #worms
/set irc.server.ircd.autojoin #tcpdirect
/set irc.server.malvager.autojoin #malvager
/set irc.server.netsec.autojoin #ch@s
/set irc.server.sandnet.autojoin #arab
/set irc.server.silph.autojoin #ramen
/set irc.server.twisted.autojoin #dev,#Twisted
/set irc.server.unreal.autojoin #unreal-support
/set irc.server.unreal.command /MODE acidvegas -x
/set irc.server.wormnet.autojoin #anythinggoes
/set irc.server.wormnet.password ELSILRACLIHP
/set irc.server.wormnet.realname "48 0 US 3.7.2.1"
/set irc.server.wtfux.autojoin #ED,#wtfux
```
---
### Services
```
/secure passphrase PASSWORD
/secure set NETWORK PASSWORD
/set irc.server.networkname.command "/msg NickServ IDENTIFY ${sec.data.networkname}
/msg NickServ register PASSWORD EMAIL
/msg NickServ ACCESS DEL CHANGEME
/msg NickServ ACCESS ADD *@big.dick.acid.vegas
/msg NickServ AJOIN ADD <channel>
/msg NickServ CERT ADD
/msg NickServ SET AUTOOP ON
/msg NickServ SET HIDE EMAIL ON
/msg NickServ SET HIDE STATUS ON
/msg NickServ SET HIDE USERMASK ON
/msg NickServ SET HIDE QUIT ON
/msg NickServ SET KEEPMODES ON
/msg NickServ SET KILL QUICK
/msg NickServ SET PRIVATE ON
/msg NickServ SET SECURE ON
/msg HostServ REQUEST MOST.DANGEROUS.MOTHER.FUCK
/msg HostServ ON
```
---
### Proxy
```
/proxy add tor socks5 127.0.0.1 9050
/set irc.server.CHANGEME.proxy tor
```
---
### Relay
```
/secure set relay PASSWORD
/secure set totp SECRET
/set relay.network.max_clients 2
/set relay.network.password ${sec.data.relay}
/set relay.network.totp_secret ${sec.data.totp}
/relay sslcertkey
/relay add ssl.weechat PORT
```
---
### Keys
| Keys | Description | Command |
| --------- | ------------------------------------- | ----------------------------------- |
| `ALT + n` | Scroll to next highlight | `/window scroll_next_highlight` |
| `ALT + p` | Scroll to previous highlight | `/window scroll_previous_highlight` |
| `ALT + u` | Scroll to first unread line in buffer | `/window scroll_unread` |
| Keys | Description | Command |
| ------------- | ------------------------ | ----------------------------- |
| `Left` | Move cursor to the left | `/input move_previous_char` |
| `Right` | Move cursor to the right | `/input move_next_char` |
| `Backspace` | Delete character | `/input delete_previous_char` |
| `Enter` | Send | `/input return` |
| `ALT + Enter` | Insert new line | `/input insert \n` |
| Keys | Description | Command |
| ------------------ | ------------------- | ------------------------- |
| `CTRL + r` | Search text | `/input search_text_here` |
| `CTRL + y` | Paste | `/input clipboard_paste` |
| `CTRL + l` | Refresh window | `/window refresh` |
| `ALT + l` | Toggle bare display | `/window bare` |
| `Alt + Shift + b` | Toggle buffer list | `/bar toggle buflist` |
| `Alt + Shift + n` | Toggle nicklist | `/bar toggle buflist` |
| Keys | Description | Command |
| ------------- | ------------------- | -------------------------- |
| `Tab` | Complete next | `/input complete_next` |
| `Shift + Tab` | Complete previous | `/input complete_previous` |
| Keys | Description | Command |
| ------------- | ---------------------------------- | -------------------------------- |
| `Up` | Show previous input history | `/input history_previous` |
| `Down` | Show next input history | `/input history_next` |
| `CTRL + Up` | Show previous global input history | `/input history_global_previous` |
| `CTRL + Down` | Show next global input history | `/input history_global_next` |
| Keys | Description | Command |
| ------------ | --------------------- | ------------ |
| `ALT + #` | Go to Nth buffer | `/buffer *N` |
| `ALT + Up` | Go to previous buffer | `/buffer -1` |
| `ALT + Down` | Go to next buffer | `/buffer +1` |
| Keys | Description | Command |
| ------------ | ----------------------------------------- | ----------------------- |
| `PgUp` | Scroll up one page in buffer history | `/window page_up` |
| `PgDn` | Scroll down one page in buffer history | `/window page_down` |
| `ALT + PgUp` | Scroll up a few lines in buffer history | `/window scroll_up` |
| `ALT + PgDn` | Scroll down a few lines in buffer history | `/window scroll_down` |
| `ALT + Home` | Scroll to top of buffer | `/window scroll_top` |
| `ALT + End` | Scroll to bottom of buffer | `/window scroll_bottom` |
| Keys | Description | Command |
| -------------- | ------------------------------- | -------------------- |
| `Ctrl + c, b` | Insert code for bold text | `/input insert \x02` |
| `Ctrl + c, c` | Insert code for colored text | `/input insert \x03` |
| `Ctrl + c, i` | Insert code for italic text | `/input insert \x1D` |
| `Ctrl + c, o` | Insert code for color reset | `/input insert \x0F` |
| `Ctrl + c, v` | Insert code for reverse color | `/input insert \x16` |
| `Ctrl + c, _` | Insert code for underlined text | `/input insert \x1F` |
---
### Todo
- Information on commands for scripts
- tdfiglet & curling git for ascii
- `sudo cpan install Pod::Select` for multiline.pl
## Mirrors
- [acid.vegas](https://git.acid.vegas/weechat)
- [GitHub](https://github.com/acidvegas/weechat)
- [GitLab](https://gitlab.com/acidvegas/weechat)
- [SuperNETs](https://git.supernets.org/acidvegas/weechat)

108
alias.conf Normal file
View File

@ -0,0 +1,108 @@
# acidvegas alias.conf for weechat - https://git.acid.vegas/weechat
#  bold |  color |  underline |  reset
[cmd]
# Art
cig = "say 8,7\;.`-,:.`\;08,08 15,0||||||||||||||||||||4,14▄▀8,01▄▀14-\;`,-\;`"
cigtoss = "me throws $1 an ice cold 8,7\;.`-,:.`\;08,08 15,0||||||||||||||||||||4,14▄▀8,01▄▀14-\;`,-\;`"
derp = "say 0,1 10,10 11,10 10,10 0,1 1,1 ; say 0,1 11,10______0,1 1,1 ; say 0,1 11,10|10,10 11,10|10,10 11,10|10,10 11,10|10,10 0,1 1,1 ; say 0,1 8,8 1,8__8,8 1,8__8,8 0,1 1,1 ; say 8,8 1,0o8,8 1,0.8,8 1,1 ; say 0,1 8,8 1,8<.8,8 1,1 ; say 0,1 8,8 0,1 1,1 ; say 0,1 8,8 0,1,'8,8 0,1 1,1 ; say 0,1 8,8 0,1 1,1.;"
lovecock = "say 0,1 ; say 0,1 5,7#######0,1 ; say 0,1 5,7#####0 0,1 hey guys im $1, let me tell ; say 0,1 5,7#####0 5_1 5)0,1 you a little about myself... ; say 0,1 5,7#####0 0100 1o0 0,1 1 ; say 0,1 5,7###1@5# 0 1 0 0,1 i LOVE cock ; say 0,1 5,7#0 5# 0 1>0 0,1 ; say 0,1 5,7#0 5\;\;\;\;\;\;\;\;0,1 i LOVE cock ; say 0,1 0,7 0,1 ; say 0,1 0,7 0,1 1 0 ; say 0,1 0,7 1 5...W.0,1 I ROMANTICIZE THE NOTION ; say 0,1 0,7 1 5...0,1 OF HAVING COCKS AND BALLS ; say 0,1 0,7 0,1 ON ME AT ALL TIMES OF MY ; say 0,7 1 >0,1 LIFE. ; say 0,7 0,1;"
pump = "exec -o curl -s 'https://raw.githubusercontent.com/ircart/ircart/master/ircart/$0.txt'"
umad = "say 0,1<$1> umadyet? 0,7 0,1 ; say 0,1<$1> hemad 0,7 0,8 0,1 0,8 0,1 4hehe am ownin these fkn noobs; say 0,1<$1> umad 0,8 0,1 ; say 0,1<$1> umad 0,8 0,1 ; say 0,1<$1> umadyet? 0,5 0,8 0,1 0,15 0,1 ; say 0,1<$1> nou 0,5 0,2 0,1 0,11 0,15 0,1 ; say 0,1<$1> umad? 0,5 0,2 0,8 0,1 0,11 0,15 0,1 ; say 0,1<$1> umad 0,5 0,2 0,8 0,1 0,11 0,15 0,1 ; say 0,1<$1> cum @ me bra 0,5 0,2 0,8 0,1 0,15 0,1 ; say 0,1<$1> umad 0,5 0,2 0,1 0,8 0,1 0,8 0,1 0,5 ; say 0,1<$1> umadyet? 0,5 0,2 0,1 0,15 0,5 0,1 0,5 ; say 0,1<$1> umad 0,5 0,8 0,1 0,5 0,1 0,5 ; say 0,1<$1> somad 0,5 0,8 0,1 0,5 0,1 0,5 ; say 0,1<$1> umadyet? 0,5 0,14 0,1 0,5 0,1 0,15 0,5 ; say 0,1<$1> umad 0,5 0,1 0,14 0,1 0,5 0,1 0,15 0,5 ; say 0,1<$1> hes ragin 0,5 0,1 0,5 0,1 0,14 0,1 5 0,5 0,1 0,15 0,5 ; say 0,1<$1> umad 0,5 0,1 0,5 0,1 0,4 0,14 0,1 5 0,5 0,1 0,15 0,5 ; say 0,1<$1> umadyet? 0,5 0,1 0,5 0,1 0,4 0,1 5 0,5 0,1 0,15 0,5 ;"
# Alerts
chat_norm = "say 8,5▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄ 8,5▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄"
chat_srs = "say 8,5▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄ 8,5▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄"
emergency = "say 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!0,4 IRC EMERGENCY 8!1,8!8!"
flashbang = "cflood -fg 0 -bg 8 FLASHBANG"
prison = "say 04----------------------------------------------------------------------[IMPENETRABLE IRC PRISON WALL]-----------------------------------------------------------------------"
terminate = "kick $1 08,04 T E R M I N A T E D "
warning = "say 1,8/!\08,04 WARNING 1,8/!\ 04$*"
# Chatters
dm_ssh = "say i did a video on hiding my ssh banner a while back"
dzl_credit = "say im with a credit union"
dzl_26 = "say i dont troll because im 26"
dzl_job = "say i need a better job im too good at entry level shit"
dzl_reality = "say nice perception of reality"
tp_boom = "say just wait till i get a supernets then enough http requests then boom"
tp_dumb = "say your suck a dumb fucking idiot..."
# Faces
shrug = "say ¯\_(ツ)_/¯"
shades = "say (⌐■_■)"
srs = "say (ಠ_ಠ)"
# Random
beer = "me throws $1 an ice cold 0,0 0,2 BUD 1,0c =)"
beer2 = "me throw $1 an ice cold 0,0 0,5 BUD 1,0c =)"
blog = "say Hi! It looks like you're blogging on IRC. Would you like to: 2[Add Comments] 2[e-Mail this to a Friend] 2[Digg This!] 6[Submit to Slashdot] 2[Add to del.icio.us] 5[Kill yourself because0⬉5 nobody cares]"
chatrain = "say ya nice; say chillin u?; say nice ty np; say ok nice %% true; say same"
coffee = "me hands $1 a 5,2""] of coffee! =)"
cooldown = "say 1,8/!\8,4 WARNING 1,8/!\ 4This keyboard is currently on 12COOL DOWN4 until $1 can handle it."
cooled = "say [9ALERT] This keyboard is no longer on fire. Chats may proceed accordingly."
doritos = "say ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄ ▲ ▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ ◄▼ ◄ ▲ ► ▼ ◄ ▲ ► ▼ Ah Mannn! I dropped my bag of Doritos!!!"
en_gold = "say You must have an EFNet 8,7GOLD account to view this message."
fadeop = "me 14<02Mode14> [-o $114] by $nick"
fakick = "me 14<05Kick14> $1 was kicked by $nick 14[$2-14]"
fred = "say 4()_ <- FRED DURST'S HAT LOL"
gotem = "say 1,0 GOT EM "
hate = "say 4 HATE  4 HATE  4 HATE "
mail = "notice $channel You have unread messages from another user! Type /server mail read to read them."
wave = "cflood ▁▂▃▄▅▆▇█▇▆▅▄▃▂▁"
weed = "say 9DUUUUUUUUUUUUUUUUUUUUUUUUUUUUDE DUDE DUDE DUDE DUDE DUDE DUDE DUDE FUCKING WEEEEEEEEED AHAHAHAHAHAHAHA DUDE!!!!!!!!!! WEED!!!!!!!!!!!! *hits bong* FUCKING DUUUUUUDE that WEEED like just...................DUDE"
# Text
1stup = "say YO BITCH IM THE 1ST UP IN THIS PIECE. RESPECT MY ABILITY TO BE UP EARLY AND CHAT BEFORE YOU COCK SUCKER!!!!!!!!!"
chatmaster = "say YOUR CHAT MASTER WILL RETURN SHORTLY"
dna = "say i got your moms dna inserted into each of my sperms and everytime i fuck you your mom is somehow cumming inside you"
dummies = "me closes IRC For Dummies"
extroverts = "say bruh i hate extroverts yall niggas never shut the fuck up"
fbi = "notice $channel The Federal Bureau of Investigation logged a record of your entry into this illegal chatroom along with your IP address due to potential violations of 18 U.S.C. º 1030. Your IP address is entered into our criminaldatabase as well as the Department of Homeland Security. If you are not associated with these claims we strongly advise you to type '/part'. Thank you."
heartbeat = "say $1: your heart will skip one (1) beat in -5 seconds; say do not read this message;"
icmp = "say how about i do a nice icmp ping 2 u, figure out where you are and what you are on, spawn your command.com to a port of my choice and log in with telnet and have a field day with you"
ircjack = "say remember when i turned your IRC to a CNAME grabbed a valid cert and had your old IRC server DDoS'd so you and everyone else reconnected with their clients with no warning to irc.supernets.org?"
limp = "say OR YOULL BE LEAVIN WITH A FAT LIP; say ITS ALL ABOUT THE HE SAYS SHE SAYS BULL SHIT.; say I THINK YOU BETTER QUIT TALKIN THAT SHIT PUNK; say SO COME ON AND GET IT.; say ITS JUST ONE OF THOSE DAYS"
knuckz = "say my knuckz: (C)(H)(A)(T)b d(L)(I)(F)(E)"
linkin = "say CRAWLING IN MY SKIN. THESE WOUNDS THEY WILL NOT HEAL. FEAR IS HOW I FALL. CONFUSING WHAT IS REAL."
money = "say u look like a fucking money irl"
pasta = "say yo bitch what kinda pasta you into, im all about barbine, bavette, bigoli, bucatini, busiate, capellini, fedellini, ferrazzuoli, fettuccine, fileja, linguine, lagane, lasagna, lasagnette, lasagnotte, maccheroni alla molinara. maccheroncini di campofilone mafalde, matriciani, pappardelle, perciatteli, picagge, pici, pillus, rustiche, sagne 'ncannulate, scialatelli, spaghetti, spagetthi alla chitarra, spaghettini, spaghettoni, stringozzi, su filindeu, tagliatelle, taglierini, trenette, tripoline, vermicelli, ziti, anelli, boccoli, calamarata, campanelle, cappeli da chef, casarecce, casacatelli, castellane, cavatappi, cavatelli, chifferi, cicioneddos, conchiglie, creste di galli, fagioloni, farfalle, fazzoletti, festoni, fiorentine, fiori, fusilli, fusilli bucati, garganelli, gemelli, gnocchi, lanterne, lorighittas, macaroni, maccheroncelli, mafaldine, malloreddus, mandala, marrile, mezzani, mezze maniche, mezze penne, mezzi, bombardoni, nuvole, paccheri, paϟϟatelli, pasta el ceppo, penne, penne ricce, picchiarelli, pipe rigate, pizzoccheri, quadrefiore, radiatory, ricciollini, ricciutelle, rigatoncini, rigatoni, rombi, rotelle, sagnette, sagneralli, sedani, spirali, strapponi, strozzaperti, testaroli, tortigiloni, treccioni, trenne, trofie, trottole, tuffoli, vesuvio, cencioni, corzetti, fainelle, fogile, d'ulivo, orecchiette, acini de pepe, alphabet pasta, anchellini, anelli, anellini, armonie, conchigliette, corquilettes, coralli, corallini, cuscuϟϟu, ditali, egg barley, fideos, filini, fregula, funghini, gianduietta, grano, gramigne, grattini, grattoni, margerthine, merletti, midolline, occhi di paϟϟero, orzo, pastina, piombi, ptitim, puntine, quadrettini, sorprese, stelle, stortini, tripolini, agnolini, agnolotti, caccavelle, canneloni, cappelletti, caramelle, casoncelli, casunziei, conchiglioni, culurgiones, fagottini, lumache, mezzelune, occhi di lupo, pansotti, ravioli, rotolo ripieno, sacchettoni, tortelli, tortelloni, tufoli, canederli, donderet"
operscum = "say I have like 50,000 shells/vhosts/bncs. Bans won't do a thing except fill your list. And 'get to where i am today' is a sad testament to your life apparently. On a side note, I used to op other chans that are far bigger than this chan. I didn't get ops by k/b'ing everyone in sight or anyone that carried a touch of annoyance to me. I reserved k/bs for spammers and flooders, that's it. Everyone else I /ignored"
peep = "say ight so boom, i told son chill ah ah ah, he like nah, this that and the 3rd, blazhee blah, so i ping ponged poofed ol boi shit then i peeped the boyz so"
worms = "say super models give me dome while i count stacks and play worms"
your = "say look its not hard, your isnt you're.. you're is YOU ARE. jesus. did you even make it out of 8th grade. can you even COUNT TO EIGHT, fuckin your an IDIOT.. and im sure right now your eaiting to CORRECT ME on using your in the wrong context now that i've TAUGHT YOU HOW TO USE IT OMG JESUS"
# SuperNETs (Oper)
botsay = "msg BotServ SAY $channel"
deprotect = "msg ChanServ MODE $channel LOCK DEL +eI ~a:$1 ~a:$1; mode $channel -eI ~a:$1 ~a:$1"
protect = "mode $channel +eI ~a:$1 ~a:$1; msg chanserv mode $channel lock add +eI ~a:$1 ~a:$1"
sf = "spamfilter add simple cpnN kill - "08,04 E N T E R T H E V O I D " "$*"
# SuperNETs
sn_auto = "say yeah you can go ahead and add irc.supernets.org to your clients auto-connect config now."
sn_cont = "masshl %n 04CAN WE CONTINUE THIS CONVERSATION AT IRC.SUPERNETS.ORG #SUPERBOWL FOR FUCKS SAKE %n"
sn_dad = "say this isnt your dads football channel"
sn_move = "masshl %n: 1,8/!\08,04 WARNING 1,8/!\ 04This channel has moved to 12IRC.SUPERNETS.ORG #SUPERBOWL"
sn_gold = "say You must have a SuperNETs 8,7GOLD account to view this message."
# Useful
ajoin = "set irc.server.$server.autojoin ${irc.server.$server.autojoin},$channel"
clear = "buffer clear"
close = "buffer close"
collapse = "allchan -current /buffer hide; /allpv -current /buffer hide"
colors = "say 1,00001,01011,02021,03031,04041,05051,06061,07071,08081,09091,10101,11111,12121,13131,14141,1515 ; say 1,16161,17171,18181,19191,20201,21211,22221,23231,24241,25251,26261,2727 ; say 1,28281,29291,30301,31311,32321,33331,34341,35351,36361,37371,38381,3939 ; say 1,40401,41411,42421,43431,44441,45451,46461,47471,48481,49491,50501,5151 ; say 1,52521,53531,54541,55551,56561,57571,58581,59591,60601,61611,62621,6363 ; say 1,64641,65651,66661,67671,68681,69691,70701,71711,72721,73731,74741,7575 ; say 1,76761,77771,78781,79791,80801,81811,82821,83831,84841,85851,86861,8787 ; say 1,88881,89891,90901,91911,92921,93931,94941,95951,96961,97971,98981,9999;"
exempt = "mode +eI *!*@*.acid.vegas *!*@*.acid.vegas"
gh = "say https://github.com/$*"
harchats = "set irc.server.$server.anti_flood_prio_high 0 ; /set irc.server.$server.anti_flood_prio_low 0"
msgbuf = "command -buffer $1 * /input send $2-"
ns_ident = "msg NickServ IDENTIFY ${sec.data.${server}}"
ns_setup = "msg NickServ ACCESS ADD *@big.dick.acid.vegas; msg NickServ CERT ADD; msg NickServ SET AUTOOP ON; msg NickServ SET HIDE EMAIL ON; msg NickServ SET HIDE STATUS ON; msg NickServ SET HIDE USERMASK ON; msg NickServ SET HIDE QUIT ON; msg NickServ SET KEEPMODES ON; msg NickServ SET KILL QUICK; msg NickServ SET PRIVATE ON; msg NickServ SET SECURE ON"
redraw = "color reset;window refresh"
say = "msg *"
softchats = "set irc.server.$server.anti_flood_prio_high 2 ; /set irc.server.$server.anti_flood_prio_low 2"
uncollapse = "allchan -current /buffer unhide; /allpv -current /buffer unhide"
v = "voice * -yes"
wx = "who * n%nc"
[completion]
msgbuf = "%(buffers_plugins_names)"

369
scripts/perl/antifuck.pl Normal file
View File

@ -0,0 +1,369 @@
# Released into the Public Domain
use strict;
use warnings;
no strict 'subs';
my $SCRIPT_NAME = 'antifuck';
my $SCRIPT_AUTHOR = 'The Krusty Krab <wowaname@volatile.ch>';
my $SCRIPT_VERSION = '1.1';
my $SCRIPT_LICENCE = 'Public domain';
my $SCRIPT_DESC = 'Defend against forcejoins (e.g. from fuckyou.pl) and '.
'forceparts (e.g. from /remove)';
my %OPTIONS = (
autopart => ['Whether to automatically part forcejoined channels. '.
'You can always do this manually with /antifuck part', '0'],
delay => ['Delay in milliseconds to wait before autoparting', '5000'],
forward => ['Whether to allow channel forwards (+f on freenode)', '1'],
ignore => ['Servers to ignore (e.g. for bouncers), separated by comma', ''],
nobufs => ['If 1, do not create buffers for forcejoined channels', '0'],
timeout =>
['Delay in milliseconds to wait for server to send JOIN after join',
'60000'],
);
# %channels: channels we joined and received JOIN / NAMES for
# %zombie: channels we joined but aren't yet in
# %part: channels we were forced into and will part soon
# %partbuf: buffers belonging to parted channels, we'll close these on
# /antifuck part
our (%channels, %zombie, %part, %partbuf, $fuckbuf, $timeout_cb, $gc_cb);
if (weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
$SCRIPT_LICENCE, $SCRIPT_DESC, '', '')) {
weechat::hook_command('antifuck', $SCRIPT_DESC, 'part', <<'HELP',
This script defends against forced joins, such as from irssi's fuckyou.pl or
from channel forwards, as well as forced parts, such as from the /remove
command. You can configure certain behaviour using the options under
"plugins.var.perl.antifuck.*". Configure rejoin-on-/remove with the
irc.server_default.autorejoin and .autorejoin_delay commands.
Running "/antifuck part" will close all forcejoined channels and part them where
appropriate.
HELP
'part', 'cmd_antifuck', '');
weechat::hook_signal('irc_server_connected', 'irc_connect', '');
weechat::hook_signal('irc_server_disconnected', 'irc_disconnect', '');
weechat::hook_signal('irc_channel_opened', 'buffer_opened', '');
weechat::hook_signal('buffer_closed', 'buffer_closed', '');
weechat::hook_signal('*,irc_out1_join', 'client_join', '');
weechat::hook_signal('*,irc_out1_part', 'client_part', '');
weechat::hook_signal('*,irc_raw_in_001', 'irc_001', '');
weechat::hook_signal('*,irc_raw_in_470', 'irc_470', '');
weechat::hook_modifier('irc_in_366', 'irc_366', '');
weechat::hook_modifier('irc_in_join', 'irc_join', '');
weechat::hook_modifier('irc_in_part', 'irc_part', '');
for my $option (keys %OPTIONS) {
weechat::config_set_plugin($option, $OPTIONS{$option}[1])
unless weechat::config_is_set_plugin($option);
weechat::config_set_desc_plugin($option, $OPTIONS{$option}[0]);
}
my $iptr = weechat::infolist_get('buffer', '', '');
while (weechat::infolist_next($iptr)) {
next unless weechat::infolist_string($iptr, 'plugin_name') eq 'irc';
my $buf = weechat::infolist_pointer($iptr, 'pointer');
$channels{
lc weechat::buffer_get_string($buf, 'localvar_server')}{
lc weechat::buffer_get_string($buf, 'localvar_channel')} = 1;
}
weechat::infolist_free($iptr);
}
sub mynick
{
my ($buf, $nick) = ($_[0], $_[1]);
return lc weechat::buffer_get_string($buf, 'localvar_nick') eq lc $nick;
}
sub ignored
{
my $server = shift;
my $ignore_conf = lc weechat::config_get_plugin('ignore');
return $ignore_conf =~ /(^|,)$server($|,)/;
}
sub nobufs { weechat::config_get_plugin('nobufs') }
sub ircbuf { weechat::buffer_search('irc', "(?i)".(join '.', @_)) }
sub ircparse { weechat::info_get_hashtable(irc_message_parse =>
{ message => shift }) }
sub servchan
{
my $buf = shift;
return (lc weechat::buffer_get_string($buf, 'localvar_server'),
lc weechat::buffer_get_string($buf, 'localvar_channel'));
}
sub reset_gc
{
weechat::unhook($gc_cb) if $gc_cb;
$gc_cb = weechat::hook_timer(weechat::config_get_plugin('timeout'), 0, 1,
'run_gc', '');
}
sub cmd_antifuck
{
my (undef, $buffer, $args) = @_;
if ($args eq 'part') {
# TODO: we really need to spend more time here making sure we send the
# fewest PARTs possible, a la irc_join_delay
weechat::buffer_close($fuckbuf);
}
return weechat::WEECHAT_RC_OK;
}
sub fuckbuf_input { return weechat::WEECHAT_RC_OK; }
sub fuckbuf_close
{
weechat::buffer_close($_) for (keys %partbuf);
%partbuf = ();
$fuckbuf = '';
return weechat::WEECHAT_RC_OK;
}
sub irc_connect
{
my $server = pop;
my ($autojoin) = (weechat::config_string(weechat::config_get(
"irc.server.$server.autojoin")) =~ /^([^ ]*)/);
$zombie{$server}{$_} = 1 for (split ',', lc($autojoin));
return weechat::WEECHAT_RC_OK;
}
sub irc_disconnect
{
my $server = pop;
$server = lc $server;
delete $channels{$server};
delete $zombie{$server};
delete $part{$server};
return weechat::WEECHAT_RC_OK;
}
sub buffer_opened {
my $buffer = pop;
my ($server, $channel) = servchan($buffer);
return weechat::WEECHAT_RC_OK if exists $channels{$server}{$channel};
return weechat::WEECHAT_RC_OK if ignored($server);
$fuckbuf = weechat::buffer_new(
'antifuck',
'fuckbuf_input',
'',
'fuckbuf_close',
''
) unless $fuckbuf;
weechat::buffer_merge($buffer, $fuckbuf);
#return weechat::WEECHAT_RC_OK unless weechat::config_get_plugin('autopart');
$partbuf{$buffer} = 1;
return weechat::WEECHAT_RC_OK;
}
sub buffer_closed {
my $buffer = pop;
delete $partbuf{$buffer};
return weechat::WEECHAT_RC_OK;
}
sub client_join
{
my (undef, $server, $channel) = (shift,
shift =~ /(.+),irc_out1_join/i,
shift =~ /^join :?([^ ]*)/i);
($server, $channel) = (lc $server, lc $channel);
reset_gc();
($_ eq '0' ? %{$channels{$server}} = () : $zombie{$server}{$_} = 1)
for (split ',', $channel);
return weechat::WEECHAT_RC_OK;
}
sub client_part
{
my (undef, $server, $channel) = (shift,
shift =~ /(.+),irc_out1_part/i,
shift =~ /^part ([^ ]*)/i);
($server, $channel) = (lc $server, lc $channel);
delete $channels{$server}{$_} for (split ',', $channel);
return weechat::WEECHAT_RC_OK;
}
# RPL_WELCOME
sub irc_001
{
my (undef, $server, $message) = (shift,
shift =~ /(.+),irc_raw_in_001/, shift);
$server = lc $server;
return weechat::WEECHAT_RC_OK unless $message =~ / :- Welcome to ZNC -$/;
my $ignore_conf = lc weechat::config_get_plugin('ignore');
return weechat::WEECHAT_RC_OK if $ignore_conf =~ /(^|,)$server($|,)/;
weechat::config_set_plugin('ignore', "$ignore_conf,$server");
return weechat::WEECHAT_RC_OK;
}
sub irc_join
{
my ($server, $message, $msghash) = (lc $_[2], $_[3], ircparse($_[3]));
my ($nick, $channel) = ($msghash->{nick}, lc $msghash->{channel});
my $buffer = ircbuf("$server.$channel");
return $message if exists $channels{$server}{$channel};
if (exists $zombie{$server}{$channel} || ignored($server)) {
delete $zombie{$server}{$channel};
$channels{$server}{$channel} = 1;
return $message;
}
# XXX return $message unless mynick($buffer, $nick);
$part{$server}{$channel} = 1;
$timeout_cb = weechat::hook_timer(
weechat::config_get_plugin('delay'), 0, 1, 'irc_join_delay', $buffer)
unless $timeout_cb || !weechat::config_get_plugin('autopart');
return $message unless nobufs();
$fuckbuf = weechat::buffer_new(
'antifuck',
'fuckbuf_input',
'',
'fuckbuf_close',
''
) unless $fuckbuf;
weechat::print($fuckbuf, weechat::prefix('join').
weechat::color('irc.color.message_join').
'You were forced to join '.weechat::color('chat_channel').$channel.
weechat::color('irc.color.message_join').', leaving');
return '';
}
# RPL_ENDOFNAMES
sub irc_366
{
my ($server, $message) = ($_[2], $_[3]);
my ($nick, $channel) = $message =~ /^:[^ ]* 366 ([^ ]*) ([^ ]*)/i;
my $buffer = ircbuf("$server.$channel");
($server, $channel) = (lc $server, lc $channel);
return $message if exists $channels{$server}{$channel};
return '' if nobufs();
weechat::print($buffer, weechat::prefix('network').
'Forcejoined, not syncing modes');
return '';
}
# ERR_LINKCHANNEL
sub irc_470
{
my (undef, $server, $oldchan, $newchan) = (shift,
shift =~ /(.+),irc_raw_in_470/,
shift =~ /^:[^ ]* 470 [^ ]+ ([^ ]+) ([^ ]+)/);
($server, $oldchan, $newchan) = (lc $server, lc $oldchan, lc $newchan);
delete $channels{$server}{$oldchan};
$channels{$server}{$newchan} = 1 if weechat::config_get_plugin('forward');
return weechat::WEECHAT_RC_OK;
}
sub irc_join_delay
{
my $buffer = shift;
for my $server (keys %part) {
my $chans = '';
for my $chan (keys %{$part{$server}}) {
if (length($chans) + length($chan) > 500) {
weechat::hook_signal_send('irc_input_send',
weechat::WEECHAT_HOOK_SIGNAL_STRING,
"$server;;priority_low;;/part $chans");
$chans = '';
}
$chans .= "$chan,";
}
weechat::hook_signal_send('irc_input_send',
weechat::WEECHAT_HOOK_SIGNAL_STRING,
"$server;;priority_low;;/part $chans");
}
$timeout_cb = '';
%part = ();
return weechat::WEECHAT_RC_OK;
}
sub run_gc
{
%zombie = ();
return weechat::WEECHAT_RC_OK;
}
sub irc_part
{
my ($server, $message, $msghash) = ($_[2], $_[3], ircparse($_[3]));
my ($arj, $arj_delay, $arjd, $arjd_delay) = (
weechat::config_get("irc.server.$server.autorejoin"),
weechat::config_get("irc.server.$server.autorejoin_delay"),
weechat::config_get("irc.server_default.autorejoin"),
weechat::config_get("irc.server_default.autorejoin_delay")
);
return $message unless (
weechat::config_option_is_null($arj) ?
weechat::config_boolean($arjd) :
weechat::config_boolean($arj)
);
my ($nick, $channel, $reason) = ($msghash->{nick}, $msghash->{channel},
$msghash->{text});
my $buffer = ircbuf("$server.$channel");
my ($lserver, $lchannel) = (lc $server, lc $channel);
return $message unless mynick($buffer, $nick);
return $message unless exists $channels{$lserver}{$lchannel};
return $message if ignored($lserver);
weechat::print($buffer, weechat::prefix('quit').
weechat::color('irc.color.message_quit').
'You were forced to part '.weechat::color('chat_channel').$channel.
weechat::color('chat_delimiters').' ('.weechat::color('reset').
$reason.weechat::color('chat_delimiters').')'.
weechat::color('irc.color.message_quit').', rejoining');
my $delay = (
weechat::config_option_is_null($arj_delay) ?
weechat::config_integer($arjd_delay) :
weechat::config_integer($arj_delay)
);
weechat::command($buffer, ($delay ? "/wait $delay " : "").
"/join $channel");
return '';
}

150
scripts/perl/cflood.pl Normal file
View File

@ -0,0 +1,150 @@
#{{{ BSD License
# Copyright (c) 2008 hzu/zionist
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#}}}
# Ported from irssi to WeeChat by the Krusty Krab
use strict;
use warnings;
no strict 'subs';
my $SCRIPT_NAME = 'colourflood';
my $SCRIPT_AUTHOR = 'hzu';
my $SCRIPT_VERSION = '0.3';
my $SCRIPT_LICENCE = 'BSD';
my $SCRIPT_DESC = 'A-rab style ircing';
my $USAGE = <<EOF;
options:
-r Random back & foreground colours (default)
-f Amount of times the message is flooded
-fg font colour, available colours:
black, blue, green
lightred, red, magenta, orange
yellow, lightgreen, cyan,
lightcyan, lightblue,
lightmagenta, gray, lightgray.
-bg background colour, available colours:
black, blue, green, red,
magenta, orange, green, cyan,
lightcyan, lightblue,
lightmagenta, gray, lightgray
EOF
our %clr = (
black => 1,
blue => 2,
green => 3,
lightred => 4,
red => 5,
magenta => 6,
orange => 7,
yellow => 8,
lightgreen => 9,
cyan => 10,
lightcyan => 11,
lightblue => 12,
lightmagenta => 13,
gray => 14,
lightgray => 15,
);
if (weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
$SCRIPT_LICENCE, $SCRIPT_DESC, '', '')) {
weechat::hook_command('cflood', $SCRIPT_DESC, '[options] text',
$USAGE, '', 'cmd_cflood', '');
my %OPTIONS = (
dir => ['Database directory',
weechat::info_get('weechat_dir', '').'/yiffs'],
db => ['Default database', 'yiffs'],
solodb => ['Default database when nick is omitted', 'solos'],
);
for my $option (keys %OPTIONS) {
weechat::config_set_plugin($option, $OPTIONS{$option}[1])
unless weechat::config_is_set_plugin($option);
weechat::config_set_desc_plugin($option, $OPTIONS{$option}[0]);
}
}
sub colour {
my ($fg, $bg, $text) = @_;
my $fore = ($fg =~ /^[0-9][0-9]?$/) ? $fg : $clr{$fg};
my $back = ($fg =~ /^[0-9][0-9]?$/) ? $bg : $clr{$bg};
$fore-- if $fore == $back;
$text = "\003$fore,$back $text \003$back,$fore $text ";
$text x= (int 400 / length $text);
return "$text\003";
}
sub parse {
my @args = ( split / +/, shift );
my ( %todo, $text, $body );
while ( ($_ = shift @args) ne '' ) {
/^-r$/ and next;
/^-f$/ and $todo{f} = shift @args, next;
/^-fg$/ and $todo{fg} = shift @args, next;
/^-bg$/ and $todo{bg} = shift @args, next;
/^-/ and weechat::print('', weechat::prefix('error').
'Invalid arguments (see /help cflood)'), return;
$text = @args < 1 ? $_ : "$_ " . join ' ', @args;
last;
}
if (!(defined $todo{fg}) || !(defined $todo{bg})) {
$body = "";
my @rnd_clr = keys %clr;
foreach ( 1 .. (defined $todo{f} ? $todo{f} : 1 ) ) {
$body .= colour($rnd_clr[rand @rnd_clr],
$rnd_clr[rand @rnd_clr], $text, $todo{f});
$body .= "\n";
}
} else {
$body = "";
foreach ( 1 .. (defined $todo{f} ? $todo{f} : 1 ) ) {
$body .= colour( $todo{fg}, $todo{bg}, $text );
$body .= "\n";
}
}
return $body;
}
sub cmd_cflood {
my (undef, $buffer, $data) = @_;
my $ret;
return weechat::WEECHAT_RC_OK if ($data eq '');
chomp( $ret = parse($data) );
if ($ret =~ /\n/) {
map { weechat::command($buffer, "/msg * $_") } (split /\n/, $ret);
} else {
weechat::command($buffer, "/msg * $ret");
}
return weechat::WEECHAT_RC_OK;
}

View File

@ -0,0 +1,38 @@
use strict; use warnings;
$INC{'Encode/ConfigLocal.pm'}=1;
require Encode;
use utf8;
use constant SCRIPT_NAME => 'color_popup';
weechat::register(SCRIPT_NAME, 'Nei <anti.teamidiot.de>', '0.4', 'GPL3', 'show mirc color codes', '', '') || return;
my %ones = map { $_ => 1 } 0, 8, 14, 15, 42, 43, 45, 53 .. 58, 65 .. 86, 95 .. 98;
weechat::hook_modifier('input_text_display_with_cursor', 'color_popup', '');
## color_popup -- show mirc colors
## () - modifier handler
## $_[2] - buffer pointer
## $_[3] - input string
## returns modified input string
sub color_popup {
Encode::_utf8_on($_[3]);
my $cc = qr/(?:\03(?:\d{1,2}(?:,(?:\d{1,2})?)?)?|\02|\x1d|\x0f|\x12|\x15|\x16|\x1f)/;
my ($p1, $x, $p2) = split /((?:$cc)?\x19b#)/, $_[3], 2;
for ($p1, $p2) {
s/($cc)/$1■/g if weechat::config_string_to_boolean(weechat::config_get_plugin('reveal'));
Encode::_utf8_on($_ = weechat::hook_modifier_exec(irc_color_decode => 1, weechat::hook_modifier_exec(irc_color_encode => 1, $_)));
}
$x .= ' ' . weechat::hook_modifier_exec(
irc_color_decode => 1, sub {
$x =~ /\cC(\d{1,2})(,(\d{1,2})?)?/;
my ($fg, $bg) = ($1//-1, $3//-1);
my $sc = $bg >= 0 ? $bg : $2?-1:$fg;
(join '', map {
"\03" . ($ones{0+$_} // 0) . ",$_$_"
}
$sc >= 0 ? grep /^0?$sc/, '00' .. '99' : ('00' .. '15'))
. "\03"
}->()
) if $x =~ /^\03/ and weechat::current_buffer() eq $_[2];
"$p1$x$p2"
}

188
scripts/perl/fuckyou.pl Normal file
View File

@ -0,0 +1,188 @@
# Ported from irssi to WeeChat by the Krusty Krab
use Time::HiRes qw(time);
use Digest::MD5 qw(md5_hex);
#__ ___ ____ _ _ ___ _ _ ____ _ _ ____ ___ _ _ ____
#\ \ / / \ | _ \| \ | |_ _| \ | |/ ___| | | | / ___|_ _| \ | |/ ___|
# \ \ /\ / / _ \ | |_) | \| || || \| | | _ | | | \___ \| || \| | | _
# \ V V / ___ \| _ <| |\ || || |\ | |_| | | |_| |___) | || |\ | |_| |
# \_/\_/_/ \_\_| \_\_| \_|___|_| \_|\____| \___/|____/___|_| \_|\____|
#
# _____ _ _ _____ ____ _____ ____ ____ ____ ___ ____ _____ ____
#|_ _| | | | ____/ ___|| ____| / ___| / ___| _ \|_ _| _ \_ _/ ___|
# | | | |_| | _| \___ \| _| \___ \| | | |_) || || |_) || | \___ \
# | | | _ | |___ ___) | |___ ___) | |___| _ < | || __/ | | ___) |
# |_| |_| |_|_____|____/|_____| |____/ \____|_| \_\___|_| |_| |____/
#
# __ __ _ __ __ ____ _____ _ _ _ __ __
#| \/ | / \\ \ / / | _ \| ____| / \ | | | | \ \ / /
#| |\/| | / _ \\ V / | |_) | _| / _ \ | | | | \ \//
#| | | |/ ___ \| | | _ <| |___ / ___ \| |___| |___| |
#|_| |_/_/ \_\_| |_| \_\_____/_/ \_\_____|_____|_|
#
# _____ _ _ ____ _ _____ _ _ ____ _ _ _ _ _ _____ __
#| ___| | | |/ ___| |/ /_ _| \ | |/ ___| / \ | \ | | \ | |/ _ \ \ / /
#| |_ | | | | | | ' / | || \| | | _ / _ \ | \| | \| | | | \ V /
#| _| | |_| | |___| . \ | || |\ | |_| | / ___ \| |\ | |\ | |_| || |
#|_| \___/ \____|_|\_\___|_| \_|\____| /_/ \_\_| \_|_| \_|\___/ |_|
#
#__ _____ _ _ ____ _ _ ____ _____ ____ ____
#\ \ / / _ \| | | | _ \ | | | / ___|| ____| _ \/ ___|
# \ V / | | | | | | |_) | | | | \___ \| _| | |_) \___ \
# | || |_| | |_| | _ < | |_| |___) | |___| _ < ___) |
# |_| \___/ \___/|_| \_\ \___/|____/|_____|_| \_\____/
my $SCRIPT_NAME = 'fuckyou';
my $SCRIPT_AUTHOR = 'Goat-See <mrtheplague@gmail.com>';
my $SCRIPT_VERSION = '2.3';
my $SCRIPT_LICENCE = 'urmom';
my $SCRIPT_DESC = '/fuckyou NICK numberchannels';
my %OPTIONS = (
forcejoin => ['Command to forcejoin. ratbox uses forcejoin, unreal sajoin',
'forcejoin'],
forcepart => ['Command to forcepart. ratbox uses forcepart, unreal sapart',
'forcepart'],
furry => ['Channel prefix (include # or &)', '&HYE'],
parallel => ['Number of channels to send per forcejoin command', 1],
whois_cmd => ['Prefix to whois user (e.g. for ratbox operspy, "/whois !")',
'/whois '],
);
sub fuckyou
{
my $buffer = shift;
my $nig = $$ * time;
my @jews;
push @jews, "${FURRY}_".md5_hex($nig + $_) for (1..$PARALLEL);
weechat::command($buffer, "/quote $FORCEJOIN $target ".join(',', @jews));
return weechat::WEECHAT_RC_OK;
}
sub cmd_fuckyou
{
my (undef, $buffer, $data) = @_;
my $server = weechat::buffer_get_string($buffer, 'localvar_server');
my $amt_end;
($target, $amt_end) = split / +/, $data;
our ($FORCEJOIN, $FURRY, $PARALLEL) = (
weechat::config_get_plugin('forcejoin'),
weechat::config_get_plugin('furry'),
weechat::config_get_plugin('parallel'));
weechat::unhook($signal) if $signal;
weechat::unhook($timer) if $timer;
unless ($target) {
weechat::print($buffer, 'Stopped any current /fuckyou');
return weechat::WEECHAT_RC_OK;
}
$amt_end //= 0;
$signal = weechat::hook_signal("$server,irc_raw_in_402", 'irc_402', '');
$timer = weechat::hook_timer(50, 0, $amt_end, 'fuckyou', $buffer);
return weechat::WEECHAT_RC_OK;
}
sub cmd_unfuckyou
{
my (undef, $buffer, $data) = @_;
my ($server, $channel) = (
weechat::buffer_get_string($buffer, 'localvar_server'),
weechat::buffer_get_string($buffer, 'localvar_channel')
);
my $WHOIS = weechat::config_get_plugin('whois_cmd');
unless ($data) {
weechat::print($buffer, '/unfuckyou user user2 user3');
return weechat::WEECHAT_RC_OK;
}
foreach my $dick (split / +/, $data) {
weechat::hook_hsignal_send(
'irc_redirect_command',
{
server => "$server",
pattern => "whois",
signal => "sigwhois"
});
weechat::hook_signal_send(
'irc_input_send',
weechat::WEECHAT_HOOK_SIGNAL_STRING,
"$server;;1;;$WHOIS$dick"
);
}
return weechat::WEECHAT_RC_OK;
}
sub event_whois_channels
{
my %hashtable = %{$_[2]};
my $FORCEPART = weechat::config_get_plugin('forcepart');
my $FURRY = weechat::config_get_plugin('furry');
my $counter = 0;
my ($nick, $channels);
for (split /^/, $hashtable{output}) {
if (/^:[^ ]* 319 [^ ]+ ([^ ]+) :(.*)$/) {
($nick, $channels) = ($1, $2);
} else { next; }
$channels =~ s/ +$//;
my @niggers = split / +/, $channels;
foreach (@niggers)
{
s/^[!@%+]*([&#])/$1/;
if(/${FURRY}_[a-f0-9]+/i)
{
#Irssi::print("Forceparting $nick from $_");
weechat::command('', "/quote $FORCEPART $nick $_");
++$counter;
}
}
}
weechat::print('', "Forceparted $nick from $counter channels")
if $counter;
return weechat::WEECHAT_RC_OK;
}
sub irc_402 {
my $message = pop;
my $targmatch = quotemeta $target;
return weechat::WEECHAT_RC_OK
unless ($message =~ /^[^ ]* 402 [^ ]+ $targmatch /i);
weechat::unhook($signal);
weechat::unhook($timer);
return weechat::WEECHAT_RC_OK;
}
if (weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
$SCRIPT_LICENCE, $SCRIPT_DESC, '', '')) {
weechat::hook_command('fuckyou', '', '[<nick> [<amt>]]',
"if nick is not given, stops current fuckyou, if any is running\n\n".
"amt is 0 by default - user will be fuckyoud until they disconnect\n".
"or you stop it manually\n",
'', 'cmd_fuckyou', '');
weechat::hook_command('unfuckyou', '', '<nick> [nick...]', '', '',
'cmd_unfuckyou', '');
weechat::hook_hsignal('irc_redirection_sigwhois_whois',
'event_whois_channels', '');
for my $option (keys %OPTIONS) {
weechat::config_set_plugin($option, $OPTIONS{$option}[1])
unless weechat::config_is_set_plugin($option);
weechat::config_set_desc_plugin($option, $OPTIONS{$option}[0]);
}
}

1146
scripts/perl/highmon.pl Normal file

File diff suppressed because it is too large Load Diff

1255
scripts/perl/hueg.pl Normal file

File diff suppressed because it is too large Load Diff

279
scripts/perl/keepnick.pl Normal file
View File

@ -0,0 +1,279 @@
# This script was made to improve upon keepnick.py
use strict;
use warnings;
no strict 'subs';
my $SCRIPT_NAME = 'keepnick';
my $SCRIPT_AUTHOR = 'The Krusty Krab <wowaname@volatile.ch>';
my $SCRIPT_VERSION = '1.0';
my $SCRIPT_LICENCE = 'Public domain';
my $SCRIPT_DESC = 'Keep your primary nickname';
our (%waiting, %connecting, %noison);
my %OPTIONS = (
default_enable => ['Whether to enable keepnick on servers by default', '0'],
check_time => ['Time between ISON checks (reload script to take effect)', '60'],
);
sub arrindex
{
1 while $_[0] ne pop;
return @_ - 1;
}
sub info
{
weechat::print(weechat::buffer_search('irc', 'server.'.shift),
weechat::prefix('server').shift);
}
sub my_nick
{ return lc weechat::info_get('irc_nick', shift); }
sub is_preferable
{
my ($server, $target) = @_;
my ($targidx, $myidx) = (
arrindex($target, @{$waiting{$server}}),
arrindex(my_nick($server), @{$waiting{$server}}));
return ($myidx == -1 or $targidx < $myidx);
}
sub is_waiting
{
my $server = lc shift;
return exists $waiting{$server} ? @{ $waiting{$server} } : ();
}
sub disable
{ delete $waiting{lc shift}; }
sub enable
{
my $server = shift;
my $force = shift // 0;
my @target = @_ ? split ',', shift : ();
unless (@target) {
my ($conf_nicks, $confd_nicks) = (
weechat::config_get("irc.server.$server.nicks"),
weechat::config_get("irc.server_default.nicks"));
@target = split ',', weechat::config_string(
weechat::config_option_is_null($conf_nicks)
? $confd_nicks : $conf_nicks);
}
$server = lc $server;
my ($defaultconf, $serverconf) = (
weechat::config_get_plugin('default_enable'),
weechat::config_get_plugin("server.$server"));
unless ($force) {
return () if $serverconf ne '' and !$serverconf;
return () if $serverconf eq '' and !$defaultconf;
}
return () if lc $target[0] eq my_nick($server);
$waiting{$server} = \@target;
return @target;
}
sub do_nick
{
my ($server, $nick) = @_;
weechat::hook_signal_send('irc_input_send',
weechat::WEECHAT_HOOK_SIGNAL_STRING,
"$server;;;;/nick $nick");
if (lc $waiting{$server}->[0] eq lc $nick) {
# we're done if we have our primary nick choice, otherwise keep trying
disable($server);
info($server, "got your primary nick!");
} else {
info($server, "got one of your nicks; still trying for your primary nick");
}
}
sub try_nick
{
my ($server, $oldnick) = @_;
($server, $oldnick) = (lc $server, lc $oldnick);
my ($mynick, @confnick) = (my_nick($server), is_waiting($server));
return unless @confnick;
return unless is_preferable($server, $oldnick);
if ($mynick eq $oldnick) { disable($server); }
else { lc $_ eq $oldnick and do_nick($server, $_) for @confnick; }
}
sub ison_check
{
my $iptr = weechat::infolist_get('irc_server', '', '');
while (weechat::infolist_next($iptr)) {
next unless weechat::infolist_integer($iptr, 'is_connected');
my $server = lc weechat::infolist_string($iptr, 'name');
next unless is_waiting($server);
next unless exists $noison{$server};
weechat::hook_hsignal_send('irc_redirect_command', {
server => $server,
pattern => 'ison',
signal => $SCRIPT_NAME,
timeout => weechat::config_get_plugin('check_time') - 1,
});
weechat::hook_signal_send('irc_input_send',
weechat::WEECHAT_HOOK_SIGNAL_STRING,
"$server;;;;/ison ".(join ' ', @{ $waiting{$server} }));
}
weechat::infolist_free($iptr);
return weechat::WEECHAT_RC_OK;
}
sub irc_ison
{
my %hashtable = %{ pop() };
unless ($hashtable{output}) {
$noison{lc $hashtable{server}} = 1;
return weechat::WEECHAT_RC_ERROR;
}
my %nicks = map { lc $_ => 1 }
split / +/, ($hashtable{output} =~ s/^:[^ ]* 303 [^ ]+ :?//r);
for my $confnick (is_waiting($hashtable{server})) {
next if exists $nicks{lc $confnick}; # still taken
do_nick($hashtable{server}, $confnick);
last;
}
return weechat::WEECHAT_RC_OK;
}
sub irc_nick
{
my (undef, $server, $oldnick, $newnick) = (shift,
shift =~ /(.+),irc_raw_in_nick/i,
shift =~ /:([^! ]+)[^ ]* nick :?(.*)/i);
return weechat::WEECHAT_RC_OK if lc $oldnick eq lc $newnick;
try_nick($server, $oldnick);
return weechat::WEECHAT_RC_OK;
}
sub irc_quit
{
my (undef, $server, $nick) = (shift,
shift =~ /(.+),irc_raw_in_quit/i,
shift =~ /:([^! ]+)[^ ]* quit /i);
try_nick($server, $nick);
return weechat::WEECHAT_RC_OK;
}
sub irc_433
{
my ($server) = $_[1] =~ /(.+),irc_raw_in2_433/i;
$server = lc $server;
# nick is taken when we connect? enable
if (exists $connecting{$server}) {
enable($server) and info($server, 'keepnick enabled');
}
return weechat::WEECHAT_RC_OK;
}
sub irc_connecting
{
$connecting{lc pop} = 1;
return weechat::WEECHAT_RC_OK;
}
sub irc_connected
{
delete $connecting{lc pop};
return weechat::WEECHAT_RC_OK;
}
sub irc_disconnect
{
my $server = lc pop;
delete $connecting{$server};
disable($server);
return weechat::WEECHAT_RC_OK;
}
sub cmd_keepnick
{
my (undef, $buffer, $command) = @_;
my $server = lc weechat::buffer_get_string($buffer, 'localvar_server');
for ($command) {
chomp;
if (/^$/) {
info($server, is_waiting($server)
? "trying to get '".(join "', '", is_waiting($server))."'"
: "not keeping your nick");
}
elsif (/^-enable$/) {
my @waiting = enable($server, 1);
if (@waiting) { info($server, "enabled, now waiting for '".(join "', '", @waiting)."'"); }
else { info($server, "you already have your primary nick! doing nothing"); }
}
elsif (/^-disable$/) {
disable($server);
info($server, "no longer trying to keep your nick");
}
elsif (/^-autoenable$/) {
weechat::config_get_plugin('default_enable')
? weechat::config_unset_plugin("server.$server")
: weechat::config_set_plugin("server.$server", '1');
enable($server);
info($server, "keepnick enabled on this server");
}
elsif (/^-autodisable$/) {
weechat::config_get_plugin('default_enable')
? weechat::config_set_plugin("server.$server", '0')
: weechat::config_unset_plugin("server.$server");
disable($server);
info($server, "keepnick disabled on this server");
}
else {
my @waiting = enable($server, 1, $command =~ s/ /,/gr);
if (@waiting) { info($server, "now waiting for '".(join "', '", @waiting)."'"); }
else { info($server, "you already have your primary nick! doing nothing"); }
}
}
return weechat::WEECHAT_RC_OK;
}
if (weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
$SCRIPT_LICENCE, $SCRIPT_DESC, '', '')) {
for my $option (keys %OPTIONS) {
weechat::config_set_plugin($option, $OPTIONS{$option}[1])
unless weechat::config_is_set_plugin($option);
weechat::config_set_desc_plugin($option, $OPTIONS{$option}[0]);
}
weechat::hook_command('keepnick', $SCRIPT_DESC,
"[nick]\n-enable|-disable\n-autoenable|-autodisable",
"This command allows you to check the current server keepnick\n".
"status or to manually specify nicks (separated by comma) to keep.\n".
"You may also manually -enable or -disable keepnick on the current\n".
"server. Both -autoenable and -autodisable choices are saved in\n".
"config under 'plugins.var.perl.$SCRIPT_NAME.server.xxx' where 'xxx'\n".
"is the server name.",
'-enable|-disable|-autoenable|-autodisable %-', 'cmd_keepnick', '');
weechat::hook_signal('*,irc_raw_in_nick', 'irc_nick', '');
weechat::hook_signal('*,irc_raw_in_quit', 'irc_quit', '');
weechat::hook_signal('*,irc_raw_in2_433', 'irc_433', '');
weechat::hook_signal('irc_server_connecting', 'irc_connecting', '');
weechat::hook_signal('irc_server_connected', 'irc_connected', '');
weechat::hook_signal('irc_server_disconnected', 'irc_disconnect', '');
weechat::hook_timer(weechat::config_get_plugin('check_time') * 1000, 0, 0,
'ison_check', '');
weechat::hook_hsignal("irc_redirection_${SCRIPT_NAME}_ison", 'irc_ison', '');
my $iptr = weechat::infolist_get('irc_server', '', '');
enable(weechat::infolist_string($iptr, 'name'))
while (weechat::infolist_next($iptr));
weechat::infolist_free($iptr);
}

798
scripts/perl/multiline.pl Normal file
View File

@ -0,0 +1,798 @@
use strict; use warnings;
$INC{'Encode/ConfigLocal.pm'}=1;
require Encode;
use utf8;
# multiline.pl is written by Nei <anti.teamidiot.de>
# and licensed under the under GNU General Public License v3
# or any later version
# to read the following docs, you can use "perldoc multiline.pl"
=head1 NAME
multiline - Multi-line edit box for WeeChat (weechat edition)
=head1 DESCRIPTION
multiline will draw a multi-line edit box to your WeeChat window so
that when you hit the return key, you can first compose a complete
multi-line message before sending it all at once.
Furthermore, if you have multi-line pastes then you can edit them
before sending out all the lines.
=head1 USAGE
make a key binding to send the finished message:
/key bind meta-s /input return
then you can send the multi-line message with Alt+S
=head1 SETTINGS
the settings are usually found in the
plugins.var.perl.multiline
namespace, that is, type
/set plugins.var.perl.multiline.*
to see them and
/set plugins.var.perl.multiline.SETTINGNAME VALUE
to change a setting C<SETTINGNAME> to a new value C<VALUE>. Finally,
/unset plugins.var.perl.multiline.SETTINGNAME
will reset a setting to its default value.
the following settings are available:
=head2 char
character(s) which should be displayed to indicate end of line
=head2 tab
character(s) which should be displayed instead of Tab key character
=head2 lead_linebreak
if turned on, multi-line messages always start on a new line
=head2 modify_keys
if turned on, cursor keys are modified so that they respect line
boundaries instead of treating the whole multi-line message as a
single line
=head2 magic
indicator displayed when message will be sent soon
=head2 magic_enter_time
delay after pressing enter before sending automatically (in ms), or 0
to disable
=head2 magic_paste_only
only use multi-line messages for multi-line pastes (multi-line on
enter is disabled by this)
=head2 paste_lock
time-out to detect pastes (disable the weechat built-in paste
detection if you want to use this)
=head2 send_empty
set to on to automatically disregard enter key on empty line
=head2 hide_magic_nl
whether the new line inserted by magic enter key will be hidden
=head2 weechat_paste_fix
disable ctrl-j binding when paste is detected to stop silly weechat
sending out pastes without allowing to edit them
=head2 ipl
this setting controls override of ctrl-m (enter key) by script. Turn
it off if you don't want multiline.pl to set and re-set the key binding.
=head1 FUNCTION DESCRIPTION
for full pod documentation, filter this script with
perl -pE'
(s/^## (.*?) -- (.*)/=head2 $1\n\n$2\n\n=over\n/ and $o=1) or
s/^## (.*?) - (.*)/=item I<$1>\n\n$2\n/ or
(s/^## (.*)/=back\n\n$1\n\n=cut\n/ and $o=0,1) or
($o and $o=0,1 and s/^sub /=back\n\n=cut\n\nsub /)'
=cut
use constant SCRIPT_NAME => 'multiline';
our $VERSION = '0.6.4';
weechat::register(SCRIPT_NAME,
'Nei <anti.teamidiot.de>', # Author
$VERSION,
'GPL3', # License
'Multi-line edit box', # Description
'stop_multiline', '') || return;
sub SCRIPT_FILE() {
my $infolistptr = weechat::infolist_get('perl_script', '', SCRIPT_NAME);
my $filename = weechat::infolist_string($infolistptr, 'filename') if weechat::infolist_next($infolistptr);
weechat::infolist_free($infolistptr);
return $filename unless @_;
}
{
package Nlib;
# this is a weechat perl library
use strict; use warnings; no warnings 'redefine';
## get_key_name -- get key name valid for any weechat version
## $key_name - name of key as valid in weechat 4.0.0; note: only supports keys used in this file, not any key
## $secondary_code - for keys with multiple codes, set to 1 to return the second code instead of the first
## returns key name unchanged if weechat >= 4.0.0; key name translated to old name if weechat < 4.0.0
sub get_key_name {
my $key_name = shift;
my $secondary_code = shift;
return $key_name if (weechat::info_get('version_number', '') || 0) >= 0x04000000;
return "ctrl-H" if $key_name eq "backspace" && $secondary_code;
return "ctrl-?" if $key_name eq "backspace" && !$secondary_code;
return "meta2-A" if $key_name eq "up";
return "meta2-B" if $key_name eq "down";
$key_name =~ s/ctrl-(\w+)/ctrl-\U$1/;
return $key_name;
}
## i2h -- copy weechat infolist content into perl hash
## $infolist - name of the infolist in weechat
## $ptr - pointer argument (infolist dependend)
## @args - arguments to the infolist (list dependend)
## $fields - string of ref type "fields" if only certain keys are needed (optional)
## returns perl list with perl hashes for each infolist entry
sub i2h {
my %i2htm = (i => 'integer', s => 'string', p => 'pointer', b => 'buffer', t => 'time');
local *weechat::infolist_buffer = sub { '(not implemented)' };
my ($infolist, $ptr, @args) = @_;
$ptr ||= "";
my $fields = ref $args[-1] eq 'fields' ? ${ pop @args } : undef;
my $infptr = weechat::infolist_get($infolist, $ptr, do { local $" = ','; "@args" });
my @infolist;
while (weechat::infolist_next($infptr)) {
my @fields = map {
my ($t, $v) = split ':', $_, 2;
bless \$v, $i2htm{$t};
}
split ',',
($fields || weechat::infolist_fields($infptr));
push @infolist, +{ do {
my (%list, %local, @local);
map {
my $fn = 'weechat::infolist_'.ref $_;
my $r = do { no strict 'refs'; &$fn($infptr, $$_) };
if ($$_ =~ /^localvar_name_(\d+)$/) {
$local[$1] = $r;
()
}
elsif ($$_ =~ /^(localvar)_value_(\d+)$/) {
$local{$local[$2]} = $r;
$1 => \%local
}
elsif ($$_ =~ /(.*?)((?:_\d+)+)$/) {
my ($key, $idx) = ($1, $2);
my @idx = split '_', $idx; shift @idx;
my $target = \$list{$key};
for my $x (@idx) {
my $o = 1;
if ($key eq 'key' or $key eq 'key_command') {
$o = 0;
}
if ($x-$o < 0) {
local $" = '|';
weechat::print('',"list error: $target/$$_/$key/$x/$idx/@idx(@_)");
$o = 0;
}
$target = \$$target->[$x-$o]
}
$$target = $r;
$key => $list{$key}
}
else {
$$_ => $r
}
} @fields
} };
}
weechat::infolist_free($infptr);
!wantarray && @infolist ? \@infolist : @infolist
}
## hdh -- hdata helper
## $_[0] - arg pointer or hdata list name
## $_[1] - hdata name
## $_[2..$#_] - hdata variable name
## $_[-1] - hashref with key/value to update (optional)
## returns value of hdata, and hdata name in list ctx, or number of variables updated
sub hdh {
if (@_ > 1 && $_[0] !~ /^0x/ && $_[0] !~ /^\d+$/) {
my $arg = shift;
unshift @_, weechat::hdata_get_list(weechat::hdata_get($_[0]), $arg);
}
while (@_ > 2) {
my ($arg, $name, $var) = splice @_, 0, 3;
my $hdata = weechat::hdata_get($name);
unless (ref $var eq 'HASH') {
$var =~ s/!(.*)/weechat::hdata_get_string($hdata, $1)/e;
(my $plain_var = $var) =~ s/^\d+\|//;
my $type = weechat::hdata_get_var_type_string($hdata, $plain_var);
if ($type eq 'pointer') {
my $name = weechat::hdata_get_var_hdata($hdata, $var);
unshift @_, $name if $name;
}
my $fn = "weechat::hdata_$type";
unshift @_, do { no strict 'refs';
&$fn($hdata, $arg, $var) };
}
else {
return weechat::hdata_update($hdata, $arg, $var);
}
}
wantarray ? @_ : $_[0]
}
use Pod::Select qw();
use Pod::Simple::TextContent;
## get_desc_from_pod -- return setting description from pod documentation
## $file - filename with pod
## $setting - name of setting
## returns description as text
sub get_desc_from_pod {
my $file = shift;
return unless -s $file;
my $setting = shift;
open my $pod_sel, '>', \my $ss;
Pod::Select::podselect({
-output => $pod_sel,
-sections => ["SETTINGS/$setting"]}, $file);
my $pt = new Pod::Simple::TextContent;
$pt->output_string(\my $ss_f);
$pt->parse_string_document($ss);
my ($res) = $ss_f =~ /^\s*\Q$setting\E\s+(.*)\s*/;
$res
}
## get_settings_from_pod -- retrieve all settings in settings section of pod
## $file - file with pod
## returns list of all settings
sub get_settings_from_pod {
my $file = shift;
return unless -s $file;
open my $pod_sel, '>', \my $ss;
Pod::Select::podselect({
-output => $pod_sel,
-sections => ["SETTINGS//!.+"]}, $file);
$ss =~ /^=head2\s+(.*)\s*$/mg
}
## mangle_man_for_wee -- turn man output into weechat codes
## @_ - list of grotty lines that should be turned into weechat attributes
## returns modified lines and modifies lines in-place
sub mangle_man_for_wee {
for (@_) {
s/_\x08(.)/weechat::color('underline').$1.weechat::color('-underline')/ge;
s/(.)\x08\1/weechat::color('bold').$1.weechat::color('-bold')/ge;
}
wantarray ? @_ : $_[0]
}
## read_manpage -- read a man page in weechat window
## $file - file with pod
## $name - buffer name
sub read_manpage {
my $caller_package = (caller)[0];
my $file = shift;
my $name = shift;
if (my $obuf = weechat::buffer_search('perl', "man $name")) {
eval qq{
package $caller_package;
weechat::buffer_close(\$obuf);
};
}
my @wee_keys = Nlib::i2h('key');
my @keys;
my $winptr = weechat::current_window();
my ($wininfo) = Nlib::i2h('window', $winptr);
my $buf = weechat::buffer_new("man $name", '', '', '', '');
return weechat::WEECHAT_RC_OK unless $buf;
my $width = $wininfo->{chat_width};
--$width if $wininfo->{chat_width} < $wininfo->{width} || ($wininfo->{width_pct} < 100 && (grep { $_->{y} == $wininfo->{y} } Nlib::i2h('window'))[-1]{x} > $wininfo->{x});
$width -= 2; # when prefix is shown
weechat::buffer_set($buf, 'time_for_each_line', 0);
eval qq{
package $caller_package;
weechat::buffer_set(\$buf, 'display', 'auto');
};
die $@ if $@;
@keys = map { $_->{key} }
grep { $_->{command} eq '/input history_previous' ||
$_->{command} eq '/input history_global_previous' } @wee_keys;
@keys = Nlib::get_key_name('up') unless @keys;
weechat::buffer_set($buf, "key_bind_$_", '/window scroll -1') for @keys;
@keys = map { $_->{key} }
grep { $_->{command} eq '/input history_next' ||
$_->{command} eq '/input history_global_next' } @wee_keys;
@keys = Nlib::get_key_name('down') unless @keys;
weechat::buffer_set($buf, "key_bind_$_", '/window scroll +1') for @keys;
weechat::buffer_set($buf, 'key_bind_ ', '/window page_down');
@keys = map { $_->{key} }
grep { $_->{command} eq '/input delete_previous_char' } @wee_keys;
@keys = (Nlib::get_key_name('backspace'), Nlib::get_key_name('backspace', 1)) unless @keys;
weechat::buffer_set($buf, "key_bind_$_", '/window page_up') for @keys;
weechat::buffer_set($buf, 'key_bind_g', '/window scroll_top');
weechat::buffer_set($buf, 'key_bind_G', '/window scroll_bottom');
weechat::buffer_set($buf, 'key_bind_q', '/buffer close');
weechat::print($buf, " \t".mangle_man_for_wee($_)) # weird bug with \t\t showing nothing?
for `pod2man \Q$file\E 2>/dev/null | GROFF_NO_SGR=1 nroff -mandoc -rLL=${width}n -rLT=${width}n -Tutf8 2>/dev/null`;
weechat::command($buf, '/window scroll_top');
unless (hdh($buf, 'buffer', 'lines', 'lines_count') > 0) {
weechat::print($buf, weechat::prefix('error').$_)
for "Unfortunately, your @{[weechat::color('underline')]}nroff".
"@{[weechat::color('-underline')]} command did not produce".
" any output.",
"Working pod2man and nroff commands are required for the ".
"help viewer to work.",
"In the meantime, please use the command ", '',
"\tperldoc $file", '',
"on your shell instead in order to read the manual.",
"Thank you and sorry for the inconvenience."
}
}
1
}
our $MAGIC_ENTER_TIMER;
our $MAGIC_LOCK;
our $MAGIC_LOCK_TIMER;
our $WEECHAT_PASTE_FIX_CTRLJ_CMD;
our $INPUT_CHANGED_EATER_FLAG;
our $IGNORE_INPUT_CHANGED;
our $IGNORE_INPUT_CHANGED2;
use constant INPUT_NL => '/input insert \x0a';
use constant INPUT_MAGIC => '/input magic_enter';
our $KEY_RET = Nlib::get_key_name('ctrl-m');
our $NL = "\x0a";
init_multiline();
my $magic_enter_cancel_dynamic = 1;
my $paste_undo_start_ignore_dynamic = 0;
my $input_changed_eater_dynamic = 0;
my $multiline_complete_fix_dynamic = 1;
sub magic_enter_cancel_dynamic { $magic_enter_cancel_dynamic ? &magic_enter_cancel : weechat::WEECHAT_RC_OK }
sub paste_undo_start_ignore_dynamic { $paste_undo_start_ignore_dynamic ? &paste_undo_start_ignore : weechat::WEECHAT_RC_OK }
sub input_changed_eater_dynamic { $input_changed_eater_dynamic ? &input_changed_eater : weechat::WEECHAT_RC_OK }
sub multiline_complete_fix_dynamic { $multiline_complete_fix_dynamic ? &multiline_complete_fix : weechat::WEECHAT_RC_OK }
weechat::hook_config('plugins.var.perl.'.SCRIPT_NAME.'.*', 'default_options', '');
weechat::hook_modifier('input_text_display_with_cursor', 'multiline_display', '');
weechat::hook_command_run('/help '.SCRIPT_NAME, 'help_cmd', '');
weechat::hook_command_run(INPUT_MAGIC, 'magic_enter', '');
weechat::hook_signal('input_text_*', 'magic_enter_cancel_dynamic', '');
weechat::hook_command_run('/input *', 'paste_undo_start_ignore_dynamic', '');
weechat::hook_signal('2000|input_text_changed', 'input_changed_eater_dynamic', '');
weechat::hook_signal('key_pressed', 'magic_lock_hatch', '');
# we need lower than default priority here or the first character is separated
weechat::hook_signal('500|input_text_changed', 'paste_undo_hack', '')
# can only do this on weechat 0.4.0
if (weechat::info_get('version_number', '') || 0) >= 0x00040000;
weechat::hook_command_run("1500|/input complete*", 'multiline_complete_fix_dynamic', 'complete*');
weechat::hook_command_run("1500|/input delete_*", 'multiline_complete_fix_dynamic', 'delete_*');
weechat::hook_command_run("1500|/input move_*", 'multiline_complete_fix_dynamic', 'move_*');
sub _stack_depth {
my $depth = -1;
1 while caller(++$depth);
$depth;
}
## multiline_display -- show multi-lines on display of input string
## () - modifier handler
## $_[2] - buffer pointer
## $_[3] - input string
## returns modified input string
sub multiline_display {
Encode::_utf8_on($_[3]);
Encode::_utf8_on(my $nl = weechat::config_get_plugin('char') || ' ');
Encode::_utf8_on(my $tab = weechat::config_get_plugin('tab'));
my $cb = weechat::current_buffer() eq $_[2] && $MAGIC_ENTER_TIMER;
if ($cb) {
$_[3] =~ s/$NL\x19b#/\x19b#/ if weechat::config_string_to_boolean(weechat::config_get_plugin('hide_magic_nl'));
}
if ($_[3] =~ s/$NL/$nl\x0d/g) {
$_[3] =~ s/\A/ \x0d/ if weechat::config_string_to_boolean(weechat::config_get_plugin('lead_linebreak'));
}
$_[3] =~ s/\x09/$tab/g if $tab;
if ($cb) {
Encode::_utf8_on(my $magic = weechat::config_get_plugin('magic'));
$_[3] =~ s/\Z/$magic/ if $magic;
}
$_[3]
}
## lock_timer_exp -- expire the magic lock timer
sub lock_timer_exp {
if ($MAGIC_LOCK_TIMER) {
weechat::unhook($MAGIC_LOCK_TIMER);
$MAGIC_LOCK_TIMER = undef;
}
weechat::WEECHAT_RC_OK
}
## paste_undo_stop_ignore -- unset ignore2 flag
sub paste_undo_stop_ignore {
$IGNORE_INPUT_CHANGED2 = undef;
weechat::WEECHAT_RC_OK
}
## paste_undo_start_ignore -- set ignore2 flag when /input is received so to allow /input undo/redo
## () - command_run handler
## $_[2] - command that was called
sub paste_undo_start_ignore {
return weechat::WEECHAT_RC_OK if $IGNORE_INPUT_CHANGED;
return weechat::WEECHAT_RC_OK if $_[2] =~ /insert/;
$IGNORE_INPUT_CHANGED2 = 1;
weechat::WEECHAT_RC_OK
}
## paste_undo_hack -- fix up undo stack when paste is detected by calling /input undo
## () - signal handler
## $_[2] - buffer pointer
sub paste_undo_hack {
return weechat::WEECHAT_RC_OK if $IGNORE_INPUT_CHANGED;
return paste_undo_stop_ignore() if $IGNORE_INPUT_CHANGED2;
if ($MAGIC_LOCK > 0 && get_lock_enabled()) {
signall_ignore_input_changed(1);
$paste_undo_start_ignore_dynamic = 1;
Encode::_utf8_on(my $input = weechat::buffer_get_string($_[2], 'input'));
my $pos = weechat::buffer_get_integer($_[2], 'input_pos');
weechat::command($_[2], '/input undo') for 1..2;
weechat::buffer_set($_[2], 'input', $input);
weechat::buffer_set($_[2], 'input_pos', $pos);
$paste_undo_start_ignore_dynamic = 0;
signall_ignore_input_changed(0);
}
weechat::WEECHAT_RC_OK
}
## input_changed_eater -- suppress input_text_changed signal on new weechats
## () - signal handler
sub input_changed_eater {
$INPUT_CHANGED_EATER_FLAG = undef;
weechat::WEECHAT_RC_OK_EAT
}
## signall_ignore_input_changed -- use various methods to "ignore" input_text_changed signal
## $_[0] - start ignore or stop ignore
sub signall_ignore_input_changed {
if ($_[0]) {
weechat::hook_signal_send('input_flow_free', weechat::WEECHAT_HOOK_SIGNAL_INT, 1);
$input_changed_eater_dynamic = 1;
$IGNORE_INPUT_CHANGED = 1;
weechat::buffer_set('', 'completion_freeze', '1');
}
else {
weechat::buffer_set('', 'completion_freeze', '0');
$IGNORE_INPUT_CHANGED = undef;
$input_changed_eater_dynamic = 0;
weechat::hook_signal_send('input_flow_free', weechat::WEECHAT_HOOK_SIGNAL_INT, 0);
}
}
## multiline_complete_fix -- add per line /input handling for completion, movement and deletion
## () - command_run handler
## $_[0] - original bound data
## $_[1] - buffer pointer
## $_[2] - original command
sub multiline_complete_fix {
$magic_enter_cancel_dynamic = 0;
$multiline_complete_fix_dynamic = 0;
if ($_[2] =~ s/_message$/_line/ || !weechat::config_string_to_boolean(weechat::config_get_plugin('modify_keys'))) {
weechat::command($_[1], $_[2]);
}
else {
signall_ignore_input_changed(1);
Encode::_utf8_on(my $input = weechat::buffer_get_string($_[1], 'input'));
my $pos = weechat::buffer_get_integer($_[1], 'input_pos');
if ($pos && $_[2] =~ /(?:previous|beginning_of)_/ && (substr $input, $pos-1, 1) eq $NL) {
substr $input, $pos-1, 1, "\0"
}
elsif ($pos < length $input && $_[2] =~ /(?:next|end_of)_/ && (substr $input, $pos, 1) eq $NL) {
substr $input, $pos, 1, "\0"
}
my @lines = $pos ? (split /$NL/, (substr $input, 0, $pos), -1) : '';
my @after = $pos < length $input ? (split /$NL/, (substr $input, $pos), -1) : '';
$lines[-1] =~ s/\0$/$NL/;
$after[0] =~ s/^\0/$NL/;
my ($p1, $p2) = (pop @lines, shift @after);
weechat::buffer_set($_[1], 'input', $p1.$p2);
weechat::buffer_set($_[1], 'input_pos', length $p1);
$magic_enter_cancel_dynamic = 1;
$INPUT_CHANGED_EATER_FLAG = 1;
weechat::command($_[1], $_[2]);
my $changed_later = !$INPUT_CHANGED_EATER_FLAG;
magic_enter_cancel() if $changed_later;
$magic_enter_cancel_dynamic = 0;
Encode::_utf8_on(my $p = weechat::buffer_get_string($_[1], 'input'));
$pos = weechat::buffer_get_integer($_[1], 'input_pos');
weechat::command($_[1], '/input undo') if @lines || @after;
weechat::command($_[1], '/input undo');
weechat::buffer_set($_[1], 'input', join $NL, @lines, $p, @after);
weechat::buffer_set($_[1], 'input_pos', $pos+length join $NL, @lines, '');
signall_ignore_input_changed(0);
weechat::hook_signal_send('input_text_changed', weechat::WEECHAT_HOOK_SIGNAL_POINTER, $_[1]) if $changed_later;
}
$multiline_complete_fix_dynamic = 1;
$magic_enter_cancel_dynamic = 1;
weechat::WEECHAT_RC_OK_EAT
}
## help_cmd -- show multi-line script documentation
## () - command_run handler
sub help_cmd {
Nlib::read_manpage(SCRIPT_FILE, SCRIPT_NAME);
weechat::WEECHAT_RC_OK_EAT
}
## get_lock_time -- gets timeout for paste detection according to setting
## returns timeout (at least 1)
sub get_lock_time {
my $lock_time = weechat::config_get_plugin('paste_lock');
$lock_time = 1 unless $lock_time =~ /^\d+$/ && $lock_time;
$lock_time
}
## get_lock_enabled -- checks whether the paste detection lock is enabled
## returns bool
sub get_lock_enabled {
my $lock = weechat::config_get_plugin('paste_lock');
$lock = weechat::config_string_to_boolean($lock)
unless $lock =~ /^\d+$/;
$lock
}
## magic_lock_hatch -- set a timer for paste detection
## () - signal handler
sub magic_lock_hatch {
lock_timer_exp();
$MAGIC_LOCK_TIMER = weechat::hook_timer(get_lock_time(), 0, 1, 'lock_timer_exp', '');
weechat::WEECHAT_RC_OK
}
## magic_unlock -- reduce the lock added by paste detection
## () - timer handler
sub magic_unlock {
if ($MAGIC_LOCK_TIMER) {
weechat::hook_timer(get_lock_time(), 0, 1, 'magic_unlock', '');
}
else {
--$MAGIC_LOCK;
if (!$MAGIC_LOCK && $WEECHAT_PASTE_FIX_CTRLJ_CMD) {
do_key_bind(Nlib::get_key_name('ctrl-j'), $WEECHAT_PASTE_FIX_CTRLJ_CMD);
$WEECHAT_PASTE_FIX_CTRLJ_CMD = undef;
}
}
weechat::WEECHAT_RC_OK
}
## get_magic_enter_time -- get timeout for auto-sending messages according to config
## returns timeout
sub get_magic_enter_time {
my $magic_enter = weechat::config_get_plugin('magic_enter_time');
$magic_enter = 1000 * weechat::config_string_to_boolean($magic_enter)
unless $magic_enter =~ /^\d+$/;
$magic_enter
}
## magic_enter -- receive enter key and do magic things: set up a timer for sending the message, add newline
## () - command_run handler
## $_[1] - buffer pointer
sub magic_enter {
Encode::_utf8_on(my $input = weechat::buffer_get_string($_[1], 'input'));
if (!length $input && weechat::config_string_to_boolean(weechat::config_get_plugin('send_empty'))) {
weechat::command($_[1], '/input return');
}
else {
magic_enter_cancel();
weechat::command($_[1], INPUT_NL);
unless (get_lock_enabled() && $MAGIC_LOCK) {
if (weechat::config_string_to_boolean(weechat::config_get_plugin('magic_paste_only')) &&
$input !~ /$NL/) {
magic_enter_send($_[1]);
}
elsif (my $magic_enter = get_magic_enter_time()) {
$MAGIC_ENTER_TIMER = weechat::hook_timer($magic_enter, 0, 1, 'magic_enter_send', $_[1]);
}
}
}
weechat::WEECHAT_RC_OK_EAT
}
## magic_enter_send -- actually send enter key when triggered by magic_enter, remove preceding newline
## $_[0] - buffer pointer
## sending is delayed by 1ms to circumvent crash bug in api
sub magic_enter_send {
magic_enter_cancel();
weechat::command($_[0], '/input delete_previous_char');
weechat::command($_[0], '/wait 1ms /input return');
weechat::WEECHAT_RC_OK
}
## magic_enter_cancel -- cancel the timer for automatic sending of message, for example when more text was added, increase the paste lock for paste detection when used as signal handler
## () - signal handler when @_ is set
sub magic_enter_cancel {
if ($MAGIC_ENTER_TIMER) {
weechat::unhook($MAGIC_ENTER_TIMER);
$MAGIC_ENTER_TIMER = undef;
}
if ($MAGIC_LOCK_TIMER && @_) {
if (!$MAGIC_LOCK && !$WEECHAT_PASTE_FIX_CTRLJ_CMD &&
weechat::config_string_to_boolean(weechat::config_get_plugin('weechat_paste_fix'))) {
($WEECHAT_PASTE_FIX_CTRLJ_CMD) = get_key_command(Nlib::get_key_name('ctrl-j'));
$WEECHAT_PASTE_FIX_CTRLJ_CMD = '-' unless defined $WEECHAT_PASTE_FIX_CTRLJ_CMD;
do_key_bind(Nlib::get_key_name('ctrl-j'), '-');
}
if ($MAGIC_LOCK < 1) {
my $lock_time = get_lock_time();
++$MAGIC_LOCK;
weechat::hook_timer(get_lock_time(), 0, 1, 'magic_unlock', '');
}
}
weechat::WEECHAT_RC_OK
}
## need_magic_enter -- check if magic enter keybinding is needed according to config settings
## returns bool
sub need_magic_enter {
weechat::config_string_to_boolean(weechat::config_get_plugin('send_empty')) || get_magic_enter_time() ||
weechat::config_string_to_boolean(weechat::config_get_plugin('magic_paste_only'))
}
## do_key_bind -- mute execute a key binding, or unbind if $_[-1] is '-'
## @_ - arguments to /key bind
sub do_key_bind {
if ($_[-1] eq '-') {
pop;
weechat::command('', "/mute /key unbind @_");
}
elsif ($_[-1] eq '!') {
pop;
weechat::command('', "/mute /key reset @_");
}
else {
weechat::command('', "/mute /key bind @_");
}
}
{ my %keys;
## get_key_command -- get the command bound to a key
## $_[0] - key in weechat syntax
## returns the command
sub get_key_command {
unless (exists $keys{$_[0]}) {
($keys{$_[0]}) =
map { $_->{command} } grep { $_->{key} eq $_[0] }
Nlib::i2h('key')
}
$keys{$_[0]}
}
}
## default_options -- set up default option values on start and when unset
## () - config handler if @_ is set
sub default_options {
my %defaults = (
char => '↩',
tab => '──▶▏',
magic => '‼',
ipl => 'on',
lead_linebreak => 'on',
modify_keys => 'on',
send_empty => 'on',
magic_enter_time => '1000',
paste_lock => '1',
magic_paste_only => 'off',
hide_magic_nl => 'on',
weechat_paste_fix => 'on',
);
unless (weechat::config_is_set_plugin('ipl')) {
if (my $bar = weechat::bar_search('input')) {
weechat::bar_set($bar, $_, '0') for 'size', 'size_max';
}
}
for (keys %defaults) {
weechat::config_set_plugin($_, $defaults{$_})
unless weechat::config_is_set_plugin($_);
}
do_key_bind($KEY_RET, INPUT_NL)
if weechat::config_string_to_boolean(weechat::config_get_plugin('ipl'));
my ($enter_key) = get_key_command($KEY_RET);
if (need_magic_enter()) {
do_key_bind($KEY_RET, INPUT_MAGIC)
if defined $enter_key && $enter_key eq INPUT_NL;
}
else {
do_key_bind($KEY_RET, INPUT_NL)
if defined $enter_key && $enter_key eq INPUT_MAGIC;
}
weechat::WEECHAT_RC_OK
}
sub init_multiline {
$MAGIC_LOCK = -1;
default_options();
my $sf = SCRIPT_FILE;
for (Nlib::get_settings_from_pod($sf)) {
weechat::config_set_desc_plugin($_, Nlib::get_desc_from_pod($sf, $_));
}
weechat::WEECHAT_RC_OK
}
sub stop_multiline {
magic_enter_cancel();
if (need_magic_enter()) {
my ($enter_key) = get_key_command($KEY_RET);
do_key_bind($KEY_RET, INPUT_NL)
if defined $enter_key && $enter_key eq INPUT_MAGIC;
}
if ($WEECHAT_PASTE_FIX_CTRLJ_CMD) {
do_key_bind(Nlib::get_key_name('ctrl-j'), $WEECHAT_PASTE_FIX_CTRLJ_CMD);
$WEECHAT_PASTE_FIX_CTRLJ_CMD = undef;
}
if (weechat::config_string_to_boolean(weechat::config_get_plugin('ipl'))) {
do_key_bind($KEY_RET, '!');
}
weechat::WEECHAT_RC_OK
}

1075
scripts/python/autosort.py Normal file

File diff suppressed because it is too large Load Diff

36
scripts/python/bufsave.py Normal file
View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# bufsave script for weechat - developed by acidvegas (https://git.acid.vegas/weechat)
# usage: /bufsave saves current buffer to a $HOME/.weechats/logs/
import time
import weechat
def cstrip(text):
return weechat.string_remove_color(text, '')
def bufsave_cmd(data, buffer, args):
filename = weechat.buffer_get_string(buffer, 'localvar_server') + '.' + weechat.buffer_get_string(buffer, 'localvar_channel') + '-' + time.strftime('%y_%m_%d-%I_%M_%S') + '.log'
filename = weechat.string_eval_path_home('%h/logs/' + filename, {}, {}, {})
try:
fp = open(filename, 'w')
except:
weechat.prnt('', 'Error writing to target file!')
return weechat.WEECHAT_RC_OK
own_lines = weechat.hdata_pointer(weechat.hdata_get('buffer'), buffer, 'own_lines')
if own_lines:
line = weechat.hdata_pointer(weechat.hdata_get('lines'), own_lines, 'first_line')
hdata_line = weechat.hdata_get('line')
hdata_line_data = weechat.hdata_get('line_data')
while line:
data = weechat.hdata_pointer(hdata_line, line, 'data')
if data:
date = weechat.hdata_time(hdata_line_data, data, 'date')
if not isinstance(date, str):
date = time.strftime('%F %T', time.localtime(int(date)))
fp.write('{0} {1} {2}\n'.format(date, cstrip(weechat.hdata_string(hdata_line_data, data, 'prefix')), cstrip(weechat.hdata_string(hdata_line_data, data, 'message'))))
line = weechat.hdata_move(hdata_line, line, 1)
fp.close()
return weechat.WEECHAT_RC_OK
if weechat.register('bufsave', 'acidvegas', '1.0', 'ISC', 'save buffer to file', '', ''):
weechat.hook_command('bufsave', 'save current buffer to a file', '[filename]', 'filename: target file (must not exist)\n', '%f', 'bufsave_cmd', '')

View File

@ -0,0 +1,416 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2010 by xt <xt@bash.no>
#
# 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/>.
#
# This script colors nicks in IRC channels in the actual message
# not just in the prefix section.
#
#
# History:
# 2022-11-07: mva
# version 30: add ":" and "," to VALID_NICK regexp,
# to don't reset colorization in input_line
# 2022-07-11: ncfavier
# version 29: check nick for exclusion *after* stripping
# decrease minimum min_nick_length to 1
# 2020-11-29: jess
# version 28: fix ignore_tags having been broken by weechat 2.9 changes
# 2020-05-09: Sébastien Helleu <flashcode@flashtux.org>
# version 27: add compatibility with new weechat_print modifier data
# (WeeChat >= 2.9)
# 2018-04-06: Joey Pabalinas <joeypabalinas@gmail.com>
# version 26: fix freezes with too many nicks in one line
# 2018-03-18: nils_2
# version 25: fix unable to run function colorize_config_reload_cb()
# 2017-06-20: lbeziaud <louis.beziaud@ens-rennes.fr>
# version 24: colorize utf8 nicks
# 2017-03-01, arza <arza@arza.us>
# version 23: don't colorize nicklist group names
# 2016-05-01, Simmo Saan <simmo.saan@gmail.com>
# version 22: invalidate cached colors on hash algorithm change
# 2015-07-28, xt
# version 21: fix problems with nicks with commas in them
# 2015-04-19, xt
# version 20: fix ignore of nicks in URLs
# 2015-04-18, xt
# version 19: new option ignore nicks in URLs
# 2015-03-03, xt
# version 18: iterate buffers looking for nicklists instead of servers
# 2015-02-23, holomorph
# version 17: fix coloring in non-channel buffers (#58)
# 2014-09-17, holomorph
# version 16: use weechat config facilities
# clean unused, minor linting, some simplification
# 2014-05-05, holomorph
# version 15: fix python2-specific re.search check
# 2013-01-29, nils_2
# version 14: make script compatible with Python 3.x
# 2012-10-19, ldvx
# version 13: Iterate over every word to prevent incorrect colorization of
# nicks. Added option greedy_matching.
# 2012-04-28, ldvx
# version 12: added ignore_tags to avoid colorizing nicks if tags are present
# 2012-01-14, nesthib
# version 11: input_text_display hook and modifier to colorize nicks in input bar
# 2010-12-22, xt
# version 10: hook config option for updating blacklist
# 2010-12-20, xt
# version 0.9: hook new config option for weechat 0.3.4
# 2010-11-01, nils_2
# version 0.8: hook_modifier() added to communicate with rainbow_text
# 2010-10-01, xt
# version 0.7: changes to support non-irc-plugins
# 2010-07-29, xt
# version 0.6: compile regexp as per patch from Chris quigybo@hotmail.com
# 2010-07-19, xt
# version 0.5: fix bug with incorrect coloring of own nick
# 2010-06-02, xt
# version 0.4: update to reflect API changes
# 2010-03-26, xt
# version 0.3: fix error with exception
# 2010-03-24, xt
# version 0.2: use ignore_channels when populating to increase performance.
# 2010-02-03, xt
# version 0.1: initial (based on ruby script by dominikh)
#
# Known issues: nicks will not get colorized if they begin with a character
# such as ~ (which some irc networks do happen to accept)
import weechat
import re
w = weechat
SCRIPT_NAME = "colorize_nicks"
SCRIPT_AUTHOR = "xt <xt@bash.no>"
SCRIPT_VERSION = "30"
SCRIPT_LICENSE = "GPL"
SCRIPT_DESC = "Use the weechat nick colors in the chat area"
# Based on the recommendations in RFC 7613. A valid nick is composed
# of anything but " ,*?.!@".
VALID_NICK = r'([@~&!%+-])?([^\s,\*?\.!@:,]+)'
valid_nick_re = re.compile(VALID_NICK)
ignore_channels = []
ignore_nicks = []
# Dict with every nick on every channel with its color as lookup value
colored_nicks = {}
CONFIG_FILE_NAME = "colorize_nicks"
# config file and options
colorize_config_file = ""
colorize_config_option = {}
def colorize_config_init():
'''
Initialization of configuration file.
Sections: look.
'''
global colorize_config_file, colorize_config_option
colorize_config_file = weechat.config_new(CONFIG_FILE_NAME,
"", "")
if colorize_config_file == "":
return
# section "look"
section_look = weechat.config_new_section(
colorize_config_file, "look", 0, 0, "", "", "", "", "", "", "", "", "", "")
if section_look == "":
weechat.config_free(colorize_config_file)
return
colorize_config_option["blacklist_channels"] = weechat.config_new_option(
colorize_config_file, section_look, "blacklist_channels",
"string", "Comma separated list of channels", "", 0, 0,
"", "", 0, "", "", "", "", "", "")
colorize_config_option["blacklist_nicks"] = weechat.config_new_option(
colorize_config_file, section_look, "blacklist_nicks",
"string", "Comma separated list of nicks", "", 0, 0,
"so,root", "so,root", 0, "", "", "", "", "", "")
colorize_config_option["min_nick_length"] = weechat.config_new_option(
colorize_config_file, section_look, "min_nick_length",
"integer", "Minimum length nick to colorize", "",
1, 20, "2", "2", 0, "", "", "", "", "", "")
colorize_config_option["colorize_input"] = weechat.config_new_option(
colorize_config_file, section_look, "colorize_input",
"boolean", "Whether to colorize input", "", 0,
0, "off", "off", 0, "", "", "", "", "", "")
colorize_config_option["ignore_tags"] = weechat.config_new_option(
colorize_config_file, section_look, "ignore_tags",
"string", "Comma separated list of tags to ignore; i.e. irc_join,irc_part,irc_quit", "", 0, 0,
"", "", 0, "", "", "", "", "", "")
colorize_config_option["greedy_matching"] = weechat.config_new_option(
colorize_config_file, section_look, "greedy_matching",
"boolean", "If off, then use lazy matching instead", "", 0,
0, "on", "on", 0, "", "", "", "", "", "")
colorize_config_option["match_limit"] = weechat.config_new_option(
colorize_config_file, section_look, "match_limit",
"integer", "Fall back to lazy matching if greedy matches exceeds this number", "",
20, 1000, "", "", 0, "", "", "", "", "", "")
colorize_config_option["ignore_nicks_in_urls"] = weechat.config_new_option(
colorize_config_file, section_look, "ignore_nicks_in_urls",
"boolean", "If on, don't colorize nicks inside URLs", "", 0,
0, "off", "off", 0, "", "", "", "", "", "")
def colorize_config_read():
''' Read configuration file. '''
global colorize_config_file
return weechat.config_read(colorize_config_file)
def colorize_nick_color(nick, my_nick):
''' Retrieve nick color from weechat. '''
if nick == my_nick:
return w.color(w.config_string(w.config_get('weechat.color.chat_nick_self')))
else:
return w.info_get('nick_color', nick)
def colorize_cb(data, modifier, modifier_data, line):
''' Callback that does the colorizing, and returns new line if changed '''
global ignore_nicks, ignore_channels, colored_nicks
if modifier_data.startswith('0x'):
# WeeChat >= 2.9
buffer, tags = modifier_data.split(';', 1)
else:
# WeeChat <= 2.8
plugin, buffer_name, tags = modifier_data.split(';', 2)
buffer = w.buffer_search(plugin, buffer_name)
channel = w.buffer_get_string(buffer, 'localvar_channel')
tags = tags.split(',')
# Check if buffer has colorized nicks
if buffer not in colored_nicks:
return line
if channel and channel in ignore_channels:
return line
min_length = w.config_integer(colorize_config_option['min_nick_length'])
reset = w.color('reset')
# Don't colorize if the ignored tag is present in message
tag_ignores = w.config_string(colorize_config_option['ignore_tags']).split(',')
for tag in tags:
if tag in tag_ignores:
return line
for words in valid_nick_re.findall(line):
nick = words[1]
# If the matched word is not a known nick, we try to match the
# word without its first or last character (if not a letter).
# This is necessary as "foo:" is a valid nick, which could be
# adressed as "foo::".
if nick not in colored_nicks[buffer]:
if not nick[-1].isalpha() and not nick[0].isalpha():
if nick[1:-1] in colored_nicks[buffer]:
nick = nick[1:-1]
elif not nick[0].isalpha():
if nick[1:] in colored_nicks[buffer]:
nick = nick[1:]
elif not nick[-1].isalpha():
if nick[:-1] in colored_nicks[buffer]:
nick = nick[:-1]
# Check that nick is not ignored and longer than minimum length
if len(nick) < min_length or nick in ignore_nicks:
continue
# Check that nick is in the dictionary colored_nicks
if nick in colored_nicks[buffer]:
nick_color = colored_nicks[buffer][nick]
try:
# Let's use greedy matching. Will check against every word in a line.
if w.config_boolean(colorize_config_option['greedy_matching']):
cnt = 0
limit = w.config_integer(colorize_config_option['match_limit'])
for word in line.split():
cnt += 1
assert cnt < limit
# if cnt > limit:
# raise RuntimeError('Exceeded colorize_nicks.look.match_limit.');
if w.config_boolean(colorize_config_option['ignore_nicks_in_urls']) and \
word.startswith(('http://', 'https://')):
continue
if nick in word:
# Is there a nick that contains nick and has a greater lenght?
# If so let's save that nick into var biggest_nick
biggest_nick = ""
for i in colored_nicks[buffer]:
cnt += 1
assert cnt < limit
if nick in i and nick != i and len(i) > len(nick):
if i in word:
# If a nick with greater len is found, and that word
# also happens to be in word, then let's save this nick
biggest_nick = i
# If there's a nick with greater len, then let's skip this
# As we will have the chance to colorize when biggest_nick
# iterates being nick.
if len(biggest_nick) > 0 and biggest_nick in word:
pass
elif len(word) < len(biggest_nick) or len(biggest_nick) == 0:
new_word = word.replace(nick, '%s%s%s' % (nick_color, nick, reset))
line = line.replace(word, new_word)
# Switch to lazy matching
else:
raise AssertionError
except AssertionError:
# Let's use lazy matching for nick
nick_color = colored_nicks[buffer][nick]
# The two .? are in case somebody writes "nick:", "nick,", etc
# to address somebody
regex = r"(\A|\s).?(%s).?(\Z|\s)" % re.escape(nick)
match = re.search(regex, line)
if match is not None:
new_line = line[:match.start(2)] + nick_color+nick+reset + line[match.end(2):]
line = new_line
return line
def colorize_input_cb(data, modifier, modifier_data, line):
''' Callback that does the colorizing in input '''
global ignore_nicks, ignore_channels, colored_nicks
min_length = w.config_integer(colorize_config_option['min_nick_length'])
if not w.config_boolean(colorize_config_option['colorize_input']):
return line
buffer = w.current_buffer()
# Check if buffer has colorized nicks
if buffer not in colored_nicks:
return line
channel = w.buffer_get_string(buffer, 'name')
if channel and channel in ignore_channels:
return line
reset = w.color('reset')
for words in valid_nick_re.findall(line):
nick = words[1]
# Check that nick is not ignored and longer than minimum length
if len(nick) < min_length or nick in ignore_nicks:
continue
if nick in colored_nicks[buffer]:
nick_color = colored_nicks[buffer][nick]
line = line.replace(nick, '%s%s%s' % (nick_color, nick, reset))
return line
def populate_nicks(*args):
''' Fills entire dict with all nicks weechat can see and what color it has
assigned to it. '''
global colored_nicks
colored_nicks = {}
buffers = w.infolist_get('buffer', '', '')
while w.infolist_next(buffers):
buffer_ptr = w.infolist_pointer(buffers, 'pointer')
my_nick = w.buffer_get_string(buffer_ptr, 'localvar_nick')
nicklist = w.infolist_get('nicklist', buffer_ptr, '')
while w.infolist_next(nicklist):
if buffer_ptr not in colored_nicks:
colored_nicks[buffer_ptr] = {}
if w.infolist_string(nicklist, 'type') != 'nick':
continue
nick = w.infolist_string(nicklist, 'name')
nick_color = colorize_nick_color(nick, my_nick)
colored_nicks[buffer_ptr][nick] = nick_color
w.infolist_free(nicklist)
w.infolist_free(buffers)
return w.WEECHAT_RC_OK
def add_nick(data, signal, type_data):
''' Add nick to dict of colored nicks '''
global colored_nicks
# Nicks can have , in them in some protocols
splitted = type_data.split(',')
pointer = splitted[0]
nick = ",".join(splitted[1:])
if pointer not in colored_nicks:
colored_nicks[pointer] = {}
my_nick = w.buffer_get_string(pointer, 'localvar_nick')
nick_color = colorize_nick_color(nick, my_nick)
colored_nicks[pointer][nick] = nick_color
return w.WEECHAT_RC_OK
def remove_nick(data, signal, type_data):
''' Remove nick from dict with colored nicks '''
global colored_nicks
# Nicks can have , in them in some protocols
splitted = type_data.split(',')
pointer = splitted[0]
nick = ",".join(splitted[1:])
if pointer in colored_nicks and nick in colored_nicks[pointer]:
del colored_nicks[pointer][nick]
return w.WEECHAT_RC_OK
def update_blacklist(*args):
''' Set the blacklist for channels and nicks. '''
global ignore_channels, ignore_nicks
ignore_channels = w.config_string(colorize_config_option['blacklist_channels']).split(',')
ignore_nicks = w.config_string(colorize_config_option['blacklist_nicks']).split(',')
return w.WEECHAT_RC_OK
if __name__ == "__main__":
if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
SCRIPT_DESC, "", ""):
colorize_config_init()
colorize_config_read()
# Run once to get data ready
update_blacklist()
populate_nicks()
w.hook_signal('nicklist_nick_added', 'add_nick', '')
w.hook_signal('nicklist_nick_removed', 'remove_nick', '')
w.hook_modifier('weechat_print', 'colorize_cb', '')
# Hook config for changing colors
w.hook_config('weechat.color.chat_nick_colors', 'populate_nicks', '')
w.hook_config('weechat.look.nick_color_hash', 'populate_nicks', '')
# Hook for working togheter with other scripts (like colorize_lines)
w.hook_modifier('colorize_nicks', 'colorize_cb', '')
# Hook for modifying input
w.hook_modifier('250|input_text_display', 'colorize_input_cb', '')
# Hook for updating blacklist (this could be improved to use fnmatch)
weechat.hook_config('%s.look.blacklist*' % SCRIPT_NAME, 'update_blacklist', '')

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# fullwidth script for weechat - developed by acidvegas in python (https://git.acid.vegas/weechat)
import weechat
def cmd_fullwidth(data, buf, args):
chars = list()
for char in list(args):
if ord(char) == 32:
char = chr(12288)
elif ord(char) > 32 and ord(char) <= 126:
char = chr(ord(char) + 65248)
chars.append(char)
weechat.command(buf, '/input send ' + ''.join(chars))
return weechat.WEECHAT_RC_OK
if weechat.register('fullwidth', 'acidvegas', '1.0', 'ISC', 'convert text to wide characters.', '', ''):
weechat.hook_command('fullwidth', 'convert text to wide characters.', '<text>', '', '', 'cmd_fullwidth', '')

574
scripts/python/go.py Normal file
View File

@ -0,0 +1,574 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2014 Sébastien Helleu <flashcode@flashtux.org>
# Copyright (C) 2010 m4v <lambdae2@gmail.com>
# Copyright (C) 2011 stfn <stfnmd@googlemail.com>
#
# 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/>.
#
#
# History:
#
# 2023-01-08, Sébastien Helleu <flashcode@flashtux.org>:
# version 2.8: send buffer pointer with signal "input_text_changed"
# 2021-05-25, Tomáš Janoušek <tomi@nomi.cz>:
# version 2.7: add new option to prefix short names with server names
# 2019-07-11, Simmo Saan <simmo.saan@gmail.com>
# version 2.6: fix detection of "/input search_text_here"
# 2017-04-01, Sébastien Helleu <flashcode@flashtux.org>:
# version 2.5: add option "buffer_number"
# 2017-03-02, Sébastien Helleu <flashcode@flashtux.org>:
# version 2.4: fix syntax and indentation error
# 2017-02-25, Simmo Saan <simmo.saan@gmail.com>
# version 2.3: fix fuzzy search breaking buffer number search display
# 2016-01-28, ylambda <ylambda@koalabeast.com>
# version 2.2: add option "fuzzy_search"
# 2015-11-12, nils_2 <weechatter@arcor.de>
# version 2.1: fix problem with buffer short_name "weechat", using option
# "use_core_instead_weechat", see:
# https://github.com/weechat/weechat/issues/574
# 2014-05-12, Sébastien Helleu <flashcode@flashtux.org>:
# version 2.0: add help on options, replace option "sort_by_activity" by
# "sort" (add sort by name and first match at beginning of
# name and by number), PEP8 compliance
# 2012-11-26, Nei <anti.teamidiot.de>
# version 1.9: add auto_jump option to automatically go to buffer when it
# is uniquely selected
# 2012-09-17, Sébastien Helleu <flashcode@flashtux.org>:
# version 1.8: fix jump to non-active merged buffers (jump with buffer name
# instead of number)
# 2012-01-03 nils_2 <weechatter@arcor.de>
# version 1.7: add option "use_core_instead_weechat"
# 2012-01-03, Sébastien Helleu <flashcode@flashtux.org>:
# version 1.6: make script compatible with Python 3.x
# 2011-08-24, stfn <stfnmd@googlemail.com>:
# version 1.5: /go with name argument jumps directly to buffer
# Remember cursor position in buffer input
# 2011-05-31, Elián Hanisch <lambdae2@gmail.com>:
# version 1.4: Sort list of buffers by activity.
# 2011-04-25, Sébastien Helleu <flashcode@flashtux.org>:
# version 1.3: add info "go_running" (used by script input_lock.rb)
# 2010-11-01, Sébastien Helleu <flashcode@flashtux.org>:
# version 1.2: use high priority for hooks to prevent conflict with other
# plugins/scripts (WeeChat >= 0.3.4 only)
# 2010-03-25, Elián Hanisch <lambdae2@gmail.com>:
# version 1.1: use a space to match the end of a string
# 2009-11-16, Sébastien Helleu <flashcode@flashtux.org>:
# version 1.0: add new option to display short names
# 2009-06-15, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.9: fix typo in /help go with command /key
# 2009-05-16, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.8: search buffer by number, fix bug when window is split
# 2009-05-03, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.7: eat tab key (do not complete input, just move buffer
# pointer)
# 2009-05-02, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.6: sync with last API changes
# 2009-03-22, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.5: update modifier signal name for input text display,
# fix arguments for function string_remove_color
# 2009-02-18, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.4: do not hook command and init options if register failed
# 2009-02-08, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.3: case insensitive search for buffers names
# 2009-02-08, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.2: add help about Tab key
# 2009-02-08, Sébastien Helleu <flashcode@flashtux.org>:
# version 0.1: initial release
#
"""
Quick jump to buffers.
(this script requires WeeChat 0.3.0 or newer)
"""
from __future__ import print_function
SCRIPT_NAME = 'go'
SCRIPT_AUTHOR = 'Sébastien Helleu <flashcode@flashtux.org>'
SCRIPT_VERSION = '2.8'
SCRIPT_LICENSE = 'GPL3'
SCRIPT_DESC = 'Quick jump to buffers'
SCRIPT_COMMAND = 'go'
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
import re
# script options
SETTINGS = {
'color_number': (
'yellow,magenta',
'color for buffer number (not selected)'),
'color_number_selected': (
'yellow,red',
'color for selected buffer number'),
'color_name': (
'black,cyan',
'color for buffer name (not selected)'),
'color_name_selected': (
'black,brown',
'color for a selected buffer name'),
'color_name_highlight': (
'red,cyan',
'color for highlight in buffer name (not selected)'),
'color_name_highlight_selected': (
'red,brown',
'color for highlight in a selected buffer name'),
'message': (
'Go to: ',
'message to display before list of buffers'),
'short_name': (
'off',
'display and search in short names instead of buffer name'),
'short_name_server': (
'off',
'prefix short names with server names for search and display'),
'sort': (
'number,beginning',
'comma-separated list of keys to sort buffers '
'(the order is important, sorts are performed in the given order): '
'name = sort by name (or short name), ',
'hotlist = sort by hotlist order, '
'number = first match a buffer number before digits in name, '
'beginning = first match at beginning of names (or short names); '
'the default sort of buffers is by numbers'),
'use_core_instead_weechat': (
'off',
'use name "core" instead of "weechat" for core buffer'),
'auto_jump': (
'off',
'automatically jump to buffer when it is uniquely selected'),
'fuzzy_search': (
'off',
'search buffer matches using approximation'),
'buffer_number': (
'on',
'display buffer number'),
}
# hooks management
HOOK_COMMAND_RUN = {
'input': ('/input *', 'go_command_run_input'),
'buffer': ('/buffer *', 'go_command_run_buffer'),
'window': ('/window *', 'go_command_run_window'),
}
hooks = {}
# input before command /go (we'll restore it later)
saved_input = ''
saved_input_pos = 0
# last user input (if changed, we'll update list of matching buffers)
old_input = None
# matching buffers
buffers = []
buffers_pos = 0
def go_option_enabled(option):
"""Checks if a boolean script option is enabled or not."""
return weechat.config_string_to_boolean(weechat.config_get_plugin(option))
def go_info_running(data, info_name, arguments):
"""Returns "1" if go is running, otherwise "0"."""
return '1' if 'modifier' in hooks else '0'
def go_unhook_one(hook):
"""Unhook something hooked by this script."""
global hooks
if hook in hooks:
weechat.unhook(hooks[hook])
del hooks[hook]
def go_unhook_all():
"""Unhook all."""
go_unhook_one('modifier')
for hook in HOOK_COMMAND_RUN:
go_unhook_one(hook)
def go_hook_all():
"""Hook command_run and modifier."""
global hooks
priority = ''
version = weechat.info_get('version_number', '') or 0
# use high priority for hook to prevent conflict with other plugins/scripts
# (WeeChat >= 0.3.4 only)
if int(version) >= 0x00030400:
priority = '2000|'
for hook, value in HOOK_COMMAND_RUN.items():
if hook not in hooks:
hooks[hook] = weechat.hook_command_run(
'%s%s' % (priority, value[0]),
value[1], '')
if 'modifier' not in hooks:
hooks['modifier'] = weechat.hook_modifier(
'input_text_display_with_cursor', 'go_input_modifier', '')
def go_start(buf):
"""Start go on buffer."""
global saved_input, saved_input_pos, old_input, buffers_pos
go_hook_all()
saved_input = weechat.buffer_get_string(buf, 'input')
saved_input_pos = weechat.buffer_get_integer(buf, 'input_pos')
weechat.buffer_set(buf, 'input', '')
old_input = None
buffers_pos = 0
def go_end(buf):
"""End go on buffer."""
global saved_input, saved_input_pos, old_input
go_unhook_all()
weechat.buffer_set(buf, 'input', saved_input)
weechat.buffer_set(buf, 'input_pos', str(saved_input_pos))
old_input = None
def go_match_beginning(buf, string):
"""Check if a string matches the beginning of buffer name/short name."""
if not string:
return False
esc_str = re.escape(string)
if re.search(r'^#?' + esc_str, buf['name']) \
or re.search(r'^#?' + esc_str, buf['short_name']):
return True
return False
def go_match_fuzzy(name, string):
"""Check if string matches name using approximation."""
if not string:
return False
name_len = len(name)
string_len = len(string)
if string_len > name_len:
return False
if name_len == string_len:
return name == string
# Attempt to match all chars somewhere in name
prev_index = -1
for i, char in enumerate(string):
index = name.find(char, prev_index+1)
if index == -1:
return False
prev_index = index
return True
def go_now(buf, args):
"""Go to buffer specified by args."""
listbuf = go_matching_buffers(args)
if not listbuf:
return
# prefer buffer that matches at beginning (if option is enabled)
if 'beginning' in weechat.config_get_plugin('sort').split(','):
for index in range(len(listbuf)):
if go_match_beginning(listbuf[index], args):
weechat.command(buf,
'/buffer ' + str(listbuf[index]['full_name']))
return
# jump to first buffer in matching buffers by default
weechat.command(buf, '/buffer ' + str(listbuf[0]['full_name']))
def go_cmd(data, buf, args):
"""Command "/go": just hook what we need."""
global hooks
if args:
go_now(buf, args)
elif 'modifier' in hooks:
go_end(buf)
else:
go_start(buf)
return weechat.WEECHAT_RC_OK
def go_matching_buffers(strinput):
"""Return a list with buffers matching user input."""
global buffers_pos
listbuf = []
if len(strinput) == 0:
buffers_pos = 0
strinput = strinput.lower()
infolist = weechat.infolist_get('buffer', '', '')
while weechat.infolist_next(infolist):
pointer = weechat.infolist_pointer(infolist, 'pointer')
short_name = weechat.infolist_string(infolist, 'short_name')
server = weechat.buffer_get_string(pointer, 'localvar_server')
if go_option_enabled('short_name'):
if go_option_enabled('short_name_server') and server:
name = server + '.' + short_name
else:
name = short_name
else:
name = weechat.infolist_string(infolist, 'name')
if name == 'weechat' \
and go_option_enabled('use_core_instead_weechat') \
and weechat.infolist_string(infolist, 'plugin_name') == 'core':
name = 'core'
number = weechat.infolist_integer(infolist, 'number')
full_name = weechat.infolist_string(infolist, 'full_name')
if not full_name:
full_name = '%s.%s' % (
weechat.infolist_string(infolist, 'plugin_name'),
weechat.infolist_string(infolist, 'name'))
matching = name.lower().find(strinput) >= 0
if not matching and strinput[-1] == ' ':
matching = name.lower().endswith(strinput.strip())
if not matching and go_option_enabled('fuzzy_search'):
matching = go_match_fuzzy(name.lower(), strinput)
if not matching and strinput.isdigit():
matching = str(number).startswith(strinput)
if len(strinput) == 0 or matching:
listbuf.append({
'number': number,
'short_name': short_name,
'name': name,
'full_name': full_name,
'pointer': pointer,
})
weechat.infolist_free(infolist)
# sort buffers
hotlist = []
infolist = weechat.infolist_get('hotlist', '', '')
while weechat.infolist_next(infolist):
hotlist.append(
weechat.infolist_pointer(infolist, 'buffer_pointer'))
weechat.infolist_free(infolist)
last_index_hotlist = len(hotlist)
def _sort_name(buf):
"""Sort buffers by name (or short name)."""
return buf['name']
def _sort_hotlist(buf):
"""Sort buffers by hotlist order."""
try:
return hotlist.index(buf['pointer'])
except ValueError:
# not in hotlist, always last.
return last_index_hotlist
def _sort_match_number(buf):
"""Sort buffers by match on number."""
return 0 if str(buf['number']) == strinput else 1
def _sort_match_beginning(buf):
"""Sort buffers by match at beginning."""
return 0 if go_match_beginning(buf, strinput) else 1
funcs = {
'name': _sort_name,
'hotlist': _sort_hotlist,
'number': _sort_match_number,
'beginning': _sort_match_beginning,
}
for key in weechat.config_get_plugin('sort').split(','):
if key in funcs:
listbuf = sorted(listbuf, key=funcs[key])
if not strinput:
index = [i for i, buf in enumerate(listbuf)
if buf['pointer'] == weechat.current_buffer()]
if index:
buffers_pos = index[0]
return listbuf
def go_buffers_to_string(listbuf, pos, strinput):
"""Return string built with list of buffers found (matching user input)."""
string = ''
strinput = strinput.lower()
for i in range(len(listbuf)):
selected = '_selected' if i == pos else ''
buffer_name = listbuf[i]['name']
index = buffer_name.lower().find(strinput)
if index >= 0:
index2 = index + len(strinput)
name = '%s%s%s%s%s' % (
buffer_name[:index],
weechat.color(weechat.config_get_plugin(
'color_name_highlight' + selected)),
buffer_name[index:index2],
weechat.color(weechat.config_get_plugin(
'color_name' + selected)),
buffer_name[index2:])
elif go_option_enabled("fuzzy_search") and \
go_match_fuzzy(buffer_name.lower(), strinput):
name = ""
prev_index = -1
for char in strinput.lower():
index = buffer_name.lower().find(char, prev_index+1)
if prev_index < 0:
name += buffer_name[:index]
name += weechat.color(weechat.config_get_plugin(
'color_name_highlight' + selected))
if prev_index >= 0 and index > prev_index+1:
name += weechat.color(weechat.config_get_plugin(
'color_name' + selected))
name += buffer_name[prev_index+1:index]
name += weechat.color(weechat.config_get_plugin(
'color_name_highlight' + selected))
name += buffer_name[index]
prev_index = index
name += weechat.color(weechat.config_get_plugin(
'color_name' + selected))
name += buffer_name[prev_index+1:]
else:
name = buffer_name
string += ' '
if go_option_enabled('buffer_number'):
string += '%s%s' % (
weechat.color(weechat.config_get_plugin(
'color_number' + selected)),
str(listbuf[i]['number']))
string += '%s%s%s' % (
weechat.color(weechat.config_get_plugin(
'color_name' + selected)),
name,
weechat.color('reset'))
return ' ' + string if string else ''
def go_input_modifier(data, modifier, modifier_data, string):
"""This modifier is called when input text item is built by WeeChat.
This is commonly called after changes in input or cursor move: it builds
a new input with prefix ("Go to:"), and suffix (list of buffers found).
"""
global old_input, buffers, buffers_pos
if modifier_data != weechat.current_buffer():
return ''
names = ''
new_input = weechat.string_remove_color(string, '')
new_input = new_input.lstrip()
if old_input is None or new_input != old_input:
old_buffers = buffers
buffers = go_matching_buffers(new_input)
if buffers != old_buffers and len(new_input) > 0:
if len(buffers) == 1 and go_option_enabled('auto_jump'):
weechat.command(modifier_data, '/wait 1ms /input return')
buffers_pos = 0
old_input = new_input
names = go_buffers_to_string(buffers, buffers_pos, new_input.strip())
return weechat.config_get_plugin('message') + string + names
def go_command_run_input(data, buf, command):
"""Function called when a command "/input xxx" is run."""
global buffers, buffers_pos
if command.startswith('/input search_text') or command.startswith('/input jump'):
# search text or jump to another buffer is forbidden now
return weechat.WEECHAT_RC_OK_EAT
elif command == '/input complete_next':
# choose next buffer in list
buffers_pos += 1
if buffers_pos >= len(buffers):
buffers_pos = 0
weechat.hook_signal_send('input_text_changed',
weechat.WEECHAT_HOOK_SIGNAL_POINTER, buf)
return weechat.WEECHAT_RC_OK_EAT
elif command == '/input complete_previous':
# choose previous buffer in list
buffers_pos -= 1
if buffers_pos < 0:
buffers_pos = len(buffers) - 1
weechat.hook_signal_send('input_text_changed',
weechat.WEECHAT_HOOK_SIGNAL_POINTER, buf)
return weechat.WEECHAT_RC_OK_EAT
elif command == '/input return':
# switch to selected buffer (if any)
go_end(buf)
if len(buffers) > 0:
weechat.command(
buf, '/buffer ' + str(buffers[buffers_pos]['full_name']))
return weechat.WEECHAT_RC_OK_EAT
return weechat.WEECHAT_RC_OK
def go_command_run_buffer(data, buf, command):
"""Function called when a command "/buffer xxx" is run."""
return weechat.WEECHAT_RC_OK_EAT
def go_command_run_window(data, buf, command):
"""Function called when a command "/window xxx" is run."""
return weechat.WEECHAT_RC_OK_EAT
def go_unload_script():
"""Function called when script is unloaded."""
go_unhook_all()
return weechat.WEECHAT_RC_OK
def go_main():
"""Entry point."""
if not weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
SCRIPT_LICENSE, SCRIPT_DESC,
'go_unload_script', ''):
return
weechat.hook_command(
SCRIPT_COMMAND,
'Quick jump to buffers', '[name]',
'name: directly jump to buffer by name (without argument, list is '
'displayed)\n\n'
'You can bind command to a key, for example:\n'
' /key bind meta-g /go\n\n'
'You can use completion key (commonly Tab and shift-Tab) to select '
'next/previous buffer in list.',
'%(buffers_names)',
'go_cmd', '')
# set default settings
version = weechat.info_get('version_number', '') or 0
for option, value in SETTINGS.items():
if not weechat.config_is_set_plugin(option):
weechat.config_set_plugin(option, value[0])
if int(version) >= 0x00030500:
weechat.config_set_desc_plugin(
option, '%s (default: "%s")' % (value[1], value[0]))
weechat.hook_info('go_running',
'Return "1" if go is running, otherwise "0"',
'',
'go_info_running', '')
if __name__ == "__main__" and IMPORT_OK:
go_main()

View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# greentext script for weechat - developed by acidvegas in python (https://git.acid.vegas/weechat)
'''
Todo: this can be turned into a trigger
'''
import re,weechat
def between(source, start, stop):
data = re.compile(start + '(.*?)' + stop, re.IGNORECASE|re.MULTILINE).search(source)
if data:
return data.group(1)
else:
return False
def cb_greentext(data,buffer,command):
if command=='/input return':
data=weechat.buffer_get_string(buffer,'input')
if data:
if data[0]=='>':
data='\x0303'+data
elif '!!' in data or '__' in data or '**' in data:
for word in data.split():
if word[:2] == '!!':
data = data.replace(word, '\x1F\x02\x0304 ' + word[2:].upper() + ' \x0f', 1)
elif word[:2] == '__':
data = data.replace(word, '\x1F\x02' + word[2:].upper() + '\x0f', 1)
weechat.buffer_set(buffer,'input',data)
return weechat.WEECHAT_RC_OK
if weechat.register('greentext','','','','','',''):weechat.hook_command_run('/input return','cb_greentext','')

38
scripts/python/masshl.py Normal file
View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# masshl script for weechat - developed by acidvegas (https://git.acid.vegas/weechat)
import weechat
nicks = list()
def timer_cb(data, remaining_calls):
try:
chan = data.split('[split]')[0]
msg = data.split('[split]')[1]
if '%n' in msg:
while '%n' in msg:
msg = msg.replace('%n', nicks[0], 1)
nicks.pop(0)
weechat.command(chan, msg))
except:
pass
finally:
return weechat.WEECHAT_RC_OK
def masshl_cmd_cb(data, buffer, args):
server = weechat.buffer_get_string(buffer, 'localvar_server')
channel = weechat.buffer_get_string(buffer, 'localvar_channel')
nicklist = weechat.infolist_get('irc_nick', '', server+','+channel)
while weechat.infolist_next(nicklist):
nicks.append(weechat.infolist_string(nicklist, 'name')
weechat.infolist_free(nicklist)
del server, channel, nicklist
nicks.pop(0)
if args[:2] == '-1':
weechat.command(buffer, ', '.join(nicks))
else:
weechat.hook_timer(100, 0, len(nicks), 'timer_cb', '[split]'.join((buffer,args)))
return weechat.WEECHAT_RC_OK
if weechat.register('masshl', 'acidvegas', '1.0', 'ISC', 'mass hilight all nicks in a channel', '', ''):
weechat.hook_command('masshl', 'mass hilight all nicks in a channel', '', '', '', 'masshl_cmd_cb', '')

24
scripts/python/rainbow.py Normal file
View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# rainbow script for weechat - developed by acidvegas in python (https://git.acid.vegas/weechat)
import weechat
def cmd_rainbow(data, buf, args):
colors = [5,4,7,8,3,9,10,11,2,12,6,13]
output = ''
if args[:2] == '-w':
for word in args[2:].split():
output += '\x03' + str(colors[0]) + word + ' '
colors.append(colors.pop(0))
else:
for char in list(args):
if char == ' ':
output += char
else:
output += '\x03' + str(colors[0]) + char
colors.append(colors.pop(0))
weechat.command(buf, '/input send ' + output)
return weechat.WEECHAT_RC_OK
if weechat.register('rainbow', 'acidvegas', '1.0', 'ISC', 'rainbow text', '', ''):
weechat.hook_command('rainbow', 'rainbow text', '<text>', '', '', 'cmd_rainbow', '')

20
scripts/python/unifuck.py Normal file
View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# unifuck script for weechat - developed by acidvegas in python (https://git.acid.vegas/weechat)
import random
import weechat
def cmd_unifuck(data, buf, args):
if args[:2] == '-e':
msg = ''
for i in range(random.randint(300, 400)):
msg += chr(random.randint(0x1F600,0x1F64F))
else:
msg='\u202e\u0007\x03' + str(random.randint(2,13))
for i in range(random.randint(300, 400)):
msg += chr(random.randint(0x1000,0x3000))
weechat.command(buf, '/input send ' + msg)
return weechat.WEECHAT_RC_OK
if weechat.register('unifuck', 'acidvegas', '1.0', 'ISC', 'random unicode spam', '', ''):
weechat.hook_command('unifuck', 'random unicode spam', '', '', '', 'cmd_unifuck', '')