1package knotserver
2
3import (
4 "bytes"
5 "io"
6 "log/slog"
7 "net/http"
8 "strings"
9
10 "tangled.sh/tangled.sh/core/types"
11)
12
13func (h *Handle) listFiles(files []types.NiceTree, data map[string]any, w http.ResponseWriter) {
14 data["files"] = files
15
16 writeJSON(w, data)
17 return
18}
19
20func countLines(r io.Reader) (int, error) {
21 buf := make([]byte, 32*1024)
22 bufLen := 0
23 count := 0
24 nl := []byte{'\n'}
25
26 for {
27 c, err := r.Read(buf)
28 if c > 0 {
29 bufLen += c
30 }
31 count += bytes.Count(buf[:c], nl)
32
33 switch {
34 case err == io.EOF:
35 /* handle last line not having a newline at the end */
36 if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' {
37 count++
38 }
39 return count, nil
40 case err != nil:
41 return 0, err
42 }
43 }
44}
45
46func (h *Handle) showFile(resp types.RepoBlobResponse, w http.ResponseWriter, l *slog.Logger) {
47 lc, err := countLines(strings.NewReader(resp.Contents))
48 if err != nil {
49 // Non-fatal, we'll just skip showing line numbers in the template.
50 l.Warn("counting lines", "error", err)
51 }
52
53 resp.Lines = lc
54 writeJSON(w, resp)
55 return
56}