5
23
2011
51

MathJax:不错的数学公式显示引擎

我最初是在Mathematics - Stack Exchange这个网站上看到MathJax的使用的。当时我偶然发现StackOverflow底部还有一大堆 Stack Exchange 站点,就随便点了几个看看,然后就看到那些漂亮的数学公式,并发现它们竟然不是像维基百科那么用的图片!

不过因为我并不搞数学,一直没需求,所以一直也没尝试玩下 MathJax。前不久看到 Garfileo 的《基于 ASCIIMathML.js 的 is-programmer 博客数学公式书写及显示》一文,昨日又和 Fermat 聊起,才折腾了下。

先来测试几个公式:\(E=mc^2\),$$x_{1,2} = \frac{-b \pm \sqrt{b^2-4ac}}{2b}.$$

原来这个 \(\mathrm{e}^{- \mathrm{i} \pi} + 1 = 0\) 叫欧拉公式,今天才知道 -_-|||。

整个部署过程非常简单,加入以下脚本即可:

<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=default"></script>

然后就是写 TeX 公式了,用\(\)括起来的是行内公式,用$$括起来的是自成一段的公式(术语叫什么我就不知道了)行间公式。

在公式上点右键还有些选项,包括选择使用 HTML+CSS 渲染还是 MathML 渲染、缩放、显示公式源码等。不过 MathML 的显示效果比较丑,而且诸如 Chrome 这些 Webkit 内核的浏览器还不支持。它会优先使用本地字体。我当然没有,于是它尝试使用网络字体。现代浏览器都会OK的,不过在火狐里,如果是本地文件(file://开头的),那么不能使用网络字体。这时候 MathJax 会使用图片代替。感觉挺智能的,而且还有各种模块和其的配置

MathJax 还支持在公式渲染之后再修改,我于是做了个简单的公式编辑器,可实时预览公式渲染的结果。有点郁闷的是,做这个网页时,相比公式处理部分,我大部分精力花在了排版上。。。另外,这个网页在 Chrome 下竟然出错了,清除缓存后才正常。以前 Chrome 也出现过这个问题,但火狐基本没有(我只在火狐3.6时代意外关机后遇到过)。


更新:

公式编辑器加了新功能,可通过 URL 的 hash 部分传递公式代码(尝试点击本段的链接),修改后 URL 也会变化,以便分享。不过发现了 Opera 浏览器的一个特性:会自动将手工输入的 URL 中的\替换成/,造成公式错误(比较点击和手工输入此链接地址的区别)。

Category: Javascript | Tags: javascript tex 数学
5
17
2011
16

强大的Vim插件——CountJump

今天,vim_dev邮件列表里有人说Vim要不要内建camelCase的移动方式。于是一帮人在那里讨论。我平时都是用fU找到下一个字母U的方式在很长的camelCase变量里移动,所以并不怎么关心讨论的结果,但想看看他们到底怎么想的。然后就看到 Ingo Karkat 说到了他的camelcasemotion插件和CountJump插件。Ingo Karkat 这人最近我经常通信的,他给我的colorizer插件(vim.orggithub)提了很多很好的意见(今天又来信了)。他还有个mark插件也很好用,同时高亮多个不同的单词/正则匹配的。

camelCase没太大的兴趣,所以我先没怎么看,看了CountJump的介绍,又见到这个在 patch 文件中跳转的插件,就下回来安装了,仔细读了帮助,才发觉,它可以实现我曾经希望有的功能。

下面开始正式介绍。首先,你得知道text-object是什么(不知道的童鞋请先:help text-object)。这个插件并不干实事,只提供了些函数,大体来说,完成了两类东西的自定义。其一是 patch 块这种区域,其二就是文本对象。定义的方式也很好,想简单,可以使用正则表达式;想更强大,支持使用自定义的函数。

我曾经折腾 Javascript 时非常希望有这样一个功能,可以像使用ci"来更改"string"中的内容这样快速更改 Javascript 正则表达式/regex/双斜线里的内容。可惜 Vim 没有内建这种文本对象。现在有了CountJump,自定义一个易如反掌:

call CountJump#TextObject#MakeWithCountSearch('', '/', 'ai', 'v', '\\\@<!/', '\\\@<!/')

就这样一句命令,然后就可以像使用i"a'这样使用i/a/来表示 Javascript 正则表达式双斜杠的文本内容了。

CountJump的区域移动也不错,不过除了那个用于 patch 的我还真没想到好的使用实例,只弄了这个:

1 call CountJump#Motion#MakeBracketMotion('', 'b', 'e', '\<\w\|\l\@<=\u\|_\@<=\w', '\w\>\|\l\u\@=\|_\w\@=', 1)
2 for mode in ['n', 'o', 'v']
3   exec mode . 'map b [b'
4   exec mode . 'map e ]b'
5 endfor

这个和camelcasemotion的功能类似,使用becamelCase或者under_score中的单词中移动,不过很不完美,实际使用时有一些问题。

最后,有一个非常令我兴奋的是,这样定义的文本对象也被surround.vim支持!在 Javascript 中想把一个字符串字面值改成一个正则表达式?cs"/即可!不过有点遗憾的是,自定义文本对象的名字不能是中文字符,自定义的中文标点文本对象surround.vim也不支持。

Category: Vim | Tags: vim
5
13
2011
6

Cairo 初体验

其实我觊觎 Cairo 很久了。昨天看到这篇文章,就下决心试了下。

简单图形的绘制

这个确实很简单,随便从后文的参考资料处抄点代码过来即可:

static gboolean on_expose_event(GtkWidget *widget,
    GdkEventExpose *event, gpointer data){
  cairo_t *cr;

  cr = gdk_cairo_create(widget->window);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_set_line_width(cr, 1);

  cairo_rectangle(cr, 20, 20, 120, 80);
  cairo_stroke_preserve(cr);
  cairo_set_source_rgb(cr, 1, 1, 1);
  cairo_fill(cr);

  cairo_destroy(cr);

  return FALSE;
}

看函数名基本上知道是在做什么了。我需要一个半透明的矩形,于是查文档,找到cairo_set_source_rgba函数即可。那个 cr,我是折腾到最后才明白它代表了绘制的 context (环境/上下文);至于那个cairo_stroke_preserve,我最终弄明白 Cairo 的绘制方法后才明白的。不管是cairo_rectangle还是我后来用到的cairo_arc,都是“画”了一个路径。之所以要把“画”加上引号,是因为路径本身是看不到的。使用cairo_stroke来描绘路径,使用cairo_fill来填充,而后面带_preserve的版本,是说路径处理完了还留着,下一个操作继续用。我之前犯了个错误,把所有的矩形和圆的路径都画好了才绘制,结果矩形和圆之间有道连线,圆的半径也被画出来了。折腾好久才知道应该在每个路径完成后就绘制。

事件处理

翻了好久的GTK、GDK文档,还是没弄明白该怎么在鼠标拖动时绘制。Google 一下,才看到 Garfileo 的这篇文章,在兴奋之余很有郁闷,Garfileo 以前的 Cairo 相关文章我都收集了,可他为什么后来又换博客了呢。。。。

  gtk_widget_add_events(window, GDK_KEY_PRESS_MASK |
      GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  g_signal_connect(window, "button-press-event",
      G_CALLBACK(drawing_start), NULL);
  g_signal_connect(window, "button-release-event",
      G_CALLBACK(drawing_finish), NULL);
  g_signal_connect(GTK_OBJECT(window), "motion_notify_event",
      G_CALLBACK(drawing_move), NULL);

就这样就可以了。然后我就开始在每个motion_notify_event发生时画一遍,结果在画的时候图像不停地闪。问了下 gtalk 好友老猫,才知道原来只要在 expose 事件时画就好了,而图像改变后,调用下gtk_widget_queue_draw即可。至于为什么这样图像就不会闪,我至今还不清楚。

右键菜单

我需要在几种不同的选区之间切换。本来用 RadioButton 挺好的,但是我现在只会在 GtkWindow 或者 GtkDialog 里画图。后来就想到了右键菜单。查阅文档后就写出以下代码:

  menu = gtk_menu_new();
  menu_rect = gtk_menu_item_new_with_label("矩形");
  menu_circ = gtk_menu_item_new_with_label("圆形");
  menu_poly = gtk_menu_item_new_with_label("多边形");
  gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_rect);
  gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_circ);
  /* TODO 绘制多边形 */
  /* gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_poly); */
  g_signal_connect(menu_rect, "activate",
      G_CALLBACK(switch_to_rect), NULL);
  g_signal_connect(menu_circ, "activate",
      G_CALLBACK(switch_to_circ), NULL);
  g_signal_connect(menu_poly, "activate",
      G_CALLBACK(switch_to_poly), NULL);

  ...

  }else if(event->button == 3){
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
  }

