From fa1bd38c1fb9314924715e7cec4a86c833613399 Mon Sep 17 00:00:00 2001 From: Joseph Barker Date: Sat, 25 Nov 2017 01:23:14 -0800 Subject: [PATCH 1/4] Add support for newline segment --- main.go | 1 + powerline.go | 75 +++++++++++++++++++++++++++++----------------- segment-newline.go | 5 ++++ 3 files changed, 54 insertions(+), 27 deletions(-) create mode 100644 segment-newline.go diff --git a/main.go b/main.go index 7f74f765..82bfb1eb 100644 --- a/main.go +++ b/main.go @@ -95,6 +95,7 @@ var modules = map[string](func(*powerline)){ "host": segmentHost, "jobs": segmentJobs, "kube": segmentKube, + "newline": segmentNewline, "perlbrew": segmentPerlbrew, "perms": segmentPerms, "root": segmentRoot, diff --git a/powerline.go b/powerline.go index d9a3a1aa..462eeeee 100644 --- a/powerline.go +++ b/powerline.go @@ -29,7 +29,8 @@ type powerline struct { symbolTemplates Symbols priorities map[string]int ignoreRepos map[string]bool - Segments []segment + Segments [][]segment + curSegment int } func NewPowerline(args args, cwd string, priorities map[string]int) *powerline { @@ -45,7 +46,7 @@ func NewPowerline(args args, cwd string, priorities map[string]int) *powerline { for _, r := range strings.Split(*args.IgnoreRepos, ",") { p.ignoreRepos[r] = true } - p.Segments = make([]segment, 0) + p.Segments = make([][]segment, 1) return p } @@ -75,7 +76,12 @@ func (p *powerline) appendSegment(origin string, segment segment) { priority, _ := p.priorities[origin] segment.priority += priority segment.width = segment.computeWidth() - p.Segments = append(p.Segments, segment) + p.Segments[p.curSegment] = append(p.Segments[p.curSegment], segment) +} + +func (p *powerline) newRow() { + p.Segments = append(p.Segments, make([]segment, 0)) + p.curSegment = p.curSegment + 1 } func termWidth() int { @@ -97,39 +103,40 @@ func termWidth() int { return termWidth } -func (p *powerline) draw() string { - shellMaxLength := termWidth() +func (p *powerline) truncateRow(rowNum int) { - shellMaxLength = shellMaxLength * *p.args.MaxWidthPercentage / 100 + shellMaxLength := termWidth() * *p.args.MaxWidthPercentage / 100 + row := p.Segments[rowNum] + rowLength := 0 - shellActualLength := 0 if shellMaxLength > 0 { - for _, segment := range p.Segments { - shellActualLength += segment.width + for _, segment := range row { + rowLength += segment.width } - if shellActualLength > shellMaxLength && *p.args.TruncateSegmentWidth > 0 { + + if rowLength > shellMaxLength && *p.args.TruncateSegmentWidth > 0 { minPriorityNotTruncated := MaxInteger minPriorityNotTruncatedSegmentId := -1 - for idx, segment := range p.Segments { + for idx, segment := range row { if segment.width > *p.args.TruncateSegmentWidth && segment.priority < minPriorityNotTruncated { minPriorityNotTruncated = segment.priority minPriorityNotTruncatedSegmentId = idx } } - for minPriorityNotTruncatedSegmentId != -1 && shellActualLength > shellMaxLength { - segment := p.Segments[minPriorityNotTruncatedSegmentId] + for minPriorityNotTruncatedSegmentId != -1 && rowLength > shellMaxLength { + segment := row[minPriorityNotTruncatedSegmentId] - shellActualLength -= segment.width + rowLength -= segment.width segment.content = runewidth.Truncate(segment.content, *p.args.TruncateSegmentWidth-runewidth.StringWidth(segment.separator)-3, "…") segment.width = segment.computeWidth() - p.Segments = append(append(p.Segments[:minPriorityNotTruncatedSegmentId], segment), p.Segments[minPriorityNotTruncatedSegmentId+1:]...) - shellActualLength += segment.width + row = append(append(row[:minPriorityNotTruncatedSegmentId], segment), row[minPriorityNotTruncatedSegmentId+1:]...) + rowLength += segment.width minPriorityNotTruncated = MaxInteger minPriorityNotTruncatedSegmentId = -1 - for idx, segment := range p.Segments { + for idx, segment := range row { if segment.width > *p.args.TruncateSegmentWidth && segment.priority < minPriorityNotTruncated { minPriorityNotTruncated = segment.priority minPriorityNotTruncatedSegmentId = idx @@ -138,33 +145,36 @@ func (p *powerline) draw() string { } } - for shellActualLength > shellMaxLength { + for rowLength > shellMaxLength { minPriority := MaxInteger minPrioritySegmentId := -1 - for idx, segment := range p.Segments { + for idx, segment := range row { if segment.priority < minPriority { minPriority = segment.priority minPrioritySegmentId = idx } } if minPrioritySegmentId != -1 { - segment := p.Segments[minPrioritySegmentId] - p.Segments = append(p.Segments[:minPrioritySegmentId], p.Segments[minPrioritySegmentId+1:]...) - shellActualLength -= segment.width + segment := row[minPrioritySegmentId] + row = append(row[:minPrioritySegmentId], row[minPrioritySegmentId+1:]...) + rowLength -= segment.width } } } + p.Segments[rowNum] = row +} +func (p *powerline) drawRow(rowNum int) string { + row := p.Segments[rowNum] var buffer bytes.Buffer - for idx, segment := range p.Segments { + for idx, segment := range row { var separatorBackground string - if idx >= len(p.Segments)-1 { + if idx >= len(row)-1 { separatorBackground = p.reset } else { - nextSegment := p.Segments[idx+1] + nextSegment := row[idx+1] separatorBackground = p.bgColor(nextSegment.background) } - buffer.WriteString(p.fgColor(segment.foreground)) buffer.WriteString(p.bgColor(segment.background)) buffer.WriteRune(' ') @@ -176,8 +186,19 @@ func (p *powerline) draw() string { buffer.WriteString(p.reset) } buffer.WriteRune(' ') + return buffer.String() +} + +func (p *powerline) draw() string { + + rows := make([]string, 0) + + for rowNum, _ := range p.Segments { + p.truncateRow(rowNum) + rows = append(rows, p.drawRow(rowNum)) + } + drawnResult := strings.Join(rows, "\n") - drawnResult := buffer.String() if *p.args.EastAsianWidth { var spaceBuffer bytes.Buffer for _, r := range drawnResult { diff --git a/segment-newline.go b/segment-newline.go new file mode 100644 index 00000000..83f03268 --- /dev/null +++ b/segment-newline.go @@ -0,0 +1,5 @@ +package main + +func segmentNewline(p *powerline) { + p.newRow() +} From dd6b5e4e9b1be0d6b0cef0e3caaf636937d2bf22 Mon Sep 17 00:00:00 2001 From: Joseph Barker Date: Sun, 17 Dec 2017 15:18:06 -0800 Subject: [PATCH 2/4] Make drawing of multiple rows more efficient --- powerline.go | 76 +++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/powerline.go b/powerline.go index 462eeeee..dc25a260 100644 --- a/powerline.go +++ b/powerline.go @@ -164,9 +164,28 @@ func (p *powerline) truncateRow(rowNum int) { p.Segments[rowNum] = row } -func (p *powerline) drawRow(rowNum int) string { +func (p *powerline) numEastAsianRunes(segmentContent *string) int { + if *p.args.EastAsianWidth { + return 0 + } + numEastAsianRunes := 0 + for _, r := range *segmentContent { + switch width.LookupRune(r).Kind() { + case width.Neutral: + case width.EastAsianAmbiguous: + numEastAsianRunes += 1 + case width.EastAsianWide: + case width.EastAsianNarrow: + case width.EastAsianFullwidth: + case width.EastAsianHalfwidth: + } + } + return numEastAsianRunes +} + +func (p *powerline) drawRow(rowNum int, buffer *bytes.Buffer) { row := p.Segments[rowNum] - var buffer bytes.Buffer + numEastAsianRunes := 0 for idx, segment := range row { var separatorBackground string if idx >= len(row)-1 { @@ -179,6 +198,7 @@ func (p *powerline) drawRow(rowNum int) string { buffer.WriteString(p.bgColor(segment.background)) buffer.WriteRune(' ') buffer.WriteString(segment.content) + numEastAsianRunes += p.numEastAsianRunes(&segment.content) buffer.WriteRune(' ') buffer.WriteString(separatorBackground) buffer.WriteString(p.fgColor(segment.separatorForeground)) @@ -186,38 +206,24 @@ func (p *powerline) drawRow(rowNum int) string { buffer.WriteString(p.reset) } buffer.WriteRune(' ') - return buffer.String() + + for i := 0; i < numEastAsianRunes; i++ { + buffer.WriteRune(' ') + } } func (p *powerline) draw() string { - rows := make([]string, 0) + var buffer bytes.Buffer - for rowNum, _ := range p.Segments { + for rowNum := range p.Segments { p.truncateRow(rowNum) - rows = append(rows, p.drawRow(rowNum)) - } - drawnResult := strings.Join(rows, "\n") - - if *p.args.EastAsianWidth { - var spaceBuffer bytes.Buffer - for _, r := range drawnResult { - switch width.LookupRune(r).Kind() { - case width.Neutral: - case width.EastAsianAmbiguous: - spaceBuffer.WriteRune(' ') - case width.EastAsianWide: - case width.EastAsianNarrow: - case width.EastAsianFullwidth: - case width.EastAsianHalfwidth: - } - } - drawnResult += spaceBuffer.String() + p.drawRow(rowNum, &buffer) + buffer.WriteRune('\n') } if *p.args.PromptOnNewLine { - var nextLineBuffer bytes.Buffer - nextLineBuffer.WriteRune('\n') + buffer.WriteRune('\n') var foreground, background uint8 if *p.args.PrevError == 0 { @@ -228,17 +234,15 @@ func (p *powerline) draw() string { background = p.theme.CmdFailedBg } - nextLineBuffer.WriteString(p.fgColor(foreground)) - nextLineBuffer.WriteString(p.bgColor(background)) - nextLineBuffer.WriteString(p.shellInfo.rootIndicator) - nextLineBuffer.WriteString(p.reset) - nextLineBuffer.WriteString(p.fgColor(background)) - nextLineBuffer.WriteString(p.symbolTemplates.Separator) - nextLineBuffer.WriteString(p.reset) - nextLineBuffer.WriteRune(' ') - - drawnResult += nextLineBuffer.String() + buffer.WriteString(p.fgColor(foreground)) + buffer.WriteString(p.bgColor(background)) + buffer.WriteString(p.shellInfo.rootIndicator) + buffer.WriteString(p.reset) + buffer.WriteString(p.fgColor(background)) + buffer.WriteString(p.symbolTemplates.Separator) + buffer.WriteString(p.reset) + buffer.WriteRune(' ') } - return drawnResult + return buffer.String() } From 4b52ee2944d0e1716c402f66c9093058be072ef4 Mon Sep 17 00:00:00 2001 From: Joseph Barker Date: Sun, 17 Dec 2017 16:22:50 -0800 Subject: [PATCH 3/4] Don't add unnecessary newline at end of prompt --- powerline.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/powerline.go b/powerline.go index dc25a260..0667f4f1 100644 --- a/powerline.go +++ b/powerline.go @@ -219,7 +219,9 @@ func (p *powerline) draw() string { for rowNum := range p.Segments { p.truncateRow(rowNum) p.drawRow(rowNum, &buffer) - buffer.WriteRune('\n') + if rowNum < len(p.Segments)-1 { + buffer.WriteRune('\n') + } } if *p.args.PromptOnNewLine { From 0ecc38328f831cecb14e965aceaaea6a71754965 Mon Sep 17 00:00:00 2001 From: Joseph Barker Date: Fri, 23 Mar 2018 12:08:54 -0700 Subject: [PATCH 4/4] Style fixes --- main.go | 2 +- powerline.go | 8 ++++---- segment-shellvar.go | 14 +++++++------- segment-termtitle.go | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index e7d09b72..ea9a4327 100644 --- a/main.go +++ b/main.go @@ -100,7 +100,7 @@ var modules = map[string](func(*powerline)){ "host": segmentHost, "jobs": segmentJobs, "kube": segmentKube, - "newline": segmentNewline, + "newline": segmentNewline, "perlbrew": segmentPerlbrew, "perms": segmentPerms, "root": segmentRoot, diff --git a/powerline.go b/powerline.go index 148d8fdd..85245fcb 100644 --- a/powerline.go +++ b/powerline.go @@ -199,10 +199,10 @@ func (p *powerline) drawRow(rowNum int, buffer *bytes.Buffer) { row := p.Segments[rowNum] numEastAsianRunes := 0 for idx, segment := range row { - if (segment.hideSeparators) { - buffer.WriteString(segment.content); - continue; - } + if segment.hideSeparators { + buffer.WriteString(segment.content) + continue + } var separatorBackground string if idx >= len(row)-1 { separatorBackground = p.reset diff --git a/segment-shellvar.go b/segment-shellvar.go index 62d046e2..7ce31f3c 100644 --- a/segment-shellvar.go +++ b/segment-shellvar.go @@ -5,20 +5,20 @@ import ( ) func segmentShellVar(p *powerline) { - shellVarName := *p.args.ShellVar; - varContent, varExists := os.LookupEnv(shellVarName); + shellVarName := *p.args.ShellVar + varContent, varExists := os.LookupEnv(shellVarName) - if (varExists) { - if (varContent != "") { - p.appendSegment("shell-var", segment { + if varExists { + if varContent != "" { + p.appendSegment("shell-var", segment{ content: varContent, foreground: p.theme.ShellVarFg, background: p.theme.ShellVarBg, }) } else { - warn("Shell variable " + shellVarName + " is empty."); + warn("Shell variable " + shellVarName + " is empty.") } } else { - warn("Shell variable " + shellVarName + " does not exist."); + warn("Shell variable " + shellVarName + " does not exist.") } } diff --git a/segment-termtitle.go b/segment-termtitle.go index b01f8d96..4b7e3286 100644 --- a/segment-termtitle.go +++ b/segment-termtitle.go @@ -13,7 +13,7 @@ func segmentTermTitle(p *powerline) { var title string term := os.Getenv("TERM") - if (!(strings.Contains(term, "xterm") || strings.Contains(term, "rxvt"))) { + if !(strings.Contains(term, "xterm") || strings.Contains(term, "rxvt")) { return }