从 Subclipse 到 Subversive: 第一印象

部分翻译自:Switching from Subclipse to Subversive: First Impressions

译者注:虽然是翻译的,但基本上和我现在的状态比较吻合。

对于个人的项目,我已经彻底转换成用 Git 来做版本管理。而工作中我不得不继续使用 Subversion 以便团队的每个人都能共享。我不是说 Git 不好用,只是我的团队还没有准备好这种转换。

我对采用 Git 作为 Subversion 的客户端使用的前景极其好奇——我知道这不是很难——然而我还没有在工作这么重要的场合尝试的勇气。我不能承受万一出什么问题。因此到目前为止我依然使用原生的 SVN 作为我的客户端。

最近我决定尝试一下 Subversive 。我刚开始使用 Subversion 的时候是用的 TortoiseSVN 。后来我开始用 Eclipse 和 CFEclipse 进行开发,(经过少许调查发现)似乎很多人认为 Subclipse 是更好的客户端。所以近几年我一直在用这个。

我本人和至少一个使用 Subclipse 的合作者碰到一些问题,我们认为是 Subclipse 特有的。我们经常将项目 checkout 到共享的目录里。有时候会出现顶层目录无法 commit 的状况,有时选择不同目录的若干个文件后也不行。这很令人恼火。命令行工具就没问题,如果IDE集成环境也能正常使用就好了。

这就是我为何要尝试新的工具。不仅因为 Subversive 是 Eclipse 的官方子项目(这是很好的认可),而且我还听到不少人的称赞。我要弄清楚当初选择 Subclipse 是不是正确的决定。

速度

我的第一印象是 Subversive 好快。我没有做过并列对比,但主观上用它浏览很大的仓库的时候非常快。checkout 看上去也很快。

管用吗

这是我决定要不要转换的重要原因。回答简单而干脆:管用!目前我还没有碰到在 Subclipse 中出现的问题。

快捷键

Update? Ctrl+Alt+U
Commit? Ctrl+Alt+C
与仓库的最新版本比较? Ctrl+Alt+L

有缺点吗

实际上,有。从 Eclipse 的更新站点安装完客户端之后,还得再装另外一样东西的做法很是让人纳闷。似乎开始装的只是个框架,当我第一次使用的时候它提示要装个 connector ——而 Subclipse 一次安装就搞定了。

这也许不是什么大问题。(译者:接下来是抱怨由此造成的 CFBuilder 和 Windows UAC 的苦恼。译者不感兴趣,略过。)

我推荐它吗

当然。有快捷键,速度又快。在我不能用 Git 地方就用 Subversive。

用 Javascript 批量查找 Excel 中的文字

比 Excel 的查找有下述优点:

  • 批量查找整个目录
  • 可以找到图形和文本框中的文字
  • 采用正则表达式查找,可以实现复杂的查找条件

缺点是比较慢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 设定值:分别是要查找的目录和查找条件
var searchPath = "D:/temp";
var searchPattern = /事業/i;
 
// 正则表达式参考:
//http://msdn.microsoft.com/en-us/library/1400241x(VS.85).aspx
//http://msdn.microsoft.com/zh-cn/library/28hw3sce(VS.80).aspx
 
var msoAutoShape = 1
var msoGroup = 6
 
var xlApp = WScript.CreateObject("Excel.Application");
xlApp.Visible = true;
xlApp.Interactive = true;
var logBook = xlApp.Workbooks.Add(); // For Output
var logSheet = logBook.Sheets(1);
var logLine = 2;
var outSheet = logBook.Sheets(2);
var outLine = 2;
 
var allFiles = new Array();
var fso = new ActiveXObject("Scripting.FileSystemObject");
 
GetFileList(searchPath, allFiles);
 
var i;
for (i = 0; i < allFiles.length; i++) {
  logSheet.Cells(logLine + i + 1, "B").Value = allFiles[i].name;
  logSheet.Cells(logLine + i + 1, "B").NoteText (allFiles[i].path);
}
 
