All Stories

也晒下我的Firefox扩展

  看到有人晒他用的Firefox扩展,想想自从我走出学校以来,就开始用Firefox,已经4个年头了,也晒下我用的扩展,Firefox如果不用扩展,还真是连IE都不如呢!   Adblock Plus,这个几乎是所有装了Firefox后都会装的扩展吧,我当年是过了好久才反应过来,用Firefox确实很少弹出各种广告窗口哦,全靠它了。   接上,有个同事后来跟我说,有个小NoScipt的东东,很霸道,我试了,果然把每个页面上的一堆脚本都禁了,确实从事实上到心理上,都更安全了。   AutoPager这是个国人做的扩展,可以自动把下一页的内容接到本页下方,造福了我这种懒人,看论坛可以一滚到底,当然我最开心的是用它来在线看小说,几百章也可以拼成一页,好壮观!   AutoProxy翻墙利器,不想花钱用VPN,只能用Tor之类的免费方案,但又难忍它的龟速,当然要把白名单里的网站剔除掉了。   Echofon似乎是个不翻墙也可以用twitter的方案,功能一般吧,有时候还自动登录不了,界面也不好看,还不能自动缩短网址。   FireGesture好像是Firefox中最流行的鼠标手势扩展吧,其中有一个版本用着很不顺手,好在过了没多久升级后,又顺手起来了。现在用鼠标手势操作浏览器大概是非菜鸟的必备技能吧。   接着是一组扩展合用,为了让Firefox的界面像Chrome那样,主要是先装个第三方Theme叫Chromifox Extreme,然后是扩展Chromifox Companion,这样可以让Firefox的Tab,工具栏,地址栏的背景色,位置等跟Chrome比较想像,然后是装Hide Caption和Hide Menubar把标题栏和菜单栏都隐藏起来,这样至少跟Chrome有九分像了!   比较有意思的是Google Redesigned扩展,可以把Google Reader、GMail、Google Calendar的默认界面替换掉,嗯,我就是个换肤论者,就是想试试不同的界面!还有个Integrated Gmail,可以在Gmail的web界面中又同时显示当前账号的Google Reader以及Google Calendar内容,对于gfan来说也是值得试用的,一个入口多种服务嘛!   Weave Sync可以将书签、浏览历史、密码和Tab信息保存到远程服务器上,不过我是没什么大用,因为我基本上只在我自己的机器上用,而且Firefox也被我用命令行的方式重新指定了用户数据的目录,所以直接备份也不麻烦。   除了这些,还有什么QuickDrag呀,Tab Mix Plus呀,UnMht呀,CoolPreviews呀,Coral IE Tab呀,Flagfox呀,Shorten URL这些扩展,平时装着也是装着,用得不多,但偶然想到时若没有这些功能,又会觉得有点儿不舒服,姑且留着吧!