但是这样点右键时只会显示一个小小的白色小边,就像没有菜单项在里面一样。百思不得其解,于是求助于 Google,最后不知道在哪里看到了,原来还需要对menu调用gtk_widget_show_all。想想也是,对窗口调用gtk_widget_show_all只是把窗口里的东西全部显示出来了,但我这个右键弹出菜单不是在窗口里的呀。

一点题外话

因为要绘制多个图形,本来准备自己写个单链表的,刚写完 node 结构体,突然想到,GLib 里不是有各种数据结构吗?于是再查文档,找到 GSList,愉快地用上了。g_slist_foreach这个函数非常好用。

参考资料

Category: 编程 | Tags: cairo C代码 gtk
5
9
2011
40

可笑的计算机网络应用设计实验作业

计算机网络应用设计实验是我们计算机网络课程的后继实验课程。今天是其上机的最后一天,于是得到最后要回去自己做的作业。看到其要求后我大跌眼镜——

要求完成FTP客户端、SMTP客户端、POP3客户端三个系统程序,以及一个应用程序

客户端操作系统为Windows XP。

FTP程序要求具有图形化界面、上传、下载功能,鼓励实现断点续传功能,SMTP/POP3程序具有邮件编写、发送、接收、阅读、删除等基本功能。FTP、SMTP、POP3程序使用socket方式编程,从创建socket、建立TCP连接开始,实现FTP、SMTP、POP3协议的功能,不得调用第三方控件(可使用操作系统自身的API函数)。编程工具可以使用C#或VC++。

