如何写出一个优雅的脚本

如何写出一个优雅的脚本

所谓优雅,指的是除了脚本本身的功能外,不影响别的不相关的地方,比如光标位置、item选中状态等等,或者说,在不得不改变以后,想办法恢复原状。也许是我在编写脚本时的一点洁癖,我觉得如果脚本运行完以后,光标跳到别的位置了,或者原来选中的一堆item被取消选中了,或者画面跳到了一个不知道什么位置,或者凭空多出来一个time selection,我都会觉得很恶心。

先说一个基础知识,可以通过reaper.PreventUIRefresh()来屏蔽UI刷新,加快脚本运行速度

reaper.PreventUIRefresh(1)
代码
代码
reaper.PreventUIRefresh(-1)

保存和恢复数值,我通常用这样的办法来实现

local temp=getXXXXX()  --保存某个会影响到的数值
代码
代码
代码
setXXXX(temp)  --恢复某个被影响到的数值

下面举一些实际的例子

  • 光标位置

当脚本用到的算法无可避免要中途移动光标位置的话,可以这样处理:

local cur=reaper.GetCursorPosition()

代码
代码

reaper.SetEditCurPos(cur, 0, 0)

这样在脚本结束以后,光标将会回到原来的位置,看不出有移动过的痕迹

  • Item 选中状态

通常可以通过建立一个table,把已选中的item存起来,之后再恢复:

local its={}  --储存已选中item
for i=0, reaper.CountSelectedMediaItems(0)-1 do
    its[i+1]=reaper.GetSelectedMediaItem(0, i)
end

代码
代码

reaper.SelectAllMediaItems(0, 0)  --取消选择所有已经选中的item
for k, v in pairs(its) do  --恢复item的选中状态
    reaper.SetMediaItemSelected(v, true)
end
  • 去掉 time selection

如果脚本运行需要先画time selection,或者脚本运行过程中要临时画一个,脚本结束后都应该去掉它

reaper.GetSet_LoopTimeRange(true, true, left, right, false)
代码
代码

reaper.Main_OnCommand(40020, 0)  -- 去掉time selection

要注意的是如果通过自带actionTime selection: Set time selection to items来添加time selection,光标会强制跳到time selection的左端点,所以要注意用上述方法保存和恢复光标位置

  • 画面显示范围

这个不太好形容,比如我在脚本运行前,我的画面显示范围是0~100秒,脚本运行后跳到了100~200秒,这同样是需要修正的:

local left,right=reaper.GetSet_ArrangeView2(0, 0, 0, 0)  --获取屏幕边缘位置

代码
代码

reaper.GetSet_ArrangeView2(0, 1, 0, 0, left, right)  --恢复屏幕边缘位置

暂时就想到想到这些

4 Likes

nice
有点像分享你的编辑器 snippets

如说是说普通api的话,我用的是这个 GitHub - jalovatt/reaper-vs-code: Reaper tools for Visual Studio Code
如果是说我自己魔改的那些,我不确定别人能不能用上 :rofl:
DSY.zip (1.8 KB)

1 Like

顺着这个 repo,发现了一个交互式有趣的东西。

https://forum.cockos.com/showthread.php?t=242185

像在 shell 里运行 python 命令的感觉

1 Like

reaper.PreventUIRefresh()
这个还没用过,又学会一招,马上试试!

noiZ佬永远滴神

这是一个很好的书写习惯
有点类似于如果一开始申请了内存分配,程序逻辑结束的时候应该释放掉内存

一定要“归零”