WeeChat操作各种聊天软件

https://github.com/MaskRay/Config/tree/master/home/.weechat/

WeeChat

参考https://pascalpoitras.com/my-weechat-configuration/

autosort.py

把相同server的buffers顺序编号

bot2human.py

1
/set python.bot2human.bot_nicks "tg2arch tox2sync xmppbot teleboto teleboto_ Orizon NyaaTelegram tg2gzlug d3tgbot tg2linuxba NyaaCat aosc-telegram XiaoT_bot"

buffers.pl

窗口左侧sidebar显示buffers

highmon.pl

参考https://pascalpoitras.com/2013/08/09/weechat-highlight/

1
2
3
/set weechat.look.highlight security,update
/set weechat.look.highlight_regex .*\bHi\b.*\bplease\b.* # 对所有buffer有效
/autosetbuffer add irc.bitlbee.#twitter highlight_regex . # 安装buffer_autoset.pyhighlight所有bitlbee的`#twitter` buffer中内容。

匹配highlight规则的行会显示在highmon窗口里。

notify.py

pastebin.py

/paste /tmp/a.jpg用img.vim-cn.com图床分享图片,在当前buffer插入链接

/paste /tmp/a.txt用cfg.vim-cn.com pastebin分享文件,在当前buffer插入链接

urlserver.py

Slack

让team owner开启IRC gateway:https://get.slack.help/hc/en-us/articles/201727913-Connecting-to-Slack-over-IRC-and-XMPP

Bitlbee

安装aur/bitlbee-libpurple-unicode-channel(或原版aur/bitlbee-libpurple)

参考,https://www.bitlbee.org/user-guide.html#set_utf8_nicks&bitlbee buffer里输入

1
2
set utf8_nicks true
set nick_format %full_name

Google Hangouts的联系人,&bitlbee中nick会优先使用Contacts里设置的备注名。设置上面两个选项后就不会显示为乱码。

/etc/bitlbee/bitlbee.conf[settings] section的Proxy可以设置proxy。

Facebook Messenger

安装aur/bitlbee-facebook-git

参考https://wiki.bitlbee.org/HowtoFacebookMQTT创建account。

Google Hangouts

参考https://wiki.bitlbee.org/HowtoGtalk创建account。

Twitter

https://wiki.bitlbee.org/HowtoTwitter

微信网页版

https://github.com/MaskRay/wechatircd

如果需要定制命令行选项的话,把/usr/lib/systemd/system/wechatircd.service复制到/etc/systemd/system/wechatircd.service,添加--ignore 不想看到的群名子串1 不想看到的群名子串2选项

1
systemctl enable --now wechatircd
1
/server add wechat 127.1/6667 -autoconnect

QQ网页版

https://github.com/MaskRay/webqqircd

1
systemctl enable --now webqqircd
1
/server add qq 127.1/6668 -autoconnect

如果需要定制命令行选项的话,把/usr/lib/systemd/system/webqqircd.service复制到/etc/systemd/system/webqqircd.service,添加--ignore 不想看到的群名子串1 不想看到的群名子串2选项

Telegram网页版

https://github.com/MaskRay/telegramircd

1
systemctl enable --now telegramircd

如果需要定制命令行选项的话,把/usr/lib/systemd/system/telegramicd.service复制到/etc/systemd/system/telegramicd.service,添加--ignore 不想看到的群名子串1 不想看到的群名子串2选项

偃师——finite automaton生成工具

我一只上海的喵怎么到北京来了呢?……“苟利长亭生死以,岂因祸福避趋之”那么所以我就到了北京。到了北京我干了这二十几天我也没有什么别的,大概三件事:

一个,开发了一个安全产品(秘); 第二个,做了一个自动机生成工具; 第三个,就是见了一些同学,从学长那里听到了一点人生的经验。

终端模拟器下宽字符退格

折腾完https://maskray.me/blog/2016-03-13-terminal-emulator-fullwidth-color-emoji后发现canonical mode下emoji字符退格只后退了一列,后发现所有宽字符都有问题,因此做了一番调研。

Canonical/noncanonical mode

早期Unix有cooked/cbreak/raw mode三种模式,raw mode和cbreak模式区别在于signal和输入输出处理,输入都是以字符为单位,即read(STDIN_FILENO, buf, 1)在键入一个字符后即返回。Cooked mode与它们差别较大,最重要的区别是终端输入以行为单位进行,并自带一个基础行编辑器,可以使用退格和WERASE(默认为^W)删除光标前的单词。

终端模拟器下使用双倍宽度多色Emoji字体

多色Emoji字体

Cairo支持

较新的FreeType支持多色,但cairo-1.14.6没有默认开启支持。hexchain指出修改cairo源码一行代码即可:

1
2
3
4
5
6
7
8
9
10
11
--- a/src/cairo-1.14.6/src/cairo-ft-font.c	2016-03-13 09:36:42.618325503 +0800
+++ b/src/cairo-1.14.6/src/cairo-ft-font.c 2016-03-13 09:38:24.194288159 +0800
@@ -2258,7 +2258,7 @@
* Moreover, none of our backends and compositors currently support
* color glyphs. As such, this is currently disabled.
*/
- /* load_flags |= FT_LOAD_COLOR; */
+ load_flags |= FT_LOAD_COLOR;
#endif

