vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Highlight with Prism in a worker and gzip text responses
306f36fcef89c145abcd0c5331453d0b179f37ce · Keenan Nemetz · 12d ago · parent e5542ac6
Highlight with Prism in a worker and gzip text responses
The code browser now names a blob's language and lets the browser colour it.
Chroma is gone: server/web/highlight.go is an extension table, and
static/prism-worker.js runs Prism — every language Prism ships — off the main
thread. The server sends escaped lines with their numbers and L# anchors, so a
page is complete and scrollable before any script runs and the worker only swaps
the contents of each line cell. The table covers 186 languages; a file it does
not claim stays plain rather than being coloured by a guess.
The bundle those grammars make is 545 KB, so the instance now gzips text
responses itself instead of relying on a proxy, and static assets carry a
content ETag so a browser revalidates with a 304 rather than re-downloading the
bundle on every code page. The raw-download route opts out with
Cache-Control: no-transform because it promises an exact Content-Length.
This also makes JavaScript a requirement rather than a nicety: the label and
assignee token inputs lose their noscript save buttons and their comma-separated
text fallback, and the docs say so.
Measured: release binary 26.08 MB -> 22.70 MB; /r/{repo}/code 11.1 KB -> 2.6 KB
over the wire; the Prism bundle 545 KB -> 206 KB gzipped, fetched once.
scripts/vendor-prism.py regenerates the bundle from Prism's components.json
require graph, and --check fails if the committed assets drift.
server/web/codebrowser.go +12−8
| @@ -55,7 +55,7 @@ type codeView struct { | |||
| 55 | 55 | Truncated bool | |
| 56 | 56 | LineCut bool | |
| 57 | 57 | Lines []string | |
| 58 | Highlight template.HTML | ||
| 58 | Language string | ||
| 59 | 59 | Size int64 | |
| 60 | 60 | IsMarkdown bool | |
| 61 | 61 | Preview bool | |
| @@ -206,14 +206,17 @@ func (w *Web) blob(rw http.ResponseWriter, r *http.Request, raw bool) { | |||
| 206 | 206 | h := rw.Header() | |
| 207 | 207 | h.Set("Content-Type", "text/plain; charset=utf-8") | |
| 208 | 208 | h.Set("Content-Length", strconv.FormatInt(stream.Size, 10)) | |
| 209 | // The announced length is part of the contract, so a text blob must not be | ||
| 210 | // re-encoded on the way out; a compressed body has no such length. | ||
| 211 | h.Set("Cache-Control", "no-transform") | ||
| 209 | 212 | if _, err := io.Copy(rw, stream); err != nil { | |
| 210 | 213 | // The client hung up mid-download; headers are already out. | |
| 211 | 214 | w.Logger("raw %s %s: %v", m.Name, p, err) | |
| 212 | 215 | } | |
| 213 | 216 | return | |
| 214 | 217 | } | |
| 215 | // Everything the page shows is a preview: the tree, the line numbers and the | ||
| 216 | // highlighter are all bounded, so there is no reason to hold the whole file. | ||
| 218 | // Everything the page shows is a preview: the tree and the line numbers are | ||
| 219 | // bounded, so there is no reason to hold the whole file. | ||
| 217 | 220 | data, truncated, err := stream.ReadPrefix(maxInlineBytes) | |
| 218 | 221 | if err != nil { | |
| 219 | 222 | w.serverError(rw, r, "cannot read "+p+": "+err.Error()) | |
| @@ -231,11 +234,12 @@ func (w *Web) blob(rw http.ResponseWriter, r *http.Request, raw bool) { | |||
| 231 | 234 | lines = lines[:maxNumberedLines] | |
| 232 | 235 | lineCut = true | |
| 233 | 236 | } | |
| 234 | // Highlight the same bytes the table would show. A language we cannot name | ||
| 235 | // stays plain, which is better than guessing wrong about its grammar. | ||
| 236 | var highlighted template.HTML | ||
| 237 | // The browser colours the same bytes the table shows. All the server does is | ||
| 238 | // name the language, and a language it cannot name stays plain, which is | ||
| 239 | // better than guessing wrong about its grammar. | ||
| 240 | language := "" | ||
| 237 | 241 | if !binary { | |
| 238 | highlighted = highlightCode(p, strings.Join(lines, "\n")) | ||
| 242 | language = prismLanguage(p) | ||
| 239 | 243 | } | |
| 240 | 244 | markdown := !binary && isMarkdown(p) | |
| 241 | 245 | // A markdown file opens as source like any other file. Rendering it is an | |
| @@ -259,7 +263,7 @@ func (w *Web) blob(rw http.ResponseWriter, r *http.Request, raw bool) { | |||
| 259 | 263 | view.Truncated = truncated | |
| 260 | 264 | view.LineCut = lineCut | |
| 261 | 265 | view.Lines = lines | |
| 262 | view.Highlight = highlighted | ||
| 266 | view.Language = language | ||
| 263 | 267 | view.Size = stream.Size | |
| 264 | 268 | view.IsMarkdown = markdown | |
| 265 | 269 | view.Preview = preview | |