Skip to content

Commit

Permalink
refactor: named regex captures
Browse files Browse the repository at this point in the history
  • Loading branch information
JanDeDobbeleer committed Nov 22, 2020
1 parent 5677827 commit fd84a46
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 36 deletions.
4 changes: 1 addition & 3 deletions properties.go
Expand Up @@ -2,7 +2,6 @@ package main

import (
"fmt"
"regexp"
)

// Property defines one property of a segment for context
Expand Down Expand Up @@ -62,8 +61,7 @@ func (p *properties) getColor(property Property, defaultValue string) string {
if err == nil {
return colorString
}
r := regexp.MustCompile(`(?P<color>#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})`)
values := groupDict(r, colorString)
values := findNamedRegexMatch(`(?P<color>#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})`, colorString)
if values != nil && values["color"] != "" {
return values["color"]
}
Expand Down
45 changes: 45 additions & 0 deletions regex.go
@@ -0,0 +1,45 @@
package main

import "regexp"

func findNamedRegexMatch(pattern, text string) map[string]string {
re := regexp.MustCompile(pattern)
match := re.FindStringSubmatch(text)
result := make(map[string]string)
if len(match) == 0 {
return result
}
for i, name := range re.SubexpNames() {
if i == 0 {
continue
}
result[name] = match[i]
}
return result
}

func findAllNamedRegexMatch(pattern, text string) []map[string]string {
re := regexp.MustCompile(pattern)
match := re.FindAllStringSubmatch(text, -1)
var results []map[string]string
if len(match) == 0 {
return results
}
for _, set := range match {
result := make(map[string]string)
for i, name := range re.SubexpNames() {
if i == 0 {
result["text"] = set[i]
continue
}
result[name] = set[i]
}
results = append(results, result)
}
return results
}

func replaceAllString(pattern, text, replaceText string) string {
re := regexp.MustCompile(pattern)
return re.ReplaceAllString(text, replaceText)
}
17 changes: 6 additions & 11 deletions renderer.go
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"errors"
"fmt"
"regexp"
"strings"

"github.com/gookit/color"
Expand Down Expand Up @@ -147,28 +146,25 @@ func (r *Renderer) writeAndRemoveText(background, foreground, text, textToRemove

func (r *Renderer) write(background, foreground, text string) {
// first we match for any potentially valid colors enclosed in <>
rex := regexp.MustCompile(`<([#A-Za-z0-9]+)?(?:,([#A-Za-z0-9]+))?>(.*?)<\/>`)
match := rex.FindAllStringSubmatch(text, -1)
match := findAllNamedRegexMatch(`<(?P<foreground>[^,>]+)?,?(?P<background>[^>]+)?>(?P<content>[^<]*)<\/>`, text)
for i := range match {
extractedForegroundColor := match[i][1]
extractedBackgroundColor := match[i][2]
extractedForegroundColor := match[i]["foreground"]
extractedBackgroundColor := match[i]["background"]
if col := r.getAnsiFromColorString(extractedForegroundColor, false); col == "" && extractedForegroundColor != Transparent && len(extractedBackgroundColor) == 0 {
continue // we skip invalid colors
}
if col := r.getAnsiFromColorString(extractedBackgroundColor, false); col == "" && extractedBackgroundColor != Transparent && len(extractedForegroundColor) == 0 {
continue // we skip invalid colors
}

// reuse function colors if only one was specified
if len(extractedBackgroundColor) == 0 {
extractedBackgroundColor = background
}
if len(extractedForegroundColor) == 0 {
extractedForegroundColor = foreground
}

escapedTextSegment := match[i][0]
innerText := match[i][3]
escapedTextSegment := match[i]["text"]
innerText := match[i]["content"]
textBeforeColorOverride := strings.Split(text, escapedTextSegment)[0]
text = r.writeAndRemoveText(background, foreground, textBeforeColorOverride, textBeforeColorOverride, text)
text = r.writeAndRemoveText(extractedBackgroundColor, extractedForegroundColor, innerText, escapedTextSegment, text)
Expand All @@ -178,8 +174,7 @@ func (r *Renderer) write(background, foreground, text string) {
}

func (r *Renderer) lenWithoutANSI(str string) int {
re := regexp.MustCompile(r.formats.rANSI)
stripped := re.ReplaceAllString(str, "")
stripped := replaceAllString(r.formats.rANSI, str, "")
switch r.shell {
case zsh:
stripped = strings.ReplaceAll(stripped, "%{", "")
Expand Down
11 changes: 11 additions & 0 deletions renderer_test.go
Expand Up @@ -85,6 +85,17 @@ func TestWriteColorOverrideBoth16(t *testing.T) {
assert.NotContains(t, renderer.string(), "</>")
}

func TestWriteColorOverrideDouble(t *testing.T) {
renderer := &Renderer{
Buffer: new(bytes.Buffer),
}
text := "<#ffffff>jan</>@<#ffffff>Jans-MBP</>"
renderer.init("pwsh")
renderer.write("#193549", "#ff5733", text)
assert.NotContains(t, renderer.string(), "<#ffffff>")
assert.NotContains(t, renderer.string(), "</>")
}

func TestWriteColorTransparent(t *testing.T) {
renderer := &Renderer{
Buffer: new(bytes.Buffer),
Expand Down
21 changes: 3 additions & 18 deletions segment_git.go
Expand Up @@ -3,7 +3,6 @@ package main
import (
"bytes"
"fmt"
"regexp"
"strconv"
"strings"
)
Expand Down Expand Up @@ -180,8 +179,7 @@ func (g *git) getStatusDetailString(status *gitStatus, color, icon Property, def
}

func (g *git) getUpstreamSymbol() string {
upstreamRegex := regexp.MustCompile("/.*")
upstream := upstreamRegex.ReplaceAllString(g.repo.upstream, "")
upstream := replaceAllString("/.*", g.repo.upstream, "")
url := g.getGitCommandOutput("remote", "get-url", upstream)
if strings.Contains(url, "github") {
return g.props.getString(GithubIcon, "\uF408 ")
Expand Down Expand Up @@ -348,19 +346,6 @@ func (g *git) getStashContext() string {
}

func (g *git) parseGitStatusInfo(branchInfo string) map[string]string {
var branchRegex = regexp.MustCompile(`^## (?P<local>\S+?)(\.{3}(?P<upstream>\S+?)( \[(?P<upstream_status>(ahead (?P<ahead>\d+)(, )?)?(behind (?P<behind>\d+))?(gone)?)])?)?$`)
return groupDict(branchRegex, branchInfo)
}

func groupDict(pattern *regexp.Regexp, haystack string) map[string]string {
match := pattern.FindStringSubmatch(haystack)
result := make(map[string]string)
if len(match) > 0 {
for i, name := range pattern.SubexpNames() {
if i != 0 {
result[name] = match[i]
}
}
}
return result
var branchRegex = `^## (?P<local>\S+?)(\.{3}(?P<upstream>\S+?)( \[(?P<upstream_status>(ahead (?P<ahead>\d+)(, )?)?(behind (?P<behind>\d+))?(gone)?)])?)?$`
return findNamedRegexMatch(branchRegex, branchInfo)
}
5 changes: 1 addition & 4 deletions segment_language.go
@@ -1,7 +1,5 @@
package main

import "regexp"

type language struct {
props *properties
env environmentInfo
Expand Down Expand Up @@ -39,8 +37,7 @@ func (l *language) enabled() bool {
}
}
versionInfo, _ := l.env.runCommand(executable, l.versionParam)
r := regexp.MustCompile(l.versionRegex)
values := groupDict(r, versionInfo)
values := findNamedRegexMatch(l.versionRegex, versionInfo)
l.version = values["version"]
return true
}

0 comments on commit fd84a46

Please sign in to comment.