转自:http://blog.csdn.net/tony821224/archive/2008/09/26/2982685.aspx
在Source Insight中添加自定义功能的步骤如下:
1.Source Insight中,Options->Custom Commands...->Add...,New Command name 随便写,我的是"Edit with Vim"
2.Run中写入: "C:/Program Files/Vim/vim63/gvim.exe" --remote-silent +%l %f
意思是在当前已经打开的gvim窗口里面打开当前的文件,并且跳转到指定行
%l为当前的行号,%f为文件名
使用 --remote-silent 的作用是,如果已经打开了对应文件,就不会打开第二次,而是在已经打开的文件里跳转到对应行
3.还是同一个对话框里面,选择Keys->Assign New Key...->按F12,如果你已经将F12设置给其他命令,选择其他的按键就行了
下面是一些常用自定义功能:( CUSTOM COMMANDS )
打开资源管理器并选中当前文件
ShellExecute open explorer /e,/select,%f
查看log
"C:/Program Files/TortoiseSVN/bin/TortoiseProc.exe" /command:log /path:%f /notempfile /closeonend
diff
"C:/Program Files/TortoiseSVN/bin/TortoiseProc.exe" /command:diff /path:%f /notempfile /closeonend
取得锁定(check out)
"C:/Program Files/TortoiseSVN/bin/TortoiseProc.exe" /command:lock /path:%f /notempfile /closeonend
提交(check in)
"C:/Program Files/TortoiseSVN/bin/TortoiseProc.exe" /command:commit /path:%f /notempfile /closeonend
更新(update)
"C:/Program Files/TortoiseSVN/bin/TortoiseProc.exe" /command:update /path:%f /notempfile /closeonend
更新整个目录(update all)
"C:/Program Files/TortoiseSVN/bin/TortoiseProc.exe" /command:update /path:*.* /notempfile /closeonend
取消锁定(undo check out)
"C:/Program Files/TortoiseSVN/bin/TortoiseProc.exe" /command:revert /path:%f /notempfile /closeonend
在ultriEdit中编辑
"C:/Program Files/UltraEdit-32/uedit32" %f
在vim中编辑并定位到当前行
"C:/Program Files/Vim/vim63/gvim.exe" --remote-silent +%l %f
汇总其他小技巧:
让{ 和 } 不缩进:
Options->Document Options->Auto Indent->Indent Open Brace/Indent Close Brace
hao space: SourceInsight 小技巧
1、按住"ctrl", 再用鼠标指向某个变量,点击一下,就能进入这个变量的定义。
2、今天把一个用sourceinsight排版整齐的C文件,偶然用VC打开一看,全乱了。研究了半天,发现SI对每个字符的宽度不太一致。
请教同事发现选上"view --> draft view", 就可以让每个字符的宽度一致了。快捷键是 "Alt + F12"
3、"shift+F8" 标亮所有文本中光标所在位置的单词
4、跳到某一行:"ctrl + g"
Source Insight是阅读和编写代码的好东东,基本上也算得上是经典之作了,虽然还有一点点小bug,不过对于我们这些C程序员来说可是一旦拥有别无所求。下列小技巧是在工作中同事整理总结的,对提高工作效率多少有点帮助,其中有些是对应于SVN的,没有使用SVN做版本管理的人就不要白费力气了。
ShellExecute open explorer /e,/select,%f
/*作用是在资源管理器中打开当前编辑文件并选中*/
/*可以设置快捷键如ctrl+e,这样能很方便的在资源管理器打开对应的文件,并进行tortoiseSVN的相关操作*/
X:/Progra~1/TortoiseSVN/bin/TortoiseProc.exe /command:log /path:% /notempfile /closeonend
/*使用前注意更改对应的bin安装路径*/
/*作用是直接查看当前文件的svn log*/
/*可以设置快捷键如ctrl+l*/
X:/Progra~1/TortoiseSVN/bin/TortoiseProc.exe /command:diff /path:% /notempfile /closeonend
/*使用前注意更改对应的bin安装路径*/
/*作用是直接查看当前文件和基准版本的比较*/
/*可以设置快捷键如ctrl+d*/
在Source Insight中快速添加注释
将以下代码保存成Utils.em,详细使用说明看文章结尾
/* Utils.em - a small collection of useful editing macros */
/*-------------------------------------------------------------------------
I N S E R T H E A D E R
Inserts a comment header block at the top of the current function.
This actually works on any type of symbol, not just functions.
To use this, define an environment variable "MYNAME" and set it
to your email name. eg. set MYNAME=raygr
-------------------------------------------------------------------------*/
macro InsertHeader()
{
// Get the owner's name from the environment variable: MYNAME.
// If the variable doesn't exist, then the owner field is skipped.
szMyName = getenv(MYNAME)
// Get a handle to the current file buffer and the name
// and location of the current symbol where the cursor is.
hbuf = GetCurrentBuf()
szFunc = GetCurSymbol()
ln = GetSymbolLine(szFunc)
// begin assembling the title string
sz = "/* "
/* convert symbol name to T E X T L I K E T H I S */
cch = strlen(szFunc)
ich = 0
while (ich < cch)
{
ch = szFunc[ich]
if (ich > 0)
if (isupper(ch))
sz = cat(sz, " ")
else
sz = cat(sz, " ")
sz = Cat(sz, toupper(ch))
ich = ich + 1
}
sz = Cat(sz, " */")
InsBufLine(hbuf, ln, sz)
InsBufLine(hbuf, ln+1, "/*-------------------------------------------------------------------------")
/* if owner variable exists, insert Owner: name */
if (strlen(szMyName) > 0)
{
InsBufLine(hbuf, ln+2, " Owner: @szMyName@")
InsBufLine(hbuf, ln+3, " ")
ln = ln + 4
}
else
ln = ln + 2
InsBufLine(hbuf, ln, " ") // provide an indent already
InsBufLine(hbuf, ln+1, "-------------------------------------------------------------------------*/")
// put the insertion point inside the header comment
SetBufIns(hbuf, ln, 4)
}
/* InsertFileHeader:
Inserts a comment header block at the top of the current function.
This actually works on any type of symbol, not just functions.
To use this, define an environment variable "MYNAME" and set it
to your email name. eg. set MYNAME=raygr
*/
macro InsertFileHeader()
{
szMyName = getenv(MYNAME)
hbuf = GetCurrentBuf()
InsBufLine(hbuf, 0, "/*-------------------------------------------------------------------------")
/* if owner variable exists, insert Owner: name */
InsBufLine(hbuf, 1, " ")
if (strlen(szMyName) > 0)
{
sz = " Owner: @szMyName@"
InsBufLine(hbuf, 2, " ")
InsBufLine(hbuf, 3, sz)
ln = 4
}
else
ln = 2
InsBufLine(hbuf, ln, "-------------------------------------------------------------------------*/")
}
// Inserts "Returns True .. or False..." at the current line
macro ReturnTrueOrFalse()
{
hbuf = GetCurrentBuf()
ln = GetBufLineCur(hbuf)
InsBufLine(hbuf, ln, " Returns True if successful or False if errors.")
}
/* Inserts ifdef REVIEW around the selection */
macro IfdefReview()
{
IfdefSz("REVIEW");
}
/* Inserts ifdef BOGUS around the selection */
macro IfdefBogus()
{
IfdefSz("BOGUS");
}
/* Inserts ifdef NEVER around the selection */
macro IfdefNever()
{
IfdefSz("NEVER");
}
// Ask user for ifdef condition and wrap it around current
// selection.
macro InsertIfdef()
{
sz = Ask("Enter ifdef condition:")
if (sz != "")
IfdefSz(sz);
}
macro InsertCPlusPlus()
{
IfdefSz("__cplusplus");
}
// Wrap ifdef <sz> .. endif around the current selection
macro IfdefSz(sz)
{
hwnd = GetCurrentWnd()
lnFirst = GetWndSelLnFirst(hwnd)
lnLast = GetWndSelLnLast(hwnd)
hbuf = GetCurrentBuf()
InsBufLine(hbuf, lnFirst, "#ifdef @sz@")
InsBufLine(hbuf, lnLast+2, "#endif /* @sz@ */")
}
// Delete the current line and appends it to the clipboard buffer
macro KillLine()
{
hbufCur = GetCurrentBuf();
lnCur = GetBufLnCur(hbufCur)
hbufClip = GetBufHandle("Clipboard")
AppendBufLine(hbufClip, GetBufLine(hbufCur, lnCur))
DelBufLine(hbufCur, lnCur)
}
// Paste lines killed with KillLine (clipboard is emptied)
macro PasteKillLine()
{
Paste
EmptyBuf(GetBufHandle("Clipboard"))
}
// delete all lines in the buffer
macro EmptyBuf(hbuf)
{
lnMax = GetBufLineCount(hbuf)
while (lnMax > 0)
{
DelBufLine(hbuf, 0)
lnMax = lnMax - 1
}
}
// Ask the user for a symbol name, then jump to its declaration
macro JumpAnywhere()
{
symbol = Ask("What declaration would you like to see?")
JumpToSymbolDef(symbol)
}
// list all siblings of a user specified symbol
// A sibling is any other symbol declared in the same file.
macro OutputSiblingSymbols()
{
symbol = Ask("What symbol would you like to list siblings for?")
hbuf = ListAllSiblings(symbol)
SetCurrentBuf(hbuf)
}
// Given a symbol name, open the file its declared in and
// create a new output buffer listing all of the symbols declared
// in that file. Returns the new buffer handle.
macro ListAllSiblings(symbol)
{
loc = GetSymbolLocation(symbol)
if (loc == "")
{
msg ("@symbol@ not found.")
stop
}
hbufOutput = NewBuf("Results")
hbuf = OpenBuf(loc.file)
if (hbuf == 0)
{
msg ("Can't open file.")
stop
}
isymMax = GetBufSymCount(hbuf)
isym = 0;
while (isym < isymMax)
{
AppendBufLine(hbufOutput, GetBufSymName(hbuf, isym))
isym = isym + 1
}
CloseBuf(hbuf)
return hbufOutput
}
/*
written by yubind
*/
macro SingleLineComment()
{
szMyName = "chenjsa"
// Get a handle to the current file buffer and the name
// and location of the current symbol where the cursor is.
hbuf = GetCurrentBuf()
ln = GetBufLnCur(hbuf)
// Get current time
szTime = GetSysTime(1)
Hour = szTime.Hour
Minute = szTime.Minute
Second = szTime.Second
Day = szTime.Day
Month = szTime.Month
Year = szTime.Year
if (Day < 10)
szDay = "0@Day@"
else
szDay = Day
//szMonth = NumToName(Month)
if (Month < 10)
szMonth = "0@Month@"
else
szMonth = Month
szDescription = Ask("请输入修改原因")
// begin assembling the title string
InsBufLine(hbuf, ln+1, "/*@szDescription@ @szMyName@.xmyanfa @Year@-@szMonth@-@szDay@*/")
}
macro MultiLineCommentHeader()
{
szMyName = "chenjsa"
// Get a handle to the current file buffer and the name
// and location of the current symbol where the cursor is.
hbuf = GetCurrentBuf()
ln = GetBufLnCur(hbuf)
// Get current time
szTime = GetSysTime(1)
Hour = szTime.Hour
Minute = szTime.Minute
Second = szTime.Second
Day = szTime.Day
Month = szTime.Month
Year = szTime.Year
if (Day < 10)
szDay = "0@Day@"
else
szDay = Day
//szMonth = NumToName(Month)
if (Month < 10)
szMonth = "0@Month@"
else
szMonth = Month
szDescription = Ask("请输入修改原因:")
// begin assembling the title string
InsBufLine(hbuf, ln + 1, "/*@szDescription@ @szMyName@.xmyanfa @Year@-@szMonth@-@szDay@ begin*/")
}
macro MultiLineCommentEnd()
{
szMyName = "chenjsa"
// Get a handle to the current file buffer and the name
// and location of the current symbol where the cursor is.
hbuf = GetCurrentBuf()
ln = GetBufLnCur(hbuf)
// Get current time
szTime = GetSysTime(1)
Hour = szTime.Hour
Minute = szTime.Minute
Second = szTime.Second
Day = szTime.Day
Month = szTime.Month
Year = szTime.Year
if (Day < 10)
szDay = "0@Day@"
else
szDay = Day
//szMonth = NumToName(Month)
if (Month < 10)
szMonth = "0@Month@"
else
szMonth = Month
InsBufLine(hbuf, ln + 1, "/*@szMyName@.xmyanfa @Year@-@szMonth@-@szDay@ end*/")
}
使用说明:可以实现在sourceinsight中快速添加修改注释。
1. Project->Open Project... 打开Base工程(该工程一般在我的文档//Source Insight//Projects//Base中);
2. 搜索utils.em 里的字串"chenjsa" 改成自己的姓名
3. Project->Add and Remove Project Files... 加入宏文件(即utils.em);
4. Options->Menu Assignments 打开Menu Assignments窗口, 在Command中输入Macro, 选中要使用的宏(SingleLineComment ,MultiLineCommentHeader,MultiLineCommentEnd), 添加到合适的菜单中.
1 开胃菜-初级应用
1.1 选择美丽的界面享受工作
虽然不能以貌取人,但似乎从来没有人责备以貌取软件的。SI的华丽界面,绝对符合现代花花世界的人的审美趣味。在SI中,我们可以轻松地把各种类型关键字、变量、标志符、函数、宏、注释等定义为不同的颜色和显示方式(正体或斜体、加粗或正常、加下划线、放大显示等),总有一种方式能让我们一眼就能分辨出这个标识是什么。
1.1.1 字体选择
在SI中样式是可以被继承,如果要从根本上改变字体,最简单的方式就是直接修改根样式中的字体,因为其它样式都会由此继承而来。选择Options/Document Options页面内的Font Options中的Screen Fonts字体,即可改变根样式中的字体。SI中的默认配置为Verdana字体,是一种非等宽字体 2 ,为了使编写的代码在各种编辑器中看起来都有良好的对齐效果,这里强烈建议使用等宽字体,Courier、New Courier和宋体等都是较好的选择。
1.1.2 颜色定义
毕竟这是见仁见智的东西,所以从来没有统一的标准3。很多人并不喜欢SI提供的默认配置,那么我们就改吧。选择Options/Style Properties页面,就可以在其中修改所有样式了。选择等号(=)表示继承Parent Style,也可以选择Pick(或者ON/OFF等)去配置一个新值。这完全视乎个人喜好。
1.1.3 标识符样式选择
在与 颜色定义 一节同样的界面内即可完成此项配置。
1.1.4 背景色选择
在希望要改变背景色的窗口点击鼠标右键(假定使用的是右手鼠标 4),选择上下文菜单的 xxx Window Properties项,然后点击弹出窗口的Back Color按钮,即可修改该窗口背景色。对于SI的源码主窗口,只需选择上下文菜单的Special Window Color项即可完成背景色修改。
1.2 配置合理的默认值高效工作
1.2.1 使用合理的缩进
我始终认为最容易获得认同的是关于这个选项的配置了。选择Options/Document Options页面,点击其内的Auto Indent按钮,在弹出的Auto Indenting窗口中,默认配置为 Auto Indent Type选择Smart,且勾选了Smart Indent Options中的两个可选项,这样得到的默认缩进效果为[pre] while (1)
{
I
}
[/pre]每次都要手工去调整其缩进,其实只要把两个勾选项去掉,就可以得到[pre] while (1)
{
I
}
[/pre]何乐而不为呢?
1.2.2 显示坐标
通常情况下在窗口状态栏左下方,最会显示当前光标所在行列信息,但我总觉得不够明显,于是通常我们作如下配置: 选择Options/Document Options页面,勾选其中的Show line numbers。同时勾选其中的Show right margin,我们就可显示一条右边界,随时提醒我们是否该行代码写得过长了。
1.3 创建便捷的快捷键快乐工作
1.3.1 几个较常用的快捷键
默认情况下,SI已经定义了很多非常实用的快捷键:
- F5
指定行号,实现行跳转,在遇到编译错误的时候,能特别方便的找到出错行。 - Shift+F8
高亮显示指定标识,快速浏览标识的使用情况。 - Ctrl+鼠标点击标识
直接跳转至标识定义处。 - Ctrl+F
本文件内查找。 - F3
本文件查找结果的上一个。 - F4
本文件查找结果的下一个。 - F7
打开Browse Project Symbols窗口,快速浏览工程内标识定义。 - Ctrl+M
创建或查找书签,方便下次找回此位置。
1.3.2 自定义快捷健
选择Options/Key Assignments,在弹出的Key Assignments窗口中可自由添加自己喜欢的快捷键。比较值得推荐的有如下几个快捷键定义:
- Edit: Drag Line Down
光标当前行下移。 - Edit: Drag Line Up
光标当前行下移。 - Edit: Join Lines
当前行和下一行连接成一行。
1.3.3 更多的快捷键
如果你正好对SI的Marco语言(下文将会介绍)有研究,那么还可以定义更多有用的快捷键,比如添加文件头、函数头、注释等(下文在介绍Marco语言时会介绍如何实现)。
2 小技巧-中级应用
2.1 查找与替换
在SI中支持多种查找及替换方式,除了上文提到的文件内查找外,还支持工程范围内查找、目录查找、指定多文件查找等等。
2.1.1 查找
[list=1]
- Loopup References
我们最常用的一种查找方式是选择Search/Lookup References或按Ctrl+/组合键再或者鼠标点 R 按钮,在弹出的Loopup References窗口进行查找操作。 在Search Method中有四种可选的查找方式:Simple String、Regular Expression、 Keyword Expression和Look Up Reference。其中Simple String是最普通的查找方式,可以查找文件中出现的任意字符或字符,甚至可以查找 _upap || u 这样的字符串,但是在工程较大时,查找过程会较慢。 Regular Expression查找方式将在后面讲述正则表达时会介绍到,这里暂时按下不表。 Keyword Expression和Look Up Reference查找的结果基本相同,但是显示方式略有差异。这两种方式都是使用SI预先建立的数据库,查找起来速度相当快。但通常这种速度只对在查找标识符时有明显效果。对于像函数名,变量名等的查找,强烈建议使用这两种方式进行查找。 - Search Files
选择Search/Search Files或按Ctrl+Shift+F组合键,在弹出的Search Files窗口进行查找操作。 在File Name框中可以填入文件名或文件夹。注意当要查询的文件夹双包含子文件夹时,可以勾选Options中的Include Subdirectiories,实现对各层文件的递归搜索。 - Search Project
选择Search/Search Project,在弹出的Search Project窗口进行查找操作。操作与Loopup References几乎完全一致,它们各自保存上次搜索的配置。2.1.2 替换
[list=1] - 单文件替换
选择Search/Replace或按Ctrl+H组合键,在弹出的Replace窗口进行查找操作。在Search项目里勾选Selection则仅对当前选中的文档部分进行替换。另外如果勾选了Confirm Replacements则是逐个确认替换,否则会同时替换所有符合替换条件内容。 - 多文件替换
选择Search/Replace Files或按Ctrl+Shift+H组合键,在弹出的Replace Files 窗口进行查找操作。除了增加New框(替换后的内容)外,其余均与Search Files窗口相同,可参照查找部分的说明进行操作。2.2 列操作
虽然开篇时就说过,SI的列操作功能比较弱,但不等于没有。先按下Alt键,接着就可用鼠标进行列选择,然后就可以删除指定的列。
2.3 无名技巧
这里介绍一些小技巧,大多数情况下我们可以无视它们的存在。但如果我们知道这些,某些时候,会有效提高工作效率。
- Smart Rename
在上下文件菜单中选Smart Rename或按Ctrl+'组合键,即可弹出Smart Rename窗口。它有很强大的功能,但最便捷的使用方式是更改函数内局部变量的名字,操作只作用于函数内部,速度非常快。 - Renumber
使用Ctrl+R将弹出Renumber窗口,这个用于处理数字顺序排列的情况相当有效,比如数组下标。例如现有代码 [pre] array[0] = 1;
array[1] = 2;
array[2] = 3;
[/pre]现在要改为 [pre] array[0] = 0;
array[1] = 1;
array[2] = 2;
array[3] = 3;
[/pre]当然可以一个个修改,但最快的方式是在array[0] = 1;之前添加array[0] = 0;,然后列选数组下标,使用Renumber功能以 0为起始值重填数值。 - Edit Condition
很多代码尤其是驱动代码,当中有大量的预编译定义,以实现对不同硬件配置的支持。在阅读这样的代码时最痛苦的是不能简单判断程序实际执行的代码分枝。大量分枝同时存在,常常会混淆我们的视听。比如对于下面的代码: [pre] #ifdef DEV1
/* DEV1代码代码 */
#else
/* 其它设备执行代码 */
#endif
[/pre]如果确定我们当前分析的是DEV1的执行情况 5,那么可以选择上下文件菜单的Edit Condition 选项,在弹出的Conditional Parsing窗口中把DEV1的值设置为True,那么 #ifdef DEV1就等价于#if 1了,相当注释掉了#else分枝的代码。反之,设置为Flase时,则注释掉#ifdef DEV1分枝的代码。
4 附录1-SI中正则表达式
由于在查找及替换中,经常会使用用正则表达式6,这里对SI的正则表达式进行简单介绍。
4.1 通配符
正则表达式通配符总表:
4.2 表达式中的组
在执行替换操作时,组将大有用武之地。正则表达式的各个部分可以用/(和/)进行分隔,分隔得到的每一项就是一个组。在进行替换时可通过组从匹配内容中抽取出特定串。在正则表达式中每个组都有一个编号,自左至右编号从1开始。 例如:abc/(xyx/)将能匹配 abcxyz ,此时组1就包含了 xyz 串。在进行替换操作时,就可以通过在替换后内容框中填入/1来取出这个字符串。推而广之,可以使用/<number>来取得组<number>所包含的串。 例如:当设定把/(abc/)/(xyz/)替换为/2/1的替换规则时,对于 abcxyz 被替换串,则组1包含 abc,组2包含 xyz,而替换后的内容定义为组2内容后跟组1内容(/2/1),因此将得到 xyzabc。 举个真实的使用例子,相信会增加大家的兴趣。有时为方便调试,代码中到处流浪着各种形式的mytrace调用[pre] mytrace("Create parameter list... ");
[/pre]有时希望把它们全部注释掉,而有些时候又希望把它们全部恢复回来。这是个简单的例子,可以使用[pre] ^/(.*/)/(//*/)/(.*mytrace.*/)/(/*//)___FCKpd___6nbsp;==> /1/3
[/pre]把它们恢复回来,而使用[pre] ^/(.*/)/(mytrace/)/(.*/)___FCKpd___7nbsp;==> /1/*/2/3*/
[/pre]则完成把它们全部注释掉。
5 附录2-SI中的宏语言
我始终认为这是SI中最有趣的部分,这是一种功能强大的编程语言,几乎可以实现在编程过程可能使用到的各种功能。 这里不准备对如何实用宏语言进行编程作介绍(可参阅SI帮助文档。),只介绍如何使用已编好程序。为方便使用,我已把这些程序都集中放在utils.em文件中,下文就此文件进行论述。 该宏文件实现了一些在编码过程中可能会用到的功能, 如添加文件头、函数说明(使用时能自动添加文件名、函数名和当前日期)和宏定义,代码补全等。 使用说明:
[list=1] - Smart Rename
- Project/Open Project...
打开Base工程(该工程一般在"我的文档/Source Insight/Projects/Base"中); - Project/Add and Remove Project Files...
加入宏文件(即utils.em); - Options/Menu Assignments
打开Menu Assignments窗口,在Command中输入Macro,选中要使用的宏,添加到合适的菜单中.推荐使用的宏:InsFileHeader、InsFunHeader、InsHeaderDef、InsIfdef和AutoExpand (为代码自动补全功能,建议建快捷键)。 关于AutoExpand的举例说明, 当你输入了 switch 且光标正处于switch后面,运行该宏则会得到[pre] switch (###)
{
case
break;
default:
}
[/pre]对于InsFunHeader宏,如果有如下函数体[pre] int nOpenConfigFile(char *pchMemConfig, char *pchFlashConfig,
int nSize, int nMode)
{
I
}
[/pre]光标在函数体内时运行该宏,那么将会在函数体上方得到[pre]/******************************************************************************
* nOpenConfigFile -
* DESCRIPTION:-
*
* Input: N/A
* Output: N/A
* Returns: N/A
*
* modification history
* --------------------
* 1.00, Apr 19, 2007, T357 written.
* --------------------
******************************************************************************/
[/pre]其中的函数名及编写日期自动按实际情况填充,T357串可通过修改utils.em文件,改成你需要的名字。
6 附录3-推荐格式
所谓人各有志,这里就不说啦。
7 结束
至此,已将我所知的所有关于Source Insight(未包括其附带的Macro语言)知识在此文档中描述出来。 如有错漏,请指正