Skip to content

Conversation

@MKadaner
Copy link
Contributor

@MKadaner MKadaner commented Oct 8, 2025

Summary

POC implementation of Menu.SetItemExtendedData Lua function.

References

Checklist

Details

This is a proof-of-concept implementation of a new Lua function Menu.SetItemExtendedData. It works except for, instead of getting extended data as a table, it takes multiple parameters representing keys and values. So, instead of

Menu.SetItemExtendedData(FarDialogEvent.hDlg, SelectPos, { Line = 496, Position = 28, Length = 6 })

one has to write

Menu.SetItemExtendedData(FarDialogEvent.hDlg, SelectPos, "Line", 496, "Position", 28, "Length", 6)

which is, of course, totally unacceptable.

The function is implemented this awkward way because, I believe, currently there is no way to pass a table parameter using Lua macro API.

I hope @shmuz or @zg0 can help me with adding table support.

@yulian5
Copy link

yulian5 commented Oct 8, 2025

Hi @MKadaner,

Did you try Copilot? Here is a result (see below 2 solutions to convert table to key/value arguments):

Accepting a table for extended data

Modify Menu.SetItemExtendedData to accept either the existing vararg key/value form or a single table for the data. Detect the argument type and normalize to a table inside the function.
Implementation sketch:

-- Old usage (existing):
-- Menu.SetItemExtendedData(hDlg, itemPos, "Line", 496, "Position", 28, "Length", 6)

-- New usage you want to support:
-- Menu.SetItemExtendedData(hDlg, itemPos, { Line = 496, Position = 28, Length = 6 })

function Menu.SetItemExtendedData(hDlg, itemPos, ...)
    local info = {}

    local third = select(1, ...)
    if type(third) == "table" and select("#", ...) == 1 then
        -- Called with a single table: normalize directly
        info = third
    else
        -- Called with vararg key/value pairs: convert to table
        local n = select("#", ...)
        if n % 2 ~= 0 then
            error("SetItemExtendedData expects key/value pairs or a single table")
        end
        for i = 1, n, 2 do
            local k = select(i, ...)
            local v = select(i+1, ...)
            if type(k) ~= "string" then
                error("SetItemExtendedData keys must be strings")
            end
            info[k] = v
        end
    end

    -- Now use `info` as the data table
    -- Example: store it in dialog item extended data
    -- (Replace the following with existing storage logic)
    -- internal_store_extended_data(hDlg, itemPos, info)
end

Backward compatibility and notes
The function above preserves the old calling convention and adds the new table-style call.
It validates keys are strings and enforces even vararg length.
Replace the placeholder storage call with your current code that actually attaches info to the dialog item.
Example usage after change:
Old: Menu.SetItemExtendedData(hDlg, pos, "Line", 496, "Position", 28, "Length", 6)
New: Menu.SetItemExtendedData(hDlg, pos, { Line = 496, Position = 28, Length = 6 })

Then:

The built-in Far Manager Lua macro API does not automatically convert a single table into the keyed varargs form — you must pass the data in the form the API expects or convert your table to key/value varargs before calling Menu.SetItemExtendedData.

Far’s API functions that accept key/value pairs from Lua are usually implemented to receive varargs, not a single table. If the C-side (or existing Lua wrapper) does not explicitly detect and accept a table, calling Menu.SetItemExtendedData(hDlg, pos, { Line = 496, Position = 28, Length = 6 }) will not work as-is.

Two simple options

  1. Convert the table to varargs at call site

Use a small helper that flattens the table into alternating key/value arguments and call the API with table.unpack:

local function table_to_kvlist(t)
    local out = {}
    for k, v in pairs(t) do
        out[#out+1] = k
        out[#out+1] = v
    end
    return out
end

local data = { Line = 496, Position = 28, Length = 6 }
Menu.SetItemExtendedData(FarDialogEvent.hDlg, SelectPos, table.unpack(table_to_kvlist(data)))

This requires no changes to Far or to existing API wrappers and preserves backward compatibility.
2) Add a Lua wrapper that accepts a table (preferred if you can change macro helpers)

If you can add a small Lua wrapper function in your macros library, normalize both calling forms and forward to the API:

function SetItemExtendedDataSafe(hDlg, pos, ...)
    local info
    if select("#", ...) == 1 and type(select(1, ...)) == "table" then
        info = select(1, ...)
        local kv = {}
        for k, v in pairs(info) do
            kv[#kv+1] = k
            kv[#kv+1] = v
        end
        Menu.SetItemExtendedData(hDlg, pos, table.unpack(kv))
    else
        Menu.SetItemExtendedData(hDlg, pos, ...)
    end
end
-- usage:
SetItemExtendedDataSafe(FarDialogEvent.hDlg, SelectPos, { Line = 496, Position = 28, Length = 6 })

This keeps old code working and gives you the nicer table call everywhere else.
If you control the API implementation

If you are writing or can modify the C-side binding or existing Lua wrapper for Menu.SetItemExtendedData, implement the normalization there (detect a single table argument and convert it to key/value pairs). That is the cleanest solution but requires changing the API wrapper code.
Recommendation

If you cannot change the API implementation, add the small Lua wrapper (option 2). If you can change the API, add table acceptance at the wrapper layer so both forms are supported natively.

@MKadaner
Copy link
Contributor Author

MKadaner commented Oct 9, 2025

Thank you, yulian5. It seems to be a correct solution for a wrong problem.

@yulian5
Copy link

yulian5 commented Oct 9, 2025

@MKadaner, I tried to help and used PR description. What did I understand wrong?

@MKadaner
Copy link
Contributor Author

@yulian5, here I am actually "writing ... the C-side binding" for Menu.SetItemExtendedData. This is the only useful thing our intellectual friend has suggested. This task is not so easy, because, as I explained in the PR description, "currently there is no way to pass a table parameter." Supporting table parameters is not entirely straightforward. I am currently discussing possibilities with the code owners.

Other suggestions of our artificial friend are as obvious as they are awkward. Having Lua wrappers transforming tables to KVPs is not an option, mostly from aesthetics perspective.

@MKadaner MKadaner force-pushed the mzk/gh-1006/Menu.SetItemExtendedData branch from bf1a40c to 768c494 Compare October 27, 2025 00:31
@MKadaner MKadaner force-pushed the mzk/gh-1006/Menu.SetItemExtendedData branch from 055a099 to 1cdd1f4 Compare November 2, 2025 15:56
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 2, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants