-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Removing the ability for plugins to modify settings.json and bindings.json. Adding an option to reject plugins to bind keys. #3618
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
Conversation
|
Now I'm inclined to think that adding such options would be a good improvement (although I still think it would good to implement what I suggested in #3385 (comment); but that can be implemented independently, and that is about bindings only, not settings). But, why limit these options to plugins only? I.e. |
|
And another thought: maybe we should go ahead and make it the default behavior? Or maybe not just yet, but at least eventually? So it seems that instead of |
Yeah that can be a separate logic.
The main use case of this PR (for me at least) is to remove the concern that any newly installed plugin (although this also kinda applies to the builtin comment plugin) will remove all the formatting + comments. I don't mind also applying this for
I am leaning towards not making it a default behavior since I think only a minority of the users would care about the settings and bindings to be formatted/commented, and I reckon the user would normally expect the |
I'm not sure about that. We've seen quite a few complaints about the existing behavior, although it doesn't prove that they represent the majority of users, but we have no proof of the opposite either. Anyway, yep, we can keep the default as is for now.
Actually, now arguing with myself: perhaps we should not overthink it and should leave
It seems it rather depends on what kind of solution we want: what your PR already implements (i.e. mere protection against insidious plugins, i.e. essentially an ad-hoc workaround for the unfortunate fact that micro allows this sneaky plugins behavior in the first place), or a "generic" solution for disabling saving settings to Now, assuming we want the former kind of solution... Perhaps instead of working around with adding options for blocking the annoying plugin behavior, we should just prevent this behavior unconditionally, once and for all? In the case of |
|
Yeah, then we can change the behavior of
I think my take is that if we are changing the behavior, we should change both keybindings and options and not 1 of them. If we are planning to only change 1 of them, we might as well just merge this PR. |
|
Also, I think it would be nice to add a (1 time?) warning to |
Ok, I don't know which plugins are those, but I can imagine that. Yeah, it seems it makes sense to handle it as you suggest. |
|
I have just updated the plugin functions to not write to any json. The reason is if the plugin action is irreversible (i.e. delete a file, edit a buffer, etc...), I want to explicitly bind it myself instead of having the plugin bind it behind my back. Having this settings guarantees that even if I pressed a keybind by mistake, I know for sure nothing nasty would happen. The same logic however can't apply to I haven't tested it yet but will do in a bit. |
|
Hi @dmaluka @Neko-Box-Coder ! any chance this would be merged? |
8843128 to
25c8278
Compare
|
Just rebased it for the merge conflict. Ready to be mergied if good. |
I guess not. If we merge it, we are stuck with these Any volunteering to make that happen is welcome. |
|
Ok, I see @Neko-Box-Coder just pushed an updated version. But it doesn't make a lot of sense to me. |
|
@dmaluka |
|
Okay, I remember now. The PR changed the implementations such that
And I kept The descriptions for documentation are not accurate, so I need to update them. But before I update them, did I miss anything else? @dmaluka Judging from my faint memory and by quickly reading back the conversation, I think the implementation here is what we want unless I missed/misinterpreted your replies. |
runtime/help/plugins.md
Outdated
| given value. Same as using the `> set` command. This will try to convert | ||
| the value into the proper type for the option. Can return an error if the | ||
| option name is not valid, or the value can not be converted. | ||
| - **Deprecated** `SetGlobalOption(option, value string) error`: sets an |
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.
If we are "deprecating" SetGlobalOption and SetGlobalOptionNative, what are we suggesting to use instead?
I haven't analyzed if implementing them via RegisterGlobalOption() is a correct approach, but assuming that it is, it means now they implement the new desired behavior, instead of the old undesired one, so we should just update their documentation accordingly, not deprecate them?
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.
I will update the docs but if a function simply gets redirected to another function that the plugin can call, the "proxy" function should get deprecated no? Since there's no point to have it anymore.
As said before, I forgot to update the docs. I will update it and mention the user/plugin should call RegisterGlobalOption instead.
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.
but if a function simply gets redirected to another function that the plugin can call
It doesn't. RegisterGlobalOption that the plugin can call is a different function, it is implemented via RegisterGlobalOptionPlug() which does a different thing than RegisterGlobalOption().
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.
Updated the documentation.
internal/action/bindings.go
Outdated
| if l, ok := config.GlobalSettings["lockbindings"]; ok && l.(bool) { | ||
| return false, errors.New("bindings is locked by the user") | ||
| } | ||
| return TryBindKey(k, v, false, false) |
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.
How about actually registering the keybinding (as I suggested in #3385 (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.
But that's no longer the "default" keybinding right?
I think we should treat plugin registered keybinds and user keybinds the same no?
So for example if an unbind is called, it will use the micro's actual default keybindings. I don't think a mutable default keybinding is a good idea.
As for reload in your comment, I am not sure what will happen atm, I assume the bindings will be reconstructed from scratch (default + user keybindings + plugin keybindings) without the unloaded plugin I guess.
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.
@dmaluka
I will do the changes in one go after we get to a conclusion for this thread, since the implementation can change quite a bit depending on what conclusion we arrive to.
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.
Ok, but then why call it "register", if it doesn't really register anything? Let's call it TryBindKey as we used to, since that it what it does - it just tries to bind a key?
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.
I don't mind either way, I am just trying to be consistent with RegisterGlobalOption, since that one also doesn't write to the .json originally. Which one do we want?
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.
RegisterGlobalOption does register a global option. It adds it to the list of known global options, right?
Actually, after a closer look, what you are doing with RegisterGlobalOption in this PR (i.e. using it to implement SetGlobalOption* for plugins) seems not just dubious but utterly wrong. SetGlobalOption* is supposed to just set a (possibly existing) option to a given value, not make this value its default value, right? Moreover, it is definitely not supposed to make it a global-only option (which is what RegisterGlobalOption does)? i.e. what happens if a plugin calls SetGlobalOption("scrollmargin", 0)? It will have not one but two nasty side effects: 0 will become the default value of scrollmargin, and the user will be no longer able to set scrollmargin per buffer via setlocal?
It seems what we actually want for plugins is just a version of SetGlobalOption*() that doesn't call config.WriteSettings(), not a hack using RegisterGlobalOption()?
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.
Yeah you are right, I see what you mean now. Then I will just add a flag to prevent the json write for SetGlobalOption() and SetGlobalOptionNative()
I got confused when trying to read and differentiate RegisterGlobalOption(), RegisterCommonOption() and SetGlobalOption().
Then in this case, I will just have TryBindKey() but without writing to the json for the plugin
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.
Yep, updated the behavior of TryBindKey() now.
| } | ||
|
|
||
| // RegisterKeybindingPlug registers a default keybinding for the plugin without writing to bindings.json. | ||
| // This operation can be rejected by lockbindings to prevent unexpected actions by the user. |
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 kind of "unexpected actions"?
AFAICS, lockbindings is completely pointless now, what it prevents is not overwriting bindings.json (that is already prevented anyway) but doing anything at all?
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.
The reason is if the plugin action is irreversible (i.e. delete a file, edit a buffer, etc...), I want to explicitly bind it myself instead of having the plugin bind it behind my back. Having this settings guarantees that even if I pressed a keybind by mistake, I know for sure nothing nasty would happen.
Ok, haven't noticed this. Well, a plugin can do nasty things behind your back anyway, by virtue of being installed.
But if you really find this lockbindings useful, we can add it.
But it is a separate change, why not do it in a separate commit? This commit does 3 different things, it can be naturally split into three?
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.
Ok, haven't noticed this. Well, a plugin can do nasty things behind your back anyway, by virtue of being installed.
Well yes, but the point of it is to stop accidental effect instead of stopping any malicious intent.
For example if a shortcut for deleting a file in a file manager plugin is ctrl-d, it is easy for the user to press it by accident (say when copying with ctrl-c) without knowing its existence. (An extreme example, of course, but the point still stands)
lockbindings (or whatever we want to call it) makes sure the user is ALWAYS in control of the bindings and mis-pressing any keys combinations will not cause any undesired effects.
But it is a separate change, why not do it in a separate commit? This commit does 3 different things, it can be naturally split into three?
Yeah, that's fine, I can separate them.
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.
Yep, separated them into 3 commits now.
48cb752 to
51af6f2
Compare
|
LGTM now. |
51af6f2 to
cffb343
Compare
cffb343 to
0525ad3
Compare
JoeKar
left 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.
The rest looks good so far!
0525ad3 to
4f1d2bb
Compare
|
Thanks to all of you! 🙏 |
If you have comments in either
settings.jsonorbindings.json, it is possible for plugins to overwrite the json, and erases all the formatting done by the user.Adding an option to lock these files to avoid losing formatting.
Related to #3385 (Which we should close), #3302 , #2194