应用程序要求实现一个网上书店的基本功能,要求具有前端(用户)和后端(管理)功能,基于Web运行方式。前端具有浏览书目、购物车等功能,后端具有管理书目、基本统计功能。编程工具可以是MS .NET(C#)或者J2EE 二选一,数据库可以是SQL Server、DB2、Oracle、Mysql、PostgreSQL之一。

我们的计算机网络课程是讲从物理层到应用层、从路由协议到TCP协议等等的,这个“计算机网络应用设计实验”总共有七次,要么使用思科的 Packet Tracer 模拟,要么在机柜的机器上弄,配置路由啊VLAN啊之类的,很是正常。可最后这个实验设计是怎么回事?就算是计算机网络应用程序设计课程也没有这么严格而变态的要求啊。这不仅仅是应用层的编程,而且还是Windows图形界面编程、数据库编程、C#或Java Web编程!这样的课程作业,实在应该在至少大二就布置下来,因为它可以作为另外至少四门课的大作业!!

对了,还有一点很令我郁闷——报告要求交Word 2003版格式的文件。根据我未读完的《Word排版艺术》里的信息,以及Word不断弹出的关于Normal.dot文件的对话框,我很确定Word会将文档的某些信息保存在本地的其它文件中,从而导致文档不具有可移植性,别人看到的排版可能根本不对。不过我估计那些用Word的老师没几个人听说过《Word排版艺术》。微软的罪孽在于,它把本来复杂的东西弄得看似简单,实则更加复杂。

武汉大学计算机学院,你太令我失望了!!!

参见:一名大学毕业生的反思已失效链接二

2011年10月10日再加个链接:珞珈山水BBS -- 作为一名毕业生,谈谈哪些行业或者企业不宜进入[原创]

Category: 未分类 | Tags: 教育
5
6
2011
6

login shell 和 non-login shell 不同造成的问题

上篇说到,我在Arch下的tmux的部分环境变量有问题。于是接下来我开始调查原因。最后终于真相大白。不过在揭露真相前,先详细说说问题是什么。

自从使用zsh以后,我在Ubuntu下发现我在~/.profile中设置PATH变量的代码在tty下没有起作用。但在~/.zshrc中设置又不行,因为图形界面登录时不会读取~/.zshrc。source 它也不行,因为可能导致双重设置(在一段时间里,我总是很奇怪地发现命令补全时某些命令会出现两次。。。)。于是,最后我的方案是这样的(箭头表示 source):

.profile --> .zsh/zshrc.env   <-+
.zshrc --> ZSHRC_ENV set? --No--+

这个方案在Ubuntu下一直工作良好。但在Arch+tmux下就出问题了。在tmux中的zsh启动前,ZSHRC_ENV已经设置,于是~/.zsh/zshrc.env没有被 source,于是$PATH设置得不对了。。。

在查阅tmux N次之后,我想,可能是某个启动文件覆盖了我自己的 PATH 变量的设置。于是打开 zsh 的文档,翻到这里:

5.1 Startup/Shutdown Files

Commands are first read from /etc/zsh/zshenv; this cannot be overridden. Subsequent be- haviour is modified by the RCS and GLOBAL_RCS options; the former affects all startup files, while the second only affects global startup files (those shown here with an path starting with a /). If one of the options is unset at any point, any subsequent startup file(s) of the corresponding type will not be read. It is also possible for a file in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and GLOBAL_RCS are set by default.

Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login shell, commands are read from /etc/zsh/zprofile and then $ZDOTDIR/.zprofile. Then, if the shell is interactive, commands are read from /etc/zsh/zshrc and then $ZDOTDIR/.zshrc. Finally, if the shell is a login shell, /etc/zsh/zlogin and $ZDOTDIR/.zlogin are read.

于是发现这一切的根源在于tmux里启动的是login shell!Arch的/etc/profile中重置了$PATH/etc/profile.d/locale.sh中重置了$LANG,所以造成我的tmux下的zsh环境变量不对的问题。于是我把设置移回了~/.profile中,然后将软链接~/.zprofile指向它。locale.shpacman不知道是什么包的,所以我就把它改成了:

[ -z "$LANG" ] && export LANG=en_US.UTF-8

至此,tmux部分的问题终于解决了!

Category: Linux | Tags: arch linux zsh tmux
5
5
2011
5

悲剧的 Arch

昨天尝试切换到Arch,结局十分悲剧。

配置文件复制完毕,启动Awesome正常,启动火狐正常,然后其它的就木有正常的了。。。

首先是tmux。Arch下的tmux一直有个让我十分郁闷的问题:PATH/LANG等环境变量会被重置,但又不是所有环境变量被重置,所以在.zshrc中的检测也失败了。结局就是,我使用脚本自动在tmux中启动的程序几乎全部失败。

其次是empathy、gnome-terminal等使用了GTK3,但是GTK3是不读取~/.gtkrc-2.0的。于是它们的外观很丑很丑。上网搜了下,~/.gtkrc-3.0的格式改变了。虽然变成类似CSS的更容易了,但我还是得花时候学习啊。另外,很多GTK3的窗口右下角都会有个调整块,看着十分碍眼。

wuala因为是Java写的,所以界面还好没变。不过,我忘记密码了!!!wuala的密码是本地存储的,没有办法找回。看了下自己设的密码提示,还是没猜出来。后来换回Ubuntu在登录wuala时看到了密码的长度,又想到了另外一个可能的密码。不过我不敢在这个已经登录的wuala里试了,万一错了就太悲剧了。

继续使用中发现更多的问题。点击empathy中的链接发现默认使用Chrome打开了,不知道该如何设置。fcitx输入法在empathy中工作不正常,一旦按回车或者退格之后就表现出来了,回车、退格无效、Ctrl-空格经常不起作用、某些字母穿透了输入法直接上屏。

我用的Ubuntu中文论坛的加速脚本是那个Python版的。我提取了其pyc文件(并且修改了端口号)。现在也悲剧了——Python 2.7 不认 Python 2.6 编译的字节码文件!于是我只好到官网下载了2.6版的,然后编译安装。然后又是找不到libpython2.6.so.0.1这个库文件,sudo ldconfig后依旧不行。过了好久我才意识到是配置文件里没有包含/usr/local/lib这个目录,在/etc/ld.so.conf.d/下建个文件里边写上后终于好了。

遇到的这么多问题就解决了Python2.6那一个。于是最后只好郁闷地回到Ubuntu下了。


2011年5月7日更新:tmux 那个诡异的问题解决了,见login shell 和 non-login shell 不同造成的问题

2011年5月31日更新:fcitx 那个问题已经在csslayer的指导下几天前就解决了,需要打补丁。Bug 报告链接,我修改的 PKGBUILD 文件

Category: Linux | Tags: arch gtk3
4
22
2011
5

初次使用 git 的“核弹级选项”:filter-branch

当初看 Pro Git 时就被作者这个“核弹级选项”的称呼吓到了,因此一直没敢好奇地去尝试。核弹啊,用对了威力无穷,用错了破坏力无穷!

但是,今天,我不得不用了,因为我想把我的 Python 脚本放到 github 上去公开。由于之前没想过要公开,所以不能肯定是不是把诸如密码之类的敏感数据直接写代码里了。于是我就用 git 的 pickaxe 选项-S来找找看。这个我也是今天才学到的哦,来源是stackoverflow上的若干问题,具体记不清了。

这个选项结合git log,其功能是把提交中包含某个文本的提交找出来。比如git log --stat -S密码就把所有提交中包含“密码”二字的提交找出来了,同时--stat告诉 git 我希望看到文件列表,以确定敏感数据在哪个文件里。另外说下zsh,我设置了hist_ignore_space选项,所以当查找密码时我在命令行最开始输入个空格,这样 zsh 就不会把这条命令写到命令历史里。

找了下,还真发现了两个包含密码的文件(其中之一 base64 过,另一个直接明文。。。)。我决定把它们转移到其它目录下,所以要删除这些文件。同时我意外地发现,有些提交中我引用了之前的提交,比如“(after xxx) fix xxx”这种。重写 git 历史后这些提交的 sha1 值会改变,所以这些提交信息也要重写。最开始我想把提交 sha1 修改为重写后的值,后来发现有点麻烦,得通过提交 sha1 查询一个备份中的提交信息(如果不事先保存相关信息的话),然后再通过提交信息查询重写后的提交的 sha1 值,还不知道 filter-branch 时能不能查询历史,于是作罢。还好这个仓库中只有一个这样的提交,所以我直接修改成~n表示引用第 n 次前的提交算了。最后,整个命令出来了:

git filter-branch --tree-filter 'rm -rf files_to_remove' --msg-filter '
sed s/d101601/~8/
' --prune-empty -f HEAD --all

命令挺复杂的,所以我是调用 Vim 写好的,然后在一个 clone 出来的仓库里先试运行。先解释下各个参数:

  • --tree-filter表示修改文件列表。
  • --msg-filter表示修改提交信息,原提交信息从标准输入读入,新提交信息输出到标准输出。
  • --prune-empty表示如果修改后的提交为空则扔掉不要。在一次试运行中我发现虽然文件被删除了,但是还剩下个空的提交,就查了下 man 文档,找到了这个选项。
  • -f是忽略备份。不加这个选项第二次运行这个命令时会出错,意思是 git 上次做了备份,现在再要运行的话得处理掉上次的备份。
  • --all是针对所有的分支。

试运行了几次,看到 150 多次提交逐一被重写,然后检查下,发现要删除的文件确实被删除了。于是高兴地到 github 建立新仓库,把脚本上传了。仓库名叫winterpy,因为网友 Vayn 建议我用 summerpy,而我更喜欢冬季 :-P

折腾完毕,我更加喜欢 git 了 :-)

Category: 版本控制 | Tags: python Git
4
19
2011
3

Vim的Python3有内存泄漏?继续修正!

给Vim的Python3支持打了个补丁,发到邮件列表上只有Bram表示希望有人来测试就没有下方了。于是,这么久了,这个补丁的内存泄漏问题一直未被发现,直到看到蓝色基因的这篇文章。花了一个下午,发现我原来的补丁不仅没有修正本来就有的内存泄漏,反而雪上加霜,浪费了更多的内存。现在终于弄好了,放在我的陈列室里了,同时还莫名其妙地修正了另一个小问题

既然是内存泄漏,我首先想到的是valgrind这个工具。于是跑了一下:

valgrind --leak-check=full --show-reachable=yes vim

在开启的 Vim 中我 source 了蓝色基因的测试脚本:

lcd %:h
tabedit tmpbuffer
setlocal buftype=nofile
 
python3 << EOF
for i in range(3):
    flines= ['x'*200] * 50000
    vim.command("%s+\\_.*++g")
    for fl in flines:
        vim.current.buffer.append(fl)
    del flines[:]
EOF

整个过程CPU占到100%,而且运行速度极慢,内存消耗也非常多。最后Vim终于按我的指令退出时,valgrind刷屏了大约十几秒钟!而其间我看到除了Python的字样外,还有不少rb的字样。难道Ruby支持也有类似的问题?不过我不管它。重新编译了个只有--enable-python3interp选项的 Vim,这回跑起来快了一些,也没有那么多不相干的内存泄漏了。我也学聪明了点,把信息重定向到文件:

