Skip to content

Instantly share code, notes, and snippets.

@stickperson
Forked from pascalpoitras/config.md
Created May 30, 2019 16:04
Show Gist options
  • Save stickperson/a92c7334968655ad5ade4383e2e06ed0 to your computer and use it in GitHub Desktop.
Save stickperson/a92c7334968655ad5ade4383e2e06ed0 to your computer and use it in GitHub Desktop.
My always up-to-date WeeChat configuration (weechat-dev)

WeeChat Screenshot

You need at least WeeChat 2.5 for everything to work

Enable mouse

/mouse enable

Encrypted password in sec.conf

/secure passphrase <pass>
/secure set freenodepass <pass>
/secure set snoonetpass <pass>
/secure set undernet_userpass <user> <pass>
/secure set undernet_secret <TOTP secret>
/secure set relaypass <pass>
/secure set mariechannel <buffer fullname of my friend's channel>

Network

Default settings

/set irc.server_default.sasl_mechanism PLAIN
/set irc.server_default.sasl_username r3m
/set irc.server_default.nicks r3m
/set irc.server_default.capabilities "account-notify,away-notify,cap-notify,multi-prefix,server-time,znc.in/self-message"

the last line request some IRCv3 capabilities. Capabilities supported by WeeChat are: account-notify, away-notify, cap-notify, extended-join, multi-prefix, server-time, userhost-in-names. See IRCv3 Specifications to learn more about IRCv3 capabilities.

Network-specific settings

/server add freenode chat.freenode.net/6697 -ssl -autoconnect
/set irc.server.freenode.sasl_password ${sec.data.freenodepass}

/server add oftc irc.oftc.net/6697 -ssl -autoconnect
/set irc.server.oftc.ssl_cert "%h/ssl/nick.pem"
/set irc.server.oftc.command_delay 5

/server add snoonet irc.snoonet.org/6697 -ssl -autoconnect
/set irc.server.snoonet.sasl_password ${sec.data.snoonetpass}

/server add undernet ix.undernet.org
/set irc.server.undernet.command "/eval /msg x@channels.undernet.org login ${sec.data.undernet_userpass} ${info:totp_generate,${sec.data.undernet_secret}};/quote silence *!*@*,~*!*@*.users.undernet.org"  

/connect -all

The command option for the undernet network automatically identify myself to X once connected and it is using 2FA. WeeChat 2.4 have a TOTP generator. The silence command will ignore everyone excepts those identified to X (even if the umode x is not set).

Plugins

Load at startup

/set weechat.plugin.autoload "*,!lua,!tcl,!fifo,!xfer,!guile,!javascript"

this will load all modules except lua, tcl, fifo, xfer, guile and javascript

spell

/set spell.check.default_dict en,fr
/set spell.check.suggestions 3
/set spell.color.suggestion *green
/spell enable

Set the dictionary order to fr,en for french channels

/trigger add setdict signal *,irc_in2_join
/trigger set setdict conditions "${nick} == ${info:irc_nick,${server}} && (${channel} =~ fr$ || ${server} == undernet) && ${info:spell_dict,irc.${server}.${channel}} !~ ^fr,"
/trigger set setdict command "/command -buffer irc.${server}.${channel} * /spell setdict fr,en"

Note: we will add the suggestions to the status bar later.

Relay

/relay sslcertkey
/relay add ssl.irc <port>
/relay add ssl.weechat <port>
/set relay.network.password ${sec.data.relaypass}

If you want a trusted certificate, use let's encrypt! with weechat relay.

Logger

/set logger.level.irc 4
/set logger.mask.irc %Y/$server/$channel.%m-%d.log

Scripts

/script install autojoinem.py buffer_autoset.py autosort.py grep.py text_item.py

autosort.py

/eval /set autosort.sorting.signals ${autosort.sorting.signals} buffer_localvar_added buffer_localvar_changed
/autosort helpers set french_channels_first ${if:${type}==channel&&${buffer.name}!~fr$&&${info:spell_dict,${buffer.full_name}}!~^fr}
/autosort rules insert 6 ${french_channels_first}

this rule will show french channels first (those that the name end with fr and also those that spell is set to fr)

buffer_autoset.py

/buffer_autoset add core.weechat notify 3
/buffer_autoset add irc.server.* notify 3

Conky

/buffer_autoset add exec.exec.conky short_name conky

exec conky at startup and right now

/set weechat.notify.exec.exec.conky none
/set weechat.startup.command_after_plugins "/exec -norc -noln -buffer conky conky"
/exec -norc -noln -buffer conky conky

change the title of the conky buffer

/buffer_autoset add exec.exec.conky title Conky - the light-weight system monitor

Change the title Executed commands to Conky - the light-weight system monitor

beautify the output

/trigger add conky_tag_color modifier weechat_print
/trigger set conky_tag_color conditions "${tg_buffer} == exec.exec.conky && ${tg_tags} =~ ,exec_stdout, && ${tg_message_nocolor} =~ ^[^:]+: *[^ ]"
/trigger set conky_tag_color regex "/^ \t([^:]+):(.*)/ ${color:_31}${re:1}\t${color:reset}${re:2}/ /.*/${tg_message_nocolor}/field /.*/${tg_message_nocolor}/value / /_/field /^([^:]+):.*/${re:1}/field /^[^:]+: *(.*)/${re:1}/value / +$//value /.*Load Average\t.*//"
/trigger set conky_tag_color command "${if:${field}==Load_Average?/buffer set localvar_set_conky_${field} ${value}:/mute set plugins.var.python.text_item.conky_${field} all \${if:${buffer.num_displayed}==?${field} ${color:white}${value}${esc:\x7D}}"

