-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fixing comment plugin not using user settings when overriding default setting #3424
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
You probably meant the following? "ft:c++": {
"commenttype": "//%s"
}since with ...So, with this PR and the above |
It does change currently when without this PR. It overwrites the setting from the user which is set in the beginning when opening the buffer.
The problem here is it registers the comment type when you do a comment. So yes... although your example is a bit unlikely, I get what you are saying.
|
|
Actually, even for custom filetypes that are not "overriding" the default, this bug would still manifest because of the if statement micro/runtime/plugins/comment/comment.lua Lines 67 to 75 in 21bb61c
|
|
Just a thought: Upon |
d8313d9 to
4d8a040
Compare
|
Okay, how about now @dmaluka @JoeKar I have added a setting called It will detect file type change and apply the corresponding comment format correctly. The new change will also update the comment format table according to the user settings for any new buffers. "ft:go": {
"commenttype": "/* %s */"
}for whatever reason, it will update the table so that this will be used next time. So if you have the above json and
The user settings will be applied instead of the default one. The only niche use case this will break is if you want a specific However, the original implementation doesn't work for this niche use case anyway since the moment you switch to a different buffer, your |
|
Due to the merge of #3343 a rebase is necessary.
See my #3424 (comment) above. |
This should do the trick for all the use cases (base is current |
4d8a040 to
b4920fb
Compare
|
@JoeKar |
runtime/plugins/comment/comment.lua
Outdated
| function updateCommentType(buf) | ||
| if buf.Settings["commenttype"] == nil or (last_ft ~= buf.Settings["filetype"] and last_ft ~= nil) then | ||
| -- NOTE: Don't use SetOptionNative() to set "comment.type", | ||
| -- otherwise "comment.type" can't be reset by a "filetype" change. |
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.
It is not nearly obvious why can't it be reset by a "filetype" change if we use SetOptionNative() (it took me some time to figure it out, for instance). We should explain it better, e.g. "Don't use SetOptionNative() to set "comment.type", otherwise "comment.type" will be marked as locally overridden and will not be updated when "filetype" changes."
Or actually it seems better to:
- use
DoSetOptionNative()instead of setting the option directly - add documentation to both
SetOptionNative()andDoSetOptionNative(), so that everyone knows what is the difference between them and when to use each of them, and then we don't need this comment here.
...Another option would be to somehow extend RegisterCommonOption() to allow registering default per-filetype values of an option, not just its default global value, at init time, - so that updateCommentType() would not be needed 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.
DoSetOptionNative() seems like an internal function to me, the name of it is also quite confusing against SetOptionNative() as well.
Would adding a function like SetOptionPersistence(bool persistent) which sets b.LocalSettings[option] be enough for now?
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.
As matter of fact, the line between internal and external functions here is pretty blurred. (Technically DoSetOptionNative() is external, it is already exported to plugins, although not on purpose but as a side effect of exporting it to other modules inside micro, which is a consequence of the bizarre design of micro's plugin system.)
Would adding a function like
SetOptionPersistence(bool persistent)which setsb.LocalSettings[option]
Maybe... @JoeKar what do you think?
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.
It is not nearly obvious why can't it be reset by a "filetype" change if we use
SetOptionNative()(it took me some time to figure it out, for instance).
I thought you can remember, after the long review road of #3343. 😉
Would adding a function like
SetOptionPersistence(bool persistent)which setsb.LocalSettings[option]Maybe... @JoeKar what do you think?
So SetOptionNative() calls then SetOptionNativeMark(option string, nativeValue interface{}, mark(Local) bool).
The same then for consistent reason for SetGlobalOptionNative() -> setGlobalOptionNativeMark(option string, nativeValue interface{}, mark(Modified) bool)
The word persistent resp. persistence smells a bit of writing it persistent into the users configuration.
BTW: Wasn't the extension with a further parameter of these functions temporary part of #3343, but rejected due to the fact a of the introduction of a further parameter?
Anyway, if fine with that adjustment, in case it helps to improve the code/interfaces. Indeed we can then drop the introduced comment in the comment 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.
I think what @Neko-Box-Coder meant is a separate function just for toggling the option's persistence state, independently of setting the option value.
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.
And also I forgot to mention is I would like to not break back compatibility as well for SetOptionNative() and SetGlobalOptionNative().
So ideally changing those 2 functions (name and parameters I guess) would be our last resort if possible.
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, these two should stay as they are, but we can rename those two called from 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.
Again, why not simply:
diff --git a/internal/buffer/settings.go b/internal/buffer/settings.go
index 838df4a5..0a05a67e 100644
--- a/internal/buffer/settings.go
+++ b/internal/buffer/settings.go
@@ -45,6 +45,11 @@ func (b *Buffer) ReloadSettings(reloadFiletype bool) {
}
}
+// DoSetOptionNative is a low-level function which just sets an option to a value
+// for this buffer, overriding the global setting. Unlike SetOption and SetOptionNative
+// it doesn't validate the option and doesn't mark it as overridden, so setting
+// an option via DoSetOptionNative doesn't prevent it from being reset to its
+// global value by the "reload" command or by changing the filetype.
func (b *Buffer) DoSetOptionNative(option string, nativeValue interface{}) {
if reflect.DeepEqual(b.Settings[option], nativeValue) {
return
@@ -119,6 +124,8 @@ func (b *Buffer) DoSetOptionNative(option string, nativeValue interface{}) {
}
}
+// SetOptionNative sets a given option to a value just for this buffer, overriding
+// the global setting.
func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
if err := config.OptionIsValid(option, nativeValue); err != nil {
return err
@@ -130,7 +137,8 @@ func (b *Buffer) SetOptionNative(option string, nativeValue interface{}) error {
return nil
}
-// SetOption sets a given option to a value just for this buffer
+// SetOption sets a given option to a value just for this buffer, overriding
+// the global setting. The value is a string the actual value is parsed from.
func (b *Buffer) SetOption(option, value string) error {
if _, ok := b.Settings[option]; !ok {
return config.ErrInvalidOption
diff --git a/runtime/plugins/comment/comment.lua b/runtime/plugins/comment/comment.lua
index 4a016bfd..f9e85931 100644
--- a/runtime/plugins/comment/comment.lua
+++ b/runtime/plugins/comment/comment.lua
@@ -63,8 +63,6 @@ ft["zscript"] = "// %s"
ft["zsh"] = "# %s"
function updateCommentType(buf)
- -- NOTE: Don't use SetOptionNative() to set "comment.type",
- -- otherwise "comment.type" can't be reset by a "filetype" change.
if buf.Settings["comment.type"] == "" then
if buf.Settings["commenttype"] ~= nil then
micro.InfoBar():Error("\"commenttype\" option has been renamed to \"comment.type\"",
@@ -72,9 +70,9 @@ function updateCommentType(buf)
end
if ft[buf.Settings["filetype"]] ~= nil then
- buf.Settings["comment.type"] = ft[buf.Settings["filetype"]]
+ buf:DoSetOptionNative("comment.type", ft[buf.Settings["filetype"]])
else
- buf.Settings["comment.type"] = "# %s"
+ buf:DoSetOptionNative("comment.type", "# %s")
end
end
end
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.
It's fine to add documentation I think but it would be difficult to rename or change the function signature afterwards if we decide to use it in the plugin (which other people will follow and do the same as well if needed)
I still stand by what I said before:
It's just I am not sure how to rename
DoSetOptionNative()such that it is not confusing and doesn't require a comment explaining what the difference is.Would it work if I add a proxy function called something like
SetNonReloadableOptionNative()(or some other names) which does the same asSetOptionNative()but without setting theLocalSettingsfield.
Or even a step further where we make DoSetOptionNative() as private just like doSetGlobalOptionNative(). The only place it is using DoSetOptionNative() is internal/action/command.go:608 after 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.
I don't think DoSetOptionNative is a particularly bad name (but you are welcome to suggest a better one). It aligns with what it does (and what is described in the documentation I've suggested above): just sets the option for this buffer and does nothing more.
Also I hope it is unlikely that any other plugin will actually want to use it. The comment plugin's use case is unusual in this regard.
Or even a step further where we make
DoSetOptionNative()as private just likedoSetGlobalOptionNative(). The only place it is usingDoSetOptionNative()isinternal/action/command.go:608after all.
internal/action/command.go is in a different package. Which is why we made DoSetOptionNative() public in the first place. Try making it private and compiling micro.
runtime/plugins/comment/comment.lua
Outdated
| micro.InfoBar():Error("\"commenttype\" option has been updated to \"comment.type\"", | ||
| "instead, please update accordingly") | ||
| micro.InfoBar():Error("\"commenttype\" option has been renamed to \"comment.type\"", | ||
| ", please update your configuration") |
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.
After changing commenttype to comment.type in settings.json and running the reload command, micro still stubbornly shows this error.
1885f79 to
414c319
Compare
|
@dmaluka: |
|
414c319 to
8c5c7dd
Compare
Removed the warning and put it in There aren't that many changes anyway so I squashed them into a single commit instead. |
8c5c7dd to
ef5c482
Compare
| } | ||
| ``` | ||
|
|
||
| `commenttype` was the previous option name that was replaced by `comment.type`. |
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.
Sounds a bit unclear and torn out of some context.
How about something like: "For backward compatibility, use can also use the option name commenttype (without the dot) instead of comment.type. It is recommended to use comment.type instead, as commenttype can get deprecated in the future."
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.
This is pretty minor but how about
`commenttype` (without the dot) is the legacy option that is superseded by `comment.type`.
`commenttype` is still supported but will get deprecated in the future.
**Use `comment.type` instead.**
Just firmer wording so that we can discourage people from using commenttype.
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, LGTM. Nit: keep these 3 sentences in one paragraph, not three? (Not worth dedicating 3 paragraphs to discussing a legacy option, right?)
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.
Shouldn't it just say commenttype is deprecated? "Will get deprecated in the future" doesn't make much sense to me.
Features are deprecated, rather than immediately removed, to provide backward compatibility and to give programmers time to bring affected code into compliance with the new standard.
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.
Shouldn't it just say
commenttypeis deprecated?
I agree.
It is deprecated in the moment of merge.
ef5c482 to
6ae4696
Compare
6ae4696 to
14ae8e3
Compare
| superseded by `comment.type`. `commenttype` is still supported | ||
| but will get deprecated in the future. |
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.
@Neko-Box-Coder:
As mentioned here, can you adapt it to something like:
| superseded by `comment.type`. `commenttype` is still supported | |
| but will get deprecated in the future. | |
| superseded by `comment.type`. `commenttype` is still supported | |
| but deprecated from now on. |
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. Thanks for reminding me.
14ae8e3 to
aa41b2b
Compare
|
|
||
| `commenttype` (without the dot) is the legacy option that is | ||
| superseded by `comment.type`. `commenttype` is still supported | ||
| but deprecated from now on. |
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 does "now" mean to someone who is ready this, say, 3 years from now?
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.
Fixing comment plugin not using user settings when overriding default setting, Migrating comment plugin to use "comment.type" option instead
aa41b2b to
fed0431
Compare
If you are overriding the default comment format say
(
"//%s"instead of"// %s")This will get ignored when switching between different file types and the default will be used again.
And also cleaned up unnecessary (and flawed) logic since we should always honor the buffer settings anyway.