valgrind  --leak-check=full --show-reachable=yes src/vim 2> log

这样可以方便地在log中找“if_py”字符串了。可惜我弄的时候没想到自己会来写博客,所以log文件并没有保存。。。

首先我找到了DoPy3Command这个函数,valgrind说它里面分配的内存没有被释放。这里边的PyUnicode_AsEncodedString这块是我加的:

    /* PyRun_SimpleString expects a UTF-8 string. Wrong encoding may cause
     * SyntaxError (unicode error). */
    cmdstr = PyUnicode_Decode(cmd, strlen(cmd), p_enc, NULL);
    PyRun_SimpleString(PyBytes_AsString(PyUnicode_AsEncodedString(cmdstr, "utf-8", NULL)));

然后我能怎么办呢?当然是查Python的文档了。于是注意到文档上说PyUnicode_AsEncodedString返回的是新的引用。又去看官方教程上的示例,才知道如果一个API返回了新的引用,那么用完后应当手动Py_XDECREF!就像是strdup函数,它内部帮你malloc了,你自己用完后要记着free掉。(Py_XDECREFPy_DECREF的差别是,前者可以传NULL。)

于是就改吧,所有通过PyUnicode_AsEncodedString得到的对象都要Py_XDECREF下。为此,不仅需要临时变量来存储这个对象,更让我郁闷的是,在两个Python版本共有的函数StringToLine中有这样一段代码:

    str = PyString_AsString(bytes);
    len = PyString_Size(bytes);

