-
Notifications
You must be signed in to change notification settings - Fork 23
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
Rm extra indirection by making (color-identifiers:refontify) an alias #122
Conversation
The check is present inside `font-lock-flush`, so calling it at top-level is unnecessary.
ff69e72
to
6e0df0f
Compare
@purcell since you're the author of the idea with aliasing font-lock (for (if (fboundp 'font-lock-flush)
(defalias 'color-identifiers:refontify 'font-lock-flush)
(defun color-identifiers:refontify ()
(with-no-warnings (font-lock-fontify-buffer)))) I figured I'd CC you in case you have any solution. I tried implementing your idea, but it gives either this: Error: the function ‘color-identifiers:refontify’ is not known to be defined. or if I wrap it to Error: the function ‘color-identifiers:refontify’ might not be defined at runtime. So I ended up doing the hackery that can be seen in commit Thanks in advance! |
Per my understanding, in But here everything is in a single file, and I presume in this case splitting it just for the sake of making an alias not cause compilation errors would be an even larger hackery 😅 |
color-identifiers-mode.el
Outdated
(font-lock-fontify-buffer))))) | ||
;; Remove unnecessary indirection by making the function an alias. So this | ||
;; whole body effectively gets called just once. | ||
(defalias 'color-identifiers:refontify 'font-lock-flush)) |
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.
Trying to alias the not-yet-defined containing function is what confuses the byte compiler. I'd suggest:
(if (fboundp 'font-lock-flush)
(defalias 'color-identifiers:refontify 'font-lock-flush)
(defun color-identifiers:refontify ()
"Refontify the buffer using font-lock.
(with-no-warnings
(and font-lock-mode (font-lock-fontify-buffer)))))
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.
Aaah, actually, I just remember a workaround to that.
Your solution doesn't work, it still prints a color-identifiers-mode.el:684:4: Error: the function ‘color-identifiers:refontify’ is not known to be defined.
. But the reason to that is this Emacs bug. And one workaround to that is adding a declare-function
right before the defun
. Like this.
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.
Huh, weird. I see code with that pattern all over the place, but have not seen that compilation error before.
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.
Well, maybe in other places the callers were in separate .el
files? Because the error appears for the call-site, not the definition-site.
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.
No, not at all. Mostly the same .el file. But looking again at this, you're apparently getting an error at a call site on line 684, but defining the function on a later line ~750, so of course the function is not known to be defined at the earlier call site. Just move the definition earlier in the file.
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.
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.
Right, yeah, was testing while compiling multiple times in the same instance. I found another pattern I've used in the past btw:
(defalias 'windswap--swap-states
(if (fboundp 'window-swap-states)
'window-swap-states
(lambda (a b)
"Docstring for local function definition.
...)))
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.
Just added CI to that project to confirm it compiles cleanly, and it does.
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.
Oh wow, this one does work! And it's functional too, nice!
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 probably found and solved that problem myself at some point in order to end up with that solution. :)
c233df3
to
7ffb728
Compare
General observation here is that the current code in |
You might be right. Although, 24.4 is just a minor release of 24, but it indeed should be "24.4" then. And either way, OTOH, I am partly interested in the correct solution (disregarding if we drop Emacs 24) because I grepped over the code at my |
aa0b0fe
to
0628b9b
Compare
Using `package-lint` on the .el file shows that the mode uses a lot of functions that weren't available prior to 24.4 release. So correct the minimal supported version.
For Emacs 25.1 and higher that makes `(color-identifiers:refontify)` an alias to `(font-lock-flush)`. `(color-identifiers:refontify)` always was just a wrapper, so no functional change is intended besides removing the unnecessary indirection.
0628b9b
to
eb74cdc
Compare
Well, running So anyway, I added a commit correcting the version, to 24.4 for now. I tried integrating |
That said — not that it matters given I can't rename it — but in my opinion using colons was a neat idea. Given that Emacs doesn't allow "local functions", so every function had to be prefixed with the plugin name to avoid naming clash, the colon allows to clearly separate that "workaround" part of the name from the actual function or variable name. |
It's cool to have an opinion or personal preference, and if Emacs were reinvented now perhaps things would be different, but the Emacs coding conventions explicitly establish two hyphens as the preferred separator for "private" symbols, and generally it is preferable to value community consistency over individual aesthetics. That's why |
BTW, it is possible to migrate from |
It's a lot of work, and then how long are we gonna keep obsolete names around, another ten years? Besides, obsoletion in plugins usually goes unnoticed. That's because to find out that you're using an obsolete variable/function you'd need to byte-compile a file, but many people don't byte-compile their |
Btw, these are conventions for code internal to Emacs, not for Elpa or plugins. I'm just saying this because that implies you can see "in the wild" code that doesn't accord to the conventions. |
It's been done before in much more popular packages than this, so I can assure you it's perfectly possible. But I really don't care here. It's not a great use of my time to engage further, sorry, just sharing my experience from reviewing thousands of packages as part of building up MELPA from 2012. |
There's a difference to changing/obsoleting a single variable/function, or doing that to everything in the entire plugin 😊
It's okay, I understand. |
For Emacs 25.1 and higher that makes
(color-identifiers:refontify)
an alias to(font-lock-flush)
.(color-identifiers:refontify)
always was just a wrapper, so nofunctional change is intended besides removing the unnecessary indirection.
I haven't found a way to just leave
(if (fboundp … (defalias …)
expression at thetop-level and not cause any byte-compilation errors, so the solution required a
little bit of hackery, but hopefully it should be safe. At least tests are passing
and I haven't found any problems.