error = FT_Load_Glyph (face,

然后编译安装cairo。

Arch Linux普通用户

可以安装aur/cairo-coloredemoji

Arch Linux infinality-bundle用户

huiyiqun指出,infinality-bundle用户应该:

  1. 安装https://aur.archlinux.org/packages/cairo-infinality-ultimate-with-colored-emoji/
  2. 删除/etc/fonts/conf.d/82-no-embedded-bitmaps.conf 。按https://gist.github.com/huiyiqun/9f20f177655946263a48170ee662cea9配置fontconfig。

Fontconfig配置

安装Noto Color Emoji字体,Arch Linux可以装extra/noto-fonts-emoji

~/.config/fontconfig/fonts.conf(更准确点应用$XDG_CONFIG_HOME)中添加下面两个<match>标签(hexchain提供)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<fontconfig>
...
<match target="scan">
<test name="family">
<string>Noto Color Emoji</string>
</test>
<edit name="scalable" mode="assign"><bool>true</bool></edit>
</match>
<match target="pattern">
<edit name="family" mode="prepend">
<string>Noto Color Emoji</string>
</edit>
</match>
</fontconfig>

可以用fc-match -s monospacefc-match -s sansfc-match -s sans-serif确定字体选择顺序。我这里Noto Color Emoji只能排到第二,不明原因。

推荐使用hexchain的配置:https://gist.github.com/hexchain/47f550472e79d0805060

Emoji字符宽度

经过以上两步配置,理应可以使用Noto Color Emoji字体了。但对于Monospace字体,emoji字符显示宽度为1,会与其后的字符重叠。

vte中设置emoji字符宽度

在终端模拟器中,字符是按列显示的,因此有宽度的概念。vte把emoji字符当作1,因此显示时会与之后的字符重叠。

以终端模拟器termite使用的community/vte3-ng为例。修改源码src/vte.cc:_vte_unichar_width,让该函数对于某些Noto Color Emoji提供的Unicode block返回2。此处我硬编码了几个用到的Unicode block,不全:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--- a/src/vte.cc        2016-03-12 23:44:04.157720973 +0800
+++ b/src/vte.cc 2016-03-13 00:20:45.592623311 +0800
@@ -206,6 +206,10 @@
return 0;
if (G_UNLIKELY (g_unichar_iswide (c)))
return 2;
+ if (G_UNLIKELY(0x25a0 <= c && c < 0x27c0 || // Geometric Shapes, Miscellaneous Symbols, Dingbats
+ 0x2b00 <= c && c < 0x2c00 || // Miscellaneous Symbols and Arrows
+ 0x1f300 <= c && c < 0x1f700 || // Miscellaneous Symbols and Pictographs ... Geometric Shapes Extended
+ 0))
+ return 2;
if (G_LIKELY (utf8_ambiguous_width == 1))
return 1;
if (G_UNLIKELY (g_unichar_iswide_cjk (c)))

Arch Linux可以装aur/vte3-ng-fullwidth-emoji。该patch另外修复了canonical mode下退格宽字符,终端模拟器只移动一格光标的问题(其实应该是kernel的bug,不妨头痛医脚)。

设置wcwidth宽度

对于ncurses应用,会用wcwidth计算待擦除字符的宽度。仅经过上面的配置,wcwidth仍认为emoji字符宽度为1,擦除时宽度计算不对,可能导致一些字符残余在屏幕上。

wcwidth对字符宽度的计算由locale决定,比如对于常用的en_US.UTF-8等,glibc提供的/usr/share/i18n/charmaps/UTF-8.gzWIDTHEND WIDTH区块给出了字符宽度信息。但其中没有列出Emoji字符,因此宽度将用缺省值1。

我用https://gist.github.com/MaskRay/86b71b50d30cfffbca7a重新生成一个UTF-8,gzip压缩后覆盖/usr/share/i18n/charmaps/UTF-8.gz,然后执行locale-gen。修改后,可以用https://gist.github.com/MaskRay/8042e39dc822a57c217f确定wcwidth计算出来的宽度确实变更了。

效果

1
echo 🚂🚊🚉🚞🚆🚄🚅🚈🚇🚝🚋🚃🚟

为了这张笑脸真是一把辛酸泪……

感想

Monospace实现很困难。要画出好看的Emoji,势必要用fullwidth,这个属性如果能由字体提供是再好不过的。对于底层的glibc、glib,它们并不能知道字体,但又不得不规定字符宽度,一不小心即与字体的实际宽度产生冲突。翻了翻http://www.unicode.org/Public/UCD/latest/ucd/等,好多地方分散地提到了fullwidth,比如Halfwidth and Fullwidth Forms、East Asian Width等,不同实现对这些概念的理解会有偏差……

在neovim里写这篇文章时又发现neovim对字符宽度也有问题,src/nvim/mbyte.c:utf_char2cells看上去是无辜的,所以谁坏掉了呢?

参考