这里的两个函数/宏我之前是这样定义的:

#define _PyUnicode_AsBytes(obj) PyUnicode_AsEncodedString(obj, p_enc, NULL)
#define PyString_AsString(obj) PyBytes_AsString(_PyUnicode_AsBytes(obj))
#define PyString_Size(obj) PyBytes_GET_SIZE(_PyUnicode_AsBytes(obj))

这下我没辙了,只好又改了if_py_both.hif_python.c文件,加了两个宏:PyString_AsBytesPyString_FreeBytes。它们在 Python2 的代码中什么也不做,但是在 Python3 的代码中用来保存和释放中间对象:

#define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, p_enc, NULL);
#define PyString_FreeBytes(obj) Py_XDECREF(bytes)
#define PyString_AsString(obj) PyBytes_AsString(obj)
#define PyString_Size(obj) PyBytes_GET_SIZE(bytes)

有人说,if it ain't broken, don't fix it。可是,虽然问题只出在 Python3 部分,我还是得改 Python2 部分,感觉很不爽。

这样改完,再次反复运行测试代码,结果不遂人愿,依旧泄漏了不少内存。于是继续valgrind,又找到这里:

    static void
BufferDestructor(PyObject *self)
{
    BufferObject *this = (BufferObject *)(self);

    if (this->buf && this->buf != INVALID_BUFFER_VALUE)
	this->buf->b_python3_ref = NULL;
}