上牌记

  买车已经一个多月了,还没有上牌,如果早知道买个车有这么多烦人的事情,我真的得考虑一下这个付出是否值得,本来想有个车,是为了方便,结果到目前为止,有的更多的是,则是烦心!   今天去绍兴上牌,起了个大早,嗯,辞职以来还没这么早过!匆匆忙忙吃过早饭,赶到4S店里。等了一会儿,售车的小姐说了相关事项后,我就先出去加油了,毕竟到绍兴有不近的路呢。结果加完油出来,明明我横插着已经过马路一半了,有辆车硬是从我前面飞过,结果擦到了!那车都没看清,就直接跑掉了。我就下了车看了看,心疼加恼火啊,一新车,连牌都没上,已经有两处被擦坏了!如果有一天让我遇到那个人,我tmd撞死他!   后来也没听到什么说话,上牌的车队一声不吭就开走了,我还以为不是我要跟的队,傻乎乎地等了一会儿,就打电话给带队的人,结果说就是那队车,郁闷了,我连路都不认识,只好沿着大路追上去,一直没追上,倒是自长训后,第一次飚快车,当然其实没上100码的。   带队的人结果只好在一个要拐弯的地方等着,他却开得更快,大概是为了追前面已经去的车队吧。不过这也有好处,至少让我明白一个事,车子在高速的情况下,确实很难刹住的。路上看到一队大客车,同一款同一色,也是去上牌的,真壮观呀!   好不容易到了车管所(?),好多车排除,现在买车的人果然多了,唉!想起那些人,一方面叫嚣着要劝人们出门多坐公交,少开私家车,一方面却仍做着那些不经过大脑的事情,就说我们地的公交车吧,已经稀疏地半个小时一趟了,还会不时地有翘班的,除了这些,有很大杀伤力的是,有个严禁超载的规定,一辆中巴能坐几个人呀,不到20吧,往往在那等几个小时也上不了车,这大冷的天,或者以后大热的天,不逼着人省吃俭用自己买车吗!   再扯回话题,好多车,慢慢排进去,几分钟才会移一个车位,过了不知道多久多久,终于到了车检了,我还真有点慌如果让我自己过那条道的话,呵呵。车检过了后,绕到后面,然后就是无休止的等待,排了个号,前面还有37个人,到12点时,前面还有18个人。出去走了快半个小时的路,找到一个地方吃快餐,好咸的大排!然后又走回去,要到1点半才开始下午的,无所事事地等了半个小时,开了门又无所事事地不知道等了多少小时,好不容易认证好手续。   最后是最重要的选号,嗯,这里我又算是被忽悠了!原来这里是分两种的,但是没人跟我说过!一种是八选一,一种是个性号码。八选一的话,当场可以拿到牌,我不知道啊,只是乐呵呵地报了个号,结果就成个性号码了,还得再等三四天他们寄过来!这其实也没多少个性,本来还想选2216,就跟家里的电话号码一样,结果2215和2217都有,就唯独没2216,唉!选好号码后,带队的人问临时牌照到期没有,是否需要再打印一张,一张5块钱!我艹,怎么以前就不知道有这回事,以前的临时牌照都是4S店里卖我车的那个女人跟我打的,我连忙打回电话去问,居然说需要再打一张,我说那你再帮我打一张不就得了。她说,一辆车只能打三张,我以前已经领完了!这明显是他们的问题啊,当时就是他们说等几天就可以在上虞上牌的,我才一拖再拖,搞得现在连3张临时牌照都用完了,而且我事先还不知道有这规矩!我实在是比较愤怒,以后再买车,绝对不会再去那家店了!   另外,我还得强烈谴责一下那些电视剧和小说,上面怎么全都是直接跑到4S店里,交了钱后什么手续都办完了的,完全是欺骗观众和读者啊!   就当吃一堑,长一智了。这辆起码车,就当是学费了。下一个目标:3到5年后,换个60到80万级别的车。

慢工出细活

  我决定,不再盲目赶进度了!   一直以来我都处于一种奇怪的紧张赶进度的状态,每个月都想着能在当月或下月底前release一个可用的版本出来,于是为了达到这个目的,又由于实现中的各种未预期的状况出现,一项又一项的特性被我临时决定砍掉,或拖延到以后版本中实现。   所谓慢工出细活,现在我决定,不这么着了!对于那些基本特性,还是要花时间仔细实现的。所谓基本特性,就是别的大部分同类都有这些特性,假如没有这些特性,用户就会感觉到不习惯甚至诧异。这些基本特性有着这样的定位:在第一个版本应该实现大部分,而且以后版本的维护工作量很小。   对于要缩短每个版本的开发周期,我觉得砍掉特性或安排特性在不同版本实现,是必然可以采用的策略。而只有那种本产品特有的,有极高技术难度的,或单纯为了推广策略而需要分步推出的特性,才可以这样做。   嗯,今天要实现中断构建过程和在文件中查找替换的功能,希望不会有太多困难。