for (i = 0; i < allFiles.length; i++) {
  xlApp.StatusBar = (i + 1) + '/' + allFiles.length + ': ' + allFiles[i].name;
  ProcessFile(allFiles[i], i);
}
 
xlApp.StatusBar = 'done.';
 
function GetFileList(folderspec, arr) {
  var f = fso.GetFolder(folderspec);
  var fc = new Enumerator(f.SubFolders);
  for (; !fc.atEnd(); fc.moveNext())
    GetFileList(fc.item(), arr);
  fc = new Enumerator(f.Files);
  for (; !fc.atEnd(); fc.moveNext()) {
    var fo = fc.item();
    if (fo.Name.match(/.xls$/i))
      arr.push(fo);
  }
}
 
function ProcessFile(fo, lineNo) {
  crtLogLine = logLine + lineNo;
  logSheet.Cells(crtLogLine, "A").Value = "WORKING...";
 
  xlBook = xlApp.Workbooks.Open(fo.path, false, true);
 
  outSheet.Cells(outLine, "A").Value = fo.Name;
  var j;
  for (j = 1; j <= xlBook.Sheets.Count; j++) {
    outSheet.Cells(outLine, "B").Value = xlBook.Sheets(j).Name;
    SearchCells(xlBook.Sheets(j));
    SearchShapes(new Enumerator(xlBook.Sheets(j).Shapes));
 
  }
  xlBook.Close(false);
 
  logSheet.Cells(crtLogLine, "A").Value = "DONE";
 
}
 
function SearchCells(sht) {
  var i, j, ur;
  ur = sht.UsedRange;
  sht.Activate();
  for (j = 1; j <= ur.Rows.Count; j++) {
    sht.Cells(j, 1).Select();
    for (i = 1; i <= ur.Columns.Count; i++)  {
      if (sht.Cells(j, i).Value)
        if ((sht.Cells(j, i).Value + "").match(searchPattern)) {
          outSheet.Cells(outLine, "C").Value = sht.Cells(j, i).Address;
          outSheet.Cells(outLine, "D").Value = sht.Cells(j, i).Value;
          outLine++;
      }
    }
  }
} 
 
 
function SearchShapes(en) {
  for (; !en.atEnd(); en.moveNext()) {
    var shp = en.item();
    switch(shp.Type) {
    case msoGroup:
      SearchShapes(new Enumerator(shp.GroupItems));
      break;
    case msoAutoShape:
      if (shp.TextFrame.Characters().Text) 
        if (shp.TextFrame.Characters().Text.match(searchPattern)) {
          outSheet.Cells(outLine, "C").Value = shp.Name;
          outSheet.Cells(outLine, "D").Value = shp.TextFrame.Characters().Text;
          outLine++;
      }
      break;
    default:
      break;
    }
  }
 
}
// 对付控件工具栏上的 TextBox:
// sheet.Shapes("TextBox1").DrawingObject.object.Text

用法:把这个文件存为.js文件,修改好参数之后直接双击即可。
查找的结果保存在新建的 Excel 文件的 Sheet2 里。
等的不耐烦的时候可以直接关掉 Excel, 它会自行报错退出。

Chrome 的两个缺点

慢慢习惯使用 Google Chrome 作为默认浏览器了。特别喜欢下载东西时的那个动画效果 (我看东西只看表面 :P)。这段时间发现其两个缺点,或者说设计得不够人性化的地方:

1. 全屏幕的时候看不到 Tab。这个及其不爽,只能用 Ctrl+Tab 抹黑切换。不如 Firefox 和 IE8。(Safari就不用说的,人家根本就没有全屏模式。不知道笔记本的屏幕小啊……)

简单的一句 “Exit full screen (F11)”  有点太把人当傻瓜了。

chrome-2

2.  Tab 的关闭按钮的位置不合理。当 Tab 比较多的时候,很容易不小心按到。这一点也是笔记本特有的吧,现如今的台式机鼠标多半都应该较精确了。

