-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Fixing comment plugin not using user settings when overriding default setting #3424
base: master
Are you sure you want to change the base?
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
|
Updating comment plugin option to be comment.type Fixing unwanted comment option reset when switching buffers
4d8a040
to
b4920fb
Compare
@JoeKar |
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 theLocalSettings
field.
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:608
after 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.
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.