支持自动编码检测与转换

  大清早的,被老妈叫起,驱车去4公里外的集市吃早餐。要了一客小笼包子,一碗馄饨,说起来从上大学开始这八九年来,还真很少吃得到这样的早餐。上学的时候嫌贵了,工作了之后就一般只在公司食堂里吃,周末虽然在家,但都睡过去了。偶尔为之,真是享受啊!   昨天突然想起,我的编辑器只能打开ANSI格式的文件,如果是Unicode,UTF-8之类的文件,打开是一片空白的,于是想改一下吧,打开时检测一下文件头部的BOM,用iconv转换一下再显示到编辑器。本来以为这将是很顺便的一件事情,从网上下载了Windows下可用的iconv库和头文件,最后却无奈地发现一个诡异的事情。原本至少ANSI格式的文件中的中文是可以正常显示出来的,如果用了iconv库,无论有没有进行编码转换,中文就全部变乱码了,而且显示乱码后,Scintilla就会报断言失败,然后整个程序就崩溃了。最后我不得不相信,这应该是iconv与wxWidgets或Scintilla配合有问题,至于到底是什么问题,我就不深究了。   没了iconv,于是我只好转投ICU门下了。还有点比较头痛,却又让我觉得解脱的一点是,我C++程序将是用MinGW编译的,而ICU当前的4.2.0.1版本曾经尝试了很久,都只能让VC编译通过,MinGW无奈地败下阵来。这就说明,我这编码转换的功能不能通过C++实现了,也省得我再费心思去琢磨到底把这个功能放在哪里实现了。Luaforge上有个叫ICU4Lua的项目,可以在Lua中使用ICU,这个库我以前也编译过,拿出来试了试,非常简单易用,只好把读取和保存文件的功能也用Lua实现成插件了。

我错了,不关iconv的事

  前面提到iconv转换编码搞得wxWidgets写成的程序在Scintilla刷新时崩溃,还以为是iconv引起的问题,于是决定使用ICU。   嗯,结果我错了,用ICU仍然有问题,有相同的问题,尽管我已经把这部分代码放到Lua中执行,对嵌入的Lua解释器,调用ICU4Lua,再调用ICU,仍然是Scintilla直接断言失败,然后崩溃,错怪iconv了!   经过一系列的尝试,最后发现只要把Scintilla的code page设成UTF-8就解决了,真是奇怪,原来设计936照理在本系统上也是正确的,它却仍把中文字符分成2,3部分显示。现在好了,连中文字符都作为1个字符显示了。另外发现,ICU的接口果然丰富呀,可以直接获取当前系统使用的code page,安逸!

小心缺省参数值

  昨天本来是想完成编译构建的特性的,结果先去搞工程树视图了,发现了好些工程树视图代码中隐藏的bug。   其中最诡异的莫过于在打开一个工程文件时,读出各个xml的DOM节点,调用另一个函数处理这个DOM节点,总是发现值为nil。搞了老大半天,把代码结构也调整了不少,最后发现是该函数本是个递归函数,在递归调用时居然少写了个参数,于是Lua就主动把后面缺的参数值赋为nil了。人都差点儿崩溃了,开始抱怨Lua不稳定,其实是人不稳定啊,哈哈。这次事件让我再次觉得,缺省参数值这个特性实在是很危险,以前在C++程序中也因为这个原因引起过问题。   在定位这个问题的过程中,还偶然发现,原来Xerces中的getElementByTagName是游走整棵树的,跟我原来的设想不一样,都是MSXML用惯了的后遗症。决定以后就只用Xerces了,无论是VC还是GCC都可以用,以后换个操作系统也可以用,现在Lua中也可以用,彻底告别Xerces,至于它保存成文件时格式不好看的问题,暂时不管它。   Xerces的文档一直没仔细看过,昨天发现,XMLString::transcode返回的字符串,用完后,要用XMLString::release释放,原来我都没这么做!

