The process as a whole is really convoluted and could be done much simpler, which would make debugging it much easier - I'm guilty of the same thing in a few of my scripts, and I can attest that they're a nightmare to sort through.

For instance:

- Only read through the chunk once
- Store the names, the relevant lines, and the relevant line numbers in a table
- Clean the names and insert them into the copied lines
- Replace the original lines with those
- Set the chunk.

SetFXName is also way too big, which makes it harder to nail problems down.

I've been reading a lot about writing "good" code lately, and one consistent point is to make functions small. They don't have to be tiny, but ideally should do only one thing. Big for and if structures can almost always be broken out into a function of their own that just returns the value you want.

It doesn't work - the same effect chain as above ends up looking like this:

test name1
VST: AradazAmp...
VST: CrossOver...
test name4

The GUID is in {}s on the FXID line, with some dashes in it.

Definitely looks like it's not storing/recalling the line to edit properly, though I can't quite tell how. Could be an index somewhere that should be index - 1, or vice versa, or checking the length on a table that starts at 0 (Lua expects them to start at 1 for any table.___ or ipairs stuff). Not sure.

This is a perfect example of why everything in Lua should be local unless you specifically want a global. This part:

Code:

for i = #t, 1, -1 do
local t_check = t[i]:gsub('-','')
if t_check:find(FX_GUID) then
search = true
-- if search then reaper.ShowConsoleMsg("found\n") end
end
if t[i]:find('<') and search and not t[i]:find('JS_SER') then
edited_line = t[i]:sub(2)
edited_line_id = i
-- reaper.ShowConsoleMsg("edited_line_id "..edited_line.."\n")
break
end
end

search is a global variable, so it retains its value after the loop finishes and has true ready to go when the next iteration of SetFXName rolls by - this causes it to grab the first line that satisfies the other conditions (starting with '<', doesn't contain 'JS_SR'). Since the loop is going from #t backwards, that means it grabs the last effect in the chunk.

Slightly cleaned up code with more console messages here:

Code:

function Msg(str)
reaper.ShowConsoleMsg(tostring(str).."\n")
end
function SetFXName(track, fx, new_name)
-- get re
if not track or not tonumber(fx) then return end
Msg("\n\nplugin "..fx)
Msg("new name:\t"..new_name)
local FX_GUID = reaper.TrackFX_GetFXGUID( track, tonumber(fx) )
if not FX_GUID then return else FX_GUID = FX_GUID:gsub('-',''):sub(2,-2) end
Msg("FX_GUID "..FX_GUID)
plug_type = reaper.TrackFX_GetIOSize( track, fx )
-- get chunk t
local _, chunk = reaper.GetTrackStateChunk( track, '', false )
local t = {}
for line in chunk:gmatch("[^\r\n]+") do
t[#t+1] = line
end
local GUID_line
local edited_line, edited_line_id
for i = #t, 1, -1 do
local t_check = t[i]:gsub('-','')
if t_check:find(FX_GUID) then
GUID_line = i
Msg("found FX_GUID: "..i)
end
end
if not GUID_line then return end
for i = GUID_line, 1, -1 do
if t[i]:find('<') and not t[i]:find('JS_SER') then
edited_line = t[i]
edited_line_id = i
Msg("line to edit\n\t"..edited_line_id..": "..tostring(edited_line))
break
end
end
-- parse line
if not edited_line then return end
Msg("parsing line:")
-- break the line into words
local t1 = {}
for word in edited_line:gmatch('[%S]+') do
t1[#t1+1] = word
Msg("\t"..tostring(word))
end
t2 = {}
-- combine the words that have "s, I think
for i = 1, #t1 do
segm = t1[i]
if not q then
t2[#t2+1] = segm
else
t2[#t2] = t2[#t2]..' '..segm
end
if segm:find('"') and not segm:find('""') then
if not q then q = true else q = nil end
end
end
if plug_type == 2 then t2[3] = '"'..new_name..'"' end -- if JS
if plug_type == 3 then t2[5] = '"'..new_name..'"' end -- if VST
local out_line = table.concat(t2,' ')
Msg("out_line:\n\t"..out_line)
t[edited_line_id] = out_line
Msg("edited line:\n\t"..t[edited_line_id])
reaper.SetTrackStateChunk( track, table.concat(t,'\n'), false )
reaper.UpdateArrange()
return true
end
function cleanup(name)
newname = name:gsub("_", " ")
return newname
end
function sleep(n)
if n > 0 then os.execute("ping -n " .. tonumber(n+1) .. " localhost > NUL") end
end
reaper.ClearConsole()
for i = 1,reaper.CountTracks(0),1 do
track = reaper.GetTrack(0,i-1)
Msg("reading FX on track "..i)
for plugin_index = 1,reaper.TrackFX_GetCount(track),1 do
retval, fxname = reaper.TrackFX_GetFXName(track, (plugin_index-1), "")
cleanname = (string.match(cleanup(fxname), ': (.-)%s%('))
Msg("\tfound\t"..tostring(fxname).."\tat index "..(plugin_index-1).."\n\tcleaned\t"..tostring(cleanname))
if cleanname or not cleanname == '' then
local ret = SetFXName(track, plugin_index-1, cleanname)
Msg("returned "..tostring(ret))
end
Msg("\n")
end
end
Msg("Finished")