this trigger will beautify the output of conky, add a localvar with the load average (to use in buflist) and add a option for every lines. These options are actually text_item options so we can use them in a bar. We will add the items later in the item option of the status bar. These items will be shown only if the conky buffer is not visible in any windows. Don't change .conkyrc because this trigger is tied to this particular .conkyrc (change the trigger if you change .conkyrc)

my .conkyrc

background no
cpu_avg_samples 2
net_avg_samples 2
no_buffers yes
out_to_stderr no
update_interval 1.0
uppercase no
use_spacer none

TEXT
Load Average: ${loadavg 1 2}
Uptime: $uptime
CPU: $cpu%
RAM: $memperc%
Swap: $swapperc%
Up: ${upspeed venet0}
Down: ${downspeed venet0}

Note: you need conky-cli package on Debian

Weather with wttr.in

/buffer_autoset add exec.exec.weather short_name weather
/set spell.dict.exec.exec.weather fr
/trigger add weather command weather
/trigger set weather regex "/\s/_/tg_argv_eol1"
/trigger set weather command "/exec -noflush -norc -noln -buffer weather curl -s http://wttr.in/${tg_argv_eol1}?lang=${spell.dict.exec.exec.weather}"

I found something very similar on the alias wiki page of WeeChat on GitHub. I adjust it for my own use. So when you type /weather Montreal, a new buffer will be created and will show the output of curl -s http://wttr.in/Montreal. (I created a trigger instead of an alias to replace space by _ in city name)

/trigger add set_title_weather_buffer print "exec.exec.weather"
/trigger set set_title_weather_buffer conditions "${tg_message_nocolor} !~ ^\W && ${tg_message_nocolor} !~ (wttr\.in|@igor_chubin)"
/trigger set set_title_weather_buffer regex "/.*/${tg_message_nocolor}/ /[^:]+:(.*)/${re:1}/tg_message"
/trigger set set_title_weather_buffer command "/buffer set title ${tg_message_nocolor};/buffer set localvar_set_weather ${tg_message}"

I created this trigger to change the title of the buffer from Executed commands to Weather for City: Montreal, Canada.

/trigger add weather_shortcut modifier input_text_for_buffer
/trigger set weather_shortcut conditions "${buffer[tg_modifier_data].full_name} == exec.exec.weather && ${tg_string_nocolor} !~ ^/"
/trigger set weather_shortcut regex "==(.*)==/weather ${re:1}"

This trigger will allow you to enter only the city name (without /weather) in the weather buffer.

Bars

Bar buflist and buflist_hotlist (need the escape)

unmerge servers buffers from core and indent

/set irc.look.server_buffer independent

Note: show channels and privates buffers under their respective server instead of mixing them all.

/bar set buflist separator off
/bar set buflist priority 2
/bar set buflist size 15
/bar set buflist items buflist
/bar add buflist_hotlist root left 1 0 buflist2
/bar set buflist_hotlist size 3
/bar set buflist_hotlist separator 1

/set buflist.format.hotlist_highlight "${color:163}"
/set buflist.format.hotlist_message "${color:229}"
/set buflist.format.hotlist_private "${color:121}"

/set buflist.format.buffer "${if:${bar_item.name}==buflist?${eval:${format_name}}:${if:${bar_item.name}==buflist2?${if:${type}==server?${color:31,31}} ${eval:${format_hotlist}}}}"
/set buflist.format.buffer_current "${if:${bar_item.name}==buflist?${eval:${format_name}}:${if:${type}==server?${color:31,31}} }"
/set buflist.format.number "${if:${current_buffer}?${if:${type}==server?${color:*white,31}:${color:*white}}${hide:>,${buffer[last_gui_buffer].number}} :${if:${type}==server?${color:black,31}:${color:239}}${number}${if:${number_displayed}?.: }}"
/set buflist.format.indent "${if:${type}==channel&&${buffer.name}=~fr$||${info:spell_dict,${buffer.full_name}}=~^fr?${color:blue}f :  }${color:*white}"
/set buflist.format.name "${cutscr:${if:${info:ruby_interpreter}!=?${info:ruby_eval,puts ((${weechat.bar.buflist.size} - 1).to_s)}:${if:${info:perl_interpreter}!=?${info:perl_eval,print ${weechat.bar.buflist.size} - 1}}},${if:${type}==server?${color:white}:${color:${weechat.color.chat_prefix_more}}}${weechat.look.prefix_align_more},${if:${type}=~^(channel|private)$?${eval:${format_number}${indent}}${eval:${color_hotlist}}${name}:${if:${type}==server?${if:${info:irc_server_isupport_value,${name},NETWORK}?${eval:${format_number}${indent}}${color:white,31}${info:irc_server_isupport_value,${name},NETWORK}:${eval:${format_number}${indent}}${color:white,31}${name}}:${eval:${format_number}${indent}}${eval:${color_hotlist}}${name} ${color:31}${buffer.local_variables.filter}${buffer.local_variables.conky_Load_Average}${buffer.local_variables.weather}}}}"
/set buflist.format.hotlist "${if:${type}==server?${color:,31}}${if:${cutscr:${weechat.bar.buflist_hotlist.size},, ${hotlist}}==${esc:\x20}${hotlist}?${repeat:${if:${info:ruby_interpreter}!=?${info:ruby_eval,hotlist = '${info:escape,${hotlist}}'; puts ((${weechat.bar.buflist_hotlist.size} - 1 - Weechat.string_remove_color(hotlist, '').chomp.size).to_s)}:${if:${info:perl_interpreter}!=?${info:perl_eval,my $hotlist = '${info:escape,${hotlist}}'; my $size = weechat::string_remove_color($hotlist, ''); chomp $size; print ${weechat.bar.buflist_hotlist.size} - 1 - length($size)}}}, }${hotlist}:${cutscr:${if:${info:ruby_interpreter}!=?${info:ruby_eval,puts ((${weechat.bar.buflist_hotlist.size} - 2).to_s)}:${if:${info:perl_interpreter}!=?${info:perl_eval,print ${weechat.bar.buflist_hotlist.size} - 2}}},${if:${type}==server?${color:white}:${color:${weechat.color.chat_prefix_more}}}${weechat.look.prefix_align_more},${hotlist}}}"