修正又一处内存泄漏

  前两天偶然发现,又有内存泄漏了。昨天仍然在写Lua脚本,于是没怎么管它,今天早上起来wc时,突然觉得这内存泄漏实在是眼中钉,肉中刺,一定要解决。   首先是发现,只有在程序中打开过文件后,才会有内存泄漏,而且泄漏的数量跟打开文件的数量似乎是成正比的。于是开始查看打开文件部分的代码,发现这部分代码实在写得太简单了,几乎不存在泄漏的机会,绝大部分函数都是立马将请求转发到Lua脚本去了,我假设Lua脚本不会出现泄漏。   于是我尝试新建一个文档而不保存,发现果然没有泄漏!这就说明泄漏可能的两个来源,一个是读写文件时,一个是根据文件类型作出不同响应时。接着,尝试打开一个txt文件,也没有泄漏,这说明第一个猜测的泄漏源不成立,那么把注意力集中在第二点上。   我先是怀疑是不是lexer相关的代码引起的泄漏。于是又用程序打开cpp文件,这是一种处于中间状态的文件,程序能认出这种文件的类型,应用相应的lexer对其着色,折叠等,但不做更多的操作。果然也没有泄漏,再打开lua文件,又有泄漏。仔细回忆了一下lua文件和cpp文件的区别,大概最有可能的两处是符号视图和代码片段视图,这两个视图在打开lua文件时是会被操作的,而打开cpp文件则没有。   这时,我先去看了一下符号视图,先把刷新视图的代码屏蔽掉。编译运行,没有泄漏。已经将范围缩小到这个函数内了,再只屏蔽添加新节点的代码,发现又有泄漏了,说明泄漏不在添加新节点的代码上。通过一段一段地屏蔽代码,直到最后发现,是我自己写的Xerces-C++的封装类在从字符串中载入xml文档后,就会有泄漏,所以可以确定问题出在这个载入函数中。   打开这个函数的代码看了看,非常简单,只有3行代码,其中第1行就new了一个对象,后面却没有任何释放的动作。在后面加了一句delete,重新编译测试,确实没有泄漏了!还有一个Lua使用Xerces-C++的绑定库,也要做相应的修改。   解决,安逸!

几个Scintilla/SciTE相关项目

  Scintilla和SciTE就不多说了,我接触到它并真正用到它,有3年多了,一直跟踪着它的最新发展。发现有几个跟它相关的项目,比如有用(有趣),值得记一下。   第一个要说的是SciTE-ru。这是个SciTE的增强版,大概作者是俄罗斯人吧,所以后面加个ru。SciTE从它本身的定位出发,并不会增加很多强悍的辅助功能,只能说是Scintilla有什么能力,SciTE便有什么功能。而SciTE-ru的出现则试图从第三方增强SciTE的不足之处,并修正了一些在Scintilla或SciTE中存在的小缺陷。如果对SciTE有爱,那么SciTe-ru则会让人觉得更有爱。遗憾的是我不在此列。   接着要说的是SciTE LaTeX IDE。这个项目在SciTE-ru的基础上发展而来,但它的定位是成为一个好用的LaTeX编辑器。作者不但在SciTE在软件包中增加了一些编写LaTeX常用的小工具,还在界面上增加了一批方便的按钮和菜单,更重要的是作者修改了Scintilla官方的LaTeX和asymptote的lexer,却没有合入到官方代码库中去。照作者的说法是修改后的lexer要求太苛刻,会破坏原有的应用程序。我是个LaTeX的初级应用者,确实使用SciTE LaTeX IDE编写过几篇文章,觉得从编辑器的角度出发,已经算是很不错了,但如果定位是IDE,则还是差得远的。   最后要说的是Sicintillua。这是个很有趣的Scintilla/SciTE的fork项目,它移除了所有Scintilla中使用C++编写的lexer,取而代之的是一个叫LexLPeg.cxx的文件,里面定义了两个lexer,分别是null和llpeg。对于各种已有编程语言lex支持都是通过外部的Lua脚本实现,所以用SciLexer原有的标准接口查询和设置的lexer都是llpeg,它又增加了两个接口用于设置直正的lexer。这个fork解决了一直以来就有的Scintilla增加lexer不方便的问题,因为有一拨人觉得,使用C++编写lexer并编译进Scintilla中实在麻烦,确实我也这么觉得,只不过我可以容忍,因为我直到现在都没有自己要添加lexer的需求。我简单地看了一下Scintillua的代码与官方CVS中的代码进行了比较,发现修改的地方不是很多,不过修改了一些接口,我不太喜欢,有可能的话,我要在Scintillua的基础上再出个修改版,能更方便地跟官方代码树进行融合。

