Illusory stillness

mumble mumble techblog

Fixing Geiser-racket-repl's Error Links

Geiser REPL mode is pretty good, but man the error links were (a) broken and (b) eyewatering. Here’s an example:

Error processing input, expected syntax: {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | “title text” [“alt text”]] %}

I mean, are there error messages somewhere in all those pathnames and red?

After some fussing I got it to look better.

The fussing

Anyway, the fontification for errors is hideously wrong: error message should be eyewatering, full path to file should be muted (except for maybe the basename.)

It’s seriously impeding my ability to read, so let’s….

Actually this is a similar problem as with flycheck, perhaps? Let’s find the fontification problem first.

… this is harder than I thought. Why, when I (setq font-lock-keywords nil) then (font-lock-fontify-buffer), does it not clear fontification? Ah. I want (font-lock-defontify) No wait, I actually want (font-lock-unfontify-buffer). And that makes it clear that the underlines links are not coming from fontity-buffer. Are they coming from compilation-mode somehow? Okay, so geiser-repl-mode calls (compilation-setup) to enter compilation-shell-minor-mode We have compilation-font-lock-keywords which doesn’t seem to have the keywords.

Ah! It’s compilation-error-regexp-alist.

After some futzing around with regex-builder and structured regexes I came to a number of different regexes, like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
(defadvice geiser-repl--startup (after pbm-geiser-repl-errors activate)
  (message "setting up geiser repl error highlighting")
  (set (make-local-variable 'compilation-error-regexp-alist)
       `(
         ;; <path>:line:col: error message
         ;; <path>: [not a function name]
         (,(rx (seq bol
                    (or "" "   ")
                    (group-n 1
                             (one-or-more (not (any ":\n \t>")))
                             (zero-or-more (not (any ":\n\t>"))))
                    ": "
                    (group-n 2 (seq "[" (minimal-match (one-or-more anything)) "]"))))
          1 nil nil 0 1
          (1 file-name-shadow-properties)
          (2 file-name-shadow-properties))
         ;; <path>:<line>:<col>: <function-name>
         (,(rx (seq bol
                    (or "" "   ")
                    (group-n 1
                             (one-or-more (not (any ":\n \t>")))
                             (zero-or-more (not (any ":\n\t>"))))
                    ":" (group-n 2 (one-or-more digit))
                    ":" (group-n 3 (one-or-more digit))
                    ": "
                    (group-n 4 (one-or-more (any word "-_~!/@$%^&<>{}?")))
                    eol))
          1 2 3 0 1
          (1 file-name-shadow-properties)
          (4 font-lock-function-name-face))
         ;; <path>:line:col: error message
         (,(rx (seq bol
                    (or "" "   ")
                    (group-n 1
                             (one-or-more (not (any ":\n \t>")))
                             (zero-or-more (not (any ":\n\t>"))))
                    ":" (group-n 2 (one-or-more digit))
                    ":" (group-n 3 (one-or-more digit))
                    ": "
                    (group-n 4 (minimal-match (one-or-more anything)))
                    eol))
          1 2 3 2 1
          (1 file-name-shadow-properties)
          (4 compilation-error-face))
         ;; <function-name>: <error-message>
         (,(rx (seq bol
                    (or "" "   ")
                    (group-n 1 (one-or-more (any word "-_~!/@$%^&<>{}?.")))
                    (group-n 2 "")
                    ": "
                    (group-n 3 (minimal-match (one-or-more anything)))
                    eol))
          nil nil nil 2 2
          (1 font-lock-function-name-face)
          (3 compilation-error-face))
         ;; <path>:<line>:<col>
         (,(rx (seq bol
                    (or "" "   ")
                    (group-n 1
                             (one-or-more (not (any ":\n \t>")))
                             (zero-or-more (not (any ":\n\t>"))))
                    ":" (group-n 2 (zero-or-more digit))
                    ":" (group-n 3 (zero-or-more digit))
                    eol))
          1 2 3 0 1
          (1 file-name-shadow-properties)))))

Which looks much better:

Error processing input, expected syntax: {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | “title text” [“alt text”]] %}

Ah, see, the actual error message is highlighted, and the pile of linked pathnames is muted.

It’s not perfect but it’s a definite improvement.