Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

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.

Build out the forge web UI

f09ef39efe44de693748053a7b596ef328fcf06b · Keenan Nemetz · 15d ago · parent 70b70264

Build out the forge web UI

Turn the web surface into a compact, server-rendered forge with HTMX as the
progressive dynamic layer.

- Split templates and assets into embedded files; add a tokenised dark theme,
  Lucide icons, and vendored HTMX.
- Add the repository Overview page and a separate chronological Activity feed
  with type filters and HTMX fragment updates.
- Finish the issue and change workflows: create pages, comments, close/reopen,
  labels and assignees, approval, discussion, line-anchored review comments,
  and HTMX list filters.
- Add syntax-highlighted blobs, contributor/statistics derivation, branch-aware
  code browsing, and a repository Runs list.
- Add a loopback-only development login for local write testing, with explicit
  configuration and listener checks.
- Extend tests for the new pages, fragments, labels, assignees, anchors, and
  development login.

server/web/highlight.go +41

@@ -0,0 +1,41 @@
1 package web
2
3 // Server-side syntax highlighting for source blobs. Chroma is a library, not a
4 // browser asset: the page ships coloured HTML and no highlighting script, which
5 // keeps code browsing fast and works with JavaScript disabled.
6
7 import (
8 "bytes"
9 "html/template"
10
11 "github.com/alecthomas/chroma/v2"
12 "github.com/alecthomas/chroma/v2/formatters/html"
13 "github.com/alecthomas/chroma/v2/lexers"
14 "github.com/alecthomas/chroma/v2/styles"
15 )
16
17 // highlightCode returns coloured HTML for a source file, or "" when no lexer
18 // recognises it. The caller falls back to a plain, line-numbered view, which is
19 // the honest result for a file we cannot classify.
20 func highlightCode(path, src string) template.HTML {
21 lexer := lexers.Match(path)
22 if lexer == nil {
23 lexer = lexers.Analyse(src)
24 }
25 if lexer == nil {
26 return ""
27 }
28 lexer = chroma.Coalesce(lexer)
29 it, err := lexer.Tokenise(nil, src)
30 if err != nil {
31 return ""
32 }
33 var buf bytes.Buffer
34 // Classes rather than inline styles: the palette lives in vole.css beside the
35 // rest of the theme and changes with it.
36 f := html.New(html.WithClasses(true), html.WithLineNumbers(true))
37 if err := f.Format(&buf, styles.Get("github-dark"), it); err != nil {
38 return ""
39 }
40 return template.HTML(buf.String())
41 }