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.

Add repository code search

aef992843b95fd107327b103c12d135cd708c11e · Keenan Nemetz · 15d ago · parent 5cab7b18

Add repository code search

The Code tab now searches file names and plain-text contents at the selected branch. Contents go through git grep with fixed strings, case-insensitive matching, binary skipping, and a capped result set; there is no second index to drift. Results group by file and link to line anchors in the blob view. Also highlights a targeted line and adds the remaining polish notes to the UI plan.

server/web/templates/code_search.html +72

@@ -0,0 +1,72 @@
1 {{define "code_search"}}
2 {{template "header" .}}
3 {{template "repohead" (nav .Name "code" .CanAdmin)}}
4
5 <div class="page-head">
6 <div class="page-head-main">
7 <h1>Search code</h1>
8 <p class="page-sub">File names and contents on <code>{{.Ref}}</code>. Content search is case-insensitive and treats the query as plain text.</p>
9 </div>
10 <div class="page-head-actions">
11 <a class="button secondary" href="/r/{{.Name}}/code?ref={{esc .Ref}}">{{icon "code"}}Browse</a>
12 </div>
13 </div>
14
15 <form class="filters" method="get" action="/r/{{.Name}}/search" role="search">
16 <input type="hidden" name="ref" value="{{.Ref}}">
17 <input type="search" name="q" value="{{.Query}}" placeholder="Find in files" aria-label="Find in files" autofocus>
18 <button type="submit">{{icon "search"}}Search</button>
19 </form>
20
21 {{if .Error}}<div class="flash bad">{{.Error}}</div>{{end}}
22
23 {{if not .Commit}}
24 <div class="empty-state">
25 <p>There is no commit on <code>{{.Ref}}</code> to search.</p>
26 </div>
27 {{else if not .Query}}
28 <div class="empty-state">
29 <p>Search this repository.</p>
30 <p class="muted">Names and file contents are searched at the selected branch. Binary files are skipped.</p>
31 </div>
32 {{else}}
33 <p class="muted">{{.Hits}} content match(es){{if .FileHits}} · {{len .FileHits}} file name match(es){{end}} for “{{.Query}}”{{if .Truncated}} · showing a partial result set{{end}}</p>
34
35 <h2>Files</h2>
36 {{if .FileHits}}
37 <div class="panel">
38 <table class="search-files">
39 <tbody>
40 {{range .FileHits}}
41 <tr><td><a href="/r/{{$.Name}}/blob/{{esc $.Ref}}/{{pathurl .}}" hx-get="/r/{{$.Name}}/blob/{{esc $.Ref}}/{{pathurl .}}" hx-target="#code-main" hx-swap="outerHTML" hx-push-url="true">{{icon "file"}}{{.}}</a></td></tr>
42 {{end}}
43 </tbody>
44 </table>
45 </div>
46 {{else}}
47 <p class="muted">No file names match.</p>
48 {{end}}
49
50 <h2>Content</h2>
51 {{if .Groups}}
52 {{range .Groups}}{{$g := .}}
53 <section class="search-group">
54 <h3><a href="/r/{{$.Name}}/blob/{{esc $.Ref}}/{{pathurl .Path}}">{{.Path}}</a></h3>
55 <table class="search-lines">
56 <tbody>
57 {{range .Lines}}
58 <tr id="L{{.Line}}">
59 <td class="ln"><a href="/r/{{$.Name}}/blob/{{esc $.Ref}}/{{pathurl $g.Path}}#L{{.Line}}">{{.Line}}</a></td>
60 <td class="code">{{.Text}}</td>
61 </tr>
62 {{end}}
63 </tbody>
64 </table>
65 </section>
66 {{end}}
67 {{else}}
68 <p class="muted">No file content matches.</p>
69 {{end}}
70 {{end}}
71 {{template "footer" .}}
72 {{end}}