Firefox、Safari 全是这样的。我印象中Maxthon好像是把关闭放在右上角的,开始我还很不习惯,现在明白这样设计的好处了。

IE8 有点不同: 只有当前的Tab才有关闭按钮。当然,这样又有另外一个缺点:每关闭一个其他窗口,都得按两次鼠标。有得必有失呵。
chrome-1

Synergy: 用一套鼠标键盘操作多台电脑

Synergy 是一款能够让使用者仅用一套键盘鼠标,就同时操控多部计算机的免费工具软件。使用者能够在包括 Windows 、 Linux 、 Mac OS 等不同的系统上安装它,并且在设定好主从关系后,就能够透过一组键盘鼠标来进行多部计算机的操控。
这样子的操控方式,对于拥有笔记型计算机的人来说尤其方便,你能够将笔记型计算机与家中的桌上型计算机设定好主从关系,如此一来,就能够利用笔记型计算机来操控两部计算机,不需要额外的切换装置的帮忙,就能够方便地完成许多工作。
使用者在使用 Synergy 时要特别注意的是,必须要仔细设置主从关系的切换设定,如此才能够顺利地透过鼠标光标的移动来切换目前所使用的计算机,不至于因为鼠标光标一移到新计算机,就无法切换为原计算机的窘境。

http://synergy2.sourceforge.net/

似乎还没有中文主页,值得翻译推广。

Windows Live Messenger 崩溃

Live Messenger 最近一登录就出现下面的错误:

Windows Live Communications Platform 错误Windows Live Communications Platform 错误2

AppName: wlcomm.exe

AppVer: 14.0.8064.206     ModName: ro.dll
ModVer: 21.0.0.3     Offset: 0005d2f8

窗口一关掉 Messenger 就会注销。把窗口放一边的话倒是还能正常使用。

http://finalfrank.pixnet.net/blog/post/23189694 里 audrey 的留言里说的消息一样,难道是中了啥新病毒了?

于是去找这个ro.dll。在System32 里找到了这个文件。一看:

描述:RsStore module install DLL

产品名称: Rising AntiVirus 2009

公司:Beijing Rising Information Technology Co., Ltd.

而数字签名却是:Kaspersky Lab,详细信息显示该签名无效。

这东东太可疑了,删了之后清净了。不知道怎么中招的,莫名。不过总算是解决了。

刚才发现粗暴删除以后不能 telnet 了。又用 WinsockFix 修复了一下,一切正常了。

火狐的下一代–Shiretoko(知床?)

昨天打开 Firefox, 发现名字不再叫 Minefield(雷区) 了。看来雷区快步入稳定阶段了?
新名字叫 Shiretoko 。看上去像日语,查了一下,看来应该是日本的“知床”。

知床半岛是日本北海道东北部的一个半岛。上有知床山脉,海岸多断崖。

【知床半島】北海道北東部、オホーツク海に突出する半島。先端は知床岬。知床岳・羅臼(らうす)岳などの火山を中心とする山脈が中央部を走り、海岸は断崖が多い。

Shiretoko / Gecko 1.9.1 Alpha 1引入的新特性:

Shiretoko / Gecko 1.9.1 Alpha 2 引入的新特性:

12.08 更新:纠正我一个错误,不能说 Minefield 变成了 Shiretoko。实际上应该说 Shiretoko 是 Minefield 的一个新分支(即3.1,就像 3.0 叫做 Gran Paradiso)。而 Minefield 是trunck,永远是最新的。

Vim 笔记

关于 \t 和 \n 要注意的是,如果你要匹配它们,也就是说出现在匹配串中的时候
要写 \t 和 \n,但是如果你要替换成它们,就不应该直接写 \t \n,而要用 Ctrl+V
或者 输入一个蓝色的特殊字符。

例如:
:s/\n/ABC^M/g
:s/\t/^T^T/g

而下面两个写法都是不对的:
:s/\n/ABC\n/g
:s/^T/^T^T/g