This is my first script, and my first Lua program. I've had to look up lots of details about the language and the functions specific to Reaper.
I wrote it so that when I duplicate a track to record, the new track gets renamed by increasing its final number (if the original name ends with a number) or by appending the number 1 (if it doesn't). The script works for multiple tracks, too, and each name gets renumbered separately, so that {Gtr02, Vox005} become {Gtr03, Vox006}.
I use this script as the final step in a custom action to duplicate tracks to record - just the settings, not the content.
Custom: Duplicate and renumber tracks (settings only, no content)
Track: Duplicate tracks
SWS: Delete all items on selected track(s)
Script: Rename and renumber selected tracks name by name.lua
Code:
-- Rename and renumber selected tracks, name by name.lua
-- juan_r
-- v1.0, 2020.10.14
-- rename selected tracks by increasing their final number (if they have one)
-- or adding a number, starting from 1 (if they don't)
Action_Name = "Rename and renumber selected tracks, name by name"
-- divide Track_name into initial basename and final number,
-- noting how many digits are in number
function parse_name(trackname)
local number = string.match (trackname, "(%d*)$")
local numberdigits = #number
local basename = string.sub(trackname, 1 , -numberdigits-1)
return basename, tonumber(number), tonumber(numberdigits)
end
function Main()
reaper.Undo_BeginBlock()
reaper.ClearConsole()
Num_of_tracks = reaper.CountSelectedTracks(0)
-- maxnumber[basename] = maximum number found in track names after basename
maxnumber = {}
Tracks = {}
-- collect names and possibly numbers
for i = 0, Num_of_tracks - 1 do
Tracks[i] = {}
Tracks[i].mediatrack = reaper.GetSelectedTrack(0,i)
_, Tracks[i].name = reaper.GetTrackName(Tracks[i].mediatrack, "")
local basename, number, numberdigits = parse_name(Tracks[i].name)
if numberdigits == 0 then -- no final number in trackname, we say it's 0 (1 digit)
number = 0
numberdigits = 1
end
Tracks[i].basename = basename
Tracks[i].number = number
Tracks[i].ndigits = numberdigits
-- find out the max number associated to the given basename
-- first occurrence of basename? Initialize maxnumber to wimpy maximum
if maxnumber[basename] == nil then maxnumber[basename] = -1 end
if number > maxnumber[basename] then maxnumber[basename] = number end
end
-- rename the tracks
for i = 0, Num_of_tracks - 1 do
new_number = maxnumber[Tracks[i].basename] + 1
maxnumber[Tracks[i].basename] = new_number
format = string.format("%%0%dd", Tracks[i].ndigits); -- e.g, "%03d" if it was 3 digits
new_name = Tracks[i].basename .. string.format(format, new_number);
reaper.GetSetMediaTrackInfo_String(Tracks[i].mediatrack, "P_NAME", new_name, true)
end
reaper.Undo_EndBlock(Action_Name, -1)
end
Main()
Advice on style/substance, comments etc. are welcome!