Print filtered gists similar to code search

This commit is contained in:
Heath Stewart 2024-10-11 00:52:00 -07:00
parent 4eaeda580b
commit 70b14215ec
No known key found for this signature in database
3 changed files with 120 additions and 11 deletions

View file

@ -136,8 +136,16 @@ func listRun(opts *ListOptions) error {
fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err)
}
cs := opts.IO.ColorScheme()
tp := tableprinter.New(opts.IO, tableprinter.WithHeader("ID", "DESCRIPTION", "FILES", "VISIBILITY", "UPDATED"))
if opts.IO.ColorEnabled() && opts.Filter != nil {
return printHighlights(opts.IO, gists, opts.Filter)
}
return printTable(opts.IO, gists)
}
func printTable(io *iostreams.IOStreams, gists []shared.Gist) error {
cs := io.ColorScheme()
tp := tableprinter.New(io, tableprinter.WithHeader("ID", "DESCRIPTION", "FILES", "VISIBILITY", "UPDATED"))
for _, gist := range gists {
fileCount := len(gist.Files)
@ -172,3 +180,76 @@ func listRun(opts *ListOptions) error {
return tp.Render()
}
func printHighlights(io *iostreams.IOStreams, gists []shared.Gist, filter *regexp.Regexp) error {
const tab string = " "
cs := io.ColorScheme()
out := &strings.Builder{}
var filename, description string
var err error
text := func(s string) string {
return s
}
for _, gist := range gists {
for _, file := range gist.Files {
found := false
out.Reset()
if filename, err = highlightMatch(file.Filename, filter, &found, cs.Green, cs.Highlight); err != nil {
return err
}
fmt.Fprintln(out, cs.Blue(gist.ID), filename)
if gist.Description != "" {
if description, err = highlightMatch(gist.Description, filter, &found, cs.Bold, cs.Highlight); err != nil {
return err
}
fmt.Fprintln(out, tab, description)
}
if file.Content != "" {
for _, line := range strings.Split(file.Content, "\n") {
if filter.MatchString(line) {
if line, err = highlightMatch(line, filter, &found, text, cs.Highlight); err != nil {
return err
}
fmt.Fprintln(out, tab, tab, line)
}
}
}
if found {
fmt.Fprintln(io.Out, out.String())
}
}
}
return nil
}
func highlightMatch(s string, filter *regexp.Regexp, found *bool, color, highlight func(string) string) (string, error) {
matches := filter.FindAllStringIndex(s, -1)
if matches == nil {
return color(s), nil
}
out := strings.Builder{}
if _, err := out.WriteString(color(s[:matches[0][0]])); err != nil {
return "", err
}
for _, match := range matches {
if _, err := out.WriteString(highlight(s[match[0]:match[1]])); err != nil {
return "", err
}
if _, err := out.WriteString(color(s[match[1]:])); err != nil {
return "", nil
}
}
if found != nil {
*found = *found || true
}
return out.String(), nil
}

View file

@ -143,7 +143,7 @@ func displayResults(io *iostreams.IOStreams, results search.CodeResult) error {
}
fmt.Fprintf(io.Out, "%s %s\n", cs.Blue(code.Repository.FullName), cs.GreenBold(code.Path))
for _, match := range code.TextMatches {
lines := formatMatch(match.Fragment, match.Matches, io.ColorEnabled())
lines := formatMatch(match.Fragment, match.Matches, io)
for _, line := range lines {
fmt.Fprintf(io.Out, "\t%s\n", strings.TrimSpace(line))
}
@ -153,7 +153,7 @@ func displayResults(io *iostreams.IOStreams, results search.CodeResult) error {
}
for _, code := range results.Items {
for _, match := range code.TextMatches {
lines := formatMatch(match.Fragment, match.Matches, io.ColorEnabled())
lines := formatMatch(match.Fragment, match.Matches, io)
for _, line := range lines {
fmt.Fprintf(io.Out, "%s:%s: %s\n", cs.Blue(code.Repository.FullName), cs.GreenBold(code.Path), strings.TrimSpace(line))
}
@ -162,7 +162,9 @@ func displayResults(io *iostreams.IOStreams, results search.CodeResult) error {
return nil
}
func formatMatch(t string, matches []search.Match, colorize bool) []string {
func formatMatch(t string, matches []search.Match, io *iostreams.IOStreams) []string {
cs := io.ColorScheme()
startIndices := map[int]struct{}{}
endIndices := map[int]struct{}{}
for _, m := range matches {
@ -186,14 +188,10 @@ func formatMatch(t string, matches []search.Match, colorize bool) []string {
continue
}
if _, ok := startIndices[i]; ok {
if colorize {
b.WriteString("\x1b[30;43m") // black text on yellow background
}
b.WriteString(cs.HighlightStart()) // black text on yellow background
found = true
} else if _, ok := endIndices[i]; ok {
if colorize {
b.WriteString("\x1b[m") // color reset
}
b.WriteString(cs.Reset()) // color reset
}
b.WriteRune(c)
}

View file

@ -8,6 +8,10 @@ import (
"github.com/mgutz/ansi"
)
const (
highlightStyle = "black:yellow"
)
var (
magenta = ansi.ColorFunc("magenta")
cyan = ansi.ColorFunc("cyan")
@ -20,6 +24,8 @@ var (
bold = ansi.ColorFunc("default+b")
cyanBold = ansi.ColorFunc("cyan+b")
greenBold = ansi.ColorFunc("green+b")
highlightStart = ansi.ColorCode(highlightStyle)
highlight = ansi.ColorFunc(highlightStyle)
gray256 = func(t string) string {
return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[m", 38, 242, t)
@ -176,6 +182,30 @@ func (c *ColorScheme) FailureIconWithColor(colo func(string) string) string {
return colo("X")
}
func (c *ColorScheme) HighlightStart() string {
if !c.enabled {
return ""
}
return highlightStart
}
func (c *ColorScheme) Highlight(t string) string {
if !c.enabled {
return t
}
return highlight(t)
}
func (c *ColorScheme) Reset() string {
if !c.enabled {
return ""
}
return ansi.Reset
}
func (c *ColorScheme) ColorFromString(s string) func(string) string {
s = strings.ToLower(s)
var fn func(string) string