vim技巧实战——关于宏记录的一个例子
嘛,人都说vim效率高,可是究竟高在什么地方呢?
有人说,双手不用离开主键盘区。。。
有人说,Ex模式最方便。。。
有人说,vimrc可编程性能简单又好用。。。
这一切的一切都让Vim变得不可战胜,让水深火热的用户们暂且有了一种“无敌”的安全感。
今天跟大家分享一个初学者进阶级别的技巧——宏记录。
所谓宏记录,就是说vim会记录下你所执行的一个操作序列,然后你可以在记录完成后的任意时间(Normal模式下)一键重复这个操作流——用过北通游戏手柄的“一键大招”功能么?就是这个了,嘿嘿。
宏的使用方法很简单。在Normal模式下按下q再加任意字母(用于标记一个宏)即可开始录制一个宏,录制完毕之后再来一下q表示结束(也就意味着宏是不能嵌套的,想通过宏生成宏的同学你们可以走了。。。哈哈);触发一个宏使用@,例如用qa录制的一个大招(名词不要乱换啊喂!!),可以通过@a来触发。
除了过程中不能嵌套宏以及最好不要:q!或者ZZ等,其他操作都是可以记录的。
Ok,原理性的东西讲完了,牛逼就是这么简单。下面来看一个实战例子。
话说,我有一个类,用于存储一个程序的所有配置参数。里面有很多变量,有int,bool,IPEndPoint等等。
然后我花了九牛二虎之力写了一个Load函数,可以把这个类里的值搬到一个GUI上面。。。
【危险动作请勿模仿——实现该函数将会导致精神烦躁、小猫被杀死、键盘断裂等异常情况。要练习的话你可以直接拷这份去。】
public void LoadFromYadliConfig()
{
//Application
currentRunningModeBox.SelectedIndex = ( int ) YadliConfig.CurrentRunningMode;
ReadonlyDatabaseBox.Checked = YadliConfig.ReadonlyDatabase;
ReadSlaveListFromConfBox.Checked = YadliConfig.ReadSlaveListFromConf;
ExperimentalFeatureOnBox.Checked = YadliConfig.ExperimentalFeatureOn;
CompatibleMessageModeBox.Checked = YadliConfig.CompatibleMessageMode;
IsStandaloneServerBox.Checked = YadliConfig.IsStandaloneServer;
//Network
ClientBufferSizeBox.Text = YadliConfig.ClientBufferSize.ToString();
ClientMaxBufferSizeBox.Text = YadliConfig.ClientMaxBufferSize.ToString();
ServerSocketBufferSizeBox.Text = YadliConfig.ServerSocketBufferSize.ToString();
ClientSocketBufferSizeBox.Text = YadliConfig.ClientSocketBufferSize.ToString();
ClientMaxConnBox.Text = YadliConfig.ClientMaxConn.ToString();
BacklogBox.Text = YadliConfig.BackLog.ToString();
ServerMaxConnBox.Text = YadliConfig.ServerMaxConn.ToString();
ServerMaxAcceptOpsBox.Text = YadliConfig.ServerMaxAcceptOps.ToString();
//Protocol
bbServerBox.Text = YadliConfig.BlackboardServer;
bbPortBox.Text = YadliConfig.BlackboardPort.ToString();
RGraphPortBox.Text = YadliConfig.RGraphPort.ToString();
slavePortBox.Text = YadliConfig.SlavePort.ToString();
YadliProxyPortBox.Text = YadliConfig.YadliProxyPort.ToString();
AggregatorPortBox.Text = YadliConfig.AggregatorPort.ToString();
//Slaves
slaveListBox.Items.Clear();
slaveListBox.BeginUpdate();
foreach ( IPEndPoint ipe in YadliConfig.SlaveList )
{
slaveListBox.Items.Add( ipe.Address.ToString() + ":" + ipe.Port );
}
slaveListBox.EndUpdate();
//Storage
MemoryPoolSizeBox.Text = YadliConfig.MemoryPoolSize.ToString();
MemoryTrunkIncrementSizeBox.Text = YadliConfig.MemoryTrunkIncrementSize.ToString();
IndexMemoryTrunkSizeBox.Text = YadliConfig.MemoryTrunkIncrementSize.ToString();
StorageRootBox.Text = YadliConfig.StorageRoot;
//Internal
UseYadliStarterBox.Checked = YadliConfig.UseYadliStarter;
QueryAggregatorOnBox.Checked = YadliConfig.QueryAggregatorOn;
CellCacheOnBox.Checked = YadliConfig.CellCacheOn;
ReadonlyCellLoadBox.Checked = YadliConfig.ReadonlyCellLoad;
CreateConnectionWhenUnavailableBox.Checked = YadliConfig.CreateConnectionWhenUnavailable;
NeighborAsListBox.Checked = YadliConfig.NeighborAsList;
RGraphOnBox.Checked = YadliConfig.RGraphOn;
GraphBufferSizeBox.Text = YadliConfig.GraphBufferSize.ToString();
XHashSetGroupSizeBox.Text = YadliConfig.XHashSetGroupSize.ToString();
DebugBox.Checked = YadliConfig.Debug;
OneBoxTestBox.Checked = YadliConfig.OneBoxTest;
}
然后在GUI上High够了,总得把值再下载回来吧。。。这个时候是不是有种“什么都不想做了啊!!”的感觉呢?
别怕!这种时候你就应该想到——其实你是有“一键大招”技能的!
我们来分析一下问题——我们在LoadFromYadliConfig()中,把YadliConfig中的变量赋值给了GUI中的控件。现在其实我们要把等号两边的东西反转过来。
把上面这段拷进vim。
定位到第一行。
qa
你的光标后面应该是"currentRunningModeBox.SelectedIndex = ( int ) YadliConfig.CurrentRunningMode;"对吧
此时你应该处于Normal模式。
按键 /=回车,找到等号
x删掉等号
d$将当前光标至末尾的内容放进剪切板
0回行首
p粘出来
x去掉分号
i=Esc 插入一个等号,再回到Normal模式
$i;Esc 跳转行尾插入分号,回到Normal模式
q 结束记录。
然后你得数数一共有多少行,假设30吧(注意是有效行的数量,空行等等不算)
30@a 重复a大招30次
啪,等号左右已经全部对换了。你得到了:
//Application
( int ) YadliConfig.CurrentRunningMode= currentRunningModeBox.SelectedIndex;
YadliConfig.ReadonlyDatabase= ReadonlyDatabaseBox.Checked;
YadliConfig.ReadSlaveListFromConf= ReadSlaveListFromConfBox.Checked;
YadliConfig.ExperimentalFeatureOn= ExperimentalFeatureOnBox.Checked;
YadliConfig.CompatibleMessageMode= CompatibleMessageModeBox.Checked;
YadliConfig.IsStandaloneServer= IsStandaloneServerBox.Checked;
//Network
YadliConfig.ClientBufferSize.ToString()= ClientBufferSizeBox.Text;
YadliConfig.ClientMaxBufferSize.ToString()= ClientMaxBufferSizeBox.Text;
YadliConfig.ServerSocketBufferSize.ToString()= ServerSocketBufferSizeBox.Text;
YadliConfig.ClientSocketBufferSize.ToString()= ClientSocketBufferSizeBox.Text;
YadliConfig.ClientMaxConn.ToString()= ClientMaxConnBox.Text;
YadliConfig.BackLog.ToString()= BacklogBox.Text;
YadliConfig.ServerMaxConn.ToString()= ServerMaxConnBox.Text;
YadliConfig.ServerMaxAcceptOps.ToString()= ServerMaxAcceptOpsBox.Text;
//Protocol
YadliConfig.BlackboardServer= bbServerBox.Text;
YadliConfig.BlackboardPort.ToString()= bbPortBox.Text;
YadliConfig.RGraphPort.ToString()= RGraphPortBox.Text;
YadliConfig.SlavePort.ToString()= slavePortBox.Text;
YadliConfig.YadliProxyPort.ToString()= YadliProxyPortBox.Text;
YadliConfig.AggregatorPort.ToString()= AggregatorPortBox.Text;
//Slaves
slaveListBox.Items.Clear();
slaveListBox.BeginUpdate();
foreach ( IPEndPoint ipe in YadliConfig.SlaveList )
{
slaveListBox.Items.Add( ipe.Address.ToString() + ":" + ipe.Port );
}
slaveListBox.EndUpdate();
//Storage
YadliConfig.MemoryPoolSize.ToString()= MemoryPoolSizeBox.Text;
YadliConfig.MemoryTrunkIncrementSize.ToString()= MemoryTrunkIncrementSizeBox.Text;
YadliConfig.MemoryTrunkIncrementSize.ToString()= IndexMemoryTrunkSizeBox.Text;
YadliConfig.StorageRoot= StorageRootBox.Text;
//Internal
YadliConfig.UseYadliStarter= UseYadliStarterBox.Checked;
YadliConfig.QueryAggregatorOn= QueryAggregatorOnBox.Checked;
YadliConfig.CellCacheOn= CellCacheOnBox.Checked;
YadliConfig.ReadonlyCellLoad= ReadonlyCellLoadBox.Checked;
YadliConfig.CreateConnectionWhenUnavailable= CreateConnectionWhenUnavailableBox.Checked;
YadliConfig.NeighborAsList= NeighborAsListBox.Checked;
YadliConfig.RGraphOn= RGraphOnBox.Checked;
YadliConfig.GraphBufferSize.ToString()= GraphBufferSizeBox.Text;
YadliConfig.XHashSetGroupSize.ToString()= XHashSetGroupSizeBox.Text;
YadliConfig.Debug= DebugBox.Checked;
YadliConfig.OneBoxTest= OneBoxTestBox.Checked;
Ok,离成功已经不远了。
下一个问题,ToString(),要想办法转换成int.Parse
qb 记录一个Q币(。。。)
/.ToString()回车 定位ToString()
xdwxx 删除ToString()
l跳过等号
iint.Parse( 插入前半。。。
$i) 插入后半。。。
esc
q Q币录制成功。
接下来仿照上面的例子来一次,你得到了:
//Application
YadliConfig.CurrentRunningMode=(RunningMode) currentRunningModeBox.SelectedIndex;
YadliConfig.ReadonlyDatabase= ReadonlyDatabaseBox.Checked;
YadliConfig.ReadSlaveListFromConf= ReadSlaveListFromConfBox.Checked;
YadliConfig.ExperimentalFeatureOn= ExperimentalFeatureOnBox.Checked;
YadliConfig.CompatibleMessageMode= CompatibleMessageModeBox.Checked;
YadliConfig.IsStandaloneServer= IsStandaloneServerBox.Checked;
//Network
YadliConfig.ClientBufferSize=int.Parse( ClientBufferSizeBox.Text);
YadliConfig.ClientMaxBufferSize=int.Parse( ClientMaxBufferSizeBox.Text);
YadliConfig.ServerSocketBufferSize=int.Parse( ServerSocketBufferSizeBox.Text);
YadliConfig.ClientSocketBufferSize=int.Parse( ClientSocketBufferSizeBox.Text);
YadliConfig.ClientMaxConn=int.Parse( ClientMaxConnBox.Text);
YadliConfig.BackLog=int.Parse( BacklogBox.Text);
YadliConfig.ServerMaxConn=int.Parse( ServerMaxConnBox.Text);
YadliConfig.ServerMaxAcceptOps=int.Parse( ServerMaxAcceptOpsBox.Text);
//Protocol
YadliConfig.BlackboardServer= bbServerBox.Text;
YadliConfig.BlackboardPort=int.Parse( bbPortBox.Text);
YadliConfig.RGraphPort=int.Parse( RGraphPortBox.Text);
YadliConfig.SlavePort=int.Parse( slavePortBox.Text);
YadliConfig.YadliProxyPort=int.Parse( YadliProxyPortBox.Text);
YadliConfig.AggregatorPort=int.Parse( AggregatorPortBox.Text);
//Slaves
slaveListBox.Items.Clear();
slaveListBox.BeginUpdate();
foreach ( IPEndPoint ipe in YadliConfig.SlaveList )
{
slaveListBox.Items.Add( ipe.Address int.Parse(+ ":" + ipe.Port );
}
slaveListBox.EndUpdate();
//Storage
YadliConfig.MemoryPoolSize=int.Parse( MemoryPoolSizeBox.Text);
YadliConfig.MemoryTrunkIncrementSize=int.Parse( MemoryTrunkIncrementSizeBox.Text);
YadliConfig.MemoryTrunkIncrementSize=int.Parse( IndexMemoryTrunkSizeBox.Text);
YadliConfig.StorageRoot= StorageRootBox.Text;
//Internal
YadliConfig.UseYadliStarter= UseYadliStarterBox.Checked;
YadliConfig.QueryAggregatorOn= QueryAggregatorOnBox.Checked;
YadliConfig.CellCacheOn= CellCacheOnBox.Checked;
YadliConfig.ReadonlyCellLoad= ReadonlyCellLoadBox.Checked;
YadliConfig.CreateConnectionWhenUnavailable= CreateConnectionWhenUnavailableBox.Checked;
YadliConfig.NeighborAsList= NeighborAsListBox.Checked;
YadliConfig.RGraphOn= RGraphOnBox.Checked;
YadliConfig.GraphBufferSize=int.Parse( GraphBufferSizeBox.Text);
YadliConfig.XHashSetGroupSize=int.Parse( XHashSetGroupSizeBox.Text);
YadliConfig.Debug= DebugBox.Checked;
YadliConfig.OneBoxTest= OneBoxTestBox.Checked;
然后修掉少部分大招搞不定的地方,再传给indent程序搞一搞,就基本成功了。
是不是瞬间有了一种无敌的感觉。
就说到这里吧,祝大家好运。 :-)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库