forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

add per-file diff stats

allow linking in diffs

Changed files
+51 -17
appview
pages
templates
fragments
repo
pulls
types
+36 -16
appview/pages/templates/fragments/diff.html
···
<span class="bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 {{ $markerstyle }}">MODIFIED</span>
{{ end }}
+
{{ $stat := .Stats }}
+
<div class="flex items-center font-mono text-sm">
+
{{ if and $stat.Insertions $stat.Deletions }}
+
<span class="rounded-l p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400">+{{ $stat.Insertions }}</span>
+
<span class="rounded-r p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400">-{{ $stat.Deletions }}</span>
+
{{ else if $stat.Insertions }}
+
<span class="rounded p-1 select-none bg-green-100 text-green-700 dark:bg-green-800/50 dark:text-green-400">+{{ $stat.Insertions }}</span>
+
{{ else if $stat.Deletions }}
+
<span class="rounded p-1 select-none bg-red-100 text-red-700 dark:bg-red-800/50 dark:text-red-400">-{{ $stat.Deletions }}</span>
+
{{ end }}
+
</div>
+
{{ if .IsDelete }}
<a class="dark:text-white whitespace-nowrap overflow-x-auto" {{if $this }}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.Old }}"{{end}}>
{{ .Name.Old }}
···
<div class="transition-all duration-700 ease-in-out">
{{ if .IsDelete }}
-
<p class="text-center text-gray-400 dark:text-gray-500 p-4">
-
This file has been deleted in this commit.
-
</p>
-
{{ else }}
-
{{ if .IsBinary }}
-
<p class="text-center text-gray-400 dark:text-gray-500 p-4">
-
This is a binary file and will not be displayed.
-
</p>
+
<p class="text-center text-gray-400 dark:text-gray-500 p-4">
+
This file has been deleted.
+
</p>
+
{{ else if .IsCopy }}
+
<p class="text-center text-gray-400 dark:text-gray-500 p-4">
+
This file has been copied.
+
</p>
+
{{ else if .IsRename }}
+
<p class="text-center text-gray-400 dark:text-gray-500 p-4">
+
This file has been renamed.
+
</p>
+
{{ else if .IsBinary }}
+
<p class="text-center text-gray-400 dark:text-gray-500 p-4">
+
This is a binary file and will not be displayed.
+
</p>
{{ else }}
+
{{ $name := .Name.New }}
<pre class="overflow-x-auto"><div class="overflow-x-auto"><div class="min-w-full inline-block">{{- range .TextFragments -}}<div class="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 select-none text-center">&middot;&middot;&middot;</div>
{{- $oldStart := .OldPosition -}}
{{- $newStart := .NewPosition -}}
-
{{- $lineNrStyle := "min-w-[3rem] flex-shrink-0 select-none text-right" -}}
-
{{- $lineNrSepStyle1 := "text-gray-400 dark:text-gray-500 bg-white dark:bg-gray-800" -}}
-
{{- $lineNrSepStyle2 := "text-gray-400 dark:text-gray-500 bg-white dark:bg-gray-800 pr-2" -}}
+
{{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800 scroll-mt-10 target:border target:border-amber-500 target:rounded " -}}
+
{{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}}
+
{{- $lineNrSepStyle1 := "" -}}
+
{{- $lineNrSepStyle2 := "pr-2" -}}
{{- range .Lines -}}
{{- if eq .Op.String "+" -}}
<div class="bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400 flex min-w-full items-center">
<div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}"><span aria-hidden="true" class="invisible">{{$newStart}}</span></div>
-
<div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}">{{ $newStart }}</div>
+
<div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}" id="{{$name}}-N{{$newStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{$newStart}}">{{ $newStart }}</a></div>
<div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div>
<div class="px-2">{{ .Line }}</div>
</div>
···
{{- end -}}
{{- if eq .Op.String "-" -}}
<div class="bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 flex min-w-full items-center">
-
<div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}">{{ $oldStart }}</div>
+
<div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}" id="{{$name}}-O{{$oldStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}">{{ $oldStart }}</a></div>
<div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}"><span aria-hidden="true" class="invisible">{{$oldStart}}</span></div>
<div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div>
<div class="px-2">{{ .Line }}</div>
···
{{- end -}}
{{- if eq .Op.String " " -}}
<div class="bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 flex min-w-full items-center">
-
<div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}">{{ $oldStart }}</div>
-
<div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}">{{ $newStart }}</div>
+
<div class="{{$lineNrStyle}} {{$lineNrSepStyle1}}" id="{{$name}}-O{{$oldStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-O{{$oldStart}}">{{ $oldStart }}</a></div>
+
<div class="{{$lineNrStyle}} {{$lineNrSepStyle2}}" id="{{$name}}-N{{$newStart}}"><a class="{{$linkStyle}}" href="#{{$name}}-N{{$newStart}}">{{ $newStart }}</a></div>
<div class="w-5 flex-shrink-0 select-none text-center">{{ .Op.String }}</div>
<div class="px-2">{{ .Line }}</div>
</div>
···
{{- end -}}
{{- end -}}</div></div></pre>
{{- end -}}
-
{{ end }}
</div>
</details>
+1 -1
appview/pages/templates/repo/pulls/pull.html
···
{{ end }}
</div>
</details>
-
<hr class="md:hidden"/>
+
<hr class="md:hidden border-t border-gray-300 dark:border-gray-600"/>
{{ end }}
{{ end }}
{{ end }}
+14
types/diff.go
···
IsRename bool `json:"is_rename"`
}
+
type DiffStat struct {
+
Insertions int64
+
Deletions int64
+
}
+
+
func (d *Diff) Stats() DiffStat {
+
var stats DiffStat
+
for _, f := range d.TextFragments {
+
stats.Insertions += f.LinesAdded
+
stats.Deletions += f.LinesDeleted
+
}
+
return stats
+
}
+
// A nicer git diff representation.
type NiceDiff struct {
Commit struct {