反思自己的时间管理

  以前蹲公司时,最开始是需要每天在notes上填工作日志的,几点几分到几点几分做了些什么事,涉及到哪些人。当然,没人教过我具体应该怎么填,我只是按照自己的喜好,也许是每天下班前花些时间填一下,而且还常常忘记。而恰恰这个工作日志又是需要每周让主管审核的,我就被逮到过,主管发来邮件让我补齐落下的日志,觉得很丢脸。   后来,除了要每天填notes上的工作日志外,又多了项不定期地向主管反馈工作完成进度,是用Microsoft Project管理的。主管会发来预先已经安排过的工作项目,我们则根据实际情况填入各个项目花费的时间,再通过邮件发回给主管,主管以此来跟踪下属们的工作进展。事实是,我常常不记得每项工作到底花了多少时间,所以上报的数据估计有3成到5成是不准确的。   再后来,另外有个主管自己用Excel的VBA编写了一套宏,然后放在公共服务器上,让我们每天往里面填写内容。工作内容主管已经事先在其中已经安排好了,我们需要的只是简单地写上ok或受阻等几种简单的情况。这种日子一直持续到我换部门,后来如何我就不得而知了。   到了新的部门,首先让我觉得很奇怪的是,他们居然不用填工作日志,他们认为要求填工作日志实在是件很过分的事。一开始我还有点儿不习惯,尽管不需要再向主管反馈了,自己仍然为了证明上班时间没有偷懒而继续自得其乐地填了几个月。后来实在是因为觉得没什么实际的作用也放弃了。   后来很长一段时间处于混乱的无组织状态。直到我被派去给别的部门做一个工具时,因为各方领导对该项目的重视,要求我每天反馈进度,于是在RedMine上通过一个自研的插件,只要我每天往RedMine上填写新闻,那么RedMine就会在每天午夜时分自动将该新闻作为邮件内容发送给各个关心该项目的领导们。我在新闻上写的内容可谓五花八门,每天遇到什么问题,如何定位bug,如何作出技术抉择,发布日期又要跳票了等等,觉得很开心很安逸,这才是比较适合我的方式。这个项目我一直做了一年半,然后又交给其他同事,我则被调回做其他项目。   调回后,项目组中又开始尝试敏捷和迭代开发,主管倒是做过一些努力,结果仍然是无序的。这样的无序状态我一直经历了半年多点,直到辞职。其间最常用的办法是,把最近一天或几天内要做的事一条一条写在笔记本上,然后完成一条就在上面划掉一条。事后回顾,也是很有成就感的事情。   这里牵扯到一个问题,说大了,是项目管理,说小了到个人,则是时间管理。以前看到过有人说,某老外的时间管理可以精确到一刻钟。当时是没有多少想法的,只是觉得这样细化的计划或回顾可能价值不大。   这几月来在家写代码,一直以为自己一天十几个小时都扑在电脑前了,应该产量很高吧。直到昨天偶然在网上找到一个叫Manic Time的免费小软件,可以记录下每天使用各个软件的时长。今天看了一下,才猛然发现,我这一天,花在编码上的时间竟然不到2个小时!真是触目惊心的数据啊,我实在是太堕落啦!   我需要好好反思!