summaryrefslogtreecommitdiff
path: root/gui/text-renderer.go
diff options
context:
space:
mode:
Diffstat (limited to 'gui/text-renderer.go')
-rw-r--r--gui/text-renderer.go191
1 files changed, 191 insertions, 0 deletions
diff --git a/gui/text-renderer.go b/gui/text-renderer.go
new file mode 100644
index 0000000..d699acf
--- /dev/null
+++ b/gui/text-renderer.go
@@ -0,0 +1,191 @@
+package gui
+
+import (
+ "regexp"
+ "strings"
+
+ "github.com/fatih/color"
+ "github.com/isacikgoz/gitbatch/core/git"
+ "github.com/isacikgoz/gitbatch/core/job"
+)
+
+var (
+ black = color.New(color.FgBlack)
+ blue = color.New(color.FgBlue)
+ green = color.New(color.FgGreen)
+ red = color.New(color.FgRed)
+ cyan = color.New(color.FgCyan)
+ yellow = color.New(color.FgYellow)
+ white = color.New(color.FgWhite)
+ magenta = color.New(color.FgMagenta)
+
+ bold = color.New(color.Bold)
+
+ maxBranchLength = 15
+ maxRepositoryLength = 20
+ hashLength = 7
+
+ ws = " "
+ pushable = string(blue.Sprint("↖"))
+ pullable = string(blue.Sprint("↘"))
+ dirty = string(yellow.Sprint("✗"))
+
+ queuedSymbol = "•"
+ workingSymbol = "•"
+ successSymbol = "✔"
+ pauseSymbol = "॥"
+ failSymbol = "✗"
+
+ fetchSymbol = "↓"
+ pullSymbol = "↓↳"
+ mergeSymbol = "↳"
+
+ keySymbol = ws + yellow.Sprint("🔑") + ws
+
+ modeSeperator = ""
+ keyBindingSeperator = "░"
+
+ selectionIndicator = ws + string(green.Sprint("→")) + ws
+ tab = ws
+)
+
+// this function handles the render and representation of the repository
+// TODO: cleanup is required, right now it looks too complicated
+func (gui *Gui) repositoryLabel(r *git.Repository) string {
+
+ var prefix string
+ b := r.State.Branch
+ if b.Pushables != "?" {
+ prefix = prefix + pushable + ws + b.Pushables +
+ ws + pullable + ws + b.Pullables
+ } else {
+ prefix = prefix + pushable + ws + yellow.Sprint(b.Pushables) +
+ ws + pullable + ws + yellow.Sprint(b.Pullables)
+ }
+
+ var repoName string
+ sr := gui.getSelectedRepository()
+ if sr == r {
+ prefix = prefix + selectionIndicator
+ repoName = green.Sprint(r.Name)
+ } else {
+ prefix = prefix + ws
+ repoName = r.Name
+ }
+ // some branch names can be really long, in that times I hope the first
+ // characters are important and meaningful
+ branch := adjustTextLength(b.Name, maxBranchLength)
+ prefix = prefix + string(cyan.Sprint(branch))
+
+ if !b.Clean {
+ prefix = prefix + ws + dirty + ws
+ } else {
+ prefix = prefix + ws
+ }
+
+ var suffix string
+ // rendering the satus according to repository's state
+ if r.WorkStatus() == git.Queued {
+ if inQueue, j := gui.State.Queue.IsInTheQueue(r); inQueue {
+ switch mode := j.JobType; mode {
+ case job.FetchJob:
+ suffix = blue.Sprint(queuedSymbol)
+ case job.PullJob:
+ suffix = magenta.Sprint(queuedSymbol)
+ case job.MergeJob:
+ suffix = cyan.Sprint(queuedSymbol)
+ default:
+ suffix = green.Sprint(queuedSymbol)
+ }
+ }
+ return prefix + repoName + ws + suffix
+ } else if r.WorkStatus() == git.Working {
+ // TODO: maybe the type of the job can be written while its working?
+ return prefix + repoName + ws + green.Sprint(workingSymbol)
+ } else if r.WorkStatus() == git.Success {
+ return prefix + repoName + ws + green.Sprint(successSymbol)
+ } else if r.WorkStatus() == git.Paused {
+ return prefix + repoName + ws + yellow.Sprint("authentication required (u)")
+ } else if r.WorkStatus() == git.Fail {
+ return prefix + repoName + ws + red.Sprint(failSymbol) + ws + red.Sprint(r.State.Message)
+ }
+ return prefix + repoName
+}
+
+func commitLabel(c *git.Commit) string {
+ var body string
+ switch c.CommitType {
+ case git.EvenCommit:
+ body = cyan.Sprint(c.Hash[:hashLength]) + " " + c.Message
+ case git.LocalCommit:
+ body = blue.Sprint(c.Hash[:hashLength]) + " " + c.Message
+ case git.RemoteCommit:
+ if len(c.Hash) > hashLength {
+ body = yellow.Sprint(c.Hash[:hashLength]) + " " + c.Message
+ } else {
+ body = yellow.Sprint(c.Hash[:len(c.Hash)]) + " " + c.Message
+ }
+ default:
+ body = c.Hash[:hashLength] + " " + c.Message
+ }
+ return body
+}
+
+// limit the text length for visual concerns
+func adjustTextLength(text string, maxLength int) string {
+ if len(text) > maxLength {
+ return text[:maxLength-2] + ".."
+ }
+ return text
+}
+
+// colorize the plain diff text collected from system output
+// the style is near to original diff command
+func colorizeDiff(original string) (colorized []string) {
+ colorized = strings.Split(original, "\n")
+ re := regexp.MustCompile(`@@ .+ @@`)
+ for i, line := range colorized {
+ if len(line) > 0 {
+ if line[0] == '-' {
+ colorized[i] = red.Sprint(line)
+ } else if line[0] == '+' {
+ colorized[i] = green.Sprint(line)
+ } else if re.MatchString(line) {
+ s := re.FindString(line)
+ colorized[i] = cyan.Sprint(s) + line[len(s):]
+ } else {
+ continue
+ }
+ } else {
+ continue
+ }
+ }
+ return colorized
+}
+
+// the remote link can be too verbose sometimes, so it is good to trim it
+func trimRemoteURL(url string) (urltype string, shorturl string) {
+ // lets trim the unnecessary .git extension of the url
+ regit := regexp.MustCompile(`.git`)
+ if regit.MatchString(url[len(url)-4:]) {
+ url = url[:len(url)-4]
+ }
+
+ // find out the protocol
+ ressh := regexp.MustCompile(`git@`)
+ rehttp := regexp.MustCompile(`http://`)
+ rehttps := regexp.MustCompile(`https://`)
+
+ // separate the protocol and remote link
+ if ressh.MatchString(url) {
+ shorturl = ressh.Split(url, 5)[1]
+ urltype = "ssh"
+ } else if rehttp.MatchString(url) {
+ shorturl = rehttp.Split(url, 5)[1]
+ urltype = "http"
+ } else if rehttps.MatchString(url) {
+ shorturl = rehttps.Split(url, 5)[1]
+ urltype = "https"
+ }
+ return urltype, shorturl
+}