Old 10-27-2017, 01:30 AM   #1
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default Find action name by its ID

Hello!

I have added in ReaPack the script amagalma_Find custom action or script name by its ID
Code:
-- @description amagalma_Find custom action or script name by its ID
-- @author amagalma
-- @version 1.0
-- @about
--   # Searches in your reaper-kb.ini file to find the action name of the provided ID

-------------------------------------------------------------------------------------

local reaper = reaper
local t = {}
local path = reaper.GetResourcePath()
local separ = string.match(reaper.GetOS(), "Win") and "\\" or "/"
local file = io.open (path .. separ .. "reaper-kb.ini")
for line in file:lines() do
  local words = {}
  for word in line:gmatch(".- ") do
    words[#words+1] = word
  end
  local id = words[4]:gsub('"', "")
  id = id:match("^%s*(.-)%s*$") -- strip spaces
  local rest = ""
  for i = #words, 5, -1 do
    rest = words[i] .. rest
  end
  local name = rest:match('".+"')
  t[id] = name
end
file:close()
local ok, id = reaper.GetUserInputs( "Find name of custom action/script by its Command ID", 1, "Enter Command ID: , extrawidth=120", "")
if ok then
  id = id:match("^%s*(.-)%s*$") -- strip spaces
  if id:find("_.+") then id = id:sub(2) end -- strip leading _
  if t[id] then
    local name = (t[id]:gsub('"', "")):match("^%s*(.-)%s*$")
    reaper.MB( name .. "\n(name copied to clipboard)", "Action name is:", 0 )
    reaper.CF_SetClipboard( name )
  else
    reaper.MB( "Could not find it!\n Either you have mistyped or this is a native/SWS action.", "Sorry! :(", 0 )
  end
end
reaper.defer(function () end )
Does anyone know how could I achieve the same thing with native and SWS actions? Thanks!
amagalma is offline   Reply With Quote
Old 10-27-2017, 01:36 AM   #2
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,838
Default

SWS does this by scraping the values off the actual Action List window (huge hack), which is not possible from ReaScripts.

FR for a GetCommandText API function: https://forum.cockos.com/showthread.php?t=186732

Last edited by cfillion; 10-27-2017 at 02:03 AM.
cfillion is online now   Reply With Quote
Old 10-27-2017, 02:10 AM   #3
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Thanks cfillion!
amagalma is offline   Reply With Quote
Old 10-27-2017, 03:35 AM   #4
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

Also, having ID support in action list filter would be nice...

@amalgama
If you really really need this feature right now, use one of the SWS action list bump and parse that file from the script.
I personnaly put one the dump in a spreadsheet (so I can export in CSV, which may be faster to parse than the HTML).

Problem: you have to remake export everytime action list change (new custom actions, script, native...)
X-Raym is offline   Reply With Quote
Old 10-27-2017, 05:17 AM   #5
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

I just read what you posted.. Funny! I had the same thought!

Here is the code:
Code:
-- @description amagalma_Find action or script name by its ID
-- @author amagalma
-- @version 2.0
-- @about
--   # 

-------------------------------------------------------------------------------------

local reaper = reaper
local path = reaper.GetResourcePath()
local separ = string.match(reaper.GetOS(), "Win") and "\\" or "/"
local file = io.open (path .. separ .. "ActionList.txt")
local version = reaper.GetAppVersion()
local ok = false
 lines = {}

function createActionList()
  reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_DUMP_CUST_ACTION_LIST"), 0)
  file = io.open (path .. separ .. "ActionList.txt")
  for line in file:lines() do
    lines[#lines+1] = line
  end
  file:close()
  local temp = io.open('temp.txt', 'w')
  temp:write(version.."\n")
  for _, line in ipairs(lines) do
    temp:write(line.."\n")
  end
  temp:close()
  os.remove("ActionList.txt")
  os.rename('temp.txt', "ActionList.txt")
  ok = true
end

if not file then
  -- create file and save in it the current version number
  reaper.MB( "For this action to work, a file named ActionList.txt must exist in your Reaper.exe's path. This file currently does not exist, therefore it will be created (this will be done only once). Just click 'Save' at the next dialog without changing anything. Thanks!", "Requirements", 0 )
  createActionList()
else
  -- check if it has updated info (check against current version)
  for line in file:lines() do
    lines[#lines+1] = line
  end
  if lines[1]:match(version) then
    ok = true
  else
    lines = nil
    lines = {}
    file:close()
    os.remove("ActionList.txt")
    reaper.MB( "Your ActionList.txt was created by an older version of Reaper and is going to be replaced by one created by the current version. Please, press Enter/Return as many times as required. Thanks!", "Update", 0)
    createActionList()
  end
end
if ok then
  local ok2, id = reaper.GetUserInputs( "Find name of custom action/script by its Command ID", 1, "Enter Command ID: , extrawidth=120", "")
  if ok2 then
    id = id:match("^%s*(.-)%s*$") -- strip spaces
    --if id:find("_.+") then id = id:sub(2) end -- strip leading _
    for i = 3, #lines do
      if lines[i]:find("\t"..id.."\t") then
        local Section, Id, Action = lines[i]:match("(.+)\t(.+)\t(.+)")
        reaper.MB( Action .. "\n(name copied to clipboard)", "Action name is:", 0 )
        reaper.CF_SetClipboard( Action )
        break
      end
    end
  end
end
reaper.defer(function () end )
amagalma is offline   Reply With Quote
Old 10-27-2017, 05:50 AM   #6
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

Nice ! You can push it to reapack now :P
X-Raym is offline   Reply With Quote
Old 10-27-2017, 01:46 PM   #7
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Here is the final code (for now):
Code:
-- @description amagalma_Find action or script name by its Command ID
-- @author amagalma
-- @version 1.0
-- @about
--   # Returns the action/script name of the given ID
--   - Script gets information from ActionList.txt created by SWS/S&M: Dump action list (all but custom actions)
--   - The script calls this action to create the said file.
--   - You can run this script as many times as you want without the need to create ActionList.txt for two hours.
--   - If ActionList.txt is older than two hours then you are prompted to update it

-------------------------------------------------------------------------------------

local reaper = reaper
local path = reaper.GetResourcePath()
local separ = string.match(reaper.GetOS(), "Win") and "\\" or "/"
local version = reaper.GetAppVersion()
local ok = false
local lines = {}
local time = os.time()
local found = false
local retry = false 

-------------------------------------------------------------------------------------

function createActionList()
  reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_DUMP_CUST_ACTION_LIST"), 0)
  local file = io.open (path .. separ .. "ActionList.txt")
  for line in file:lines() do
    lines[#lines+1] = line
  end
  file:close()
  local temp = io.open('temp.txt', 'w')
  temp:write("version: " .. version .. "  time: " .. time .. "\n")
  for _, line in ipairs(lines) do
    temp:write(line.."\n")
  end
  temp:close()
  os.remove("ActionList.txt")
  os.rename('temp.txt', "ActionList.txt")
  ok = true
end

-------------------------------------------------------------------------------------

::START::
local file = io.open (path .. separ .. "ActionList.txt")
if not file then
  -- create file and save in it the current version number
  if retry ~= true then
    reaper.MB( "For this action to work, a file named ActionList.txt must exist in your Reaper.exe's path. This file currently does not exist, therefore it will be created (this will be done only once). Just click 'Save' at the next dialog without changing anything. Thanks!", "Requirements..", 0 )
  end
  createActionList()
else
  -- check if it has updated info (check against current version)
  for line in file:lines() do
    lines[#lines+1] = line
  end
  file:close()
  if lines[1]:match(version) and os.time() - lines[1]:match("time: (%d+)") < 7200 then
    ok = true
  else
    lines = nil
    lines = {}
    os.remove("ActionList.txt")
    reaper.MB( "For best results, your ActionList.txt must get updated. Please, press Enter/Return as many times as required. Thanks!", "Update..", 0)
    createActionList()
  end
end
if ok then
  local ok2, id = reaper.GetUserInputs( "Find name of action/script by its Command ID", 1, "Enter Command ID: , extrawidth=120", "")
  if ok2 then
    id = id:match("^%s*(.-)%s*$") -- strip spaces
    for i = 3, #lines do
      if lines[i]:find("\t"..id.."\t") then
        local Section, Id, Action = lines[i]:match("(.+)\t(.+)\t(.+)")
        reaper.MB( Action .. "\n\nSection: " .. Section .. "\n\n(name copied to clipboard)", "Action name is:", 0 )
        reaper.CF_SetClipboard( Action )
        found = true
        --break
      end
    end
    if not found then
      local ok3 = reaper.MB("Could not match the given ID to an action/script present in your action list. Perhaps you mistyped or the ActionList.txt is outdated.\nDo you want to update your ActionList.txt and retry?", "Not found! Update and retry?", 4)
      if ok3 == 6 then
        lines = nil
        lines = {}
        time = os.time()
        os.remove(path .. separ .. "ActionList.txt")
        retry = true
        goto START
      end
    end
  end
end
reaper.defer(function () end )
Up in ReaPack
amagalma is offline   Reply With Quote
Old 11-13-2017, 10:32 AM   #8
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

Bug report:
Code:
...magalma_Find action or script name by its Command ID.lua:59: attempt to perform arithmetic on a nil value
:S
X-Raym is offline   Reply With Quote
Old 11-13-2017, 11:06 AM   #9
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Could you tell me the steps to reproduce the bug? Thanks
amagalma is offline   Reply With Quote
Old 11-13-2017, 02:50 PM   #10
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

I just run the script lol ^^
X-Raym is offline   Reply With Quote
Old 11-13-2017, 04:27 PM   #11
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Hmm.. Are you on MacOS?

Does it always give this error?
amagalma is offline   Reply With Quote
Old 11-13-2017, 05:44 PM   #12
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

Win10 x64.

It always give the error but I don't do anything special than Lauching REAPER then rugging the script. Then I get the warning. Code is from your last post with code.
X-Raym is offline   Reply With Quote
Old 11-13-2017, 06:51 PM   #13
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

sry
O T

Last edited by FnA; 11-14-2017 at 02:49 PM.
FnA is offline   Reply With Quote
Old 11-13-2017, 08:13 PM   #14
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Quote:
Originally Posted by X-Raym View Post
Win10 x64.

It always give the error but I don't do anything special than Lauching REAPER then rugging the script. Then I get the warning. Code is from your last post with code.
Try changing line 59 to:
Code:
if lines[1]:match(version) and lines[1]:match("time: (%d+)") and os.time() - lines[1]:match("time: (%d+)") < 7200 then
and tell me if it works now. Thanks!
amagalma is offline   Reply With Quote
Old 06-16-2018, 03:27 AM   #15
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

@amalgama
Look what mespotine doc for C++ extension reveals:


http://mespotine.de/Ultraschall/Reap...getTextFromCmd


It seems that there is an REAPER API function (currently only avaible to extensions) to get command name from ID! Simple as that :P


Access to it could be brought by SWS extension I think. I'll talk to cfillion about it :P
X-Raym is offline   Reply With Quote
Old 06-16-2018, 05:07 AM   #16
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 9,117
Default

^^ He already added for next SWS version.
https://github.com/reaper-oss/sws/pull/990
nofish is offline   Reply With Quote
Old 06-16-2018, 05:22 AM   #17
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

oh very nice !!


Still waiting for next SWS release then :P
X-Raym is offline   Reply With Quote
Old 02-06-2019, 09:36 AM   #18
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

With last SWS release, your whole script could have a condition to use reaper.CF_GetCommandText() if reaper.CF_GetCommandText, instead of rendering an action list file :P
X-Raym is offline   Reply With Quote
Old 02-11-2019, 01:23 PM   #19
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Thanks! Will check this out as soon as I have a working computer... Hard disk died and me idiot had no backup...
amagalma is offline   Reply With Quote
Old 04-07-2019, 06:02 PM   #20
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Updated and simplified
amagalma is offline   Reply With Quote
Old 04-08-2019, 02:20 AM   #21
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,066
Default

Many thx !


I used this a lot when I help people which dont use the same langpackpack as me.
X-Raym is offline   Reply With Quote
Old 11-18-2019, 01:05 PM   #22
Buy One
Human being with feelings
 
Join Date: Sep 2019
Posts: 41
Default

The latest version on my end throws an error

Quote:
...magalma_Find action or script name by its Command ID.lua:38: attempt to call a nil value (field 'CF_GetCommandText')
does it need access to some additional resources?
Buy One is offline   Reply With Quote
Old 11-18-2019, 01:47 PM   #23
Dafarkias
Human being with feelings
 
Dafarkias's Avatar
 
Join Date: Feb 2019
Location: England
Posts: 293
Default

Wouldn't it also be possible to find/execute a script by its name by writing a script that parses reaper-kb.ini?
Dafarkias is offline   Reply With Quote
Old 11-18-2019, 02:14 PM   #24
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 1,463
Default

Quote:
Originally Posted by Dafarkias View Post
Wouldn't it also be possible to find/execute a script by its name by writing a script that parses reaper-kb.ini?
Maybe have a look at CF_EnumerateActions function (SWS), for my _startup.lua I use it something like,

Code:
local function GetIdFromActionName(section, search)
  local name, cnt, ret = '', 0, 1
  while ret > 0 do
    ret, name = reaper.CF_EnumerateActions(section, cnt, '')
    if name == search then return ret end
    cnt=cnt+1 
  end 
end

function UpdateToolBarButtons()  
  local ID = GetIdFromActionName(0, 'Script: Do not process muted tracks toggle.lua')
  if ID then...
Edgemeal is offline   Reply With Quote
Old 11-18-2019, 11:30 PM   #25
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,838
Default

Quote:
Originally Posted by Buy One View Post
does it need access to some additional resources?
Yes, the latest SWS: http://www.sws-extension.org/

(@Edgemeal If that startup script's job is just running a specific script, it would be quicker to use its named command ID with NamedCommandLookup. They're deterministic, based on the path relative to the resource directory the script is installed inside. ReaPack-installed scripts also always have the same named command ID everywhere.)
cfillion is online now   Reply With Quote
Old 11-19-2019, 04:40 AM   #26
Buy One
Human being with feelings
 
Join Date: Sep 2019
Posts: 41
Default

Quote:
Originally Posted by cfillion View Post
Yes, the latest SWS: http://www.sws-extension.org/
my installation is dated to Sep 1 of this year, i guess it's up to date judging by the dates of previous exchange in this thread up until my post.
Buy One is offline   Reply With Quote
Old 11-19-2019, 07:12 AM   #27
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 1,463
Default

Quote:
Originally Posted by cfillion View Post
(@Edgemeal If that startup script's job is just running a specific script, it would be quicker to use its named command ID with NamedCommandLookup.
Ya bad example I guess, the function really comes in handy where I need the actual ID # for use in a Windows EXE that can run my scripts, so for that script I don't enter any script names, they are all parsed from the kb.ini file.

Last edited by Edgemeal; 11-19-2019 at 07:40 AM.
Edgemeal is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 07:26 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.