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
racket-hash-lang-mode not highlighting buffer with font-lock #642
Comments
Hi! Thank you for trying this. I'll take a look. It worked for me, last I tried... but I haven't tried in awhile. (If it still does work for me, I'll follow up with some questions so we can figure it out.) Some background: I've spent quite a lot of time working on this branch, so far -- but not for some months. I think it's in pretty OK shape, but I've been reluctant to commit to merging it. I'm just worried about bugs and performance and maintaining it long-term. Basically, I'm kind of waiting for a "sponsor" -- not financially, but someone who truly needs/wants to use it for real work. TL;DR I'm OK with it turning out to be much more work, provided it's solving a real problem for someone. 😄 If you turn out to be that person (or the first such person), that's great and I can spend more time on this. (OTOH if you're not willing or able to, that's also OK and I'll probably just keep waiting.) |
It's still working for me, using Emacs 25.2 and Racket 8.6.0.8. In the following little example file, I make various changes. The appearance changes as expected within a second:
I can try Emacs latest built from source, as well as refresh my Racket built from source. |
|
Another thought: It sounds like As a guess, this could happen if the Emacs Lisp code in So as a sanity check I'd recommend deleting the Racket Mode (If it still persists, then I'd like to ponder your |
Thanks for the extensive feedback!
I would love to see hash-lang-mode released, but to be honest I am probably not the right person to be a sponsor. I’m mostly in the RnRS Scheme world and only dabble in Racket occasionally.
I installed the whole Git branch from scratch, and I don’t see any issue when I do e.g. My debug information is here. (I upgraded to 28.2 today to see if that would fix the issue, but it didn’t.) ((alist-get 'racket-mode package-alist)) ((emacs-version "28.2") (system-type darwin) (x-gtk-use-system-tooltips UNDEFINED) (major-mode racket-mode) (racket--el-source-dir "/Users/dpk/.emacs.d/racket-mode/") (racket--rkt-source-dir "/Users/dpk/.emacs.d/racket-mode/racket/") (racket-program "racket") (racket-command-timeout 10) (racket-path-from-emacs-to-racket-function UNDEFINED) (racket-path-from-racket-to-emacs-function UNDEFINED) (racket-browse-url-function racket-browse-url-using-temporary-file) (racket-documentation-search-location "https://docs.racket-lang.org/search/index.html?q=%s") (racket-xp-after-change-refresh-delay 1) (racket-xp-mode-lighter (:eval (racket--xp-mode-lighter))) (racket-xp-highlight-unused-regexp "^[^_]") (racket-repl-buffer-name-function nil) (racket-submodules-to-run ((test) (main))) (racket-memory-limit 2048) (racket-error-context medium) (racket-repl-history-directory "~/.emacs.d/racket-mode/") (racket-history-filter-regexp "\\`\\s *\\'") (racket-images-inline t) (racket-imagemagick-props nil) (racket-images-keep-last 100) (racket-images-system-viewer "open") (racket-pretty-print t) (racket-use-repl-submit-predicate nil) (racket-pretty-print t) (racket-indent-curly-as-sequence t) (racket-indent-sequence-depth 0) (racket-pretty-lambda nil) (racket-smart-open-bracket-enable nil) (racket-module-forms "\\s(\\(?:module[*+]?\\|library\\)") (racket-logger-config ((cm-accomplice . warning) (GC . info) (module-prefetch . warning) (optimizer . info) (racket/contract . error) (racket-mode-debugger . info) (sequence-specialization . info) (* . fatal))) (racket-show-functions (racket-show-pseudo-tooltip))) (enabled-minor-modes (auto-composition-mode) (auto-compression-mode) (auto-encryption-mode) (auto-fill-mode) (auto-save-mode) (blink-cursor-mode) (column-number-mode) (delete-selection-mode) (display-line-numbers-mode) (file-name-shadow-mode) (font-lock-mode) (global-display-line-numbers-mode) (global-eldoc-mode) (global-font-lock-mode) (global-git-commit-mode) (global-undo-tree-mode) (hs-minor-mode) (line-number-mode) (magit-auto-revert-mode) (menu-bar-mode) (mouse-wheel-mode) (pcre-mode) (racket-hash-lang-mode) (semantic-minor-modes-format) (shell-dirtrack-mode) (show-paren-mode) (tooltip-mode) (transient-mark-mode) (undo-tree-mode) (which-key-mode) (xterm-mouse-mode)) (disabled-minor-modes (abbrev-mode) (auto-fill-function) (auto-revert-mode) (auto-revert-tail-mode) (auto-save-visited-mode) (buffer-face-mode) (buffer-read-only) (button-mode) (cl-old-struct-compat-mode) (compilation-minor-mode) (compilation-shell-minor-mode) (completion-in-region-mode) (context-menu-mode) (dash-fontify-mode) (defining-kbd-macro) (diff-auto-refine-mode) (diff-minor-mode) (dired-hide-details-mode) (eldoc-mode) (electric-indent-mode) (electric-layout-mode) (electric-quote-mode) (geiser-autodoc-mode) (geiser-mode) (geiser-smart-tab-mode) (git-commit-mode) (global-auto-revert-mode) (global-dash-fontify-mode) (global-prettify-symbols-mode) (global-semantic-highlight-edits-mode) (global-semantic-highlight-func-mode) (global-semantic-show-parser-state-mode) (global-semantic-show-unmatched-syntax-mode) (global-semantic-stickyfunc-mode) (global-visual-line-mode) (horizontal-scroll-bar-mode) (ido-everywhere) (indent-tabs-mode) (isearch-mode) (jit-lock-debug-mode) (lock-file-mode) (magit-blame-mode) (magit-blame-read-only-mode) (magit-blob-mode) (magit-wip-after-apply-mode) (magit-wip-after-save-local-mode) (magit-wip-after-save-mode) (magit-wip-before-change-mode) (magit-wip-initial-backup-mode) (magit-wip-mode) (mail-abbrevs-mode) (mml-mode) (next-error-follow-minor-mode) (outline-minor-mode) (overwrite-mode) (paragraph-indent-minor-mode) (poly-psgml-html-mode) (polymode-minor-mode) (prettify-symbols-mode) (racket-smart-open-bracket-mode) (racket-xp-mode) (rich-minority-mode) (rxt--read-pcre-mode) (rxt-global-mode) (rxt-mode) (semantic-highlight-edits-mode) (semantic-highlight-func-mode) (semantic-mode) (semantic-show-parser-state-mode) (semantic-show-unmatched-syntax-mode) (semantic-stickyfunc-mode) (server-mode) (sgml-electric-tag-pair-mode) (sh-electric-here-document-mode) (shell-command-with-editor-mode) (size-indication-mode) (smerge-mode) (tab-bar-history-mode) (tab-bar-mode) (temp-buffer-resize-mode) (text-scale-mode) (tool-bar-mode) (transient-resume-mode) (undo-tree-visualizer-selection-mode) (unify-8859-on-decoding-mode) (unify-8859-on-encoding-mode) (url-handler-mode) (use-hard-newlines) (view-mode) (visible-mode) (visual-line-mode) (which-function-mode) (window-divider-mode) (with-editor-mode) (xref-etags-mode)) |
Just to confirm: deleting the |
And the variable |
Thanks for the responses!
One thing you could try would be to un-comment the (defun racket--hash-lang-on-new-lang (plist)
"We get this whenever any #lang supplied attributes have changed.
We do /not/ get notified when a new lang uses exactly the same
attributes as the old one. For example changing from #lang racket
to #lang racket/base will /not/ notify us, because none of the
lang's attributes that care about have changed."
- ;;;(message "racket--hash-lang-on-new-lang %s" plist)
+ (message "racket--hash-lang-on-new-lang %s" plist)
(with-silent-modifications (defun racket--hash-lang-on-changed-tokens (_gen beg end)
"The back end has processed a change that resulted in new tokens.
All we do here is mark the span as not fontified, then let the
usual font-lock machinery do its thing if/when this span ever
becomes visible."
- ;;;(message "racket--hash-lang-on-changed-tokens %s %s %s" _gen beg end)
+ (message "racket--hash-lang-on-changed-tokens %s %s %s" _gen beg end)
(with-silent-modifications
(save-restriction
(widen)
(put-text-property beg
(min end (point-max))
'fontified nil)))) Then, if you make some edits, and look in the It might help me to know whether if these are being called but for some reason their work isn't having any visible effect, --or--, not even being called in the first place. |
Yes,
On testing it again, the |
I uncommented the similar log line in |
Potentially related, potentially an irrelevant other issue: I turned on
(There are not 85 parentheses in the file. Indeed, there are not that many characters in this test file.) |
Thanks! That all seems like super helpful information. I'll mull it over, and try some things. Ideally I want to reproduce it here, too, so I can know what to fix, and how, and in fact know I have fixed it. (I'm pretty sure the "invalid face reference" stuff is a red herring, but I'll make a change to avoid that. (When using e.g. the |
What values do you have for the customization variables |
|
To the
Neither of these should be substantive changes that would fix the problem you're having, though. I'm very confused. I've been re-reading the doc and source for font-lock and jit-lock, and reloading my brain with some details. I have no mental model, yet, for what you're seeing. Probably I should set this aside and let my subconscious work on it for awhile. Also I may try with Emacs 28.2 (like you) on the (unlikely?) chance something was broken/different then, but not in 25.2 or 29.x. |
If you're willing/able to try this branch again, you might get a different result now? I've still not been able to reproduce this. I tried again recently with more Emacs versions (28.2 and 29.1), and on more platforms (macosx as well as linux). I really want to merge this branch soon; it's been open for years now. I've worked on it a lot the last month or two; I've started to dog-food it for some real editing of .rkt and .scrbl files. My only hesitation is this issue as well as #669, where something is happening that I can't reproduce, which means I'm overlooking something. 😞 |
Following up here from the Discourse thread: this does sound like the issue I'm experiencing!
Indentation seems to work from my limited testing so far.
Here you go!
And here's what I get from ((alist-get 'racket-mode package-alist) #s(package-desc racket-mode (1) "Racket editing, REPL, and more" ((emacs (25 1))) nil nil "/gnu/store/hga14hb1lg1pnw255n96mwgxd2cy2b3d-emacs-racket-mode-0.0.2-8.65ebeb3/share/emacs/site-lisp/racket-mode-0.0.2-8.65ebeb3" ((:url . "https://www.racket-mode.com/") (:authors ("Greg Hendershott" . "racket-mode-author@greghendershott.com"))) nil) #s(package-desc racket-mode (1) "Racket editing, REPL, and more" ((emacs (25 1))) nil nil "/gnu/store/hga14hb1lg1pnw255n96mwgxd2cy2b3d-emacs-racket-mode-0.0.2-8.65ebeb3/share/emacs/site-lisp/racket-mode-0.0.2-8.65ebeb3" ((:url . "https://www.racket-mode.com/") (:authors ("Greg Hendershott" . "racket-mode-author@greghendershott.com"))) nil)) ((emacs-version "29.1") (system-type gnu/linux) (x-gtk-use-system-tooltips t) (major-mode help-mode) (racket--el-source-dir "/gnu/store/hga14hb1lg1pnw255n96mwgxd2cy2b3d-emacs-racket-mode-0.0.2-8.65ebeb3/share/emacs/site-lisp/racket-mode-0.0.2-8.65ebeb3/") (racket--rkt-source-dir "/gnu/store/hga14hb1lg1pnw255n96mwgxd2cy2b3d-emacs-racket-mode-0.0.2-8.65ebeb3/share/emacs/site-lisp/racket-mode-0.0.2-8.65ebeb3/racket/") (racket-program "racket") (racket-command-timeout 10) (racket-path-from-emacs-to-racket-function UNDEFINED) (racket-path-from-racket-to-emacs-function UNDEFINED) (racket-browse-url-function racket-browse-url-using-temporary-file) (racket-documentation-search-location "https://docs.racket-lang.org/search/index.html?q=%s") (racket-xp-after-change-refresh-delay 1) (racket-xp-mode-lighter (:eval (racket--xp-mode-lighter))) (racket-xp-highlight-unused-regexp "^[^_]") (racket-repl-buffer-name-function nil) (racket-submodules-to-run ((test) (main))) (racket-memory-limit 2048) (racket-error-context medium) (racket-repl-history-directory "/home/philip/.emacs.d/var/racket-mode/repl-history/") (racket-history-filter-regexp "\\`\\s *\\'") (racket-images-inline t) (racket-imagemagick-props nil) (racket-images-keep-last 100) (racket-images-system-viewer "display") (racket-pretty-print t) (racket-use-repl-submit-predicate nil) (racket-pretty-print t) (racket-indent-curly-as-sequence t) (racket-indent-sequence-depth 0) (racket-pretty-lambda nil) (racket-smart-open-bracket-enable nil) (racket-module-forms "\\s(\\(?:module[*+]?\\|library\\)") (racket-logger-config ((cm-accomplice . warning) (GC . info) (module-prefetch . warning) (optimizer . info) (racket/contract . error) (racket-mode-debugger . info) (sequence-specialization . info) (* . fatal))) (racket-show-functions (racket-show-pseudo-tooltip))) (enabled-minor-modes (auto-composition-mode) (auto-compression-mode) (auto-encryption-mode) (auto-fill-mode) (auto-save-mode) (blink-cursor-mode) (buffer-read-only) (delete-selection-mode) (electric-indent-mode) (file-name-shadow-mode) (font-lock-mode) (global-eldoc-mode) (global-font-lock-mode) (global-git-commit-mode) (global-undo-tree-mode) (isearch-fold-quotes-mode) (line-number-mode) (magit-auto-revert-mode) (menu-bar-mode) (mouse-wheel-mode) (override-global-mode) (semantic-minor-modes-format) (shell-dirtrack-mode) (show-paren-mode) (tool-bar-mode) (tooltip-mode) (transient-mark-mode) (undo-tree-mode)) (disabled-minor-modes (abbrev-mode) (auto-fill-function) (auto-package-update-minor-mode) (auto-revert-mode) (auto-revert-tail-mode) (auto-save-visited-mode) (buffer-face-mode) (button-mode) (cl-old-struct-compat-mode) (column-number-mode) (comint-fontify-input-mode) (compilation-minor-mode) (compilation-shell-minor-mode) (completion-in-region-mode) (context-menu-mode) (cursor-face-highlight-mode) (cursor-intangible-mode) (cursor-sensor-mode) (dash-fontify-mode) (defining-kbd-macro) (diff-auto-refine-mode) (diff-minor-mode) (dired-hide-details-mode) (edit-indirect--overlay) (eldoc-mode) (electric-layout-mode) (electric-quote-mode) (elm-format-on-save-mode) (elm-indent-mode) (elm-indent-simple-mode) (flymake-mode) (geiser-autodoc-mode) (geiser-repl-autoeval-mode) (geiser-smart-tab-mode) (git-commit-mode) (global-auto-revert-mode) (global-dash-fontify-mode) (global-prettify-symbols-mode) (global-semantic-highlight-edits-mode) (global-semantic-highlight-func-mode) (global-semantic-show-parser-state-mode) (global-semantic-show-unmatched-syntax-mode) (global-semantic-stickyfunc-mode) (global-visual-line-mode) (haskell-decl-scan-mode) (haskell-indentation-mode) (horizontal-scroll-bar-mode) (hs-minor-mode) (indent-tabs-mode) (isearch-mode) (jit-lock-debug-mode) (lock-file-mode) (lost-selection-mode) (magit-blame-mode) (magit-blame-read-only-mode) (magit-blob-mode) (magit-wip-after-apply-mode) (magit-wip-after-save-local-mode) (magit-wip-after-save-mode) (magit-wip-before-change-mode) (magit-wip-initial-backup-mode) (magit-wip-mode) (mail-abbrevs-mode) (markdown-live-preview-mode) (mml-mode) (next-error-follow-minor-mode) (outline-minor-mode) (overwrite-mode) (paragraph-indent-minor-mode) (paredit-mode) (prettify-symbols-mode) (racket-hash-lang-repl-mode) (racket-smart-open-bracket-mode) (racket-xp-mode) (read-extended-command-mode) (semantic-highlight-edits-mode) (semantic-highlight-func-mode) (semantic-mode) (semantic-show-parser-state-mode) (semantic-show-unmatched-syntax-mode) (semantic-stickyfunc-mode) (server-mode) (sh-electric-here-document-mode) (shell-command-with-editor-mode) (shell-highlight-undef-mode) (size-indication-mode) (smerge-mode) (tab-bar-history-mode) (tab-bar-mode) (temp-buffer-resize-mode) (text-scale-mode) (transient-resume-mode) (treesit-explore-mode) (treesit-inspect-mode) (undelete-frame-mode) (undo-tree-visualizer-selection-mode) (url-handler-mode) (use-hard-newlines) (vc-dir-git-mode) (view-mode) (visible-mode) (visual-line-mode) (which-function-mode) (window-divider-mode) (with-editor-mode) (xref-etags-mode) (yas-global-mode) (yas-minor-mode)) It occurs to me that Guix may be able to create a reproducible minimal environment that demonstrates the bug. I'll give that a try. |
I’ll try this again when I get the chance. We both use |
Okay, this still doesn’t work with the latest version, and neither Manually evalling I’m trying some other stuff out to see what might be going on here. |
Even running Emacs with I wonder if the issue is actually on the Racket end, rather than the Emacs end … |
|
I’ve got it. PR incoming. |
(This still doesn’t fix the issue that only strings, keywords, and some constants are being fontified.) |
I finally realized this might be like Sherlock Holmes and the dog who didn't bark. Instead of you using some minor-mode that makes this fail? It looks like I'm using a minor-mode that makes it work. 🤕 [A year ago I'd tested with Emacs 29 built from source and run with It looks like So this is... a lead. I can push a commit to do this in (For background, |
Oops the page here hadn't refreshed when I left my previous comment. @dpk I see you got all the way to the root of it! 🎉
|
That is basically what I would expect. This uses the color-lexer supplied by each lang. That's just a tokenizer. For The resulting appearance should be like DrRacket -- fairly "plain". If you also enable the minor mode The default face values give me something roughly like what classic Racket Mode would do -- not exactly the same, but approximately "as colorful" -- for say .rkt and .scrbl files I've dog-fooded so far. This aspect can be customized, but the out-of-box defaults might not be great for all langs. [As @samth pointed out to me yesterday w.r.t. rhombus and its Of course so-called "semantic" highlighting analysis could go further. e.g. I miss classic Anyway "better semantic highlighting" is probably its own issue, even if the comment thread on this one weren't already so long. 😄 But it's important, too. |
Weird. I thought I remembered previous versions doing significantly more highlighting (when I manually activated it). But probably I’m misremembering. |
Credit and big thanks to @dpk for identifying the root cause! I had been unable to reproduce the problem because of my use of paren-face-mode; it was doing a font-lock-ensure, which in turn calls font-lock-set-defaults. It suffices for us to call the latter directly. Also: - Group the font-lock-xxx items at the start of the major mode function. Move some "miscellaneous" settings to the end. - Remove redundant init of racket--hash-lang-generation; this is leftover from it being a minor mode, and furthermore it's now the responsibility of racket--hash-lang-{create delete}. - Update doc string about how much coloring to expect, and a hint that racket-xp-mode can contribute more colors.
This commit is a squash of nearly 250 commits from the long-running branch, `hash-lang`. Major themes: 1. Change REPL I/O. We no longer use a TCP connection to do I/O for each REPL. Instead use commands (input) and notifications (output). Furthermore send various kinds of output as distinct notifications. 2. Support use of hash-lang colors, indent, navigation when editing and in REPL. Add racket-hash-lang-mode, an alternative to racket-mode for editing source files, which uses coloring, indent and navigation supplied by a lang. Any number of racket-mode or racket-hash-lang-mode buffers may take turns using the same racket-repl-mode. The last-run edit buffer's settings are used in the REPL. Needs Racket 6.12+ for interval-map-ref/bounds. Use syntax-color/color-textoid when available (with new-enough versions of Racket and/or syntax-color-lib) but not required. 3. racket-xp-mode: Do "semantic" highlighting of binding sites. Intended for use by racket-hash-lang-mode to get more than just lexer colors. --- Closes #661. Fixes #642. Fixes #667. Fixes #671. Fixes #672. Fixes #673.
Hi @greghendershott , thanks for your fantastic racket-mode! I'm using But, I'm using the latest racket-mode-20231222.1554 and still get little highlighting...
And I get this with Update: Tried racket-mode-20231224.2126, still the same. Package
System values
Buffer values
Racket Mode values
Minor modes
Disabled minor modes |
@zhaozhixu Hello. You're welcome! :) Strictly speaking, this issue is about having no font-lock colors at all. It is normal (unfortunately) for See the end of the doc string for
Is either satisfactory for you? |
Thanks! I enabled racket-xp-mode but forgot to set |
The doc string mentions two options. The first one (which you're trying) draws color based on binding arrows. It's not going to be the same as classic You can also try the second option listed above. Basically this uses the hard-coded curated list of keywords from Maybe you could take another look at the doc string, try these things, and if you're still not satisfied, please open a fresh issue about this? |
I’m trying out the head of the
hash-lang
branch on Emacs 28.1 with Racket 8.6. (I know it’s pre-release, so you might already know about this problem.) It works and the buffers are definitely talking to the backend, which is great! (Among other things, Scribble indentation works correctly like in DrRacket.) But neither font-lock nor recognizing when the#lang
has changed are working. Specifically, I can colour the whole buffer byM-:
evaluating(racket--hash-lang-font-lock-fontify-region (point-min) (point-max))
, which works fine, but it doesn’t automatically font-lock the buffer as I type, and if I start an empty buffer and add any#lang
line, it doesn’t recognize the new language I set.after-change-functions
in aracket-hash-lang-mode
buffer are(t racket--hash-lang-after-change-hook)
, andfont-lock-fontify-region-function
is indeedracket--hash-lang-font-lock-fontify-region
, so I don’t understand what’s up here.The text was updated successfully, but these errors were encountered: