-
Notifications
You must be signed in to change notification settings - Fork 230
gh-1006: Menu.SetItemExtendedData
#1024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
gh-1006: Menu.SetItemExtendedData
#1024
Conversation
|
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. Backward compatibility and notes 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
Use a small helper that flattens the table into alternating key/value arguments and call the API with table.unpack: local data = { Line = 496, Position = 28, Length = 6 } This requires no changes to Far or to existing API wrappers and preserves backward compatibility. If you can add a small Lua wrapper function in your macros library, normalize both calling forms and forward to the API: This keeps old code working and gives you the nicer table call everywhere else. 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. 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. |
|
Thank you, yulian5. It seems to be a correct solution for a wrong problem. |
|
@MKadaner, I tried to help and used PR description. What did I understand wrong? |
|
@yulian5, here I am actually "writing ... the C-side binding" for 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. |
055a099 to
1cdd1f4
Compare
26a03ff to
13694f6
Compare
I couldn't get this to work. Maybe I'm not doing it right. After calling |
I apologize. I've spent too much time in this feature, so it's all obvious to me, and I failed to clearly specify the expected behavior. What you observed is exactly what is implemented. The new Lua function sets the extended data, it is observable with So, I would say everything works. Thank you very much for testing. To add some details. The appearance of the menu item is not affected by P.S. BTW, these should work as well: -- Current menu
Menu.SetItemExtendedData(SelectPos, { Line = 496, Position = 28, Length = 6 })
-- Currently selected item
Menu.SetItemExtendedData(FarDialogEvent.hDlg, { Line = 496, Position = 28, Length = 6 })
-- Currently selected item in the current menu
Menu.SetItemExtendedData({ Line = 496, Position = 28, Length = 6 }) |
13694f6 to
8fa887d
Compare
8fa887d to
6b3ddb2
Compare
| api.PushTable(); | ||
| for (const auto& [Key, Value] : ExtendedData) | ||
| { | ||
| api.SetField(Key, Value, -3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is -3?
Maybe introduce some named constant or add a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is -3?
Maybe introduce some named constant or add a comment?
It is table position in Lua stack.
Stack position is often expressed as a negative value relative to stack top.
When we want to set a key-value pair in a table we first push the key then push the value.
If initially the table was on Lua stack top its stack position was -1.
After key and value were pushed the table position became -3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the explanation, @shmuz.
@alabuzhev, as you can see, it is not a magic constant. I'll add a comment.
| break; | ||
|
|
||
| case FMVT_NEXT: | ||
| if (pos >= 1 && pos <= top - 1 && lua_istable(L, pos)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pos >= 1 && pos <= top - 1 -> pos > 0 && pos < top?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elements in the Lua stack are numbered starting from 1:
The first element in the stack (that is, the element that was pushed first) has index 1, the next one has index 2, and so on. We can also access elements using the top of the stack as our reference, using negative indices. In that case, -1 refers to the element at the top (that is, the last element pushed), -2 to the previous element, and so on.
So, pos >= 1 is a sanity check. Given how pos is calculated above (int pos = param >= 0 ? param : top + 1 + param;), we could say pos != 0. However, I followed the style established by FMVT_SETTABLE and FMVT_GETTABLE handlers above. Also, I believe that we should not reference cbdata->start_stack (unlike in FMVT_STACKPOP handler), because the pos here is the position of the table, which can probably be below the part of the stack provided by Lua to our C code.
As for the second part (pos <= top - 1), since lua_next expects one value at the top of the stack (the Key), the table cannot be at the top.
I can add all these explanations to the comment in the code, but I am not sure it would be a good idea. Let's keep it as is.
|
I added a comment explaining enigmatic All other |
|
|
@rohitab, may I ask you to kindly remind the motivation for It would also be great if you could share the macro we discussed in #1006 and which inspired this new function, so that the maintainer could get better idea of what functionality cannot be properly supported without |



Summary
Added Lua API
B=Menu.SetItemExtendedData([hDlg,][N,]T).References
Checklist
If not checked, I accept that this work might be rejected in favor of a different great big ineffable plan.
Details
The implementation is ready for review, complete with the support in the Editor. Special thanks to @shmuz for the great help with passing Lua tables as parameters to native functions.
When all comments are addressed, I will update all changelogs and version files.
Now, one can write in Lua:
@rohitab, could you please test the new function with your macro?
@shmuz, could you please look at the changes related to the new function and passing table as a parameter?
@alabuzhev, could you please look at Editor and VMenu?