/set weechat.look.bar_more_down ""
/set weechat.look.bar_more_up ""

/trigger add bar_scroll command_run "/bar scroll buflist*"
/trigger set bar_scroll regex "/.*/${tg_command}/arguments /.* ([^ ]+)$/${re:1}/arguments"
/trigger set bar_scroll command "/bar scroll buflist * ${arguments};/bar scroll buflist_hotlist * ${arguments}"
/trigger set bar_scroll return_code "ok_eat"

/trigger add bar_resize command_run "/bar set buflist size*;/bar set buflist_hotlist size*"
/trigger set bar_resize command "/buflist refresh"

/key bindctxt mouse @bar(buflist*):alt-wheelup /bar set ${_bar_name} size ${if:${info:ruby_interpreter}!=?${info:ruby_eval,puts ((${weechat.bar.${_bar_name}.size} - 1).to_s)}:${if:${info:perl_interpreter}!=?${info:perl_eval,print ${weechat.bar.${_bar_name}.size} - 1}}}
/key bindctxt mouse @bar(buflist*):alt-wheeldown /bar set ${_bar_name} size ${if:${info:ruby_interpreter}!=?${info:ruby_eval,puts ((${weechat.bar.${_bar_name}.size} + 1).to_s)}:${if:${info:perl_interpreter}!=?${info:perl_eval,print ${weechat.bar.${_bar_name}.size} + 1}}}

There's a lot going on here. I created a second bar, buflist_hotlist, that contain the item buflist2. This item contain only the hotlist so we can resize this bar individually from the buflist bar. I use a very small amount of scripting, only to substract one from a number and get the length of ${hotlist}. The trigger will synchronise the scroll between the two bars. That is, if you scroll the buflist bar, the buflist_hotlist bar will also be scroll, and vice versa. I bind two keys, alt-wheelup and alt-wheeldown, to resize the bars. You need eitheir ruby or perl for my buflist, if ruby is not loaded it will fall back to perl.

Bar active title

/bar add activetitle window top 1 0 [#window_number],buffer_title
/bar set activetitle priority 500
/bar set activetitle conditions ${active}
/bar set activetitle color_fg white
/bar set activetitle color_bg 31
/bar set activetitle separator 1

Note: This bar will be different from the already created one. I set the conditions to ${active} so this bar will be displayed on the active window only. The other one will be used for other windows.

Bar title

/bar set title conditions ${inactive}
/bar set title color_fg black
/bar set title color_bg 31
/bar set title items [#window_number],buffer_title

Bar status

/bar add rootstatus root bottom 1 0 [time],[buffer_count],[buffer_plugin],buffer_number+:+buffer_name+(buffer_modes)+{buffer_nicklist_count}+buffer_filter,[bitlbee_typing_notice],[lag],[spell_dict],[spell_suggest],completion,scroll,conky_CPU,conky_RAM,conky_Swap,conky_Up,conky_Down
/bar set rootstatus color_fg 31
/bar set rootstatus color_bg 234
/bar set rootstatus separator 1
/bar set rootstatus priority 500
/bar del status
/bar set rootstatus name status

Note: the built-in status bar is of type window. I prefer a status bar of type root which means it will be outside any window. At this time, you can't change the type of a bar. So we delete the status bar and create a new one.

Bar input

/bar add rootinput root bottom 1 0 [buffer_name]+[input_prompt]+(away),[input_search],[input_paste],input_text
/bar set rootinput color_bg black
/bar set rootinput priority 1000
/bar del input
/bar set rootinput name input

Note: the built-in input bar is of type window. I prefer a input bar of type root which means it will be outside any window. At this time, you can't change the type of a bar. So we delete the status bar and create a new one.

Bar Nicklist

/bar set nicklist color_fg 229
/bar set nicklist separator 1
/bar set nicklist conditions ${nicklist} && ${window.number} == 1 && ${buffer.full_name} !~ ^irc.freenode.(#newsbin|##news)$
/bar set nicklist size_max 14
/bar set nicklist size 14

Note: I changed the conditions to display the nicklist only on buffer of type channels ${nicklist} and on the window number 1, which is my chat window (2 being my highlight window and 3 my conky window). In my case, I could remove ${window.numer} == 1 because the highmon and exec buffer (conky) are not of type channels so ${nicklist} is enough.

Layouts

Layout highlight-or-news

/eval /ruby eval -oc print "/window splith #{(8.0 / ${window[gui_current_window].win_height} * 100).to_i}"
/buffer add -switch highmon
/window 1
/layout store highlight-or-news

Note: Instead of having only one window, we split it to create another one that we will use to show all highlights.

Layout highlight-or-news-and-conky

/window 2
/window splitv 85
/buffer exec.conky
/window 1
/layout store highlight-or-news-and-conky

Note: split the highlight monitor window in 2 and show conky in the new one

Channel Monitor

WeeChat Screenshot

/buffer_autoset add core.chanmon title Channels Monitor

/trigger add chanmon_like print "*;irc_privmsg"
/trigger set chanmon_like conditions "${buffer.local_variables.type} == channel && ${buffer.full_name} != irc.freenode.##news"
/trigger set chanmon_like command "/print -newbuffer chanmon -tags ${tg_tags} ${color:${info:nick_color_name,${server}}}${cut:4,${color:${weechat.color.chat_prefix_more}}${weechat.look.prefix_buffer_align_more},${server}}${color:${info:nick_color_name,${channel}}}${channel}\t${if:${tg_tags} !~ ,irc_action,?${weechat.look.quote_nick_prefix}${tg_prefix}${color:reset}${weechat.look.quote_nick_suffix}:${tg_prefix}${color:reset}} ${tg_message}"

This trigger create a new buffer named chanmon. This buffer will contain all the messages from all the channels you are on. This is almost identical to the scripts chanmon.pl but without any options.

Highlight Monitor

/eval /set weechat.startup.command_after_plugins "${weechat.startup.command_after_plugins};/buffer add highmon"

/buffer_autoset add core.highmon title Highlight Monitor

/trigger add highmon_like print ""
/trigger set highmon_like conditions "${tg_highlight} == 1 && ${tg_displayed} == 1 && ${buffer.local_variables.type} == channel && ${tg_tags} =~ ,irc_privmsg,"
/trigger set highmon_like command "/print -newbuffer highmon -tags ${tg_tags} ${color:${info:nick_color_name,${server}}}${cut:4,${color:${weechat.color.chat_prefix_more}}${weechat.look.prefix_buffer_align_more},${server}}${color:${info:nick_color_name,${channel}}}${channel}\t${if:${tg_tags} !~ ,irc_action,?${weechat.look.quote_nick_prefix}${tg_prefix}${color:reset}${weechat.look.quote_nick_suffix}:${tg_prefix}${color:reset}} ${tg_message}"

This trigger create a new buffer named highmon. This buffer will contain all the highlighted message from all the channels you are on. This is similar to the highmon.pl script but without any options.

News

WeeChat Screenshot

/filter add news irc.freenode.##news !nick_newsly*+!host_yano@unaffiliated/yano/bot/rssly,!irc_privmsg *
/filter add news_interest irc.freenode.##news nick_newsly*+irc_privmsg,host_yano@unaffiliated/yano/bot/rssly+irc_privmsg !^(\s|\[)(Reddit [-] /r/netsec|Wired|freenode|EFF Updates|erry's blog|techdirt|TorrentFreak|Science Daily|Hacker News|CNET|phoronix|Ars Technica|The Intercept|france24|Radio-Canada Nouvelles|Canoe|Huffington Post [-] Weird News|Journal du hacker|Futura Sciences)( \-| | |\])

##news is a channel on Freenode with a bot named newsly that display news from various sources. The first /filter command hides everything that happends on the channel except PRIVMSG from newsly. The second /filter hides every news except those from the given list.

The following triggers use the new hook_line. You must be using weechat 2.3. Otherwise, looks in the revisions to take the other version.

/trigger add news_line line *;irc.freenode.##news;irc_privmsg+nick_newsly*
/trigger set news_line regex "/.*/${tg_message_nocolor}/site_name /^\[([^]]+)\].*/${re:1}/site_name /.*/${tg_message_nocolor}/title /^\[[^]]+\]//title /.*/${site_name}/site_color /^([^-]+).*/${info:nick_color_name,${re:1}}/site_color /.*/${title}/url ==.*(https?://[^ ]+).*==${re:1}==url /\+/%2B/url /,/%2C/url /\!/%21/url /\*/%2A/url /.*/${re:0},url_${url}/tags ==https?://[^ ]+ .*====title /.*/[${color:${site_color}}${site_name}${color:reset}] ${title}/message /.*//prefix"

the normal version.

/trigger add news_line line *;irc.freenode.##news;irc_privmsg+nick_newsly*
/trigger set news_line regex "/.*/${tg_message_nocolor}/site_name /^\[([^]]+)\].*/${re:1}/site_name /.*/${tg_message_nocolor}/title /^\[[^]]+\]//title / - / ${color:-underline} /site_name /.*/${site_name}/site_color /^([^-]+).*/${info:nick_color_name,${re:1}}/site_color /.*/${title}/url ==.*(https?://[^ ]+).*==${re:1}==url /\+/%2B/url /,/%2C/url /\!/%21/url /\*/%2A/url /.*/${re:0},url_${url}/tags ==https?://[^ ]+ .*====title /.*/${color:_black,${site_color}} ${site_name} ${color:${site_color},default}${color:reset}${title}/message /.*//prefix"

the one with powerline symbols.

These triggers will do a few things. The URL will be removed from the message and inserted, as a tag, in the tags instead. This is very useful because url are often very long. The date will also be removed from the message for similar reason. The difference between the two triggers above are the way they display the site name (refers to the screenshot above).

Note: The url and the date will not appears in log. This is a consequence of using a modifier or a line trigger.

/trigger add hsignal_news_click hsignal news_click
/trigger set hsignal_news_click regex "/.*,url_([^,]+).*/${re:1}/_chat_line_tags"
/trigger set hsignal_news_click command "/command -buffer ${buffer.full_name} core /input insert ${if:${_key}==m?${_chat_line_message} }${_chat_line_tags}\x20"

/key bindctxt cursor @chat(irc.freenode.##news):i hsignal:news_click;/cursor stop
/key bindctxt cursor @chat(irc.freenode.##news):m hsignal:news_click;/cursor stop

This trigger will be triggered when we press 'i' or 'm' on a news in cursor mode (in general we invoke this with the middle mouse button). 'i' insert the URL in the input bar. If the URL is too long to view it all, simply press return to send it to the channel, which anyway is +m so nobody will see it, and press alt+l to go in bare mode (so you can click on the URL). 'm' is more interesting, generally when you press 'm' in cursor mode, you add the message in the input bar, but remember, the message does not contain the URL anymore, so it is useless to send the title to someone without the URL. So, in this channel, 'm' is different. The URL is added back to the message.

nullpointer (https://0x0.st)

/alias add nullpointer /exec -sh -hsignal nullpointer $* 2>&1 | curl -sfSF file=@- https://0x0.st
/trigger add nullpointer hsignal nullpointer
/trigger set nullpointer regex "/\n//out"
/trigger set nullpointer command "/command -buffer ${buffer.full_name} core /input delete_line;/command -buffer ${buffer.full_name} core /input insert ${out}"

This allow you to type /nullpointer uptime for example, to send the output of the uptime command to 0x0.st. Your input bar content will be replaced by the url of the paste. This way you can visit the URL to see if there is sensitive information before giving the url to everyone. You may wonder why I didn't used something like: _/exec -sh -pipe "/input delete_line;/input insert " $* 2>&1 | curl -sF c=@- https://0x0.st Well If we use this, the input bar will be filled with the command and not the url.

Dev info

WeeChat Screenshot

/trigger add devinfofr hsignal devinfofr
/trigger set devinfofr conditions ${err}==
/trigger set devinfofr regex "/([0-9]{4})-01-([0-9]{2})/${re:2} Janvier ${re:1}/out /([0-9]{4})-02-([0-9]{2})/${re:2} Février ${re:1}/out /([0-9]{4})-03-([0-9]{2})/${re:2} Mars ${re:1}/out /([0-9]{4})-04-([0-9]{2})/${re:2} Avril ${re:1}/out /([0-9]{4})-05-([0-9]{2})/${re:2} Mai ${re:1}/out /([0-9]{4})-06-([0-9]{2})/${re:2} Juin ${re:1}/out /([0-9]{4})-07-([0-9]{2})/${re:2} Juillet ${re:1}/out /([0-9]{4})-08-([0-9]{2})/${re:2} Août ${re:1}/out /([0-9]{4})-09-([0-9]{2})/${re:2} Septembre ${re:1}/out /([0-9]{4})-10-([0-9]{2})/${re:2} Octobre ${re:1}/out /([0-9]{4})-11-([0-9]{2})/${re:2} Novembre ${re:1}/out /([0-9]{4})-12-([0-9]{2})/${re:2} Décembre ${re:1}/out /.*/\n${out}/out /.*/${out}/stable /.*/${out}/stable_date /.*/${out}/devel /.*/${out}/next_stable_date /.*\nstable:([^\n]+).*/La version stable de WeeChat est la ${re:1}./stable /.*\nstable_date:([^\n]+).*/Elle est la version stable depuis le ${re:1}${info:ruby_eval,require 'date'; print ' (' + (Date.today.mjd - Date.parse('${re:1}').mjd).to_s + ' jours)'}./stable_date /.*\ndevel:([^\n]+).*/La version devel de WeeChat est la ${re:1}./devel /.*\nnext_stable_date:([^\n]+).*/La prochaine stable devrait arriver aux alentour du ${re:1}${info:ruby_eval,require 'date'; print ' (' + (Date.parse('${re:1}').mjd - Date.today.mjd).to_s + ' jours)'}./next_stable_date"
/trigger set devinfofr command "/command -buffer ${buffer.full_name} * /say ${stable} ${stable_date} ${devel} ${next_stable_date}"

/trigger add devinfo hsignal devinfo
/trigger set devinfo conditions ${err}==
/trigger set devinfo regex "/([0-9]{4})-01-([0-9]{2})/January ${re:2} ${re:1}/out /([0-9]{4})-02-([0-9]{2})/February ${re:2} ${re:1}/out /([0-9]{4})-03-([0-9]{2})/March ${re:2} ${re:1}/out /([0-9]{4})-04-([0-9]{2})/April ${re:2} ${re:1}/out /([0-9]{4})-05-([0-9]{2})/May ${re:2} ${re:1}/out /([0-9]{4})-06-([0-9]{2})/June ${re:2} ${re:1}/out /([0-9]{4})-07-([0-9]{2})/July ${re:2} ${re:1}/out /([0-9]{4})-08-([0-9]{2})/August ${re:2} ${re:1}/out /([0-9]{4})-09-([0-9]{2})/September ${re:2} ${re:1}/out /([0-9]{4})-10-([0-9]{2})/October ${re:2} ${re:1}/out /([0-9]{4})-11-([0-9]{2})/November ${re:2} ${re:1}/out /([0-9]{4})-12-([0-9]{2})/December ${re:2} ${re:1}/out /.*/\n${out}/out /.*/${out}/stable /.*/${out}/stable_date /.*/${out}/devel /.*/${out}/next_stable_date /.*\nstable:([^\n]+).*/The stable version of WeeChat is ${re:1}./stable /.*\nstable_date:([^\n]+).*/It is the stable version since ${re:1}${info:ruby_eval,require 'date'; print ' (' + (Date.today.mjd - Date.parse('${re:1}').mjd).to_s + ' days)'}./stable_date /.*\ndevel:([^\n]+).*/The devel version of WeeChat is ${re:1}./devel /.*\nnext_stable_date:([^\n]+).*/The next stable should be release around ${re:1}${info:ruby_eval,require 'date'; print ' (' + (Date.parse('${re:1}').mjd - Date.today.mjd).to_s + ' days)'}./next_stable_date"
/trigger set devinfo command "/command -buffer ${buffer.full_name} * /say ${stable} ${stable_date} ${devel} ${next_stable_date}"

/alias add devinfo /exec -norc -timeout 5 -hsignal devinfo url:https://weechat.org/dev/info/all/
/alias add devinfofr /exec -norc -timeout 5 -hsignal devinfofr url:https://weechat.org/dev/info/all/

These alias send info about the current stable version of WeeChat and the next stable to the channel. The alias call exec and the output of exec is send as a hsignal. So the triggers handle the output.

translate with translate-shell (need the escape_shell_single_quote trigger)

WeeChat Screenshot

/trigger add translate_modifier modifier weechat_print
/trigger set translate_modifier conditions "${tg_tags} =~ ,exec_cmd_translated_(text|lang),"
/trigger set translate_modifier regex "/.*/${color:*_31}${if:${tg_tags}=~,exec_cmd_translated_text,?Translation:Language}${color:reset}\t${tg_message_nocolor}/"

/key bindctxt cursor @chat(*):t /window ${_window_number};/command -buffer ${_buffer_full_name} * /exec -norc -name translated_text trans -brief -target fr -no-auto '${info:escape_shell_single_quote,${_chat_line_message}}';/cursor stop
/key bindctxt cursor @chat(*):l /window ${_window_number};/command -buffer ${_buffer_full_name} * /exec -norc -name translated_lang trans -brief -no-auto -id '${info:escape_shell_single_quote,${_chat_line_message}}';/cursor stop
/key bindctxt cursor @chat(*):d /window ${_window_number};/command -buffer ${_buffer_full_name} * /exec -norc -name translated_dict -n trans -dictionary -no-auto '${info:escape_shell_single_quote,${_chat_word}}';/cursor stop

This let you translate text with the translate-shell program (package has the same name, at least for Debian). If you want to translate something someone said, press the middle mouse button on the message then press 't'. If you want to know the language of the text, press 'l' instead. Finally, you can press 'd' this will open a buffer and call translate-shell in dictionary mode. The trigger will beautify the output of translate-shell.

Highlight

/set weechat.look.highlight *pascalpoitras*
/buffer_autoset add irc.bitlbee.#twitter_pascalpoitras* highlight_words freenode,snoonet,*weechat*
/buffer_autoset add irc.bitlbee.#LET highlight_regex .*
/buffer_autoset add irc.bitlbee.#deals highlight_regex .*
/buffer_autoset add irc.freenode.##reddit-hockey highlight_regex (^GOAL: MTL.*|^Le But: MTL.*)

Triggers

/trigger add upgrade_scripts signal day_changed
/trigger set upgrade_scripts command "/script update;/wait 10s /script upgrade"

The trigger upgrade_scripts will update the local script cache and then upgrade all the installed scripts at midnight.

/trigger add marie_birthday signal day_changed
/trigger set marie_birthday conditions "${tg_signal_data} =~ 03-22$"
/trigger set marie_birthday command "/command -buffer ${sec.data.mariechannel} ruby /ruby eval -o print "BONNNE FÊTEEEE!!! BON #{${date:%Y} - 1984}ieme anniversaire!!!""

The trigger marie_birthday will be triggered the March 22 of each years at midnight to tell my friend "happy birthday"

/trigger add new_year signal day_changed
/trigger set new_year conditions "${tg_signal_data} =~ 01-01$"
/trigger set new_year command "/command -buffer ${sec.data.mariechannel} irc /msg * BONNNE ANNÉE ${date:%Y}!!! santé, bonheur et sexe a toi chère amie :)"

The Happy New Year trigger!

WeeChat Screenshot

/trigger add modifier_is_nick_valid modifier input_text_display 
/trigger set modifier_is_nick_valid conditions "${tg_string_nocolor} =~ ^/nick .+ && ${buffer.plugin.name} == irc"
/trigger set modifier_is_nick_valid regex "==/nick (.+)==${re:1}==tg_string_nocolor ===/nick (.+)===/nick ${if:${info:irc_is_nick,${tg_string_nocolor}}&&${cut:${info:irc_server_isupport_value,${server},NICKLEN},,${tg_string_nocolor}}==${tg_string_nocolor}?${color:*green}:${color:*red}}${re:1}      -- NICKLEN:${color:-bold} ${info:perl_eval,print ${info:irc_server_isupport_value,${server},NICKLEN} - (${buffer.input_buffer_length} - 6) . ' /'} ${info:irc_server_isupport_value,${server},NICKLEN}  ${color:bold}Allowed Chars: ${color:-bold}${esc:a-zA-Z0-9_-\[]{}^`|}===tg_string"

The trigger modifier_is_nick_valid will give you hint about max nickname length and available character in nickname and will also tell you if the nick is valid (green) or not (red). Note that it doesn't works with -all option of the /nick command.

hook_info triggers

/trigger add escape info escape
/trigger set escape conditions "${tg_arguments}"
/trigger set escape regex "/.*/${tg_arguments}/tg_info /'/\'/ /\"/\\"/"

example: /eval -n ${info:ruby_eval,puts '${info:escape,Hi' Everyone}'} will result in Hi' Everyone

/trigger add escape_shell_single_quote info escape_shell_single_quote
/trigger set escape_shell_single_quote conditions "${tg_arguments}"
/trigger set escape_shell_single_quote regex "/.*/${tg_arguments}/tg_info /'/'\''/"

example: /eval /exec -norc -sh echo '${info:escape_shell_single_quote,${plugins.var.text}}' | cowsay will display a cow saying the content of plugins.var.text option

/trigger add length_utils info length
/trigger set length_utils regex "/.*/${if:${tg_arguments}?${info:ruby_eval,puts '${info:escape,${tg_arguments}}'.size.to_s}:0}/tg_info"

example: /eval -n ${info:length,weechat} will result in 7

/trigger add inc_utils info inc
/trigger set inc_utils conditions "${tg_arguments} =~ ^(-?[0-9]+)*,[0-9]+$"
/trigger set inc_utils regex "/^,/1,/tg_arguments /.*/${tg_arguments}/the_number /^(-?[0-9]+),[0-9]+/${re:1}/the_number /^-?[0-9]+,([0-9]+)/${re:1}/tg_arguments /.*/${info:ruby_eval, puts((${tg_arguments} + ${the_number}).to_s)}/tg_info"

example: /eval -n ${info:inc,,7} and ${info:inc,5,${info:length,weechat}} will result 8 and 12

/trigger add ircbufstats_utils info ircbufstats
/trigger set ircbufstats_utils conditions "${tg_arguments} =~ ^(server|channel|private)$"
/trigger set ircbufstats_utils regex "/^(server|channel|private)$/${re:1}/tg_arguments /.*/${info:ruby_eval, infolist = Weechat.infolist_get('buffer', '', ''); buffers_stats = Hash.new do |hash,key| hash[key] = 0 end; while Weechat.infolist_next(infolist) != 0 do buffer_ptr = Weechat.infolist_pointer(infolist, 'pointer'); buffers_stats[Weechat.buffer_get_string(buffer_ptr, 'localvar_type')] += 1 if Weechat.infolist_string(infolist, 'plugin_name') == 'irc' end if infolist != 0; Weechat.infolist_free(infolist); puts buffers_stats['${tg_arguments}'].to_s}/tg_info"

example: /eval -n I am on ${info:ircbufstats,server} networks and ${info:ircbufstats,channel} channels will result in I am on 3 networks and 17 channels

hook_info triggers are new in WeeChat 2.5. The 5 triggers above are useful and some are used somewhere in the configuration. The escape trigger will escape single-quote and double quote characters. The escape_shell_single_quote is designed to escape single-quote in single-quoted string for the shell. The ircbufstats trigger return the number of servers, channels or query. The length return the length of the string. The inc is used to increment (or decrement with a negative number as the first number) a number.

Keys

/key bindctxt cursor @item(buffer_nicklist):v /window ${_window_number};/voice ${nick}
/key bindctxt cursor @item(buffer_nicklist):o /window ${_window_number};/op ${nick}
/key bindctxt cursor @item(buffer_nicklist):V /window ${_window_number};/devoice ${nick}
/key bindctxt cursor @item(buffer_nicklist):O /window ${_window_number};/deop ${nick}
/key bindctxt cursor @chat(*):s /window ${_window_number};/slap ${_chat_line_nick};/cursor stop
/key bindctxt cursor @item(buffer_nicklist):s /window ${_window_number};/slap ${nick};/cursor stop
/key bindctxt cursor @item(buflist):h /command -buffer ${full_name} irc /allchan -current buffer hide;/command -buffer ${full_name} irc /allpv -current buffer hide;/cursor stop
/key bindctxt cursor @item(buflist):H /command -buffer ${full_name} irc /allchan -current buffer unhide;/command -buffer ${full_name} irc /allpv -current buffer unhide;/cursor stop
/key bindctxt cursor @chat(*):g /window ${_window_number};/customgrep ${_chat_line_nick};/cursor stop
/key bindctxt cursor @item(buffer_nicklist):g /window ${_window_number};/customgrep ${nick};/cursor stop

/key bindctxt cursor @chat(*):a /command -buffer ${buffer.full_name} core /input insert ${_chat_bol}\x20;/cursor stop
/key bindctxt cursor @chat(*):e /command -buffer ${buffer.full_name} core /input insert ${_chat_eol}\x20;/cursor stop
/key bindctxt cursor @chat(*):w /command -buffer ${buffer.full_name} core /input insert ${_chat_word}\x20;/cursor stop

Others Keyboard shortcuts

/key bind meta-meta2-A /bar scroll nicklist * -100%
/key bind meta-meta2-B /bar scroll nicklist * +100%
/key bind meta2-A /input history_global_previous
/key bind meta2-B /input history_global_next

Alias

/alias add ame allchan -current /me
/alias add amsg allchan -current /msg *
/alias add cq allpv /buffer close
/alias add slap /me slaps $1- around a bit with a large trout
/alias add customgrep /input delete_line;/input insert /grep log */$server/$channel.* -a ^\[\d{2}:\d{2}:\d{2}\] <%{escape $1}>\x20
/alias add znc /quote znc
/alias add fu /say (╹◡╹)凸 $*
/alias addcompletion %(weechat_commands) multicomm /alias add temp $*;/temp
/alias add znc-o /exec -o -sh znc --version | head -1 | cut -d' ' -f1-2
/alias add funnyversion /eval ${if:$*==?${info:ruby_eval,print %W[mIRC irssi KVIrc HexChat AdiIRC BitchX].sample}:$*} ${info:version} (git: ${info:version_git}) [compiled on ${info:date}]
/alias add savechan /allserv mute unset irc.server.$server.autojoin;/allchan mute autojoinem add;/mute unset irc.server.undernet.autojoin
/alias add change-color /fset c:${type_en} == color && ${value} == $1;/command -buffer fset.fset core /input send m:*;/fset -add -$1;/fset -add $2    

The multicomm alias is an alternative to /eval -s, but more "secure". If you use eval -s for this purpose (execute more than one command) but you forget that thing like secure variables will be evaluate this can be very bad. The change-color alias allow you to change all colors options corresponding to a certain value with another one.

The savechan alias will first remove every channels in the autojoin option (because I dont want to keep the channels that I'm not there anymore) then it add all the channels but then unset the option for undernet because I dont want to join any channel on this network (No I can't combine allserv and allchan and exclude undernet). Also note that I used allserv unset instead of unset -mask: because I don't want to remove the channels of servers I am not currently connected to.

Filters

/set irc.look.smart_filter on
/filter add irc_smart *,!irc.undernet.* irc_smart_filter *

Custom join color

/set weechat.color.chat_prefix_join 121
/set weechat.color.chat_host 31
/set irc.color.message_join 121

The weechat.color.chat_host option will also set this color for part and quit. To have a different color, for example, a host in red for parts and quits and green for joins, see this.

Custom part and quit

/set weechat.color.chat_prefix_quit 131
/set irc.color.message_quit 131

The remaining IRC options

/set irc.server_default.away_check 5
/set irc.server_default.away_check_max_nicks 25
/set irc.color.nick_prefixes "q:lightred;a:lightcyan;o:121;h:lightmagenta;v:229;*:lightblue"
/set irc.network.ban_mask_default "*!*@$host"
/set irc.look.buffer_switch_autojoin off
/set irc.look.buffer_switch_join off
/set irc.look.color_nicks_in_nicklist on
/set irc.look.part_closes_buffer on

The remaining Weechat options

/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_notify_default message
/set weechat.look.buffer_time_format "${253}%H${245}%M"
/set weechat.look.color_inactive_message off
/set weechat.look.color_inactive_prefix off
/set weechat.look.color_inactive_prefix_buffer off
/set weechat.look.color_inactive_window off
/set weechat.look.day_change_message_1date ▬▬▶ %a, %d %b %Y ◀▬▬
/set weechat.look.day_change_message_2dates ▬▬▶ %%a, %%d %%b %%Y (%a, %d %b %Y) ◀▬▬
/set weechat.look.item_buffer_filter "•"
/set weechat.look.prefix_align_min 0
/set weechat.look.prefix_align_max 10
/set weechat.look.prefix_join "▬▬▶"
/set weechat.look.prefix_quit "◀▬▬"
/set weechat.look.prefix_suffix "│"
/set weechat.look.read_marker_string "─"
/set weechat.look.separator_horizontal ""


/set weechat.color.bar_more 229
/set weechat.color.chat_highlight lightred
/set weechat.color.chat_highlight_bg default
/set weechat.color.chat_nick_colors "cyan,magenta,green,brown,lightblue,lightcyan,lightmagenta,lightgreen,blue"
/set weechat.color.chat_prefix_more 31
/set weechat.color.chat_prefix_suffix 31
/set weechat.color.chat_read_marker 31
/set weechat.color.chat_time 239
/set weechat.color.chat_delimiters 31
/set weechat.color.separator 31
/set weechat.color.status_data_highlight 163
/set weechat.color.status_data_msg 229
/set weechat.color.status_data_private 121
/set weechat.color.status_more 229
/set weechat.color.status_name 121
/set weechat.color.status_name_ssl 121

The following command will let you run all the commands of my configuration (not really recommended, you should take only what you want and understand)

First, type the following

/secure passphrase <pass>
/secure set freenodepass <pass>
/secure set snoonetpass <pass>
/secure set undernet_userpass <user> <pass>
/secure set undernet_secret <TOTP secret>
/secure set relaypass <pass>
/script install autojoinem.py buffer_autoset.py autosort.py grep.py text_item.py
/secure set mariechannel <buffer fullname of my friend's channel>

Once scripts are installed

/exec -sh -oc curl -sfS https://gist.githubusercontent.com/pascalpoitras/8406501/raw/myweechat.md | sed -E 's/^\s+//;/^(\/secure|\/script|\/ruby)/d;/^\//!d'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment