From 6e6d918bfe1e8da9232e11bb7ac79c3614c100c7 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 18 Jul 2018 16:16:28 -0700 Subject: [PATCH] CmdRunner now displays ANSI color codes --- Gopkg.lock | 24 +- cmdrunner/widget.go | 5 +- .../google/go-github/github/apps.go | 2 + .../go-github/github/github-accessors.go | 16 + .../google/go-github/github/github.go | 3 - .../google/go-github/github/licenses.go | 6 - .../google/go-github/github/pulls_comments.go | 28 +- .../google/go-github/github/repos.go | 12 +- .../google/go-github/github/repos_hooks.go | 16 +- vendor/github.com/pkg/profile/.travis.yml | 11 + vendor/github.com/pkg/profile/AUTHORS | 1 + vendor/github.com/pkg/profile/LICENSE | 24 ++ vendor/github.com/pkg/profile/README.md | 54 ++++ vendor/github.com/pkg/profile/mutex.go | 13 + vendor/github.com/pkg/profile/mutex17.go | 9 + vendor/github.com/pkg/profile/profile.go | 244 +++++++++++++++ vendor/github.com/pkg/profile/trace.go | 8 + vendor/github.com/pkg/profile/trace16.go | 10 + vendor/github.com/rivo/tview/README.md | 2 +- .../rivo/tview/{ansii.go => ansi.go} | 58 ++-- vendor/github.com/rivo/tview/form.go | 39 +++ vendor/github.com/xanzy/go-gitlab/tags.go | 8 +- weatherservices/prettyweather/colors.go | 32 -- weatherservices/prettyweather/widget.go | 2 +- wtf/colors.go | 286 ++++++++++++++++++ 25 files changed, 813 insertions(+), 100 deletions(-) create mode 100644 vendor/github.com/pkg/profile/.travis.yml create mode 100644 vendor/github.com/pkg/profile/AUTHORS create mode 100644 vendor/github.com/pkg/profile/LICENSE create mode 100644 vendor/github.com/pkg/profile/README.md create mode 100644 vendor/github.com/pkg/profile/mutex.go create mode 100644 vendor/github.com/pkg/profile/mutex17.go create mode 100644 vendor/github.com/pkg/profile/profile.go create mode 100644 vendor/github.com/pkg/profile/trace.go create mode 100644 vendor/github.com/pkg/profile/trace16.go rename vendor/github.com/rivo/tview/{ansii.go => ansi.go} (85%) delete mode 100644 weatherservices/prettyweather/colors.go diff --git a/Gopkg.lock b/Gopkg.lock index bfa5b6c7..6dc98de7 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -4,8 +4,8 @@ [[projects]] name = "cloud.google.com/go" packages = ["compute/metadata"] - revision = "777200caa7fb8936aed0f12b1fd79af64cc83ec9" - version = "v0.24.0" + revision = "aad3f485ee528456e0768f20397b4d9dd941e755" + version = "v0.25.0" [[projects]] branch = "master" @@ -62,7 +62,7 @@ branch = "master" name = "github.com/google/go-github" packages = ["github"] - revision = "60f2773bd99aa86164bc80bf370be6ba63b47dea" + revision = "c0b63e2f9bb198baf328c8abf1ddcbe05ff9427e" [[projects]] branch = "master" @@ -100,6 +100,12 @@ revision = "645ef00459ed84a119197bfb8d8205042c6df63d" version = "v0.8.0" +[[projects]] + name = "github.com/pkg/profile" + packages = ["."] + revision = "5b67d428864e92711fcbd2f8629456121a56d91f" + version = "v1.2.1" + [[projects]] name = "github.com/pmezard/go-difflib" packages = ["difflib"] @@ -116,7 +122,7 @@ branch = "master" name = "github.com/rivo/tview" packages = ["."] - revision = "83483397e826c343edb7b8c1f33fb7983dda9fc5" + revision = "c33dd0cf8ef840e1c8905c838d5b1ce93050a825" [[projects]] name = "github.com/stretchr/testify" @@ -125,10 +131,10 @@ version = "v1.2.2" [[projects]] + branch = "master" name = "github.com/xanzy/go-gitlab" packages = ["."] - revision = "79dad8e74fd097eb2e0fd0883f1978213e88107a" - version = "v0.10.7" + revision = "fb3ece09ef3e80cfa5c1e52dc75fcfb56c12e026" [[projects]] branch = "master" @@ -143,7 +149,7 @@ "context", "context/ctxhttp" ] - revision = "039a4258aec0ad3c79b905677cceeab13b296a77" + revision = "8887df42c721e930089d31b28391090a10a497d7" [[projects]] branch = "master" @@ -179,7 +185,7 @@ "googleapi/internal/uritemplates", "sheets/v4" ] - revision = "1d2d9cc0ae74226e8076e2a87e211c8fea38a160" + revision = "efcb5f25ac56eae06c8b5672456c0b7767522685" [[projects]] name = "google.golang.org/appengine" @@ -207,6 +213,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "9eaa70ed639c832e3cde26a4270f4c7b9124960952aa76506f702c2c296d5019" + inputs-digest = "8da356b338a76c5de5dce08eb73d808f139685850a2ef9ac3a9962197e36313f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/cmdrunner/widget.go b/cmdrunner/widget.go index 62183b4d..8318bd9a 100644 --- a/cmdrunner/widget.go +++ b/cmdrunner/widget.go @@ -5,6 +5,7 @@ import ( "os/exec" "strings" + "github.com/rivo/tview" "github.com/senorprogrammer/wtf/wtf" ) @@ -33,7 +34,7 @@ func (widget *Widget) Refresh() { widget.UpdateRefreshedAt() widget.execute() - title := wtf.Config.UString("wtf.mods.cmdrunner.title", widget.String()) + title := tview.TranslateANSI(wtf.Config.UString("wtf.mods.cmdrunner.title", widget.String())) widget.View.SetTitle(title) widget.View.SetText(widget.result) @@ -46,5 +47,5 @@ func (widget *Widget) String() string { func (widget *Widget) execute() { cmd := exec.Command(widget.cmd, widget.args...) - widget.result = wtf.ExecuteCommand(cmd) + widget.result = tview.TranslateANSI(wtf.ExecuteCommand(cmd)) } diff --git a/vendor/github.com/google/go-github/github/apps.go b/vendor/github.com/google/go-github/github/apps.go index 249a449b..dd5e5a7a 100644 --- a/vendor/github.com/google/go-github/github/apps.go +++ b/vendor/github.com/google/go-github/github/apps.go @@ -57,6 +57,8 @@ type Installation struct { RepositorySelection *string `json:"repository_selection,omitempty"` Events []string `json:"events,omitempty"` Permissions *InstallationPermissions `json:"permissions,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` } func (i Installation) String() string { diff --git a/vendor/github.com/google/go-github/github/github-accessors.go b/vendor/github.com/google/go-github/github/github-accessors.go index d9939c20..f99e5887 100644 --- a/vendor/github.com/google/go-github/github/github-accessors.go +++ b/vendor/github.com/google/go-github/github/github-accessors.go @@ -2828,6 +2828,14 @@ func (i *Installation) GetAppID() int64 { return *i.AppID } +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (i *Installation) GetCreatedAt() time.Time { + if i == nil || i.CreatedAt == nil { + return time.Time{} + } + return *i.CreatedAt +} + // GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. func (i *Installation) GetHTMLURL() string { if i == nil || i.HTMLURL == nil { @@ -2892,6 +2900,14 @@ func (i *Installation) GetTargetType() string { return *i.TargetType } +// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise. +func (i *Installation) GetUpdatedAt() time.Time { + if i == nil || i.UpdatedAt == nil { + return time.Time{} + } + return *i.UpdatedAt +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (i *InstallationEvent) GetAction() string { if i == nil || i.Action == nil { diff --git a/vendor/github.com/google/go-github/github/github.go b/vendor/github.com/google/go-github/github/github.go index a0c78aae..8b223541 100644 --- a/vendor/github.com/google/go-github/github/github.go +++ b/vendor/github.com/google/go-github/github/github.go @@ -45,9 +45,6 @@ const ( // Media Type values to access preview APIs - // https://developer.github.com/changes/2015-03-09-licenses-api/ - mediaTypeLicensesPreview = "application/vnd.github.drax-preview+json" - // https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/ mediaTypeStarringPreview = "application/vnd.github.v3.star+json" diff --git a/vendor/github.com/google/go-github/github/licenses.go b/vendor/github.com/google/go-github/github/licenses.go index e9cd1777..1176d3a8 100644 --- a/vendor/github.com/google/go-github/github/licenses.go +++ b/vendor/github.com/google/go-github/github/licenses.go @@ -67,9 +67,6 @@ func (s *LicensesService) List(ctx context.Context) ([]*License, *Response, erro return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeLicensesPreview) - var licenses []*License resp, err := s.client.Do(ctx, req, &licenses) if err != nil { @@ -90,9 +87,6 @@ func (s *LicensesService) Get(ctx context.Context, licenseName string) (*License return nil, nil, err } - // TODO: remove custom Accept header when this API fully launches - req.Header.Set("Accept", mediaTypeLicensesPreview) - license := new(License) resp, err := s.client.Do(ctx, req, license) if err != nil { diff --git a/vendor/github.com/google/go-github/github/pulls_comments.go b/vendor/github.com/google/go-github/github/pulls_comments.go index a7f8ac30..f3067762 100644 --- a/vendor/github.com/google/go-github/github/pulls_comments.go +++ b/vendor/github.com/google/go-github/github/pulls_comments.go @@ -14,7 +14,7 @@ import ( // PullRequestComment represents a comment left on a pull request. type PullRequestComment struct { ID *int64 `json:"id,omitempty"` - InReplyTo *int64 `json:"in_reply_to,omitempty"` + InReplyTo *int64 `json:"in_reply_to_id,omitempty"` Body *string `json:"body,omitempty"` Path *string `json:"path,omitempty"` DiffHunk *string `json:"diff_hunk,omitempty"` @@ -129,6 +129,32 @@ func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, r return c, resp, nil } +// CreateCommentInReplyTo creates a new comment as a reply to an existing pull request comment. +// +// GitHub API docs: https://developer.github.com/v3/pulls/comments/#alternative-input +func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner string, repo string, number int, body string, commentID int64) (*PullRequestComment, *Response, error) { + comment := &struct { + Body string `json:"body,omitempty"` + InReplyTo int64 `json:"in_reply_to,omitempty"` + }{ + Body: body, + InReplyTo: commentID, + } + u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number) + req, err := s.client.NewRequest("POST", u, comment) + if err != nil { + return nil, nil, err + } + + c := new(PullRequestComment) + resp, err := s.client.Do(ctx, req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + // EditComment updates a pull request comment. // A non-nil comment.Body must be provided. Other comment fields should be left nil. // diff --git a/vendor/github.com/google/go-github/github/repos.go b/vendor/github.com/google/go-github/github/repos.go index aa9b6ace..fce4ad54 100644 --- a/vendor/github.com/google/go-github/github/repos.go +++ b/vendor/github.com/google/go-github/github/repos.go @@ -178,7 +178,7 @@ func (s *RepositoriesService) List(ctx context.Context, user string, opt *Reposi } // TODO: remove custom Accept headers when APIs fully launch. - acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} + acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var repos []*Repository @@ -216,7 +216,7 @@ func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opt *Re } // TODO: remove custom Accept headers when APIs fully launch. - acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} + acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) var repos []*Repository @@ -297,7 +297,7 @@ func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Rep // TODO: remove custom Accept header when the license support fully launches // https://developer.github.com/v3/licenses/#get-a-repositorys-license - acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} + acceptHeaders := []string{mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview} req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) repository := new(Repository) @@ -341,10 +341,6 @@ func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repositor return nil, nil, err } - // TODO: remove custom Accept header when the license support fully launches - // https://developer.github.com/v3/licenses/#get-a-repositorys-license - req.Header.Set("Accept", mediaTypeLicensesPreview) - repository := new(Repository) resp, err := s.client.Do(ctx, req, repository) if err != nil { @@ -1018,7 +1014,7 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo // TransferRequest represents a request to transfer a repository. type TransferRequest struct { NewOwner string `json:"new_owner"` - TeamID []int64 `json:"team_id,omitempty"` + TeamID []int64 `json:"team_ids,omitempty"` } // Transfer transfers a repository from one account or organization to another. diff --git a/vendor/github.com/google/go-github/github/repos_hooks.go b/vendor/github.com/google/go-github/github/repos_hooks.go index f7ab3a13..1e9e8848 100644 --- a/vendor/github.com/google/go-github/github/repos_hooks.go +++ b/vendor/github.com/google/go-github/github/repos_hooks.go @@ -136,9 +136,13 @@ func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, i if err != nil { return nil, nil, err } - hook := new(Hook) - resp, err := s.client.Do(ctx, req, hook) - return hook, resp, err + h := new(Hook) + resp, err := s.client.Do(ctx, req, h) + if err != nil { + return nil, resp, err + } + + return h, resp, nil } // EditHook updates a specified Hook. @@ -152,7 +156,11 @@ func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, } h := new(Hook) resp, err := s.client.Do(ctx, req, h) - return h, resp, err + if err != nil { + return nil, resp, err + } + + return h, resp, nil } // DeleteHook deletes a specified Hook. diff --git a/vendor/github.com/pkg/profile/.travis.yml b/vendor/github.com/pkg/profile/.travis.yml new file mode 100644 index 00000000..192c5c27 --- /dev/null +++ b/vendor/github.com/pkg/profile/.travis.yml @@ -0,0 +1,11 @@ +language: go +go_import_path: github.com/pkg/profile +go: + - 1.4.3 + - 1.5.2 + - 1.6.3 + - tip + +script: + - go test github.com/pkg/profile + - go test -race github.com/pkg/profile diff --git a/vendor/github.com/pkg/profile/AUTHORS b/vendor/github.com/pkg/profile/AUTHORS new file mode 100644 index 00000000..00441d35 --- /dev/null +++ b/vendor/github.com/pkg/profile/AUTHORS @@ -0,0 +1 @@ +Dave Cheney diff --git a/vendor/github.com/pkg/profile/LICENSE b/vendor/github.com/pkg/profile/LICENSE new file mode 100644 index 00000000..f747a841 --- /dev/null +++ b/vendor/github.com/pkg/profile/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2013 Dave Cheney. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pkg/profile/README.md b/vendor/github.com/pkg/profile/README.md new file mode 100644 index 00000000..37bfa58c --- /dev/null +++ b/vendor/github.com/pkg/profile/README.md @@ -0,0 +1,54 @@ +profile +======= + +Simple profiling support package for Go + +[![Build Status](https://travis-ci.org/pkg/profile.svg?branch=master)](https://travis-ci.org/pkg/profile) [![GoDoc](http://godoc.org/github.com/pkg/profile?status.svg)](http://godoc.org/github.com/pkg/profile) + + +installation +------------ + + go get github.com/pkg/profile + +usage +----- + +Enabling profiling in your application is as simple as one line at the top of your main function + +```go +import "github.com/pkg/profile" + +func main() { + defer profile.Start().Stop() + ... +} +``` + +options +------- + +What to profile is controlled by config value passed to profile.Start. +By default CPU profiling is enabled. + +```go +import "github.com/pkg/profile" + +func main() { + // p.Stop() must be called before the program exits to + // ensure profiling information is written to disk. + p := profile.Start(profile.MemProfile, profile.ProfilePath("."), profile.NoShutdownHook) + ... +} +``` + +Several convenience package level values are provided for cpu, memory, and block (contention) profiling. + +For more complex options, consult the [documentation](http://godoc.org/github.com/pkg/profile). + +contributing +------------ + +We welcome pull requests, bug fixes and issue reports. + +Before proposing a change, please discuss it first by raising an issue. diff --git a/vendor/github.com/pkg/profile/mutex.go b/vendor/github.com/pkg/profile/mutex.go new file mode 100644 index 00000000..e69c5b44 --- /dev/null +++ b/vendor/github.com/pkg/profile/mutex.go @@ -0,0 +1,13 @@ +// +build go1.8 + +package profile + +import "runtime" + +func enableMutexProfile() { + runtime.SetMutexProfileFraction(1) +} + +func disableMutexProfile() { + runtime.SetMutexProfileFraction(0) +} diff --git a/vendor/github.com/pkg/profile/mutex17.go b/vendor/github.com/pkg/profile/mutex17.go new file mode 100644 index 00000000..b004c21d --- /dev/null +++ b/vendor/github.com/pkg/profile/mutex17.go @@ -0,0 +1,9 @@ +// +build !go1.8 + +package profile + +// mock mutex support for Go 1.7 and earlier. + +func enableMutexProfile() {} + +func disableMutexProfile() {} diff --git a/vendor/github.com/pkg/profile/profile.go b/vendor/github.com/pkg/profile/profile.go new file mode 100644 index 00000000..c44913a4 --- /dev/null +++ b/vendor/github.com/pkg/profile/profile.go @@ -0,0 +1,244 @@ +// Package profile provides a simple way to manage runtime/pprof +// profiling of your Go application. +package profile + +import ( + "io/ioutil" + "log" + "os" + "os/signal" + "path/filepath" + "runtime" + "runtime/pprof" + "sync/atomic" +) + +const ( + cpuMode = iota + memMode + mutexMode + blockMode + traceMode +) + +// Profile represents an active profiling session. +type Profile struct { + // quiet suppresses informational messages during profiling. + quiet bool + + // noShutdownHook controls whether the profiling package should + // hook SIGINT to write profiles cleanly. + noShutdownHook bool + + // mode holds the type of profiling that will be made + mode int + + // path holds the base path where various profiling files are written. + // If blank, the base path will be generated by ioutil.TempDir. + path string + + // memProfileRate holds the rate for the memory profile. + memProfileRate int + + // closer holds a cleanup function that run after each profile + closer func() + + // stopped records if a call to profile.Stop has been made + stopped uint32 +} + +// NoShutdownHook controls whether the profiling package should +// hook SIGINT to write profiles cleanly. +// Programs with more sophisticated signal handling should set +// this to true and ensure the Stop() function returned from Start() +// is called during shutdown. +func NoShutdownHook(p *Profile) { p.noShutdownHook = true } + +// Quiet suppresses informational messages during profiling. +func Quiet(p *Profile) { p.quiet = true } + +// CPUProfile enables cpu profiling. +// It disables any previous profiling settings. +func CPUProfile(p *Profile) { p.mode = cpuMode } + +// DefaultMemProfileRate is the default memory profiling rate. +// See also http://golang.org/pkg/runtime/#pkg-variables +const DefaultMemProfileRate = 4096 + +// MemProfile enables memory profiling. +// It disables any previous profiling settings. +func MemProfile(p *Profile) { + p.memProfileRate = DefaultMemProfileRate + p.mode = memMode +} + +// MemProfileRate enables memory profiling at the preferred rate. +// It disables any previous profiling settings. +func MemProfileRate(rate int) func(*Profile) { + return func(p *Profile) { + p.memProfileRate = rate + p.mode = memMode + } +} + +// MutexProfile enables mutex profiling. +// It disables any previous profiling settings. +// +// Mutex profiling is a no-op before go1.8. +func MutexProfile(p *Profile) { p.mode = mutexMode } + +// BlockProfile enables block (contention) profiling. +// It disables any previous profiling settings. +func BlockProfile(p *Profile) { p.mode = blockMode } + +// Trace profile controls if execution tracing will be enabled. It disables any previous profiling settings. +func TraceProfile(p *Profile) { p.mode = traceMode } + +// ProfilePath controls the base path where various profiling +// files are written. If blank, the base path will be generated +// by ioutil.TempDir. +func ProfilePath(path string) func(*Profile) { + return func(p *Profile) { + p.path = path + } +} + +// Stop stops the profile and flushes any unwritten data. +func (p *Profile) Stop() { + if !atomic.CompareAndSwapUint32(&p.stopped, 0, 1) { + // someone has already called close + return + } + p.closer() + atomic.StoreUint32(&started, 0) +} + +// started is non zero if a profile is running. +var started uint32 + +// Start starts a new profiling session. +// The caller should call the Stop method on the value returned +// to cleanly stop profiling. +func Start(options ...func(*Profile)) interface { + Stop() +} { + if !atomic.CompareAndSwapUint32(&started, 0, 1) { + log.Fatal("profile: Start() already called") + } + + var prof Profile + for _, option := range options { + option(&prof) + } + + path, err := func() (string, error) { + if p := prof.path; p != "" { + return p, os.MkdirAll(p, 0777) + } + return ioutil.TempDir("", "profile") + }() + + if err != nil { + log.Fatalf("profile: could not create initial output directory: %v", err) + } + + logf := func(format string, args ...interface{}) { + if !prof.quiet { + log.Printf(format, args...) + } + } + + switch prof.mode { + case cpuMode: + fn := filepath.Join(path, "cpu.pprof") + f, err := os.Create(fn) + if err != nil { + log.Fatalf("profile: could not create cpu profile %q: %v", fn, err) + } + logf("profile: cpu profiling enabled, %s", fn) + pprof.StartCPUProfile(f) + prof.closer = func() { + pprof.StopCPUProfile() + f.Close() + logf("profile: cpu profiling disabled, %s", fn) + } + + case memMode: + fn := filepath.Join(path, "mem.pprof") + f, err := os.Create(fn) + if err != nil { + log.Fatalf("profile: could not create memory profile %q: %v", fn, err) + } + old := runtime.MemProfileRate + runtime.MemProfileRate = prof.memProfileRate + logf("profile: memory profiling enabled (rate %d), %s", runtime.MemProfileRate, fn) + prof.closer = func() { + pprof.Lookup("heap").WriteTo(f, 0) + f.Close() + runtime.MemProfileRate = old + logf("profile: memory profiling disabled, %s", fn) + } + + case mutexMode: + fn := filepath.Join(path, "mutex.pprof") + f, err := os.Create(fn) + if err != nil { + log.Fatalf("profile: could not create mutex profile %q: %v", fn, err) + } + enableMutexProfile() + logf("profile: mutex profiling enabled, %s", fn) + prof.closer = func() { + if mp := pprof.Lookup("mutex"); mp != nil { + mp.WriteTo(f, 0) + } + f.Close() + disableMutexProfile() + logf("profile: mutex profiling disabled, %s", fn) + } + + case blockMode: + fn := filepath.Join(path, "block.pprof") + f, err := os.Create(fn) + if err != nil { + log.Fatalf("profile: could not create block profile %q: %v", fn, err) + } + runtime.SetBlockProfileRate(1) + logf("profile: block profiling enabled, %s", fn) + prof.closer = func() { + pprof.Lookup("block").WriteTo(f, 0) + f.Close() + runtime.SetBlockProfileRate(0) + logf("profile: block profiling disabled, %s", fn) + } + + case traceMode: + fn := filepath.Join(path, "trace.out") + f, err := os.Create(fn) + if err != nil { + log.Fatalf("profile: could not create trace output file %q: %v", fn, err) + } + if err := startTrace(f); err != nil { + log.Fatalf("profile: could not start trace: %v", err) + } + logf("profile: trace enabled, %s", fn) + prof.closer = func() { + stopTrace() + logf("profile: trace disabled, %s", fn) + } + } + + if !prof.noShutdownHook { + go func() { + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + <-c + + log.Println("profile: caught interrupt, stopping profiles") + prof.Stop() + + os.Exit(0) + }() + } + + return &prof +} diff --git a/vendor/github.com/pkg/profile/trace.go b/vendor/github.com/pkg/profile/trace.go new file mode 100644 index 00000000..b349ed8b --- /dev/null +++ b/vendor/github.com/pkg/profile/trace.go @@ -0,0 +1,8 @@ +// +build go1.7 + +package profile + +import "runtime/trace" + +var startTrace = trace.Start +var stopTrace = trace.Stop diff --git a/vendor/github.com/pkg/profile/trace16.go b/vendor/github.com/pkg/profile/trace16.go new file mode 100644 index 00000000..6aa6566e --- /dev/null +++ b/vendor/github.com/pkg/profile/trace16.go @@ -0,0 +1,10 @@ +// +build !go1.7 + +package profile + +import "io" + +// mock trace support for Go 1.6 and earlier. + +func startTrace(w io.Writer) error { return nil } +func stopTrace() {} diff --git a/vendor/github.com/rivo/tview/README.md b/vendor/github.com/rivo/tview/README.md index 89b866c4..e40fc3a0 100644 --- a/vendor/github.com/rivo/tview/README.md +++ b/vendor/github.com/rivo/tview/README.md @@ -71,7 +71,7 @@ Add your issue here on GitHub. Feel free to get in touch if you have any questio - `Flex` and `Grid` don't clear their background per default, thus allowing for custom modals. See the [Wiki](https://github.com/rivo/tview/wiki/Modal) for an example. - v0.14 (2018-04-13) - Added an `Escape()` function which keep strings like color or region tags from being recognized as such. - - Added `ANSIIWriter()` and `TranslateANSII()` which convert ANSII escape sequences to `tview` color tags. + - Added `ANSIWriter()` and `TranslateANSI()` which convert ANSI escape sequences to `tview` color tags. - v0.13 (2018-04-01) - Added background colors and text attributes to color tags. - v0.12 (2018-03-13) diff --git a/vendor/github.com/rivo/tview/ansii.go b/vendor/github.com/rivo/tview/ansi.go similarity index 85% rename from vendor/github.com/rivo/tview/ansii.go rename to vendor/github.com/rivo/tview/ansi.go index 0ce3d4a7..f5c6e833 100644 --- a/vendor/github.com/rivo/tview/ansii.go +++ b/vendor/github.com/rivo/tview/ansi.go @@ -8,44 +8,44 @@ import ( "strings" ) -// The states of the ANSII escape code parser. +// The states of the ANSI escape code parser. const ( - ansiiText = iota - ansiiEscape - ansiiSubstring - ansiiControlSequence + ansiText = iota + ansiEscape + ansiSubstring + ansiControlSequence ) -// ansii is a io.Writer which translates ANSII escape codes into tview color +// ansi is a io.Writer which translates ANSI escape codes into tview color // tags. -type ansii struct { +type ansi struct { io.Writer // Reusable buffers. buffer *bytes.Buffer // The entire output text of one Write(). csiParameter, csiIntermediate *bytes.Buffer // Partial CSI strings. - // The current state of the parser. One of the ansii constants. + // The current state of the parser. One of the ansi constants. state int } -// ANSIIWriter returns an io.Writer which translates any ANSII escape codes +// ANSIWriter returns an io.Writer which translates any ANSI escape codes // written to it into tview color tags. Other escape codes don't have an effect // and are simply removed. The translated text is written to the provided // writer. -func ANSIIWriter(writer io.Writer) io.Writer { - return &ansii{ +func ANSIWriter(writer io.Writer) io.Writer { + return &ansi{ Writer: writer, buffer: new(bytes.Buffer), csiParameter: new(bytes.Buffer), csiIntermediate: new(bytes.Buffer), - state: ansiiText, + state: ansiText, } } -// Write parses the given text as a string of runes, translates ANSII escape +// Write parses the given text as a string of runes, translates ANSI escape // codes to color tags and writes them to the output writer. -func (a *ansii) Write(text []byte) (int, error) { +func (a *ansi) Write(text []byte) (int, error) { defer func() { a.buffer.Reset() }() @@ -54,23 +54,23 @@ func (a *ansii) Write(text []byte) (int, error) { switch a.state { // We just entered an escape sequence. - case ansiiEscape: + case ansiEscape: switch r { case '[': // Control Sequence Introducer. a.csiParameter.Reset() a.csiIntermediate.Reset() - a.state = ansiiControlSequence + a.state = ansiControlSequence case 'c': // Reset. fmt.Fprint(a.buffer, "[-:-:-]") - a.state = ansiiText + a.state = ansiText case 'P', ']', 'X', '^', '_': // Substrings and commands. - a.state = ansiiSubstring + a.state = ansiSubstring default: // Ignore. - a.state = ansiiText + a.state = ansiText } // CSI Sequences. - case ansiiControlSequence: + case ansiControlSequence: switch { case r >= 0x30 && r <= 0x3f: // Parameter bytes. if _, err := a.csiParameter.WriteRune(r); err != nil { @@ -194,22 +194,22 @@ func (a *ansii) Write(text []byte) (int, error) { fmt.Fprintf(a.buffer, "[%s:%s%s]", foreground, background, attributes) } } - a.state = ansiiText + a.state = ansiText default: // Undefined byte. - a.state = ansiiText // Abort CSI. + a.state = ansiText // Abort CSI. } // We just entered a substring/command sequence. - case ansiiSubstring: + case ansiSubstring: if r == 27 { // Most likely the end of the substring. - a.state = ansiiEscape + a.state = ansiEscape } // Ignore all other characters. - // "ansiiText" and all others. + // "ansiText" and all others. default: if r == 27 { // This is the start of an escape sequence. - a.state = ansiiEscape + a.state = ansiEscape } else { // Just a regular rune. Send to buffer. if _, err := a.buffer.WriteRune(r); err != nil { @@ -227,11 +227,11 @@ func (a *ansii) Write(text []byte) (int, error) { return len(text), nil } -// TranslateANSII replaces ANSII escape sequences found in the provided string +// TranslateANSI replaces ANSI escape sequences found in the provided string // with tview's color tags and returns the resulting string. -func TranslateANSII(text string) string { +func TranslateANSI(text string) string { var buffer bytes.Buffer - writer := ANSIIWriter(&buffer) + writer := ANSIWriter(&buffer) writer.Write([]byte(text)) return buffer.String() } diff --git a/vendor/github.com/rivo/tview/form.go b/vendor/github.com/rivo/tview/form.go index d778a6a0..0fcc0479 100644 --- a/vendor/github.com/rivo/tview/form.go +++ b/vendor/github.com/rivo/tview/form.go @@ -218,6 +218,25 @@ func (f *Form) AddButton(label string, selected func()) *Form { return f } +// RemoveButton removes the button at the specified position, starting with 0 +// for the button that was added first. +func (f *Form) RemoveButton(index int) *Form { + f.buttons = append(f.buttons[:index], f.buttons[index+1:]...) + return f +} + +// GetButtonIndex returns the index of the button with the given label, starting +// with 0 for the button that was added first. If no such label was found, -1 +// is returned. +func (f *Form) GetButtonIndex(label string) int { + for index, button := range f.buttons { + if button.GetLabel() == label { + return index + } + } + return -1 +} + // Clear removes all input elements from the form, including the buttons if // specified. func (f *Form) Clear(includeButtons bool) *Form { @@ -251,6 +270,14 @@ func (f *Form) GetFormItem(index int) FormItem { return f.items[index] } +// RemoveFormItem removes the form element at the given position, starting with +// index 0. Elements are referenced in the order they were added. Buttons are +// not included. +func (f *Form) RemoveFormItem(index int) *Form { + f.items = append(f.items[:index], f.items[index+1:]...) + return f +} + // GetFormItemByLabel returns the first form element with the given label. If // no such element is found, nil is returned. Buttons are not searched and will // therefore not be returned. @@ -263,6 +290,18 @@ func (f *Form) GetFormItemByLabel(label string) FormItem { return nil } +// GetFormItemIndex returns the index of the first form element with the given +// label. If no such element is found, -1 is returned. Buttons are not searched +// and will therefore not be returned. +func (f *Form) GetFormItemIndex(label string) int { + for index, item := range f.items { + if item.GetLabel() == label { + return index + } + } + return -1 +} + // SetCancelFunc sets a handler which is called when the user hits the Escape // key. func (f *Form) SetCancelFunc(callback func()) *Form { diff --git a/vendor/github.com/xanzy/go-gitlab/tags.go b/vendor/github.com/xanzy/go-gitlab/tags.go index b726410e..d3ac9dec 100644 --- a/vendor/github.com/xanzy/go-gitlab/tags.go +++ b/vendor/github.com/xanzy/go-gitlab/tags.go @@ -93,7 +93,7 @@ func (s *TagsService) GetTag(pid interface{}, tag string, options ...OptionFunc) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), tag) + u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), url.QueryEscape(tag)) req, err := s.client.NewRequest("GET", u, nil, options) if err != nil { @@ -154,7 +154,7 @@ func (s *TagsService) DeleteTag(pid interface{}, tag string, options ...OptionFu if err != nil { return nil, err } - u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), tag) + u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), url.QueryEscape(tag)) req, err := s.client.NewRequest("DELETE", u, nil, options) if err != nil { @@ -182,7 +182,7 @@ func (s *TagsService) CreateRelease(pid interface{}, tag string, opt *CreateRele if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/repository/tags/%s/release", url.QueryEscape(project), tag) + u := fmt.Sprintf("projects/%s/repository/tags/%s/release", url.QueryEscape(project), url.QueryEscape(tag)) req, err := s.client.NewRequest("POST", u, opt, options) if err != nil { @@ -215,7 +215,7 @@ func (s *TagsService) UpdateRelease(pid interface{}, tag string, opt *UpdateRele if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/repository/tags/%s/release", url.QueryEscape(project), tag) + u := fmt.Sprintf("projects/%s/repository/tags/%s/release", url.QueryEscape(project), url.QueryEscape(tag)) req, err := s.client.NewRequest("PUT", u, opt, options) if err != nil { diff --git a/weatherservices/prettyweather/colors.go b/weatherservices/prettyweather/colors.go deleted file mode 100644 index f54746be..00000000 --- a/weatherservices/prettyweather/colors.go +++ /dev/null @@ -1,32 +0,0 @@ -package prettyweather - -import ( - "regexp" - "strconv" -) - -var colors = map[int]string{0: "#000000", 1: "#800000", 2: "#008000", 3: "#808000", 4: "#000080", 5: "#800080", 6: "#008080", 7: "#c0c0c0", 8: "#808080", 9: "#ff0000", 10: "#00ff00", 11: "#ffff00", 12: "#0000ff", 13: "#ff00ff", 14: "#00ffff", 15: "#ffffff", 16: "#000000", 17: "#00005f", 18: "#000087", 19: "#0000af", 20: "#0000d7", 21: "#0000ff", 22: "#005f00", 23: "#005f5f", 24: "#005f87", 25: "#005faf", 26: "#005fd7", 27: "#005fff", 28: "#008700", 29: "#00875f", 30: "#008787", 31: "#0087af", 32: "#0087d7", 33: "#0087ff", 34: "#00af00", 35: "#00af5f", 36: "#00af87", 37: "#00afaf", 38: "#00afd7", 39: "#00afff", 40: "#00d700", 41: "#00d75f", 42: "#00d787", 43: "#00d7af", 44: "#00d7d7", 45: "#00d7ff", 46: "#00ff00", 47: "#00ff5f", 48: "#00ff87", 49: "#00ffaf", 50: "#00ffd7", 51: "#00ffff", 52: "#5f0000", 53: "#5f005f", 54: "#5f0087", 55: "#5f00af", 56: "#5f00d7", 57: "#5f00ff", 58: "#5f5f00", 59: "#5f5f5f", 60: "#5f5f87", 61: "#5f5faf", 62: "#5f5fd7", 63: "#5f5fff", 64: "#5f8700", 65: "#5f875f", 66: "#5f8787", 67: "#5f87af", 68: "#5f87d7", 69: "#5f87ff", 70: "#5faf00", 71: "#5faf5f", 72: "#5faf87", 73: "#5fafaf", 74: "#5fafd7", 75: "#5fafff", 76: "#5fd700", 77: "#5fd75f", 78: "#5fd787", 79: "#5fd7af", 80: "#5fd7d7", 81: "#5fd7ff", 82: "#5fff00", 83: "#5fff5f", 84: "#5fff87", 85: "#5fffaf", 86: "#5fffd7", 87: "#5fffff", 88: "#870000", 89: "#87005f", 90: "#870087", 91: "#8700af", 92: "#8700d7", 93: "#8700ff", 94: "#875f00", 95: "#875f5f", 96: "#875f87", 97: "#875faf", 98: "#875fd7", 99: "#875fff", 100: "#878700", 101: "#87875f", 102: "#878787", 103: "#8787af", 104: "#8787d7", 105: "#8787ff", 106: "#87af00", 107: "#87af5f", 108: "#87af87", 109: "#87afaf", 110: "#87afd7", 111: "#87afff", 112: "#87d700", 113: "#87d75f", 114: "#87d787", 115: "#87d7af", 116: "#87d7d7", 117: "#87d7ff", 118: "#87ff00", 119: "#87ff5f", 120: "#87ff87", 121: "#87ffaf", 122: "#87ffd7", 123: "#87ffff", 124: "#af0000", 125: "#af005f", 126: "#af0087", 127: "#af00af", 128: "#af00d7", 129: "#af00ff", 130: "#af5f00", 131: "#af5f5f", 132: "#af5f87", 133: "#af5faf", 134: "#af5fd7", 135: "#af5fff", 136: "#af8700", 137: "#af875f", 138: "#af8787", 139: "#af87af", 140: "#af87d7", 141: "#af87ff", 142: "#afaf00", 143: "#afaf5f", 144: "#afaf87", 145: "#afafaf", 146: "#afafd7", 147: "#afafff", 148: "#afd700", 149: "#afd75f", 150: "#afd787", 151: "#afd7af", 152: "#afd7d7", 153: "#afd7ff", 154: "#afff00", 155: "#afff5f", 156: "#afff87", 157: "#afffaf", 158: "#afffd7", 159: "#afffff", 160: "#d70000", 161: "#d7005f", 162: "#d70087", 163: "#d700af", 164: "#d700d7", 165: "#d700ff", 166: "#d75f00", 167: "#d75f5f", 168: "#d75f87", 169: "#d75faf", 170: "#d75fd7", 171: "#d75fff", 172: "#d78700", 173: "#d7875f", 174: "#d78787", 175: "#d787af", 176: "#d787d7", 177: "#d787ff", 178: "#d7af00", 179: "#d7af5f", 180: "#d7af87", 181: "#d7afaf", 182: "#d7afd7", 183: "#d7afff", 184: "#d7d700", 185: "#d7d75f", 186: "#d7d787", 187: "#d7d7af", 188: "#d7d7d7", 189: "#d7d7ff", 190: "#d7ff00", 191: "#d7ff5f", 192: "#d7ff87", 193: "#d7ffaf", 194: "#d7ffd7", 195: "#d7ffff", 196: "#ff0000", 197: "#ff005f", 198: "#ff0087", 199: "#ff00af", 200: "#ff00d7", 201: "#ff00ff", 202: "#ff5f00", 203: "#ff5f5f", 204: "#ff5f87", 205: "#ff5faf", 206: "#ff5fd7", 207: "#ff5fff", 208: "#ff8700", 209: "#ff875f", 210: "#ff8787", 211: "#ff87af", 212: "#ff87d7", 213: "#ff87ff", 214: "#ffaf00", 215: "#ffaf5f", 216: "#ffaf87", 217: "#ffafaf", 218: "#ffafd7", 219: "#ffafff", 220: "#ffd700", 221: "#ffd75f", 222: "#ffd787", 223: "#ffd7af", 224: "#ffd7d7", 225: "#ffd7ff", 226: "#ffff00", 227: "#ffff5f", 228: "#ffff87", 229: "#ffffaf", 230: "#ffffd7", 231: "#ffffff", 232: "#080808", 233: "#121212", 234: "#1c1c1c", 235: "#262626", 236: "#303030", 237: "#3a3a3a", 238: "#444444", 239: "#4e4e4e", 240: "#585858", 241: "#626262", 242: "#6c6c6c", 243: "#767676", 244: "#808080", 245: "#8a8a8a", 246: "#949494", 247: "#9e9e9e", 248: "#a8a8a8", 249: "#b2b2b2", 250: "#bcbcbc", 251: "#c6c6c6", 252: "#d0d0d0", 253: "#dadada", 254: "#e4e4e4", 255: "#eeeeee"} - -func ASCIItoTviewColors(text string) string { - fgColorRegExp := regexp.MustCompile(`\033\[38;5;(?P\d+)m`) - // bgColorRegExp := regexp.MustCompile(`\033\[48;5;(?P\d+)m`) - boldRegExp := regexp.MustCompile(`\033\[1m`) - resColorRegExp := regexp.MustCompile(`\033\[0m`) - - return resColorRegExp.ReplaceAllString( - boldRegExp.ReplaceAllString( - fgColorRegExp.ReplaceAllStringFunc( - text, replaceWithHexColorString), `[::b]`), `[-]`) -} - -/* -------------------- Unexported Functions -------------------- */ -func replaceWithHexColorString(substring string) string { - colorID, err := strconv.Atoi(substring[7 : len(substring)-1]) - if err != nil { - return substring - } - - hexColor := "[" + colors[colorID] + "]" - - return hexColor -} diff --git a/weatherservices/prettyweather/widget.go b/weatherservices/prettyweather/widget.go index f5f58ff5..44f9e340 100644 --- a/weatherservices/prettyweather/widget.go +++ b/weatherservices/prettyweather/widget.go @@ -59,5 +59,5 @@ func (widget *Widget) prettyWeather() { } //widget.result = strings.TrimSpace(string(contents)) - widget.result = strings.TrimSpace(ASCIItoTviewColors(string(contents))) + widget.result = strings.TrimSpace(wtf.ASCIItoTviewColors(string(contents))) } diff --git a/wtf/colors.go b/wtf/colors.go index 406e67be..0686d517 100644 --- a/wtf/colors.go +++ b/wtf/colors.go @@ -1,9 +1,271 @@ package wtf import ( + "regexp" + "strconv" + "github.com/gdamore/tcell" ) +var colorMap = map[int]string{ + 0: "#000000", + 1: "#800000", + 2: "#008000", + 3: "#808000", + 4: "#000080", + 5: "#800080", + 6: "#008080", + 7: "#c0c0c0", + 8: "#808080", + 9: "#ff0000", + 10: "#00ff00", + 11: "#ffff00", + 12: "#0000ff", + 13: "#ff00ff", + 14: "#00ffff", + 15: "#ffffff", + 16: "#000000", + 17: "#00005f", + 18: "#000087", + 19: "#0000af", + 20: "#0000d7", + 21: "#0000ff", + 22: "#005f00", + 23: "#005f5f", + 24: "#005f87", + 25: "#005faf", + 26: "#005fd7", + 27: "#005fff", + 28: "#008700", + 29: "#00875f", + 30: "#008787", + 31: "#0087af", + 32: "#0087d7", + 33: "#0087ff", + 34: "#00af00", + 35: "#00af5f", + 36: "#00af87", + 37: "#00afaf", + 38: "#00afd7", + 39: "#00afff", + 40: "#00d700", + 41: "#00d75f", + 42: "#00d787", + 43: "#00d7af", + 44: "#00d7d7", + 45: "#00d7ff", + 46: "#00ff00", + 47: "#00ff5f", + 48: "#00ff87", + 49: "#00ffaf", + 50: "#00ffd7", + 51: "#00ffff", + 52: "#5f0000", + 53: "#5f005f", + 54: "#5f0087", + 55: "#5f00af", + 56: "#5f00d7", + 57: "#5f00ff", + 58: "#5f5f00", + 59: "#5f5f5f", + 60: "#5f5f87", + 61: "#5f5faf", + 62: "#5f5fd7", + 63: "#5f5fff", + 64: "#5f8700", + 65: "#5f875f", + 66: "#5f8787", + 67: "#5f87af", + 68: "#5f87d7", + 69: "#5f87ff", + 70: "#5faf00", + 71: "#5faf5f", + 72: "#5faf87", + 73: "#5fafaf", + 74: "#5fafd7", + 75: "#5fafff", + 76: "#5fd700", + 77: "#5fd75f", + 78: "#5fd787", + 79: "#5fd7af", + 80: "#5fd7d7", + 81: "#5fd7ff", + 82: "#5fff00", + 83: "#5fff5f", + 84: "#5fff87", + 85: "#5fffaf", + 86: "#5fffd7", + 87: "#5fffff", + 88: "#870000", + 89: "#87005f", + 90: "#870087", + 91: "#8700af", + 92: "#8700d7", + 93: "#8700ff", + 94: "#875f00", + 95: "#875f5f", + 96: "#875f87", + 97: "#875faf", + 98: "#875fd7", + 99: "#875fff", + 100: "#878700", + 101: "#87875f", + 102: "#878787", + 103: "#8787af", + 104: "#8787d7", + 105: "#8787ff", + 106: "#87af00", + 107: "#87af5f", + 108: "#87af87", + 109: "#87afaf", + 110: "#87afd7", + 111: "#87afff", + 112: "#87d700", + 113: "#87d75f", + 114: "#87d787", + 115: "#87d7af", + 116: "#87d7d7", + 117: "#87d7ff", + 118: "#87ff00", + 119: "#87ff5f", + 120: "#87ff87", + 121: "#87ffaf", + 122: "#87ffd7", + 123: "#87ffff", + 124: "#af0000", + 125: "#af005f", + 126: "#af0087", + 127: "#af00af", + 128: "#af00d7", + 129: "#af00ff", + 130: "#af5f00", + 131: "#af5f5f", + 132: "#af5f87", + 133: "#af5faf", + 134: "#af5fd7", + 135: "#af5fff", + 136: "#af8700", + 137: "#af875f", + 138: "#af8787", + 139: "#af87af", + 140: "#af87d7", + 141: "#af87ff", + 142: "#afaf00", + 143: "#afaf5f", + 144: "#afaf87", + 145: "#afafaf", + 146: "#afafd7", + 147: "#afafff", + 148: "#afd700", + 149: "#afd75f", + 150: "#afd787", + 151: "#afd7af", + 152: "#afd7d7", + 153: "#afd7ff", + 154: "#afff00", + 155: "#afff5f", + 156: "#afff87", + 157: "#afffaf", + 158: "#afffd7", + 159: "#afffff", + 160: "#d70000", + 161: "#d7005f", + 162: "#d70087", + 163: "#d700af", + 164: "#d700d7", + 165: "#d700ff", + 166: "#d75f00", + 167: "#d75f5f", + 168: "#d75f87", + 169: "#d75faf", + 170: "#d75fd7", + 171: "#d75fff", + 172: "#d78700", + 173: "#d7875f", + 174: "#d78787", + 175: "#d787af", + 176: "#d787d7", + 177: "#d787ff", + 178: "#d7af00", + 179: "#d7af5f", + 180: "#d7af87", + 181: "#d7afaf", + 182: "#d7afd7", + 183: "#d7afff", + 184: "#d7d700", + 185: "#d7d75f", + 186: "#d7d787", + 187: "#d7d7af", + 188: "#d7d7d7", + 189: "#d7d7ff", + 190: "#d7ff00", + 191: "#d7ff5f", + 192: "#d7ff87", + 193: "#d7ffaf", + 194: "#d7ffd7", + 195: "#d7ffff", + 196: "#ff0000", + 197: "#ff005f", + 198: "#ff0087", + 199: "#ff00af", + 200: "#ff00d7", + 201: "#ff00ff", + 202: "#ff5f00", + 203: "#ff5f5f", + 204: "#ff5f87", + 205: "#ff5faf", + 206: "#ff5fd7", + 207: "#ff5fff", + 208: "#ff8700", + 209: "#ff875f", + 210: "#ff8787", + 211: "#ff87af", + 212: "#ff87d7", + 213: "#ff87ff", + 214: "#ffaf00", + 215: "#ffaf5f", + 216: "#ffaf87", + 217: "#ffafaf", + 218: "#ffafd7", + 219: "#ffafff", + 220: "#ffd700", + 221: "#ffd75f", + 222: "#ffd787", + 223: "#ffd7af", + 224: "#ffd7d7", + 225: "#ffd7ff", + 226: "#ffff00", + 227: "#ffff5f", + 228: "#ffff87", + 229: "#ffffaf", + 230: "#ffffd7", + 231: "#ffffff", + 232: "#080808", + 233: "#121212", + 234: "#1c1c1c", + 235: "#262626", + 236: "#303030", + 237: "#3a3a3a", + 238: "#444444", + 239: "#4e4e4e", + 240: "#585858", + 241: "#626262", + 242: "#6c6c6c", + 243: "#767676", + 244: "#808080", + 245: "#8a8a8a", + 246: "#949494", + 247: "#9e9e9e", + 248: "#a8a8a8", + 249: "#b2b2b2", + 250: "#bcbcbc", + 251: "#c6c6c6", + 252: "#d0d0d0", + 253: "#dadada", + 254: "#e4e4e4", + 255: "#eeeeee", +} + var colors = map[string]tcell.Color{ "aliceblue": tcell.ColorAliceBlue, "antiquewhite": tcell.ColorAntiqueWhite, @@ -147,6 +409,17 @@ var colors = map[string]tcell.Color{ "yellowgreen": tcell.ColorYellowGreen, } +func ASCIItoTviewColors(text string) string { + boldRegExp := regexp.MustCompile(`\033\[1m`) + fgColorRegExp := regexp.MustCompile(`\033\[38;5;(?P\d+)m`) + resColorRegExp := regexp.MustCompile(`\033\[0m`) + + return resColorRegExp.ReplaceAllString( + boldRegExp.ReplaceAllString( + fgColorRegExp.ReplaceAllStringFunc( + text, replaceWithHexColorString), `[::b]`), `[-]`) +} + func ColorFor(label string) tcell.Color { if _, ok := colors[label]; ok { return colors[label] @@ -154,3 +427,16 @@ func ColorFor(label string) tcell.Color { return tcell.ColorGreen } } + +/* -------------------- Unexported Functions -------------------- */ + +func replaceWithHexColorString(substring string) string { + colorID, err := strconv.Atoi(substring[7 : len(substring)-1]) + if err != nil { + return substring + } + + hexColor := "[" + colorMap[colorID] + "]" + + return hexColor +}