然后再次查教程中的示例:

static void
Noddy_dealloc(Noddy* self)
{
    Py_XDECREF(self->first);
    Py_XDECREF(self->last);
    Py_TYPE(self)->tp_free((PyObject*)self);
}

再看看 Python2 部分的代码,在相应的函数里有Py_DECREF,于是把这示例的最后一行给BufferDestructor以及WindowDestructorRangeDestructor加上。再测试,内存不再消耗100多M了,反复source也不会继续增加,于是作出结论:Vim 的 Python3 支持部分没有已知的 bug 了!

做完这一切,我只想说:Vim 这 Python3 支持也太 broken 了吧,中文经常乱码就算了,vim.error不能用我也忍了,竟然还内存泄漏!难道写这个代码的人也是初学Python C API啊?

不过抱怨归抱怨,还是很感谢原作者的,不然我连修正都不可能。不过,patch 弄好也提交了,却一直没人理我,原作者难道是一时兴起才写的、然后就消失了?

最后,补丁现在放到陈列室了。

Category: python | Tags: vim python C代码
4
16
2011
10

换火狐4了

既然决定换 Arch 了(虽然至今仍未换过去),终将放弃火狐3.6,于是终于地,我用上了火狐4。我的火狐4是从这里下载的国际版。一直很不喜欢中国版的火狐。

之所以没在第一时间使用火狐4,除了插件兼容性的担心外,我还很不喜欢火狐4的UI。标签栏和状态栏学Chrome、菜单学Opera就算了,打开附加组件栏后这算什么啊?下边明明有那么多的空间,状态栏非要浮在它上面!

对于自己的配置,我一向很保守,因此,我启动火狐4的命令是:

~/soft/firefox/firefox -P --no-remote

创建了一个新的 profile。我并没有把之前的 profile 复制过去,因为我觉得用了好几年的配置,是时候清理下了。

我先是尝试了下Pentadactyl这个vimperator的新分支,很快就放弃了,直接原因是,我没有找到能够用的使用拼音的 hint 插件。我可不想为了 follow 一个全中文的链接而伸手去按数字,不方便。根本原因还是不习惯 hint 这种方式,不想放弃自己已经养成的并没有任何明显问题的习惯。

于是再创建一个 profile,开始逐个安装自己要的插件。还好重要的插件都支持火狐4。弄完时安装了40个插件,一个炫彩风格。其中有一个插件是我不再留恋火狐3.6的重要原因——Status-4-Evar。我就知道喜欢火狐以前的状态栏的不止我一个,果然已经有了现成的插件。而且,这个插件还包含了Fission的功能——地址栏进度条,虽然填充的时候把地址栏的边框给遮住了。

最后,还有五个插件我想要,但是不支持火狐4:

  • Link Status,在状态栏显示链接是否已加为书签,以及如果访问过,上次访问的时间
  • FireRainbow,Firebug 的脚本高亮
  • CacheViewer,查看缓存文件的。除了从缓存中找媒体文件外,我还用它来删除因非正常关机等原因导致坏掉的缓存文件
  • History Submenus,将历史记录菜单按天分成子菜单
  • MR Tech Toolkit,增强附加组件管理页面,包括导出列表等

