Skip to content

Commit

Permalink
support custom progress color
Browse files Browse the repository at this point in the history
  • Loading branch information
lonnywong committed Jul 14, 2024
1 parent bb31ecf commit 615fd3d
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 22 deletions.
3 changes: 3 additions & 0 deletions README.cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ _有关 `trzsz ( trz / tsz )` 更详细的文档,请查看 [https://trzsz.gith
DefaultUploadPath =
DefaultDownloadPath = /Users/username/Downloads/
DragFileUploadCommand = trz -y
ProgressColorPair = B14FFF 00FFA3
```
- 如果 `DefaultUploadPath` 不为空,上传选择文件时会默认打开此目录。
Expand All @@ -213,6 +214,8 @@ DragFileUploadCommand = trz -y
- `DragFileUploadCommand` 的默认值是 `trz`,如果想上传时覆盖现有文件可配置成 `trz -y`,如果想使用 `rz` 上传可配置成 `rz`。
- `ProgressColorPair` 配置进度条的颜色,需要配置 2 个颜色并且不要带 `#`,进度条将从第一个颜色渐变到第二个颜色。
## 常见问题
- 如果 [MSYS2](https://www.msys2.org/) 或 [Git Bash](https://www.atlassian.com/git/tutorials/git-bash) 遇到错误 `The handle is invalid`。
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ _Please check [https://trzsz.github.io](https://trzsz.github.io) for more inform
DefaultUploadPath =
DefaultDownloadPath = /Users/username/Downloads/
DragFileUploadCommand = trz -y
ProgressColorPair = B14FFF 00FFA3
```
- If the `DefaultUploadPath` is not empty, the path will be opened by default while choosing upload files.
Expand All @@ -213,6 +214,8 @@ DragFileUploadCommand = trz -y
- The default value of `DragFileUploadCommand` is `trz`, configure it to `trz -y` if you want to overwrite the existing files, configure it to `rz` if you want to use `rz` to upload.
- The `ProgressColorPair` configures the color of the progress bar. You need to configure 2 colors and do not include `#`. The progress bar will gradient from the first color to the second color.
## Trouble shooting
- If using [MSYS2](https://www.msys2.org/) or [Git Bash](https://www.atlassian.com/git/tutorials/git-bash) on windows, and getting an error `The handle is invalid`.
Expand Down
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ go 1.20
require (
github.com/UserExistsError/conpty v0.1.4
github.com/atotto/clipboard v0.1.4
github.com/charmbracelet/lipgloss v0.12.1
github.com/creack/pty v1.1.21
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/klauspost/compress v1.17.9
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mattn/go-runewidth v0.0.15
github.com/ncruces/zenity v0.10.13
github.com/stretchr/testify v1.8.4
Expand All @@ -21,10 +23,14 @@ require (
require (
github.com/akavel/rsrc v0.10.2 // indirect
github.com/alexflint/go-scalar v1.2.0 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/x/ansi v0.1.4 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f // indirect
github.com/josephspurrier/goversioninfo v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
Expand Down
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ github.com/alexflint/go-scalar v1.2.0 h1:WR7JPKkeNpnYIOfHRa7ivM21aWAdHD0gEWHCx+W
github.com/alexflint/go-scalar v1.2.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs=
github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8=
github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM=
github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
Expand All @@ -25,8 +31,14 @@ github.com/josephspurrier/goversioninfo v1.4.0 h1:Puhl12NSHUSALHSuzYwPYQkqa2E1+7
github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/ncruces/zenity v0.10.13 h1:0Gd/EdjjEQIhrFaJ05Q5ZvyjlcjnorlZpdzgUzqQIH0=
github.com/ncruces/zenity v0.10.13/go.mod h1:UyAUPSjHm1hOdeZa3Lrh/zmItyGq+iH5AP6xSCx8CFM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -50,6 +62,7 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
Expand Down
14 changes: 13 additions & 1 deletion trzsz/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ type TrzszFilter struct {
currentUploadCommand atomic.Pointer[string]
tunnelConnector atomic.Pointer[func(int) net.Conn]
osc52Sequence *bytes.Buffer
progressColorPair atomic.Pointer[string]
}

// NewTrzszFilter create a TrzszFilter to support trzsz ( trz / tsz ).
Expand Down Expand Up @@ -203,6 +204,11 @@ func (filter *TrzszFilter) SetDragFileUploadCommand(command string) {
filter.dragFileUploadCommand.Store(&command)
}

// SetProgressColorPair set the color pair for the progress bar.
func (filter *TrzszFilter) SetProgressColorPair(colorPair string) {
filter.progressColorPair.Store(&colorPair)
}

// SetTunnelConnector set the connector for tunnel transferring.
func (filter *TrzszFilter) SetTunnelConnector(connector func(int) net.Conn) {
if connector == nil {
Expand Down Expand Up @@ -245,6 +251,8 @@ func (filter *TrzszFilter) readTrzszConfig() {
filter.SetDefaultDownloadPath(value)
case name == "dragfileuploadcommand" && filter.dragFileUploadCommand.Load() == nil:
filter.SetDragFileUploadCommand(value)
case name == "progresscolorpair" && filter.progressColorPair.Load() == nil:
filter.SetProgressColorPair(value)
}
}
}
Expand Down Expand Up @@ -343,8 +351,12 @@ func (filter *TrzszFilter) createProgressBar(quiet bool, tmuxPaneColumns int32)
filter.progress.Store(nil)
return
}
colorPair := ""
if color := filter.progressColorPair.Load(); color != nil {
colorPair = *color
}
filter.progress.Store(newTextProgressBar(filter.clientOut, filter.options.TerminalColumns,
tmuxPaneColumns, filter.trigger.tmuxPrefix))
tmuxPaneColumns, filter.trigger.tmuxPrefix, colorPair))
}

func (filter *TrzszFilter) resetProgressBar() {
Expand Down
40 changes: 34 additions & 6 deletions trzsz/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import (
"sync/atomic"
"time"

"github.com/charmbracelet/lipgloss"
"github.com/lucasb-eyer/go-colorful"
"github.com/mattn/go-runewidth"
)

Expand Down Expand Up @@ -171,15 +173,27 @@ type textProgressBar struct {
recentSpeed recentSpeed
pausing atomic.Bool
tmuxPrefix string
colorA *colorful.Color
colorB *colorful.Color
}

func newTextProgressBar(writer io.Writer, columns int32, tmuxPaneColumns int32, tmuxPrefix string) *textProgressBar {
func newTextProgressBar(writer io.Writer, columns int32, tmuxPaneColumns int32,
tmuxPrefix, colorPair string) *textProgressBar {
if tmuxPaneColumns > 1 {
columns = tmuxPaneColumns - 1 // -1 to avoid messing up the tmux pane
}
progress := &textProgressBar{writer: writer, firstWrite: true, tmuxPrefix: tmuxPrefix}
progress.columns.Store(columns)
progress.tmuxPaneColumns.Store(tmuxPaneColumns)
colors := strings.Fields(colorPair)
if len(colors) == 2 {
if colorA, err := colorful.Hex("#" + colors[0]); err == nil {
progress.colorA = &colorA
}
if colorB, err := colorful.Hex("#" + colors[1]); err == nil {
progress.colorB = &colorB
}
}
return progress
}

Expand Down Expand Up @@ -390,10 +404,24 @@ func (p *textProgressBar) getProgressBar(length int) string {
if length < 12 {
return ""
}
total := length - 2
complete := total
totalSize := length - 2
fullSize := totalSize
if p.fileSize != 0 {
complete = int(math.Round((float64(total) * float64(p.fileStep)) / float64(p.fileSize)))
}
return "[\u001b[36m" + strings.Repeat("\u2588", complete) + strings.Repeat("\u2591", total-complete) + "\u001b[0m]"
fullSize = int(math.Round((float64(totalSize) * float64(p.fileStep)) / float64(p.fileSize)))
}
emptySize := totalSize - fullSize
if p.colorA == nil || p.colorB == nil {
return fmt.Sprintf("[\x1b[36m%s%s\x1b[0m]",
strings.Repeat("\u2588", fullSize), strings.Repeat("\u2591", emptySize))
}
var buf strings.Builder
buf.WriteString("[")
for i := 0; i < fullSize; i++ {
color := p.colorA.BlendLuv(*p.colorB, float64(i)/float64(totalSize))
render := lipgloss.NewStyle().Foreground(lipgloss.Color(color.Hex()))
buf.WriteString(render.Render("\u2588"))
}
buf.WriteString(strings.Repeat("\u2591", emptySize))
buf.WriteString("]")
return buf.String()
}
30 changes: 15 additions & 15 deletions trzsz/progress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestProgressWithEmptyFile(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564135000}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(0)
Expand All @@ -88,7 +88,7 @@ func TestProgressZeroStep(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564135100}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(100)
Expand All @@ -104,7 +104,7 @@ func TestProgressLastStep(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564135200}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(100)
Expand All @@ -120,7 +120,7 @@ func TestProgressWithSpeedAndEta(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564135100}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(100)
Expand All @@ -141,7 +141,7 @@ func TestProgressNewestSpeed(t *testing.T) {
}
callTimeNowCount := mockTimeNow(mockTimes, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(100000)
Expand Down Expand Up @@ -200,7 +200,7 @@ func TestProgressReduceOutput(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564135001, 1646564135099}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(100)
Expand All @@ -217,7 +217,7 @@ func TestProgressFastSpeed(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(1125899906842624)
Expand All @@ -233,7 +233,7 @@ func TestProgressSlowSpeed(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(1024 * 1024)
Expand All @@ -249,7 +249,7 @@ func TestProgressLongFileName(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000, 1646564138000}, 0)

progress := newTextProgressBar(writer, 110, 0, "")
progress := newTextProgressBar(writer, 110, 0, "", "")
progress.onNum(1)
progress.onName("中文😀非常长非常长非常长非常长非常长非常长非常长非常长.txt")
progress.onSize(1024 * 1024)
Expand All @@ -270,7 +270,7 @@ func TestProgressWithoutTotalSize(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000, 1646564138000}, 0)

progress := newTextProgressBar(writer, 95, 0, "")
progress := newTextProgressBar(writer, 95, 0, "", "")
progress.onNum(1)
progress.onName("中文😀非常长非常长非常长非常长非常长非常长非常长非常长.txt")
progress.onSize(1000 * 1024 * 1024 * 1024)
Expand All @@ -289,7 +289,7 @@ func TestProgressWithoutSpeedOrEta(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000, 1646564138000}, 0)

progress := newTextProgressBar(writer, 70, 0, "")
progress := newTextProgressBar(writer, 70, 0, "", "")
progress.onNum(1)
progress.onName("中文😀longlonglonglonglonglongname.txt")
progress.onSize(1000)
Expand All @@ -308,7 +308,7 @@ func TestProgressWithoutFileName(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000, 1646564138000}, 0)

progress := newTextProgressBar(writer, 48, 0, "")
progress := newTextProgressBar(writer, 48, 0, "", "")
progress.onNum(1)
progress.onName("中文😀llong文件名.txt")
progress.onSize(1000)
Expand All @@ -328,7 +328,7 @@ func TestProgressWithoutBar(t *testing.T) {
writer := newTestWriter(t)
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000}, 0)

progress := newTextProgressBar(writer, 10, 0, "")
progress := newTextProgressBar(writer, 10, 0, "", "")
progress.onNum(1)
progress.onName("中文😀test.txt")
progress.onSize(1000)
Expand All @@ -345,7 +345,7 @@ func TestProgressWithMultiFiles(t *testing.T) {
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000, 1646564136000,
1646564137000, 1646564139000, 1646564139000}, 0)

progress := newTextProgressBar(writer, 100, 0, "")
progress := newTextProgressBar(writer, 100, 0, "", "")
progress.onNum(2)
progress.onName("中文😀test.txt")
progress.onSize(1000)
Expand All @@ -371,7 +371,7 @@ func TestProgressInTmuxPane(t *testing.T) {
callTimeNowCount := mockTimeNow([]int64{1646564135000, 1646564136000, 1646564137000, 1646564137000,
1646564138000, 1646564139000, 1646564139000}, 0)

progress := newTextProgressBar(writer, 100, 80, "")
progress := newTextProgressBar(writer, 100, 80, "", "")
progress.onNum(2)
progress.onName("中文😀test.txt")
progress.onSize(1000)
Expand Down

0 comments on commit 615fd3d

Please sign in to comment.