IntelliSense with Matlab

Typically: "How do I... ", "How can I... " questions
Post Reply
CroCr
Posts: 95
Joined: 29 Dec 2022, 01:47

IntelliSense with Matlab

Post by CroCr »

I am using CoppeliaSim 4.6 on a Windows 10 platform in conjunction with MATLAB. The communication is conducted through ZeroMQ. I wonder if there is a way to get IntelliSense in MATLAB with CoppeliaSim.
coppelia
Site Admin
Posts: 10804
Joined: 14 Dec 2012, 00:25

Re: IntelliSense with Matlab

Post by coppelia »

Hello,

we haven't tried ourselves, but you can generate something in a similar manner as with the CoppeliaSim "Notepad++ autocompletion" add-on:

MATLAB supports a functionSignatures.json file that provides rich IntelliSense for custom functions. For that, generate functionSignatures.json from CoppeliaSim, with following add-on:

Code: Select all

local sim = require 'sim'
local json = require 'dkjson'  -- or use cjson if available

function sysCall_info()
    return {autoStart = false, menu = 'Exporters\nMATLAB functionSignatures.json'}
end

function sysCall_init()
    local f = sim.getApiFunc(-1, '+')
    local v = sim.getApiFunc(-1, '-')
    local signatures = {}

    for i = 1, #f, 1 do
        local s = sim.getApiInfo(-1, f[i])
        if s and not string.find(string.lower(s), "deprecated") then
            s = string.gsub(s, "\n", "")
            local ep = string.find(s, ")")
            if ep then
                local fullSig = string.sub(s, 1, ep)
                local safeName = string.gsub(f[i], "%.", "_")

                -- Parse inputs
                local argsStart = string.find(s, "%(")
                local args = string.sub(s, argsStart + 1, ep - 1)
                local inputs = {}
                for arg in string.gmatch(args, "([^,]+)") do
                    arg = arg:match("^%s*(.-)%s*$")  -- trim
                    if #arg > 0 then
                        table.insert(inputs, {
                            name = arg,
                            kind = "required",
                            type = {{"numeric", "char", "logical"}}
                        })
                    end
                end

                signatures[safeName] = {
                    inputs = inputs,
                    description = "CoppeliaSim: " .. fullSig
                }
            end
        end
    end

    local jsonStr = json.encode(signatures, {indent = true})
    local file = io.open("functionSignatures.json", "w")
    file:write(jsonStr)
    io.close(file)
    sim.addLog(sim.verbosity_msgs, "Wrote 'functionSignatures.json'")
    sim.addLog(sim.verbosity_msgs, "Place this file in the same folder as your MATLAB wrapper functions.")

    return {cmd = 'cleanup'}
end
Then place the file in the same directory as RemoteApiClient.m. MATLAB should automatically read this file and provide IntelliSense.

There is another path: you can create a MATLAB package (+sim folder) with stub .m files:

Code: Select all

local sim = require 'sim'

function sysCall_info()
    return {autoStart = false, menu = 'Exporters\nMATLAB package stubs'}
end

function sysCall_init()
    local f = sim.getApiFunc(-1, '+')
    
    -- Create output directory
    os.execute("mkdir +sim 2>nul")  -- Windows

    for i = 1, #f, 1 do
        local s = sim.getApiInfo(-1, f[i])
        if s and not string.find(string.lower(s), "deprecated") then
            s = string.gsub(s, "\n", "")
            local ep = string.find(s, ")")
            if ep then
                local fullSig = string.sub(s, 1, ep)
                -- Extract just the function name after "sim."
                local dotPos = string.find(f[i], "%.")
                if dotPos then
                    local funcName = string.sub(f[i], dotPos + 1)
                    local argsStart = string.find(s, "%(")
                    local args = string.sub(s, argsStart + 1, ep - 1)

                    local rets = ""
                    local eqPos = string.find(s, "=")
                    if eqPos and eqPos < argsStart then
                        rets = string.sub(s, 1, eqPos - 1)
                        rets = rets:match("^%s*(.-)%s*$")
                    end

                    local mTxt = ""
                    if #rets > 0 then
                        mTxt = "function " .. rets .. " = " .. funcName .. "(" .. args .. ")\n"
                    else
                        mTxt = "function " .. funcName .. "(" .. args .. ")\n"
                    end
                    mTxt = mTxt .. "% " .. funcName .. " - " .. fullSig .. "\n"
                    mTxt = mTxt .. "%\n"
                    mTxt = mTxt .. "% CoppeliaSim API function (auto-generated stub for IntelliSense)\n"
                    mTxt = mTxt .. "% Original: " .. fullSig .. "\n"
                    mTxt = mTxt .. "end\n"

                    local file = io.open("+sim/" .. funcName .. ".m", "w")
                    if file then
                        file:write(mTxt)
                        io.close(file)
                    end
                end
            end
        end
    end

    sim.addLog(sim.verbosity_msgs, "Wrote MATLAB package stubs to '+sim/' folder")
    sim.addLog(sim.verbosity_msgs, "Place the '+sim' folder on your MATLAB path for IntelliSense.")

    return {cmd = 'cleanup'}
end
Again, we haven't tried this ourselves, but that is probably the fastest/easiest track to what you want.

Cheers
Post Reply