另外,还遭遇了一个bug:在安装若干插件后,打开附加组件管理页面,会停止响应,从 strace 的信息来看是死锁了。不过既然是新版,只出了一个bug还是比较好理解的。想当初,刚转到Linux下的时候,那个火狐各种崩溃……至于配置插件,对于没有在附加组件栏之类的地方提供打开“选项”对话框的插件,只好看它的源码然后像这样访问啰:

chrome://imagetweak/content/prefs.xul
chrome://textlink/content/pref/prefDialog.xul

火狐4新增的标签页分组功能很好用,可以把与当前工作不相关的网页放到另外的组,以免像Chrome那样让标签页挤满标签栏,所以Tree Style Tab也不需要了。而且,当一个分组里的标签页太多而分组占用的区域很小的时候,火狐也处理得很好。注意到截图下方中央有个按钮,点一下就会弹出一个大的区域,展示被“叠放”在一起的标签以便操作。在分组管理界面中也支持中键关闭、双击新建,那些功能很明显的按钮我就不说了。不过我在想,如果它支持Awesome或者Subtle那样的平铺,再加上多个工作区(或者边界不局限于窗口边界),那样就更好了。

最后要说一下的是,火狐原先位于地址栏的RSS订阅按钮没了,说是用的人少,不想让它占地方(Orz....)。办法有二,要么点“书签”按钮,然后在下拉菜单里找,要么定制工具栏,拖个RSS图标到工具栏上,并不能放到地址栏里。而且这样的话,即使网页没有提供RSS功能,RSS图标依旧显示,这才是真正的占用宝贵的空间呢!


2011年4月29日更新:

今天火狐提示尽快升级到 4.0.1。升级之后,附加组件管理页面终于恢复正常了!

Category: 火狐 | Tags: 火狐
4
12
2011
8

Google 字典大降级

2011年4月13日更新:

今天Google字典又回来了。而且我确认过了,昨天不是4月1日。Google这是技术故障?

2011年8月8日更新:

今天,Google 字典再一次消失了。。。


今天打开火狐时惊讶地发现,我一直打开着的“Google字典”标签被一个搜索“字典”的Google搜索页替换了。又看到书签工具栏上少了几项,我以为这也是火狐的bug,重启之,书签工具栏正常了,但还是没有Google字典。使用“关键字搜索”打开一个新网页,看到 URL 从https://www.google.com/dictionary跳转走,才知道坏了。

是的,Google 字典已经降级为Google搜索了!cnbeta也有报道。Google搜索有查字典的功能这我是早就知道了的,但是我觉得并不好用。不过查一个不认识的词嘛,有必要开个标签进行一次完整的搜索么?Google字典我之前也不用,因为“清除之前的输入(这会覆盖选择区的内容)-> Ctrl-V 或者如果没Ctrl-C过就回到原网页选中单词再回来中键粘贴 -> 点击搜索或者按回车键”这个流程太麻烦了,这通常需要2次键鼠切换、4次按键、1次鼠标点击。而使用关键字搜索每次都得打前缀,然后中键粘贴,然后按回车,鼠标键盘切换好几次也很是不方便,所以我一直使用的是Dict.CN或者是后来因为Dict.CN速度变得太慢而改用的沪江词典的划词小书签,虽然每次用的时候还得点个书签,然后等待会儿,但还是比较方便的。

后来看到这个Super Google Dictionary 2 GreaseMonkey脚本,经过自己的修改,让查词便捷了很多:选中要查的词 -> 转到Google字典标签 -> 在输入框点击左键清除之前的输入 -> 点击中键粘贴要查的词,稍等片刻,结果就出来了。总共三次鼠标点击

一直觉得这样是除了写(或者装)火狐插件之外可能的最快捷的查在线词典的办法了,可是今天,Google字典降级,Google 在 Chrome 浏览器之后再一次用行动证明他们某些设计的脑残。(关于 Chrome 浏览器的脑残之处我有时间整理好了再写。)

Category: 网络 | Tags: google 词典

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com